"use strict"; class trweb { #knownTorrents = {}; #needsSort = false; #loadcb = function(key) {return localStorage.getItem(`trweb.${key}`)}; #savecb = function(key, value) {localStorage.setItem(`trweb.${key}`, value)}; #logger = function(msg) {}; #logcb = function(module, loglevel, msg) {this.#logger(`${module}: ${msg}`)}.bind(this); #timer; #container; #guiFooter; #dom_menubar = new trdom_menubar(); #dom_servermanager; #dom_torrentmanagger = new trdom_torrentmanager(); constructor (container, loadcb, savecb, logger) { this.#container = container; if (loadcb != null) { this.#loadcb = loadcb; this.#savecb = savecb; } if (logger != null) { this.#logger = logger; } this.#dom_servermanager = new trdom_servermanager(this.#loadcb, this.#savecb, this.#logcb, this.#registerServer) this.#guiFooter = document.createElement('div'); this.#guiFooter.classList.add('trweb_footer'); if (document.readyState === 'complete' || document.readyState === 'interactive') { this.#logger('Document already loaded, jumpstarting'); this.#handler({'type': 'DOMContentLoaded'}); } else { this.#logger('Waiting for document to load'); document.addEventListener('DOMContentLoaded', this.#handler); } } #registerServer = function(name, initdata) { let torrentCallback = function(hash, torrentInfo) { let mergedTorrentInfo = this.#knownTorrents[hash]; if (mergedTorrentInfo == null) { mergedTorrentInfo = this.#createTorrentEntry(hash); } mergedTorrentInfo.setStatus(name, torrentInfo); mergedTorrentInfo.name = torrentInfo.name; this.#updateTorrentDisplay(mergedTorrentInfo); }.bind(this); let newserver = new trserver(initdata, function(msg) {this.#logger(`[Server: ${name}]: ${msg}`);}.bind(this), torrentCallback); this.#dom_servermanager.getServers()[name] = newserver; newserver.refreshTorrentList(); }.bind(this); #createTorrentEntry(hash) { let torrent = new trtorrent(hash); this.#knownTorrents[hash] = torrent; for (const srv of Object.keys(this.#dom_servermanager.getServers())) { this.#createServerEntryForTorrent(hash, srv); } this.#dom_torrentmanagger.getElement().appendChild(torrent.getElement()); this.#updateTorrentDisplay(torrent); return torrent; } #createServerEntryForTorrent(hash, srv) { this.#needsSort = true; let control = new trdom_torrentcontrol(hash, this.#dom_servermanager.getServers()[srv], this.#logcb, function() {return this.#knownTorrents}.bind(this)); let torrent = this.#knownTorrents[hash]; torrent.addControl(srv, control); } #updateTorrentDisplay(torrent) { let txt_name = torrent.getElement().element_name; nukeChildren(txt_name); txt_name.appendChild(document.createTextNode(torrent.name)); for (const srv of Object.keys(this.#dom_servermanager.getServers())) { let control = torrent.getControl(srv); let control_element = control.getElement(); let status = control_element.element_status; control_element.classList.remove( 'trweb_status_asdf', 'trweb_status_offline', 'trweb_status_nonexistent', 'trweb_status_paused', 'trweb_status_verifqueued', 'trweb_status_verifying', 'trweb_status_downloading', 'trweb_status_seeding' ); nukeChildren(status); let statustext = 'Nothing to see here'; let statusclass = 'trweb_status_asdf' let barwidth = 50; if (!this.#dom_servermanager.getServers()[srv].isOnline()) { statustext = "Server offline"; statusclass = 'trweb_status_offline'; barwidth = 0; } else { let server_status = torrent.getStatus(srv); if (server_status == undefined || server_status.deleted) { statustext = "Not available"; statusclass = 'trweb_status_nonexistent'; barwidth = 0; } else { statustext = `${server_status.status}`; barwidth = server_status.percentDone; switch (server_status.status) { case 0: statustext = 'Paused'; statusclass = 'trweb_status_paused'; break; case 1: statustext = 'Queued for verification'; statusclass = 'trweb_status_verifqueued'; break; case 2: statustext = 'Verifying'; statusclass = 'trweb_status_verifying'; break; case 3: statustext = 'Queued'; break; case 4: statustext = 'Downloading'; statusclass = 'trweb_status_downloading'; break; case 6: statustext = 'Seeding'; statusclass = 'trweb_status_seeding'; break; } statustext = `[${srv}]: ${statustext} - ${server_status.percentDone}%`; } } control_element.element_statusbar.style.width = `${barwidth}%`; control_element.classList.add(statusclass); status.appendChild(document.createTextNode(statustext)); } } #handler = function(e) { switch (e.type) { case 'DOMContentLoaded': this.#logger('Activating TRWEB instance'); this.#container = document.getElementById(this.#container); this.#container.classList.add('trweb_container'); this.#container.appendChild(this.#dom_menubar.getElement()); this.#container.appendChild(this.#dom_torrentmanagger.getElement()); this.#container.appendChild(this.#guiFooter); this.#dom_servermanager.loadServers(); this.#dom_servermanager.saveServers(); this.setTimer(); break; } }.bind(this); refresh() { for (const [key, value] of Object.entries(this.#dom_servermanager.getServers())) { //value.refreshSession(); value.refreshTorrentList(); } } sort() { let list = Object.values(this.#knownTorrents); list.sort((a, b) => a.name.localeCompare(b.name)); for (const torrent of list) { this.#dom_torrentmanagger.getElement().appendChild(torrent.getElement()); } return list; } #timercb = function() { if (this.#needsSort) { this.#needsSort = false; this.sort(); } this.refresh(); }.bind(this); setTimer() { this.#timer = window.setInterval(this.#timercb, 2000); } haltTimer() { window.clearInterval(this.#timer); } save() { this.#dom_servermanager.saveServers(); } rpc(server, method, args) { this.#dom_servermanager.getServers()[server].rpccall_debug(method, args); } addServer(name, url, user, pass) { this.#registerServer(name, {'rpcurl': url, 'auth': `Basic ${btoa(`${user}:${pass}`)}`}); for (const hash of Object.keys(this.#knownTorrents)) { this.#createServerEntryForTorrent(hash, name); } this.#dom_servermanager.saveServers(); } removeServer(name) { delete this.#dom_servermanager.getServers()[name]; for (const [hash, entry] of Object.entries(this.#knownTorrents)) { entry.element.removeChild(entry.element_server[name]); delete entry.servers[name]; delete entry.element_server[name] } this.#dom_servermanager.saveServers(); } } var trinstance = new trweb('trcontainer', null, null, function(msg) {console.info(`TRWEB: ${msg}`)}); //var trinstance = new trweb('trcontainer', null, null, null);