From 1ac3ed91345063d10324bc1c17aecaa8bb5d9a54 Mon Sep 17 00:00:00 2001 From: purocean Date: Mon, 31 Jul 2023 15:38:20 +0800 Subject: [PATCH] feat(document-history): limit history file size --- src/main/server/file.ts | 23 +++++++++++++++++++---- src/renderer/components/DocHistory.vue | 20 ++++++++++++++++++-- src/renderer/support/api.ts | 2 +- 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/src/main/server/file.ts b/src/main/server/file.ts index 5344f8c56..fbd2fc67c 100644 --- a/src/main/server/file.ts +++ b/src/main/server/file.ts @@ -86,7 +86,7 @@ function writeHistoryZip (zip: AdmZip, zipFilePath: string) { } async function writeHistory (filePath: string, content: any) { - const limit = Math.min(10000, config.get('doc-history.number-limit', 500)) + let limit = Math.min(10000, config.get('doc-history.number-limit', 500)) if (limit < 1) { return } @@ -94,8 +94,15 @@ async function writeHistory (filePath: string, content: any) { const historyFilePath = getHistoryFilePath(filePath) let zip: AdmZip + let tooLarge = false if ((await fs.pathExists(historyFilePath))) { + const stats = await fs.stat(historyFilePath) + if (stats.size > 1024 * 1024 * 5) { // 5M + console.log('history file too large, limit max versions.', historyFilePath, stats.size) + tooLarge = true + } + zip = readHistoryZip(historyFilePath) } else { zip = new AdmZip() @@ -105,7 +112,12 @@ async function writeHistory (filePath: string, content: any) { zip.addFile(dayjs().format('YYYY-MM-DD HH-mm-ss') + ext, content) - orderBy(zip.getEntries(), x => x.entryName, 'desc').slice(limit).forEach(entry => { + const entries = zip.getEntries() + if (tooLarge) { + limit = Math.min(limit, Math.floor(entries.length / 3 * 2)) + } + + orderBy(entries, x => x.entryName, 'desc').slice(limit).forEach(entry => { if (!entry.comment) { zip.deleteFile(entry) } @@ -376,14 +388,17 @@ export function historyList (repo: string, path: string) { const historyFilePath = getHistoryFilePath(filePath) if (!(await fs.pathExists(historyFilePath))) { - return [] + return { list: [], size: 0 } } + const stats = await fs.stat(historyFilePath) const zip = readHistoryZip(historyFilePath) - return orderBy(zip.getEntries(), x => x.entryName, 'desc').map(x => ({ + const list = orderBy(zip.getEntries(), x => x.entryName, 'desc').map(x => ({ name: x.entryName, comment: x.comment })) + + return { list, size: stats.size } }, path) } diff --git a/src/renderer/components/DocHistory.vue b/src/renderer/components/DocHistory.vue index 955b9d496..2983f51cc 100644 --- a/src/renderer/components/DocHistory.vue +++ b/src/renderer/components/DocHistory.vue @@ -3,7 +3,7 @@
-
{{$t('doc-history.clear')}}
+
{{$t('doc-history.clear')}}({{sizeText}})
[ const currentDoc = ref(null) const currentVersion = ref() const versions = ref([]) +const size = ref(0) const content = ref('') const displayType = ref<'content' | 'diff'>('content') const listType = ref<'all' | 'marked'>('all') @@ -116,6 +117,11 @@ const xVersions = computed(() => { return versions.value }) +const sizeText = computed(() => { + const val = Math.round(size.value / 1024) + return val > 1024 ? `${Math.round(val / 1024)}M` : `${val}K` +}) + function show (doc?: Doc) { doc ??= currentFile.value! currentDoc.value = doc @@ -133,12 +139,22 @@ function show (doc?: Doc) { function hide () { currentDoc.value = null versions.value = null + size.value = 0 } async function fetchVersions () { try { versions.value = null - versions.value = (currentDoc.value ? await fetchHistoryList(currentDoc.value) : []).map(({ name: value, comment }) => { + size.value = 0 + + let list: any[] = [] + if (currentDoc.value) { + const data = await fetchHistoryList(currentDoc.value!) + list = data.list + size.value = data.size + } + + versions.value = list.map(({ name: value, comment }) => { const arr = value.split('.') const name = arr[0] const encrypted = isEncrypted({ type: 'file', path: value }) diff --git a/src/renderer/support/api.ts b/src/renderer/support/api.ts index 85409b576..565961c9d 100644 --- a/src/renderer/support/api.ts +++ b/src/renderer/support/api.ts @@ -162,7 +162,7 @@ export async function deleteFile (file: FileItem): Promise> { return fetchHttp(`/api/file?path=${encodeURIComponent(path)}&repo=${encodeURIComponent(repo)}`, { method: 'DELETE' }) } -export async function fetchHistoryList (file: PathItem): Promise<{name: string, comment: string}[]> { +export async function fetchHistoryList (file: PathItem): Promise<{size: number, list: {name: string, comment: string}[]}> { const { path, repo } = file const { data } = await fetchHttp(`/api/history/list?path=${encodeURIComponent(path)}&repo=${encodeURIComponent(repo)}`) return data