您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
exhentai-manga-manager的附加浏览器脚本
当前为
// ==UserScript== // @name ehentai显示已下载 提取页面元数据 // @namespace http://tampermonkey.net/ // @version 1.4 // @license MIT // @description exhentai-manga-manager的附加浏览器脚本 // @author You // @match *exhentai.org/* // @match *e-hentai.org/* // @icon https://www.google.com/s2/favicons?sz=64&domain=exhentai.org // @grant GM_addStyle // @require https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js // ==/UserScript== (function() { GM_addStyle(` .mark { cursor:pointer; position: relative; background:rgba(0, 0, 0, 0.1); } .mark::before { text-align: center; content: "点击录入元数据"; position: absolute; width:100px; top: -5px; left: 50%; transform: translate(-50%,0); padding: 5px; background-color: #444; color: #fff; opacity: 0; visibility: hidden; transition: opacity 0.3s ease, visibility 0.3s ease; border-radius: 5px; } .mark:hover::before { opacity: 1; visibility: visible; } .copyed{ font-size:30px; position:fixed; left: 50%; top:100px; transform: translate(-50%,0); z-index:99; padding:10px; background-color: #444; border-radius: 10px; display:none; color:#fff; } .showDialog{ white-space: nowrap; position:fixed; background-color: #444; border-radius: 10px; padding:18.7px; z-index:99; color:#fff; left: 50%; transform: translate(-50%,0); vertical-align: middle; display:none; } .showDialog div .right{ } .inputtext{ width: 400px; } .pointer{ cursor: pointer; } `); 'use strict'; $("body").prepend("<div class='showDialog'><div><label>端口号<input type='text' class='right inputtext port'></label></div> <br> <div> <label> <span title='点击选择文件路径' class='pointer'>database路径</span> <input type='file' style='display: none;' id='database' name='file'> <input type='text' class='right inputtext databasepath' name=''> </label> </div> <br> <div> <label> <span title='点击选择文件路径' class='pointer'>metabase路径</span> <input type='file' style='display: none;' id='metabase' name='file'> <input type='text' class='right inputtext metadatapath' > </label> </div> <br> <div class='right'> <button class='confim'>保存</button> <button class='close'>关闭</button> </div> </div>"); $("body").prepend("<a class='setting'></a>"); $("body").prepend("<div class='copyed'></div>"); $(".showDialog .close").click(function(){ $(".showDialog").hide(); }); $(".showDialog .confim").click(function(){ if( ($(".showDialog .databasepath").val()!='')&&($(".showDialog .port").val()!='')&&($(".showDialog .metadatapath").val()!='')){ if(confirm("要保存当前配置吗?")){ setting("del"); setting("add"); } }else{ alert("配置不完整"); } }); $('#database').change(function() { $(".showDialog .databasepath").val(this.value); }); $('#metabase').change(function() { $(".showDialog .metadatapath").val(this.value); }); var ehid; var url=window.location.href; var result_port; var result_appAppDatapath; var result_metadatapath; var metadatapath; const request = indexedDB.open('ex1', 1); request.onupgradeneeded = function(event) { const db = event.target.result; // 检查对象存储空间是否存在 if (!db.objectStoreNames.contains('setting')) { // 创建对象存储空间 const objectStore = db.createObjectStore('setting', { keyPath: 'name' }); } }; request.onsuccess = function(event) { const db = event.target.result; // 开始事务(读写模式) const transaction = db.transaction(['setting'], 'readwrite'); // 获取对象存储空间 const store = transaction.objectStore('setting'); // 获取数据 store.get("appAppDatapath").onsuccess = function(event) { result_appAppDatapath = event.target.result; }; store.get("port").onsuccess = function(event) { result_port = event.target.result; }; store.get("metadatapath").onsuccess = function(event) { result_metadatapath = event.target.result; }; transaction.oncomplete = function() { //端口路径为空时 if((result_appAppDatapath==undefined)||(result_port==undefined)||(result_metadatapath==undefined)){ $(".setting").html("没有设置端口或数据库文件路径,点击设置"); $(".setting").click(function(){ $(".showDialog").show(50); }); }else{ $(".setting").html("已设置端口和数据库路径"); //删除indexdb $(".setting").click(function(){ $(".showDialog .databasepath").val(result_appAppDatapath['val']); $(".showDialog .port").val(result_port['val']); $(".showDialog .metadatapath").val(result_metadatapath['val']); $(".showDialog").show(); // if(confirm("是否要清空端口和路径")){ // setting('del'); // } }); //主功能开始 //漫画详细页 if(url.indexOf("hentai.org/g/")!=-1){ //详情页显示 $("#taglist").append("<div class='mark'><div style='color:#999;text-align: center;'>未连接</div></div>"); //获取当前uid ehid='["/'+url.split("/")[4]+'/"]'; //显示有没有下载 $.ajax({ url: "http://localhost:"+result_port['val']+"/data.php", // 请求的URL method: "POST", // 请求方法,可选项包括 "GET", "POST", "PUT", "DELETE" 等. data:{ appAppDatapath:result_appAppDatapath['val'], metadatapath:result_metadatapath['val'], ehid:ehid, fun:'showDownload' }, // 请求参数,如果不需要传递参数可以省略 success: function(response) { response = eval(response)[0]; if(ehid.indexOf(response)!=-1){ $(".mark").html("<div style='color:#1b1;text-align: center;'>已下载</div>"); }else{ $(".mark").html("<div style='color:#999;text-align: center;'>未下载</div>"); } }, error: function(xhr, status, error) { console.log("请求错误:", error); } }); //点击后添加到数据库 $(".mark").click(function(){ updateSqlite(url,result_appAppDatapath['val'],result_port['val'],result_metadatapath['val']) }); } //e站搜索页面 if(url.indexOf("hentai.org")!=-1&&$("#toppane").length==1){ ehid=[]; $("#f_search").contextmenu(function(){ $("#f_search").val(""); }); //格式化搜索框内的内容 $("#f_search").change(function(){ var kw=$("#f_search").val(); kw=kw.replace(/\(.*?\)/g,''); kw=kw.replaceAll('~',''); kw=kw.replace('.zip',''); if(!isNaN(kw.substring(0,kw.indexOf("-")))){ kw=kw.substring(kw.indexOf("-")+1,kw.length); } $("#f_search").val(kw); $("#f_search").next().trigger("click"); }); $(".gl1t").append("<div class='mark'><div style='color:#999;text-align: center;'>未连接</div></div>"); $(".mark").click(function(){ updateSqlite($(this).parent().find("a").attr("href"),result_appAppDatapath['val'],result_port['val'],result_metadatapath['val']) }); $(".gl1t").each(function(){ var ehurl=$(this).find("a").attr("href"); ehurl=ehurl.split("/"); ehid.push("/"+ehurl[4]+"/"); }); $.ajax({ url: "http://localhost:"+result_port['val']+"/data.php", // 请求的URL method: "POST", // 请求方法,可选项包括 "GET", "POST", "PUT", "DELETE" 等. data: { appAppDatapath:result_appAppDatapath['val'], result_metadatapath:result_metadatapath['val'], ehid:JSON.stringify(ehid), fun:'showDownload' }, // 请求参数,如果不需要传递参数可以省略 success: function(response){ //转为对象 var back_obj = eval(response); $(".mark").html("<div style='color:#999;text-align: center;'>未下载</div>"); //遍历网址 $(".gl1t").each(function(){ //遍历返回的对象 for(let i=0;i<back_obj.length;i++){ if($(this).find("a").attr("href").indexOf(back_obj[i])!=-1){ $(this).find(".mark").html("<div style='color:#1c1;text-align: center;'>已下载</div>"); break; } } //当前页面只有一个搜素结果时自动提取meta if($(".gl1t").length==1&& $(".mark").text()=="未下载"){ $(".mark").focus(); $(".mark").trigger("click"); } }); }, error: function(xhr, status, error) { // 请求失败时的回调函数 console.log("请求错误:", error); } }); } } console.log('事务已完成'); // 关闭数据库连接 db.close(); }; }; //更新数据库 function updateSqlite(url,appAppDatapath,port,metadatapath){ //获取元数据 let match = /(\d+)\/([a-z0-9]+)/.exec(url) fetch('https://api.e-hentai.org/api.php', { method: "POST", body: JSON.stringify({ 'method': 'gdata', 'gidlist': [ [+match[1], match[2]] ], 'namespace': 1 }) }) .then(async res => { let metaobj = {} let gmetadata = await res.json() gmetadata = gmetadata.gmetadata[0] let tags = {} gmetadata.tags.forEach(tagString => { let match = /^(.+):(.+)$/.exec(tagString) if (tags[match[1]]) { tags[match[1]].push(match[2]) } else { tags[match[1]] = [match[2]] } }) metaobj.tags = tags metaobj.url = url metaobj.title = gmetadata.title metaobj.title_jpn = gmetadata.title_jpn metaobj.rating = +gmetadata.rating metaobj.posted = +gmetadata.posted metaobj.filecount = +gmetadata.filecount metaobj.category = gmetadata.category metaobj.filesize = gmetadata.filesize metaobj.status = 'tagged' var gid=gmetadata.gid //连接data.php //三次搜索,用gid搜索文件夹名,主要用于ehviewer下载的文件中所带的gid号,用日文搜索文件名,用英文搜索文件名 $.ajax({ url: "http://localhost:"+port+"/data.php", // 请求的URL method: "POST", data:{ appAppDatapath:appAppDatapath, metadatapath:metadatapath, gid:gid, metaobj:JSON.stringify(metaobj), fun:'updateDatabase' }, // 请求参数,如果不需要传递参数可以省略 success: function(response) { //无搜索结果时使用手动输入 if(response.indexOf("notfind")!=-1){ //复制 navigator.clipboard.writeText(JSON.stringify(metaobj)); $(".copyed").text("录入失败,请手动录入元数据,元数据已复制到剪切版"); } if(response.indexOf("success")!=-1){ $(".copyed").text("录入成功"); } $('.copyed').fadeIn(); // 元素开始时显示 setTimeout(function() { $('.copyed').fadeOut(); // 5秒后元素消失 }, 2000); }, error: function(xhr, status, error) { console.log("请求错误:", error); } }); }) } //设置端口和文件路径 function setting(type){ const request = indexedDB.open('ex1', 1); request.onupgradeneeded = function(event) { const db = event.target.result; // 检查对象存储空间是否存在 if (!db.objectStoreNames.contains('setting')) { // 创建对象存储空间 const objectStore = db.createObjectStore('setting', { keyPath: 'name' }); } }; request.onsuccess = function(event) { const db = event.target.result; // 开始事务(读写模式) const transaction = db.transaction(['setting'], 'readwrite'); // 获取对象存储空间 const store = transaction.objectStore('setting'); if(type=='add'){ var port = $(".showDialog .port").val(); var appAppDatapath= $(".showDialog .databasepath").val(); var metadatapath=$(".showDialog .metadatapath").val(); const data_port = { name:'port', val: port }; store.add(data_port); const data_appAppDatapath = { name:'appAppDatapath', val: appAppDatapath }; store.add(data_appAppDatapath); const data_metadatapath = { name:'metadatapath', val: metadatapath }; store.add(data_metadatapath); }else if(type=='del'){ store.delete('port'); store.delete('appAppDatapath'); store.delete('metadatapath'); } transaction.oncomplete = function() { // 关闭数据库连接 db.close(); location.reload(); }; } } })();