Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // ==UserScript==
- // @name FB2 Converter for DM
- // @version 1.2.5
- // @grant none
- // @include https://l.dm.am/ModuleInfo.aspx*
- // ==/UserScript==
- /*
- FB2 Converter
- */
- var rooms = document.querySelectorAll('a[id*="repRooms"]:not(.aspNetDisabled), a[id*="archiveRepRooms"]:not(.aspNetDisabled), a[id*="lnkSession"]');
- if (window.location.href.indexOf('ModuleInfo') > 0) {
- //Загрузка файла в браузере
- function download(data, filename, type) {
- var file = new Blob([data], {type: type});
- if (window.navigator.msSaveOrOpenBlob) // IE10+
- window.navigator.msSaveOrOpenBlob(file, filename);
- else { // Others
- var a = document.createElement("a"),
- url = URL.createObjectURL(file);
- a.href = url;
- a.download = filename;
- document.body.appendChild(a);
- a.click();
- setTimeout(function() {
- document.body.removeChild(a);
- window.URL.revokeObjectURL(url);
- }, 0);
- }
- }
- //Загрузка аватарок
- async function getBase64ImageFromUrl(imageUrl) {
- var name = imageUrl.match(/\d*\.jpg/);
- var res = await fetch(imageUrl);
- var blob = await res.blob();
- return new Promise((resolve, reject) => {
- var reader = new FileReader();
- reader.addEventListener("load", function () {
- resolve('["' + name +'","' + reader.result.replace("data:image/jpeg;base64,","") + '"]');
- }, false);
- reader.onerror = () => {
- return reject(this);
- };
- reader.readAsDataURL(blob);
- })
- }
- //Подготовка тегов
- function replace_tags(content) {
- var open = "";
- var close = "";
- content = content.replace(/<div><div><a href="javascript[^]+?none;">/g, "<br>");
- content = content.replace(/<div class="spoiler-tag"><div><a href="javascript[^]+?none;">/g, "<br>");
- content = content.replace(/<\/div><\/div><\/div>/g, "<br>");
- content = content.replace(/<div class="nsfw-tag">[^]+?blurred-content">/g, "<br>");
- content = content.replace(/<\/div>[^]+?<\/div><\/span><\/div>/g, "<br>");
- content = content.replace(/<span class="nsfw-tag-end"><\/span>/g, "");
- content = content.replace(/<(\/)?u>/g, "");
- content = content.replace(/<(\/)?ul>/g, "");
- content = content.replace(/<(\/)?ol>/g, "");
- content = content.replace(/<(\/)?li>/g, "<br>");
- content = content.replace(/<span class="comment">([^]+?)<\/span>/g, function (match, p1, offset, string) {
- return "<br><sup>" + p1.replace(/<br>/g, "") + "</sup><br>";
- });
- content = content.replace(/<img src="([^]*?)">/g, function (match, p1, offset, string) {
- p1 = p1.replace(/</g, "<");
- p1 = p1.replace(/>/g, ">");
- return '<a l:href="' + p1 + '">' + p1 + '<\/a>';
- });
- content = content.replace(/<a href="([^]*?)">ссылка/g, function (match, p1, offset, string) {
- p1 = p1.replace(/</g, "<");
- p1 = p1.replace(/>/g, ">");
- return '<a l:href="' + p1 + '">' + p1;
- });
- content = content.replace(/<div class="greenText inline">([^]*?)<\/div>/g, "($1)");
- content = content.replace(/(<br>)+/g, "</p><p>");
- content = content.replace(/<span>([^]+?)<\/span>/g, function (match, p1, offset, string) {
- return p1;
- });
- content = content.replace(/<span class="quote">/g, "<cite>");
- content = content.replace(/<\/span>/g, "</cite>");
- content = content.replace(/<(\/)?b>/g, "<$1strong>");
- content = content.replace(/<(\/)?i>/g, "<$1emphasis>");
- content = content.replace(/<(\/)?strike>/g, "<$1strikethrough>");
- content = content.replace(/<(\/)?pre>/g, "<$1code>");
- content = content.replace(/<(\/)?(cite|strong|emphasis|strikethrough|code|p)>/g, function (match, p1, p2, offset, string) {
- if ((p2 == "strong" || p2 == "emphasis" || p2 == "strikethrough" || p2 == "code") && p1 == undefined) {
- open = open + "<" + p2 + ">";
- close = "</" + p2 + ">" + close;
- return match;
- }
- if ((p2 == "strong" || p2 == "emphasis" || p2 == "strikethrough" || p2 == "code") && p1 !== undefined) {
- var re_opn = new RegExp ("<" + p2 + ">([^]+?)?$");
- open = open.replace(re_opn, "$1");
- var re_cls = new RegExp ("^([^]+?)?</" + p2 + ">");
- close = close.replace(re_cls, "$1");
- return match;
- }
- if (p2 == "p" && p1 !== undefined) {
- return close + match;
- }
- if (p2 == "p" && p1 == undefined) {
- return match + open;
- }
- if (p2 == "cite" && p1 == undefined) {
- return close + match + "<p>" + open;
- }
- if (p2 == "cite" && p1 !== undefined) {
- return close + "</p>" + match + open;
- }
- });
- content = content.replace(/ /g, " ");
- return content;
- }
- //Подготовка загрузки
- function prepare_download() {
- var main = document.getElementById("main");
- var workframe = document.createElement("div");
- var insert = "<p><b>Опции</b></p>";
- insert += "<p><input type='checkbox' id='chars'> Выгружать чарлисты</p>";
- insert += "<p><input type='checkbox' id='avatars'> Отображать аватары в постах</p>";
- insert += "<p><b>Выберите комнаты для выгрузки</b></p>";
- insert += "<p><input type='checkbox' id='toggle'> <i>Выделить/снять все</i></p>";
- workframe.setAttribute("id", "workframe");
- workframe.setAttribute("style", "position:absolute;top:0px;left:500px;background-color:white;padding:50px;border:1px solid black;max-height:500px;max-width:300px;overflow:scroll;white-space:nowrap;");
- for (var i = 0; i < rooms.length; i++) {
- insert = insert + "<p><input type='checkbox' name='selection' value='" + i + "'> " + rooms[i].innerHTML + " </p>";
- }
- insert = insert+ "<p><input id='start_convert' type='button' value='Старт'> <input id='cancel' type='button' value='Закрыть' onclick='this.parentElement.parentElement.remove();'></p>";
- workframe.innerHTML = insert;
- main.appendChild(workframe);
- document.getElementById("start_convert").addEventListener("click", convert);
- document.getElementById("toggle").addEventListener("change", toggle);
- }
- //Выделить все
- function toggle() {
- var selection = document.querySelectorAll('input[name=selection]');
- if (document.getElementById("toggle").checked == true) {
- for (var i = 0; i < selection.length; i++) {
- selection[i].checked = true;
- }
- } else {
- for (var i = 0; i < selection.length; i++) {
- selection[i].checked = false;
- }
- }
- }
- //Загрузка страницы
- function loadifrm (item, page, pagesize, href) {
- if (href == null) href = "https://l.dm.am/" + rooms[item].getAttribute("href").replace(/#\d+$/, "") + "&page=" + page + "&pagesize=" + pagesize;
- var xhr= new XMLHttpRequest();
- xhr.open('GET', href, false);
- xhr.send();
- if (xhr.status != 200) {
- return ("error");
- } else {
- var parser = new DOMParser ();
- var doc = parser.parseFromString (xhr.response, "text/html");
- return (doc);
- }
- }
- function convert() {
- //Готовим формат FB2
- var fb2 = '<?xml version="1.0" encoding="utf-8"?><FictionBook xmlns="http://www.gribuser.ru/xml/fictionbook/2.0" xmlns:l="http://www.w3.org/1999/xlink"><description><title-info><genre>adventure</genre>';
- var tags = document.getElementById("ctl00_mainContent_panTags").children;
- var tags_arr = new Map([
- ['Альтернативная история', 'sf_history'],
- ['Боевик', 'det_action'],
- ['Детектив', 'detective'],
- ['Киберпанк', 'sf_cyberpunk'],
- ['Космоопера', 'sf_space'],
- ['Триллер', 'thriller'],
- ['Ужас', 'sf_horror'],
- ['Фентези', 'sf_fantasy']
- ]);
- for (var i = 0; i < tags.length; i++) {
- if (tags_arr.has(tags[i].innerHTML)) {
- fb2 = fb2 + "<genre>" + tags_arr.get(tags[i].innerHTML) + "</genre>";
- }
- }
- fb2 = fb2 + "<author><nickname>" + document.getElementById('ctl00_mainContent_lnkMaster').innerHTML + "</nickname></author>";
- var title = document.querySelector('#ctl00_mainContent_panModuleInfo > h1').innerHTML.replace(/([^]+?) \| Описание игры/, "$1").trim();
- fb2 = fb2 + "<book-title>" + title + "</book-title>";
- fb2 = fb2 + "<lang>ru</lang></title-info><document-info><author><nickname>Hatchet</nickname></author><program-used>FB2 Converter for DM</program-used>";
- var time = new Date(Date.now());
- date = time.getFullYear() + '-' + ('0' + (time.getMonth() + 1)).slice(-2) + '-' + ('0' + time.getDate()).slice(-2);
- var time = time.getHours() + '-' + time.getMinutes() + '-' + time.getSeconds();
- fb2 = fb2 + '<date value="' + date + '">' + date + '</date>';
- fb2 = fb2 + "<src-url>" + window.location.href + "</src-url>";
- fb2 = fb2 + "<id>" + date + "-" + time + "</id>";
- fb2 = fb2 + "<version>1.2.5</version>";
- fb2 = fb2 + "</document-info>";
- fb2 = fb2 + "</description><body>";
- var progress = document.createElement("span");
- progress.setAttribute("style", "color:#393;");
- progress.innerHTML = " Загрузка";
- var loaderror = document.createElement("span");
- loaderror.innerHTML = " Ошибка загрузки или комната не содержит сообщений";
- loaderror.setAttribute("style", "color:#933;");
- var readyerror = document.createElement("span");
- readyerror.innerHTML = " Ошибка загрузки";
- readyerror.setAttribute("style", "color:#933;");
- //Загрузка персонажей и аватарок
- document.getElementById("start_convert").remove();
- var chars_select = document.getElementById("chars");
- var avs_select = document.getElementById("avatars");
- if (chars_select.checked || avs_select.checked) {
- if (chars_select.checked) chars_select.parentNode.appendChild(progress.cloneNode(true));
- if (avs_select.checked) avs_select.parentNode.appendChild(progress.cloneNode(true));
- var href = window.location.href.replace("ModuleInfo", "PlayerProfiles");
- var chars = loadifrm(null, null, null, href);
- if (chars == "error") {
- if (chars_select.checked) chars_select.parentNode.appendChild(readyerror.cloneNode(true));
- if (avs_select.checked) avs_select.parentNode.appendChild(readyerror.cloneNode(true));
- } else {
- if (chars_select.checked) {
- var chrs = chars.querySelectorAll(".padding5");
- if (chrs) {
- fb2 = fb2 + "<section><title><p>Персонажи</p></title>";
- for (var i = 0; i < chrs.length; i++) {
- fb2 = fb2 + "<p><b>" + chrs[i].querySelector("h2").innerHTML + "</b></p>";
- if (chrs[i].querySelector('img[id*="imgAvatar"]')) fb2 = fb2 + "<image l:href='#"+ chrs[i].querySelector('img[id*="imgAvatar"]').src.match(/\d*\.jpg/) + "'/>";
- fb2 = fb2 + "<p><b>Автор:</b> " + chrs[i].querySelector('a[id*="lnkPlayer"]').innerHTML + "</p>";
- var char_info = chrs[i].querySelectorAll(".p");
- for (var j = 1; j < char_info.length; j++) {
- fb2 = fb2 + "<p>" + replace_tags(char_info[j].innerHTML).replace("Информация доступна только мастеру и хозяину персонажа.", "") + "</p>";
- }
- }
- fb2 = fb2 + "</section>";
- } else {
- chars_select.parentNode.appendChild(readyerror.cloneNode(true));
- }
- }
- var avs = chars.querySelectorAll('img[id*="imgAvatar"]');
- if (avs) {
- var avs_res = "";
- for (var i = 0; i < avs.length; i++) {
- var src = avs[i].src.replace(/\?[^]*/, "");
- getBase64ImageFromUrl(src).then(
- result => {
- var json = JSON.parse(result);
- avs_res = avs_res + "<binary id='" + json[0] + "' content-type='image/jpeg'>" + json[1] + "</binary>"
- },
- error => {
- if (avs_select.checked) avs_select.parentNode.appendChild(readyerror.cloneNode(true));
- if (chars_select.checked) chars_select.parentNode.appendChild(readyerror.cloneNode(true));
- }
- );
- }
- } else {
- if (avs_select.checked) avs_select.parentNode.appendChild(readyerror.cloneNode(true));
- if (chars_select.checked) chars_select.parentNode.appendChild(readyerror.cloneNode(true));
- }
- }
- }
- //Загрузка комнат
- var selection = document.querySelectorAll('input[name=selection]');
- var selected = [];
- for (var i = 0; i < selection.length; i++) {
- if (selection[i].checked == true) selected.push(selection[i].value);
- }
- selected.forEach(function(item, i, arr) {
- var page = 1;
- selection[item].parentNode.appendChild(progress.cloneNode(true));
- do {
- selection[item].parentNode.children[1].innerHTML += ">";
- var pagesize = 100;
- var loaded = loadifrm (item, page, pagesize, null);
- if (loaded == "error") {
- selection[item].parentNode.appendChild(readyerror.cloneNode(true));
- break;
- }
- var pager = loaded.querySelector(".pager");
- if (pager) {
- pager = pager.querySelectorAll("a, span");
- if (pager[0].tagName == "SPAN") var first = true;
- if (pager[pager.length - 1].tagName == "SPAN") var last = true;
- } else {
- var first = true;
- var last = true;
- }
- if (first == true) {
- fb2 = fb2 + "<section><title><p>" + rooms[item].innerHTML + "</p></title>";
- first = false;
- }
- var posts = loaded.getElementsByClassName("commentItem").length;
- if (posts !== 0) {
- var author = loaded.getElementsByClassName("gray6");
- for (var i = 0; i < posts; i++) {
- var post_id = "[id$='lblBody_" + i + "']>.p";
- var comment_id = "[id$='lblComment_" + i + "']";
- var author_i = author[i].innerHTML + ":";
- var avatar = false;
- if (avs_select.checked && loaded.querySelector("[id$='imgAvatar_" + i + "']")) avatar = loaded.querySelector("[id$='imgAvatar_" + i + "']").src.match(/\d*\.jpg/);
- var post_content = loaded.querySelector(post_id).innerHTML;
- //Готовим текст поста для выгрузки
- author_i = author_i.replace(/<(\/)?b>/g, "<$1strong>");
- post_content = replace_tags(post_content);
- //Готовим комментарий для выгрузки
- if (loaded.querySelector(comment_id).innerHTML !== "") {
- var comment = loaded.querySelector(comment_id).firstChild.innerHTML;
- comment = "</p><p>----------</p><p>" + comment;
- comment = replace_tags(comment);
- } else var comment = "";
- if (avatar) fb2 = fb2 + "<image l:href='#"+ avatar + "'/>";
- fb2 = fb2 + "<p>" + author_i + "</p><p>" + post_content + comment + "</p>";
- }
- } else {
- selection[item].parentNode.appendChild(loaderror.cloneNode(true));
- fb2 = fb2 + "</section>";
- break;
- }
- if (last == true) {
- fb2 = fb2 + "</section>";
- }
- page++;
- } while (last !== true);
- });
- fb2 = fb2 + "</body>";
- fb2 = fb2 + avs_res;
- fb2 = fb2 + "</FictionBook>";
- download (fb2, title + ".fb2", "text/plain");
- }
- var actions = document.getElementById("ctl00_leftMenu_ctl00_lnkManagePlayers").outerHTML;
- if (document.getElementById("dwnld") == null) {
- document.getElementById("ctl00_leftMenu_ctl00_lnkManagePlayers").outerHTML = actions + "<br>- <a id='dwnld' href='javascript:void(0);'>Скачать в формате FB2</a>";
- document.getElementById("dwnld").addEventListener("click", prepare_download);
- }
- }
Add Comment
Please, Sign In to add comment