您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
On a fandom tag's Landing Page, writes out how many wranglers are currently assigned to the listed subfandoms
当前为
// ==UserScript== // @name AO3: [Wrangling] Count Wranglers on Subfandoms // @namespace https://gf.qytechs.cn/en/users/906106-escctrl // @description On a fandom tag's Landing Page, writes out how many wranglers are currently assigned to the listed subfandoms // @author escctrl // @version 0.1 // @match *://*.archiveofourown.org/tags/* // @require https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js // @license MIT // ==/UserScript== (function($) { 'use strict'; // wait duration between checking individual bins - set this number higher if you often run into Retry Later // this applies especially to huge fandom trees like DCU!! 3sec is NOT enough for the full list! make this number huge and let it run in the background // defined in milliseconds, e.g. 3000 = 3 seconds const interval = 5000; const subfandoms = document.getElementsByClassName('sub')[0]; if ($('div.parent.fandom').length == 0) { console.log('Count Wranglers on Subfandoms script says: this is not a fandom tag'); return true; } // bow out gracefully if we're not looking at a fandom if (subfandoms == null) { console.log('Count Wranglers on Subfandoms script says: fandom doesn\'t have subfandoms'); return true; } // bow out gracefully if the fandom has no subfandoms // some code to add *) hidden span to track ao3jail *) span for progress bar/report global results, *) button to start the checking $(subfandoms).children('h3.heading').before('<span id="countwranglers-jail" style="display: none;"></span>' + '<span id="countwranglers-unwrangled" style="display: none;">0</span>' + '<span id="countwranglers-results" style="float:right;"><button id="countwranglers">Count Wranglers</button></span>'); // assign the function to the click event (will trigger only once user clicked the link) $(subfandoms).find('button#countwranglers').click(countWranglers); // a function that gets run on button push function countWranglers() { // checking that the click event actually worked var progress = document.getElementById('countwranglers-results'); $(progress).css("padding", "0.3em 0.25em"); $(progress).html('Counting wranglers... grab a drink, this may take a while!'); // find all the subfandoms var fandoms = $(subfandoms).find('ul.tree a'); // immediately add a span placeholder next to each fandom for the # of wranglers, show TBD until the fandom was checked // this is basically our progress bar while the script slowly works down the fandom tree $(fandoms).after('<span style="font-size: smaller;"> <em>... wranglers TBD</em></span>'); // loop through the unwrangled bins $(fandoms).each(function(i, fandom) { // set a delay between bin checks to reduce chances of jail setTimeout(function() { // if previous loops hit Ao3 Jail, don't try looking for wranglers anymore if ( document.getElementById('countwranglers-jail').innerText == "true") { console.log('previously received "Retry later" response, skipped check on subfandom'); return false; } var assignedCount = 0; var unwrangledTotal = document.getElementById('countwranglers-unwrangled'); // retrieve the data from the fandom tag's edit page $.get(fandom.href + '/edit', function(response) { // nothing to do here, all interactions are in done() and failed() // do stuff on success (write out how many wranglers are on a fandom tag, add an Edit link when 0, and count global unwrangled's up) }).done(function(response) { // pick the correct field in the form containing the assigned wranglers var assignedWranglers = $(response).find('#edit_tag fieldset:first dd:nth-of-type(4)').text(); var unwrangledCount = parseInt(unwrangledTotal.innerText); // unwrangled fandoms have a Sign Up link here if (assignedWranglers == 'Sign Up') { // count up the global total of unwrangled subfandoms unwrangledCount++; unwrangledTotal.innerText = unwrangledCount.toString(); // update the fandom tag with that information and put in an Edit & Wrangle child tags button for convenience $(fandom).next().html(' ... unwrangled [<a href="'+ fandom.href + '/edit">Edit</a>] [<a href="'+ fandom.href + '/wrangle">Wrangle</a>]'); // highlight the fandom tag to make it easily findable in a long list $(fandom).parent().css("background-color", "yellow"); } // assigned wranglers are plaintext else { // split the a comma-seperated list into an array and count its length (that's the number of wranglers) assignedCount = assignedWranglers.split(', ').length; // update the fandom tag with that information $(fandom).next().html(' ... '+ assignedCount +' wrangler' + ((assignedCount > 1) ? "s" : "")); } // if last loop also succeeded, update global progress with "all wrangled" or "# unwrangled" if (fandoms.length == i+1) { if (unwrangledCount == 0) { $(progress).html('all subfandoms are wrangled \\o/'); } else { $(progress).html(unwrangledCount + ' subfandoms unwrangled'); } } // thanks to Przemysław Sienkiewicz on Stackoverflow for the code to catch error responses https://stackoverflow.com/a/40256829 // do other stuff on fail (set the ao3jail marker) }).fail(function(data, textStatus, xhr) { // update user on the issue $(progress).html('Wrangler Count has hit "Retry later", sorry!'); document.getElementById('countwranglers-jail').innerText = "true"; // set it in DOM so next delayed loops can skip //This shows status code eg. 429 console.log("Wrangler Count has hit Retry later", data.status); //This shows status message eg. Too Many Requests //console.log("bin #"+i+" STATUS: "+xhr); return false; }); // the each() loops immediately and creates all timeout calls (async) at once, so we need to stagger them // by multiplying the 3s delay by the loop number (bin #0 = 3000*0, bin #1 = 3000*1, bin #2 = 3000*2, etc) }, interval*i); }); // end each } // end function })(jQuery);
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址