remove all logic from webserver_common

This commit is contained in:
Martijn Voncken 2008-03-21 17:11:00 +00:00
parent d2d0e26f4c
commit b4e1051fe0
18 changed files with 215 additions and 205 deletions

View File

@ -32,33 +32,39 @@
import lib.newforms_plus as forms
import page_decorators as deco
import web
from webserver_common import ws, proxy, log
from deluge.ui.client import sclient as proxy
from deluge.log import LOG as log
from render import render
from web import seeother
import sys
import os
import utils
from deluge import component
from deluge import component
from deluge.configmanager import ConfigManager
config = ConfigManager("webui.conf")
config_page_manager = component.get("ConfigPageManager")
class WebCfgForm(forms.Form):
"config base for webui"
def initial_data(self):
return ws.config
return config.get_config()
def save(self, data):
ws.config.update(data)
ws.save_config()
for key, value in data.iteritems():
config.set(key, value)
config.save()
class CookieCfgForm(forms.Form):
"config base for webui"
def initial_data(self):
return ws.config
return dict(config)
def save(self, data):
ws.config.update(data)
ws.save_config()
config.update(data)
config.save_config()
class CfgForm(forms.Form):

View File

@ -30,8 +30,11 @@
# this exception statement from your version. If you delete this exception
# statement from all source files in the program, then also delete it here.
from deluge.ui.client import sclient as proxy
from deluge.log import LOG as log
import utils
from webserver_common import ws, proxy , log
import lib.newforms_plus as forms
import config_forms
from deluge import component
@ -125,13 +128,10 @@ config_page.register('deluge','daemon', Daemon)
class Plugins(forms.Form):
title = _("Enabled Plugins")
try:
_choices = [(p,p) for p in proxy.get_available_plugins()]
enabled_plugins = forms.MultipleChoice(_(""), _choices)
except:
log.error("Not connected to daemon, Unable to load plugin-list")
#TODO: reload on reconnect!
enabled_plugins = forms.LazyMultipleChoice(
choices_getter = lambda: [(p,p) for p in proxy.get_available_plugins()]
)
def initial_data(self):
return {'enabled_plugins':proxy.get_enabled_plugins()}

View File

@ -31,12 +31,14 @@
# this exception statement from your version. If you delete this exception
# statement from all source files in the program, then also delete it here.
from deluge.ui.client import sclient as proxy
from deluge.log import LOG as log
import utils
from webserver_common import ws, log
import lib.newforms_plus as forms
import config_forms
from deluge import component
from render import render
config_page = component.get("ConfigPageManager")
plugins = component.get("WebPluginManager")
@ -44,7 +46,7 @@ plugins = component.get("WebPluginManager")
class Template(config_forms.WebCfgForm):
title = _("Template")
_templates = [(t,t) for t in ws.get_templates()]
_templates = [(t,t) for t in render.get_templates()]
_button_choices = enumerate([_('Text and image'), _('Image Only')
, _('Text Only')])
@ -93,21 +95,6 @@ class Password(forms.Form):
utils.end_session()
#raise forms.ValidationError(_("Password changed,please login again"))
class WebUiPlugins(forms.Form):
title = _("WebUi Plugins")
_choices = [(p,p) for p in plugins.get_available_plugins()]
enabled_plugins = forms.MultipleChoice(_(""), _choices)
def initial_data(self):
return {'enabled_plugins':plugins.get_enabled_plugins()}
def save(self, data):
log.debug(data)
for plugin_name in data['enabled_plugins']:
plugins.enable_plugin(plugin_name)
config_page.register('webui','template', Template)
config_page.register('webui','server',Server)
config_page.register('webui','password',Password)
config_page.register('webui','webuiplugins',WebUiPlugins)

View File

@ -27,40 +27,71 @@
# this exception statement from your version. If you delete this exception
# statement from all source files in the program, then also delete it here.
#initialize components:
import web
import random
import gettext
import locale
from deluge.configmanager import ConfigManager
import pkg_resources
from deluge.ui.client import sclient
# Initialize gettext
locale.setlocale(locale.LC_MESSAGES, '')
locale.bindtextdomain("deluge",
pkg_resources.resource_filename(
"deluge", "i18n"))
locale.textdomain("deluge")
gettext.bindtextdomain("deluge",
pkg_resources.resource_filename(
"deluge", "i18n"))
gettext.textdomain("deluge")
gettext.install("deluge",
pkg_resources.resource_filename(
"deluge", "i18n"))
#self registering components:
import plugin_manager #registers as "WebPluginManager"
import menu_manager #registers as "MenuManager"
import config_page_manager #registers as "ConfigPageManager"
import plugin_manager #registers as "WebPluginManager"
import page_manager #registers as "PageManager"
from debugerror import deluge_debugerror
from render import render
import utils
## Init ##
config = ConfigManager("webui.conf")
random.seed()
web.webapi.internalerror = deluge_debugerror
#self registering pages etc.
import pages
import config_tabs_webui #auto registers in ConfigUiManager
import config_tabs_deluge #auto registers in ConfigUiManager
import register_menu
#debugerror
from debugerror import deluge_debugerror
import web
web.webapi.internalerror = deluge_debugerror
utils.set_config_defaults()
sclient.set_core_uri(config.get('daemon'))
from webserver_common import ws #todo: remove ws.
def create_webserver(urls, methods, middleware):
from webserver_common import ws
from web import webpyfunc
from web import webapi
from web import webpyfunc, wsgifunc
from lib.gtk_cherrypy_wsgiserver import CherryPyWSGIServer
import os
func = webapi.wsgifunc(webpyfunc(urls, methods, False), *middleware)
server_address=("0.0.0.0", int(ws.config.get('port')))
func = wsgifunc(webpyfunc(urls, methods, False), *middleware)
server_address=("0.0.0.0", int(config.get('port')))
server = CherryPyWSGIServer(server_address, func, server_name="localhost")
if ws.config.get('use_https'):
"""if config.get('use_https'):
server.ssl_certificate = os.path.join(ws.webui_path,'ssl/deluge.pem')
server.ssl_private_key = os.path.join(ws.webui_path,'ssl/deluge.key')
"""
print "http://%s:%d/" % server_address
return server

View File

@ -10,7 +10,7 @@ from newforms.forms import BoundField
import sys, os
import webpy022 as web
import web
#Form
class FilteredForm(newforms.Form):
@ -115,13 +115,6 @@ class IntChoiceField(newforms.ChoiceField):
def clean(self, value):
return int(newforms.ChoiceField.clean(self, value))
class MultipleChoice(newforms.MultipleChoiceField):
#temp/test/debug!!
"Non Required MultipleChoiceField,why the f is it required by default?"
def __init__(self, label, choices, **kwargs):
newforms.MultipleChoiceField.__init__(self, label=label, choices=choices,
widget=newforms.CheckboxSelectMultiple, required=False)
class ServerFolder(newforms.CharField):
def __init__(self, label, **kwargs):
newforms.CharField.__init__(self, label=label,**kwargs)
@ -142,8 +135,44 @@ class Password(newforms.CharField):
newforms.CharField.__init__(self, label=label, widget=newforms.PasswordInput,
**kwargs)
#Lazy multiple select:
class _LazyCheckboxSelectMultiple(newforms.CheckboxSelectMultiple):
"""
choices are not know at define-time
choices_getter returns self.choices.
"""
def __init__(self, attrs=None,choices_getter = None):
self.choices_getter = choices_getter
newforms.CheckboxSelectMultiple.__init__(self,attrs)
def render(self, name, value, attrs=None, choices=()):
self.choices = self.choices_getter()
return newforms.CheckboxSelectMultiple.render(self, name, value, attrs, choices)
class LazyMultipleChoice(newforms.MultipleChoiceField):
"""
choices are not know at define-time
choices_getter returns self.choices.
defaults to non-required.
"""
def __init__(self, label = "",widget=_LazyCheckboxSelectMultiple,
choices_getter = None, **kwargs):
self.choices_getter = choices_getter
#default to non-required
if not 'required' in kwargs:
kwargs['required'] = False
#init, and pass get_choices to the widget.
newforms.MultipleChoiceField.__init__(self, label=label,
widget=widget(choices_getter=choices_getter),**kwargs)
def clean(self, value):
self.choices = self.choices_getter()
return newforms.MultipleChoiceField.clean(self, value)
#Deluge specific:
class _DelugeIntInput(newforms.TextInput):
class _DelugeIntInputWidget(newforms.TextInput):
"""
because deluge-floats are edited as ints.
"""
@ -159,7 +188,7 @@ class _DelugeIntInput(newforms.TextInput):
class DelugeInt(newforms.IntegerField):
def __init__(self, label , **kwargs):
newforms.IntegerField.__init__(self, label=label, min_value=-1,
max_value=sys.maxint, widget=_DelugeIntInput, **kwargs)
max_value=sys.maxint, widget=_DelugeIntInputWidget, **kwargs)
def clean(self, value):
if str(value).lower() == _('Unlimited').lower():

View File

@ -6,8 +6,8 @@
static fileserving for web.py
without the need for wsgi wrapper magic.
"""
import webpy022 as web
from webpy022 import seeother, url
import web
from web import seeother, url
import posixpath
import urlparse

View File

@ -0,0 +1,2 @@
#compatibility: use the included version/release of web.py.
from webpy022 import *

View File

@ -3,8 +3,10 @@ decorators for html-pages.
"""
#relative imports
from render import render
from webserver_common import ws, log, proxy
from utils import *
import utils
from deluge.ui.client import sclient as proxy
from deluge.log import LOG as log
#/relative
from web import cookies, setcookie as w_setcookie
@ -34,7 +36,7 @@ def check_session(func):
name))
vars = web.input(redir_after_login = None)
ck = cookies()
if ck.has_key("session_id") and ck["session_id"] in ws.SESSIONS:
if ck.has_key("session_id") and ck["session_id"] in utils.SESSIONS:
return func(self, name) #check_session:ok
elif vars.redir_after_login:
seeother(url("/login",redir=self_url()))

View File

@ -34,7 +34,6 @@
#todo: remove useless imports.
from webserver_common import ws, proxy, log
from utils import *
import utils #todo remove the line above.
from render import render, error_page
@ -44,6 +43,7 @@ from torrent_options import torrent_options
from torrent_move import torrent_move
from deluge.common import get_pixmap
from deluge.log import LOG as log
import web
from web import seeother, url
@ -53,6 +53,7 @@ from torrent_add import torrent_add
from operator import attrgetter
import os
from deluge import component
from deluge.ui.client import sclient as proxy
page_manager = component.get("PageManager")
@ -112,7 +113,7 @@ class login:
def POST(self):
vars = web.input(pwd = None, redir = None)
if ws.check_pwd(vars.pwd):
if utils.check_pwd(vars.pwd):
#start new session
start_session()
do_redirect()
@ -347,11 +348,11 @@ class connect:
if vars.uri == 'other_uri':
if not vars.other:
return error_page(_("no uri"))
url = vars.other
uri = vars.other
else:
uri = vars.uri
#TODO: more error-handling
proxy.set_core_uri(uri)
utils.daemon_connect(uri)
do_redirect()
class daemon_control:
@ -372,16 +373,16 @@ class daemon_control:
seeother('/connect')
def start(self):
import time
uri = web.input(uri = None).uri
if not uri:
uri = 'http://localhost:58846'
port = int(uri.split(':')[2])
utils.daemon_start_localhost(port)
time.sleep(1) #pause a while to let it start?
proxy.set_core_uri( uri )
utils.daemon_connect( uri )
#other stuff:
class remote_torrent_add:
@ -395,7 +396,7 @@ class remote_torrent_add:
vars = web.input(pwd = None, torrent = {},
data_b64 = None , torrent_name= None)
if not ws.check_pwd(vars.pwd):
if not utils.check_pwd(vars.pwd):
return 'error:wrong password'
if vars.data_b64: #b64 post (greasemonkey)

View File

@ -34,6 +34,8 @@
from deluge import component, pluginmanagerbase
from deluge.configmanager import ConfigManager
from deluge.log import LOG as log
from deluge.ui.client import aclient as client
class PluginManager(pluginmanagerbase.PluginManagerBase,
component.Component):
@ -52,6 +54,7 @@ class PluginManager(pluginmanagerbase.PluginManagerBase,
# Disable the plugins
self.disable_plugins()
def _on_get_enabled_plugins(self, enabled_plugins):
log.debug("Webui has these plugins enabled: %s", enabled_plugins)
self.config["enabled_plugins"] = enabled_plugins

View File

@ -30,13 +30,16 @@
# statement from all source files in the program, then also delete it here.
#relative:
from webserver_common import ws,REVNO,VERSION
from webserver_common import REVNO, VERSION
from utils import *
#/relative
from deluge import common
from web import changequery as self_url, template, Storage
import os
from deluge.configmanager import ConfigManager
config = ConfigManager("webui.conf")
class subclassed_render(object):
"""
adds limited subclassing for templates.
@ -46,22 +49,23 @@ class subclassed_render(object):
self.apply_cfg()
def apply_cfg(self):
self.cache = ws.config.get('cache_templates')
self.cache = config.get('cache_templates')
self.renderers = []
self.plugin_renderers = []
self.template_cache = {}
self.webui_path = os.path.dirname(__file__)
#load template-meta-data
cfg_template = ws.config.get('template')
template_path = os.path.join(ws.webui_path, 'templates/%s/' % cfg_template)
cfg_template = config.get('template')
template_path = os.path.join(self.webui_path, 'templates/%s/' % cfg_template)
if not os.path.exists(template_path):
template_path = os.path.join(ws.webui_path, 'templates/deluge/')
template_path = os.path.join(self.webui_path, 'templates/deluge/')
self.meta = Storage(eval(open(os.path.join(template_path,'meta.cfg')).read()))
#load renerders
for template_name in [cfg_template] + list(reversed(self.meta.inherits)):
self.renderers.append(template.render(
os.path.join(ws.webui_path, 'templates/%s/' % template_name),cache=False))
os.path.join(self.webui_path, 'templates/%s/' % template_name),cache=False))
@logcall
def register_template_path(self, path):
@ -89,6 +93,16 @@ class subclassed_render(object):
"for plugins/templates"
return getattr(self, item)
@staticmethod
def get_templates():
"utility method."
template_path = os.path.join(os.path.dirname(__file__), 'templates')
return [dirname for dirname
in os.listdir(template_path)
if os.path.isdir(os.path.join(template_path, dirname))
and not dirname.startswith('.')]
render = subclassed_render()
def error_page(error):
@ -137,7 +151,7 @@ def template_part_stats():
return '[not connected]'
def get_config(var):
return ws.config.get(var)
return config.get(var)
irow = 0
def altrow(reset = False):
@ -181,7 +195,7 @@ template.Template.globals.update({
'version': VERSION,
'getcookie':getcookie,
'get': lambda (var): getattr(web.input(**{var:None}), var), # unreadable :-(
'env':ws.env,
'env':'0.6',
'forms':web.Storage(),
'enumerate':enumerate

View File

@ -2,5 +2,4 @@
#only for development/debugging.
import deluge_webserver
deluge_webserver.ws.init_06(uri = 'http://localhost:58846')
deluge_webserver.run(debug = True)

View File

@ -29,7 +29,9 @@
# this exception statement from your version. If you delete this exception
# statement from all source files in the program, then also delete it here.
#
from webserver_common import ws, log, proxy
from deluge.ui.client import sclient as proxy
from deluge.log import LOG as log
import utils
from render import render, error_page
import page_decorators as deco

View File

@ -30,12 +30,13 @@
# statement from all source files in the program, then also delete it here.
#
from webserver_common import ws, proxy
from deluge.ui.client import sclient as proxy
from deluge.log import LOG as log
import utils
from render import render
import page_decorators as deco
import lib.newforms_plus as forms
import web
#Too much boilerplate code here, todo : fix it.

View File

@ -29,12 +29,9 @@
# this exception statement from your version. If you delete this exception
# statement from all source files in the program, then also delete it here.
#
from webserver_common import ws
import utils
from render import template
import page_decorators as deco
import lib.newforms_plus as forms
import web
class TorrentOptionsForm(forms.Form):

View File

@ -38,6 +38,7 @@ from web import Storage
from web import seeother, url
from deluge.common import fsize,fspeed,ftime
from deluge.log import LOG as log
import traceback
import random
@ -45,11 +46,18 @@ from operator import attrgetter
import datetime
import pickle
from urlparse import urlparse
from md5 import md5
from webserver_common import REVNO, VERSION, TORRENT_KEYS, STATE_MESSAGES
from webserver_common import ws, proxy, async_proxy, log
from webserver_common import REVNO, VERSION, TORRENT_KEYS, STATE_MESSAGES, CONFIG_DEFAULTS
from deluge.ui.client import sclient as proxy
from deluge.ui.client import aclient as async_proxy
debug_unicode = False
from deluge import component
from deluge.configmanager import ConfigManager
webui_plugin_manager = component.get("WebPluginManager")
config = ConfigManager("webui.conf")
#async-proxy: map callback to a a dict-setter
def dict_cb(key,d):
@ -62,16 +70,18 @@ def setcookie(key, val):
"""add 30 days expires header for persistent cookies"""
return w_setcookie(key, val , expires=2592000)
#really simple sessions, to bad i had to implement them myself.
SESSIONS = []
def start_session():
log.debug('start session')
session_id = str(random.random())
ws.SESSIONS.append(session_id)
SESSIONS.append(session_id)
setcookie("session_id", session_id)
def end_session():
session_id = getcookie("session_id")
setcookie("session_id","")
#/sessions
def do_redirect():
"""for redirects after a POST"""
@ -201,7 +211,7 @@ def get_newforms_data(form_class):
#/utils
#generic/ non-webui utils todo: move to trunk/core.
#daemon:
def daemon_test_online_status(uri):
"""Tests the status of URI.. Returns True or False depending on status.
"""
@ -224,14 +234,52 @@ def daemon_start_localhost(port):
# Spawn a local daemon
os.popen("deluged -p %s" % port)
def daemon_connect(uri):
if config.get('daemon') <> uri:
config.set('daemon', uri)
config.save()
proxy.set_core_uri(uri)
webui_plugin_manager.start()
#generic:
def logcall(func):
"log a function/method-call"
"deco to log a function/method-call"
def deco(*args, **kwargs):
log.debug("call: %s<%s,%s>" % (func.__name__, args, kwargs))
return func(*args, **kwargs) #logdeco
return deco
#c&p from ws:
def update_pwd(pwd):
sm = md5()
sm.update(str(random.getrandbits(5000)))
salt = sm.digest()
config["pwd_salt"] = salt
#
m = md5()
m.update(salt)
m.update(pwd)
config["pwd_md5"] = m.digest()
def check_pwd(pwd):
m = md5()
m.update(config.get('pwd_salt'))
m.update(pwd)
return (m.digest() == config.get('pwd_md5'))
def set_config_defaults():
changed = False
for key, value in CONFIG_DEFAULTS.iteritems():
if not key in config.config:
config.config[key] = value
changed = True
if changed:
config.save()
#exceptions:
class WebUiError(Exception):

View File

@ -1,2 +1,2 @@
#compatibility: use the included version/release of web.py.
from lib.webpy022 import *
from lib.web import *

View File

@ -30,34 +30,10 @@
# statement from all source files in the program, then also delete it here.
"""
initializes config,render and proxy.
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
webui constants
"""
import os
import deluge
import random
import pickle
import sys
import base64
from md5 import md5
import inspect
from deluge.log import LOG as log
from deluge.ui.client import sclient as proxy
from deluge.ui.client import aclient as async_proxy
random.seed()
try:
_('translate something')
except:
import gettext
gettext.install('~/')
log.error('no translations :(')
#constants
try:
@ -102,98 +78,10 @@ CONFIG_DEFAULTS = {
"pwd_salt":"2\xe8\xc7\xa6(n\x81_\x8f\xfc\xdf\x8b\xd1\x1e\xd5\x90",
"pwd_md5":".\xe8w\\+\xec\xdb\xf2id4F\xdb\rUc",
"cache_templates":True,
"use_https":False
"use_https":False,
"daemon":"http://localhost:58846"
}
#/constants
class Ws:
"""
singleton
important attributes here are environment dependent.
Most important public attrs:
ws.proxy
ws.log
ws.config
Other:
ws.env
ws.config_dir
ws.session_file
ws.SESSIONS
"""
def __init__(self):
self.webui_path = os.path.dirname(__file__)
self.env = 'UNKNOWN'
self.config = {}
try:
self.config_dir = deluge.common.CONFIG_DIR
except:
self.config_dir = os.path.expanduser("~/.config/deluge")
self.config_file = os.path.join(self.config_dir,'webui.conf')
self.session_file = os.path.join(self.config_dir,'webui.sessions')
self.SESSIONS = []
def init_process(self):
self.config = pickle.load(open(self.config_file))
if self.config.get('enabled_plugins') == None:
self.config['enabled_plugins'] = []
self.save_config()
def init_06(self, uri = 'http://localhost:58846'):
proxy.set_core_uri(uri)
log.debug('cfg-file %s' % self.config_file)
if not os.path.exists(self.config_file):
log.debug('create cfg file %s' % self.config_file)
#load&save defaults.
f = file(self.config_file,'wb')
pickle.dump(CONFIG_DEFAULTS,f)
f.close()
self.init_process()
self.env = '0.6'
from render import render
render.apply_cfg()
#utils for config:
def get_templates(self):
template_path = os.path.join(os.path.dirname(__file__), 'templates')
return [dirname for dirname
in os.listdir(template_path)
if os.path.isdir(os.path.join(template_path, dirname))
and not dirname.startswith('.')]
def save_config(self):
log.debug('Save Webui Config')
data = pickle.dumps(self.config)
f = open(self.config_file,'wb')
f.write(data)
f.close()
def update_pwd(self,pwd):
sm = md5()
sm.update(str(random.getrandbits(5000)))
salt = sm.digest()
self.config["pwd_salt"] = salt
#
m = md5()
m.update(salt)
m.update(pwd)
self.config["pwd_md5"] = m.digest()
def check_pwd(self,pwd):
m = md5()
m.update(self.config.get('pwd_salt'))
m.update(pwd)
return (m.digest() == self.config.get('pwd_md5'))
ws =Ws()