Skip to content

Instantly share code, notes, and snippets.

@Nothing4You
Last active November 29, 2023 23:57
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Nothing4You/b127b3cc4d4fabe372dcf078dbe86070 to your computer and use it in GitHub Desktop.
Save Nothing4You/b127b3cc4d4fabe372dcf078dbe86070 to your computer and use it in GitHub Desktop.
hacky replacement dashboard script to show b/s and i/s values
// ==UserScript==
// @name betterDashboard
// @namespace Nothing4You
// @match https://tracker.archiveteam.org/*/
// @grant none
// @version 1.2.0
// @author Nothing4You
// @description adds more information to archive team tracker dashboards
// @updateURL https://gist.githubusercontent.com/Nothing4You/b127b3cc4d4fabe372dcf078dbe86070/raw/dashboard.user.js
// ==/UserScript==
/***
WARNING:
This script may break things!
If you're experiencing any issues on the Archive Team tracker website please
disable this script and remove any content blocker rules before reporting this to the Archive Team!
Usage:
1. Block tracker.archiveteam.org/js/dashboard.js from loading e.g. via content blocker.
uBlock Origin filter example:
||tracker.archiveteam.org/js/dashboard.js$script,domain=tracker.archiveteam.org
2. Install this script
3. Don't complain if anything breaks :)
***/
(function initDashboard(trackerConfig) {
window.customDashboardStats = {};
window.customDashboardDomainStats = {};
window.customDashboardInitialItemCounts = false;
// via https://stackoverflow.com/a/6313008
function formatTimeDelta(sec) {
let hours = Math.floor(sec / 3600);
let minutes = Math.floor((sec - (hours * 3600)) / 60);
let seconds = sec - (hours * 3600) - (minutes * 60);
if (hours < 10) {hours = "0"+hours;}
if (minutes < 10) {minutes = "0"+minutes;}
if (seconds < 10) {seconds = "0"+seconds;}
return hours + ':' + minutes + ':' + seconds;
}
const queuestats_frame = document.getElementById('queuestats');
const sorter = natsort();
let redraw_timer = null;
const redraw_interval = 500;
const redraw_enqueue = () => {
if (redraw_timer !== null) {
return;
}
redraw_timer = setTimeout(() => {
redrawStats();
redraw_timer = null;
}, redraw_interval);
};
function DifferenceSeries(periodDuration, unitDuration) {
this.periodDuration = periodDuration;
this.unitDuration = unitDuration;
this.startOfPeriodIndex = null;
this.data = [];
this.rateData = [];
this.series = null;
}
DifferenceSeries.prototype.addPoint = function(options, redraw, shift, animation) {
var idx = this.startOfPeriodIndex,
dur = this.periodDuration,
data = this.data, n = data.length;
if (idx != null && n > 1) {
while (idx < n && data[idx][0] < options[0] - dur) {
idx++;
}
idx = idx - 1;
if (idx >= 0) {
var prevPoint = data[idx];
var timeDiff = options[0] - prevPoint[0];
var valueDiff = options[1] - prevPoint[1];
var rate = valueDiff / (timeDiff / this.unitDuration);
if (this.series) {
this.series.addPoint([ options[0], rate ], redraw, shift, animation);
} else {
this.rateData.push([ options[0], rate ]);
}
this.startOfPeriodIndex = idx + 1;
}
} else {
this.startOfPeriodIndex = 0;
}
this.data.push(options);
};
function makeEmpty(el) {
while (el.firstChild) {
el.removeChild(el.firstChild);
}
}
function makeTD() {
var td, span, span2;
td = document.createElement('td');
switch (arguments[0]) {
case 'legend':
span = document.createElement('span');
span2 = document.createElement('span');
span2.innerHTML = '&#8226;';
span2.id = 'legend-'+arguments[1];
span.appendChild(span2);
span.className = 'text';
span.appendChild(document.createTextNode(' '+arguments[1]));
td.appendChild(span);
break;
case 'text':
span = document.createElement('span');
span.className = 'text';
span.appendChild(document.createTextNode(arguments[1]));
td.appendChild(span);
break;
case 'num':
td.className = 'num';
span = document.createElement('span');
span.className = 'value';
span.appendChild(document.createTextNode(arguments[1]));
td.appendChild(span);
span = document.createElement('span');
span.className = 'unit';
span.appendChild(document.createTextNode(arguments[2]));
td.appendChild(span);
break;
}
return td;
}
function toggleShowAll() {
var showAll = ((''+location.hash).match('show-all'));
if (showAll) {
location.hash = '#';
} else {
location.hash = '#show-all';
}
redraw_enqueue();
updateChart();
return false;
}
function redrawStats() {
var showAll = ((''+location.hash).match('show-all'));
var div, table, tbody, tfoot, tr, td, span;
var div = document.createElement('div');
table = document.createElement('table');
table.className = 'items-count';
tbody = document.createElement('tbody');
tr = document.createElement('tr');
tr.appendChild(makeTD('text', 'items'));
td = document.createElement('td');
td.className = 'num';
tr.appendChild(td);
span = document.createElement('span');
span.className = 'value';
span.innerHTML = numeral(Number(stats.counts.done)).format('0.00a').toUpperCase().replace(/\.00$/, '');
td.appendChild(span);
span = document.createElement('span');
span.className = 'unit';
span.innerHTML = 'done';
td.appendChild(span);
//var out = stats.counts.out - Math.round(stats.counts.out * stats.counts.rcr);
var out = stats.counts.out;
if (out > 0) {
td.appendChild(document.createTextNode(' + '));
span = document.createElement('span');
span.className = 'value';
span.innerHTML = numeral(Number(out)).format('0.00a').toUpperCase().replace(/\.00$/, '');
td.appendChild(span);
span = document.createElement('span');
span.className = 'unit';
span.innerHTML = 'out';
td.appendChild(span);
}
//var todo = stats.counts.todo + Math.round(stats.counts.out * stats.counts.rcr);
var todo = stats.counts.todo;
td.appendChild(document.createTextNode(' + '));
span = document.createElement('span');
span.className = 'value';
span.innerHTML = numeral(Number(todo)).format('0.00a').toUpperCase().replace(/\.00$/, '');
td.appendChild(span);
span = document.createElement('span');
span.className = 'unit';
span.innerHTML = 'to do';
td.appendChild(span);
tbody.appendChild(tr);
table.appendChild(tbody);
div.appendChild(table);
table = document.createElement('table');
tbody = document.createElement('tbody');
var domain_count = 0;
for (var domain in stats.domain_bytes) {
if (trackerConfig.domains[domain]) {
domain_count += 1;
tr = document.createElement('tr');
tr.appendChild(makeTD('text', trackerConfig.domains[domain]));
var size = filesize(stats.domain_bytes[domain], {standard: 'iec', unix: false, output: 'array'});
tr.appendChild(makeTD('num',
size[0],
size[1]));
size = filesize(stats.domain_bytes[domain]/stats.counts.done, {standard: 'iec', unix: false, output: 'array'});
tr.appendChild(makeTD('num',
size[0],
size[1] + '/u'));
if (window.customDashboardDomainStats[domain]) {
let delta_seconds = ((new Date()) - window.customDashboardDomainStats[domain][0]) / 1000;
let bytes_per_second = filesize((stats.domain_bytes[domain] - window.customDashboardDomainStats[domain][2]) / delta_seconds, {standard: 'iec', unix: false, output: 'array', bits: true});
let items_per_second = numeral(Number((stats.counts.done - window.customDashboardDomainStats[domain][1]) / delta_seconds)).format('0.00a').toUpperCase().replace(/\.00$/, '');
tr.appendChild(makeTD('num',
bytes_per_second[0],
bytes_per_second[1] + "/s"));
tr.appendChild(makeTD('num',
items_per_second,
'items/s'));
tbody.appendChild(tr);
tr = document.createElement('tr');
tr.appendChild(makeTD('text', "estimates"));
tr.appendChild(makeTD('text', formatTimeDelta(Math.floor((stats.counts.todo + stats.counts.out) / items_per_second))));
tr.appendChild(makeTD('text', "from items/s"));
}
tbody.appendChild(tr);
}
}
table.appendChild(tbody);
if (domain_count > 1) {
tfoot = document.createElement('tfoot');
tr = document.createElement('tr');
tr.appendChild(makeTD('text', 'total'));
var size = filesize(stats.total_bytes, {standard: 'iec', unix: false, output: 'array'});
tr.appendChild(makeTD('num',
size[0],
size[1]));
size = filesize(stats.total_bytes/stats.counts.done, {standard: 'iec', unix: false, output: 'array'});
tr.appendChild(makeTD('num',
size[0],
size[1] + '/u'));
tfoot.appendChild(tr);
table.appendChild(tfoot);
}
div.appendChild(table);
var downloaders = stats.downloaders.sort(function(a, b) {
return stats.downloader_bytes[b] - stats.downloader_bytes[a];
});
table = document.createElement('table');
tbody = document.createElement('tbody');
for (var i=0; i<downloaders.length && (showAll || i<trackerConfig.numberOfDownloaders); i++) {
var downloader = downloaders[i];
tr = document.createElement('tr');
tr.downloader = downloader;
tr.style.cursor = 'pointer';
tr.appendChild(makeTD('legend', downloader));
var size = filesize(stats.downloader_bytes[downloader], {standard: 'iec', unix: false, output: 'array'});
tr.appendChild(makeTD('num',
size[0],
size[1]));
if (window.customDashboardStats[downloader]) {
let delta_seconds = ((new Date()) - window.customDashboardStats[downloader][0]) / 1000;
let bytes_per_second = filesize((stats.downloader_bytes[downloader] - window.customDashboardStats[downloader][2]) / delta_seconds, {standard: 'iec', unix: false, output: 'array', bits: true});
let items_per_second = numeral(Number((stats.downloader_count[downloader] - window.customDashboardStats[downloader][1]) / delta_seconds)).format('0.00a').toUpperCase().replace(/\.00$/, '');
tr.appendChild(makeTD('num',
bytes_per_second[0],
bytes_per_second[1] + "/s"));
tr.appendChild(makeTD('num',
numeral(Number(stats.downloader_count[downloader])).format('0.00a').toUpperCase().replace(/\.00$/, ''),
'items'));
tr.appendChild(makeTD('num',
items_per_second,
'items/s'));
} else {
tr.appendChild(makeTD('num',
"0",
"B"));
tr.appendChild(makeTD('num',
numeral(Number(stats.downloader_count[downloader])).format('0.00a').toUpperCase().replace(/\.00$/, ''),
'items'));
tr.appendChild(makeTD('num',
"0",
'items/s'));
}
tbody.appendChild(tr);
}
table.appendChild(tbody);
div.appendChild(table);
var a = document.createElement('a');
a.innerHTML = showAll ? '&ndash; ' : '+ ';
a.id = 'show-all';
a.href = showAll ? '#' : '#show-all';
a.onclick = toggleShowAll;
span = document.createElement('span');
span.innerHTML = showAll ? 'Show fewer' : 'Show all';
a.appendChild(span);
div.appendChild(a);
var left = document.getElementById('left');
left.parentNode.replaceChild(div, left);
div.id = 'left';
if (stats.stats && stats.stats.queues) {
const queuestats_text = [];
Array.prototype.push.apply(queuestats_text, Object.entries(stats.stats.queues).sort((a, b) => sorter(a[0], b[0])).map(line => `${line[0]}: ${line[1]}`));
queuestats_text.push(`-----`);
Array.prototype.push.apply(queuestats_text, Object.entries(stats.stats.values).sort((a, b) => sorter(a[0], b[0])).map(line => `${line[0]}: ${line[1]}`));
queuestats_text.push(`-----`);
queuestats_text.push(`reclaim rate: ${Math.round(stats.counts.rcr * 100)}% (${stats.counts.rcr})`);
queuestats_text.push(`reclaim serve rate: ${Math.round(stats.counts.rcsr * 100)}% (${stats.counts.rcsr})`);
queuestats_text.push(`item request serve rate: ${Math.round(stats.counts.irsr * 100)}% (${stats.counts.irsr})`);
queuestats_text.push(`item filter rate: ${Math.round(stats.counts.ifir * 100)}% (${stats.counts.ifir})`);
queuestats_text.push(`item fail rate: ${Math.round(stats.counts.ifar * 100)}% (${stats.counts.ifar})`);
queuestats_frame.innerText = queuestats_text.join('\n');
}
}
var lastRedrawn = null;
var downloaderSeries = {};
function updateChart() {
if (!chart) return;
var downloaders = stats.downloaders.sort(function(a, b) {
return stats.downloader_bytes[b] - stats.downloader_bytes[a];
});
chart.series[0].addPoint([ new Date() * 1, stats.counts.done ],
false, false, false);
stats.items_done_rate.addPoint([ new Date() * 1, stats.counts.done ],
false, false, false);
stats.bytes_download_rate.addPoint([ new Date() * 1, stats.total_bytes ],
false, false, false);
for (var i=0; i<downloaders.length && i<trackerConfig.numberOfDownloadersInGraph; i++) {
var downloader = downloaders[i];
var series = downloaderSeries[downloader];
if (!series) {
var seriesData = [];
if (stats.downloader_chart[downloader]) {
seriesData = stats.downloader_chart[downloader];
for (var j=seriesData.length-1; j>=0; j--) {
seriesData[j][0] = seriesData[j][0] * 1000;
seriesData[j][1] = seriesData[j][1] / (1024*1024*1024);
}
}
seriesData.push([ new Date() * 1, stats.downloader_bytes[downloader]/(1024*1024*1024) ]);
downloaderSeries[downloader] = series = chart.addSeries({'name':downloader,
'marker':{'enabled':false},
'shadow':false,
'data':seriesData,
stickyTracing: false
},
false, false);
} else {
series.addPoint([ new Date() * 1, stats.downloader_bytes[downloader]/(1024*1024*1024) ],
false, false, false);
}
var span = document.getElementById('legend-'+downloader);
if (span) {
span.style.color = series.color;
span.style.visibility = series.visible ? 'visible' : 'hidden';
}
}
if (lastRedrawn == null || new Date() - lastRedrawn > 30*1000) {
lastRedrawn = new Date();
chart.redraw();
}
}
function handleDownloaderClick(evt) {
var tr = evt.target;
while (tr && tr.nodeName!='TR' && tr.parentNode) {
tr = tr.parentNode;
}
if (tr && tr.nodeName=='TR' && tr.downloader) {
var downloader = tr.downloader;
if (downloaderSeries[downloader]) {
var series = downloaderSeries[downloader];
if (series.visible)
series.hide();
else
series.show();
var span = document.getElementById('legend-'+downloader);
if (span) {
span.style.visibility = series.visible ? 'visible' : 'hidden';
}
chart.series[0].hide();
chart.series[0].show();
}
}
}
function updateStats(msg, dupe) {
stats.counts = msg.counts;
stats.queuestats = msg.queuestats;
stats.stats = msg.stats;
if (!dupe) {
if (!stats.downloader_bytes[msg.downloader]) {
stats.downloader_bytes[msg.downloader] = 0;
stats.downloader_count[msg.downloader] = 0;
stats.downloaders.push(msg.downloader);
}
stats.downloader_count[msg.downloader] += msg.items.length;
}
for (var domain in msg.domain_bytes) {
bytes = msg.domain_bytes[domain] * 1;
if (!stats.domain_bytes[domain]) {
stats.domain_bytes[domain] = 0;
}
stats.domain_bytes[domain] += bytes;
stats.downloader_bytes[msg.downloader] += bytes;
stats.total_bytes += bytes;
if (!window.customDashboardDomainStats[domain]) {
window.customDashboardDomainStats[domain] = [new Date(), stats.counts.done, stats.domain_bytes[domain]];
}
}
if (!window.customDashboardStats[msg.downloader]) {
window.customDashboardStats[msg.downloader] = [new Date(), stats.downloader_count[msg.downloader], stats.downloader_bytes[msg.downloader]];
}
if (!window.customDashboardInitialItemCounts) {
window.customDashboardInitialItemCounts = [new Date(), stats.counts];
}
redraw_enqueue();
updateChart();
}
function addLog(msg) {
var tbody, tr;
tbody = document.getElementById('log');
tr = document.createElement('tr');
tr.className = [
msg.user_agent && msg.user_agent.match(/Warrior$/) ? 'warrior' : undefined,
msg.is_duplicate && msg.items.length === 1 ? 'dup' : undefined
].filter(className => className !== undefined).join(' ');
var downloaderTd = makeTD('text', msg.downloader);
//var itemTextTd = makeTD('text', msg.items.length > 1 ? (msg.move_items.length !== msg.items.length ? (msg.move_items.length + '/') : '') + msg.items.length + ' items' : msg.item);
//var itemTextTd = makeTD('text', msg.items.length > 1 ? msg.move_items.length + '/' + msg.items.length + ' items' + (msg.move_items.length !== msg.items.length ? ' (-' + (msg.items.length - msg.move_items.length) + ')' : '') : msg.item);
var itemTextTd = makeTD('text', msg.items.length > 1 ? msg.items.length + ' items' + (msg.move_items.length !== msg.items.length ? ' (' + (msg.items.length - msg.move_items.length) + ' dupes)' : '') : msg.item);
var size = filesize(msg.bytes, {standard: 'iec', unix: false, output: 'array'});
var sizeTd = makeTD('num', size[0], size[1]);
downloaderTd.className = 'downloader';
itemTextTd.title = msg.item;
tr.appendChild(downloaderTd);
tr.appendChild(itemTextTd);
tr.appendChild(sizeTd);
downloaderTd.title = '';
if (msg.version) {
downloaderTd.title = 'Version: '+msg.version;
}
if (msg.user_agent) {
downloaderTd.title += ' | User Agent: '+msg.user_agent;
}
tbody.insertBefore(tr, tbody.firstChild);
while (tbody.childNodes.length > trackerConfig.numberOfLogLines) {
tbody.removeChild(tbody.childNodes[trackerConfig.numberOfLogLines]);
}
}
function getLogHostURL() {
if (document.location.protocol == 'http:') {
return trackerConfig.logHost;
} else {
return trackerConfig.sslLogHost;
}
}
function startLogClient() {
var socket = io.connect(document.location.protocol+'//'+getLogHostURL()+'/'+trackerConfig.logChannel);
socket.on("log_message", function(data) {
var msg = JSON.parse(data);
if (msg.downloader && msg.item && msg.bytes !== undefined) {
addLog(msg);
updateStats(msg, msg.is_duplicate);
}
});
}
function initLog() {
jQuery.getJSON(document.location.protocol+'//'+getLogHostURL()+'/recent/'+(trackerConfig.logChannel), function(messages) {
for (var i=0; i<messages.length; i++) {
var msg = messages[i];
if (msg.downloader && msg.item && msg.bytes !== undefined) {
addLog(msg);
}
}
startLogClient();
});
}
var chart = null;
function buildChart() {
var maxMinTimestamp = 0;
if (stats.items_done_chart.length > 0) {
maxMinTimestamp = Math.max(maxMinTimestamp, stats.items_done_chart[0][0] * 1000);
}
for (var i in stats.downloader_chart) {
if (stats.downloader_chart[i].length > 0) {
maxMinTimestamp = Math.max(maxMinTimestamp, stats.downloader_chart[i][0][0] * 1000);
}
}
if (maxMinTimestamp == 0) {
maxMinTimestamp = null;
}
var seriesData = stats.items_done_chart;
for (var j=seriesData.length-1; j>=0; j--) {
seriesData[j][0] *= 1000;
}
// take the hourly rate based on a moving interval of 10 minutes
var diffSeries = new DifferenceSeries(trackerConfig.movingAverageInterval * 60000, 60 * 60000);
for (var j=0; j<seriesData.length; j++) {
diffSeries.addPoint(seriesData[j]);
}
stats.items_done_rate = diffSeries;
// count MB/s based on a moving interval of 10 minutes
diffSeries = new DifferenceSeries(trackerConfig.movingAverageInterval * 60000, 1000);
var perDownloaderData = [], perDownloaderIndex = [];
for (var i in stats.downloader_chart) {
perDownloaderData.push(stats.downloader_chart[i]);
perDownloaderIndex.push(0);
}
var sumBytes = 0;
while (perDownloaderData.length > 0) {
var minTime = null, minTimeIdx = null, j;
for (j = perDownloaderData.length - 1; j>=0; j--) {
var entry = perDownloaderData[j][perDownloaderIndex[j]];
if (entry && (minTime == null || entry[0] <= minTime)) {
minTime = entry[0];
minTimeIdx = j;
}
}
if (j < 0) break;
if (minTimeIdx != null) {
if (perDownloaderIndex[minTimeIdx] > 0) {
sumBytes -= perDownloaderData[minTimeIdx][perDownloaderIndex[minTimeIdx] - 1][1];
}
sumBytes += perDownloaderData[minTimeIdx][perDownloaderIndex[minTimeIdx]][1];
diffSeries.addPoint([ minTime * 1000, sumBytes ]);
perDownloaderIndex[minTimeIdx]++;
if (perDownloaderIndex[minTimeIdx] >= perDownloaderData[minTimeIdx].length) {
perDownloaderIndex.splice(minTimeIdx, 1);
perDownloaderData.splice(minTimeIdx, 1);
}
}
}
stats.bytes_download_rate = diffSeries;
chart = new Highcharts.StockChart({
chart: {renderTo:'chart-container', zoomType:'x'},
title:{text:null},
legend:{enabled:false},
credits:{enabled:false},
rangeSelector: {
buttons: [ {type:'day', count:1,text: '1d'},
{type:'week', count:1,text: '1w'},
{type:'month',count:1,text: '1m'},
{type:'all', text: 'all'} ]
},
xAxis:{type:'datetime'},
yAxis:[ { min:0, maxPadding: 0,
title:{text:'GB done'},
labels:{align:'left',x:0,y:-2},
height: 200 },
{ min:0, maxPadding: 0,
title:{text:'items', style:{color:'#aaa'}},
opposite:true,
labels:{align:'right',x:0, y:-2},
height: 200 },
{ min:0, maxPadding: -0.5,
title:{text:'bytes/s', style:{color:'#000'}},
labels:{align:'left',x:0,y:-2},
height: 70, top: 260, offset: 0 },
{ min:0, maxPadding: -0.5,
title:{text:'items/hour'},
opposite:true,
labels:{align:'right',x:0, y:-2},
height: 70, top: 260, offset: 0 } ],
series:[{ name:'items done',
type: 'area',
data: seriesData,
color: '#aaa',
fillColor: '#eee',
shadow: false,
marker: {enabled: false},
yAxis: 1 },
{ name:'items/hour',
type: 'spline',
data: stats.items_done_rate.rateData,
color: '#6D869F',
shadow: false,
marker: {enabled: false},
yAxis: 3 },
{ name:'bytes/s',
type: 'spline',
data: stats.bytes_download_rate.rateData,
color: '#000',
shadow: false,
marker: {enabled: false},
yAxis: 2 }],
tooltip: {
crosshairs: false,
shared: false,
snap: 0
}
});
stats.items_done_rate.series = chart.series[1];
stats.bytes_download_rate.series = chart.series[2];
$(document.body).bind('click', handleDownloaderClick);
}
function refreshUpdateStatus() {
if (!trackerConfig.updateStatusPath) return;
jQuery.getJSON(trackerConfig.updateStatusPath, function(data) {
if (data.current_version == null || data.current_version == '')
return;
var mustUpdate = [];
for (var d in data.downloader_version) {
if (data.downloader_version[d] < data.current_version) {
mustUpdate.push(d);
}
}
var p = document.getElementById("update-status");
p.style.display = 'none';
makeEmpty(p);
if (mustUpdate.length > 0) {
mustUpdate.sort();
var sentence = data.current_version_update_message + ": " + mustUpdate.join(", ");
p.appendChild(document.createTextNode(sentence));
p.style.display = 'block';
}
});
}
var previousChartDataUrls = [];
function handleCharts(newCharts) {
if (!stats.downloader_chart) stats.downloader_chart = {};
if (!stats.items_done_chart) stats.items_done_chart = [];
if (!stats.items_done_chart) stats.items_done_chart = [];
for (var d in newCharts.downloader_chart) {
if (!stats.downloader_chart[d]) stats.downloader_chart[d] = [];
stats.downloader_chart[d] = newCharts.downloader_chart[d].concat(stats.downloader_chart[d]);
}
stats.items_done_chart = newCharts.items_done_chart.concat(stats.items_done_chart);
stats.bytes_done_chart = newCharts.bytes_done_chart.concat(stats.bytes_done_chart);
if (newCharts.previous_chart_data_urls) {
previousChartDataUrls.push.apply(previousChartDataUrls, newCharts.previous_chart_data_urls);
}
if (previousChartDataUrls.length > 0) {
jQuery.getJSON(previousChartDataUrls.shift(), handleCharts);
} else {
buildChart();
redraw_enqueue();
updateChart();
}
}
var stats = null;
jQuery.getJSON(trackerConfig.statsPath, function(newStats) {
stats = newStats;
redraw_enqueue();
initLog();
if (trackerConfig.updateStatusPath) {
refreshUpdateStatus();
window.setInterval(function() { refreshUpdateStatus(); }, 60000);
}
jQuery.getJSON(trackerConfig.chartsPath, handleCharts);
});
$('#how-to-help-cue').click(function(e) {
e.preventDefault();
$('#how-to-help-cue').animate({height: "hide"});
$('#how-to-help').animate({height: "show"});
});
})(window.trackerConfig);
@devnoname120
Copy link

devnoname120 commented Nov 29, 2023

Fix for native Chrome support of userscripts + annoying sandboxed userscript runtimes.

--- /dev/fd/13	2023-11-29 23:27:58
+++ /dev/fd/14	2023-11-29 23:27:58
@@ -3,7 +3,7 @@
 // @namespace   Nothing4You
 // @match       https://tracker.archiveteam.org/*/
 // @grant       none
-// @version     1.2.0
+// @version     1.3.0
 // @author      Nothing4You
 // @description adds more information to archive team tracker dashboards
 // @updateURL   https://gist.githubusercontent.com/Nothing4You/b127b3cc4d4fabe372dcf078dbe86070/raw/dashboard.user.js
@@ -23,6 +23,12 @@
  3. Don't complain if anything breaks :)
  ***/

+// Inject script into DOM in order to bypass Userscript sandbox
+const script = document.createElement('script');
+script.appendChild(document.createTextNode('('+ main +')();'));
+(document.body || document.head || document.documentElement).appendChild(script);
+
+function main() {
 (function initDashboard(trackerConfig) {
   window.customDashboardStats = {};
   window.customDashboardDomainStats = {};
@@ -736,3 +742,4 @@
   });

 })(window.trackerConfig);
+}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment