72 lines
2.3 KiB
TypeScript
72 lines
2.3 KiB
TypeScript
import { extname } from "node:path";
|
|
import type { DocumentBody } from "../model/doc";
|
|
import { readZip } from "../util/zipwrap";
|
|
import { type ContentConstructOption, createDefaultClass, registerContentReferrer } from "./file";
|
|
import { TextWriter } from "@zip.js/zip.js";
|
|
|
|
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);
|
|
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");
|
|
if (entry === undefined) {
|
|
return;
|
|
}
|
|
if (entry.getData === undefined) {
|
|
throw new Error("entry.getData is undefined");
|
|
}
|
|
const textWriter = new TextWriter();
|
|
const data = (await entry.getData(textWriter));
|
|
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}`) ?? []);
|
|
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);
|