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());
})();