Names quak builds from server data fit in 255 bytes (closes #205)
check / check (push) Canceled after 0s
check / check (push) Canceled after 0s
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:
@@ -17,6 +17,7 @@ import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
safeExtension,
|
||||
sanitizeFileName,
|
||||
shortenKeepingExtension,
|
||||
shortenToBytes,
|
||||
} from "../../src/filename.js";
|
||||
|
||||
@@ -94,6 +95,12 @@ describe("safeExtension", () => {
|
||||
expect(safeExtension("x.jp g")).toBe(".bin");
|
||||
expect(safeExtension("x.jpg\0")).toBe(".bin");
|
||||
});
|
||||
|
||||
it("keeps an extension of 16 letters and digits, and uses .bin for a longer one", () => {
|
||||
expect(safeExtension(`x.${"e".repeat(16)}`)).toBe(`.${"e".repeat(16)}`);
|
||||
expect(safeExtension(`x.${"e".repeat(17)}`)).toBe(".bin");
|
||||
expect(safeExtension(`b.${"e".repeat(300)}`)).toBe(".bin");
|
||||
});
|
||||
});
|
||||
|
||||
describe("shortenToBytes", () => {
|
||||
@@ -118,3 +125,42 @@ describe("shortenToBytes", () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("shortenKeepingExtension", () => {
|
||||
it("returns a name that fits unchanged", () => {
|
||||
expect(shortenKeepingExtension("beach.jpg", 9)).toBe("beach.jpg");
|
||||
expect(shortenKeepingExtension("beach", 5)).toBe("beach");
|
||||
});
|
||||
|
||||
it("cuts the part before the extension short and keeps the extension", () => {
|
||||
expect(shortenKeepingExtension(`${"t".repeat(296)}.jpg`, 255)).toBe(
|
||||
`${"t".repeat(251)}.jpg`,
|
||||
);
|
||||
expect(shortenKeepingExtension("é".repeat(150), 255)).toBe(
|
||||
"é".repeat(127),
|
||||
);
|
||||
});
|
||||
|
||||
it("cuts the extension short when it alone does not fit", () => {
|
||||
expect(shortenKeepingExtension(`b.${"e".repeat(300)}`, 255)).toBe(
|
||||
`.${"e".repeat(254)}`,
|
||||
);
|
||||
// "€" takes three bytes, so the extension is cut to 253 and the
|
||||
// part before it keeps the two bytes left over, for the "a".
|
||||
expect(shortenKeepingExtension(`a.${"€".repeat(90)}`, 255)).toBe(
|
||||
`a.${"€".repeat(84)}`,
|
||||
);
|
||||
});
|
||||
|
||||
it("puts `insert` right before the extension and leaves room for it", () => {
|
||||
expect(shortenKeepingExtension("beach.jpg", 255, " (7)")).toBe(
|
||||
"beach (7).jpg",
|
||||
);
|
||||
expect(
|
||||
shortenKeepingExtension(`${"t".repeat(296)}.jpg`, 255, " (7)"),
|
||||
).toBe(`${"t".repeat(247)} (7).jpg`);
|
||||
expect(
|
||||
shortenKeepingExtension(`b.${"e".repeat(300)}`, 255, " (7)"),
|
||||
).toBe(` (7).${"e".repeat(250)}`);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user