import { extname } from "node:path"; import type { DocumentBody } from "../model/doc"; import { readAllFromZip, readZip } from "../util/zipwrap"; import { type ContentConstructOption, createDefaultClass, registerContentReferrer } from "./file"; 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 { if (this.desc !== undefined) return; const zip = await readZip(this.path); const entries = await zip.entries(); this.pagenum = Object.keys(entries).filter((x) => ImageExt.includes(extname(x))).length; const entry = entries["desc.json"]; if (entry === undefined) { return; } const data = (await readAllFromZip(zip, entry)).toString("utf-8"); 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 { 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}`) ?? []); const type = Array.isArray(this.desc.type) ? this.desc.type[0] : this.desc.type; tags.push(`type:${type}`); return { ...basebody, title: this.desc.title, additional: { page: this.pagenum, }, tags: tags, }; } } registerContentReferrer(ComicReferrer);