refactor+enhance json api
This commit is contained in:
parent
9b12c231da
commit
6a216c0122
|
@ -53,6 +53,25 @@ from utils import dict_cb
|
|||
from lib import json
|
||||
|
||||
|
||||
def json_response(result, id):
|
||||
print json.write({
|
||||
"version":"1.1",
|
||||
"result":result,
|
||||
"id":id
|
||||
})
|
||||
|
||||
def json_error(message , id , msg_number=123):
|
||||
log.error("JSON-error:%s" % message)
|
||||
print json.write({
|
||||
"version":"1.1",
|
||||
"id":id,
|
||||
"error":{
|
||||
"number":msg_number,
|
||||
"message":message,
|
||||
"error":message
|
||||
}
|
||||
})
|
||||
|
||||
class json_rpc:
|
||||
"""
|
||||
== Full client api ==
|
||||
|
@ -60,6 +79,10 @@ class json_rpc:
|
|||
* rpc-api : http://en.wikipedia.org/wiki/JSON-RPC#Version_1.0
|
||||
* methods : http://dev.deluge-torrent.org/wiki/Development/UiClient#Remoteapi
|
||||
"""
|
||||
#extra exposed methods
|
||||
json_exposed = ["update_ui","get_stats","system_listMethods"]
|
||||
|
||||
|
||||
def GET(self):
|
||||
print '{"error":"only POST is supported"}'
|
||||
|
||||
|
@ -67,38 +90,30 @@ class json_rpc:
|
|||
def POST(self , name=None):
|
||||
web.header("Content-Type", "application/x-json")
|
||||
ck = cookies()
|
||||
if not(ck.has_key("session_id") and ck["session_id"] in utils.SESSIONS):
|
||||
print """{"error":{
|
||||
"number":1,
|
||||
"message":"not authenticated",
|
||||
"error":"not authenticated"
|
||||
}
|
||||
}
|
||||
"""
|
||||
return
|
||||
id = 0
|
||||
if not(ck.has_key("session_id") and ck["session_id"] in utils.SESSIONS):
|
||||
return json_error("not authenticated", id)
|
||||
|
||||
try:
|
||||
log.debug("json-data:")
|
||||
log.debug(webapi.data())
|
||||
json_data = json.read(webapi.data())
|
||||
id = json_data["id"]
|
||||
method = json_data["method"]
|
||||
method = json_data["method"].replace(".", "_")
|
||||
params = json_data["params"]
|
||||
|
||||
if method.startswith('_'):
|
||||
raise Exception('_ methods are illegal.')
|
||||
|
||||
if method.startswith("system."):
|
||||
result = self.exec_system_method(method, params,id)
|
||||
elif method == ("list_torrents"):
|
||||
result = self.list_torrents(method, params,id)
|
||||
elif method == ("get_stats"):
|
||||
result = self.exec_get_stats(method, params,id)
|
||||
elif method in self.json_exposed:
|
||||
func = getattr(self, method)
|
||||
result = func(*params)
|
||||
else:
|
||||
result = self.exec_client_method(method, params,id)
|
||||
result = self.exec_client_method(method, params)
|
||||
|
||||
log.debug("JSON-result:%s(%s)[%s] = %s" % (method, params, id, result))
|
||||
print json.write(result)
|
||||
#log.debug("JSON-result:%s(%s)[%s] = %s" % (method, params, id, result))
|
||||
|
||||
return json_response(result, id)
|
||||
|
||||
except Exception,e:
|
||||
#verbose because you don't want exeptions in the error-handler.
|
||||
|
@ -106,42 +121,24 @@ class json_rpc:
|
|||
if hasattr(e,"message"):
|
||||
message = e.message
|
||||
log.debug(format_exc())
|
||||
log.error("JSON-error:%s:%s %s" % (e, message, id))
|
||||
print json.write({
|
||||
"version":"1.1",
|
||||
"id":id,
|
||||
"error":{
|
||||
"number":123,
|
||||
"message":"%s:%s %s" % (e, message, id),
|
||||
"error":format_exc()
|
||||
}
|
||||
})
|
||||
return json_error("%s:%s" % (e, message), id)
|
||||
|
||||
def exec_client_method(self, method, params, id):
|
||||
def exec_client_method(self, method, params):
|
||||
if not hasattr(sclient,method):
|
||||
raise Exception('Unknown method:%s', method)
|
||||
|
||||
#Call:
|
||||
func = getattr(sclient, method)
|
||||
result = func(*params)
|
||||
return func(*params)
|
||||
|
||||
return {
|
||||
"version":"1.1",
|
||||
"result":result,
|
||||
"id":id
|
||||
}
|
||||
#
|
||||
#Extra exposed methods:
|
||||
#
|
||||
def system_listMethods(self):
|
||||
"system.list_methods() see json/xmlrpc docs"
|
||||
return sclient.list_methods() + self.json_exposed
|
||||
|
||||
def exec_system_method(self, method, params, id):
|
||||
if method == "system.listMethods":
|
||||
methods = sclient.list_methods()
|
||||
return {
|
||||
"version":"1.1",
|
||||
"result":methods + ["get_stats"],
|
||||
"id":id
|
||||
}
|
||||
raise Exception('Unknown method:%s', method)
|
||||
|
||||
def exec_get_stats(self, method, params, id):
|
||||
def get_stats(self):
|
||||
stats = {}
|
||||
|
||||
aclient.get_download_rate(dict_cb('download_rate',stats))
|
||||
|
@ -157,81 +154,45 @@ class json_rpc:
|
|||
|
||||
aclient.force_call(block=True)
|
||||
|
||||
return {
|
||||
"version":"1.1",
|
||||
"result":stats,
|
||||
"id":id
|
||||
}
|
||||
return stats
|
||||
|
||||
|
||||
|
||||
def list_torrents(self,params,id):
|
||||
def update_ui(self, keys ,filter_dict , cache_id = None ):
|
||||
"""
|
||||
== torrent_list ==
|
||||
Composite call.
|
||||
Goal : limit the number of ajax calls
|
||||
|
||||
filter is only effective if the organize plugin is enabled.
|
||||
label is redirected to the tracker column, there will be a label feature in the future.
|
||||
filter is only effective if the label plugin is enabled.
|
||||
cache_id = future feature, not effective yet.
|
||||
|
||||
=== input ===
|
||||
{{{
|
||||
{
|
||||
keys: [<like get_torrent_status>],
|
||||
filter: {
|
||||
/*ommitted keys are ignored*/
|
||||
"keyword":string
|
||||
"label":string,
|
||||
"state":string
|
||||
} ,
|
||||
cache_id: int
|
||||
keys: see get_torrent_status
|
||||
filter_dict: see label_get_filtered_ids
|
||||
cache_id: # todo
|
||||
}
|
||||
}}}
|
||||
|
||||
=== output ===
|
||||
{{{
|
||||
{
|
||||
torrents:
|
||||
[ {"id":string,"name":string, ..}, ..]
|
||||
states:
|
||||
[('string',int), ..]
|
||||
trackers:
|
||||
[('string',int), ..]
|
||||
stats:
|
||||
[upload_rate, download_rate, nu_connections, num_dht_nodes]
|
||||
}
|
||||
cache_id:int
|
||||
"torrents": see get_torrent_status
|
||||
"filters": see label_get_filters
|
||||
"stats": see get_stats
|
||||
"cache_id":int # todo
|
||||
}
|
||||
}}}
|
||||
"""
|
||||
"""filter = params["filter"]
|
||||
keys = params["keys"]
|
||||
cache_id = params["cache_id"]
|
||||
organize_filters = {}
|
||||
|
||||
if 'Organize' in proxy.get_enabled_plugins():
|
||||
if 'Label' in sclient.get_enabled_plugins():
|
||||
filter_dict = {}
|
||||
|
||||
for filter_name in ["state","tracker","keyword"]:
|
||||
value = get(filter,filter_name)
|
||||
if value and value <> "All":
|
||||
filter_dict[filter_name] = value
|
||||
|
||||
torrent_ids = proxy.organize_get_session_state(filter_dict)
|
||||
organize_filters = Storage(proxy.organize_all_filter_items())
|
||||
torrent_ids = sclient.label_get_filtered_ids(filter_dict)
|
||||
filters = sclient.label_filter_items()
|
||||
else:
|
||||
torrent_ids = proxy.get_session_state()
|
||||
torrent_ids = proxy.get_session_state()
|
||||
organize_filters = {"state":[["All",-1]],"tracker":[]}
|
||||
|
||||
result = {
|
||||
return {
|
||||
"torrents":sclient.get_torrents_status(torrent_ids, keys),
|
||||
"state":organize_filters["state"],
|
||||
"tracker":organize_filters["tracker"],
|
||||
"stats":[0, 1, 2, 3], #todo
|
||||
"cache_id":cache_id
|
||||
"filters":filters,
|
||||
"stats":self.get_stats(),
|
||||
"cache_id":-1
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -407,6 +407,8 @@ route("/template_style.css", template_style)
|
|||
class pixmaps:
|
||||
"use the deluge-images. located in data/pixmaps"
|
||||
def GET(self, name):
|
||||
if name.startswith("flags") and not name.endswith('.png'):
|
||||
name = name + ".png"
|
||||
if not name.endswith('.png'):
|
||||
if name == 'paused':
|
||||
name = 'inactive'
|
||||
|
|
|
@ -64,7 +64,7 @@ function update_torrent(torrent) {
|
|||
function get_stats() {
|
||||
service.get_stats({params:[],
|
||||
onSuccess:function(stats){
|
||||
alert(stats.download_rate);
|
||||
alert(service.__toJSON(stats));
|
||||
},
|
||||
onException:function(errorObj){
|
||||
alert("Error: " + errorObj);
|
||||
|
@ -74,19 +74,32 @@ function get_stats() {
|
|||
|
||||
|
||||
|
||||
|
||||
function update_ui() {
|
||||
service.update_ui({params:[ ["name","state","label","tracker_host"],{"state":"Seeding"} ],
|
||||
onSuccess:function(data){
|
||||
alert(service.__toJSON(data));
|
||||
},
|
||||
onException:function(errorObj){
|
||||
alert("Error: " + errorObj);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<h1>sclient:</h1>
|
||||
<button onclick="get_session_state()">get_session_state()</button>
|
||||
|
||||
<button onclick="list_torrents()">List torrents</button>
|
||||
|
||||
<button onclick="list_torrents()">List torrents using get_session_state() + get_torrents_status()</button> <br>
|
||||
<h1>json extra:</h1>
|
||||
<button onclick="get_stats()">get_stats()</button>
|
||||
|
||||
<button onclick="update_ui()">update_ui() filter on "Seeding"</button>
|
||||
|
||||
|
||||
<div id="torrent_list">
|
||||
|
||||
</div>
|
||||
|
|
|
@ -5,20 +5,21 @@ $def with (torrent)
|
|||
|
||||
$altrow(True)
|
||||
<tr class="head">
|
||||
<th>$_("Ip")</th>
|
||||
<th>$_("Up Speed")</th>
|
||||
<th> <!--country-flag--></th>
|
||||
<th>$_("Address")</th>
|
||||
<th>$_("Down Speed")</th>
|
||||
<th>$_("Country")</th>
|
||||
<th>$_("Up Speed")</th>
|
||||
<th>$_("Client")</th>
|
||||
<th>$_("Progress")</th>
|
||||
<!--<th>$_("Progress")</th>-->
|
||||
</tr>
|
||||
$for peer in torrent.peers:
|
||||
<tr class="tab_$altrow()" >
|
||||
<td><img src="$base/pixmaps/flags/$(peer['country'].lower())" /></td>
|
||||
<td>$peer['ip']</td>
|
||||
<td>$fspeed(peer['up_speed'])</td>
|
||||
<td>$fspeed(peer['down_speed'])</td>
|
||||
<td>$peer['country']</td>
|
||||
<td>$fspeed(peer['up_speed'])</td>
|
||||
<td>$peer['client']</td>
|
||||
<!--not in gtk-ui anymore, broken?
|
||||
<td class="progress_bar">
|
||||
$if peer.get('progress'):
|
||||
<div class="progress_bar_outer">
|
||||
|
@ -31,6 +32,7 @@ $for peer in torrent.peers:
|
|||
? %
|
||||
</div>
|
||||
</td>
|
||||
-->
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
|
|
Loading…
Reference in New Issue