feat(document-history): limit history file size

This commit is contained in:
purocean
2023-07-31 15:38:20 +08:00
parent c8aca872e4
commit 1ac3ed9134
3 changed files with 38 additions and 7 deletions
+19 -4
View File
@@ -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)
}
+18 -2
View File
@@ -3,7 +3,7 @@
<div class="history-wrapper" v-if="currentDoc" @click.stop>
<div class="history">
<div class="versions-wrapper" v-if="versions && versions.length">
<div v-if="listType === 'all'" class="clear" @click="clearVersions">{{$t('doc-history.clear')}}</div>
<div v-if="listType === 'all'" class="clear" @click="clearVersions">{{$t('doc-history.clear')}}({{sizeText}})</div>
<GroupTabs class="tabs" :tabs="getListTypes()" v-model="listType" />
<div class="versions" v-if="xVersions && xVersions.length">
<div
@@ -100,6 +100,7 @@ const getListTypes = () => [
const currentDoc = ref<Doc | null>(null)
const currentVersion = ref<Version>()
const versions = ref<Version[] | null>([])
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 })
+1 -1
View File
@@ -162,7 +162,7 @@ export async function deleteFile (file: FileItem): Promise<ApiResult<any>> {
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