您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Transcribes books you read on OverDrive for offline reading
当前为
// ==UserScript== // @name OverDrive Transcriber // @description Transcribes books you read on OverDrive for offline reading // @namespace Violentmonkey Scripts // @match *://*.overdrive.com/* // @match *://*.gf.qytechs.cn/* // @grant GM_setValue // @grant GM_getValue // @grant GM_listValues // @grant GM_deleteValue // @grant GM_xmlhttpRequest // @run-at document-start // @version 0.1.3 // @author qsniyg // ==/UserScript== (function() { var content_html_regex = /\.x?html?\?cmpt=/; var content_html_match = /^(?:.*\/)?([^/.]*)\.x?html?/; var default_options = { images: { name: "Include images", default: true } }; var options = {}; var img_requests = 0; for (var option in default_options) { var value = GM_getValue("SETTINGS:" + option); if (value !== undefined) options[option] = JSON.parse(value); else options[option] = default_options[option].default; } function onload(f) { if (document.readyState === "interactive" || document.readyState === "complete") { f(); } else { document.addEventListener("DOMContentLoaded", f, false); } } function makebutton(el, bg) { el.style.padding = ".5em 1em"; el.style.background = bg; el.style.color = "white"; el.style.textDecoration = "none"; el.style.display = "inline-block"; el.style.margin = ".3em .5em"; } var fullurl = function(url, x) { return urljoin(url, x); }; function urljoin(a, b) { var protocol_split = a.split("://"); var protocol = protocol_split[0]; var splitted = protocol_split[1].split("/"); var domain = splitted[0]; var start = protocol + "://" + domain; if (b.length === 0) return a; if (b.match(/[a-z]*:\/\//)) return b; if (b.length >= 2 && b.slice(0, 2) === "//") return protocol + ":" + b; if (b.length >= 1 && b.slice(0, 1) === "/") return start + b; if (a.match(/\/$/)) return a + b.replace(/^\/*/, ""); else return a.replace(/\/[^/]*$/, "/") + b.replace(/^\/*/, ""); } // OverDrive section function overdrive() { var transcribe_btn; var transcribed = false; function parse(url, content) { var html = document.createElement("html"); html.innerHTML = content; var url_match = url.match(content_html_match); if (!url_match) // shouldn't happen return; //var book_id = url_match[2]; var book_id = bData["-odread-buid"]; var var_id = url_match[1]; var titleel = html.getElementsByTagName("title")[0]; if (!titleel) return; var title = titleel.innerHTML; /*console.log(book_id); console.log(var_id); console.log(title);*/ GM_setValue("TITLE:" + book_id, title.toString()); GM_setValue("INFO:" + book_id, JSON.stringify(unsafeWindow.bData)); var setcontents = function(contents) { GM_setValue("CONTENTS:" + book_id + ":" + var_id, contents); _contents = contents; } var scripts = html.getElementsByTagName("script"); var regex = /^ *parent\.[^;(]*\(.*?['"](.*?)['"]/; var set = false; var _contents; for (var i = 0; i < scripts.length; i++) { var matchobj = scripts[i].innerHTML.match(regex); if (matchobj) { var text = unsafeWindow.atob(matchobj[1]); setcontents(text); set = true; } } if (!set) { if (html.querySelectorAll("body > p").length >= 0) { var body = html.getElementsByTagName("body")[0].cloneNode(true); body.removeAttribute("xmlns"); body.removeAttribute("onload"); setcontents(body.outerHTML); } } if (options.images) { var doc = document.implementation.createHTMLDocument("preview"); var newhtml = doc.createElement("html"); newhtml.innerHTML = _contents; /*var parser = new DOMParser(); var newhtml = parser.parseFromString(_contents, "text/xml");*/ var images = newhtml.getElementsByTagName("img"); for (var i = 0; i < images.length; i++) { console.log(images[i]); img_requests++; (function(src) { var full_url = fullurl(document.location.href, url); var newsrc = fullurl(full_url, src); new GM_xmlhttpRequest({ method: 'GET', url: newsrc, overrideMimeType: 'text/plain; charset=x-user-defined', headers: { "Origin": document.location.href.replace(/^([a-z]+:\/\/[^/]*).*?$/, "$1"), "Referer": full_url }, onload: function (resp) { if (resp.status !== 200 && resp.status !== 304) { console.dir(resp); return; } console.log(src); img_requests--; var retval = ""; for (var i = 0; i < resp.responseText.length; i++) { retval += String.fromCharCode(resp.responseText.charCodeAt(i) & 0xff); } GM_setValue("IMAGE:" + book_id + ":" + src.replace(/.*?:\/\/[^/]*\/*/, ""), retval); if (img_requests === 0 && transcribed) { transcribe_btn.innerHTML = "Done"; } } }); })(images[i].getAttribute("src")); } } } var original_open = window.XMLHttpRequest.prototype.open; window.XMLHttpRequest.prototype.open = function(method, url) { if (!url) return; if (url.match(content_html_regex)) { this.addEventListener("readystatechange", function() { if (this.readyState === 4) { parse(url, this.responseText); } }); } original_open.apply(this, arguments); }; function run_iframe(iframe) { var ifdocument = iframe.contentDocument || iframe.contentWindow.document; parse(iframe.src, ifdocument.documentElement.innerHTML) } function find_iframes() { return; var iframes = document.getElementsByTagName("iframe"); for (var i = 0; i < iframes.length; i++) { if (iframes[i].src.match(content_html_regex)) { (function(iframes, i) { iframes[i].onload = function() { run_iframe(iframes[i]); } run_iframe(iframes[i]); })(iframes, i); } } } function transcribe(el) { el.innerHTML = "Transcribing..."; var info = unsafeWindow.bData; var i = 0; function do_request() { if (i >= info.spine.length) { console.log("Done text"); transcribed = true; if (img_requests === 0) { el.innerHTML = "Done"; } return; } var path = info.spine[i].path; i++; console.log(path); if (!path.match(content_html_regex)) { console.log("Skipping: " + path); do_request(); return; } var oReq = new XMLHttpRequest(); oReq.addEventListener("load", do_request); oReq.open("GET", path); oReq.send(); } do_request(); } function start() { new MutationObserver(find_iframes).observe(document.documentElement, { attributes: true, childList: true }); find_iframes(); if (unsafeWindow.bData) { var outer_div = document.createElement("div"); outer_div.style.width = "100%"; transcribe_btn = document.createElement("a"); transcribe_btn.innerHTML = "Transcribe"; transcribe_btn.onclick = function() { transcribe(transcribe_btn); }; transcribe_btn.href = "javascript:void(0)"; transcribe_btn.style.zIndex = 999999999; transcribe_btn.style.position = "absolute"; makebutton(transcribe_btn, "#1070a0"); outer_div.appendChild(transcribe_btn); document.body.appendChild(outer_div); } } onload(start); } // GreasyFork section function greasyfork() { function start() { var insert = document.getElementById("overdrive-insert"); if (!insert) { var addto = document.querySelector(".script-author-description"); addto.innerHTML = "<div id='overdrive-insert'></div>" + addto.innerHTML; insert = document.getElementById("overdrive-insert"); } insert.innerHTML = ""; var table = document.createElement("table"); table.style.border = "1px solid black"; table.style.background = "white"; table.style.width = "100%"; var preview_iframe = document.createElement("iframe"); preview_iframe.style.width = "100%"; preview_iframe.style.display = "block"; preview_iframe.style.border = "0"; var preview_tr = document.createElement("tr"); preview_tr.style.padding = 0; preview_tr.style.margin = 0; var preview_td = document.createElement("td"); preview_td.style.padding = 0; preview_td.style.margin = 0; preview_td.style.borderBottom = "1px solid black"; preview_td.style.display = "none"; preview_td.setAttribute("colspan", 10); preview_td.appendChild(preview_iframe); preview_tr.appendChild(preview_td); table.appendChild(preview_tr); var keys = GM_listValues(); if (keys.length === 0) { var tr = document.createElement("tr"); var td = document.createElement("td"); td.innerHTML = "<i>No books yet</>"; tr.appendChild(td); table.appendChild(tr); } for (var i = 0; i < keys.length; i++) { if (!keys[i].match(/^TITLE:/)) { continue; } (function(key) { var title = GM_getValue(key); var id = key.replace(/.*:/, ""); var info = JSON.parse(GM_getValue("INFO:" + id)); var tr = document.createElement("tr"); tr.style.border = "1px solid black"; var name_td = document.createElement("td"); name_td.innerHTML = "<b>" + title + "</b>"; var html = '<html><head><title>' + title + '</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /></head><body>'; var size = 0; var items = {}; var images = {}; for (var i = 0; i < keys.length; i++) { if (keys[i].indexOf("CONTENTS:" + id + ":") !== 0 && keys[i].indexOf("IMAGE:" + id + ":") !== 0) { continue; } var contents = GM_getValue(keys[i]); size += contents.length; if (keys[i].indexOf("IMAGE:") === 0) { images[keys[i].replace(/.*:/, "")] = contents; continue; } var element = document.createElement("html"); element.innerHTML = '<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /></head>'; element.innerHTML += contents; var text = element.getElementsByTagName("body")[0].innerHTML; //html += text; items[keys[i].replace(/.*:/, "")] = text; } var have = 0; var total = 0; for (var i = 0; i < info.spine.length; i++) { if (!info.spine[i].path.match(content_html_regex)) continue; total++; var spinematch = info.spine[i].path.match(content_html_match); if (!spinematch) continue; var spineid = spinematch[1]; if (spineid in items) { html += items[spineid]; have++; } else { console.log("Missing " + spineid); } } html += "</body></html>"; if (Object.keys(images).length > 0) { var doc = document.implementation.createHTMLDocument("preview"); var htmlel = doc.createElement("html"); htmlel.innerHTML = html; var img_els = htmlel.getElementsByTagName("img"); for (var i = 0; i < img_els.length; i++) { var src = img_els[i].getAttribute("src"); if (src in images) { var ext = src.replace(/.*\.([a-zA-Z]*).*?$/, "$1").toLowerCase(); var mime = "image/" + ext; if (ext === "jpg") mime = "image/jpeg"; img_els[i].setAttribute("src", "data:" + mime + ";base64," + btoa(images[src])); } } html = htmlel.innerHTML; } var link = "data:text/html," + encodeURIComponent(html); name_td.innerHTML += " (" + have + "/" + total + ")"; var preview = document.createElement("a"); preview.onclick = function() { preview_iframe.src = link; preview_td.style.display = "table-cell"; }; preview.href = "javascript:void(0)"; preview.innerHTML = "Preview"; makebutton(preview, "#105210"); var download = document.createElement("a"); download.href = link; download.setAttribute("download", title + ".html"); download.innerHTML = "Download (" + (html.length / 1024).toFixed(1) + "KB)"; makebutton(download, "#1070a0"); var del = document.createElement("a"); del.href = "javascript:void(0)"; del.onclick = function() { if (!confirm("Delete '" + title + "'?")) return; for (var i = 0; i < keys.length; i++) { if (keys[i] === ("TITLE:" + id) || keys[i] === ("INFO:" + id) || keys[i].indexOf("CONTENTS:" + id + ":") >= 0 || keys[i].indexOf("IMAGE:" + id + ":") >= 0) { console.log(keys[i]); GM_deleteValue(keys[i]); } } start(); } del.innerHTML = "Delete (" + (size / 1024).toFixed(1) + "KB)"; del.style.float = "right"; makebutton(del, "#a02010"); var actions_td = document.createElement("td"); actions_td.appendChild(preview); actions_td.appendChild(download); actions_td.appendChild(del); tr.appendChild(name_td); tr.appendChild(actions_td); table.appendChild(tr); })(keys[i]); } var hr_tr = document.createElement("tr"); var hr_td = document.createElement("td"); hr_td.setAttribute("colspan", 10); hr_td.style.borderBottom = "1px solid black"; hr_tr.appendChild(hr_td); table.appendChild(hr_tr); for (var option in default_options) { (function(option) { var tr = document.createElement("tr"); var name_td = document.createElement("td"); name_td.innerHTML = default_options[option].name; tr.appendChild(name_td); var value_td = document.createElement("td"); var value_input = document.createElement("input"); value_input.type = "checkbox"; if (options[option]) value_input.setAttribute("checked", ""); value_input.onclick = function() { var val = false; if (value_input.checked) val = true; GM_setValue("SETTINGS:" + option, JSON.stringify(val)); }; value_td.appendChild(value_input); tr.appendChild(value_td); table.appendChild(tr); })(option); } insert.appendChild(table); } onload(start); } if (document.location.href.match(/:\/\/[^/]*\.overdrive\.com\//)) overdrive(); else if (document.location.href.match(/\/41000-overdrive-transcriber(?:\/?[?#].*)?$/)) greasyfork(); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址