您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Duplicate tags for translated galleries from original galleries
// ==UserScript== // @name tagDuplicator // @namespace tagDuplicator // @description Duplicate tags for translated galleries from original galleries // @include https://exhentai.org/g/* // @include https://e-hentai.org/g/* // @version alpha // @grant none // @run-at document-end // ==/UserScript== /** * Created by atashiyuki on 2017/2/27. */ var exclude_namespaces=[ "language", "reclass", ]; var prompt_map={ "zh-CN":"请输入要导入tag的画廊地址", "en-US":"please input the link of the gallery you want to import tags from", "default":"please input the link of the gallery you want to import tags from", }; var confirm_map={ "zh-CN":"两个画廊看起来并不像同一个作品的说...即使如此仍然想要导入tag吗?", "en-US":"the two galleries are not likely to be the same piece, still want to import tags?", "default":"the two galleries are not likely to be the same piece, still want to import tags?", } var wrong_url_map={ "zh-CN":"请输入从\"https\"开始的完整的画廊链接", "en-US":"please input the complete gallery link, from \"https\"", "default":"please input the complete gallery link, from \"https\"", } function get_text_in_local_language(map){ var user_language = navigator.language || navigator.userLanguage; var text=map[user_language]; if(text==undefined) text=map.default; return text; } function get_source_sync(url){ var req=new XMLHttpRequest(); req.open('GET',url,false); req.send(); return req.response; } function get_source_async(url,call_back){ var req=new XMLHttpRequest(); req.open('GET',url,true); req.onreadystatechange=function(){ if(req.readyState === XMLHttpRequest.DONE && req.status === 200) call_back(req.response); }; req.send(); } function check_gallery(current_source, target_source) { var regexp="<h1 id=\"gj\">(.+?)\\[(.+?)\\](.+?)\\[.+?</h1>"; var result_current=current_source.match(regexp); var result_target=target_source.match(regexp); var diff=0; if(result_current==result_target) return false; for(let i=1;i<4;++i){ if((""+result_current[i]).trim()!=(""+result_target[i]).trim()) diff+=1; } return diff<=1; } function parse_tags(source_text) { var ret={}; var regexp=/return toggle_tagmenu\('(.+?)',/g; var result; while(result=regexp.exec(source_text)){ var namespace_tag=result[1].split(':'); if(namespace_tag.length==1){ namespace_tag=["misc",namespace_tag[0]]; } // do not add excluded namespaces if(exclude_namespaces.includes(namespace_tag[0])) continue; if(ret[namespace_tag[0]]==undefined) ret[namespace_tag[0]]=[]; ret[namespace_tag[0]].push(namespace_tag[1]); } return ret; } function fill_tag_field(tags){ var field=document.getElementById('newtagfield'); var text=""; for(let namespace in tags){ for(let tag of tags[namespace]){ text+=namespace+':'+tag+','; } } field.value=text; if(text.length==0) field.placeholder="no tags to add..."; } // this tool is to add tag to a translated gallery, not to farm tagging MP // please do not abuse this function subtract_tags(current_tags, tags_to_add){ var ret={}; for(let namespace in tags_to_add){ if(current_tags[namespace]==undefined){ ret[namespace]=tags_to_add[namespace]; continue; } for(let tag of tags_to_add[namespace]){ if(current_tags[namespace].includes(tag)) continue; if(ret[namespace]==undefined) ret[namespace]=[]; ret[namespace].push(tag); } } return ret; } function make_callbacks(parse,subtract,fill) { var current_finished_getting=false; var current_source=""; var target_finished_getting=false; var target_source=""; var action=function() { if(current_finished_getting&&target_finished_getting){ if(!check_gallery(current_source,target_source)){ var confirm_text=get_text_in_local_language(confirm_map); var keep=confirm(confirm_text); if(!keep) return; } var tags_current=parse(current_source); var tags_target=parse(target_source); var tags_to_add=subtract(tags_current,tags_target); fill(tags_to_add); } } return { current_callback:function(text) { current_finished_getting=true; current_source=text; action(); }, target_callback:function(text) { target_finished_getting=true; target_source=text; action(); } } } function start() { var prompt_text=get_text_in_local_language(prompt_map); var url=prompt(prompt_text); if(url.substr(0,23)!=location.href.substr(0,23)) alert(get_text_in_local_language(wrong_url_map)); var callbacks=make_callbacks(parse_tags,subtract_tags,fill_tag_field); get_source_async(window.location.href,callbacks.current_callback); get_source_async(url,callbacks.target_callback); } function init() { var div=document.getElementById("tagmenu_new"); var btn=document.createElement('input'); // use input rather than button to inherit some style btn.type="submit"; btn.name="submit"; btn.value="duplicate tags from another gallery"; btn.style.position="relative"; btn.style.bottom="55px"; btn.style.margin="0px"; btn.style.cursor="pointer"; btn.onclick=start; div.appendChild(btn); } init();