// ==UserScript==
// @name Zelluloza Dumper
// @version 0.5
// @description Сохраняет фрагмент или все фрагменты книги, доступные для чтения в формате fb2. Книги защищенные максимальной защитой сохранет в виде картинок в pdf или fb2
// @author MadDAD
// @require https://greasyfork.org/scripts/15924-jspdf/code/jsPDF.js?version=99137
// @require https://greasyfork.org/scripts/2350-filesaver-js/code/filesaverjs.js?version=6255
// @include https://zelluloza.ru/books/*
// @namespace https://greasyfork.org/users/38856
// ==/UserScript==
//*************************************
//Asinc image loader
function ImageLoader(images, callback)
{
// store the call-back
this.callback = callback;
// initialize internal state.
this.nLoaded = 0;
this.nProcessed = 0;
this.aImages = new Array();
// record the number of images.
this.nImages = images.length;
// for each image, call preload()
for (var i = 0; i < images.length; i++)
this.preload(images[i]);
}
ImageLoader.prototype.preload = function (image)
{
// create new Image object and add to array
var oImage = new Image();
this.aImages.push(oImage);
// set up event handlers for the Image object
oImage.onload = ImageLoader.prototype.onload;
oImage.onerror = ImageLoader.prototype.onerror;
oImage.onabort = ImageLoader.prototype.onabort;
// assign pointer back to this.
oImage.oImageLoader = this;
oImage.bLoaded = false;
oImage._src = image;
// assign the .src property of the Image object
oImage.src = image;
};
ImageLoader.prototype.onComplete = function ()
{
this.nProcessed++;
my_getbyid("bookpg").innerHTML = 'Загружено страниц: ' + this.nProcessed + ' из ' + this.nImages;
if (this.nProcessed == this.nImages)
{
this.callback(this.aImages, this.nLoaded);
}
};
ImageLoader.prototype.onload = function ()
{
this.bLoaded = true;
this.oImageLoader.nLoaded++;
this.oImageLoader.onComplete();
};
ImageLoader.prototype.onerror = function ()
{
this.bError = true;
this.oImageLoader.onComplete();
};
ImageLoader.prototype.onabort = function ()
{
this.bAbort = true;
this.oImageLoader.onComplete();
};
//*************************************
function ParceUserToken(aScripts)
{
for (var i = 0; i < aScripts.length; i++)
{
var CurrentScript = aScripts[i];
if(CurrentScript.text !== "")
if (CurrentScript.text.indexOf('getbook') > 0)
{
UserToken = eval(CurrentScript.text.split(';')[1].split(',')[5]);
if (UserToken !== undefined)
return UserToken;
}
}
}
function GetUserToken()
{
var UserToken = ParceUserToken(document.getElementsByTagName("script"));
if (UserToken === undefined)
{
var URL = document.getElementsByClassName("taglnk2");
for (var i = 0; i < URL.length; i++)
{
var xmlhttp = getXmlHttp();
xmlhttp.open("GET", URL[i], false);
if (xmlhttp.readyState == 1)
{
xmlhttp.setRequestHeader("Content-Type", "text/html");
xmlhttp.send();
}
if (xmlhttp.status != 200)
{
alert(xmlhttp.status + ': ' + xmlhttp.statusText); // пример вывода: 404: Not Found
}
else
{
var doc = new DOMParser().parseFromString(xmlhttp.responseText, "text/html");
UserToken = ParceUserToken(doc.getElementsByTagName("script"));
if (UserToken !== undefined)
return UserToken;
}
}
}
return UserToken;
}
function MyAjax(obj, notused, par1, par2, par3, par4, append)
{
var xmlhttp = getXmlHttp();
var params = "op=" + encodeURIComponent(par1) + "&par1=" + encodeURIComponent(par2) + "&par2=" + encodeURIComponent(par3) + "&par4=" + encodeURIComponent(par4);
ajaxDone = 0;
if (xmlhttp.readyState == 0)
{
xmlhttp.open("POST", "/ajaxcall/", false);
}
if (xmlhttp.readyState == 1)
{
xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xmlhttp.send(params);
}
if (xmlhttp.readyState == 4)
{
if (xmlhttp.status == 200)
{
ajaxDone = 1;
if (obj != "")
{
var str = xmlhttp.responseText;
if (par1 == "getbook")
{
chp = str.split("<END>");
return chp;
}
}
}
}
}
function AllBook(book)
{
//var MaxProtection = my_getbyid("protected1").src !== '';
var MaxProtection = false;
if (!MaxProtection)
{
var pageHtml = "";
var BookId = document.getElementById("gotobook").value;
var PartId = document.getElementsByClassName("taglnk2")[0].href.split('/')[4];
var UserToken = GetUserToken();
var BookTitle = document.getElementsByClassName("booklnk4")[1].childNodes[0].innerHTML;
var PartTitle = document.getElementsByClassName("taglnk2")[0].text;
var series = "";
var res = new RegExp('.*Серия: (.*)$', 'm').exec(document.getElementsByClassName('serie')[1].outerText);
if (res !== null)
series = res[1];
pageHtml = '<?xml version="1.0" encoding="utf-8"?><FictionBook xmlns="http://www.gribuser.ru/xml/fictionbook/2.0" xmlns:xlink="http://www.w3.org/1999/xlink">';
pageHtml += '<description><title-info><genre/><author><first-name>' + document.getElementsByClassName("txt")[5].text + '</first-name><last-name/></author>';
pageHtml += '<book-title>' + BookTitle + '</book-title>';
pageHtml += '<annotation><p>' + document.getElementsByTagName("meta", "")[4].content + '</p></annotation>';
pageHtml += '<lang>ru</lang><src-lang>ru</src-lang>';
pageHtml += '<sequence name="' + series + '" number="" />';
pageHtml += '</title-info><document-info><author><nickname/><email/></author><version>2.0</version></document-info>';
pageHtml += '<publish-info><book-name>' + BookTitle + '</book-name></publish-info></description>';
pageHtml += '<body>';
pageHtml += '<title>';
pageHtml += '<p>' + BookTitle + '</p>';
pageHtml += '</title>';
//var chp = new Array();
var links = document.getElementsByClassName("taglnk2");
for (var i = 0; i < links.length; i++)
{
book.childNodes[0].innerHTML = BookTitle + "(" + (i / links.length * 100) + "% загружено...)";
var item = links[i];
PartId = item.href.split('/')[5];
PartTitle = item.text;
var chp = MyAjax('booktext', '', 'getbook', BookId, PartId + ':0.0.1::0', UserToken, 0);
pageHtml += '<section><title><p>' + PartTitle + '</p></title>';
var Z = chp[0].split(/\n/);
for (var j in Z)
{
pageHtml += '<p>' + DS('', Z[j]).replace('\r', '').replace('\n', '').replace('[ctr][gry]- Конец фрагмента -[/][/]', '') + '</p>\n';
}
pageHtml += '</section>';
};
pageHtml += '</body></FictionBook>';
var file = new File([pageHtml], BookTitle + '.fb2',
{
type : "text/plain;charset=utf-8"
}
);
saveAs(file, BookTitle + '.fb2');
}
}
function unprotect(text, format)
{
var pageHtml = null;
if (format === undefined)
format = "fb2";
if (document.location.hostname == "zelluloza.ru")
{
var BookId = document.getElementById("gotobook").value;
var PartId = document.getElementsByClassName("taglnk2")[0].href.split('/')[4];
var UserToken = GetUserToken();
var BookTitle = document.getElementsByClassName("booklnk4")[1].childNodes[0].innerHTML;
var PartTitle = document.getElementsByClassName("taglnk2")[0].text;
if (document.getElementsByClassName("booklnk4"))
{
var series = "";
var res = new RegExp('.*Серия: (.*)$', 'm').exec(document.getElementsByClassName('serie')[1].outerText);
if (res !== null)
series = res[1];
pageHtml = '<?xml version="1.0" encoding="utf-8"?><FictionBook xmlns="http://www.gribuser.ru/xml/fictionbook/2.0" xmlns:xlink="http://www.w3.org/1999/xlink">';
pageHtml += '<description><title-info><genre/><author><first-name>' + document.getElementsByClassName("txt")[5].text + '</first-name><last-name/></author>';
pageHtml += '<book-title>' + BookTitle + '</book-title>';
pageHtml += '<annotation><p>' + document.getElementsByTagName("meta", "")[4].content + '</p></annotation>';
pageHtml += '<lang>ru</lang><src-lang>ru</src-lang>';
pageHtml += '<sequence name="' + series + '" number="" />';
pageHtml += '</title-info><document-info><author><nickname/><email/></author><version>2.0</version></document-info>';
pageHtml += '<publish-info><book-name>' + BookTitle + '</book-name></publish-info></description>';
pageHtml += '<body>';
pageHtml += '<title>';
pageHtml += '<p>' + BookTitle + '</p>';
pageHtml += '</title>';
pageHtml += '<section><title><p>' + PartTitle + '</p></title>';
}
var MaxProtection = my_getbyid("protected1").src !== '';
if (!MaxProtection)
{
var Z = chp[0].split(/\n/);
for (var j in Z)
{
pageHtml += '<p>' + DS('', Z[j]).replace('\r', '').replace('\n', '').replace('[ctr][gry]- Конец фрагмента -[/][/]', '') + '</p>\n';
}
pageHtml += '</section></body></FictionBook>';
var file = new File([pageHtml], BookTitle + '.fb2',
{
type : "text/plain;charset=utf-8"
}
);
saveAs(file, BookTitle + '(' + PartTitle + ').fb2');
}
else
{
var pages = new Array();
oCanvas = my_getbyid("cnv1");
oCtx = oCanvas.getContext("2d");
var page = 0;
var loaded = false;
for (page = 0; page <= maxpg; page += pagessize)
{
pages[page] = "/get/" + base64_encode(bookid + ":" + chapterid + ":" + pagessize + ":" + page);
}
var binaryImages = "";
var pp = new ImageLoader(pages, function (aImages, nLoaded)
{
if (format == "fb2")
{
aImages.forEach(function (item, i, aImages)
{
if (item.bLoaded)
{
oCtx.drawImage(item, 0, 0);
pageHtml += '<image xlink:href="#page_' + i + '.jpg"/>\n';
binaryImages += '<binary content-type="image/png" id="page_' + i + '.jpg">\n' + oCanvas.toDataURL("image/png", 1.0).replace('data:image/png;base64,', '') + '\n</binary>';
}
}
);
pageHtml += '</section></body>';
pageHtml += binaryImages;
pageHtml += '</FictionBook>';
var file = new File([pageHtml], BookTitle + '(' + PartTitle + ').fb2',
{
type : "text/plain;charset=utf-8"
}
);
saveAs(file, BookTitle + '(' + PartTitle + ').fb2');
}
else
{
var pdf = new jsPDF('p', 'pt', 'b5', 1);
pdf.internal.pageSize = {height:480, widht:550};
var pdfInternals = pdf.internal;
var pdfPageSize = pdfInternals.pageSize;
var pdfPageWidth = pdfPageSize.width;
var pdfPageHeight = pdfPageSize.height;
var flags = {noBOM:true, autoencode:true};
pdf.text(BookTitle, pdfPageWidth / 3, 20, flags);
pdf.text(PartTitle, pdfPageWidth / 3, 40, flags);
aImages.forEach(function (item, i, aImages){
if (item.bLoaded)
{
oCtx.drawImage(item, 0, 0);
var img = oCanvas.toDataURL("image/png", 1.0);
pdf.addPage();
pdf.addImage(img, "png", 10, 70, 0, 0);
}
});
pdf.save(BookTitle + '(' + PartTitle + ').pdf');
}
});
}
}
}
unsafeWindow.wait_for_text = function ()
{
var text = document.getElementById("bookpgm");
if (null === text)
{
var book = document.getElementsByClassName("booklnk4")[1];
if (null === book)
alert('No copyable text found!');
else
{
var button = document.createElement("BUTTON");
button.innerHTML = 'Get fb2';
button.addEventListener('click', function ()
{
AllBook(book);
}, true);
book.parentNode.insertBefore(button, book);
}
return;
}
if (text.innerHTML.length > 100)
{
var button = document.createElement("BUTTON");
button.innerHTML = 'Get fb2';
button.addEventListener('click', function ()
{
unprotect(text);
}, true);
text.parentNode.insertBefore(button, text);
var MaxProtection = my_getbyid("protected1").src !== '';
if (MaxProtection)
{
var button2 = document.createElement("BUTTON");
button2.innerHTML = 'Get pdf';
button2.addEventListener('click', function ()
{
unprotect(text, "pdf");
}, true);
text.parentNode.insertBefore(button2, text);
}
}
else
window.setTimeout("wait_for_text()", 1000);
};
window.setTimeout("wait_for_text()", 1000);