From 3f7540675edab7f652aa68cce2e87c24c4f5592e Mon Sep 17 00:00:00 2001 From: Jordan Lee Date: Thu, 25 Aug 2011 23:06:41 +0000 Subject: [PATCH] (trunk web) significant shrinkage of our memory + network footprint by only loading torrent's fields when they're needed. --- web/javascript/file-row.js | 6 +- web/javascript/torrent.js | 258 ++++++++-------- web/javascript/transmission.js | 423 ++++++++++++-------------- web/javascript/transmission.remote.js | 48 +-- 4 files changed, 353 insertions(+), 382 deletions(-) diff --git a/web/javascript/file-row.js b/web/javascript/file-row.js index 58f053384..4ac31da93 100644 --- a/web/javascript/file-row.js +++ b/web/javascript/file-row.js @@ -90,7 +90,7 @@ FileRow.prototype = { var i = this.getIndex(); var t = this.getTorrent(); - this.readAttributes(t._files[i]); + this.readAttributes(t.getFile(i)); this.refreshHTML(); }, @@ -98,13 +98,13 @@ FileRow.prototype = return this._done >= this._size; }, isEditable: function () { - return (this.getTorrent()._files.length>1) && !this.isDone(); + return (this.getTorrent().getFileCount()>1) && !this.isDone(); }, createRow: function(torrent, i) { var me = this; - var file = torrent._files[i]; + var file = torrent.getFile(i); var name = file.name.substring (file.name.lastIndexOf('/')+1); var root = document.createElement('li'); diff --git a/web/javascript/torrent.js b/web/javascript/torrent.js index 1d5b88ecc..53ca16823 100644 --- a/web/javascript/torrent.js +++ b/web/javascript/torrent.js @@ -45,25 +45,79 @@ Torrent._TrackerQueued = 2; Torrent._TrackerActive = 3; -// fields whose values never change and are always known -Torrent._StaticFields = [ - 'hashString', 'id' ]; - -// fields whose values never change and are known upon constructon OR -// when a magnet torrent finishes downloading its metadata -Torrent._MetaDataFields = [ - 'addedDate', 'comment', 'creator', 'dateCreated', - 'isPrivate', 'name', 'totalSize', 'pieceCount', 'pieceSize' ]; - -// torrent fields whose values change all the time -Torrent._DynamicFields = [ - 'desiredAvailable', 'downloadDir', 'downloadedEver', 'error', - 'errorString', 'eta', 'haveUnchecked', 'haveValid', 'isFinished', - 'leftUntilDone', 'metadataPercentComplete', 'peers', 'peersConnected', - 'peersGettingFromUs', 'peersSendingToUs', 'queuePosition', - 'rateDownload', 'rateUpload', 'recheckProgress', 'seedRatioLimit', - 'seedRatioMode', 'sizeWhenDone', 'status', 'trackerStats', - 'uploadedEver', 'uploadRatio', 'webseedsSendingToUs' ]; +Torrent.Fields = { }; + +// commonly used fields which only need to be loaded once, +// either on startup or when a magnet finishes downloading its metadata +// finishes downloading its metadata +Torrent.Fields.Metadata = [ + 'addedDate', + 'name', + 'totalSize' +]; + +// commonly used fields which need to be periodically refreshed +Torrent.Fields.Stats = [ + 'error', + 'errorString', + 'eta', + 'isFinished', + 'isStalled', + 'leftUntilDone', + 'metadataPercentComplete', + 'peersConnected', + 'peersGettingFromUs', + 'peersSendingToUs', + 'percentDone', + 'queuePosition', + 'rateDownload', + 'rateUpload', + 'recheckProgress', + 'seedRatioMode', + 'sizeWhenDone', + 'status', + 'trackers', + 'uploadedEver', + 'uploadRatio' +]; + +// fields used by the inspector which only need to be loaded once +Torrent.Fields.InfoExtra = [ + 'comment', + 'creator', + 'dateCreated', + 'files', + 'hashString', + 'isPrivate', + 'pieceCount', + 'pieceSize' +]; + +// fields used in the inspector which need to be periodically refreshed +Torrent.Fields.StatsExtra = [ + 'activityDate', + 'desiredAvailable', + 'downloadDir', + 'downloadLimit', + 'downloadLimited', + 'downloadedEver', + 'fileStats', + 'haveUnchecked', + 'haveValid', + 'honorsSessionLimits', + 'manualAnnounceTime', + 'peer-limit', + 'peers', + 'seedIdleLimit', + 'seedIdleMode', + 'seedRatioLimit', + 'startDate', + 'torrentFile', + 'trackerStats', + 'uploadLimited', + 'uploadLimit', + 'webseedsSendingToUs' +]; /*** **** @@ -76,129 +130,76 @@ Torrent.prototype = initialize: function(data) { this.fields = {}; - this._files = []; - - // these fields are set in the ctor and never change - for (var i=0, key; key=Torrent._StaticFields[i]; ++i) { - if (key in data) { - this.fields[key] = data[key]; - } - } - - this.initMetaData(data); - this._trackerStats = this.buildTrackerStats(data.trackerStats); - this.refresh(data); + this.refresh (data); }, - buildTrackerStats: function(trackerStats) { - var announce = []; - var result = []; - for (var i=0, tracker; tracker=trackerStats[i]; ++i) { - var tier = result[tracker.tier] || []; - tier.push(tracker); - result[tracker.tier] = tier; - announce.push(tracker.announce); - } - this.fields.collatedTrackers = announce.join('\t'); - return result; + setField: function(o, name, value) + { + var changed = !(name in o) || (o[name] !== value); + if (changed) + o[name] = value; + return changed; }, - initMetaData: function(data) { - - var f = this.fields; + // fields.files is an array of unions of RPC's "files" and "fileStats" objects. + updateFiles: function(files) { var changed = false; - - // populate the metadata fields - for (var i=0, key; key=Torrent._MetaDataFields[i]; ++i) { - if (key in data) { - if (f[key] !== data[key]) { - f[key] = data[key]; - if (key === 'name') - f.collatedName = data.name.toLowerCase(); - changed = true; - } - } - } - - // populate the files array - if (data.files) { - for (var i=0, row; row=data.files[i]; ++i) { - this._files[i] = { - 'index': i, - 'length': row.length, - 'name': row.name - }; - } + var myfiles = this.fields.files || []; + var keys = [ 'length', 'name', 'bytesCompleted', 'wanted', 'priority' ]; + for (var i=0, f; f=files[i]; ++i) { + var myfile = myfiles[i] || {}; + for (var j=0, key; key=keys[j]; ++j) + if(key in f) + changed |= this.setField(myfile,key,f[key]); + myfiles[i] = myfile; } - + this.fields.files = myfiles; return changed; }, - refreshMetaData: function(data) - { - var changed = this.initMetaData(data); - if (changed) - this.fireDataChanged(); - return changed; + collateTrackers: function(trackers) { + announces = []; + for (var i=0, t; t=trackers[i]; ++i) + announces.push(t.announce.toLowerCase()); + return announces.join('\t'); }, - refresh: function(data) + isField: function(name) { + return ( name === 'id' ) + || ( Torrent.Fields.Stats.indexOf(name) !== -1 ) + || ( Torrent.Fields.StatsExtra.indexOf(name) !== -1 ) + || ( Torrent.Fields.InfoExtra.indexOf(name) !== -1 ) + || ( Torrent.Fields.Metadata.indexOf(name) !== -1 ); + }, + + refreshFields: function(data) { var changed = false; - // FIXME: unnecessary coupling... this should be handled by transmission.js - if (this.needsMetaData() && (data.metadataPercentComplete >= 1)) - changed |= transmission.refreshMetaData([ this.getId() ]); - - var f = this.fields; - - // refresh the dynamic fields - for (var i=0, key; key=Torrent._DynamicFields[i]; ++i) { - if (key in data) { - if (f[key] !== data[key]) { - f[key] = data[key]; - changed = true; - } + for (var key in data) { + if (this.isField(key)) switch (key) { + case 'files': + case 'fileStats': // merge files and fileStats together + changed |= this.updateFiles(data[key]); + break; + case 'trackerStats': // 'trackerStats' is a superset of 'trackers'... + changed |= this.setField(this.fields,'trackers',data[key]); + case 'trackers': // ...so only save 'trackers' if we don't have it already + if (!(key in this.fields)) + changed |= this.setField(this.fields,key,data[key]); + break; + default: + changed |= this.setField(this.fields,key,data[key]); } } - this._trackerStats = this.buildTrackerStats(data.trackerStats); - - if (data.fileStats) - changed |= this.refreshFiles(data); - - if (changed) - this.fireDataChanged(); - }, - - refreshFiles: function(data) { - var changed = false; - for (var i=0; i 0) { var command = wanted ? 'files-wanted' : 'files-unwanted'; @@ -1144,7 +1141,7 @@ Transmission.prototype = var torrents = this.getSelectedTorrents(); if (!torrents.length && iPhone) { - this.hideInspector(); + this.setInspectorVisible(false); return; } @@ -1302,137 +1299,149 @@ Transmission.prototype = } this.changeFileCommand(command, [ row ]); }, - clearFileList: function() { + clearFileList: function() + { $(this._inspector_file_list).empty(); - delete this._files_torrent; - delete this._files; + delete this._file_torrent; + delete this._file_rows; }, - updateFileList: function() { - - // if the file list is hidden, clear the list - if (this._inspector_tab_files.className.indexOf('selected') == -1) { - this.clearFileList(); + updateFileList: function() + { + if (!$(this._inspector_file_list).is(':visible')) return; - } - // if not torrent is selected, clear the list - var selected_torrents = this.getSelectedTorrents(); - if (selected_torrents.length != 1) { + var sel = this.getSelectedTorrents(); + if (sel.length !== 1) { this.clearFileList(); return; } - // if the active torrent hasn't changed, noop - var torrent = selected_torrents[0]; - if (this._files_torrent === torrent) - return; + var torrent = sel[0]; + if (torrent === this._files_torrent) + if(torrent.getFileCount() === (this._files ? this._files.length: 0)) + return; // build the file list this.clearFileList(); - this._files_torrent = torrent; - var n = torrent._files.length; - this._files = new Array(n); + this._file_torrent = torrent; + var n = torrent.getFileCount(); + this._file_rows = []; var fragment = document.createDocumentFragment(); var tr = this; for (var i=0; i'); - if (torrents.length > 1) { - html.push('
', torrent.getName(), '
'); - } - if (peers.length == 0) { - html.push('
'); // firefox won't paint the top border if the div is empty - continue; - } - html.push('', - '', - '', - '', - '', - '', - '', - '', - '', - ''); - for (var i=0, peer; peer=peers[i]; ++i) { - var parity = ((i+1) % 2 == 0 ? 'even' : 'odd'); - html.push('', - '', - '', - '', - '', - '', - '', - '', - ''); - } - html.push('
UpDown%StatusAddressClient
', (peer.isEncrypted ? 'Encrypted' : ''), '', (peer.rateToPeer ? fmt.speedBps(peer.rateToPeer) : ''), '', (peer.rateToClient ? fmt.speedBps(peer.rateToClient) : ''), '', Math.floor(peer.progress*100), '%', '', fmt.peerStatus(peer.flagStr), '', peer.address, '', peer.clientName, '
'); + + for (var k=0, torrent; torrent=torrents[k]; ++k) { + var peers = torrent.getPeers(); + html.push('
'); + if (torrents.length > 1) { + html.push('
', torrent.getName(), '
'); + } + if (!peers || !peers.length) { + html.push('
'); // firefox won't paint the top border if the div is empty + continue; } + html.push('', + '', + '', + '', + '', + '', + '', + '', + '', + ''); + for (var i=0, peer; peer=peers[i]; ++i) { + var parity = ((i+1) % 2 == 0 ? 'even' : 'odd'); + html.push('', + '', + '', + '', + '', + '', + '', + '', + ''); + } + html.push('
UpDown%StatusAddressClient
', (peer.isEncrypted ? 'Encrypted' : ''), '', (peer.rateToPeer ? fmt.speedBps(peer.rateToPeer) : ''), '', (peer.rateToClient ? fmt.speedBps(peer.rateToClient) : ''), '', Math.floor(peer.progress*100), '%', '', fmt.peerStatus(peer.flagStr), '', peer.address, '', peer.clientName, '
'); } + setInnerHTML(this._inspector_peers_list, html.join('')); }, updateTrackersLists: function() { - // By building up the HTML as as string, then have the browser - // turn this into a DOM tree, this is a fast operation. + if (!$(this._inspector_trackers_list).is(':visible')) + return; + var tr = this; var html = [ ]; var na = 'N/A'; var torrents = this.getSelectedTorrents(); - if ($(this._inspector_trackers_list).is(':visible')) { - for (var k=0, torrent; torrent = torrents[k]; ++k) { - html.push ('
'); - if (torrents.length > 1) { - html.push('
', torrent.getName(), '
'); - } - for (var i=0, tier; tier=torrent._trackerStats[i]; ++i) { + + // By building up the HTML as as string, then have the browser + // turn this into a DOM tree, this is a fast operation. + for (var i=0, torrent; torrent=torrents[i]; ++i) + { + html.push ('
'); + + if (torrents.length > 1) + html.push('
', torrent.getName(), '
'); + + var tier = -1; + var trackers = torrent.getTrackers(); + for (var j=0, tracker; tracker=trackers[j]; ++j) + { + if (tier != tracker.tier) + { + if (tier !== -1) // close previous tier + html.push('
'); + + tier = tracker.tier; + html.push('
', - 'Tier ', (i + 1), '
', - '
    '); - for (var j=0, tracker; tracker=tier[j]; ++j) { - var lastAnnounceStatusHash = tr.lastAnnounceStatus(tracker); - var announceState = tr.announceState(tracker); - var lastScrapeStatusHash = tr.lastScrapeStatus(tracker); - - // Display construction - var parity = ((j+1) % 2 == 0 ? 'even' : 'odd'); - html.push('
  • ', - tracker.host, '
    ', - '
    ', - '
    ', lastAnnounceStatusHash['label'], ': ', lastAnnounceStatusHash['value'], '
    ', - '
    ', announceState, '
    ', - '
    ', lastScrapeStatusHash['label'], ': ', lastScrapeStatusHash['value'], '
    ', - '
    ', - '', - '', - '', - '
    Seeders:', (tracker.seederCount > -1 ? tracker.seederCount : na), '
    Leechers:', (tracker.leecherCount > -1 ? tracker.leecherCount : na), '
    Downloads:', (tracker.downloadCount > -1 ? tracker.downloadCount : na), '
  • '); - } - html.push('
'); + 'Tier ', tier, '
', + '
    '); } - html.push(''); + + var lastAnnounceStatusHash = tr.lastAnnounceStatus(tracker); + var announceState = tr.announceState(tracker); + var lastScrapeStatusHash = tr.lastScrapeStatus(tracker); + + // Display construction + var parity = ((j+1) % 2 == 0 ? 'even' : 'odd'); + html.push('
  • ', + tracker.host, '
    ', + '
    ', + '
    ', lastAnnounceStatusHash['label'], ': ', lastAnnounceStatusHash['value'], '
    ', + '
    ', announceState, '
    ', + '
    ', lastScrapeStatusHash['label'], ': ', lastScrapeStatusHash['value'], '
    ', + '
    ', + '', + '', + '', + '
    Seeders:', (tracker.seederCount > -1 ? tracker.seederCount : na), '
    Leechers:', (tracker.leecherCount > -1 ? tracker.leecherCount : na), '
    Downloads:', (tracker.downloadCount > -1 ? tracker.downloadCount : na), '
  • '); } + if (tier !== -1) // close last tier + html.push('
'); + + html.push(''); // inspector_group } + setInnerHTML(this._inspector_trackers_list, html.join('')); }, @@ -1493,128 +1502,95 @@ Transmission.prototype = return {'label':lastScrapeLabel, 'value':lastScrape}; }, - /* - * Toggle the visibility of the inspector (used by the context menu) - */ - toggleInspector: function() { - if (this[Prefs._ShowInspector]) - this.hideInspector(); - else - this.showInspector(); + toggleInspector: function() + { + this.setInspectorVisible(!this[Prefs._ShowInspector]); }, - - showInspector: function() { - $('#torrent_inspector').show(); - if (iPhone) { - $('body').addClass('inspector_showing'); - $('#inspector_close').show(); - this.hideiPhoneAddressbar(); - } else { - var w = $('#torrent_inspector').width() + 1 + 'px'; - $('#torrent_container')[0].style.right = w; + setInspectorVisible: function(visible) + { + // we collect extra stats on torrents when they're in the inspector... + clearInterval(this._periodic_inspector_refresh); + delete this._periodic_inspector_refresh; + if (visible) { + var tr = this; + this._periodic_inspector_refresh = setInterval(function() {tr.refreshInspectorTorrents(false);},2000); + this.refreshInspectorTorrents(true); } - setInnerHTML($('ul li#context_toggle_inspector')[0], 'Hide Inspector'); - - this.setPref(Prefs._ShowInspector, true); - this.updateInspector(); - }, - - /* - * Hide the inspector - */ - hideInspector: function() { - - $('#torrent_inspector').hide(); - + // update the ui widgetry + $('#torrent_inspector').toggle(visible); if (iPhone) { - this.deselectAll(); - $('body.inspector_showing').removeClass('inspector_showing'); - $('#inspector_close').hide(); + $('body').toggleClass('inspector_showing',visible); + $('#inspector_close').toggle(visible); this.hideiPhoneAddressbar(); } else { - $('#torrent_container')[0].style.right = '0px'; - setInnerHTML($('ul li#context_toggle_inspector')[0], 'Show Inspector'); + var w = visible ? $('#torrent_inspector').width() + 1 + 'px' : '0px'; + $('#torrent_container')[0].style.right = w; } - this.setPref(Prefs._ShowInspector, false); - }, - - refreshMetaData: function(ids) { - var tr = this; - this.remote.getMetaDataFor(ids, function(active) { tr.updateMetaData(active); }); + setInnerHTML($('ul li#context_toggle_inspector')[0], (visible?'Hide':'Show')+' Inspector'); + this.setPref(Prefs._ShowInspector, visible); + if (visible) + this.updateInspector(); }, - updateMetaData: function(torrents) + onTorrentChanged: function(ev) { - var tr = this; - var refresh_files_for = [ ]; - var selected_torrents = this.getSelectedTorrents(); - jQuery.each(torrents, function() { - var t = tr._torrents[ this.id ]; - if (t) { - t.refreshMetaData(this); - if (selected_torrents.indexOf(t) != -1) - refresh_files_for.push(t.getId()); - } - }); - if (refresh_files_for.length > 0) - tr.remote.loadTorrentFiles(refresh_files_for); + this.refilterSoon(); + + // if this torrent is in the inspector, refresh the inspector + if (this[Prefs._ShowInspector]) + if (this.getSelectedTorrentIds().indexOf(ev.target.getId()) !== -1) + this.updateInspector(); }, - refreshTorrents: function(ids) { - var tr = this; - if (!ids) - ids = 'recently-active'; - - this.remote.getUpdatedDataFor(ids, function(active, removed) { tr.updateTorrentsData(active, removed); }); - }, + updateFromTorrentGet: function(updates, removed_ids) + { + var new_ids = []; - updateTorrentsData: function(updated, removed_ids) { - var tr = this; - var new_torrent_ids = []; - var refresh_files_for = []; - var selected_torrents = this.getSelectedTorrents(); - - for (var i=0, o; o=updated[i]; ++i) { - var t = tr._torrents[o.id]; - if (t == null) - new_torrent_ids.push(o.id); - else { + for (var i=0, o; o=updates[i]; ++i) { + var t; + var id = o.id; + if ((t = this._torrents[id])) t.refresh(o); - if (selected_torrents.indexOf(t) != -1) - refresh_files_for.push(t.getId()); + else { + t = this._torrents[id] = new Torrent(o); + $(t).bind('dataChanged',function(ev) {tr.onTorrentChanged(ev);}); + new_ids.push(id); } } - if (refresh_files_for.length > 0) - tr.remote.loadTorrentFiles(refresh_files_for); - - if (new_torrent_ids.length > 0) - tr.remote.getInitialDataFor(new_torrent_ids, function(torrents) {tr.addTorrents(torrents);}); - - tr.deleteTorrents(removed_ids); - - if (new_torrent_ids.length != 0) { - tr.hideiPhoneAddressbar(); - tr.deselectAll(true); + if (new_ids.length) { + var tr = this; + this.remote.getTorrentInitial(new_ids, function(a,b){tr.updateFromTorrentGet(a,b);}); + this.refilterSoon(); } - }, - updateTorrentsFileData: function(torrents) { - for (var i=0, o; o=torrents[i]; ++i) { - var t = this._torrents[o.id]; - if (t) { - t.refreshFiles(o); - if (t === this._files_torrent) - this.refreshFileView(); - } + if (removed_ids) { + this.deleteTorrents(removed_ids); + this.refilterSoon(); } }, + refreshTorrents: function(ids) { + if (!ids) + ids = 'recently-active'; + var tr = this; + this.remote.getTorrentStats(ids, function(a,b){tr.updateFromTorrentGet(a,b);}); + }, initializeAllTorrents: function() { var tr = this; - this.remote.getInitialDataFor(null ,function(torrents) { tr.addTorrents(torrents); }); + this.remote.getTorrentInitial(null, function(a,b){tr.updateFromTorrentGet(a,b);}); + }, + refreshMetadata: function(ids) { + var tr = this; + this.remote.getTorrentMetadata(ids, function(a,b){tr.updateFromTorrentGet(a,b);}); + }, + refreshInspectorTorrents: function(full) { + var tr = this; + var ids = tr.getSelectedTorrentIds(); + if (ids.length > 0) + this.remote.getTorrentDetails(ids, full, function(a,b){tr.updateFromTorrentGet(a,b);}); }, onRowClicked: function(ev, row) @@ -1634,7 +1610,7 @@ Transmission.prototype = // Shift-Click - selects a range from the last-clicked row to this one if (iPhone) { if (row.isSelected()) - this.showInspector(); + this.setInspectorVisible(true); this.setSelectedRow(row); } else if (ev.shiftKey) { @@ -1662,20 +1638,6 @@ Transmission.prototype = this._last_torrent_clicked = row.getTorrent().getId(); }, - addTorrents: function(new_torrents) - { - var tr = this; - var key = 'dataChanged'; - - for (var i=0, row; row=new_torrents[i]; ++i) { - var t = new Torrent(row); - $(t).bind(key,function() {tr.refilterSoon();}); - this._torrents[t.getId()] = t; - } - - this.refilterSoon(); - }, - deleteTorrents: function(torrent_ids) { if (torrent_ids && torrent_ids.length) @@ -2197,27 +2159,26 @@ Transmission.prototype = getTrackers: function() { - var trackers = {}; + var ret = {}; var torrents = this.getAllTorrents(); for (var i=0, torrent; torrent=torrents[i]; ++i) { var names = []; - for (var j=0, tier; tier=torrent._trackerStats[j]; ++j) { - for (var k=0, tracker; tracker=tier[k]; ++k) { - var uri = parseUri(tracker.announce); - var domain = this.getDomainName(uri.host); - var name = this.getReadableDomain(domain); - if (!(name in trackers)) - trackers[name] = { 'uri': uri, 'domain': domain, 'count': 0 }; - if (names.indexOf(name) === -1) - names.push(name); - } + var trackers = torrent.getTrackers(); + for (var j=0, tracker; tracker=trackers[j]; ++j) { + var uri = parseUri(tracker.announce); + var domain = this.getDomainName(uri.host); + var name = this.getReadableDomain(domain); + if (!(name in ret)) + ret[name] = { 'uri': uri, 'domain': domain, 'count': 0 }; + if (names.indexOf(name) === -1) + names.push(name); } for (var j=0, name; name=names[j]; ++j) - trackers[name].count++; + ret[name].count++; } - return trackers; + return ret; }, /*** diff --git a/web/javascript/transmission.remote.js b/web/javascript/transmission.remote.js index 8558b922d..325e176b5 100644 --- a/web/javascript/transmission.remote.js +++ b/web/javascript/transmission.remote.js @@ -30,20 +30,20 @@ RPC._TurtleTimeEnd = 'alt-speed-time-end'; RPC._TurtleTimeDay = 'alt-speed-time-day'; RPC._PeerLimitGlobal = 'peer-limit-global'; RPC._PeerLimitPerTorrent = 'peer-limit-per-torrent'; -RPC._PexEnabled = 'pex-enabled'; +RPC._PexEnabled = 'pex-enabled'; RPC._DhtEnabled = 'dht-enabled'; RPC._LpdEnabled = 'lpd-enabled'; RPC._BlocklistEnabled = 'blocklist-enabled'; RPC._BlocklistURL = 'blocklist-url'; RPC._BlocklistSize = 'blocklist-size'; -RPC._UtpEnabled = 'utp-enabled'; +RPC._UtpEnabled = 'utp-enabled'; RPC._PeerPortRandom = 'peer-port-random-on-start'; RPC._PortForwardingEnabled = 'port-forwarding-enabled'; RPC._StartAddedTorrent = 'start-added-torrents'; -RPC._QueueMoveTop = 'queue-move-top'; -RPC._QueueMoveBottom = 'queue-move-bottom'; -RPC._QueueMoveUp = 'queue-move-up'; -RPC._QueueMoveDown = 'queue-move-down'; +RPC._QueueMoveTop = 'queue-move-top'; +RPC._QueueMoveBottom = 'queue-move-bottom'; +RPC._QueueMoveUp = 'queue-move-up'; +RPC._QueueMoveDown = 'queue-move-down'; function TransmissionRemote(controller) { @@ -133,28 +133,25 @@ TransmissionRemote.prototype = this.sendRequest(o, callback, async); }, - getInitialDataFor: function(torrent_ids, callback) { + getTorrentInitial: function(torrent_ids, callback) { var o = { method: 'torrent-get', arguments: { - fields: Torrent._StaticFields.concat(Torrent._MetaDataFields, - Torrent._DynamicFields, - [ 'files', 'fileStats' ]) + fields: ['id'].concat(Torrent.Fields.Metadata, Torrent.Fields.Stats) } }; if (torrent_ids) o.arguments.ids = torrent_ids; - this.sendRequest(o, function(data){ callback(data.arguments.torrents);}); + this.sendRequest(o, function(data){ callback(data.arguments.torrents, data.arguments.removed);}); }, - getMetaDataFor: function(torrent_ids, callback) { + getTorrentMetadata: function(torrent_ids, callback) { var o = { method: 'torrent-get', arguments: { - fields: Torrent._StaticFields.concat(Torrent._MetaDataFields, - ['files', 'fileStats']) + fields: ['id'].concat(Torrent.Fields.Metadata) } }; @@ -164,26 +161,31 @@ TransmissionRemote.prototype = this.sendRequest(o, function(data) {callback(data.arguments.torrents)}); }, - getUpdatedDataFor: function(torrent_ids, callback) { + getTorrentStats: function(torrent_ids, callback) { var o = { method: 'torrent-get', arguments: { 'ids': torrent_ids, - fields: [ 'id' ].concat(Torrent._DynamicFields) + fields: ['id'].concat(Torrent.Fields.Stats) } }; this.sendRequest(o, function(data) {callback(data.arguments.torrents, data.arguments.removed);}); }, - loadTorrentFiles: function(torrent_ids) { - var tr = this._controller; - this.sendRequest({ + /* called for the torrents in the inspector aka details dialog */ + getTorrentDetails: function(torrent_ids, full, callback) { + var f = ['id'].concat(Torrent.Fields.StatsExtra); + if (full) // these only need to be loaded once... + f = f.concat(Torrent.Fields.InfoExtra); + var o = { method: 'torrent-get', - arguments: { fields: [ 'id', 'fileStats'], ids: torrent_ids } - }, function(data) { - tr.updateTorrentsFileData(data.arguments.torrents); - }); + arguments: { + 'ids': torrent_ids, + fields: f, + } + }; + this.sendRequest(o, function(data) {callback(data.arguments.torrents,null)}); }, changeFileCommand: function(command, rows) { -- 2.40.0