gadl/platform.ts

95 lines
2.5 KiB
TypeScript
Raw Normal View History

2023-12-02 23:22:33 +09:00
import fs from "node:fs/promises";
import path from "node:path";
import type { Book } from "./library";
2023-11-19 16:18:00 +09:00
import type { Browser } from "./browser";
2023-12-02 23:22:33 +09:00
import type { Database } from "./database";
2023-11-19 16:18:00 +09:00
import { DmmBooks } from "./platforms/dmm-books";
2023-12-03 05:54:45 +09:00
import { FanzaDoujin } from "./platforms/fanza-doujin";
2023-12-02 23:22:33 +09:00
import { GooglePlayBooks } from "./platforms/google-play-books";
const platforms = {
"dmm-books": DmmBooks,
2023-12-03 05:54:45 +09:00
"fanza-doujin": FanzaDoujin,
2023-12-02 23:22:33 +09:00
"google-play-books": GooglePlayBooks,
};
export type TPlatform = keyof typeof platforms;
export function site(url: string): TPlatform {
2023-12-03 05:54:45 +09:00
for (const [platform, { siteUrl }] of Object.entries(platforms)) {
if (siteUrl(new URL(url))) return platform as TPlatform;
2023-12-02 23:22:33 +09:00
}
throw new Error(`Unsupported URL: ${url}`);
}
export function createPlatform(opts: {
platform: TPlatform;
db: Database;
browser: Browser;
}) {
if (!(opts.platform in platforms)) {
2023-12-03 05:54:45 +09:00
throw new Error(
`The value must be a platform type: ${[...Object.keys(platforms)].join(
", ",
)}.`,
);
2023-12-02 23:22:33 +09:00
}
const platform = platforms[opts.platform](opts.browser);
2023-11-19 02:25:32 +09:00
2023-12-02 23:22:33 +09:00
return {
...platform,
2023-12-03 00:48:24 +09:00
2023-12-02 23:22:33 +09:00
async download(dir: string, book: Book): Promise<void> {
await fs.mkdir(path.dirname(dir), { recursive: true });
await fs.mkdir(dir);
2023-12-03 00:48:24 +09:00
const files: Array<() => Promise<string>> = await platform.getFiles(book);
const digits = String(files.length).length;
function pad(n: string) {
return n.padStart(digits, "0");
}
const supportedTypes = {
"image/png": "png",
"image/jpeg": "jpg",
2023-12-03 12:44:31 +09:00
"application/zip": "zip",
"application/vnd.comicbook+zip": "cbz",
2023-12-03 00:48:24 +09:00
};
for (const [n, dataUrl] of Object.entries(files)) {
const [prefix, base64] = (await dataUrl()).split(",", 2);
const [, type, encoding] =
/^data:([^;]*)(;base64)?$/.exec(prefix) ?? [];
const extension = supportedTypes[type];
if (!extension) {
throw new Error(
`It was ${type}. The image must be a file of type: ${[
...Object.keys(supportedTypes),
].join(", ")}.`,
);
}
if (encoding !== ";base64") {
throw new Error("Only base64 is supported.");
}
const buffer = Buffer.from(base64, "base64");
await fs.writeFile(`${dir}/${pad(n)}.${extension}`, buffer);
}
process.stderr.write(`\n`);
2023-12-02 23:22:33 +09:00
},
2023-12-03 00:48:24 +09:00
2023-12-02 23:22:33 +09:00
async logout() {
await opts.db.run(
`update platforms set secrets = 'null' where name = ?`,
opts.platform,
);
},
};
2023-11-19 02:25:32 +09:00
}