Zelluloza Dumper

Сохраняет фрагмент или все фрагменты книги, доступные для чтения в формате fb2. Книги защищенные максимальной защитой сохранет в виде картинок в pdf или fb2

当前为 2016-08-11 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

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