Skip to content

Commit

Permalink
feat(document-history): limit history file size
Browse files Browse the repository at this point in the history
  • Loading branch information
purocean committed Jul 31, 2023
1 parent c8aca87 commit 1ac3ed9
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 7 deletions.
23 changes: 19 additions & 4 deletions src/main/server/file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,16 +86,23 @@ 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
}

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()
Expand All @@ -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)
}
Expand Down Expand Up @@ -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)
}

Expand Down
20 changes: 18 additions & 2 deletions src/renderer/components/DocHistory.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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')
Expand 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
Expand All @@ -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 })
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/support/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

1 comment on commit 1ac3ed9

@vercel
Copy link

@vercel vercel bot commented on 1ac3ed9 Jul 31, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.