This commit is contained in:
Lilith Ashley Nyx Arson 🔥 2024-11-03 22:55:51 +01:00
parent 70b92ce0fc
commit aa5816daef
Signed by: lilith
SSH key fingerprint: SHA256:LAjgsAMyT3LO2JVtr6fQ4N3RTYoRRlIm5wAKsbDife4
16 changed files with 382 additions and 61 deletions

View file

@ -11,6 +11,13 @@ body {
background: #eff1f5;
color: #4c4f69;
font-family: "Terminess Nerd Font Mono", monospace;
}
a {
color: #8839ef;
text-decoration: none;
}
@media (prefers-color-scheme: dark) {
@ -18,6 +25,15 @@ body {
background: #1e1e2e;
color: #cdd6f4;
}
a {
color: #cba6f7;
}
}
th,
td {
text-align: left;
}
fieldset {

39
css/terminess.css Normal file
View file

@ -0,0 +1,39 @@
@font-face {
font-family: 'Terminess Nerd Font Mono';
src: local('Terminess Nerd Font Mono Bold Italic'), local('TerminessNFM-BoldItalic'),
url('TerminessNFM-BoldItalic.woff2') format('woff2'),
url('TerminessNFM-BoldItalic.woff') format('woff');
font-weight: bold;
font-style: italic;
font-display: swap;
}
@font-face {
font-family: 'Terminess Nerd Font Mono';
src: local('Terminess Nerd Font Mono Bold'), local('TerminessNFM-Bold'),
url('TerminessNFM-Bold.woff2') format('woff2'),
url('TerminessNFM-Bold.woff') format('woff');
font-weight: bold;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Terminess Nerd Font Mono';
src: local('Terminess Nerd Font Mono Italic'), local('TerminessNFM-Italic'),
url('TerminessNFM-Italic.woff2') format('woff2'),
url('TerminessNFM-Italic.woff') format('woff');
font-weight: 500;
font-style: italic;
font-display: swap;
}
@font-face {
font-family: 'Terminess Nerd Font Mono';
src: local('Terminess Nerd Font Mono'), local('TerminessNFM'),
url('TerminessNFM.woff2') format('woff2'),
url('TerminessNFM.woff') format('woff');
font-weight: 500;
font-style: normal;
font-display: swap;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
fonts/TerminessNFM.woff Normal file

Binary file not shown.

BIN
fonts/TerminessNFM.woff2 Normal file

Binary file not shown.

View file

@ -5,26 +5,15 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>opentracker</title>
<link rel="stylesheet" href="css/terminess.css">
<link rel="stylesheet" href="css/style.css">
<link rel="stylesheet" href="css/nerd-fonts.min.css">
</head>
<body>
<fieldset class="container">
<legend>opentracker</legend>
<table>
<tr>
<th id="s"><i class="nf nf-fa-spinner nf-spin"></i></th>
<td>Seeder(s)</td>
</tr>
<tr>
<th id="l"><i class="nf nf-fa-spinner nf-spin"></i></th>
<td>Leecher(s)</td>
</tr>
</table>
<small id="footer"><i class="nf nf-fa-spinner nf-spin"></i> Loading...</small>
<table id="torrents"></table>
<small id="footer">Please wait...</small>
</fieldset>
<script defer src="js/script.js"></script>

View file

@ -1,50 +1,78 @@
function xml2json(xml) {
var obj = {};
if (xml.nodeType == 1) {
if (xml.attributes.length > 0) {
obj["@attributes"] = {};
for (var j = 0; j < xml.attributes.length; j++) {
var attribute = xml.attributes.item(j);
obj["@attributes"][attribute.nodeName] = attribute.nodeValue;
}
}
} else if (xml.nodeType == 3) {
obj = xml.nodeValue.trim();
}
var textNodes = [].slice.call(xml.childNodes).filter(function (node) {
return node.nodeType === 3;
});
if (xml.hasChildNodes() && xml.childNodes.length === textNodes.length) {
obj = [].slice.call(xml.childNodes).reduce(function (text, node) {
return text + node.nodeValue.trim();
}, "");
} else if (xml.hasChildNodes()) {
for (var i = 0; i < xml.childNodes.length; i++) {
var item = xml.childNodes.item(i);
var nodeName = item.nodeName;
if (nodeName == "#text") continue;
if (typeof obj[nodeName] == "undefined") {
obj[nodeName] = xml2json(item);
} else {
if (typeof obj[nodeName].push == "undefined") {
var old = obj[nodeName];
obj[nodeName] = [];
obj[nodeName].push(old);
}
obj[nodeName].push(xml2json(item));
}
}
}
return obj;
}
const parser = new DOMParser();
fetch("stats?mode=everything").then(r => r.text()).then(r => {
var data = xml2json(parser.parseFromString(r, "text/xml")).stats;
document.querySelector("#s").textContent = data.seeds.count;
document.querySelector("#l").textContent = data.completed.count;
document.querySelector("#footer").textContent = `serving ${data.torrents.count_mutex} torrents`;
var host = "stats?mode=%";
if (["localhost", "127.0.0.1", "[::]"].includes(location.hostname)) {
host = "sample/%.txt"
}
fetch(host.replace("%", "torr")).then(r => r.text()).then(r => {
document.querySelector("#footer").textContent = r.split("\n")[2];
});
var i = {
"S": "\uf062",
"P": "\uf063",
"L": "\uf46f"
}
fetch(host.replace("%", "top10")).then(r => r.text()).then(r => {
var lines = r.split("\n");
var current = "";
var data = {}
var hashes = {}
for (const line of lines) {
if (line.trim() == "") continue;
if (!line.startsWith("\t")) {
current = line.slice(line.indexOf("by ") + 3, -1);
data[current] = [];
} else {
var segments = line.trim().split("\t");
var info = {
num: parseInt(segments[0]),
hash: segments[1]
}
hashes[info.hash] = hashes[info.hash] ?? { "seeds": 0 };
hashes[info.hash][current] = hashes[info.hash][current] ?? 0;
hashes[info.hash][current] += info.num;
data[current].push(info);
}
}
var tr = document.createElement("tr");
var th = document.createElement("th");
th.textContent = "\uf4df";
tr.appendChild(th);
for (const t of Object.keys(hashes[Object.keys(hashes)[0]])) {
var th = document.createElement("th");
th.textContent = i[t.slice(0, 1).toUpperCase()];
tr.appendChild(th);
}
document.querySelector("#torrents").appendChild(tr);
for (const hash of Object.keys(hashes)) {
var data = hashes[hash];
var tr = document.createElement("tr");
tr.style = "font-family:monospace";
var td = document.createElement("td");
var a = document.createElement("a");
a.href = `magnet:?xt=urn:btih:${hash}&tr=https://${location.hostname}/announce&tr=http://${location.hostname}/announce&tr=udp://${location.hostname}:6969/announce`;
a.textContent = hash;
td.appendChild(a);
tr.appendChild(td);
for (const key of Object.keys(data)) {
var td = document.createElement("td");
td.textContent = data[key];
tr.appendChild(td);
}
document.querySelector("#torrents").appendChild(tr);
}
});

101
sample/everything.txt Normal file
View file

@ -0,0 +1,101 @@
<?xml version="1.0" encoding="UTF-8"?>
<stats>
<tracker_id>964180315</tracker_id>
<version>
https://erdgeist.org/gitweb/opentracker/commit/?id=c854b3db9bf620e86481acfcc9fc31eba64bc8e6
</version>
<uptime>6392</uptime>
<torrents>
<count_mutex>59</count_mutex>
<count_iterator>59</count_iterator>
</torrents>
<peers>
<count>118</count>
</peers>
<seeds>
<count>118</count>
</seeds>
<completed>
<count>3</count>
</completed>
<connections>
<tcp>
<accept>324</accept>
<announce>64</announce>
<scrape>3</scrape>
</tcp>
<udp>
<overall>156</overall>
<connect>14</connect>
<announce>123</announce>
<scrape>19</scrape>
<missmatch>0</missmatch>
</udp>
<livesync>
<count>0</count>
</livesync>
</connections>
<debug>
<renew>
<count interval="00">1</count>
<count interval="01">1</count>
<count interval="02">31</count>
<count interval="03">26</count>
<count interval="04">0</count>
<count interval="05">0</count>
<count interval="06">0</count>
<count interval="07">0</count>
<count interval="08">0</count>
<count interval="09">1</count>
<count interval="10">0</count>
<count interval="11">0</count>
<count interval="12">1</count>
<count interval="13">0</count>
<count interval="14">0</count>
<count interval="15">0</count>
<count interval="16">0</count>
<count interval="17">0</count>
<count interval="18">0</count>
<count interval="19">0</count>
<count interval="20">0</count>
<count interval="21">0</count>
<count interval="22">0</count>
<count interval="23">0</count>
<count interval="24">0</count>
<count interval="25">0</count>
<count interval="26">0</count>
<count interval="27">1</count>
<count interval="28">0</count>
<count interval="29">2</count>
<count interval="30">0</count>
<count interval="31">1</count>
<count interval="32">0</count>
<count interval="33">0</count>
<count interval="34">0</count>
<count interval="35">0</count>
<count interval="36">0</count>
<count interval="37">0</count>
<count interval="38">0</count>
<count interval="39">0</count>
<count interval="40">0</count>
<count interval="41">0</count>
<count interval="42">0</count>
<count interval="43">0</count>
<count interval="44">0</count>
</renew>
<http_error>
<count code="302 Redirect">1</count>
<count code="400 Parse Error">0</count>
<count code="400 Invalid Parameter">13</count>
<count code="400 Invalid Parameter (compact=0)">0</count>
<count code="400 Not Modest">0</count>
<count code="402 Payment Required">0</count>
<count code="403 Access Denied">0</count>
<count code="404 Not found">6</count>
<count code="500 Internal Server Error">1</count>
</http_error>
<mutex_stall>
<count>0</count>
</mutex_stall>
</debug>
</stats>

23
sample/top10.txt Normal file
View file

@ -0,0 +1,23 @@
Top 10 torrents by peers:
2 03C2E7E18CA5314E39A3FFC753D1024FBFB20784
2 04EBCEDCE991140547F9480EDD8051EEAB2BB668
2 060FCE53DFE77485BAD7FBB919C5ED543472EB30
2 08A47A77872979C7C086F412143916A7096369CD
2 0E1610F5C681BBE8E908DDB7F73DC890899994F4
2 16AA39B7F784C6D3519D1D9893EE3B1EAF3B3AAD
2 174187E47484B3A46D34ACCEC66245F504932081
2 1B5EF508045EB4B0B28261311E63800B7B50A2F2
2 2187F35114A736DC847113878687EC0EEBA1B854
2 23C8467227E53AE940BC22423FB2D603B9B4FF7C
Top 10 torrents by seeds:
2 03C2E7E18CA5314E39A3FFC753D1024FBFB20784
2 04EBCEDCE991140547F9480EDD8051EEAB2BB668
2 060FCE53DFE77485BAD7FBB919C5ED543472EB30
2 08A47A77872979C7C086F412143916A7096369CD
2 0E1610F5C681BBE8E908DDB7F73DC890899994F4
2 16AA39B7F784C6D3519D1D9893EE3B1EAF3B3AAD
2 174187E47484B3A46D34ACCEC66245F504932081
2 1B5EF508045EB4B0B28261311E63800B7B50A2F2
2 2187F35114A736DC847113878687EC0EEBA1B854
2 23C8467227E53AE940BC22423FB2D603B9B4FF7C
Top 10 torrents by leechers:

121
sample/top100.txt Normal file
View file

@ -0,0 +1,121 @@
Top 100 torrents by peers:
2 03C2E7E18CA5314E39A3FFC753D1024FBFB20784
2 04EBCEDCE991140547F9480EDD8051EEAB2BB668
2 060FCE53DFE77485BAD7FBB919C5ED543472EB30
2 08A47A77872979C7C086F412143916A7096369CD
2 0E1610F5C681BBE8E908DDB7F73DC890899994F4
2 16AA39B7F784C6D3519D1D9893EE3B1EAF3B3AAD
2 174187E47484B3A46D34ACCEC66245F504932081
2 1B5EF508045EB4B0B28261311E63800B7B50A2F2
2 2187F35114A736DC847113878687EC0EEBA1B854
2 23C8467227E53AE940BC22423FB2D603B9B4FF7C
2 2C5F3C95275151B88FE5F2C0D9FDFB99124133F1
2 2FC843BCB8137E88B75B98B5C553CD071552852B
2 31D6E5FD572688BC51460E86FDD83B1BE5651F6E
2 3359EEE1F8BB251A8E1C5F12984BBADE267C1A02
2 396C9CF961703CCC8B8E9368BBDD5E6182A2160E
2 39B7654A7F415EBB4B86F78D384054792856111A
2 3DF7FA24521A67005B7B4E0A08F0C9E2D45E086F
2 3F09A805066876F2A54BD4CED55178D25E05BF10
2 40762B23D0AF64AE6D10EAD50022D83155E93827
2 4BEC5076C6CF7382EB6AD20156394C7230D590E7
2 4DCCED4A8C502C0C7E92B0BD5F63DD7814D86FC5
2 4FAB99B5620FA761A665DA5DC73CEA43A09A7D2B
2 56BA092EBBD70D1F389F7C207D89867300A33D49
2 7888264FFFD96AB2FA5A188A060A4BC9D0AEDAED
2 7A8217D9C65441C4ABEE33A0291CBA437BF844CA
2 8A7403772FAA4B3C987C613D99A783E26FD9BC93
2 8C7BB67E61065C5CEAB44D757D0CA2CB69BEED31
2 8C873164EBB96A4C3C15F111DD06575F770C9001
2 8D732DA24D0011D82F770B4AF8BC3539A6A89BC4
2 9239D8792C8226F533EAFCACDC88AF470D2670D4
2 93A06433A4217130FED11FFF7F9186A5FDB66628
2 9C12DF3391A4BFE4E51DE96EB3A98C1C8D5BA92E
2 AC35536AF8E7FE0BFF25CD8783747F7B96C53E8F
2 AF8C7138AA1869DA4D65099BDF4EE3C09DAF2EB1
2 B06F3E1FF3573905C4653892B22F15C491A28CB8
2 B1C6A489D03B2AC090EFAED2B8897064D591A386
2 B85BF16A2DA3D73B135471C41DF3E1640E57A48B
2 BC55684FFD49F37118C86E4B78653FC57B9D1721
2 C1C12677F61F58EC920AB5A5526D3A2906AF72A1
2 C578A179954753693176292D44380F2BF5200EC6
2 C6BE5D71C483B3E952524CFE782C151E60C72152
2 C6E943B742BF05F648AF7AF03D0954F819A66CE1
2 C7F5234582D772BD16011F0E480F06706CD12F14
2 CA3E8DE93CD7BA71C28FDCC71C1828D6DF45006A
2 CDC00E20D451A1C9BC674A58A2014A84C66AE9F7
2 CDFAC041819603EF8345EF6E241FF67477E2BF55
2 CE0C28F10F87830254E80D6F54516F2AD2E7F5C2
2 CFEC68E6D5EC4713ECF50301DFC26AE0443B3620
2 D0341227B45EC1415C54D13C3FB670E760BD95D5
2 D2B10F9480B70664835BEC6401EA3D72343D645A
2 D62B82A02E718CB86282812624C0C63F8246693D
2 D7B41897BCCB71AE27AB646BB0FA1E98D5BAABA6
2 D813DBB9A69B979AD745CFC17895068A73F1C81B
2 D8D32670CDB2264416A0A88FB33D246F6B85CC24
2 E59712FDEA810860CDE3DAE8494B047BFA947E0D
2 E8027DD86E35A2F146C4690B69B9EDE793F527E8
2 F235B0E32828A3D5CE873C738F8553720F92E796
2 F3542CBB1AB193FADDF3204A0C936E37F3381055
2 FC3278EF007EA723D8ACED9B0A73C7F55C5ECAD5
Top 100 torrents by seeds:
2 03C2E7E18CA5314E39A3FFC753D1024FBFB20784
2 04EBCEDCE991140547F9480EDD8051EEAB2BB668
2 060FCE53DFE77485BAD7FBB919C5ED543472EB30
2 08A47A77872979C7C086F412143916A7096369CD
2 0E1610F5C681BBE8E908DDB7F73DC890899994F4
2 16AA39B7F784C6D3519D1D9893EE3B1EAF3B3AAD
2 174187E47484B3A46D34ACCEC66245F504932081
2 1B5EF508045EB4B0B28261311E63800B7B50A2F2
2 2187F35114A736DC847113878687EC0EEBA1B854
2 23C8467227E53AE940BC22423FB2D603B9B4FF7C
2 2C5F3C95275151B88FE5F2C0D9FDFB99124133F1
2 2FC843BCB8137E88B75B98B5C553CD071552852B
2 31D6E5FD572688BC51460E86FDD83B1BE5651F6E
2 3359EEE1F8BB251A8E1C5F12984BBADE267C1A02
2 396C9CF961703CCC8B8E9368BBDD5E6182A2160E
2 39B7654A7F415EBB4B86F78D384054792856111A
2 3DF7FA24521A67005B7B4E0A08F0C9E2D45E086F
2 3F09A805066876F2A54BD4CED55178D25E05BF10
2 40762B23D0AF64AE6D10EAD50022D83155E93827
2 4BEC5076C6CF7382EB6AD20156394C7230D590E7
2 4DCCED4A8C502C0C7E92B0BD5F63DD7814D86FC5
2 4FAB99B5620FA761A665DA5DC73CEA43A09A7D2B
2 56BA092EBBD70D1F389F7C207D89867300A33D49
2 7888264FFFD96AB2FA5A188A060A4BC9D0AEDAED
2 7A8217D9C65441C4ABEE33A0291CBA437BF844CA
2 8A7403772FAA4B3C987C613D99A783E26FD9BC93
2 8C7BB67E61065C5CEAB44D757D0CA2CB69BEED31
2 8C873164EBB96A4C3C15F111DD06575F770C9001
2 8D732DA24D0011D82F770B4AF8BC3539A6A89BC4
2 9239D8792C8226F533EAFCACDC88AF470D2670D4
2 93A06433A4217130FED11FFF7F9186A5FDB66628
2 9C12DF3391A4BFE4E51DE96EB3A98C1C8D5BA92E
2 AC35536AF8E7FE0BFF25CD8783747F7B96C53E8F
2 AF8C7138AA1869DA4D65099BDF4EE3C09DAF2EB1
2 B06F3E1FF3573905C4653892B22F15C491A28CB8
2 B1C6A489D03B2AC090EFAED2B8897064D591A386
2 B85BF16A2DA3D73B135471C41DF3E1640E57A48B
2 BC55684FFD49F37118C86E4B78653FC57B9D1721
2 C1C12677F61F58EC920AB5A5526D3A2906AF72A1
2 C578A179954753693176292D44380F2BF5200EC6
2 C6BE5D71C483B3E952524CFE782C151E60C72152
2 C6E943B742BF05F648AF7AF03D0954F819A66CE1
2 C7F5234582D772BD16011F0E480F06706CD12F14
2 CA3E8DE93CD7BA71C28FDCC71C1828D6DF45006A
2 CDC00E20D451A1C9BC674A58A2014A84C66AE9F7
2 CDFAC041819603EF8345EF6E241FF67477E2BF55
2 CE0C28F10F87830254E80D6F54516F2AD2E7F5C2
2 CFEC68E6D5EC4713ECF50301DFC26AE0443B3620
2 D0341227B45EC1415C54D13C3FB670E760BD95D5
2 D2B10F9480B70664835BEC6401EA3D72343D645A
2 D62B82A02E718CB86282812624C0C63F8246693D
2 D7B41897BCCB71AE27AB646BB0FA1E98D5BAABA6
2 D813DBB9A69B979AD745CFC17895068A73F1C81B
2 D8D32670CDB2264416A0A88FB33D246F6B85CC24
2 E59712FDEA810860CDE3DAE8494B047BFA947E0D
2 E8027DD86E35A2F146C4690B69B9EDE793F527E8
2 F235B0E32828A3D5CE873C738F8553720F92E796
2 F3542CBB1AB193FADDF3204A0C936E37F3381055
2 FC3278EF007EA723D8ACED9B0A73C7F55C5ECAD5
Top 100 torrents by leechers:

4
sample/torr.txt Normal file
View file

@ -0,0 +1,4 @@
59
0
opentracker serving 59 torrents
opentracker