diff --git a/src/content/file.ts b/src/content/file.ts index 8339c59..bad6edc 100644 --- a/src/content/file.ts +++ b/src/content/file.ts @@ -15,10 +15,7 @@ export interface ContentFile{ readonly type: string; } export type ContentConstructOption = { - hash: string, - tags: string[], - title: string, - additional: JSONMap + hash: string } type ContentFileConstructor = (new (path:string,option?:ContentConstructOption) => ContentFile)&{content_type:string}; export const createDefaultClass = (type:string):ContentFileConstructor=>{ @@ -41,16 +38,13 @@ export const createDefaultClass = (type:string):ContentFileConstructor=>{ content_type: cons.content_type, filename: base, tags: [], - content_hash: await this.getHash(), + content_hash: this.hash || await this.getHash(), } as DocumentBody; return ret; } get type():string{ return cons.content_type; } - async getDesc(): Promise { - return null; - } async getHash():Promise{ if(this.hash !== undefined) return this.hash; const stat = await promises.stat(this.path); diff --git a/src/content/manga.ts b/src/content/manga.ts index f01e2d5..023ae0a 100644 --- a/src/content/manga.ts +++ b/src/content/manga.ts @@ -1,26 +1,65 @@ import {ContentFile, createDefaultClass,registerContentReferrer, ContentConstructOption} from './file'; import {readZip,createReadStreamFromZip, readAllFromZip} from '../util/zipwrap'; +import { DocumentBody } from '../model/doc'; +import {extname} from 'path'; + +type MangaType = "doujinshi"|"artist cg"|"manga"|"western"; +interface MangaDesc{ + title:string, + artist?:string[], + group?:string[], + series?:string[], + type:MangaType|[MangaType], + character?:string[], + tags?:string[] +} +const ImageExt = ['.gif', '.png', '.jpeg', '.bmp', '.webp', '.jpg']; export class MangaReferrer extends createDefaultClass("manga"){ - desc: object|null|undefined; - additional: object| undefined; + desc: MangaDesc|undefined; + pagenum: number; + additional: ContentConstructOption| undefined; constructor(path:string,option?:ContentConstructOption){ super(path); this.additional = option; + this.pagenum = 0; } - async getDesc(){ - if(this.desc !== undefined){ - return this.desc; - } + async initDesc():Promise{ + if(this.desc !== undefined) return; const zip = await readZip(this.path); - const entry = zip.entry("desc.json"); + const entries = zip.entries(); + this.pagenum = Object.keys(entries).filter(x=>ImageExt.includes(extname(x))).length; + const entry = entries["desc.json"]; if(entry === undefined){ - this.desc = null; - return this.desc; + 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"); - return this.desc; + 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 = this.desc.type instanceof Array ? this.desc.type[0]: this.desc.type; + tags.push(`type:${type}`); + return { + ...basebody, + title:this.desc.title, + additional:{ + page:this.pagenum + }, + tags:tags + }; } }; registerContentReferrer(MangaReferrer); \ No newline at end of file