bangumi过滤搜索结果

自动去除标签搜索结果中错误的结果,手动去除你认为错误的标签或关键词搜索结果,下次搜索时将自动过滤

  1. // ==UserScript==
  2. // @name bangumi过滤搜索结果
  3. // @namespace https://github.com/bangumi/scripts/tree/master/liaune
  4. // @version 0.3.3
  5. // @description 自动去除标签搜索结果中错误的结果,手动去除你认为错误的标签或关键词搜索结果,下次搜索时将自动过滤
  6. // @author Liaune
  7. // @license MIT
  8. // @include /^https?://(bgm\.tv|chii\.in|bangumi\.tv)/*
  9. // @grant none
  10. // ==/UserScript==
  11.  
  12. (function() {
  13. // 检测 indexedDB 兼容性,因为只有新版本浏览器支持
  14. let indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB;
  15. // 初始化 indexedDB
  16. const dbName = 'Bangumi_Subject_Tags';
  17. const tableName = 'tags';
  18. const indexName = 'id';
  19. if (indexedDB) {
  20. let request = indexedDB.open(dbName, 1);
  21. request.onupgradeneeded = evt => {
  22. let db = evt.target.result;
  23. let objectStore = db.createObjectStore(tableName, {keyPath: indexName});
  24. }
  25. request.onsuccess = evt => {
  26. //removeCache();
  27. }
  28. }
  29. // 用来记录已经被使用的缓存列表
  30. let cacheLists = [];
  31. // 获取本地缓存
  32. function getCache(itemId, callback) {
  33. let request = indexedDB.open(dbName, 1);
  34. request.onsuccess = evt => {
  35. let db = evt.target.result;
  36. let transaction = db.transaction([tableName], 'readonly');
  37. let objectStore = transaction.objectStore(tableName);
  38. let reqInfo = objectStore.get(itemId);
  39. reqInfo.onsuccess = evt => {
  40. let result = evt.target.result;
  41. if(!!result) {
  42. cacheLists.push(itemId);
  43. callback(true, result.value.content);
  44. } else {
  45. callback(false);
  46. }
  47. }
  48. reqInfo.onerror = evt => {
  49. callback(false);
  50. }
  51. };
  52. }
  53. // 记录到本地缓存
  54. function setCache(itemId, data) {
  55. let request = indexedDB.open(dbName, 1);
  56. request.onsuccess = evt => {
  57. let db = evt.target.result;
  58. let transaction = db.transaction([tableName], 'readwrite');
  59. let objectStore = transaction.objectStore(tableName);
  60. let cache = {
  61. content: data,
  62. created: new Date()
  63. };
  64. let reqInfo = objectStore.put({id: itemId, value: cache})
  65. reqInfo.onerror = evt => {
  66. // console.log('Error', evt.target.error.name);
  67. }
  68. reqInfo.onsuccess = evt => {}
  69. };
  70. }
  71. // 清除和更新缓存
  72. function removeCache() {
  73. let request = indexedDB.open(dbName, 1);
  74. request.onsuccess = evt => {
  75. let db = evt.target.result;
  76. let transaction = db.transaction([tableName], 'readwrite'),
  77. store = transaction.objectStore(tableName),
  78. cacheTime = 1000*3600*24*7*4; //4周
  79. store.openCursor().onsuccess = evt => {
  80. let cursor = evt.target.result;
  81. if (cursor) {
  82. if (cacheLists.indexOf(cursor.value.name) !== -1) {
  83. cursor.value.created = new Date();
  84. cursor.update(cursor.value);
  85. } else {
  86. let now = new Date(),
  87. last = cursor.value.created;
  88. if (now - last > cacheTime) {
  89. cursor.delete();
  90. }
  91. }
  92. cursor.continue();
  93. }
  94. }
  95. };
  96. }
  97.  
  98.  
  99.  
  100. let itemsList,blacklist,type,key,count=0,see=0;
  101. const hotTags = ['TV','剧场版','漫画改','原创','搞笑','OVA','轻小说改','里番'];
  102.  
  103. if(localStorage.getItem('bangumi_result_blacklist'))
  104. blacklist = JSON.parse(localStorage.getItem('bangumi_result_blacklist'));
  105. else
  106. blacklist = {"tag":{},"subject_search":{}};
  107. //let match = decodeURI(location.href).match(/(tag|subject_search)\/(\S+)(\/|.?).*/);
  108. let match = decodeURI(location.pathname).match(/(tag|subject_search)/);
  109. if(match){
  110. type = match[1];
  111. let arr = decodeURI(location.pathname).split('/');
  112. let index = arr.findIndex((e)=> e == type);
  113. key = arr[index+1];
  114. let showBtn = document.createElement('li');
  115. let select = document.createElement('a'); $(select).css({"background-image": "url(https://i.loli.net/2018/11/04/5bdef15ba9076.png)","background-size": "1600px 2444px","background-position": "-405px -1045px"});
  116. select.href='javascript:;';
  117. if(document.querySelectorAll('#browserTypeSelector li')[0]) document.querySelector('#browserTypeSelector').insertBefore(showBtn, document.querySelectorAll('#browserTypeSelector li')[0]);
  118. showBtn.appendChild(select);
  119. select.addEventListener('click', filter);
  120.  
  121. filter();
  122. see = 0;
  123. }
  124. function filter(){
  125. count = 0;
  126. itemsList = document.querySelectorAll('#browserItemList li.item');
  127. if(!itemsList.length) return 0;
  128. see = (see==1)? 0 :1;
  129. if(!blacklist[type][key]) blacklist[type][key] = [];
  130. let fetchList = [];
  131. itemsList.forEach( (elem) => {
  132. let href = elem.querySelector('a.subjectCover').href;
  133. let ID = href.split('/subject/')[1];
  134.  
  135. let hideBtn = document.createElement('a'); hideBtn.href='javascript:;'; hideBtn.className = 'delet-icon'; hideBtn.textContent = '☒'; hideBtn.style.float='right';
  136. hideBtn.addEventListener('click', function(){
  137. if(blacklist[type][key].includes(ID)){
  138. blacklist[type][key].splice(blacklist[type][key].indexOf(ID),1);
  139. alert("已将此条目从黑名单中移除");
  140. localStorage.setItem('bangumi_result_blacklist',JSON.stringify(blacklist));
  141. }
  142. else{
  143. $(elem).hide();
  144. blacklist[type][key].push(ID);
  145. localStorage.setItem('bangumi_result_blacklist',JSON.stringify(blacklist));
  146. }
  147. });
  148. if(!$(elem).find('.delet-icon').length) elem.appendChild(hideBtn);
  149.  
  150. if(blacklist[type][key].includes(ID)){
  151. if(see) $(elem).hide();
  152. else $(elem).show();
  153. count++;
  154. }
  155. else if(type == 'tag'){
  156. getCache(ID, function(success, result) {
  157. if (success) {
  158. if(!result.includes(key)){
  159. blacklist[type][key].push(ID);
  160. localStorage.setItem('bangumi_result_blacklist',JSON.stringify(blacklist));
  161. $(elem).hide();
  162. }
  163. }
  164. else{
  165. fetchList.push(elem);
  166. }
  167. });
  168. fetchList.push(elem);
  169. }
  170. else count++;
  171. });
  172. let i = 0;
  173. let getitemsList= setInterval(function(){
  174. let elem = fetchList[i];
  175. if(elem){
  176. let href = elem.querySelector('a.subjectCover').href;
  177. getStatus(href,elem);
  178. i++;
  179. }
  180. if(count >= itemsList.length){
  181. clearInterval(getitemsList);
  182. }
  183. },300);
  184. }
  185.  
  186. function getStatus(href,elem){
  187. let xhr = new XMLHttpRequest();
  188. xhr.open( "GET", href );
  189. xhr.withCredentials = true;
  190. xhr.responseType = "document";
  191. xhr.send();
  192. xhr.onload = function(){
  193. let d = xhr.responseXML;
  194. let ID = href.split('/subject/')[1];
  195. let tagList = d.querySelectorAll('#subject_detail .subject_tag_section .inner a.l');
  196. let tagsAll = {"tag":[],"vote":[]};
  197. for(let i=0;i<tagList.length;i++){
  198. tagsAll.tag.push(tagList[i].querySelector('span').textContent);
  199. tagsAll.vote.push(tagList[i].querySelector('small').textContent);
  200. }
  201. let Tags = [];
  202. for(let i=0;i<tagsAll.tag.length;i++){
  203. if(checkTag(tagsAll.tag[i]) && parseInt(tagsAll.vote[i])>= Math.min(10,parseInt(tagsAll.vote[0])/10))
  204. Tags.push(tagsAll.tag[i]);
  205. }
  206. Tags = Tags.slice(0,Math.min(10,Tags.length));
  207. console.log('check '+ID+':'+Tags);
  208. setCache(ID,Tags);
  209. let TagsN = Tags;
  210. if(hotTags.includes(key)){
  211. TagsN = Tags.slice(0,5);
  212. }
  213. if(!TagsN.includes(key)){
  214. blacklist[type][key].push(ID);
  215. localStorage.setItem('bangumi_result_blacklist',JSON.stringify(blacklist));
  216. $(elem).hide();
  217. }
  218. count++;
  219. }
  220. }
  221.  
  222. function checkTag(Tag){
  223. function parseDate(Datestring){
  224. let yy=Datestring.match(/(\d{4})/)? Datestring.match(/(\d{4})/)[1].toString():'';
  225. let year = Datestring.match(/(\d{4})(年|-)(\d{1,2})(月|-)(\d{1,2})/)? Datestring.match(/(\d{4})(年|-)(\d{1,2})(月|-)(\d{1,2})/)[1].toString(): yy;
  226. let month = Datestring.match(/(\d{4})(年|-)(\d{1,2})(月|-)(\d{1,2})/)? Datestring.match(/(\d{4})(年|-)(\d{1,2})(月|-)(\d{1,2})/)[3].toString(): '';
  227. let day = Datestring.match(/(\d{4})(年|-)(\d{1,2})(月|-)(\d{1,2})/)?Datestring.match(/(\d{4})(年|-)(\d{1,2})(月|-)(\d{1,2})/)[5].toString(): '';
  228. let time = year? (month? (year+'/'+month+'/'+day):year):'';
  229. return time;
  230. }
  231. if(!Tag) return false;
  232. else if(parseDate(Tag)!='') return false;
  233. else return true;
  234. }
  235.  
  236. //设置
  237. if(document.location.href.match(/settings/)){
  238. $("#header > ul").append('<li><a id="blacklist" href="javascript:void(0);"><span>blacklist</span></a></li>');
  239. $("#blacklist").on("click", function() {
  240. $("#header").find("[class='selected']").removeClass("selected");
  241. $("#blacklist").addClass("selected");
  242. let data= localStorage.getItem('bangumi_result_blacklist');
  243. let html = '<form>' +
  244. '<span class="text">以下是你所保存的搜索结果过滤黑名单,你可以编辑和替换,点击"确定"即可保存修改</span>'+
  245. '<textarea id="data_content" name="content" cols="45" rows="15" style="width: 1000px;" class="quick">'+data+'</textarea>'+
  246. '<input id="submitBtn" class="inputBtn" value="确定" readonly unselectable="on" style="width:26px">' +
  247. '<a id="alert_submit" style="color: #F09199; font-size: 14px; padding: 20px"></a>'+
  248. '</form>';
  249. $("#columnA").html(html);
  250. $("#submitBtn").on("click", function() {
  251. data = $("#data_content").attr("value");
  252. localStorage.setItem('bangumi_result_blacklist',data);
  253. alert('保存成功!');
  254. });
  255. });
  256. }
  257. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址