Files
eh-downloader/tasks/export_zip.ts
2023-06-10 10:53:48 +08:00

83 lines
2.3 KiB
TypeScript

import { join } from "std/path/mod.ts";
import { Uint8ArrayReader, ZipWriter } from "zipjs/index.js";
import { EhDb } from "../db.ts";
import {
addZero,
asyncForEach,
configureZipJs,
filterFilename,
} from "../utils.ts";
import { Config } from "../config.ts";
import { Task, TaskExportZipProgress, TaskType } from "../task.ts";
import { TaskManager } from "../task_manager.ts";
export type ExportZipConfig = {
output?: string;
};
export const DEFAULT_EXPORT_ZIP_CONFIG: ExportZipConfig = {};
export async function export_zip(
task: Task,
db: EhDb,
cfg: Config,
signal: AbortSignal,
ecfg: ExportZipConfig,
manager: TaskManager,
) {
const gid = task.gid;
const g = db.get_gmeta_by_gid(gid);
if (!g) throw Error("Gallery not found in database.");
const progress: TaskExportZipProgress = {
total_page: g.filecount,
added_page: 0,
};
const sendEvent = () => {
manager.dispatchTaskProgressEvent(TaskType.ExportZip, task.id, {
added_page: progress.added_page,
total_page: progress.total_page,
});
};
sendEvent();
const output = ecfg.output === undefined
? join(cfg.base, filterFilename(g.title + ".zip"))
: ecfg.output;
const f = await Deno.open(output, {
create: true,
write: true,
truncate: true,
});
try {
configureZipJs();
const z = new ZipWriter(f.writable, {
signal,
level: 0,
});
const l = g.filecount.toString().length;
await asyncForEach(
db.get_pmeta(gid).sort((a, b) => a.index - b.index),
async (p) => {
const f = db.get_files(gid, p.token);
if (f.length) {
const r = await Deno.readFile(f[0].path, { signal });
await z.add(
`${addZero(p.index, l)}_${p.name}`,
new Uint8ArrayReader(r),
{ signal },
);
}
progress.added_page += 1;
sendEvent();
},
);
await z.close();
} finally {
try {
f.close();
} catch (_) {
null;
}
}
return task;
}