webui sync r168

This commit is contained in:
Marcos Pinto 2007-12-22 08:15:51 +00:00
parent 93d0ab797b
commit b803d39d63
33 changed files with 204 additions and 44 deletions

View File

@ -97,7 +97,7 @@ class plugin_WebUi(object):
if status[0] == 0:
os.kill(int(status[1].split()[0]), 9)
time.sleep(1) #safe time to wait for kill to finish.
self.config_file = os.path.join(deluge.common.CONFIG_DIR, "webui.conf")
self.config_file = deluge.common.CONFIG_DIR + "/webui.conf"
self.config = deluge.pref.Preferences(self.config_file, False)
try:
self.config.load()
@ -162,7 +162,7 @@ class plugin_WebUi(object):
else:
print 'Start Webui(in process)..'
server_bin = os.path.join(os.path.dirname(__file__), 'run_webserver')
server_bin = os.path.dirname(__file__) + '/run_webserver'
self.proc = Popen((server_bin,'env=0.5'))
def kill_server(self):

View File

@ -11,9 +11,9 @@ http://www.xfree86.org/3.3.6/COPYRIGHT2.html#5
__all__ = ["debugerror", "djangoerror"]
import sys, urlparse, pprint
from webpy022.net import websafe
from webpy022.template import Template
import webpy022.webapi as web
from lib.webpy022.net import websafe
from lib.webpy022.template import Template
import lib.webpy022.webapi as web
import webserver_common as ws
from traceback import format_tb

View File

@ -34,13 +34,15 @@
import webserver_common as ws
from webserver_framework import *
import webpy022 as web
from webpy022.http import seeother, url
import lib.webpy022 as web
from lib.webpy022.http import seeother, url
import base64
from operator import attrgetter
import os
from json_api import json_api
#routing:
urls = (
"/login", "login",
@ -64,6 +66,7 @@ urls = (
"/logout", "logout",
#remote-api:
"/remote/torrent/add(.*)", "remote_torrent_add",
"/json/(.*)","json_api",
#static:
"/static/(.*)", "static",
"/template/static/(.*)", "template_static",

132
plugins/WebUi/json_api.py Normal file
View File

@ -0,0 +1,132 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# webserver_framework.py
#
# Copyright (C) Martijn Voncken 2007 <mvoncken@gmail.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# exception, you may extend this exception to your version of the file(s),
# but you are not obligated to do so. If you do not wish to do so, delete
# this exception statement from your version. If you delete this exception
# statement from all source files in the program, then also delete it here.
"""
json api.
only used for XUL and/or external scripts
it would be possible not to incluse the python-json dependency.
"""
import deluge.ui.client as proxy
from new import instancemethod
from inspect import getargspec
from webserver_framework import remote,ws,get_torrent_status,log
proxy = ws.proxy
def to_json(obj):
from lib.pythonize import pythonize
obj = pythonize(obj)
try:
import json
return json.write(obj)
except ImportError:
raise ImportError("""Install python-json using your package-manager
http://sourceforge.net/projects/json-py/""")
class json_api:
"""
eperimental json api
generic proxy for all methods onm self.
"""
illegal_methods = ['shutdown', 'socket', 'xmlrpclib','pickle','os',
'is_localhost','CoreProxy','connect_on_new_core', 'connect_on_no_core',
'connected','deluge','GET','POST']
def __init__(self):
self._add_proxy_methods()
@remote
def GET(self,name):
if name.startswith('_'):
raise AttributeError('_ methods are illegal!')
if name in self.illegal_methods:
raise AttributeError('Illegal method , I smell a rat!')
if not(hasattr(self,name)):
raise AttributeError('No such Method')
method = getattr(self,name)
kwargs = {}
result = method(**kwargs)
return to_json(result)
POST = GET
def list_methods(self):
"""
list all json methods
returns a dict of {methodname:{args:[list of kwargs],doc:'string'},..}
"""
methods = [getattr(self,m) for m in dir(self)
if not m.startswith('_')
and (not m in self.illegal_methods)
and callable(getattr(self,m))
]
return dict([(f.__name__,
{'args':getargspec(f)[0],'doc':(f.__doc__ or '').strip()})
for f in methods])
def _add_proxy_methods(self):
methods = [getattr(proxy,m) for m in dir(proxy)
if not m.startswith('_')
and (not m in self.illegal_methods)
and callable(getattr(proxy,m))
]
for m in methods:
setattr(self,m.__name__,m)
#extra's:
def list_torrents(self):
return [get_torrent_status(torrent_id)
for torrent_id in ws.proxy.get_session_state()]
get_torrent_status = get_torrent_status
if __name__ == '__main__':
from pprint import pprint
#proxy.set_core_uri('http://localhost:58846') #How to configure this?
j = json_api()
if True:
print 'list-methods:'
methods = j.list_methods()
names = methods.keys()
names.sort()
for name in names:
m = methods[name]
print "%s(%s)\n %s\n" % (name , m['args'] , m['doc'])
#j.GET('list_torrents')
j.POST('list_torrents')

View File

View File

@ -0,0 +1,8 @@
This folder may only contain general purpose utilities/files/tools.
They should be usable outside of deluge.
Disclaimer:
Some may have been adapted to work better with deluge.
But they will not other import parts of deluge or Webui.

View File

@ -1 +0,0 @@
165

View File

@ -47,7 +47,7 @@ $:render.header(_('Torrent list'))
<div id="tableContainer" class="tableContainer">
<table class="torrent_list" border=1 id="torrent_list">
<table class="torrent_list" border=0 cellspacing=0 cellpadding=2 id="torrent_list">
<thead class="fixedHeader">
<tr>
$:(sort_head('calc_state_str', 'S'))
@ -67,9 +67,10 @@ $:render.header(_('Torrent list'))
</tr>
</thead>
<tbody class="scrollContent">
$altrow(True)
$#4-space indentation is mandatory for for-loops in templetor!
$for torrent in torrent_list:
<tr class="torrent_table" onclick="on_click_row(event, '$torrent.id')" id="torrent_$torrent.id">
<tr class="$altrow()" onclick="on_click_row(event, '$torrent.id')" id="torrent_$torrent.id">
<td>
<form action="/torrent/$torrent.action/$torrent.id" method="POST"
class="pause_resume">

View File

@ -78,6 +78,19 @@ tr.torrent_table:hover {
background-color:#68a;
}
tr.altrow0:hover {
background-color:#68a;
}
tr.altrow1:hover {
background-color:#68a;
}
tr.altrow1{
background-color: #37506f;
}
tr.torrent_table_selected {
background-color:#900;
}
@ -85,6 +98,9 @@ tr.torrent_table_selected {
th.torrent_table:hover {
background-color:#68a;
}
th.torrent_table {
background-color: #37506f;
}
img.button {
margin-bottom:0px;

View File

@ -45,6 +45,9 @@ function on_click_row_js(e, id) {
function select_row(id){
var row = get_row(id);
if (row) {
if (!(row.default_class_name)) {
row.default_class_name = row.className;
}
row.className = 'torrent_table_selected';
state.selected_rows[state.selected_rows.length] = id;
setCookie('selected_rows',state.selected_rows);
@ -54,7 +57,7 @@ function select_row(id){
function deselect_row(id){
var row = get_row(id);
if (row) {
row.className = 'torrent_table'
row.className = row.default_class_name
/*remove from state.selected_rows*/
var idx = state.selected_rows.indexOf(id);
state.selected_rows.splice(idx,1);

View File

@ -1,13 +0,0 @@
<div id='refresh_panel'>
<div class="panel" >
$_('Auto refresh:')
$if getcookie('auto_refresh') == '1':
($getcookie('auto_refresh_secs')) $_('seconds')) &nbsp;
$:render.part_button('GET', '/refresh/set', _('Set'), 'tango/preferences-system.png')
$:render.part_button('POST', '/refresh/off', _('Disable'), 'tango/process-stop.png')
$else:
$_('Off') &nbsp;
$:render.part_button('POST', '/refresh/on', _('Enable'), 'tango/view-refresh.png')
$#end
</div>
</div>

View File

@ -1,5 +0,0 @@
revision-id: mvoncken@gmail.com-20070930083408-sv8mo0mi1rbjnfvk
date: 2007-12-05 15:10:08 +0200
build-date: 2007-12-05 15:34:50 +0200
revno: 165
branch-nick: WebUi

View File

@ -31,8 +31,8 @@
"""
initializes config,render and proxy.
contains all hacks to support running in process0.5 ,run inside-gtk0.5 and
run in process0.6
All hacks go here, so this is a really ugly source-file..
Support running in process0.5 ,run inside-gtk0.5 and run in process0.6
"""
import os
@ -41,7 +41,7 @@ import random
import pickle
import sys
import base64
from webpy022 import template
from lib.webpy022 import template
random.seed()
webui_path = os.path.dirname(__file__)
@ -163,7 +163,8 @@ def init_gtk_05():
def init_logger():
#only for 0.5..
import logging
logging.basicConfig(level=logging.DEBUG,format="[%(levelname)-8s] %(module)s:%(lineno)d %(message)s")
logging.basicConfig(level=logging.DEBUG,
format="[%(levelname)s] %(message)s")
globals()['log'] = logging

View File

@ -40,13 +40,13 @@ Todo's before stable:
-clear finished?
-torrent files.
"""
import webpy022 as web
import lib.webpy022 as web
from webpy022.webapi import cookies, setcookie as w_setcookie
from webpy022.http import seeother, url
from webpy022 import template,changequery as self_url
from webpy022.utils import Storage
from static_handler import static_handler
from lib.webpy022.webapi import cookies, setcookie as w_setcookie
from lib.webpy022.http import seeother, url
from lib.webpy022 import template,changequery as self_url
from lib.webpy022.utils import Storage
from lib.static_handler import static_handler
from deluge.common import fsize,fspeed
@ -144,7 +144,8 @@ def check_session(func):
return func if session is valid, else redirect to login page.
"""
def deco(self, name = None):
log.debug('%s.%s(name=%s)' % (self.__class__.__name__,func.__name__,name))
log.debug('%s.%s(name=%s)' % (self.__class__.__name__, func.__name__,
name))
vars = web.input(redir_after_login = None)
ck = cookies()
if ck.has_key("session_id") and ck["session_id"] in ws.SESSIONS:
@ -282,6 +283,7 @@ def filter_torrent_state(torrent_list,filter_name):
,'queued':lambda t: (t.paused and not t.user_paused)
,'paused':lambda t: (t.user_paused)
,'seeding':lambda t:(t.is_seed and not t.paused )
,'active':lambda t: (t.download_rate > 0 or t.upload_rate > 0)
}
filter_func = filters[filter_name]
return [t for t in torrent_list if filter_func(t)]
@ -300,7 +302,8 @@ def category_tabs(torrent_list):
(_('Downloading'),'downloading') ,
(_('Queued'),'queued') ,
(_('Paused'),'paused') ,
(_('Seeding'),'seeding')
(_('Seeding'),'seeding'),
(_('Active'),'active')
]:
title += ' (%s)' % (
len(filter_torrent_state(torrent_list, filter_name)), )
@ -349,6 +352,17 @@ def template_part_stats():
def get_config(var):
return ws.config.get(var)
irow = 0
def altrow(reset = False):
global irow
if reset:
irow = 1
return
irow +=1
irow = irow % 2
return "altrow%s" % irow
template.Template.globals.update({
'sort_head': template_sort_head,
'part_stats':template_part_stats,
@ -357,6 +371,7 @@ template.Template.globals.update({
'_': _ , #gettext/translations
'str': str, #because % in templetor is broken.
'sorted': sorted,
'altrow':altrow,
'get_config': get_config,
'self_url': self_url,
'fspeed': common.fspeed,
@ -370,9 +385,9 @@ template.Template.globals.update({
#/template-defs
def create_webserver(urls, methods):
from webpy022.request import webpyfunc
from webpy022 import webapi
from gtk_cherrypy_wsgiserver import CherryPyWSGIServer
from lib.webpy022.request import webpyfunc
from lib.webpy022 import webapi
from lib.gtk_cherrypy_wsgiserver import CherryPyWSGIServer
import os
func = webapi.wsgifunc(webpyfunc(urls, methods, False))