diff --git a/library.ts b/library.ts index 8e3df62..d58f16e 100644 --- a/library.ts +++ b/library.ts @@ -1,3 +1,7 @@ +import fs from "node:fs/promises"; +import { createWriteStream } from "node:fs"; +import stream from "node:stream/promises"; +import { Zip, ZipPassThrough } from "fflate"; import { Database } from "./database"; export type Book = { @@ -35,5 +39,40 @@ export function createLibrary(db: Database) { return books; }, + async archive(dir: string) { + const bookDirs = await fs.readdir(dir, { withFileTypes: true }); + + for (const bookDir of bookDirs) { + if (!bookDir.isDirectory()) { + continue; + } + + const path = `${bookDir.path}/${bookDir.name}`; + const out = createWriteStream(`${path}.cbz`); + const zip = new Zip(function cb(err, data, final) { + if (err) { + out.destroy(err); + return; + } + + out[final ? "end" : "write"](data); + }); + + const files = await fs.readdir(path); + + for (const file of files) { + const data = new ZipPassThrough(file); + zip.add(data); + + const buffer = await fs.readFile(`${path}/${file}`); + data.push(buffer, true); + } + + zip.end(); + + await stream.finished(out); + await fs.rm(path, { recursive: true }); + } + }, }; } diff --git a/main.ts b/main.ts index 8e0b699..090bac4 100644 --- a/main.ts +++ b/main.ts @@ -93,6 +93,15 @@ const options = { const platform = createPlatform({ db, browser }); const dir = `${args.values["out-dir"]!}/${book.id}`; await platform.download(dir, book); + await library.archive(args.values["out-dir"]!); + }, + }, + archive: { + type: "boolean", + async run() { + const db = await createDatabase(args.values.db!); + const library = createLibrary(db); + await library.archive(args.values["out-dir"]!); }, }, help: { diff --git a/package-lock.json b/package-lock.json index ef81fa2..18bb480 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "0.0.0", "license": "AGPL-3.0", "dependencies": { + "fflate": "^0.8.1", "playwright": "^1.39.0", "sqlite": "^5.1.1", "sqlite3": "^5.1.6", @@ -661,6 +662,11 @@ "@esbuild/win32-x64": "0.18.20" } }, + "node_modules/fflate": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.1.tgz", + "integrity": "sha512-/exOvEuc+/iaUm105QIiOt4LpBdMTWsXxqR0HDF35vx3fmaKzw7354gTilCh5rkzEt8WYyG//ku3h3nRmd7CHQ==" + }, "node_modules/fs-minipass": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", diff --git a/package.json b/package.json index 4f236c2..4fd0b63 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "type": "module", "bin": "bin/run.js", "dependencies": { + "fflate": "^0.8.1", "playwright": "^1.39.0", "sqlite": "^5.1.1", "sqlite3": "^5.1.6",