Zelluloza Dumper

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

目前為 2016-08-11 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 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);