From 80a1ae36e27488197b34d1077f7786231ccb51d0 Mon Sep 17 00:00:00 2001 From: TadusPro Date: Mon, 26 Feb 2024 20:44:19 +0100 Subject: [PATCH 01/44] ratelimit handeling fully supporting the new 2 types of ratelimits --- lib/muledump/mule.js | 11 +- lib/setuptools/src/mulequeue.js | 656 +++++++++++++++++++------------- 2 files changed, 392 insertions(+), 275 deletions(-) diff --git a/lib/muledump/mule.js b/lib/muledump/mule.js index 71f722ef..e0e4c118 100644 --- a/lib/muledump/mule.js +++ b/lib/muledump/mule.js @@ -578,6 +578,15 @@ xhr.done(onResponse).fail(onFail) } ); + //check if response is equal to "Internal error, please wait 5 minutes to try again!" + } else if (xml === "Internal error, please wait 5 minutes to try again!") { + self.queueFinish(self.guid, 'hardRateLimited', 'Request was rate limited by Appspot'); + console.log('Your IP is being rate limited by Deca. Waiting 5 minutes to retry. test'); + window.RateLimitExpiration = Date.now() + 301000; + try { + localStorage['muledump:ratelimitexpiration'] = 301000 + } catch (e) { } + } else { self.queueFinish(self.guid, 'error', false, xml); self.error(xml); @@ -2233,4 +2242,4 @@ window.Mule = Mule -})($, window); +})($, window); \ No newline at end of file diff --git a/lib/setuptools/src/mulequeue.js b/lib/setuptools/src/mulequeue.js index 6f739d41..2bf8018d 100644 --- a/lib/setuptools/src/mulequeue.js +++ b/lib/setuptools/src/mulequeue.js @@ -20,19 +20,19 @@ setuptools.app.mulequeue = { }, queue: [], // list of guids in queue (corresponds to tasks) tasks: {}, // task configuration data - history: {data: []}, // history of queue tasks + history: { data: [] }, // history of queue tasks }; // initialize mulequeue -setuptools.app.mulequeue.main = function() { +setuptools.app.mulequeue.main = function () { // some config sanity - if ( $.isNumeric(setuptools.data.config.mqConcurrent) === false || setuptools.data.config.mqConcurrent > 30 ) setuptools.data.config.mqConcurrent = 1; + if ($.isNumeric(setuptools.data.config.mqConcurrent) === false || setuptools.data.config.mqConcurrent > 30) setuptools.data.config.mqConcurrent = 1; // check if we're already rate limited setuptools.app.mulequeue.state.rateLimitExpiration = setuptools.storage.read('ratelimitexpiration'); - if ( !setuptools.app.mulequeue.state.rateLimitExpiration ) setuptools.app.mulequeue.state.rateLimitExpiration = Date.now(); - if ( setuptools.app.mulequeue.state.rateLimitExpiration > new Date ) setuptools.app.mulequeue.task.rateLimit(true); + if (!setuptools.app.mulequeue.state.rateLimitExpiration) setuptools.app.mulequeue.state.rateLimitExpiration = Date.now(); + if (setuptools.app.mulequeue.state.rateLimitExpiration > new Date) setuptools.app.mulequeue.task.rateLimit(true); // start the background task setuptools.app.mulequeue.task.background(); @@ -47,10 +47,10 @@ setuptools.app.mulequeue.main = function() { /*/ // background tasks health checker -setuptools.app.mulequeue.task.bgHealth = function() { +setuptools.app.mulequeue.task.bgHealth = function () { // check how long it has been since the background task last ran - if ( (setuptools.app.mulequeue.state.rateLimited === false && setuptools.app.mulequeue.state.paused === false) && new Date > (Number(setuptools.app.mulequeue.state.bgPing)+(setuptools.data.config.mqBGTimeout*1000)) ) { + if ((setuptools.app.mulequeue.state.rateLimited === false && setuptools.app.mulequeue.state.paused === false) && new Date > (Number(setuptools.app.mulequeue.state.bgPing) + (setuptools.data.config.mqBGTimeout * 1000))) { window.techlog('MuleQueue/bgHealth starting background task'); setuptools.app.mulequeue.state.active = false; @@ -65,7 +65,7 @@ setuptools.app.mulequeue.task.bgHealth = function() { }; // update the background health state -setuptools.app.mulequeue.task.ping = function() { +setuptools.app.mulequeue.task.ping = function () { setuptools.app.mulequeue.state.bgPing = new Date; setuptools.app.mulequeue.state.bgHealth = true; @@ -73,13 +73,13 @@ setuptools.app.mulequeue.task.ping = function() { }; // create a task promise and run the task -setuptools.app.mulequeue.task.createPromise = function(guid) { +setuptools.app.mulequeue.task.createPromise = function (guid) { return new Promise(function (MuleQueue) { var task = setuptools.app.mulequeue.tasks[guid]; window.techlog('MuleQueue/TaskStart - ' + guid); - if ( mules[guid] instanceof Mule ) { + if (mules[guid] instanceof Mule) { mules[guid].query(task.ignore_cache, task.cache_only, false, MuleQueue); } else setuptools.app.mulequeue.task.cancel(guid); @@ -88,10 +88,10 @@ setuptools.app.mulequeue.task.createPromise = function(guid) { }; // background tasks processes queue items -setuptools.app.mulequeue.task.background = function() { +setuptools.app.mulequeue.task.background = function () { // start the background task if it isn't already running - if ( !setuptools.app.mulequeue.state.bgTask ) { + if (!setuptools.app.mulequeue.state.bgTask) { setuptools.app.mulequeue.state.bgTask = setInterval( setuptools.app.mulequeue.task.background, @@ -109,19 +109,19 @@ setuptools.app.mulequeue.task.background = function() { ) setuptools.app.mulequeue.queuemanager.Modifiers.callbacks.update(); // check for rate limiting - if ( setuptools.app.mulequeue.state.rateLimited === true ) { + if (setuptools.app.mulequeue.state.rateLimited === true) { setuptools.app.mulequeue.task.ping(); return; } // don't run if background task is already active or paused - if ( setuptools.app.mulequeue.state.active === true ) return; + if (setuptools.app.mulequeue.state.active === true) return; // ping setuptools.app.mulequeue.task.ping(); // check if the queue is paused - if ( setuptools.app.mulequeue.state.paused === true ) return; + if (setuptools.app.mulequeue.state.paused === true) return; // check for queue items if ( @@ -134,16 +134,16 @@ setuptools.app.mulequeue.task.background = function() { $('#mulequeue').addClass('running'); // log queue size if larger than peak - if ( setuptools.app.mulequeue.queue.length > setuptools.app.mulequeue.state.queuePeak ) setuptools.app.mulequeue.state.queuePeak = setuptools.app.mulequeue.queue.length; + if (setuptools.app.mulequeue.queue.length > setuptools.app.mulequeue.state.queuePeak) setuptools.app.mulequeue.state.queuePeak = setuptools.app.mulequeue.queue.length; // if this is the top of a cycle, check if the minimum cycle delay has passed - var lastRunDifference = ((new Date)-setuptools.app.mulequeue.state.lastTaskFinished)/1000; + var lastRunDifference = ((new Date) - setuptools.app.mulequeue.state.lastTaskFinished) / 1000; if ( setuptools.app.mulequeue.state.busy === 0 && lastRunDifference < window.accountLoadDelay ) { - window.techlog('MuleQueue/TaskWait - ' + Math.ceil(window.accountLoadDelay-lastRunDifference) + ' seconds until next cycle', 'aggregate'); + window.techlog('MuleQueue/TaskWait - ' + Math.ceil(window.accountLoadDelay - lastRunDifference) + ' seconds until next cycle', 'aggregate'); return; } @@ -153,18 +153,18 @@ setuptools.app.mulequeue.task.background = function() { setuptools.app.mulequeue.state.running = true; // run up to a specified number of concurrent tasks - while ( setuptools.app.mulequeue.state.busy < setuptools.data.config.mqConcurrent ) { + while (setuptools.app.mulequeue.state.busy < setuptools.data.config.mqConcurrent) { // find the first task in queue state var queueIndex = setuptools.app.mulequeue.state.busy; - for ( var i = 0; i < setuptools.app.mulequeue.queue.length; i++ ) { + for (var i = 0; i < setuptools.app.mulequeue.queue.length; i++) { var guid = setuptools.app.mulequeue.queue[queueIndex]; - if ( typeof guid === 'string' && !(mules[guid] instanceof Mule) ) { + if (typeof guid === 'string' && !(mules[guid] instanceof Mule)) { setuptools.app.mulequeue.task.cancel(guid); continue; } - if ( setuptools.app.mulequeue.tasks[guid].state === 'queue' ) break; + if (setuptools.app.mulequeue.tasks[guid].state === 'queue') break; } @@ -183,7 +183,7 @@ setuptools.app.mulequeue.task.background = function() { /*/ // save mulequeue cache data to local storage -setuptools.app.mulequeue.task.saveConfig = function(returnData) { +setuptools.app.mulequeue.task.saveConfig = function (returnData) { var Config = { date: Date.now(), @@ -196,12 +196,12 @@ setuptools.app.mulequeue.task.saveConfig = function(returnData) { queue: [] }; - if ( returnData === true ) return Config; + if (returnData === true) return Config; - for ( var guid in setuptools.app.mulequeue.tasks ) + for (var guid in setuptools.app.mulequeue.tasks) if (setuptools.app.mulequeue.tasks.hasOwnProperty(guid)) - if ( setuptools.app.mulequeue.tasks[guid].action === 'reload' ) - if ( setuptools.app.mulequeue.tasks[guid].state === 'queue' ) + if (setuptools.app.mulequeue.tasks[guid].action === 'reload') + if (setuptools.app.mulequeue.tasks[guid].state === 'queue') Config.queue.push(guid); setuptools.storage.write('mulequeue:config', Config); @@ -209,28 +209,28 @@ setuptools.app.mulequeue.task.saveConfig = function(returnData) { }; // load mulequeue history and cache data and import it if necessary -setuptools.app.mulequeue.task.loadConfig = function() { +setuptools.app.mulequeue.task.loadConfig = function () { // import any mulequeue cache data var ConfigJson = setuptools.storage.read('mulequeue:config'); var Config; try { Config = JSON.parse(ConfigJson); - } catch(e) {} + } catch (e) { } if ( typeof Config === 'object' && Config !== null ) { - if ( Config.queue.length === 0 ) Config.state.paused = false; + if (Config.queue.length === 0) Config.state.paused = false; $.extend(true, setuptools.app.mulequeue.state, Config.state); // load queue cache if it isn't stale - if ( (Date.now()-Config.date) < setuptools.config.mqStaleCache && Array.isArray(Config.queue) && Config.queue.length > 0 ) { + if ((Date.now() - Config.date) < setuptools.config.mqStaleCache && Array.isArray(Config.queue) && Config.queue.length > 0) { // filter out disabled or banned accounts var count = 0; - if ( setuptools.state.loaded === true ) Config.queue = Config.queue.filter(function(item) { + if (setuptools.state.loaded === true) Config.queue = Config.queue.filter(function (item) { if ( typeof setuptools.data.accounts.accounts[item] === 'object' && @@ -250,11 +250,11 @@ setuptools.app.mulequeue.task.loadConfig = function() { setuptools.app.mulequeue.state.lastTaskFinished = new Date(setuptools.app.mulequeue.state.lastTaskFinished); setuptools.app.mulequeue.task.reload(Config.queue); - if ( Config.state.paused === true ) $('#mulequeue').addClass('paused'); + if (Config.state.paused === true) $('#mulequeue').addClass('paused'); setuptools.app.mulequeue.state.running = true; // save any cleanup changes - if ( count > 0 ) setuptools.app.mulequeue.task.saveConfig(); + if (count > 0) setuptools.app.mulequeue.task.saveConfig(); } @@ -264,7 +264,7 @@ setuptools.app.mulequeue.task.loadConfig = function() { var History; try { History = JSON.parse(HistoryJson); - } catch (e) {} + } catch (e) { } if ( typeof History === 'object' && History !== null @@ -276,7 +276,7 @@ setuptools.app.mulequeue.task.loadConfig = function() { }; -setuptools.app.mulequeue.task.rateLimitCancel = function() { +setuptools.app.mulequeue.task.rateLimitCancel = function () { clearInterval(setuptools.app.mulequeue.state.rateLimitTimer); delete setuptools.app.mulequeue.state.rateLimitExpiration; @@ -284,14 +284,14 @@ setuptools.app.mulequeue.task.rateLimitCancel = function() { setuptools.storage.delete('ratelimitexpiration'); setuptools.app.mulequeue.state.rateLimited = false; $('div.mulequeue.progress > div.bar').removeClass('rateLimited nopulse'); - if ( setuptools.data.config.animations === 1 ) $('#stickynotice').removeClass('rateLimited nopulse'); + if (setuptools.data.config.animations === 1) $('#stickynotice').removeClass('rateLimited nopulse'); // reset spinners - for ( var task in setuptools.app.mulequeue.tasks ) { + for (var task in setuptools.app.mulequeue.tasks) { - if ( setuptools.app.mulequeue.tasks.hasOwnProperty(task) ) { + if (setuptools.app.mulequeue.tasks.hasOwnProperty(task)) { - if ( setuptools.app.mulequeue.tasks[task].state === 'queue' && setuptools.data.config.animations === 1 ) { + if (setuptools.app.mulequeue.tasks[task].state === 'queue' && setuptools.data.config.animations === 1) { setuptools.app.mulequeue.tasks[task].reloader .empty() @@ -316,7 +316,7 @@ setuptools.app.mulequeue.task.rateLimitCancel = function() { }; // rate limit all tasks -setuptools.app.mulequeue.task.rateLimit = function(soft) { +setuptools.app.mulequeue.task.rateLimit = function (soft) { function RateLimitTimer() { @@ -330,11 +330,11 @@ setuptools.app.mulequeue.task.rateLimit = function(soft) { var Time = RateLimitRemaining.match(/^([0-9]*?)\.([0-9]*?)$/); var Minutes = '00'; var Seconds = 0; - if ( typeof Time === 'object' ) { + if (typeof Time === 'object') { Minutes = Time[1]; - Seconds = (Number('0.'+Time[2])*60).toFixed(0); + Seconds = (Number('0.' + Time[2]) * 60).toFixed(0); } - if ( Seconds < 10 ) Seconds = '0' + Seconds; + if (Seconds < 10) Seconds = '0' + Seconds; var RateLimitTime = Minutes + ':' + Seconds; $('#mulequeue').addClass('rateLimited'); $('#stickynotice').html(' \ @@ -350,7 +350,7 @@ setuptools.app.mulequeue.task.rateLimit = function(soft) { \ \ '); - $('div.muledump.resetratelimit').off('click.muledump.resetratelimit').on('click.muledump.resetratelimit', function() { + $('div.muledump.resetratelimit').off('click.muledump.resetratelimit').on('click.muledump.resetratelimit', function () { setuptools.app.mulequeue.task.rateLimitCancel(); }); @@ -361,9 +361,9 @@ setuptools.app.mulequeue.task.rateLimit = function(soft) { // prepare the rate limit window.techlog('MuleQueue/RateLimit detected', 'force'); setuptools.app.mulequeue.state.rateLimited = true; - if ( soft !== true ) { + if (soft !== true) { - setuptools.app.mulequeue.state.rateLimitExpiration = Date.now()+setuptools.config.mqRateLimitExpiration; + setuptools.app.mulequeue.state.rateLimitExpiration = Date.now() + setuptools.config.mqRateLimitExpiration; // write it to storage setuptools.storage.write('ratelimitexpiration', setuptools.app.mulequeue.state.rateLimitExpiration); @@ -383,12 +383,12 @@ setuptools.app.mulequeue.task.rateLimit = function(soft) { } // reset state for any tasks that encountered rate limiting - if ( setuptools.app.mulequeue.queue.length > 0 ) { + if (setuptools.app.mulequeue.queue.length > 0) { for (var index = (setuptools.app.mulequeue.state.busy - 1); index >= 0; index--) { setuptools.app.mulequeue.tasks[setuptools.app.mulequeue.queue[index]].state = 'queue'; - if ( setuptools.data.config.animations === 1 ) { + if (setuptools.data.config.animations === 1) { setuptools.app.mulequeue.tasks[setuptools.app.mulequeue.queue[index]].reloader .empty() @@ -408,34 +408,135 @@ setuptools.app.mulequeue.task.rateLimit = function(soft) { setuptools.app.mulequeue.state.active = false; //setuptools.app.mulequeue.state.queuePeak = 0; $('div.mulequeue.progress > div.bar').addClass('rateLimited nopulse'); - if ( setuptools.data.config.animations === 1 ) $('#stickynotice').addClass('rateLimited nopulse'); + if (setuptools.data.config.animations === 1) $('#stickynotice').addClass('rateLimited nopulse'); // start the rate limit timer setuptools.app.mulequeue.state.rateLimitTimer = setInterval(RateLimitTimer, 1000); }; +// handeling of the 5 min limit +setuptools.app.mulequeue.task.hardRateLimit = function (soft) { + + function RateLimitTimer() { + + var RateLimitRemaining = ((setuptools.app.mulequeue.state.rateLimitExpiration - Date.now()) / 1000 / 60).toFixed(2); + if (RateLimitRemaining <= 0) { + + setuptools.app.mulequeue.task.rateLimitCancel(); + + } else { + + var Time = RateLimitRemaining.match(/^([0-9]*?)\.([0-9]*?)$/); + var Minutes = '00'; + var Seconds = 0; + if (typeof Time === 'object') { + Minutes = Time[1]; + Seconds = (Number('0.' + Time[2]) * 60).toFixed(0); + } + if (Seconds < 10) Seconds = '0' + Seconds; + var RateLimitTime = Minutes + ':' + Seconds; + $('#mulequeue').addClass('rateLimited'); + $('#stickynotice').html(' \ +
\ +
Warning: Your account is rate limited by Deca. \ + You must wait ' + RateLimitTime + ' before you can reload your account.
\ + \ +
\ + '); + $('div.mulequeue.progress > div.percentage').html(' \ +
\ +
You are rate limited and must wait ' + RateLimitTime + ' before continuing.
\ + \ +
\ + '); + $('div.muledump.resetratelimit').off('click.muledump.resetratelimit').on('click.muledump.resetratelimit', function () { + setuptools.app.mulequeue.task.rateLimitCancel(); + }); + + } + + } + + // prepare the rate limit + window.techlog('MuleQueue/RateLimit detected', 'force'); + setuptools.app.mulequeue.state.rateLimited = true; + if (soft !== true) { + + setuptools.app.mulequeue.state.rateLimitExpiration = Date.now() + 300000; + + // write it to storage + setuptools.storage.write('ratelimitexpiration', setuptools.app.mulequeue.state.rateLimitExpiration); + + setuptools.app.ga('send', 'event', { + eventCategory: 'rateLimited', + eventAction: 'hard' + }); + + } else { + + setuptools.app.ga('send', 'event', { + eventCategory: 'rateLimited', + eventAction: 'soft' + }); + + } + + // reset state for any tasks that encountered rate limiting + if (setuptools.app.mulequeue.queue.length > 0) { + for (var index = (setuptools.app.mulequeue.state.busy - 1); index >= 0; index--) { + + setuptools.app.mulequeue.tasks[setuptools.app.mulequeue.queue[index]].state = 'queue'; + + if (setuptools.data.config.animations === 1) { + + setuptools.app.mulequeue.tasks[setuptools.app.mulequeue.queue[index]].reloader + .empty() + .append(setuptools.app.mulequeue.spinner.running('error')) + .attr('title', 'Error: You are presently rate limited by Deca.'); + + } + + $('div.queuetask[data-listPos="' + index + '"] > div:first-child') + .html(setuptools.app.mulequeue.spinner.running('error', true)) + .attr('title', 'Error: You are presently rate limited by Deca.'); + } + } + + // reset the busy counter to 0 + setuptools.app.mulequeue.state.busy = 0; + setuptools.app.mulequeue.state.active = false; + //setuptools.app.mulequeue.state.queuePeak = 0; + $('div.mulequeue.progress > div.bar').addClass('rateLimited nopulse'); + if (setuptools.data.config.animations === 1) $('#stickynotice').addClass('rateLimited nopulse'); + + // start the rate limit timer + setuptools.app.mulequeue.state.rateLimitTimer = setInterval(RateLimitTimer, 1000); + +}; + + // parse provided guids list into correct format -setuptools.app.mulequeue.task.guidsCheck = function(guids) { +setuptools.app.mulequeue.task.guidsCheck = function (guids) { - if ( !guids ) guids = []; - if ( typeof guids === 'string' ) guids = [guids]; - if ( Array.isArray(guids) === false ) setuptools.lightbox.error('Data type for argument "guids" not valid.', 1000); + if (!guids) guids = []; + if (typeof guids === 'string') guids = [guids]; + if (Array.isArray(guids) === false) setuptools.lightbox.error('Data type for argument "guids" not valid.', 1000); return guids; }; // queue task on all or specified guids -setuptools.app.mulequeue.task.queue = function(guids, config) { +setuptools.app.mulequeue.task.queue = function (guids, config) { // parse guids guids = setuptools.app.mulequeue.task.guidsCheck(guids); // set a default config object if none provided or invalid - if ( typeof config === 'function' ) { + if (typeof config === 'function') { callback = config; config = {}; - } else if ( typeof config !== 'object' || Array.isArray(config) === true ) config = {}; + } else if (typeof config !== 'object' || Array.isArray(config) === true) config = {}; // merge supplied config into default config config = $.extend(true, {}, setuptools.data.config.mqDefaultConfig, config); @@ -445,15 +546,15 @@ setuptools.app.mulequeue.task.queue = function(guids, config) { delete config.creation; // add guid to the queue - for ( var i = 0; i < guids.length; i++ ) { + for (var i = 0; i < guids.length; i++) { - if ( i === 0 ) setuptools.app.mulequeue.state.running = true; + if (i === 0) setuptools.app.mulequeue.state.running = true; // check if guid is already in the queue - if ( typeof setuptools.app.mulequeue.tasks[guids[i]] === 'object' ) { + if (typeof setuptools.app.mulequeue.tasks[guids[i]] === 'object') { // do not interfere if the queue item is already running - if ( setuptools.app.mulequeue.tasks[guids[i]].state === 'running' ) continue; + if (setuptools.app.mulequeue.tasks[guids[i]].state === 'running') continue; // update the queue item's configuration $.extend(true, setuptools.app.mulequeue.tasks[guids[i]], config); @@ -465,7 +566,7 @@ setuptools.app.mulequeue.task.queue = function(guids, config) { config.state = 'queue'; config.creation = new Date; config.reloader = $('div.mule[data-guid="' + guids[i] + '"] > div.button.reloader'); - if ( setuptools.data.config.animations === 1 ) config.reloader.empty().append(setuptools.app.mulequeue.spinner.running()).attr('title', 'Task is waiting in MuleQueue'); + if (setuptools.data.config.animations === 1) config.reloader.empty().append(setuptools.app.mulequeue.spinner.running()).attr('title', 'Task is waiting in MuleQueue'); setuptools.app.mulequeue.queue.push(guids[i]); // sets queue order setuptools.app.mulequeue.tasks[guids[i]] = $.extend(true, {}, config); // sets queue config data @@ -478,9 +579,9 @@ setuptools.app.mulequeue.task.queue = function(guids, config) { // reload (ignore_cache) task on all or specified guids -setuptools.app.mulequeue.task.reload = function(guids, callback) { +setuptools.app.mulequeue.task.reload = function (guids, callback) { - if ( typeof guids === 'function' ) { + if (typeof guids === 'function') { callback = guids; guids = undefined; @@ -488,7 +589,7 @@ setuptools.app.mulequeue.task.reload = function(guids, callback) { } // parse guids - if ( !guids ) guids = Object.keys(window.accounts); + if (!guids) guids = Object.keys(window.accounts); guids = setuptools.app.mulequeue.task.guidsCheck(guids); // force account data reload @@ -500,26 +601,26 @@ setuptools.app.mulequeue.task.reload = function(guids, callback) { setuptools.app.mulequeue.state.running = true; - if ( typeof callback === 'function' ) callback(); + if (typeof callback === 'function') callback(); }; // refresh (cache_only) task on all or specified guids (bypasses queue) -setuptools.app.mulequeue.task.refresh = function(guids) { +setuptools.app.mulequeue.task.refresh = function (guids) { // parse guids guids = setuptools.app.mulequeue.task.guidsCheck(guids); - for ( var x = 0; x < guids.length; x++ ) mules[guids[x]].query(false, true, true); + for (var x = 0; x < guids.length; x++) mules[guids[x]].query(false, true, true); }; // attempt a cache_only load of guids and send stale guids to reload -setuptools.app.mulequeue.task.load = function(guids) { +setuptools.app.mulequeue.task.load = function (guids) { // parse guids guids = setuptools.app.mulequeue.task.guidsCheck(guids); - if ( guids.length === 0 ) guids = Object.keys(window.accounts); + if (guids.length === 0) guids = Object.keys(window.accounts); // first loop: cache_only load on all provided guids setuptools.app.mulequeue.task.refresh(guids); @@ -532,22 +633,22 @@ setuptools.app.mulequeue.task.load = function(guids) { }; // start task on specified guid -setuptools.app.mulequeue.task.start = function(guid, callback) { +setuptools.app.mulequeue.task.start = function (guid, callback) { // require a guid be provided - if ( !guid ) return; + if (!guid) return; // check if a task exists and insert it into the queue if not - if ( typeof setuptools.app.mulequeue.tasks[guid] === 'undefined' ) setuptools.app.mulequeue.task.reload(guid); + if (typeof setuptools.app.mulequeue.tasks[guid] === 'undefined') setuptools.app.mulequeue.task.reload(guid); // check if a task exists and make sure it is in the proper state - if ( typeof setuptools.app.mulequeue.tasks[guid] === 'object' && setuptools.app.mulequeue.tasks[guid].state !== 'queue' ) return; + if (typeof setuptools.app.mulequeue.tasks[guid] === 'object' && setuptools.app.mulequeue.tasks[guid].state !== 'queue') return; // reorder the queue if this item isn't in its position var taskIndex = setuptools.app.mulequeue.task.reorder(guid); // we won't run the request if we're rate limited - if ( setuptools.app.mulequeue.state.rateLimited === true ) return; + if (setuptools.app.mulequeue.state.rateLimited === true) return; // run the task setuptools.app.mulequeue.state.busy++; @@ -556,34 +657,40 @@ setuptools.app.mulequeue.task.start = function(guid, callback) { // update task state setuptools.app.mulequeue.tasks[guid].state = 'running'; setuptools.app.mulequeue.tasks[guid].startTime = new Date; - if ( setuptools.data.config.animations === 1 ) setuptools.app.mulequeue.tasks[guid].reloader.empty().append(setuptools.app.mulequeue.spinner.running('running')).attr('title', 'Mule data request running...'); + if (setuptools.data.config.animations === 1) setuptools.app.mulequeue.tasks[guid].reloader.empty().append(setuptools.app.mulequeue.spinner.running('running')).attr('title', 'Mule data request running...'); $('div.queuetask[data-listPos="' + taskIndex + '"] > div:first-child').html(setuptools.app.mulequeue.spinner.running('running', true)).attr('title', 'Mule data request running...'); // create the promise to run the task - setuptools.app.mulequeue.tasks[guid].promise = setuptools.app.mulequeue.task.createPromise(guid).then(function(response) { + setuptools.app.mulequeue.tasks[guid].promise = setuptools.app.mulequeue.task.createPromise(guid).then(function (response) { // handle responses from the task var task = setuptools.app.mulequeue.tasks[response.guid]; - if (response.state === 'finished' && task.state === 'running' ) { + if (response.state === 'finished' && task.state === 'running') { // handle rate limit detection - if ( response.status === 'rateLimited' ) { + if (response.status === 'rateLimited') { setuptools.app.mulequeue.task.rateLimit(); return; + } + else if (response.status === 'hardRateLimited') { + + setuptools.app.mulequeue.task.hardRateLimit(); + return; + } // update the task data for task history task.state = 'finished'; task.finishTime = new Date; - task.runTime = task.finishTime-task.startTime; - setuptools.app.mulequeue.state.timePerTaskAverage = Math.round((setuptools.app.mulequeue.state.timePerTaskAverage+task.runTime)/2); + task.runTime = task.finishTime - task.startTime; + setuptools.app.mulequeue.state.timePerTaskAverage = Math.round((setuptools.app.mulequeue.state.timePerTaskAverage + task.runTime) / 2); task.response = response; - if ( response.status === 'error' ) { + if (response.status === 'error') { - if ( setuptools.data.config.animations === 1 ) task.reloader.empty().append(setuptools.app.mulequeue.spinner.running('error')).attr('title', 'Error loading account: ' + response.errorMessage); + if (setuptools.data.config.animations === 1) task.reloader.empty().append(setuptools.app.mulequeue.spinner.running('error')).attr('title', 'Error loading account: ' + response.errorMessage); } else { @@ -606,10 +713,10 @@ setuptools.app.mulequeue.task.start = function(guid, callback) { 'MuleQueue/TaskFinish ' + '- ' + response.guid + ' \'' + response.status + '\'' + ((response.errorMessage) ? - ' - \'' + response.errorMessage + '\'' : - ' - runtime ' + (task.runTime/1000).toFixed(2) + ' seconds') + - ' - waited ' + Math.floor((task.finishTime-task.creation)/1000) + ' seconds' + - ' - remaining tasks ' + (setuptools.app.mulequeue.queue.length-1), + ' - \'' + response.errorMessage + '\'' : + ' - runtime ' + (task.runTime / 1000).toFixed(2) + ' seconds') + + ' - waited ' + Math.floor((task.finishTime - task.creation) / 1000) + ' seconds' + + ' - remaining tasks ' + (setuptools.app.mulequeue.queue.length - 1), 'force' ); @@ -623,10 +730,10 @@ setuptools.app.mulequeue.task.start = function(guid, callback) { finish: task.finishTime, state: task.state, guid: response.guid, - ign: ( ( + ign: (( setuptools.state.loaded === true && setuptools.app.config.determineFormat(setuptools.data.accounts) === 1 - ) ? (setuptools.data.accounts.accounts[response.guid] && setuptools.data.accounts.accounts[response.guid].ign) : undefined ), + ) ? (setuptools.data.accounts.accounts[response.guid] && setuptools.data.accounts.accounts[response.guid].ign) : undefined), status: response.status, errorMessage: response.errorMessage || undefined, runtime: (task.runTime / 1000).toFixed(2), @@ -653,22 +760,22 @@ setuptools.app.mulequeue.task.start = function(guid, callback) { }).join(); setuptools.app.mulequeue.ui.progressBar(); - if ( setuptools.lightbox.menu.context.isOpen('mulequeue-menu') === true ) setuptools.app.mulequeue.menu(); + if (setuptools.lightbox.menu.context.isOpen('mulequeue-menu') === true) setuptools.app.mulequeue.menu(); if ( typeof setuptools.lightbox.active['mulequeue-manager'] === 'object' && typeof setuptools.lightbox.menu.paginate.state.QueueList === 'object' ) setuptools.lightbox.menu.paginate.state.QueueList.Modifiers.callbacks.update(); // no tasks are active anymore - if ( setuptools.app.mulequeue.state.busy === 0 ) setuptools.app.mulequeue.state.active = false; + if (setuptools.app.mulequeue.state.busy === 0) setuptools.app.mulequeue.state.active = false; // if the queue is now empty we can switch the running state to false - if ( setuptools.app.mulequeue.queue.length === 0 ) { + if (setuptools.app.mulequeue.queue.length === 0) { $('#mulequeue').removeClass('running'); setuptools.app.mulequeue.state.running = false; setuptools.app.mulequeue.state.queuePeak = 0; - if( + if ( typeof setuptools.lightbox.active['mulequeue-manager'] === 'object' && typeof setuptools.app.mulequeue.queuemanager === 'object' ) setuptools.app.mulequeue.queuemanager.Modifiers.callbacks.update(); @@ -684,10 +791,10 @@ setuptools.app.mulequeue.task.start = function(guid, callback) { }; -setuptools.app.mulequeue.task.history = function(record) { +setuptools.app.mulequeue.task.history = function (record) { - if ( Array.isArray(setuptools.app.mulequeue.history.data) === false ) setuptools.app.mulequeue.history.data = []; - if ( typeof setuptools.app.mulequeue.history.stats === 'undefined' ) setuptools.app.mulequeue.history.stats = { + if (Array.isArray(setuptools.app.mulequeue.history.data) === false) setuptools.app.mulequeue.history.data = []; + if (typeof setuptools.app.mulequeue.history.stats === 'undefined') setuptools.app.mulequeue.history.stats = { ok: 0, error: 0, cors: 0, @@ -701,21 +808,21 @@ setuptools.app.mulequeue.task.history = function(record) { setuptools.app.mulequeue.history.data.splice(setuptools.data.config.mqKeepHistory); // parse the record - if ( record.status === 'ok' ) setuptools.app.mulequeue.history.stats.ok++; - if ( record.status === 'cache' ) setuptools.app.mulequeue.history.stats.cache++; - if ( record.status === 'error' ) { + if (record.status === 'ok') setuptools.app.mulequeue.history.stats.ok++; + if (record.status === 'cache') setuptools.app.mulequeue.history.stats.cache++; + if (record.status === 'error') { setuptools.app.mulequeue.history.stats.error++; - if ( record.errorMessage.match(/CORS/) ) { + if (record.errorMessage.match(/CORS/)) { setuptools.app.mulequeue.history.stats.cors++; } - else if ( record.errorMessage.match(/rate limited/) ) { + else if (record.errorMessage.match(/rate limited/)) { setuptools.app.mulequeue.history.stats.rateLimited++; } - else if ( record.errorMessage.match(/banned/) ) { + else if (record.errorMessage.match(/banned/)) { setuptools.app.mulequeue.history.stats.banned++; } - else if ( record.errorMessage.match(/Account in use/) ) { + else if (record.errorMessage.match(/Account in use/)) { setuptools.app.mulequeue.history.stats.accountInUse++; } else setuptools.app.mulequeue.history.stats.otherError++; @@ -726,19 +833,19 @@ setuptools.app.mulequeue.task.history = function(record) { }; // pause tasks and update the ui -setuptools.app.mulequeue.task.pause = function(callback) { +setuptools.app.mulequeue.task.pause = function (callback) { - if ( setuptools.app.mulequeue.state.rateLimited === false ) $('#mulequeue').removeClass('running').addClass('paused'); + if (setuptools.app.mulequeue.state.rateLimited === false) $('#mulequeue').removeClass('running').addClass('paused'); setuptools.app.mulequeue.state.paused = true; setuptools.app.mulequeue.task.saveConfig(); var pauseList = setuptools.app.mulequeue.queue; - for ( var i = 0; i < pauseList.length; i++ ) { + for (var i = 0; i < pauseList.length; i++) { var task = setuptools.app.mulequeue.tasks[pauseList[i]]; - if ( task.state === 'queue' ) { + if (task.state === 'queue') { - if ( setuptools.data.config.animations === 1 ) task.reloader.empty().append(setuptools.app.mulequeue.spinner.running('pause')).attr('title', 'Task paused in MuleQueue'); + if (setuptools.data.config.animations === 1) task.reloader.empty().append(setuptools.app.mulequeue.spinner.running('pause')).attr('title', 'Task paused in MuleQueue'); $('div.queuetask[data-listPos="' + i + '"] > div:first-child').html(setuptools.app.mulequeue.spinner.running('pause', true)).attr('title', 'Task paused in MuleQueue'); } @@ -746,15 +853,15 @@ setuptools.app.mulequeue.task.pause = function(callback) { } - if ( typeof callback === 'function' ) callback(); + if (typeof callback === 'function') callback(); window.techlog('MuleQueue/TaskPause'); }; // return task on all or specified guids -setuptools.app.mulequeue.task.resume = function(guids, callback) { +setuptools.app.mulequeue.task.resume = function (guids, callback) { - if ( typeof guids === 'function' ) { + if (typeof guids === 'function') { callback = guids; guids = []; @@ -762,24 +869,24 @@ setuptools.app.mulequeue.task.resume = function(guids, callback) { } // parse guids - if ( !guids ) guids = []; + if (!guids) guids = []; guids = setuptools.app.mulequeue.task.guidsCheck(guids); var pauseList = guids; - if ( guids.length === 0 ) { + if (guids.length === 0) { - if ( setuptools.app.mulequeue.state.rateLimited === false ) $('#mulequeue').removeClass('paused').addClass('running'); + if (setuptools.app.mulequeue.state.rateLimited === false) $('#mulequeue').removeClass('paused').addClass('running'); setuptools.app.mulequeue.state.paused = false; pauseList = setuptools.app.mulequeue.queue; } - if ( pauseList.length === 0 ) return; - for ( var i = 0; i < pauseList.length; i++ ) { + if (pauseList.length === 0) return; + for (var i = 0; i < pauseList.length; i++) { var task = setuptools.app.mulequeue.tasks[pauseList[i]]; - if ( task.state === 'queue' ) { + if (task.state === 'queue') { - if ( setuptools.data.config.animations === 1 ) task.reloader.empty().append(setuptools.app.mulequeue.spinner.running('queue')).attr('title', 'Task is waiting in MuleQueue'); + if (setuptools.data.config.animations === 1) task.reloader.empty().append(setuptools.app.mulequeue.spinner.running('queue')).attr('title', 'Task is waiting in MuleQueue'); $('div.queuetask[data-listPos="' + i + '"] > div:first-child').html(setuptools.app.mulequeue.spinner.running('queue', true)).attr('title', 'Task is waiting in MuleQueue'); } @@ -787,16 +894,16 @@ setuptools.app.mulequeue.task.resume = function(guids, callback) { } setuptools.app.mulequeue.state.running = true; - setuptools.app.mulequeue.state.lastTaskFinished = ((new Date)-(window.accountLoadDelay*1000)); - if ( typeof callback === 'function' ) callback(); + setuptools.app.mulequeue.state.lastTaskFinished = ((new Date) - (window.accountLoadDelay * 1000)); + if (typeof callback === 'function') callback(); window.techlog('MuleQueue/TaskResume'); }; // cancel task on all or specified guids -setuptools.app.mulequeue.task.cancel = function(guids, callback) { +setuptools.app.mulequeue.task.cancel = function (guids, callback) { - if ( typeof guids === 'function' ) { + if (typeof guids === 'function') { callback = guids; guids = []; @@ -805,22 +912,22 @@ setuptools.app.mulequeue.task.cancel = function(guids, callback) { // parse guids var cancelAll = false; - if ( !guids ) guids = []; + if (!guids) guids = []; guids = setuptools.app.mulequeue.task.guidsCheck(guids); - if ( guids.length === 0 ) { + if (guids.length === 0) { cancelAll = true; guids = setuptools.app.mulequeue.queue; } window.techlog('MuleQueue/TaskCancel clearing ' + guids.length + ' tasks', 'force'); // cancel and remove all queued tasks - for ( var i = (guids.length-1); i >= 0; i-- ) { + for (var i = (guids.length - 1); i >= 0; i--) { var guid = guids[i]; var task = setuptools.app.mulequeue.tasks[guid]; - if ( ['queue', 'error'].indexOf(task.state) > -1 ) { + if (['queue', 'error'].indexOf(task.state) > -1) { - if ( mules[guid] instanceof Mule && mules[guid].loginOnly !== true ) setuptools.app.mulequeue.tasks[guid].reloader.empty().text('\u21bb').attr('title', 'last updated: ' + ( (typeof mules[guid].data === 'object') ? + if (mules[guid] instanceof Mule && mules[guid].loginOnly !== true) setuptools.app.mulequeue.tasks[guid].reloader.empty().text('\u21bb').attr('title', 'last updated: ' + ((typeof mules[guid].data === 'object') ? (Date(mules[guid].data.query.created)).toLocaleString() : 'Unknown' )); @@ -835,7 +942,7 @@ setuptools.app.mulequeue.task.cancel = function(guids, callback) { } setuptools.app.mulequeue.task.saveConfig(); - if ( cancelAll === false ) return; + if (cancelAll === false) return; // clean up if we cancelled all tasks setuptools.app.mulequeue.state.paused = false; @@ -844,24 +951,24 @@ setuptools.app.mulequeue.task.cancel = function(guids, callback) { setuptools.app.mulequeue.state.busy = 0; setuptools.app.mulequeue.state.queuePeak = 0; $('#mulequeue').removeClass('running paused'); - if ( typeof callback === 'function' ) callback(); + if (typeof callback === 'function') callback(); }; // reorder task position specified guids -setuptools.app.mulequeue.task.reorder = function(guids, position) { +setuptools.app.mulequeue.task.reorder = function (guids, position) { - if ( typeof guids === 'undefined' ) setuptools.lightbox.error('Argument "guids" is required.', 1000); + if (typeof guids === 'undefined') setuptools.lightbox.error('Argument "guids" is required.', 1000); // parse guids guids = setuptools.app.mulequeue.task.guidsCheck(guids); - if ( typeof position !== 'number' ) position = 0; - for ( var i = 0; i < guids.length; i++ ) { + if (typeof position !== 'number') position = 0; + for (var i = 0; i < guids.length; i++) { var guid = guids[i]; var taskIndex = setuptools.app.mulequeue.queue.indexOf(guid); - var taskPosition = setuptools.app.mulequeue.state.busy+position; + var taskPosition = setuptools.app.mulequeue.state.busy + position; if (taskIndex !== taskPosition) { window.techlog('MuleQueue/Start pushing ' + guids[i] + ' to position ' + taskPosition); @@ -873,7 +980,7 @@ setuptools.app.mulequeue.task.reorder = function(guids, position) { } - if ( guids.length === 1 ) return taskPosition; + if (guids.length === 1) return taskPosition; } @@ -884,19 +991,19 @@ setuptools.app.mulequeue.task.reorder = function(guids, position) { /*/ // mulequeue menu -setuptools.app.mulequeue.menu = function() { +setuptools.app.mulequeue.menu = function () { // don't redraw if the menu is already open setuptools.lightbox.menu.context.close('mulequeue-menu'); var MuleQueueButton = $('#mulequeue'); // clear the hover close interval if mousing over this menu's button - MuleQueueButton.mouseover(function() { + MuleQueueButton.mouseover(function () { clearInterval(setuptools.tmp.muleMenuMouseLeaveTimer); }); // set our options - var YesIAmSplittingHairs = ( setuptools.app.mulequeue.queue.length === 1 ) ? '' : 's'; + var YesIAmSplittingHairs = (setuptools.app.mulequeue.queue.length === 1) ? '' : 's'; var options = [ { option: 'hover', @@ -926,15 +1033,16 @@ setuptools.app.mulequeue.menu = function() { option: 'class', value: 'smallMenuCells mulequeue-topMenu' }, - { option: 'css', + { + option: 'css', css: { position: 'fixed' } }, { class: 'openManager', - name: setuptools.app.mulequeue.queue.length + ' Task' + YesIAmSplittingHairs + ' ' + ( (setuptools.app.mulequeue.state.paused === false) ? 'Running' : 'Paused' ), - callback: function() { + name: setuptools.app.mulequeue.queue.length + ' Task' + YesIAmSplittingHairs + ' ' + ((setuptools.app.mulequeue.state.paused === false) ? 'Running' : 'Paused'), + callback: function () { setuptools.lightbox.menu.context.closeSkip('mulequeue-menu'); setuptools.app.mulequeue.ui.manager(); }, @@ -942,7 +1050,7 @@ setuptools.app.mulequeue.menu = function() { } ]; - if ( setuptools.app.mulequeue.state.rateLimited === true ) { + if (setuptools.app.mulequeue.state.rateLimited === true) { options.push( { @@ -960,9 +1068,9 @@ setuptools.app.mulequeue.menu = function() { } else { - if ( MuleQueueButton.hasClass('running') === true || MuleQueueButton.hasClass('paused') === true ) { + if (MuleQueueButton.hasClass('running') === true || MuleQueueButton.hasClass('paused') === true) { - if ( setuptools.app.mulequeue.state.paused === false ) { + if (setuptools.app.mulequeue.state.paused === false) { options.push({ class: 'pauseQueue', @@ -987,7 +1095,7 @@ setuptools.app.mulequeue.menu = function() { options.push({ class: 'cancelQueue', name: 'Cancel', - callback: function() { + callback: function () { setuptools.app.mulequeue.task.cancel(); } }); @@ -1011,11 +1119,11 @@ setuptools.app.mulequeue.menu = function() { }; // draw ui buttons reflecting the current state -setuptools.app.mulequeue.ui.drawButtons = function() { +setuptools.app.mulequeue.ui.drawButtons = function () { var html = ''; - if ( setuptools.app.mulequeue.state.running === false ) { + if (setuptools.app.mulequeue.state.running === false) { html += ' \