您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds AniList links for each show in release list
// ==UserScript== // @name SubsPlease AniList // @namespace https://github.com/ipha/userscripts // @version 1.4.1 // @description Adds AniList links for each show in release list // @author ipha // @license MIT // @match https://subsplease.org/ // @connect graphql.anilist.co // @grant GM_xmlhttpRequest // @grant GM_addStyle // @grant GM_setValue // @grant GM_getValue // ==/UserScript== (function () { 'use strict'; // anilist graphql stuff var query = ` query ($search: String) { Media(search: $search, type: ANIME) { siteUrl } }`; // Watch for changes on release list var mutationConfig = { attributes: false, childList: true, subtree: false }; // Watch for changes in table function mutationCallback(mutationsList) { for (var mutation of mutationsList) { if (mutation.type == 'childList') { addBadges(); } } } var observer = new MutationObserver(mutationCallback); observer.observe(document.querySelector('#releases-table'), mutationConfig); // Time to keep cached URLs // Two weeks in ms const CACHE_VALID_TIME = 1000 * 60 * 60 * 24 * 14; // Save URL and timestamp in cache function setCache(name, url) { GM_setValue(name, [url, Date.now()]); } // Fetch URL from cache function getCache(name) { var cache = GM_getValue(name, undefined) if (cache && ((Date.now() - cache[1]) < CACHE_VALID_TIME)) { return cache[0]; } else { return undefined; } } // Search MAL for 'name'. Returns first result of type 'TV' // TODO: This probably doesn't work for OVAs function fetchLink(name, callback) { var ret = GM_xmlhttpRequest({ method: "POST", headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', }, responseType: "json", url: "https://graphql.anilist.co", data: JSON.stringify({ query: query, variables: { search: name } }), onload: function (res) { // todo: error handling var url = res.response.data.Media.siteUrl setCache(name, url); callback(url); } }); } // Add MAL badge next to release resolutions function addBadges() { // var time = Date.now() document.querySelectorAll('#releases-table .badge-wrapper').forEach(function (item) { if (item.textContent.search("AniList") == -1) { var name = item.parentElement.querySelector('a').textContent.split(' - ')[0]; var a = document.createElement("a"); var s = document.createElement("span"); a.appendChild(s); s.append("AniList"); s.classList.add("badge"); item.appendChild(a); var cachedURL = getCache(name); if (cachedURL) { console.log("Cache hit for:", name); a.href = cachedURL; // console.log(Date.now() - time); } else { console.log("Cache miss for:", name); fetchLink(name, function (url) { a.href = url; // console.log(Date.now() - time); }); } } }); } // cached page loads don't trigger the observer addBadges(); })();