78 lines
2.2 KiB
TypeScript
78 lines
2.2 KiB
TypeScript
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 = {
|
|
id: number;
|
|
platform: "dmm-books" | "google-play-books";
|
|
readerUrl: string;
|
|
};
|
|
|
|
export function createLibrary(db: Database) {
|
|
return {
|
|
async add(readerUrl: string) {
|
|
const platform = "dmm-books";
|
|
|
|
await db.run(
|
|
`insert into books(reader_url, platform_id) values(?, (select id from platforms where name = ?))`,
|
|
readerUrl,
|
|
platform,
|
|
);
|
|
},
|
|
async delete(id: number) {
|
|
await db.run(`delete from books where id = ?`, id);
|
|
},
|
|
async get(id: number): Promise<Book | undefined> {
|
|
const book: Book | undefined = await db.get(
|
|
`select books.id, platforms.name as platform, books.reader_url as readerUrl from books left join platforms on books.platform_id = platforms.id where books.id = ?`,
|
|
id,
|
|
);
|
|
|
|
return book;
|
|
},
|
|
async getBooks(): Promise<Array<Book>> {
|
|
const books: Array<Book> = await db.all(
|
|
`select books.id, platforms.name as platform, books.reader_url as readerUrl from books left join platforms on books.platform_id = platforms.id`,
|
|
);
|
|
|
|
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 });
|
|
}
|
|
},
|
|
};
|
|
}
|