mirror of
https://github.com/codex-storage/deluge.git
synced 2025-02-18 06:16:29 +00:00
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))
|
checksum = str(make_checksum(session_id))
|
||||||
|
|
||||||
request.addCookie('_session_id', session_id + checksum,
|
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)
|
log.debug("Creating session for %s", login)
|
||||||
config = component.get("DelugeWeb").config
|
config = component.get("DelugeWeb").config
|
||||||
@ -233,7 +233,7 @@ class Auth(JSONComponent):
|
|||||||
|
|
||||||
_session_id = request.getCookie("_session_id")
|
_session_id = request.getCookie("_session_id")
|
||||||
request.addCookie('_session_id', _session_id,
|
request.addCookie('_session_id', _session_id,
|
||||||
path=request.base+"json", expires=expires_str)
|
path=request.base, expires=expires_str)
|
||||||
|
|
||||||
if method:
|
if method:
|
||||||
if not hasattr(method, "_json_export"):
|
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>
|
* 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.
|
* statement from all source files in the program, then also delete it here.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(function() {
|
Ext.define('Deluge.details.PeersTab', {
|
||||||
function flagRenderer(value) {
|
extend: 'Ext.grid.Panel',
|
||||||
if (!value.replace(' ', '').replace(' ', '')){
|
title: _('Peers'),
|
||||||
return '';
|
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) {
|
columns: [{
|
||||||
var seed = (record.data['seed'] == 1024) ? 'x-deluge-seed' : 'x-deluge-peer';
|
text: ' ',
|
||||||
if (peer_ip.length > 2) {
|
dataIndex: 'country',
|
||||||
var port = peer_ip.pop();
|
width: 30,
|
||||||
var ip = peer_ip.join(":");
|
sortable: true,
|
||||||
value = "[" + ip + "]:" + port;
|
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);
|
}, {
|
||||||
}
|
text: 'Address',
|
||||||
function peerProgressRenderer(value) {
|
dataIndex: 'ip',
|
||||||
var progress = (value * 100).toFixed(0);
|
width: 125,
|
||||||
return Deluge.progressBar(progress, this.width - 8, progress + '%');
|
sortable: true,
|
||||||
}
|
renderer: function(v, p, r) {
|
||||||
|
var cls = (r.data['seed'] == 1024) ? 'x-deluge-seed': 'x-deluge-peer';
|
||||||
Ext.define('Deluge.details.PeersTab', {
|
return Ext.String.format('<div class="{0}">{1}</div>', cls, v);
|
||||||
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: '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 os
|
||||||
|
import json
|
||||||
import time
|
import time
|
||||||
import shutil
|
import shutil
|
||||||
import urllib
|
import urllib
|
||||||
@ -52,7 +53,7 @@ from deluge import common, component, configmanager
|
|||||||
from deluge.core.rpcserver import check_ssl_keys
|
from deluge.core.rpcserver import check_ssl_keys
|
||||||
from deluge.ui import common as uicommon
|
from deluge.ui import common as uicommon
|
||||||
from deluge.ui.tracker_icons import TrackerIcons
|
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.common import Template, compress
|
||||||
from deluge.ui.web.json_api import JSON, WebApi
|
from deluge.ui.web.json_api import JSON, WebApi
|
||||||
from deluge.ui.web.pluginmanager import PluginManager
|
from deluge.ui.web.pluginmanager import PluginManager
|
||||||
@ -86,6 +87,8 @@ CONFIG_DEFAULTS = {
|
|||||||
"cert": "ssl/daemon.cert"
|
"cert": "ssl/daemon.cert"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PEERS_KEYS = ["peers"]
|
||||||
|
|
||||||
UI_CONFIG_KEYS = (
|
UI_CONFIG_KEYS = (
|
||||||
"theme", "sidebar_show_zero", "sidebar_multiple_filters",
|
"theme", "sidebar_show_zero", "sidebar_multiple_filters",
|
||||||
"show_session_speed", "base", "first_login"
|
"show_session_speed", "base", "first_login"
|
||||||
@ -198,6 +201,46 @@ class Tracker(resource.Resource):
|
|||||||
d.addCallback(self.on_got_icon, request)
|
d.addCallback(self.on_got_icon, request)
|
||||||
return server.NOT_DONE_YET
|
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):
|
class Flag(resource.Resource):
|
||||||
def getChild(self, path, request):
|
def getChild(self, path, request):
|
||||||
request.country = path
|
request.country = path
|
||||||
@ -466,6 +509,9 @@ class TopLevel(resource.Resource):
|
|||||||
self.putChild("resources", static.File(rpath("resources")))
|
self.putChild("resources", static.File(rpath("resources")))
|
||||||
self.putChild("tracker", Tracker())
|
self.putChild("tracker", Tracker())
|
||||||
|
|
||||||
|
# Torrent REST resources
|
||||||
|
self.putChild("peers", Peers())
|
||||||
|
|
||||||
theme = component.get("DelugeWeb").config["theme"]
|
theme = component.get("DelugeWeb").config["theme"]
|
||||||
if not os.path.isfile(rpath("themes", "css", "xtheme-%s.css" % theme)):
|
if not os.path.isfile(rpath("themes", "css", "xtheme-%s.css" % theme)):
|
||||||
theme = CONFIG_DEFAULTS.get("theme")
|
theme = CONFIG_DEFAULTS.get("theme")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user