- // ==UserScript==
- // @name bangumi过滤搜索结果
- // @namespace https://github.com/bangumi/scripts/tree/master/liaune
- // @version 0.3.3
- // @description 自动去除标签搜索结果中错误的结果,手动去除你认为错误的标签或关键词搜索结果,下次搜索时将自动过滤
- // @author Liaune
- // @license MIT
- // @include /^https?://(bgm\.tv|chii\.in|bangumi\.tv)/*
- // @grant none
- // ==/UserScript==
-
- (function() {
- // 检测 indexedDB 兼容性,因为只有新版本浏览器支持
- let indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB;
- // 初始化 indexedDB
- const dbName = 'Bangumi_Subject_Tags';
- const tableName = 'tags';
- const indexName = 'id';
- if (indexedDB) {
- let request = indexedDB.open(dbName, 1);
- request.onupgradeneeded = evt => {
- let db = evt.target.result;
- let objectStore = db.createObjectStore(tableName, {keyPath: indexName});
- }
- request.onsuccess = evt => {
- //removeCache();
- }
- }
- // 用来记录已经被使用的缓存列表
- let cacheLists = [];
- // 获取本地缓存
- function getCache(itemId, callback) {
- let request = indexedDB.open(dbName, 1);
- request.onsuccess = evt => {
- let db = evt.target.result;
- let transaction = db.transaction([tableName], 'readonly');
- let objectStore = transaction.objectStore(tableName);
- let reqInfo = objectStore.get(itemId);
- reqInfo.onsuccess = evt => {
- let result = evt.target.result;
- if(!!result) {
- cacheLists.push(itemId);
- callback(true, result.value.content);
- } else {
- callback(false);
- }
- }
- reqInfo.onerror = evt => {
- callback(false);
- }
- };
- }
- // 记录到本地缓存
- function setCache(itemId, data) {
- let request = indexedDB.open(dbName, 1);
- request.onsuccess = evt => {
- let db = evt.target.result;
- let transaction = db.transaction([tableName], 'readwrite');
- let objectStore = transaction.objectStore(tableName);
- let cache = {
- content: data,
- created: new Date()
- };
- let reqInfo = objectStore.put({id: itemId, value: cache})
- reqInfo.onerror = evt => {
- // console.log('Error', evt.target.error.name);
- }
- reqInfo.onsuccess = evt => {}
- };
- }
- // 清除和更新缓存
- function removeCache() {
- let request = indexedDB.open(dbName, 1);
- request.onsuccess = evt => {
- let db = evt.target.result;
- let transaction = db.transaction([tableName], 'readwrite'),
- store = transaction.objectStore(tableName),
- cacheTime = 1000*3600*24*7*4; //4周
- store.openCursor().onsuccess = evt => {
- let cursor = evt.target.result;
- if (cursor) {
- if (cacheLists.indexOf(cursor.value.name) !== -1) {
- cursor.value.created = new Date();
- cursor.update(cursor.value);
- } else {
- let now = new Date(),
- last = cursor.value.created;
- if (now - last > cacheTime) {
- cursor.delete();
- }
- }
- cursor.continue();
- }
- }
- };
- }
-
-
-
- let itemsList,blacklist,type,key,count=0,see=0;
- const hotTags = ['TV','剧场版','漫画改','原创','搞笑','OVA','轻小说改','里番'];
-
- if(localStorage.getItem('bangumi_result_blacklist'))
- blacklist = JSON.parse(localStorage.getItem('bangumi_result_blacklist'));
- else
- blacklist = {"tag":{},"subject_search":{}};
- //let match = decodeURI(location.href).match(/(tag|subject_search)\/(\S+)(\/|.?).*/);
- let match = decodeURI(location.pathname).match(/(tag|subject_search)/);
- if(match){
- type = match[1];
- let arr = decodeURI(location.pathname).split('/');
- let index = arr.findIndex((e)=> e == type);
- key = arr[index+1];
- let showBtn = document.createElement('li');
- 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"});
- select.href='javascript:;';
- if(document.querySelectorAll('#browserTypeSelector li')[0]) document.querySelector('#browserTypeSelector').insertBefore(showBtn, document.querySelectorAll('#browserTypeSelector li')[0]);
- showBtn.appendChild(select);
- select.addEventListener('click', filter);
-
- filter();
- see = 0;
- }
- function filter(){
- count = 0;
- itemsList = document.querySelectorAll('#browserItemList li.item');
- if(!itemsList.length) return 0;
- see = (see==1)? 0 :1;
- if(!blacklist[type][key]) blacklist[type][key] = [];
- let fetchList = [];
- itemsList.forEach( (elem) => {
- let href = elem.querySelector('a.subjectCover').href;
- let ID = href.split('/subject/')[1];
-
- let hideBtn = document.createElement('a'); hideBtn.href='javascript:;'; hideBtn.className = 'delet-icon'; hideBtn.textContent = '☒'; hideBtn.style.float='right';
- hideBtn.addEventListener('click', function(){
- if(blacklist[type][key].includes(ID)){
- blacklist[type][key].splice(blacklist[type][key].indexOf(ID),1);
- alert("已将此条目从黑名单中移除");
- localStorage.setItem('bangumi_result_blacklist',JSON.stringify(blacklist));
- }
- else{
- $(elem).hide();
- blacklist[type][key].push(ID);
- localStorage.setItem('bangumi_result_blacklist',JSON.stringify(blacklist));
- }
- });
- if(!$(elem).find('.delet-icon').length) elem.appendChild(hideBtn);
-
- if(blacklist[type][key].includes(ID)){
- if(see) $(elem).hide();
- else $(elem).show();
- count++;
- }
- else if(type == 'tag'){
- getCache(ID, function(success, result) {
- if (success) {
- if(!result.includes(key)){
- blacklist[type][key].push(ID);
- localStorage.setItem('bangumi_result_blacklist',JSON.stringify(blacklist));
- $(elem).hide();
- }
- }
- else{
- fetchList.push(elem);
- }
- });
- fetchList.push(elem);
- }
- else count++;
- });
- let i = 0;
- let getitemsList= setInterval(function(){
- let elem = fetchList[i];
- if(elem){
- let href = elem.querySelector('a.subjectCover').href;
- getStatus(href,elem);
- i++;
- }
- if(count >= itemsList.length){
- clearInterval(getitemsList);
- }
- },300);
- }
-
- function getStatus(href,elem){
- let xhr = new XMLHttpRequest();
- xhr.open( "GET", href );
- xhr.withCredentials = true;
- xhr.responseType = "document";
- xhr.send();
- xhr.onload = function(){
- let d = xhr.responseXML;
- let ID = href.split('/subject/')[1];
- let tagList = d.querySelectorAll('#subject_detail .subject_tag_section .inner a.l');
- let tagsAll = {"tag":[],"vote":[]};
- for(let i=0;i<tagList.length;i++){
- tagsAll.tag.push(tagList[i].querySelector('span').textContent);
- tagsAll.vote.push(tagList[i].querySelector('small').textContent);
- }
- let Tags = [];
- for(let i=0;i<tagsAll.tag.length;i++){
- if(checkTag(tagsAll.tag[i]) && parseInt(tagsAll.vote[i])>= Math.min(10,parseInt(tagsAll.vote[0])/10))
- Tags.push(tagsAll.tag[i]);
- }
- Tags = Tags.slice(0,Math.min(10,Tags.length));
- console.log('check '+ID+':'+Tags);
- setCache(ID,Tags);
- let TagsN = Tags;
- if(hotTags.includes(key)){
- TagsN = Tags.slice(0,5);
- }
- if(!TagsN.includes(key)){
- blacklist[type][key].push(ID);
- localStorage.setItem('bangumi_result_blacklist',JSON.stringify(blacklist));
- $(elem).hide();
- }
- count++;
- }
- }
-
- function checkTag(Tag){
- function parseDate(Datestring){
- let yy=Datestring.match(/(\d{4})/)? Datestring.match(/(\d{4})/)[1].toString():'';
- 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;
- let month = Datestring.match(/(\d{4})(年|-)(\d{1,2})(月|-)(\d{1,2})/)? Datestring.match(/(\d{4})(年|-)(\d{1,2})(月|-)(\d{1,2})/)[3].toString(): '';
- let day = Datestring.match(/(\d{4})(年|-)(\d{1,2})(月|-)(\d{1,2})/)?Datestring.match(/(\d{4})(年|-)(\d{1,2})(月|-)(\d{1,2})/)[5].toString(): '';
- let time = year? (month? (year+'/'+month+'/'+day):year):'';
- return time;
- }
- if(!Tag) return false;
- else if(parseDate(Tag)!='') return false;
- else return true;
- }
-
- //设置
- if(document.location.href.match(/settings/)){
- $("#header > ul").append('<li><a id="blacklist" href="javascript:void(0);"><span>blacklist</span></a></li>');
- $("#blacklist").on("click", function() {
- $("#header").find("[class='selected']").removeClass("selected");
- $("#blacklist").addClass("selected");
- let data= localStorage.getItem('bangumi_result_blacklist');
- let html = '<form>' +
- '<span class="text">以下是你所保存的搜索结果过滤黑名单,你可以编辑和替换,点击"确定"即可保存修改</span>'+
- '<textarea id="data_content" name="content" cols="45" rows="15" style="width: 1000px;" class="quick">'+data+'</textarea>'+
- '<input id="submitBtn" class="inputBtn" value="确定" readonly unselectable="on" style="width:26px">' +
- '<a id="alert_submit" style="color: #F09199; font-size: 14px; padding: 20px"></a>'+
- '</form>';
- $("#columnA").html(html);
- $("#submitBtn").on("click", function() {
- data = $("#data_content").attr("value");
- localStorage.setItem('bangumi_result_blacklist',data);
- alert('保存成功!');
- });
- });
- }
- })();