Manga downloader for comic-days.com and other sites using the same reader
// ==UserScript== // @name ComicDaysDownloader // @namespace https://github.com/Timesient/manga-download-scripts // @version 1.0 // @license GPL-3.0 // @author Timesient // @description Manga downloader for comic-days.com and other sites using the same reader // @icon https://comic-days.com/images/favicon.ico // @homepageURL https://greasyfork.org/scripts/451861-comicdaysdownloader // @supportURL https://github.com/Timesient/manga-download-scripts/issues // @match https://comic-days.com/*/* // @match https://shonenjumpplus.com/*/* // @match https://kuragebunch.com/*/* // @match https://www.sunday-webry.com/*/* // @match https://comicbushi-web.com/*/* // @match https://comic-growl.com/*/* // @match https://tonarinoyj.jp/*/* // @match https://comic-gardo.com/*/* // @match https://pocket.shonenmagazine.com/*/* // @match https://comic-zenon.com/*/* // @match https://comic-trail.com/*/* // @match https://comic-action.com/*/* // @match https://magcomi.com/*/* // @match https://viewer.heros-web.com/*/* // @match https://feelweb.jp/*/* // @match https://comicborder.com/*/* // @match https://comic-ogyaaa.com/*/* // @match https://comic-earthstar.com/*/* // @match https://comic-seasons.com/*/* // @require https://unpkg.com/[email protected]/dist/axios.min.js // @require https://unpkg.com/[email protected]/dist/jszip.min.js // @require https://unpkg.com/[email protected]/dist/FileSaver.min.js // @require https://update.greasyfork.org/scripts/451810/1398192/ImageDownloaderLib.js // @grant GM_info // @grant GM_xmlhttpRequest // ==/UserScript== (async function (axios, JSZip, saveAs, ImageDownloader) { 'use strict'; // reload page when enter or leave chapter const re = new RegExp(`${window.location.origin}/.*/.*`); const oldHref = window.location.href; const timer = setInterval(() => { const newHref = window.location.href; if (newHref === oldHref) return; if (re.test(newHref) || re.test(oldHref)) { clearInterval(timer); window.location.reload(); } }, 200); // return if not reading chapter now if (!re.test(oldHref)) return; // get JSON data of episode const jsonData = await new Promise(resolve => { GM_xmlhttpRequest({ method: 'GET', url: window.location.origin + window.location.pathname, responseType: 'text', headers: { 'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1' }, onload: res => { const parser = new DOMParser(); const dom = parser.parseFromString(res.response, 'text/html'); resolve(JSON.parse(dom.querySelector('#episode-json').dataset.value)); } }); }); // get url of images and title const imageURLs = jsonData.readableProduct.pageStructure.pages.filter(item => item.src).map(item => item.src); const title = jsonData.readableProduct.title; // setup ImageDownloader ImageDownloader.init({ maxImageAmount: imageURLs.length, getImagePromises, title }); // collect promises of image function getImagePromises(startNum, endNum) { return imageURLs .slice(startNum - 1, endNum) .map(url => axios.get(url, { responseType: 'arraybuffer' }) .then(res => res.data) .then(ImageDownloader.fulfillHandler) .catch(ImageDownloader.rejectHandler) ); } })(axios, JSZip, saveAs, ImageDownloader);