/// /** * MIT License * Copyright (c) 2023 Yan */ import ComicDownloader from '../../core'; export default class GanmaDownloader extends ComicDownloader { static readonly siteName = 'ganma'; static canHandleUrl(url: string): boolean { return /ganma\.jp/.test(url); } static urlCompletion(shorthandUrl: string): string { return `https://ganma.jp/${shorthandUrl}`; } getMangaId(url: string): string | undefined { // https://ganma.jp/otonanokoi/70427cf0-9abf-11ed-a01f-2283d0206510/2 return new URL(url).pathname.split('/')[1]; } getChapterId(url: string): string | undefined { return new URL(url).pathname.split('/')[2]; } protected detectBaseUrl(url: string): string { const baseURL = new URL(url).origin; this.axios.defaults.baseURL = baseURL; return baseURL; } async getSerieInfo(url: string): Promise { this.axios.defaults.headers['x-from'] = this.detectBaseUrl(url); const mangaId = this.getMangaId(url); if (!mangaId) { throw new Error('Invalid URL.'); } const res = await this.axios.get( `/api/1.0/magazines/web/${mangaId}`, ); const data = res?.data?.root ?? {}; const title = data.title; const count = data.items?.length; const summary = `${data.overview}\n${data.description}\n${data.lead}`; const info: ComicInfo = { Manga: 'YesAndRightToLeft', Serie: title, Count: count, Summary: summary, Web: url, Location: 'Japan', Penciller: data.author?.penName, Status: data.flags?.isFinish ? 'End' : 'Ongoing', }; const chapters: Chapter[] = data.items?.map((e, i) => ({ index: i, name: `${e.title} ${e.subtitle ?? ''}`, uri: url, options: { chapterId: e?.id, pageUrls: e?.page?.files?.map( file => `${e?.page?.baseUrl}${file}?${e?.page?.token}`, ), }, })); return { title, chapters, info, }; } protected async getImageList( url: string, options: Record = {}, ): Promise<(string | null)[]> { if (options.pageUrls) { return options?.pageUrls ?? null; } const serieInfo = await this.getSerieInfo(url); const chapterId = this.getChapterId(url); if (!chapterId) { throw new Error('Invalid URL.'); } const chapter = serieInfo.chapters.find( e => e?.options?.chapterId === chapterId, ); if (!chapter) { throw new Error('Chapter not found.'); } return chapter?.options?.pageUrls ?? null; } }