您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Allows for multiple cover art images to be uploaded simultaneously.
当前为
// ==UserScript== // @name MusicBrainz: Cover Art Uploader Parallel Submissions // @namespace https://musicbrainz.org/user/chaban // @version 1.0.2 // @tag ai-created // @description Allows for multiple cover art images to be uploaded simultaneously. // @author chaban // @license MIT // @match *://*.musicbrainz.org/release/*/add-cover-art* // @match *://*.musicbrainz.org/event/*/add-event-art* // @grant none // @icon https://musicbrainz.org/static/images/favicons/android-chrome-512x512.png // @run-at document-start // ==/UserScript== (function() { 'use strict'; // --- CONFIGURATION --- // The number of images to upload at the same time. const CONCURRENCY_LIMIT = 4; // --- CORE LOGIC --- // This is our replacement for the original `iteratePromises` function. // It runs a set number of promise-generating functions in parallel. function runPromisesInParallel(promiseFuncs) { const masterDeferred = $.Deferred(); const totalTasks = promiseFuncs.length; let completedTasks = 0; let activeTasks = 0; let taskIndex = 0; let hasFailed = false; function updateMasterProgress() { // Update the main progress bar based on overall completion. const overallProgress = (completedTasks / totalTasks) * 100; // We can't access the specific view model here easily, but we can // create a visual indicator if we wanted to. For now, we'll rely on the // individual progress bars. } function runNext() { if (taskIndex >= totalTasks) { // No more tasks to run. If all active tasks are finished, we're done. if (activeTasks === 0) { if (hasFailed) { masterDeferred.reject(); } else { masterDeferred.resolve(); } } return; } const currentTaskIndex = taskIndex++; const promiseFunc = promiseFuncs[currentTaskIndex]; activeTasks++; promiseFunc() .always(() => { // 'always' is like 'finally' for jQuery promises completedTasks++; activeTasks--; updateMasterProgress(); runNext(); // Start the next task in the queue }) .fail(() => { hasFailed = true; // Individual failure is already marked on the UI by MB's code. }); } // Start the initial pool of workers. for (let i = 0; i < CONCURRENCY_LIMIT && i < totalTasks; i++) { runNext(); } return masterDeferred.promise(); } // We must wait for the MB object to be available. // Using `@run-at document-start` means we need to be careful. const checkMB = setInterval(() => { if (window.MB && window.MB.Art && window.MB.Art.add_art_submit) { clearInterval(checkMB); overrideUploader(); } }, 50); function overrideUploader() { // Store the original function const original_add_art_submit = MB.Art.add_art_submit; // Overwrite it with our new version MB.Art.add_art_submit = function(gid, upvm) { // This part is mostly copied from the original function var pos = parseInt($(`#id-add-cover-art\\.position`).val(), 10); $('.add-files.row').hide(); $(`#cover-art-position-row`).hide(); $('#content')[0].scrollIntoView(); $(`#add-cover-art-submit`).prop('disabled', true); var queue = MB.Art.process_upload_queue(gid, upvm, pos); // This is the key change: call our parallel function instead of the original. runPromisesInParallel(queue) .done(function() { window.location.href = `/release/${gid}/cover-art`; }) .fail(function() { // Re-enable the submit button if any of the parallel uploads fail $(`#add-cover-art-submit`).prop('disabled', false); alert('One or more uploads failed. Please review the upload statuses and try again.'); }); }; console.log('[MusicBrainz: Cover Art Uploader Parallel Submissions] is active.'); } })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址