UNPKG

comic-book-dl

Version:
154 lines (153 loc) 5.82 kB
import got from '../../../../node_modules/got/dist/source/index.js'; import { load } from 'cheerio'; import pLimit from 'p-limit'; import { Base } from '../../../lib/parse/base/index.js'; import { fixPathName, isHasHost, sleep, toReversed } from '../../../utils/index.js'; export class Ikuku extends Base { constructor() { super(...arguments); this.type = 'Ikuku'; } async parseBookInfo() { const url = this.bookUrl; const rawUrl = url; let response; try { response = await got.get(url, this.genReqOptions()); } catch (e) { return false; } if (!response || response.statusCode !== 200) { return false; } const decoder = new TextDecoder('gbk'); const $ = load(decoder.decode(response.rawBody)); const name = $('#comicName').text().trim(); const desc = $('.txtDesc').text().trim(); const author = $('.Introduct_Sub .txtItme:nth-child(1)').text().trim(); const coverUrl = $('#Cover img').attr('src')?.trim() ?? ''; let chapters = []; const chaptersEl = $('#list li'); toReversed(chaptersEl.toArray()).forEach((el, index) => { const target = $(el); const aEl = target.find('a'); const name = aEl.text().trim(); const href = aEl.attr('href')?.trim() ?? ''; chapters.push({ name: `${index}_${fixPathName(name)}`, rawName: name, href, imageList: [], imageListPath: [], index }); }); if (!name || chapters.length === 0) { return false; } chapters = chapters.map((item, index) => { const newItem = { ...item }; if (index !== 0) { newItem.preChapter = { name: chapters[index - 1].name, rawName: chapters[index - 1].rawName, href: chapters[index - 1].href, index: chapters[index - 1].index }; } if (index !== chapters.length - 1) { newItem.nextChapter = { name: chapters[index + 1].name, rawName: chapters[index + 1].rawName, href: chapters[index + 1].href, index: chapters[index + 1].index }; } return newItem; }); return { name, pathName: fixPathName(name), author, desc, coverUrl, coverPath: '', chapters, url, language: '简体', rawUrl }; } async getImgList(chapterUrl) { const { origin } = new URL(this.bookUrl); const reqUrl = isHasHost(chapterUrl) ? chapterUrl : `${origin}${chapterUrl}`; const response = await got(reqUrl, this.genReqOptions()); const decoder = new TextDecoder('gbk'); const bodyStr = decoder.decode(response.rawBody); const reg = /document\.write\("<a href='(.*?)'><IMG SRC='(.*?)'>/g; const [, nextImgUrlPath, tempCurImgPath] = reg.exec(bodyStr) ?? []; if (!nextImgUrlPath || !tempCurImgPath) return []; const nextImgUrl = `${origin}${nextImgUrlPath}`; const isEnd = nextImgUrlPath.includes('exit'); const imgHostMap = {}; const scriptReg = /<script language='javascript' src='(.*?)'><\/script>/g; const scriptMap = bodyStr.match(scriptReg); let imgHostString = ''; if (Array.isArray(scriptMap)) { for (const item of scriptMap) { scriptReg.lastIndex = 0; const scriptUrl = scriptReg.exec(item)?.[1] ?? ''; if (!scriptUrl) continue; const response = await got.get(`${origin}${scriptUrl}`, this.genReqOptions()); imgHostString = imgHostString + '\n' + response.body; } } if (imgHostString) { const matchArr = imgHostString.match(/\{(.*?)='(.*?)';\}/g); matchArr?.forEach(item => { const [, key, value] = /\{(.*?)='(.*?)';\}/.exec(item) || []; if (key && value) { imgHostMap[key] = value; } }); } let curImgPath = tempCurImgPath; Object.keys(imgHostMap).forEach(hostKey => { const host = imgHostMap[hostKey]; curImgPath = curImgPath.replace(new RegExp('"\\+' + hostKey + '\\+"'), host); }); if (!curImgPath) return []; let imgList = [curImgPath]; if (!isEnd && nextImgUrl) { const nextImgList = await this.getImgList(nextImgUrl); imgList = imgList.concat(nextImgList); } return [...new Set(imgList)]; } async saveImgList(path, imgList, saveImgCallback) { const limit = pLimit(6); const promiseList = imgList.map((imgUrl, index) => limit(async () => { let isSuccess = true; let imgFileName = ''; try { imgFileName = await this.saveImg(path, imgUrl, String(index + 1)); } catch (err) { isSuccess = false; } if (typeof saveImgCallback === 'function') saveImgCallback(imgUrl, isSuccess); return imgFileName; })); return await Promise.all(promiseList); } async saveImg(path, imgUrl, fixFileName, fixSuffix) { await sleep(600); const res = await super.saveImg(path, imgUrl, fixFileName, fixSuffix); return res; } }