alxspb / bookree.org downloader

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