Zelluloza Dumper

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

  1. // ==UserScript==
  2. // @name Zelluloza Dumper
  3. // @version 0.7
  4. // @description Сохраняет фрагмент или все фрагменты книги, доступные для чтения в формате fb2. Книги защищенные максимальной защитой сохранет в виде картинок в pdf или fb2
  5. // @author MadDAD
  6. // @require https://greasyfork.org/scripts/15924-jspdf/code/jsPDF.js?version=99137
  7. // @require https://greasyfork.org/scripts/2350-filesaver-js/code/filesaverjs.js?version=6255
  8. // @include https://zelluloza.ru/books/*
  9. // @include https://zelluloza.ru/search/*
  10. // @namespace https://greasyfork.org/users/38856
  11. // ==/UserScript==
  12.  
  13. //*******************************************************************************************
  14. function $(id)
  15. {
  16. var result = document.getElementById(id);
  17.  
  18. if (result === null)
  19. {
  20. result = document.getElementsByClassName(id);
  21.  
  22. if (result === undefined)
  23. result = document.getElementsByTagName(id);
  24.  
  25. if (result === undefined)
  26. return null;
  27.  
  28. if (result.length == 1)
  29. return result[0];
  30. }
  31. else
  32. return result;
  33. }
  34.  
  35. //*******************************************************************************************
  36. function retrieveWindowVariables(variables)
  37. {
  38. var ret = {};
  39.  
  40. var scriptContent = "";
  41. for (var i = 0; i < variables.length; i++)
  42. {
  43. var currVariable = variables[i];
  44. scriptContent += "if (typeof " + currVariable + " !== 'undefined') document.body.attributes['tmp_" + currVariable + "'] = eval(" + currVariable + ");\n"
  45. }
  46.  
  47. var script = document.createElement('script');
  48. script.id = 'tmpScript';
  49. script.appendChild(document.createTextNode(scriptContent));
  50. (document.body || document.head || document.documentElement).appendChild(script);
  51.  
  52. for (var i = 0; i < variables.length; i++)
  53. {
  54. var currVariable = variables[i];
  55. ret[currVariable] = document.body.attributes[currVariable];
  56. document.body.removeAttribute(currVariable);
  57. }
  58.  
  59. document.getElementById("tmpScript").remove();
  60.  
  61. return ret;
  62. }
  63.  
  64. //***************************************
  65. function getXmlHttp()
  66. {
  67. var a;
  68. try
  69. {
  70. a = new ActiveXObject("Msxml2.XMLHTTP")
  71. }
  72. catch (d)
  73. {
  74. try
  75. {
  76. a = new ActiveXObject("Microsoft.XMLHTTP")
  77. }
  78. catch (b)
  79. {
  80. a = false
  81. }
  82. }
  83. if (!a && typeof XMLHttpRequest != "undefined")
  84. {
  85. a = new XMLHttpRequest()
  86. }
  87. return a
  88. }
  89.  
  90. //*************************************
  91. HTMLImageElement.prototype.getUrlData = function ()
  92. {
  93. var cnv = document.createElement("CANVAS");
  94. cnv.width = this.width;
  95. cnv.height = this.height;
  96. var cont = cnv.getContext("2d");
  97. cont.drawImage(this, 0, 0);
  98. return cnv.toDataURL('image/png', 0, 0);
  99. };
  100.  
  101. //Asinc image loader
  102. function ImageLoader(images, callback)
  103. {
  104. // store the call-back
  105. this.callback = callback;
  106. // initialize internal state.
  107. this.nLoaded = 0;
  108. this.nProcessed = 0;
  109. this.aImages = new Array();
  110. // record the number of images.
  111. this.nImages = images.length;
  112. // for each image, call preload()
  113. for (var i = 0; i < images.length; i++)
  114. this.preload(images[i]);
  115. }
  116.  
  117. ImageLoader.prototype.preload = function (image)
  118. {
  119. // create new Image object and add to array
  120. var oImage = new Image();
  121. this.aImages.push(oImage);
  122. // set up event handlers for the Image object
  123. oImage.onload = ImageLoader.prototype.onload;
  124. oImage.onerror = ImageLoader.prototype.onerror;
  125. oImage.onabort = ImageLoader.prototype.onabort;
  126. // assign pointer back to this.
  127. oImage.oImageLoader = this;
  128. oImage.bLoaded = false;
  129. oImage._src = image;
  130. // assign the .src property of the Image object
  131. oImage.src = image;
  132. };
  133.  
  134. ImageLoader.prototype.onComplete = function ()
  135. {
  136. this.nProcessed++;
  137. my_getbyid("bookpg").innerHTML = 'Загружено страниц: ' + this.nProcessed + ' из ' + this.nImages;
  138. if (this.nProcessed == this.nImages)
  139. {
  140. this.callback(this.aImages, this.nLoaded);
  141. }
  142. };
  143.  
  144. ImageLoader.prototype.onload = function ()
  145. {
  146. this.bLoaded = true;
  147. this.oImageLoader.nLoaded++;
  148. this.oImageLoader.onComplete();
  149. };
  150.  
  151. ImageLoader.prototype.onerror = function ()
  152. {
  153. this.bError = true;
  154. this.oImageLoader.onComplete();
  155. };
  156.  
  157. ImageLoader.prototype.onabort = function ()
  158. {
  159. this.bAbort = true;
  160. this.oImageLoader.onComplete();
  161. };
  162. //*************************************
  163.  
  164. function ParceUserToken(aScripts)
  165. {
  166. for (var i = 0; i < aScripts.length; i++)
  167. {
  168. var CurrentScript = aScripts[i];
  169. if (CurrentScript.text !== "")
  170. if (CurrentScript.text.indexOf('getbook') > 0)
  171.  
  172. {
  173. UserToken = eval(CurrentScript.text.split(';')[1].split(',')[5]);
  174. if (UserToken !== undefined)
  175. return UserToken;
  176. }
  177. }
  178. }
  179.  
  180. function getDoc(ref)
  181. {
  182. var xmlhttp = getXmlHttp();
  183. xmlhttp.open("GET", ref, false);
  184.  
  185. if (xmlhttp.readyState == 1)
  186. {
  187. xmlhttp.setRequestHeader("Content-Type", "text/html");
  188. xmlhttp.send();
  189. }
  190.  
  191. if (xmlhttp.status != 200)
  192. {
  193. alert(xmlhttp.status + ': ' + xmlhttp.statusText); // пример вывода: 404: Not Found
  194. }
  195. else
  196. {
  197. return new DOMParser().parseFromString(xmlhttp.responseText, "text/html");
  198. }
  199. }
  200.  
  201. function GetUserToken(dDoc)
  202. {
  203. if (dDoc === undefined)
  204. dDoc = document;
  205.  
  206. var UserToken = ParceUserToken(dDoc.getElementsByTagName("script"));
  207.  
  208. if (UserToken === undefined)
  209. {
  210. var URL = dDoc.getElementsByClassName("taglnk2");
  211. for (var i = 0; i < URL.length; i++)
  212. {
  213. UserToken = ParceUserToken(getDoc(URL[i].getAttribute("href")).getElementsByTagName("script"));
  214. if (UserToken !== undefined)
  215. return UserToken;
  216. }
  217.  
  218. }
  219.  
  220. return UserToken;
  221. }
  222.  
  223. //************************************* Асинхронный загрузчик глав
  224. function FragmentLoader(links, usertoken, callback, progressor)
  225. {
  226. this.callback = callback;
  227. this.nLoaded = 0;
  228. this.nProcessed = 0;
  229. this.bloaded = false;
  230. this.nFragments = links.length;
  231. this.usertoken = usertoken;
  232. this.aFragments = new Array();
  233. this.progressor = progressor;
  234. for (var i = 0; i < this.nFragments; i++)
  235. {
  236. this.load(links[i], i);
  237. }
  238. }
  239.  
  240. FragmentLoader.prototype.load = function (fragment, fnumber)
  241. {
  242. var xmlhttp = getXmlHttp();
  243. xmlhttp.oFragmentLoader = this;
  244.  
  245. var Chapter =
  246. {
  247. number : fnumber,
  248. name : fragment.childNodes[3].text,
  249. link : fragment.childNodes[3].getAttribute("href"),
  250. bookId : fragment.childNodes[3].getAttribute("href").split('/')[2],
  251. partId : fragment.childNodes[3].getAttribute("href").split('/')[3],
  252. text : '<p>Необходимо купить фрагмент</p>',
  253. needToBuy : fragment.childNodes[1].value.indexOf('Купить') != -1
  254. };
  255.  
  256. xmlhttp.Fragment = Chapter;
  257. //xmlhttp.onload = FragmentLoader.prototype.onload;
  258. xmlhttp.onreadystatechange = FragmentLoader.prototype.onload;
  259.  
  260. if (Chapter.needToBuy)
  261. {
  262. xmlhttp.onreadystatechange();
  263. return;
  264. }
  265.  
  266. var params = "op=" + encodeURIComponent('getbook') + "&par1=" + encodeURIComponent(Chapter.bookId) + "&par2=" + encodeURIComponent(Chapter.partId + ':0.0.1::0') + "&par4=" + encodeURIComponent(this.usertoken);
  267. if (xmlhttp.readyState == 0)
  268. {
  269. xmlhttp.open("POST", "/ajaxcall/", true);
  270. }
  271.  
  272. if (xmlhttp.readyState == 1)
  273. {
  274. xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  275. xmlhttp.send(params);
  276. }
  277.  
  278. };
  279.  
  280. FragmentLoader.prototype.onload = function ()
  281. {
  282.  
  283. if (this.Fragment.needToBuy)
  284. {
  285. this.oFragmentLoader.nLoaded++;
  286. this.oFragmentLoader.aFragments[this.Fragment.number] = this.Fragment;
  287. this.oFragmentLoader.onComplete();
  288. return;
  289. }
  290.  
  291. if (this.readyState == 4 && this.status == 200)
  292. {
  293. this.Fragment.text = "";
  294. var str = this.responseText.split("<END>")[0].split(/\n/);
  295. for (var j in str)
  296. {
  297. this.Fragment.text += '<p>' + DS('', str[j]).replace('\r', '').replace('[ctr][gry]- Конец фрагмента -[/][/]', '') + '</p>\n';
  298. }
  299. this.oFragmentLoader.nLoaded++;
  300. this.oFragmentLoader.aFragments[this.Fragment.number] = this.Fragment;
  301. this.oFragmentLoader.onComplete();
  302. }
  303. };
  304.  
  305. FragmentLoader.prototype.onerror = function ()
  306. {
  307. this.bError = true;
  308. this.Fragment.text = "<p>Ошибка загрузки фрагмента</p>";
  309. this.oFragmentLoader.aFragments.push(this.Fragment);
  310. this.oFragmentLoader.onComplete();
  311. };
  312.  
  313. FragmentLoader.prototype.onComplete = function ()
  314. {
  315. this.nProcessed++;
  316. this.progressor(this.nProcessed, this.nFragments);
  317. this.bloaded = this.nProcessed == this.nFragments;
  318.  
  319. if (this.bloaded)
  320. {
  321. this.callback(this.aFragments, this.nProcessed);
  322. }
  323. };
  324. //**************************************************************************************************************************************
  325.  
  326. function getGenre(doc)
  327. {
  328. if (doc === undefined)
  329. doc = document;
  330.  
  331. var genresList =
  332. {
  333. "Фантастика" : "sf",
  334. "ЛитРПГ" : "sf_etc",
  335. "Фэнтези" : "sf_fantasy",
  336. "Фантастический боевик" : "sf_action",
  337. "Ужасы" : "sf_horror",
  338. "Любовная фантастика" : "love_sf",
  339. "Альтернативная история" : "sf_history",
  340. "Социальная фантастика" : "sf_social",
  341. "Космическая фантастика" : "sf_space",
  342. "Юмористическая фантастика" : "sf_humor",
  343. "Детская фантастика" : "child_sf",
  344. "Попаданцы" : "popadanec",
  345. "Мистика" : "sf_mystic",
  346. "Городское фэнтези" : "sf_fantasy_city",
  347. "Детективная фантастика" : "sf_detective",
  348. "Героическая фантастика" : "sf_heroic",
  349. "Постапокалипсис" : "sf_postapocalyptic",
  350. "Киберпанк" : "sf_cyberpunk",
  351. "Эпическая фантастика" : "sf_epic",
  352. "Юмористическое фэнтези" : "humor_fantasy",
  353. "Космоопера" : "sf_space_opera",
  354. "Историческое фэнтези" : "historical_fantasy",
  355. "Сказочная фантастика" : "fairy_fantasy",
  356. "Технофэнтези" : "sf_technofantasy",
  357. "Ненаучная фантастика" : "nsf",
  358. "Ироническая фантастика" : "sf_irony",
  359. "Стимпанк" : "sf_stimpank",
  360. "Ироническое фэнтези" : "sf_fantasy_irony",
  361. "Готический роман" : "gothic_novel",
  362. "Современная проза" : "prose_contemporary",
  363. "Классическая проза" : "prose_classic",
  364. "Историческая проза" : "prose_history",
  365. "Русская классическая проза" : "prose_rus_classic",
  366. "Советская классическая проза" : "prose_su_classics",
  367. "Проза" : "prose",
  368. "Рассказ" : "short_story",
  369. "О войне" : "prose_military",
  370. "Контркультура" : "prose_counter",
  371. "Роман" : "roman",
  372. "Эссе, очерк, этюд, набросок" : "essay",
  373. "Повесть" : "great_story",
  374. "Магический реализм" : "prose_magic",
  375. "Эпистолярная проза" : "epistolary_fiction",
  376. "Афоризмы" : "aphorisms",
  377. "Новелла" : "story",
  378. "Антисоветская литература" : "dissident",
  379. "Семейный роман/Семейная сага" : "sagas",
  380. "Сентиментальная проза" : "prose_sentimental",
  381. "Эпопея" : "prose_epic",
  382. "Феерия" : "extravaganza",
  383. "История" : "sci_history",
  384. "Психология" : "sci_psychology",
  385. "Философия" : "sci_philosophy",
  386. "Технические науки" : "sci_tech",
  387. "Политика" : "sci_politics",
  388. "Литературоведение" : "sci_philology",
  389. "Культурология" : "sci_culture",
  390. "Научная литература" : "science",
  391. "Учебники" : "sci_textbook",
  392. "Медицина" : "sci_medicine",
  393. "Военная история" : "military_history",
  394. "Языкознание" : "sci_linguistic",
  395. "Религиоведение" : "sci_religion",
  396. "Юриспруденция" : "sci_juris",
  397. "Биология" : "sci_biology",
  398. "Математика" : "sci_math",
  399. "Педагогика" : "sci_pedagogy",
  400. "Физика" : "sci_phys",
  401. "Деловая литература" : "sci_business",
  402. "Астрономия и Космос" : "sci_cosmos",
  403. "Геология и география" : "sci_geo",
  404. "Альтернативная медицина" : "sci_medicine_alternative",
  405. "Экономика" : "sci_economy",
  406. "Обществознание" : "sci_social_studies",
  407. "Секс и семейная психология" : "psy_sex_and_family",
  408. "Иностранные языки" : "foreign_language",
  409. "Шпаргалки" : "sci_crib",
  410. "Химия" : "sci_chem",
  411. "Психотерапия и консультирование" : "psy_theraphy",
  412. "Детская психология" : "psy_childs",
  413. "Зоология" : "sci_zoo",
  414. "Ботаника" : "sci_botany",
  415. "Государство и право" : "sci_state",
  416. "Экология" : "sci_ecology",
  417. "Биохимия" : "sci_biochem",
  418. "Ветеринария" : "sci_veterinary",
  419. "Физическая химия" : "sci_physchem",
  420. "Биофизика" : "sci_biophys",
  421. "Органическая химия" : "sci_orgchem",
  422. "Аналитическая химия" : "sci_anachem",
  423. "Рефераты" : "sci_abstract",
  424. "Детективы" : "detective",
  425. "Триллер" : "thriller",
  426. "Классический детектив" : "det_classic",
  427. "Боевик" : "det_action",
  428. "Исторический детектив" : "det_history",
  429. "Полицейский детектив" : "det_police",
  430. "Криминальный детектив" : "det_crime",
  431. "Любовный детектив" : "love_detective",
  432. "Иронический детектив" : "det_irony",
  433. "Детские остросюжетные" : "child_det",
  434. "Шпионский детектив" : "det_espionage",
  435. "Крутой детектив" : "det_hard",
  436. "Дамский детективный роман" : "det_cozy",
  437. "Политический детектив" : "det_political",
  438. "Маньяки" : "det_maniac",
  439. "Медицинский триллер" : "thriller_medical",
  440. "Юридический триллер" : "thriller_legal",
  441. "Техно триллер" : "thriller_techno",
  442. "Биографии и Мемуары" : "nonf_biography",
  443. "Публицистика" : "nonf_publicism",
  444. "Научпоп" : "sci_popular",
  445. "Путешествия и география" : "adv_geo",
  446. "Критика" : "nonf_criticism",
  447. "Документальная литература" : "nonfiction",
  448. "Природа и животные" : "adv_animal",
  449. "Военная документалистика" : "nonf_military",
  450. "Современные любовный роман" : "love_contemporary",
  451. "Короткие любовный роман" : "love_short",
  452. "Исторические любовный роман" : "love_history",
  453. "О любви" : "love",
  454. "18+" : "love_erotica",
  455. "любовный детективы" : "love_detective",
  456. "Порно" : "love_hard",
  457. "Газеты и журналы" : "periodic",
  458. "Фанфик" : "fanfiction",
  459. "Музыка" : "music",
  460. "Недописанное" : "unfinished",
  461. "Кино" : "cine",
  462. "Изобразительное искусство, фотография" : "visual_arts",
  463. "Театр" : "theatre",
  464. "Партитуры" : "notes",
  465. "Неотсортированное" : "other",
  466. "Детская проза" : "child_prose",
  467. "Сказка" : "child_tale",
  468. "Детская литература" : "children",
  469. "Образовательная литература" : "child_education",
  470. "Детские приключения" : "child_adv",
  471. "Детские стихи" : "child_verse",
  472. "Подростковая литература" : "ya",
  473. "Книга-игра" : "prose_game",
  474. "Детский фольклор" : "child_folklore",
  475. "Домоводство" : "Дом и семья",
  476. "Здоровье" : "home_health",
  477. "Эротика, Секс" : "home_sex",
  478. "Хобби и ремесла" : "home_crafts",
  479. "Кулинария" : "home_cooking",
  480. "Сделай сам" : "home_diy",
  481. "Спорт" : "home_sport",
  482. "Домашние животные" : "home_pets",
  483. "Сад и огород" : "home_garden",
  484. "Развлечения" : "home_entertain",
  485. "Коллекционирование" : "home_collecting",
  486. "Эзотерика" : "religion_esoterics",
  487. "Самосовершенствование" : "religion_self",
  488. "Религия" : "religion_rel",
  489. "Христианство" : "religion_christianity",
  490. "Православие" : "religion_orthodoxy",
  491. "Буддизм" : "religion_budda",
  492. "Индуизм" : "religion_hinduism",
  493. "Иудаизм" : "religion_judaism",
  494. "Астрология" : "astrology",
  495. "Протестантизм" : "religion_protestantism",
  496. "Язычество" : "religion_paganism",
  497. "Ислам" : "religion_islam",
  498. "Религиозная литература" : "religion",
  499. "Католицизм" : "religion_catholicism",
  500. "Хиромантия" : "palmistry",
  501. "Приключения" : "adventure",
  502. "Исторические приключения" : "adv_history",
  503. "Морские приключения" : "adv_maritime",
  504. "Вестерн" : "adv_western",
  505. "Приключения про индейцев" : "adv_indian",
  506. "Юмористическая проза" : "humor_prose",
  507. "Юмор" : "humor",
  508. "Сатира" : "humor_satire",
  509. "Комедия" : "comedy",
  510. "Анекдоты" : "humor_anecdote",
  511. "Юмористические стихи" : "humor_verse",
  512. "Военная техника и вооружение" : "military_weapon",
  513. "Cпецслужбы" : "military_special",
  514. "Боевые искусства" : "military_arts",
  515. "Военное дело" : "military",
  516. "Справочники" : "ref_ref",
  517. "Руководства" : "ref_guide",
  518. "Энциклопедии" : "ref_encyc",
  519. "Искусство и Дизайн" : "design",
  520. "Путеводители" : "geo_guides",
  521. "Справочная литература" : "reference",
  522. "Словари" : "ref_dict",
  523. "Поэзия" : "poetry",
  524. "Лирика" : "lyrics",
  525. "в стихах" : "in_verse",
  526. "Эпическая поэзия" : "epic_poetry",
  527. "Песенная поэзия" : "song_poetry",
  528. "Басни" : "fable",
  529. "Экспериментальная поэзия" : "experimental_poetry",
  530. "Палиндромы" : "palindromes",
  531. "Верлибры" : "vers_libre",
  532. "Визуальная поэзия" : "visual_poetry",
  533. "Транспорт и авиация" : "sci_transport",
  534. "Радиоэлектроника" : "sci_radio",
  535. "Автомобили и ПДД" : "auto_regulations",
  536. "Строительство и сопромат" : "sci_build",
  537. "Архитектура" : "architecture_book",
  538. "Металлургия" : "sci_metal",
  539. "Драматургия" : "dramaturgy",
  540. "Драма" : "drama",
  541. "Киносценарии" : "screenplays",
  542. "Трагедия" : "tragedy",
  543. "Сценарии" : "scenarios",
  544. "Водевиль" : "vaudeville",
  545. "Мистерия" : "mystery",
  546. "О бизнесе популярно" : "popular_business",
  547. "Управление, подбор персонала" : "management",
  548. "Маркетинг, PR, реклама" : "marketing",
  549. "Ценные бумаги, инвестиции" : "stock",
  550. "Бухучет и аудит" : "accounting",
  551. "Личные финансы" : "personal_finance",
  552. "Малый бизнес" : "small_business",
  553. "Поиск работы, карьера" : "job_hunting",
  554. "Корпоративная культура" : "org_behavior",
  555. "Отраслевые издания" : "industries",
  556. "Банковское дело" : "banking",
  557. "Торговля" : "trade",
  558. "Делопроизводство" : "paper_work",
  559. "Недвижимость" : "real_estate",
  560. "Внешняя торговля" : "global_economy",
  561. "Околокомпьютерная литература" : "computers",
  562. "Программирование" : "comp_programming",
  563. "Программы" : "comp_soft",
  564. "ОС и Сети" : "comp_osnet",
  565. "Интернет" : "comp_www",
  566. "Аппаратное обеспечение" : "comp_hard",
  567. "Базы данных" : "comp_db",
  568. "Цифровая обработка сигналов" : "comp_dsp",
  569. "Мифы.Легенды.Эпос" : "antique_myths",
  570. "Древневосточная литература" : "antique_east",
  571. "Античная литература" : "antique_ant",
  572. "Древнеевропейская литература" : "antique_european",
  573. "Старинная литература" : "antique",
  574. "Древнерусская литература" : "antique_russian",
  575. "Народные сказки" : "folk_tale",
  576. "Фольклор" : "folklore",
  577. "Пословицы, поговорки" : "proverbs",
  578. "Былины" : "epic",
  579. "Народные песни" : "folk_songs",
  580. "Частушки, прибаутки, потешки" : "limerick",
  581. "Загадки" : "riddles"
  582. };
  583.  
  584. var genre = "";
  585. var Series = doc.getElementsByClassName('gnres');
  586.  
  587. if (Series.length == 1)
  588. var genres = RegExp('.*Жанры: (.*)$', 'm').exec(Series[0].outerText)[1].split(', ').join(',').split(',');
  589. else
  590. var genres = RegExp('.*Жанры: (.*)$', 'm').exec(Series[1].outerText)[1].split(', ').join(',').split(',');
  591.  
  592. if (genres !== null)
  593. {
  594. for (var i = 0; i < genres.length; i++)
  595. {
  596.  
  597. if (genresList[genres[i]] !== undefined)
  598. {
  599. genre += "<genre>" + genresList[genres[i]] + "</genre>\n";
  600. }
  601. }
  602.  
  603. return genre;
  604. }
  605.  
  606. if (genre === "")
  607. {
  608. return "<genre/>";
  609. }
  610.  
  611. }
  612.  
  613. function getAuthorName(doc)
  614. {
  615. if (doc === undefined)
  616. doc = document;
  617.  
  618. var authors = doc.getElementsByClassName('city3');
  619.  
  620. if (authors.length == 1)
  621. var FIO = authors[0].getElementsByClassName('txt')[0].text.split(' ');
  622. else
  623. var FIO = authors[1].getElementsByClassName('txt')[0].text.split(' ');
  624.  
  625. if (FIO.length == 1)
  626. {
  627. return "<first-name>" + FIO[0] + "</first-name>";
  628. }
  629.  
  630. if (FIO.length == 2)
  631. {
  632. return "<first-name>" + FIO[0] + "</first-name>\n<last-name>" + FIO[1] + "</last-name>";
  633. }
  634.  
  635. if (FIO.length == 3)
  636. {
  637. return "<first-name>" + FIO[1] + "</first-name>\n<middle-name>" + FIO[2] + "</middle-name>\n<last-name>" + FIO[0] + "</last-name>";
  638. }
  639.  
  640. return "<first-name>" + FIO[0].join(' ') + "</first-name>";
  641.  
  642. }
  643.  
  644. function getAnnotation(doc)
  645. {
  646. if (doc === undefined)
  647. doc = document;
  648.  
  649. return doc.getElementsByTagName("meta", "")[4].content;
  650. }
  651.  
  652. function getSeries(doc)
  653. {
  654. if (doc === undefined)
  655. doc = document;
  656.  
  657. var Series = doc.getElementsByClassName('serie');
  658.  
  659. if (Series.length == 1)
  660. var res = new RegExp('.*Серия: (.*)$', 'm').exec(Series[0].outerText);
  661. else
  662. var res = new RegExp('.*Серия: (.*)$', 'm').exec(Series[1].outerText);
  663.  
  664. if (res !== null)
  665. return '<sequence name="' + res[1].trim() + '" number=""/>';
  666. else
  667. return '';
  668. }
  669.  
  670. function getBookCover()
  671. {
  672. }
  673.  
  674. function AllBook(event)
  675. {
  676. var book = event.path[1].children[1];
  677. var bookid = parseInt(book.href.split('/')[4]);
  678. //var MaxProtection = my_getbyid("protected1").src !== '';
  679. var doc = getDoc(book.getAttribute("href"));
  680.  
  681. var coverImage = new Image();
  682. coverImage.src = doc.getElementById("relat" + bookid).children[0].children[0].getAttribute("src");
  683. var coverLoaded = false;
  684. coverImage.onload = function ()
  685. {
  686.  
  687. var cover = coverImage.getUrlData();
  688. var MaxProtection = false;
  689. if (!MaxProtection)
  690. {
  691. var pageHtml = "";
  692. var UserToken = GetUserToken(doc);
  693. var BookTitle = book.childNodes[0].textContent;
  694.  
  695. pageHtml = '<?xml version="1.0" encoding="utf-8"?>\n<FictionBook xmlns="http://www.gribuser.ru/xml/fictionbook/2.0" xmlns:xlink="http://www.w3.org/1999/xlink">\n';
  696. pageHtml += '<description>\n<title-info>' + getGenre(doc) + '<author>' + getAuthorName(doc) + '</author>\n';
  697. pageHtml += '<coverpage><image xlink:href="#' + coverImage.src + '"/></coverpage>\n';
  698. pageHtml += '<book-title>' + BookTitle + '</book-title>\n';
  699. pageHtml += '<annotation><p>' + getAnnotation(doc) + '</p></annotation>\n';
  700. pageHtml += '<lang>ru</lang><src-lang>ru</src-lang>\n';
  701. pageHtml += getSeries(doc);
  702. pageHtml += '</title-info><document-info><author><nickname/><email/></author><version>2.0</version></document-info>\n';
  703. pageHtml += '<publish-info><book-name>' + BookTitle + '</book-name></publish-info></description>\n';
  704. pageHtml += '<body>\n';
  705. pageHtml += '<title>\n';
  706. pageHtml += '<p>' + BookTitle + '</p>\n';
  707. pageHtml += '</title>\n';
  708.  
  709. var loader = new FragmentLoader(doc.getElementsByClassName('chapt'), UserToken,
  710. function (aChapters, nChapters)
  711. {
  712. aChapters.forEach(function (item, i, aChapters)
  713. {
  714. pageHtml += '<section><title><p>' + item.name + '</p></title>\n';
  715. pageHtml += item.text;
  716. pageHtml += '</section>\n';
  717.  
  718. }
  719. );
  720.  
  721. pageHtml += '</body>';
  722. pageHtml += '<binary content-type="image/png" id="' + coverImage.src + '">\n' + cover.replace('data:image/png;base64,', '') + '\n</binary>';
  723. pageHtml += '</FictionBook>';
  724.  
  725. var file = new File([pageHtml], BookTitle + '.fb2',
  726. {
  727. type : "text/plain;charset=utf-8"
  728. }
  729. );
  730. saveAs(file, BookTitle + '.fb2');
  731. book.childNodes[0].innerHTML = BookTitle;
  732.  
  733. },
  734. function (nProcessed, nCount)
  735. {
  736. book.childNodes[0].innerHTML = BookTitle + "(Загружено " + nProcessed + " глав из " + nCount + ")";
  737. }
  738. );
  739. }
  740. };
  741. }
  742.  
  743. function getMaxPages()
  744. {
  745. var scripts = document.getElementsByTagName("script");
  746. var maxpg = null;
  747. for (var i = 0; i < scripts.length; i++)
  748. {
  749. if(scripts[i].text.indexOf('InitRead') != -1)
  750. {
  751. return scripts[i].text.split('\n')[1];
  752. maxpg = parseInt(scripts[i].text.split('\n')[1].split(',')[6]);
  753. return maxpg;
  754. }
  755. }
  756. return null;
  757. }
  758.  
  759. function unprotect(text, format)
  760. {
  761. var pageHtml = null;
  762. if (format === undefined)
  763. format = "fb2";
  764.  
  765. if (document.location.hostname == "zelluloza.ru")
  766. {
  767.  
  768. eval(getMaxPages());
  769. //var maxpg = getMaxPages();
  770.  
  771. var BookId = document.getElementById("gotobook").value;
  772. var PartId = document.getElementsByClassName("taglnk2")[0].href.split('/')[5];
  773. var UserToken = GetUserToken();
  774. var BookTitle = "";
  775.  
  776. if (books.length == 1)
  777. BookTitle = document.getElementsByClassName("booklnk4")[0].childNodes[0].innerHTML;
  778. else
  779. BookTitle = document.getElementsByClassName("booklnk4")[1].childNodes[0].innerHTML;
  780. var PartTitle = document.getElementsByClassName("taglnk2")[0].text;
  781.  
  782. if (document.getElementsByClassName("booklnk4"))
  783. {
  784.  
  785. pageHtml = '<?xml version="1.0" encoding="utf-8"?>\n<FictionBook xmlns="http://www.gribuser.ru/xml/fictionbook/2.0" xmlns:xlink="http://www.w3.org/1999/xlink">\n';
  786. pageHtml += '<description>\n<title-info>' + getGenre() + '<author>' + getAuthorName() + '</author>\n';
  787. //pageHtml += '<coverpage><image xlink:href="#' + coverImage.src + '"/></coverpage>\n';
  788. pageHtml += '<book-title>' + BookTitle + '</book-title>\n';
  789. pageHtml += '<annotation><p>' + getAnnotation() + '</p></annotation>\n';
  790. pageHtml += '<lang>ru</lang><src-lang>ru</src-lang>\n';
  791. pageHtml += getSeries();
  792. pageHtml += '</title-info><document-info><author><nickname/><email/></author><version>2.0</version></document-info>\n';
  793. pageHtml += '<publish-info><book-name>' + BookTitle + '</book-name></publish-info></description>\n';
  794. pageHtml += '<body>\n';
  795. pageHtml += '<title>\n';
  796. pageHtml += '<p>' + BookTitle + '</p>\n';
  797. pageHtml += '</title>\n';
  798.  
  799. pageHtml += '<section><title><p>' + PartTitle + '</p></title>';
  800. }
  801.  
  802. var MaxProtection = my_getbyid("protected1").src !== '';
  803. if (!MaxProtection)
  804. {
  805. var Z = chp[0].split(/\n/);
  806. for (var j in Z)
  807. {
  808. pageHtml += '<p>' + DS('', Z[j]).replace('\r', '').replace('\n', '').replace('[ctr][gry]- Конец фрагмента -[/][/]', '') + '</p>\n';
  809. }
  810. pageHtml += '</section></body></FictionBook>';
  811. var file = new File([pageHtml], BookTitle + '.fb2',
  812. {
  813. type : "text/plain;charset=utf-8"
  814. }
  815. );
  816. saveAs(file, BookTitle + '(' + PartTitle + ').fb2');
  817. }
  818. else
  819. {
  820. var pages = new Array();
  821. oCanvas = my_getbyid("cnv1");
  822. oCtx = oCanvas.getContext("2d");
  823. pagessize = 5;
  824. var page = 0;
  825. var loaded = false;
  826. for (page = 0; page <= maxpg; page += pagessize)
  827. {
  828. pages[page] = "/get/" + base64_encode(BookId + ":" + PartId + ":" + pagessize + ":" + page);
  829. }
  830.  
  831. var binaryImages = "";
  832. var pp = new ImageLoader(pages, function (aImages, nLoaded)
  833. {
  834. if (format == "fb2")
  835. {
  836.  
  837. aImages.forEach(function (item, i, aImages)
  838. {
  839. if (item.bLoaded)
  840. {
  841. oCtx.drawImage(item, 0, 0);
  842. pageHtml += '<image xlink:href="#page_' + i + '.jpg"/>\n';
  843. binaryImages += '<binary content-type="image/png" id="page_' + i + '.jpg">\n' + oCanvas.toDataURL("image/png", 1.0).replace('data:image/png;base64,', '') + '\n</binary>';
  844. }
  845. }
  846. );
  847.  
  848. pageHtml += '</section></body>';
  849. pageHtml += binaryImages;
  850. pageHtml += '</FictionBook>';
  851. var file = new File([pageHtml], BookTitle + '(' + PartTitle + ').fb2',
  852. {
  853. type : "text/plain;charset=utf-8"
  854. }
  855. );
  856. saveAs(file, BookTitle + '(' + PartTitle + ').fb2');
  857. }
  858. else
  859. {
  860. var pdf = new jsPDF('p', 'pt', 'b5', 1);
  861. pdf.internal.pageSize =
  862. {
  863. "height" : 480,
  864. "widht" : 550
  865. };
  866.  
  867. var pdfInternals = pdf.internal;
  868. var pdfPageSize = pdfInternals.pageSize;
  869. var pdfPageWidth = pdfPageSize.width;
  870. var pdfPageHeight = pdfPageSize.height;
  871.  
  872. var flags =
  873. {
  874. "noBOM" : true,
  875. "autoencode" : true
  876. };
  877.  
  878. pdf.text(BookTitle, pdfPageWidth / 3, 20, flags);
  879. pdf.text(PartTitle, pdfPageWidth / 3, 40, flags);
  880.  
  881. aImages.forEach(function (item, i, aImages)
  882. {
  883. if (item.bLoaded)
  884. {
  885. oCtx.drawImage(item, 0, 0);
  886. var img = oCanvas.toDataURL("image/png", 1.0);
  887. pdf.addPage();
  888. pdf.addImage(img, "png", 10, 70, 0, 0);
  889. }
  890. }
  891. );
  892.  
  893. pdf.save(BookTitle + '(' + PartTitle + ').pdf');
  894. }
  895. }
  896. );
  897.  
  898. }
  899. }
  900. }
  901.  
  902. function loadScriptText(ref)
  903. {
  904. var xmlhttp = getXmlHttp();
  905. xmlhttp.open("GET", ref, false);
  906.  
  907. if (xmlhttp.readyState == 1)
  908. {
  909. xmlhttp.setRequestHeader("Content-Type", "text/html");
  910. xmlhttp.send();
  911. }
  912.  
  913. if (xmlhttp.status != 200)
  914. {
  915. alert(xmlhttp.status + ': ' + xmlhttp.statusText); // пример вывода: 404: Not Found
  916. }
  917. else
  918. {
  919. return xmlhttp.responseText;
  920. }
  921. }
  922.  
  923. function loadNativeScript()
  924. {
  925. var scripts = document.getElementsByTagName("script");
  926. for (var i = 0; i < scripts.length; i++)
  927. {
  928. if (scripts[i].src !== "")
  929. if (scripts[i].src.indexOf("zelluloza") != -1)
  930. return loadScriptText(scripts[i].src);
  931. }
  932. }
  933.  
  934. unsafeWindow.wait_for_text = function ()
  935. {
  936. var text = document.getElementById("bookpgm");
  937. if (null === books)
  938. alert('No copyable text found!');
  939. else
  940. {
  941. for (var i = 0; i < books.length; i++)
  942. {
  943. buttons[i] = document.createElement("INPUT");
  944. buttons[i].setAttribute("type", "button");
  945. buttons[i].setAttribute("value", 'Скачать в fb2');
  946. buttons[i].setAttribute("ref", books[i].href);
  947. buttons[i].addEventListener('click', AllBook, true);
  948. books[i].parentNode.insertBefore(buttons[i], books[i]);
  949. }
  950. }
  951.  
  952. if (null !== text)
  953. if (text.innerHTML.length > 100)
  954. {
  955. var button = document.createElement("BUTTON");
  956. button.value = 'Скачать в fb2';
  957.  
  958. button.addEventListener('click', function ()
  959. {
  960. unprotect(text);
  961. }, true);
  962. text.parentNode.insertBefore(button, text);
  963. var MaxProtection = my_getbyid("protected1").src !== '';
  964.  
  965. if (MaxProtection)
  966. {
  967. var button2 = document.createElement("BUTTON");
  968. button2.innerHTML = 'Скачать в pdf';
  969. button2.addEventListener('click', function ()
  970. {
  971. unprotect(text, "pdf");
  972. }, true);
  973. text.parentNode.insertBefore(button2, text);
  974. }
  975. }
  976. else
  977. window.setTimeout("wait_for_text()", 100);
  978. };
  979.  
  980. //eval(loadNativeScript());
  981. //eval(loadScriptText("https://cdn.rawgit.com/eligrey/FileSaver.js/master/FileSaver.min.js"));
  982. //eval(loadScriptText("https://greasyfork.org/scripts/15924-jspdf/code/jsPDF.js?version=99137"));
  983.  
  984. var books = document.getElementsByClassName("booklnk4");
  985. var buttons = new Array();
  986. window.setTimeout("wait_for_text()", 100);