UNPKG

comic-book-dl

Version:
145 lines (144 loc) 5.7 kB
import path from 'node:path'; import pLimit from 'p-limit'; import ProgressBar from './lib/ProgressBar.js'; import { existsMkdir } from './utils/index.js'; import { matchParse } from './lib/parse/index.js'; import { writeBookInfoFile } from './lib/download.js'; export async function run(config, hooks) { const match = matchParse(config.targetUrl); if (!match) { if (hooks.parseErr) hooks.parseErr(); return; } const { preHandleUrl, getInstance } = match; if (typeof preHandleUrl === 'function') { config.targetUrl = preHandleUrl(config.targetUrl); } const parseInstance = getInstance(config.targetUrl); const bookInfo = await parseInstance.parseBookInfo(); if (!bookInfo) { if (hooks.parseErr) hooks.parseErr(); return; } const bookName = bookInfo.name; const bookDistPath = path.resolve(config.bookPath, bookInfo.pathName); existsMkdir(bookDistPath); const total = bookInfo.chapters.length; const progressBar = new ProgressBar(bookDistPath, total, config.ignoreConsole); await progressBar.init(); if (progressBar.curr === total) { if (hooks.success) hooks.success(bookName, bookDistPath, null); return; } let chaptersList = bookInfo.chapters; if (config.userConfig?.ignore) { const ignoreInfo = config.userConfig?.ignore.find(item => item.name === bookName); if (ignoreInfo) { const ignoreChapter = ignoreInfo.chapter ?? []; chaptersList = chaptersList.filter(chaptersItem => { return !ignoreChapter.includes(chaptersItem.name); }); if (progressBar.curr === total - ignoreChapter.length) { if (hooks.success) { progressBar.bar?.stop(); hooks.success(bookName, bookDistPath, null); } return; } } } if (hooks.start) hooks.start(bookName); if (progressBar.isDownloadInterrupted) { if (hooks.downloadInterrupted) hooks?.downloadInterrupted(); const updateProgressInfo = []; chaptersList = chaptersList.filter((chaptersItem) => { return !progressBar.progressInfo.some(item => { try { let isSameHref = item.href === chaptersItem.href; const isUrlReg = /(http|https):\/\//; if (!isSameHref && isUrlReg.test(item.href) && isUrlReg.test(chaptersItem.href)) { isSameHref = new URL(item.href).pathname === new URL(chaptersItem.href).pathname; } const isSameName = item.rawName == chaptersItem.rawName; if (isSameHref && isSameName) { chaptersItem.imageList = item.imageList; chaptersItem.imageListPath = item.imageListPath; updateProgressInfo.push(item); } return isSameHref && isSameName; } catch (e) { return false; } }); }); progressBar.resetProgressInfo(updateProgressInfo); } const LIMIT_MAX = 6; const limit = pLimit(LIMIT_MAX); const errorList = []; const promiseList = chaptersList.map(item => { return limit(async () => { const chaptersItemPath = `${bookDistPath}/chapters/${item.name}`; existsMkdir(chaptersItemPath); let getImageListSuccess = true; const imageList = await parseInstance.getImgList(item.href) .catch(() => { getImageListSuccess = false; errorList.push({ bookName, chapter: item }); return []; }); let imageListPath = []; const curBar = progressBar.multiBarCreate({ total: imageList.length, file: `下载「${item.name}」中的图片...` }); let isAllSuccess = true; imageListPath = await parseInstance.saveImgList(chaptersItemPath, imageList, (imgUrl, isSuccess) => { if (!isSuccess) { isAllSuccess = false; errorList.push({ bookName, imgUrl, chapter: item }); } progressBar.multiBarUpdate(curBar); }); imageListPath = imageListPath.map((itemPath) => { return `chapters/${item.name}/${itemPath}`; }); item.imageList = imageList; item.imageListPath = imageListPath; progressBar.multiBarRemove(curBar); await progressBar.updateProgress({ name: item.name, rawName: item.rawName, path: chaptersItemPath, href: item.href, index: item.index, imageList, imageListPath }, isAllSuccess && getImageListSuccess); return isAllSuccess && getImageListSuccess; }); }); const isAllSuccess = await Promise.all(promiseList); await writeBookInfoFile(bookInfo, bookDistPath, parseInstance); if (errorList.length > 0) { if (hooks.error) hooks.error(bookName, chaptersList, errorList); } else if (progressBar.curr === total && isAllSuccess) { if (hooks.success) hooks.success(bookName, bookDistPath, chaptersList); } }