38a413e95b
* Pre-compute name, formatted sizes and speeds. * Handle name edge-cases such as no-path and no-uris better. * Unroll getCtx. * Improve performance of mergeMap. * Delay the search filter. As indicated by Chrome/Gecko profilers.
168 lines
4.5 KiB
JavaScript
168 lines
4.5 KiB
JavaScript
angular.module('webui.services.utils', [])
|
||
.factory('$utils', ['$filter', function(filter) {
|
||
var rnd16 = (function() {
|
||
"use strict";
|
||
var rndBuffer = new Uint8Array(16);
|
||
var rnd16Weak = function() {
|
||
for (var i = 0, r; i < 16; i++) {
|
||
if (!(i % 0x3)) r = Math.random() * 0x100000000 | 0;
|
||
rndBuffer[i] = r >>> ((i & 0x3) << 0x3) & 0xff;
|
||
}
|
||
return rndBuffer;
|
||
};
|
||
|
||
if (!crypto.getRandomValues) {
|
||
return rnd16Weak;
|
||
}
|
||
return function() {
|
||
try {
|
||
crypto.getRandomValues(rndBuffer);
|
||
return rndBuffer;
|
||
}
|
||
catch (ex) {
|
||
// Entropy might be exhausted
|
||
return rnd16Weak();
|
||
}
|
||
};
|
||
})();
|
||
|
||
var utils = {
|
||
|
||
fmtsize: function(len) {
|
||
len = +len; // coerce to number
|
||
if (len <= 1024) {
|
||
return len.toFixed(0) + " B";
|
||
}
|
||
len /= 1024;
|
||
if (len <= 1024) {
|
||
return len.toFixed(1) + " KB"
|
||
}
|
||
len /= 1024;
|
||
if (len <= 1024) {
|
||
return len.toFixed(2) + " MB";
|
||
}
|
||
len /= 1024;
|
||
return len.toFixed(3) + " GB";
|
||
},
|
||
|
||
fmtspeed: function(speed) {
|
||
return utils.fmtsize(speed) + "/s";
|
||
},
|
||
// saves the key value pair in cookies
|
||
setCookie: function(key, value) {
|
||
var exdate = new Date();
|
||
exdate.setDate(exdate.getDate() + 30 * 12);
|
||
var cvalue = escape(JSON.stringify(value)) + "; expires=" + exdate.toUTCString();
|
||
document.cookie = key + "=" + cvalue;
|
||
},
|
||
// gets a value for a key stored in cookies
|
||
getCookie: function(key) {
|
||
var chunks = document.cookie.split(";");
|
||
for (var i = 0; i < chunks.length; i++) {
|
||
var ckey = chunks[i].substr(0, chunks[i].indexOf("=")).replace(/^\s+|\s+$/g,"");
|
||
var cvalue = chunks[i].substr(chunks[i].indexOf("=") + 1);
|
||
if (key == ckey) {
|
||
return JSON.parse(unescape(cvalue));
|
||
}
|
||
}
|
||
|
||
return null;
|
||
},
|
||
getFileName: function(path) {
|
||
var seed = path.split(/[/\\]/);
|
||
return seed[seed.length - 1];
|
||
},
|
||
uuid: (function() {
|
||
var bt = [];
|
||
for (var i = 0; i < 0x100; ++i) {
|
||
bt.push((i + 0x100).toString(16).substr(1));
|
||
}
|
||
Object.freeze(bt);
|
||
|
||
return function() {
|
||
var r = rnd16();
|
||
r[6] = (r[6] & 0xf) | 0x40; // Version 4
|
||
r[8] = (r[8] & 0x3f) | 0x80; // Version 4y
|
||
return bt[r[0]] + bt[r[1]] + bt[r[2]] + bt[r[3]] + "-" +
|
||
bt[r[4]] + bt[r[5]] + "-" +
|
||
bt[r[6]] + bt[r[7]] + "-" +
|
||
bt[r[8]] + bt[r[9]] + "-" +
|
||
bt[r[10]] + bt[r[11]] + bt[r[12]] + bt[r[13]] + bt[r[14]] + bt[r[15]];
|
||
};
|
||
})(),
|
||
randStr: function() {
|
||
return utils.uuid();
|
||
},
|
||
|
||
// maps the array in place to the destination
|
||
// arr, dest (optional): array
|
||
// func: a merge mapping func, see ctrls/download.js
|
||
mergeMap: function(arr, dest, func) {
|
||
if (!dest) {
|
||
dest = [];
|
||
}
|
||
|
||
for (var i = 0, e = Math.min(arr.length, dest.length); i < e; ++i) {
|
||
func(arr[i], dest[i]);
|
||
}
|
||
|
||
// Insert newly created downloads
|
||
while (i < arr.length) {
|
||
dest.push(func(arr[i++]));
|
||
}
|
||
|
||
// Truncate if necessary.
|
||
dest.length = arr.length;
|
||
|
||
return dest;
|
||
},
|
||
// get info title from global statistics
|
||
getTitle: function(stats) {
|
||
var title =
|
||
'('
|
||
+ ' active:' + stats.numActive
|
||
+ ' waiting:' + stats.numWaiting
|
||
+ ' stopped:' + stats.numStopped
|
||
+ ') '
|
||
+ 'aria2 Web Client';
|
||
|
||
return title;
|
||
},
|
||
|
||
// get download chunks from aria2 bitfield
|
||
getChunksFromHex: function(bitfield, numOfPieces) {
|
||
var chunks = [], len = 0, numPieces = parseInt(numOfPieces);
|
||
if (!bitfield) return [];
|
||
|
||
var totalDownloaded = 0;
|
||
if (numPieces > 1) {
|
||
var chunk_ratio = 1 / numPieces;
|
||
var piecesProcessed = 0;
|
||
for (var i = 0; i < bitfield.length; i++) {
|
||
var hex = parseInt(bitfield[i], 16);
|
||
for (var j = 1; j <= 4; j++) {
|
||
var bit = hex & (1 << (4 - j));
|
||
if (bit) totalDownloaded++;
|
||
var prog = !!bit;
|
||
if (len >= 1 && chunks[len - 1].show == prog) {
|
||
chunks[len - 1].ratio += chunk_ratio;
|
||
}
|
||
else {
|
||
chunks.push({
|
||
ratio: chunk_ratio,
|
||
show: prog
|
||
});
|
||
len++;
|
||
}
|
||
piecesProcessed++;
|
||
if (piecesProcessed == numPieces)
|
||
return chunks;
|
||
}
|
||
}
|
||
}
|
||
return chunks;
|
||
}
|
||
};
|
||
return utils;
|
||
}]);
|