ionian/packages/server/src/content/comic.ts

72 lines
2.3 KiB
TypeScript
Raw Normal View History

2024-03-29 00:19:36 +09:00
import { extname } from "node:path";
import type { DocumentBody } from "../model/doc";
2024-04-03 21:46:18 +09:00
import { readZip } from "../util/zipwrap";
2024-03-29 00:19:36 +09:00
import { type ContentConstructOption, createDefaultClass, registerContentReferrer } from "./file";
2024-04-03 21:46:18 +09:00
import { TextWriter } from "@zip.js/zip.js";
2024-03-26 23:58:26 +09:00
type ComicType = "doujinshi" | "artist cg" | "manga" | "western";
interface ComicDesc {
title: string;
artist?: string[];
group?: string[];
series?: string[];
type: ComicType | [ComicType];
character?: string[];
tags?: string[];
}
const ImageExt = [".gif", ".png", ".jpeg", ".bmp", ".webp", ".jpg"];
export class ComicReferrer extends createDefaultClass("comic") {
desc: ComicDesc | undefined;
pagenum: number;
additional: ContentConstructOption | undefined;
constructor(path: string, option?: ContentConstructOption) {
super(path);
this.additional = option;
this.pagenum = 0;
}
async initDesc(): Promise<void> {
if (this.desc !== undefined) return;
const zip = await readZip(this.path);
2024-04-03 21:46:18 +09:00
const entries = await zip.reader.getEntries();
this.pagenum = entries.filter((x) => ImageExt.includes(extname(x.filename))).length;
const entry = entries.find(x=> x.filename === "desc.json");
2024-03-26 23:58:26 +09:00
if (entry === undefined) {
return;
}
2024-04-03 21:46:18 +09:00
if (entry.getData === undefined) {
throw new Error("entry.getData is undefined");
}
const textWriter = new TextWriter();
const data = (await entry.getData(textWriter));
2024-03-26 23:58:26 +09:00
this.desc = JSON.parse(data);
if (this.desc === undefined) {
throw new Error(`JSON.parse is returning undefined. ${this.path} desc.json format error`);
}
}
async createDocumentBody(): Promise<DocumentBody> {
await this.initDesc();
const basebody = await super.createDocumentBody();
this.desc?.title;
if (this.desc === undefined) {
return basebody;
}
let tags: string[] = this.desc.tags ?? [];
tags = tags.concat(this.desc.artist?.map((x) => `artist:${x}`) ?? []);
tags = tags.concat(this.desc.character?.map((x) => `character:${x}`) ?? []);
tags = tags.concat(this.desc.group?.map((x) => `group:${x}`) ?? []);
tags = tags.concat(this.desc.series?.map((x) => `series:${x}`) ?? []);
2024-03-29 00:19:36 +09:00
const type = Array.isArray(this.desc.type) ? this.desc.type[0] : this.desc.type;
2024-03-26 23:58:26 +09:00
tags.push(`type:${type}`);
return {
...basebody,
title: this.desc.title,
additional: {
page: this.pagenum,
},
tags: tags,
};
}
}
registerContentReferrer(ComicReferrer);