Greasy Fork is available in English.
Try to take over the world!
当前为
// ==UserScript==
// @name MB: CoverArt Uploads Auto Retry on Error
// @namespace http://greasyfork.icu/users/321857-anakunda
// @version 1.02
// @match https://musicbrainz.org/release/*/add-cover-art
// @match https://musicbrainz.org/release/*/add-cover-art?*
// @run-at document-end
// @author Anakunda
// @copyright 2023, Anakunda (http://greasyfork.icu/users/321857-anakunda)
// @license GPL-3.0-or-later
// @grant GM_notification
// @grant GM_getValue
// @description Try to take over the world!
// ==/UserScript==
{
'use strict';
function clearTimeouts(countdown) {
if (timer != undefined) { clearTimeout(timer); timer = undefined; }
if (countdownTimer != undefined) { clearInterval(countdownTimer); countdownTimer = undefined; }
if (controls == null) return;
if ((countdown || (countdown = controls.querySelector('span#countdown'))) != null) countdown.textContent = '--- ';
}
const btnSubmit = document.body.querySelector('button#add-cover-art-submit');
if (btnSubmit == null) throw 'Submit button not found';
let haveErrors = false, active = true, controls = null, timer, countdownTimer, countdownTime;
let retryCounter = 0, retryDelay = GM_getValue('retry_delay', 5);
const captions = ['Suspend', 'Resume'];
new MutationObserver(function(ml, mo) {
clearTimeouts();
for (let mutation of ml) if (!mutation.target.disabled)
if (Array.prototype.some.call(document.querySelectorAll('form#add-cover-art > table > tbody > tr > td > span.msg.error'),
span => span.style.display != 'none' && /^⚠ (?:Server busy|Error)\b/.test(span.textContent.trim()))) {
haveErrors = true;
if (controls == null) {
controls = document.createElement('span');
var btnSuspend = Object.assign(document.createElement('button'), {
textContent: captions[0],
id: 'autoretry',
style: 'padding: 5px 10px 5px 7px; margin-left: 1em;',
onclick: function(evt) {
evt.currentTarget.textContent = captions[(active = !active) ? 0 : 1] + ' autoretry';
clearTimeouts();
return false;
},
});
const wrapper = Object.assign(document.createElement('span'), {
style: 'display: inline-block; padding: 5pt 10pt;',
});
var retryCounter = Object.assign(document.createElement('span'), {
style: 'font-weight: bold; color: red;',
id: 'retry-counter',
}), countdown = Object.assign(document.createElement('span'), {
style: 'font-weight: bold;',
id: 'countdown',
});
wrapper.append('Retry ', retryCounter, ' in ', countdown, 's');
controls.append(btnSuspend, wrapper);
btnSuspend.parentNode.append(controls);
} else [retryCounter, countdown] =
['retry-counter', 'countdown'].map(id => controls.querySelector('span#' + id));
if (retryCounter != null) retryCounter.textContent = retryCounter;
const e = Math.log10(retryCounter++);
if (e > 0 && e == ~~e) retryDelay *= e + 1;
if (active) timer = setTimeout(function(elem) {
clearTimeouts(countdown);
if (active && elem instanceof HTMLElement && !elem.disabled) elem.click();
}, retryDelay * 1000 || 0, mutation.target); else continue;
if (countdown != null && (countdownTime = retryDelay) > 0) {
countdown.textContent = retryDelay;
countdown = setInterval(elem => { elem.textContent = --countdownTime }, 1000, countdown);
}
} else if (haveErrors) {
mo.disconnect();
if (controls != null) controls.remove();
GM_notification({ text: 'Successfully completed', title: 'MusicBrainz', highlight: true });
}
}).observe(btnSubmit, { attributes: true, attributeFilter: ['disabled'] });
}