summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--deluge/ui/web/auth.py4
-rw-r--r--deluge/ui/web/js/deluge-all/data/PeerRecord.js2
-rw-r--r--deluge/ui/web/js/deluge-all/details/PeersTab.js204
-rw-r--r--deluge/ui/web/server.py48
4 files changed, 133 insertions, 125 deletions
diff --git a/deluge/ui/web/auth.py b/deluge/ui/web/auth.py
index 5cd345e2c..0675d9d9d 100644
--- a/deluge/ui/web/auth.py
+++ b/deluge/ui/web/auth.py
@@ -136,7 +136,7 @@ class Auth(JSONComponent):
checksum = str(make_checksum(session_id))
request.addCookie('_session_id', session_id + checksum,
- path=request.base+"json", expires=expires_str)
+ path=request.base, expires=expires_str)
log.debug("Creating session for %s", login)
config = component.get("DelugeWeb").config
@@ -233,7 +233,7 @@ class Auth(JSONComponent):
_session_id = request.getCookie("_session_id")
request.addCookie('_session_id', _session_id,
- path=request.base+"json", expires=expires_str)
+ path=request.base, expires=expires_str)
if method:
if not hasattr(method, "_json_export"):
diff --git a/deluge/ui/web/js/deluge-all/data/PeerRecord.js b/deluge/ui/web/js/deluge-all/data/PeerRecord.js
index 4d2312c24..f5bf6b3de 100644
--- a/deluge/ui/web/js/deluge-all/data/PeerRecord.js
+++ b/deluge/ui/web/js/deluge-all/data/PeerRecord.js
@@ -1,5 +1,5 @@
/*!
- * Deluge.data.PeerRecord.js
+ * Deluge.data.Peer.js
*
* Copyright (c) Damien Churchill 2009-2011 <damoxc@gmail.com>
*
diff --git a/deluge/ui/web/js/deluge-all/details/PeersTab.js b/deluge/ui/web/js/deluge-all/details/PeersTab.js
index d0980dd40..4c1f24393 100644
--- a/deluge/ui/web/js/deluge-all/details/PeersTab.js
+++ b/deluge/ui/web/js/deluge-all/details/PeersTab.js
@@ -30,131 +30,93 @@
* statement from all source files in the program, then also delete it here.
*/
-(function() {
- function flagRenderer(value) {
- if (!value.replace(' ', '').replace(' ', '')){
- return '';
- }
- return String.format('<img src="flag/{0}" />', value);
- }
- function peerAddressRenderer(value, p, record) {
- var seed = (record.data['seed'] == 1024) ? 'x-deluge-seed' : 'x-deluge-peer';
- if (peer_ip.length > 2) {
- var port = peer_ip.pop();
- var ip = peer_ip.join(":");
- value = "[" + ip + "]:" + port;
- }
- return String.format('<div class="{0}">{1}</div>', seed, value);
- }
- function peerProgressRenderer(value) {
- var progress = (value * 100).toFixed(0);
- return Deluge.progressBar(progress, this.width - 8, progress + '%');
- }
-
- Ext.define('Deluge.details.PeersTab', {
- extend: 'Ext.grid.Panel',
- title: _('Peers'),
- cls: 'x-deluge-peers',
-
- store: Ext.create('Ext.data.Store', {
- model: 'Deluge.data.Peer'
- }),
-
- columns: [{
- header: '&nbsp;',
- width: 30,
- sortable: true,
- renderer: flagRenderer,
- dataIndex: 'country'
- }, {
- header: 'Address',
- width: 125,
- sortable: true,
- renderer: peerAddressRenderer,
- dataIndex: 'ip'
- }, {
- header: 'Client',
- width: 125,
- sortable: true,
- renderer: function(v) { return fplain(v) },
- dataIndex: 'client'
- }, {
- header: 'Progress',
- width: 150,
- sortable: true,
- renderer: peerProgressRenderer,
- dataIndex: 'progress'
- }, {
- header: 'Down Speed',
- width: 100,
- sortable: true,
- renderer: function(v) { return fspeed(v) },
- dataIndex: 'down_speed'
- }, {
- header: 'Up Speed',
- width: 100,
- sortable: true,
- renderer: function(v) { return fspeed(v) },
- dataIndex: 'up_speed'
- }],
+Ext.define('Deluge.details.PeersTab', {
+ extend: 'Ext.grid.Panel',
+ title: _('Peers'),
+ cls: 'x-deluge-peers',
+ viewConfig: {
+ loadMask: false,
+ },
+ invalidateScrollerOnRefresh: false,
- stripeRows: true,
- deferredRender: false,
- autoScroll: true,
-
- // fast way to figure out if we have a peer already.
- peers: {},
-
- clear: function() {
- this.getStore().removeAll();
- this.peers = {};
- },
-
- update: function(torrentId) {
- deluge.client.web.get_torrent_status(torrentId, Deluge.Keys.Peers, {
- success: this.onRequestComplete,
- scope: this
- });
- },
+ store: {
+ model: 'Deluge.data.Peer',
+ proxy: {
+ type: 'ajax',
+ url: 'peers/',
+ reader: {
+ type: 'json',
+ root: 'peers'
+ }
+ }
+ },
- onRequestComplete: function(torrent, options) {
- if (!torrent) return;
+ columns: [{
+ text: '&nbsp;',
+ dataIndex: 'country',
+ width: 30,
+ sortable: true,
+ renderer: function(v) {
+ if (!v.replace(' ', '').replace(' ', '')) {
+ return '';
+ }
+ return Ext.String.format('<img src="flag/{0}" />', v);
+ }
+ }, {
+ text: 'Address',
+ dataIndex: 'ip',
+ width: 125,
+ sortable: true,
+ renderer: function(v, p, r) {
+ var cls = (r.data['seed'] == 1024) ? 'x-deluge-seed': 'x-deluge-peer';
+ return Ext.String.format('<div class="{0}">{1}</div>', cls, v);
+ }
+ }, {
+ text: 'Client',
+ dataIndex: 'client',
+ width: 125,
+ sortable: true,
+ renderer: function(v) { return fplain(v) }
+ }, {
+ text: 'Progress',
+ dataIndex: 'progress',
+ width: 150,
+ sortable: true,
+ renderer: function(v) {
+ var progress = (v * 100).toFixed(0);
+ return Deluge.progressBar(progress, this.width - 8, progress + '%');
+ }
+ }, {
+ text: 'Down Speed',
+ dataIndex: 'down_speed',
+ width: 100,
+ sortable: true,
+ renderer: function(v) { return fspeed(v) }
+ }, {
+ text: 'Up Speed',
+ dataIndex: 'up_speed',
+ width: 100,
+ sortable: true,
+ renderer: function(v) { return fspeed(v) }
+ }],
- var store = this.getStore();
- var newPeers = [];
- var addresses = {};
+ autoScroll: true,
+ deferredRender: false,
+ stripeRows: true,
- // Go through the peers updating and creating peer records
- Ext.each(torrent.peers, function(peer) {
- if (this.peers[peer.ip]) {
- var record = store.getById(peer.ip);
- record.beginEdit();
- for (var k in peer) {
- if (record.get(k) != peer[k]) {
- record.set(k, peer[k]);
- }
- }
- record.endEdit();
- } else {
- this.peers[peer.ip] = 1;
- newPeers.push(new Deluge.data.Peer(peer, peer.ip));
- }
- addresses[peer.ip] = 1;
- }, this);
- store.add(newPeers);
+ clear: function() {
+ this.getStore().removeAll();
+ },
- // Remove any peers that shouldn't be left in the store
- store.each(function(record) {
- if (!addresses[record.id]) {
- store.remove(record);
- delete this.peers[record.id];
- }
- }, this);
- store.commitChanges();
+ update: function(torrentId) {
+ var store = this.getStore(),
+ view = this.getView();
- var sortState = store.getSortState();
- if (!sortState) return;
- store.sort(sortState.field, sortState.direction);
+ if (torrentId != this.torrentId) {
+ store.removeAll();
+ store.getProxy().url = 'peers/' + torrentId;
+ this.torrentId = torrentId;
}
- });
-})();
+ store.load();
+ }
+});
diff --git a/deluge/ui/web/server.py b/deluge/ui/web/server.py
index c9bc2a786..b775d9860 100644
--- a/deluge/ui/web/server.py
+++ b/deluge/ui/web/server.py
@@ -34,6 +34,7 @@
#
import os
+import json
import time
import shutil
import urllib
@@ -52,7 +53,7 @@ from deluge import common, component, configmanager
from deluge.core.rpcserver import check_ssl_keys
from deluge.ui import common as uicommon
from deluge.ui.tracker_icons import TrackerIcons
-from deluge.ui.web.auth import Auth
+from deluge.ui.web.auth import Auth, AuthError, AUTH_LEVEL_DEFAULT
from deluge.ui.web.common import Template, compress
from deluge.ui.web.json_api import JSON, WebApi
from deluge.ui.web.pluginmanager import PluginManager
@@ -86,6 +87,8 @@ CONFIG_DEFAULTS = {
"cert": "ssl/daemon.cert"
}
+PEERS_KEYS = ["peers"]
+
UI_CONFIG_KEYS = (
"theme", "sidebar_show_zero", "sidebar_multiple_filters",
"show_session_speed", "base", "first_login"
@@ -198,6 +201,46 @@ class Tracker(resource.Resource):
d.addCallback(self.on_got_icon, request)
return server.NOT_DONE_YET
+class TorrentResource(resource.Resource):
+ """
+ Base class for exposing parts of a torrent's information
+ as a REST-ish interface.
+ """
+
+ def getChild(self, path, request):
+ request.torrent_id = path
+ return self
+
+ def send_response(self, response, request):
+ request.setHeader("content-type", "text/plain")
+ request.write(compress(json.dumps(response), request))
+ request.finish()
+
+class Peers(TorrentResource):
+ """
+ Returns a list of the peers that a torrent currently has in JSON format.
+ """
+
+ def on_got_peers(self, torrent, request):
+ peers = torrent["peers"]
+ self.send_response({
+ "peers": peers,
+ "total": len(peers)
+ }, request)
+
+ def render(self, request):
+ try:
+ component.get("Auth").check_request(request,
+ level=AUTH_LEVEL_DEFAULT)
+ except AuthError:
+ request.setResponseCode(http.FORBIDDEN)
+ return '<h1>Forbidden</h1>'
+
+ component.get("SessionProxy"
+ ).get_torrent_status(request.torrent_id, PEERS_KEYS
+ ).addCallback(self.on_got_peers, request)
+ return server.NOT_DONE_YET
+
class Flag(resource.Resource):
def getChild(self, path, request):
request.country = path
@@ -466,6 +509,9 @@ class TopLevel(resource.Resource):
self.putChild("resources", static.File(rpath("resources")))
self.putChild("tracker", Tracker())
+ # Torrent REST resources
+ self.putChild("peers", Peers())
+
theme = component.get("DelugeWeb").config["theme"]
if not os.path.isfile(rpath("themes", "css", "xtheme-%s.css" % theme)):
theme = CONFIG_DEFAULTS.get("theme")