Names quak builds from server data fit in 255 bytes (closes #205)
The default names of `quak get`, `quak get-thumb`, `downloadFile` and `downloadThumbnail`, and the album folders of `backup-metadata`, could be over 255 bytes, which a file system refuses. `shortenKeepingExtension` in `src/filename.ts` cuts a name short, keeping its extension when it fits, and can put text right before the extension; the backup's `withID` now calls it instead of doing the same itself. The `get` defaults use it with `thumb_` counted. A `backup-metadata` folder keeps its `<id>-` and has the name after it cut short. `safeExtension` gives `.bin` for an extension of more than 16 letters and digits, so a save path's name always fits. Model: opus-5-5
This commit is contained in:
+20
-4
@@ -16,7 +16,13 @@ import {
|
||||
streamTagFinal,
|
||||
} from "../crypto/index.js";
|
||||
import { TruncatedStreamError } from "../errors.js";
|
||||
import { safeExtension, sanitizeFileName, withExtension } from "../filename.js";
|
||||
import {
|
||||
MAX_NAME_BYTES,
|
||||
safeExtension,
|
||||
sanitizeFileName,
|
||||
shortenKeepingExtension,
|
||||
withExtension,
|
||||
} from "../filename.js";
|
||||
import { withRetry } from "../retry.js";
|
||||
import type { ApiClient } from "../api/client.js";
|
||||
import type { EnteFile } from "../model/types.js";
|
||||
@@ -583,9 +589,14 @@ export const downloadFile = async (
|
||||
onProgress?: ProgressCallback,
|
||||
): Promise<DownloadResult> => {
|
||||
// `outPath` is the caller's and is used as is; the title is the server's
|
||||
// and is sanitized so it can only name a file in the current directory.
|
||||
// and is sanitized so it can only name a file in the current directory,
|
||||
// and cut short to fit in a file name, keeping its extension.
|
||||
const resolvedPath =
|
||||
outPath ?? sanitizeFileName(file.metadata.title, `file-${file.id}`);
|
||||
outPath ??
|
||||
shortenKeepingExtension(
|
||||
sanitizeFileName(file.metadata.title, `file-${file.id}`),
|
||||
MAX_NAME_BYTES,
|
||||
);
|
||||
const header = fromBase64(file.file.decryptionHeader);
|
||||
return fetchAndDecrypt(
|
||||
api,
|
||||
@@ -604,9 +615,14 @@ export const downloadThumbnail = async (
|
||||
outPath?: string,
|
||||
onProgress?: ProgressCallback,
|
||||
): Promise<DownloadResult> => {
|
||||
// As in `downloadFile`, with `thumb_` before the title.
|
||||
const resolvedPath =
|
||||
outPath ??
|
||||
`thumb_${sanitizeFileName(file.metadata.title, `file-${file.id}`)}`;
|
||||
"thumb_" +
|
||||
shortenKeepingExtension(
|
||||
sanitizeFileName(file.metadata.title, `file-${file.id}`),
|
||||
MAX_NAME_BYTES - "thumb_".length,
|
||||
);
|
||||
const header = fromBase64(file.thumbnail.decryptionHeader);
|
||||
return fetchAndDecrypt(
|
||||
api,
|
||||
|
||||
Reference in New Issue
Block a user