Greasy Fork

来自缓存

MB: CoverArt Uploads Auto Retry on Error

Try to take over the world!

目前为 2023-09-13 提交的版本。查看 最新版本

// ==UserScript==
// @name         MB: CoverArt Uploads Auto Retry on Error
// @namespace    https://greasyfork.org/users/321857-anakunda
// @version      1.01
// @match        https://musicbrainz.org/release/*/add-cover-art
// @match        https://musicbrainz.org/release/*/add-cover-art?*
// @description  Try to take over the world!
// @run-at       document-end
// @author       Anakunda
// @copyright    2023, Anakunda (https://greasyfork.org/users/321857-anakunda)
// @license      GPL-3.0-or-later
// @grant        GM_notification
// @grant        GM_getValue
// ==/UserScript==

{

'use strict';

function clearTimeouts(elem) {
	if (timer != undefined) { clearTimeout(timer); timer = undefined; }
	if (countdown != undefined) { clearInterval(countdown); countdown = undefined; }
	if (elem != null) elem.textContent = '--- ';
}

const btnSubmit = document.body.querySelector('button#add-cover-art-submit');
if (btnSubmit == null) throw 'Submit button not found';
let haveErrors = false, active = true, btnSuspend = null, counter = null, delay = null;
let retryCounter = 0, retryDelay = GM_getValue('retry_delay', 5), timer, countdown, s;
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 (btnSuspend == null) btnSubmit.parentNode.append(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;
				},
			}));
			if (counter == null || delay == null) {
				const wrapper = Object.assign(document.createElement('span'), {
					textContent: 'Retry ',
					style: 'display: inline-block; padding: 5pt 10pt;',
				});
				wrapper.append(counter = Object.assign(document.createElement('span'), {
					style: 'font-weight: bold; color: red;',
				}), ' in ', delay = Object.assign(document.createElement('span'), {
					style: 'font-weight: bold;',
				}), 's');
				btnSuspend.parentNode.append(wrapper);
			}
			const e = Math.log10(retryCounter++);
			if (active) {
				if (e > 0 && e == ~~e) retryDelay *= e + 1;
				timer = setTimeout(function retry(elem) {
					clearTimeouts();
					if (active && elem instanceof HTMLElement && !elem.disabled) elem.click();
				}, retryDelay * 1000 || 0, mutation.target);
				if ((s = retryDelay) > 0) {
					delay.textContent = retryDelay;
					countdown = setInterval(() => { delay.textContent = --s }, 1000, mutation.target);
				}
			}
			counter.textContent = retryCounter;
		} else if (haveErrors) {
			mo.disconnect();
			if (btnSuspend != null) btnSuspend.remove();
			if (counter != null) counter.parentNode.remove();
			GM_notification({
				text: 'Successfully completed',
				title: 'MusicBrainz',
				highlight: true,
			});
		}
}).observe(btnSubmit, { attributes: true, attributeFilter: ['disabled'] });

}