fix: wrong creation-time

Massimo Melina committed Jan 17, 2025 at 18:27 UTC 4eb213f47689b418f7a00e15da6311d9e46b15c1
9 files changed +14 -14
admin/src/FileForm.ts
+2 -2
@@ -138,7 +138,7 @@ export default function FileForm({ file, addToBar, statusApi, accounts, saved }:
138 save: {
139 ...propsForModifiedValues(isModifiedConfig(values, rest)),
140 async onClick() {
141 - const props = _.omit(values, ['ctime','mtime','size','id'])
141 + const props = _.omit(values, ['birthtime','mtime','size','id'])
142 ;(props as any).masks ||= null // undefined cannot be serialized
143 await apiCall('set_vfs', { uri: values.id, props })
144 if (props.name !== file.name) // when the name changes, the id of the selected file is changing too, and we have to update it in the state if we want it to be correctly re-selected after reload
@@ -191,7 +191,7 @@ export default function FileForm({ file, addToBar, statusApi, accounts, saved }:
191 toField: x => x > '',
192 },
193 showSize && { k: 'size', comp: DisplayField, sm: 6, lg: 4, toField: formatBytes },
194 - showTimestamps && { k: 'ctime', comp: DisplayField, sm: 6, lg: showSize && 4, label: "Created", toField: formatTimestamp },
194 + showTimestamps && { k: 'birthtime', comp: DisplayField, sm: 6, lg: showSize && 4, label: "Created", toField: formatTimestamp },
195 showTimestamps && { k: 'mtime', comp: DisplayField, sm: 6, lg: showSize && 4, label: "Modified", toField: formatTimestamp },
196 showAccept && { k: 'accept', label: "Accept on upload", placeholder: "anything", xl: showWebsite ? 4 : 12,
197 helperText: h(Link, { href: ACCEPT_LINK, target: '_blank' }, "Example: .zip") },
admin/src/VfsPage.ts
+2 -2
@@ -184,9 +184,9 @@ export async function deleteFiles() {
184 }
185 }
186
187 -export interface VfsNode extends Omit<VfsNodeAdminSend, 'ctime' | 'mtime' | 'children'> {
187 +export interface VfsNode extends Omit<VfsNodeAdminSend, 'birthtime' | 'mtime' | 'children'> {
188 id: string
189 - ctime?: string
189 + birthtime?: string
190 mtime?: string
191 default?: string
192 children?: VfsNode[]
src/api.get_file_list.ts
+2 -2
@@ -125,8 +125,8 @@ export const get_file_list: ApiHandler = async ({ uri='/', offset, limit, search
125 const pa = Boolean(can_archive) === hasPermission(node, 'can_archive', ctx) ? '' : can_archive ? 'a' : 'A'
126 return {
127 n: name + (isFolder ? '/' : ''),
128 - c: st?.ctime,
129 - m: !st || Math.abs(+st.mtime - +st.ctime) < 1000 ? undefined : st.mtime,
128 + c: st?.birthtime,
129 + m: !st || Math.abs(st.mtimeMs - st.birthtimeMs) < 1000 ? undefined : st.mtime,
130 s: isFolder ? undefined : st?.size,
131 p: (pr + pl + pd + pa) || undefined,
132 comment: node.comment ?? await getCommentFor(source),
src/api.vfs.ts
+3 -3
@@ -35,9 +35,9 @@ const apis: ApiHandlers = {
35 const { source } = node
36 const stats = !source ? undefined : (node.stats || await stat(source!).catch(() => undefined))
37 const isDir = !nodeIsLink(node) && (!source || (stats?.isDirectory() ?? node.children?.length! > 0))
38 - const copyStats: Pick<VfsNodeAdminSend, 'size' | 'ctime' | 'mtime'> = stats ? _.pick(stats, ['size', 'ctime', 'mtime'])
38 + const copyStats: Pick<VfsNodeAdminSend, 'size' | 'birthtime' | 'mtime'> = stats ? _.pick(stats, ['size', 'birthtime', 'mtime'])
39 : { size: source ? -1 : undefined }
40 - if (copyStats.mtime && Number(copyStats.mtime) === Number(copyStats.ctime))
40 + if (copyStats.mtime && (stats?.mtimeMs! - stats?.birthtimeMs!) < 1000)
41 delete copyStats.mtime
42 const inherited = node.parent && permsFromParent(node.parent, {})
43 const byMasks = node.original && _.pickBy(node, (v,k) =>
@@ -213,7 +213,7 @@ const apis: ApiHandlers = {
213 list.add({
214 n: name,
215 s: stats.size,
216 - c: stats.ctime,
216 + c: stats.birthtime,
217 m: stats.mtime,
218 k: isDir ? 'd' : undefined,
219 })
src/config.ts
+1 -1
@@ -174,7 +174,7 @@ const saveDebounced = debounceAsync(async () => {
174 // keep backup
175 const bak = filePath + '.bak'
176 const aWeekAgo = Date.now() - DAY * 7
177 - if (await stat(bak).then(x => aWeekAgo > Number(x.mtime || x.ctime), () => true))
177 + if (await stat(bak).then(x => aWeekAgo > (x.mtimeMs || x.birthtimeMs), () => true))
178 await copyFile(filePath, bak).catch(() => {}) // ignore errors
179
180 await configFile.save(stringify({ ...state, version: VERSION }))
src/cross.ts
+1 -1
@@ -72,7 +72,7 @@ export type VfsNodeAdminSend = {
72 name: string
73 type?: 'folder'
74 size?: number
75 - ctime?: Date
75 + birthtime?: Date
76 mtime?: Date
77 website?: true
78 byMasks?: VfsPerms
src/dirStream.ts
+1 -1
@@ -65,7 +65,7 @@ export function createDirStream(startPath: string, { depth=0, hidden=true }) {
65 work(Object.assign(Object.create(methods), {
66 isDir: f.IS_DIRECTORY,
67 name: f.LONG_NAME,
68 - stats: { size: f.SIZE, ctime: f.CREATION_TIME, mtime: f.LAST_WRITE_TIME } as Stats
68 + stats: { size: f.SIZE, birthtime: f.CREATION_TIME, mtime: f.LAST_WRITE_TIME } as Stats
69 }))
70 }
71 }
src/log.ts
+1 -1
@@ -32,7 +32,7 @@ class Logger {
32 return this.stream = undefined
33 try {
34 const stats = await stat(path)
35 - this.last = stats.mtime || stats.ctime
35 + this.last = stats.mtime || stats.birthtime
36 }
37 catch {
38 if (await prepareFolder(path) === false)
src/zip.ts
+1 -1
@@ -57,7 +57,7 @@ export async function zipStreamFromFolder(node: VfsNode, ctx: Koa.Context) {
57 return {
58 path: name,
59 size: st.size,
60 - ts: st.mtime || st.ctime,
60 + ts: st.mtime || st.birthtime,
61 mode: st.mode,
62 sourcePath: source,
63 getData: () => createReadStream(source, { start: 0 , end: Math.max(0, st.size-1) })