Skip to content

Commit

Permalink
feat: add support for handling existing files during upload
Browse files Browse the repository at this point in the history
  • Loading branch information
purocean committed Oct 9, 2024
1 parent a6f4ee4 commit 1132c0f
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 8 deletions.
28 changes: 26 additions & 2 deletions src/main/server/file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,9 +248,33 @@ export async function checkHash (repo: string, p: string, oldHash: string) {
return oldHash === await hash(repo, p)
}

export async function upload (repo: string, buffer: Buffer, path: string) {
export async function upload (repo: string, buffer: Buffer, filePath: string, ifExists: 'rename' | 'overwrite' | 'skip' | 'error' = 'error'): Promise<{ path: string, hash: string }> {
if (readonly) throw new Error('Readonly')
await write(repo, path, buffer)

let newFilePath = filePath

if (await exists(repo, filePath)) {
if (ifExists === 'overwrite') {
// do nothing
} else if (ifExists === 'skip') {
return { path: filePath, hash: await hash(repo, filePath) }
} else if (ifExists === 'rename') {
const dir = path.dirname(filePath)
const ext = path.extname(filePath)
const base = path.basename(filePath, ext)

let i = 1
while (await exists(repo, newFilePath)) {
i++
const seq = i > 100 ? Math.floor(Math.random() * 1000000) : i
newFilePath = path.join(dir, base + `-${seq}` + ext)
}
} else {
throw new Error('File exists')
}
}

return { path: newFilePath, hash: await write(repo, newFilePath, buffer) }
}

function getRelativePath (from: string, to: string) {
Expand Down
5 changes: 3 additions & 2 deletions src/main/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,9 +206,10 @@ const attachment = async (ctx: any, next: any) => {
const path = ctx.request.body.path
const repo = ctx.request.body.repo
const attachment = ctx.request.body.attachment
const exists = ctx.request.body.exists
const buffer = Buffer.from(attachment.substring(attachment.indexOf(',') + 1), 'base64')
await file.upload(repo, buffer, path)
ctx.body = result('ok', 'success', path)
const res = await file.upload(repo, buffer, path, exists)
ctx.body = result('ok', 'success', res)
} else if (ctx.method === 'GET') {
let { repo, path } = ctx.query

Expand Down
8 changes: 5 additions & 3 deletions src/renderer/services/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export function getAttachmentURL (doc: Doc, opts: { origin: boolean } = { origin
* @param name filename
* @returns
*/
export async function upload (file: File, belongDoc: Pick<Doc, 'repo' | 'path'>, name?: string) {
export async function upload (file: File, belongDoc: Pick<Doc, 'repo' | 'path'>, name?: string, ifExists: 'rename' | 'overwrite' | 'skip' | 'error' = 'rename'): Promise<string> {
if (FLAG_DEMO) {
return Promise.resolve(URL.createObjectURL(file))
}
Expand All @@ -67,11 +67,13 @@ export async function upload (file: File, belongDoc: Pick<Doc, 'repo' | 'path'>,
.replaceAll('{date}', dayjs().format('YYYY-MM-DD'))
.replaceAll('{docHash}', binMd5(parentNameWithoutMdExt).slice(0, 8))

const path: string = resolve(parentPath, assetsDir, filename)
let path: string = resolve(parentPath, assetsDir, filename)

logger.debug('upload', belongDoc, file, path)

await api.upload(belongDoc.repo, fileBase64Url, path)
const res = await api.upload(belongDoc.repo, fileBase64Url, path, ifExists)

path = res.data.path

if (
assetsPathType === 'relative' ||
Expand Down
4 changes: 3 additions & 1 deletion src/renderer/support/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -393,12 +393,14 @@ export async function watchFs (
* @param repo
* @param fileBase64Url
* @param filePath
* @param ifExists
*/
export async function upload (repo: string, fileBase64Url: string, filePath: string): Promise<ApiResult<any>> {
export async function upload (repo: string, fileBase64Url: string, filePath: string, ifExists: 'rename' | 'overwrite' | 'skip' | 'error' = 'rename'): Promise<ApiResult<{ path: string, hash: string }>> {
const formData = new FormData()
formData.append('repo', repo)
formData.append('path', filePath)
formData.append('attachment', fileBase64Url)
formData.append('exists', ifExists)

return fetchHttp('/api/attachment', { method: 'POST', body: formData })
}
Expand Down

0 comments on commit 1132c0f

Please sign in to comment.