web: convert the peers tab to use an ext proxy
Instead of fetching the peer information via a rpc call simply expose it as a fetching page via ajax so we can make use of the Ext proxy and reader instead of manually loading it into the store ourselves.
This commit is contained in:
parent
0c3d2322cc
commit
280377ad6f
|
@ -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"):
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*!
|
||||
* Deluge.data.PeerRecord.js
|
||||
* Deluge.data.Peer.js
|
||||
*
|
||||
* Copyright (c) Damien Churchill 2009-2011 <damoxc@gmail.com>
|
||||
*
|
||||
|
|
|
@ -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 '';
|
||||
Ext.define('Deluge.details.PeersTab', {
|
||||
extend: 'Ext.grid.Panel',
|
||||
title: _('Peers'),
|
||||
cls: 'x-deluge-peers',
|
||||
viewConfig: {
|
||||
loadMask: false,
|
||||
},
|
||||
invalidateScrollerOnRefresh: false,
|
||||
|
||||
store: {
|
||||
model: 'Deluge.data.Peer',
|
||||
proxy: {
|
||||
type: 'ajax',
|
||||
url: 'peers/',
|
||||
reader: {
|
||||
type: 'json',
|
||||
root: 'peers'
|
||||
}
|
||||
}
|
||||
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;
|
||||
},
|
||||
|
||||
columns: [{
|
||||
text: ' ',
|
||||
dataIndex: 'country',
|
||||
width: 30,
|
||||
sortable: true,
|
||||
renderer: function(v) {
|
||||
if (!v.replace(' ', '').replace(' ', '')) {
|
||||
return '';
|
||||
}
|
||||
return Ext.String.format('<img src="flag/{0}" />', v);
|
||||
}
|
||||
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: ' ',
|
||||
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'
|
||||
}],
|
||||
|
||||
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
|
||||
});
|
||||
},
|
||||
|
||||
onRequestComplete: function(torrent, options) {
|
||||
if (!torrent) return;
|
||||
|
||||
var store = this.getStore();
|
||||
var newPeers = [];
|
||||
var addresses = {};
|
||||
|
||||
// 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);
|
||||
|
||||
// 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();
|
||||
|
||||
var sortState = store.getSortState();
|
||||
if (!sortState) return;
|
||||
store.sort(sortState.field, sortState.direction);
|
||||
}, {
|
||||
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) }
|
||||
}],
|
||||
|
||||
autoScroll: true,
|
||||
deferredRender: false,
|
||||
stripeRows: true,
|
||||
|
||||
clear: function() {
|
||||
this.getStore().removeAll();
|
||||
},
|
||||
|
||||
update: function(torrentId) {
|
||||
var store = this.getStore(),
|
||||
view = this.getView();
|
||||
|
||||
if (torrentId != this.torrentId) {
|
||||
store.removeAll();
|
||||
store.getProxy().url = 'peers/' + torrentId;
|
||||
this.torrentId = torrentId;
|
||||
}
|
||||
store.load();
|
||||
}
|
||||
});
|
||||
|
|
|
@ -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")
|
||||
|
|
Loading…
Reference in New Issue