NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name bookree.org downloader // @namespace alxspb // @version 0.1 // @description bookree.org zip downloader // @author alxspb // @copyright 2020, alxspb (https://openuserjs.org/users/alxspb) // @license MIT // @match *://bookree.org/reader* // @require https://raw.githubusercontent.com/Stuk/jszip/master/dist/jszip.min.js // @require https://raw.githubusercontent.com/Stuk/jszip-utils/master/dist/jszip-utils.min.js // @require https://raw.githubusercontent.com/eligrey/FileSaver.js/master/dist/FileSaver.min.js // @grant none // ==/UserScript== let pbbg = null; let pb = null; function getBookName() { var name_block = document.querySelector("#srch_wrd"); if (name_block === null) { alert('name_block === null'); return 'unknown'; } return name_block.textContent.match(/"(.+?)"/)[1]; } function getPages() { let res = []; let pages = document.querySelector("#pagenum"); if (pages === null) { alert('pages === null'); } for (let i = 0; i < pages.length; ++i) { res.push(pages[i].text); } return res; } function setProgress(cur, total) { let per = 100.0 * cur / total; pbbg.style.visibility = 'visible'; pb.style.width = `${per}%`; pb.innerHTML = `${cur}/${total}`; } function getImageLinkConverter() { let page_img = document.querySelector("#page_image"); if (page_img === null) { alert('page_img === null'); return; } let linkMatch = page_img.src.match(/(.*=).*(\..*)$/); return function(page) { return linkMatch[1] + page + linkMatch[2]; }; } function getReaderLinkConverter() { let page_next = document.querySelector("#iresult2 > div.page_nav > div.pages_next > a"); if (page_next === null) { alert('page_next === null'); return; } let url = page_next.href.match(/(.*=).*/)[1]; return function(page) { return url + page; }; } function getFilename(url) { return url.match(/^.*=(.*\..*)$/)[1]; } function download() { let pages = getPages(); let pagesLen = pages.length; let getReaderLink = getReaderLinkConverter(); let getImageLink = getImageLinkConverter(); let i = 0; setProgress(i, pagesLen); let zip = new JSZip(); (function proceed_page() { $.get(getReaderLink(pages[i]), function page_loaded(d) { let url = getImageLink(pages[i]); JSZipUtils.getBinaryContent(url, function (err, data) { if (err) { console.log(`error: ${err}`); proceed_page(); return; } zip.file(getFilename(url), data, { binary: true }); setProgress(i++, pagesLen); //console.log(`page[${i}/${pages.length}]`); if (i >= pages.length) { zip.generateAsync({ type: 'blob' }).then(function(content) { saveAs(content, `${getBookName()}.zip`); }); } else { setTimeout(proceed_page()); } }); }); })(); } function createButton() { var btn = document.createElement("input"); btn.type = 'button'; btn.value = "Download Book"; btn.onclick = download; return btn; } function createProgressBar() { pbbg = document.createElement("div"); pbbg.id = 'download_progress_bg'; pbbg.style = 'width: 100%; background-color: grey; visibility: hidden;'; pb = document.createElement("div"); pb.id = 'download_progress'; pb.style = 'width: 0%; height: 25px; background-color: #4CAF50; text-align: center; line-height: 25px; color: white;'; pbbg.appendChild(pb); return pbbg; } (function() { 'use strict'; var navigationDiv = document.querySelector("#iresult2 > div.page_nav"); if (navigationDiv === null) { return; } navigationDiv.appendChild(createButton()); navigationDiv.appendChild(createProgressBar()); })();