mirror of
https://github.com/codex-storage/deluge.git
synced 2025-02-26 10:05:19 +00:00
webui rev-80
This commit is contained in:
parent
278c6c9f3e
commit
bf8727f7bf
@ -115,7 +115,7 @@ class DbusManager(dbus.service.Object):
|
|||||||
for key in ["total_seeds", "total_peers","is_seed", "total_done",
|
for key in ["total_seeds", "total_peers","is_seed", "total_done",
|
||||||
"total_download", "total_upload", "download_rate",
|
"total_download", "total_upload", "download_rate",
|
||||||
"upload_rate", "num_files", "piece_length", "distributed_copies"
|
"upload_rate", "num_files", "piece_length", "distributed_copies"
|
||||||
,"next_announce","tracker"]:
|
,"next_announce","tracker","queue_pos"]:
|
||||||
status[key] = state[key]
|
status[key] = state[key]
|
||||||
|
|
||||||
#print 'all_keys:',sorted(status.keys())
|
#print 'all_keys:',sorted(status.keys())
|
||||||
@ -162,6 +162,19 @@ class DbusManager(dbus.service.Object):
|
|||||||
self._add_torrent(filename)
|
self._add_torrent(filename)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@dbus.service.method(dbus_interface=dbus_interface,
|
||||||
|
in_signature="s", out_signature="b")
|
||||||
|
def queue_up(self, torrent_id):
|
||||||
|
print 'UP!'
|
||||||
|
self.core.queue_up(int(torrent_id))
|
||||||
|
return True
|
||||||
|
|
||||||
|
@dbus.service.method(dbus_interface=dbus_interface,
|
||||||
|
in_signature="s", out_signature="b")
|
||||||
|
def queue_down(self, torrent_id):
|
||||||
|
self.core.queue_down(int(torrent_id))
|
||||||
|
return True
|
||||||
|
|
||||||
@dbus.service.method(dbus_interface=dbus_interface,
|
@dbus.service.method(dbus_interface=dbus_interface,
|
||||||
in_signature="ss", out_signature="b")
|
in_signature="ss", out_signature="b")
|
||||||
def add_torrent_filecontent(self, name, filecontent_b64):
|
def add_torrent_filecontent(self, name, filecontent_b64):
|
||||||
|
@ -102,6 +102,8 @@ urls = (
|
|||||||
"/torrent/pause(.*)", "torrent_pause",
|
"/torrent/pause(.*)", "torrent_pause",
|
||||||
"/torrent/add(.*)", "torrent_add",
|
"/torrent/add(.*)", "torrent_add",
|
||||||
"/torrent/delete/(.*)", "torrent_delete",
|
"/torrent/delete/(.*)", "torrent_delete",
|
||||||
|
"/torrent/queue/up/(.*)", "torrent_queue_up",
|
||||||
|
"/torrent/queue/down/(.*)", "torrent_queue_down",
|
||||||
"/pause_all(.*)", "pause_all",
|
"/pause_all(.*)", "pause_all",
|
||||||
"/resume_all(.*)", "resume_all",
|
"/resume_all(.*)", "resume_all",
|
||||||
"/refresh/set(.*)", "refresh_set",
|
"/refresh/set(.*)", "refresh_set",
|
||||||
@ -234,6 +236,21 @@ class torrent_delete:
|
|||||||
ws.proxy.remove_torrent(torrent_id, data_also, torrent_also)
|
ws.proxy.remove_torrent(torrent_id, data_also, torrent_also)
|
||||||
do_redirect()
|
do_redirect()
|
||||||
|
|
||||||
|
|
||||||
|
class torrent_queue_up:
|
||||||
|
@check_session
|
||||||
|
def POST(self, name):
|
||||||
|
torrent_id = name
|
||||||
|
ws.proxy.queue_up(torrent_id)
|
||||||
|
do_redirect()
|
||||||
|
|
||||||
|
class torrent_queue_down:
|
||||||
|
@check_session
|
||||||
|
def POST(self, name):
|
||||||
|
torrent_id = name
|
||||||
|
ws.proxy.queue_down(torrent_id)
|
||||||
|
do_redirect()
|
||||||
|
|
||||||
class pause_all:
|
class pause_all:
|
||||||
@check_session
|
@check_session
|
||||||
def POST(self, name):
|
def POST(self, name):
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
7
plugins/WebUi/scripts/build_webui_tarball.sh
Normal file
7
plugins/WebUi/scripts/build_webui_tarball.sh
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
cd ~/prj/WebUi
|
||||||
|
bzr revno > revno
|
||||||
|
bzr version-info > version
|
||||||
|
rm ~/prj/WebUi/WebUi.tgz
|
||||||
|
cd ~/prj
|
||||||
|
tar -zcvf ~/prj/WebUi/WebUi.tgz WebUi/ --exclude '.*' --exclude '*.pyc' --exclude '*.tgz' --exclude 'attic' --exclude 'xul' --exclude '*.sh' --exclude '*.*~'
|
24
plugins/WebUi/scripts/extract_template_strings.py
Normal file
24
plugins/WebUi/scripts/extract_template_strings.py
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
from __future__ import with_statement
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
template_dir = '~/prj/WebUi/templates/deluge'
|
||||||
|
template_dir = os.path.expanduser(template_dir )
|
||||||
|
|
||||||
|
|
||||||
|
files = [os.path.join(template_dir,fname)
|
||||||
|
for fname in os.listdir(template_dir)
|
||||||
|
if fname.endswith('.html')]
|
||||||
|
|
||||||
|
all_strings = []
|
||||||
|
for filename in files:
|
||||||
|
with open(filename,'r') as f:
|
||||||
|
content = f.read()
|
||||||
|
all_strings += re.findall("\$\_\(\'(.*)\'\)",content)
|
||||||
|
all_strings += re.findall("\$\_\(\"(.*)\"\)",content)
|
||||||
|
|
||||||
|
all_strings = sorted(set(all_strings))
|
||||||
|
|
||||||
|
with open ('./template_strings.py','w') as f:
|
||||||
|
for value in all_strings:
|
||||||
|
f.write("_('%s')\n" % value )
|
||||||
|
|
30
plugins/WebUi/scripts/template_strings.py
Normal file
30
plugins/WebUi/scripts/template_strings.py
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
_('# Of Files')
|
||||||
|
_('About')
|
||||||
|
_('Auto refresh:')
|
||||||
|
_('Availability')
|
||||||
|
_('Debug:Data Dump')
|
||||||
|
_('Delete .torrent file')
|
||||||
|
_('Delete downloaded files.')
|
||||||
|
_('Details')
|
||||||
|
_('Downloaded')
|
||||||
|
_('ETA')
|
||||||
|
_('Next Announce')
|
||||||
|
_('Off')
|
||||||
|
_('Password')
|
||||||
|
_('Password is invalid,try again')
|
||||||
|
_('Peers')
|
||||||
|
_('Pieces')
|
||||||
|
_('Refresh page every:')
|
||||||
|
_('Remove')
|
||||||
|
_('Seeders')
|
||||||
|
_('Set')
|
||||||
|
_('Share Ratio')
|
||||||
|
_('Speed')
|
||||||
|
_('Submit')
|
||||||
|
_('Total Size')
|
||||||
|
_('Tracker')
|
||||||
|
_('Tracker Status')
|
||||||
|
_('Upload torrent')
|
||||||
|
_('Uploaded')
|
||||||
|
_('Url')
|
||||||
|
_('seconds')
|
@ -5,7 +5,7 @@ $:render.header(_('Torrent list'))
|
|||||||
<table class="torrent_list" border=1>
|
<table class="torrent_list" border=1>
|
||||||
<tr>
|
<tr>
|
||||||
$:(sort_head('calc_state_str', 'S'))
|
$:(sort_head('calc_state_str', 'S'))
|
||||||
$:(sort_head('id', '#'))
|
$:(sort_head('queue_pos', '#'))
|
||||||
$:(sort_head('name', _('Name')))
|
$:(sort_head('name', _('Name')))
|
||||||
$:(sort_head('total_size', _('Size')))
|
$:(sort_head('total_size', _('Size')))
|
||||||
$:(sort_head('progress', _('Progress')))
|
$:(sort_head('progress', _('Progress')))
|
||||||
@ -24,7 +24,7 @@ $for torrent in torrent_list:
|
|||||||
src="/static/images/$(torrent.calc_state_str)16.png"
|
src="/static/images/$(torrent.calc_state_str)16.png"
|
||||||
name="$torrent.action" value="$torrent.id">
|
name="$torrent.action" value="$torrent.id">
|
||||||
</td>
|
</td>
|
||||||
<td>$torrent.id</td>
|
<td>$torrent.queue_pos</td>
|
||||||
<td style="width:100px; overflow:hidden;white-space: nowrap">
|
<td style="width:100px; overflow:hidden;white-space: nowrap">
|
||||||
<a href="/torrent/info/$torrent.id">$(crop(torrent.name, 40))</a></td>
|
<a href="/torrent/info/$torrent.id">$(crop(torrent.name, 40))</a></td>
|
||||||
<td>$fsize(torrent.total_size)</td>
|
<td>$fsize(torrent.total_size)</td>
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
$def with (method, url, title, image='')
|
$def with (method, url, title, image='')
|
||||||
<div class="deluge_button">
|
<div class="deluge_button">
|
||||||
<form method="$method" action="$url" class="deluge_button">
|
<form method="$method" action="$url" class="deluge_button">
|
||||||
<button type="submit" class="deluge_button">
|
|
||||||
<input type="hidden" name="redir" value="$self_url()">
|
<input type="hidden" name="redir" value="$self_url()">
|
||||||
|
<button type="submit" class="deluge_button">
|
||||||
$if (get_config('button_style') == 0):
|
$if (get_config('button_style') == 0):
|
||||||
$title
|
$title
|
||||||
$if image:
|
$if image:
|
||||||
|
@ -82,6 +82,7 @@ class="deluge_button">
|
|||||||
|
|
||||||
$:render.part_button('GET', '/torrent/delete/' + str(torrent.id), _('Remove'), 'tango/user-trash.png')
|
$:render.part_button('GET', '/torrent/delete/' + str(torrent.id), _('Remove'), 'tango/user-trash.png')
|
||||||
|
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
[<a onclick="javascript:toggle_dump()">$_('Debug:Data Dump')</a>]
|
[<a onclick="javascript:toggle_dump()">$_('Debug:Data Dump')</a>]
|
||||||
|
|
||||||
@ -103,6 +104,16 @@ function toggle_dump(){
|
|||||||
</script>
|
</script>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class='panel'>
|
||||||
|
Queue pos: $torrent.queue_pos
|
||||||
|
|
||||||
|
$:render.part_button('POST', '/torrent/queue/up/' + str(torrent.id), _('Queue Up'), 'tango/up.png')
|
||||||
|
|
||||||
|
$:render.part_button('POST', '/torrent/queue/down/' + str(torrent.id), _('Queue Down'), 'tango/down.png')
|
||||||
|
</div>
|
||||||
|
|
||||||
$:render.part_refresh()
|
$:render.part_refresh()
|
||||||
|
|
||||||
$:render.footer()
|
$:render.footer()
|
||||||
|
@ -52,11 +52,14 @@ if not hasattr(deluge,'pref'):
|
|||||||
|
|
||||||
def init():
|
def init():
|
||||||
#appy possibly changed config-vars, only called in when runing inside gtk.
|
#appy possibly changed config-vars, only called in when runing inside gtk.
|
||||||
|
path = os.path.dirname(__file__)
|
||||||
from dbus_interface import get_dbus_manager
|
from dbus_interface import get_dbus_manager
|
||||||
globals()['proxy'] = get_dbus_manager()
|
globals()['proxy'] = get_dbus_manager()
|
||||||
globals()['config'] = deluge.pref.Preferences(config_file, False)
|
globals()['config'] = deluge.pref.Preferences(config_file, False)
|
||||||
globals()['render'] = template.render('templates/%s/' % config.get('template'),
|
globals()['render'] = template.render(os.path.join(path, 'templates/%s/' %
|
||||||
cache=config.get('cache_templates'))
|
config.get('template')), cache=config.get('cache_templates'))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
REVNO = open(os.path.join(os.path.dirname(__file__),'revno')).read()
|
REVNO = open(os.path.join(os.path.dirname(__file__),'revno')).read()
|
||||||
@ -69,7 +72,7 @@ TORRENT_KEYS = ['distributed_copies', 'download_payload_rate',
|
|||||||
'total_payload_download', 'total_payload_upload', 'total_peers',
|
'total_payload_download', 'total_payload_upload', 'total_peers',
|
||||||
'total_seeds', 'total_size', 'total_upload', 'total_wanted',
|
'total_seeds', 'total_size', 'total_upload', 'total_wanted',
|
||||||
'tracker_status', 'upload_payload_rate', 'upload_rate',
|
'tracker_status', 'upload_payload_rate', 'upload_rate',
|
||||||
'uploaded_memory','tracker','state']
|
'uploaded_memory','tracker','state','queue_pos']
|
||||||
|
|
||||||
STATE_MESSAGES = (_("Queued"),
|
STATE_MESSAGES = (_("Queued"),
|
||||||
_("Checking"),
|
_("Checking"),
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
|
# webserver_framework.py
|
||||||
|
#
|
||||||
# Copyright (C) Martijn Voncken 2007 <mvoncken@gmail.com>
|
# Copyright (C) Martijn Voncken 2007 <mvoncken@gmail.com>
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
@ -29,53 +31,303 @@
|
|||||||
# this exception statement from your version. If you delete this exception
|
# this exception statement from your version. If you delete this exception
|
||||||
# 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.
|
||||||
|
|
||||||
import os
|
"""
|
||||||
import deluge
|
Todo's before stable:
|
||||||
from deluge.common import INSTALL_PREFIX
|
-__init__:kill->restart is not waiting for kill to be finished.
|
||||||
|
--later/features:---
|
||||||
|
-alternating rows?
|
||||||
|
-set prio
|
||||||
|
-clear finished?
|
||||||
|
-torrent files.
|
||||||
|
"""
|
||||||
|
import webpy022 as web
|
||||||
|
|
||||||
|
from webpy022.webapi import cookies, setcookie
|
||||||
|
from webpy022.http import seeother, url
|
||||||
|
from webpy022 import template,changequery as self_url
|
||||||
|
|
||||||
|
import traceback
|
||||||
import random
|
import random
|
||||||
import pickle
|
from operator import attrgetter
|
||||||
from webpy022 import template
|
|
||||||
|
|
||||||
random.seed()
|
from deluge import common
|
||||||
|
from webserver_common import REVNO, VERSION
|
||||||
|
import webserver_common as ws
|
||||||
|
|
||||||
config_file = deluge.common.CONFIG_DIR + "/webui.conf"
|
#init:
|
||||||
|
web.webapi.internalerror = web.debugerror
|
||||||
#a bit hacky way of detecting i'm in the deluge gui or in a process :(
|
|
||||||
if not hasattr(deluge,'pref'):
|
|
||||||
import dbus
|
|
||||||
bus = dbus.SessionBus()
|
|
||||||
proxy = bus.get_object("org.deluge_torrent.dbusplugin"
|
|
||||||
, "/org/deluge_torrent/DelugeDbusPlugin")
|
|
||||||
config = pickle.load(open(config_file))
|
|
||||||
render = template.render('templates/%s/' % config.get('template'),
|
|
||||||
cache=config.get('cache_templates'))
|
|
||||||
|
|
||||||
def init():
|
|
||||||
#appy possibly changed config-vars, only called in when runing inside gtk.
|
|
||||||
from dbus_interface import get_dbus_manager
|
|
||||||
globals()['proxy'] = get_dbus_manager()
|
|
||||||
globals()['config'] = deluge.pref.Preferences(config_file, False)
|
|
||||||
globals()['render'] = template.render('templates/%s/' % config.get('template'),
|
|
||||||
cache=config.get('cache_templates'))
|
|
||||||
|
|
||||||
|
|
||||||
REVNO = open(os.path.join(os.path.dirname(__file__),'revno')).read()
|
#/init
|
||||||
VERSION = open(os.path.join(os.path.dirname(__file__),'version')).read()
|
|
||||||
|
#methods:
|
||||||
|
SESSIONS = [] #dumb sessions.
|
||||||
|
def start_session():
|
||||||
|
session_id = str(random.random())
|
||||||
|
SESSIONS.append(session_id)
|
||||||
|
setcookie("session_id", session_id)
|
||||||
|
|
||||||
|
if getcookie('auto_refresh_secs') == None:
|
||||||
|
setcookie('auto_refresh_secs','10')
|
||||||
|
|
||||||
|
def do_redirect():
|
||||||
|
"""for redirects after a POST"""
|
||||||
|
vars = web.input(redir = None)
|
||||||
|
ck = cookies()
|
||||||
|
|
||||||
|
if vars.redir:
|
||||||
|
seeother(vars.redir)
|
||||||
|
elif ("order" in ck and "sort" in ck):
|
||||||
|
seeother(url("/index", sort=ck['sort'], order=ck['order']))
|
||||||
|
else:
|
||||||
|
seeother(url("/index"))
|
||||||
|
|
||||||
|
def error_page(error):
|
||||||
|
web.header("Content-Type", "text/html; charset=utf-8")
|
||||||
|
web.header("Cache-Control", "no-cache, must-revalidate")
|
||||||
|
print ws.render.error(error)
|
||||||
|
|
||||||
|
def getcookie(key, default=None):
|
||||||
|
ck = cookies()
|
||||||
|
return str(ck.get(key, default))
|
||||||
|
|
||||||
|
#deco's:
|
||||||
|
def deluge_page_noauth(func):
|
||||||
|
"""
|
||||||
|
add http headers
|
||||||
|
print result of func
|
||||||
|
"""
|
||||||
|
def deco(self, name=None):
|
||||||
|
web.header("Content-Type", "text/html; charset=utf-8")
|
||||||
|
web.header("Cache-Control", "no-cache, must-revalidate")
|
||||||
|
res = func(self, name)
|
||||||
|
print res
|
||||||
|
return deco
|
||||||
|
|
||||||
|
def check_session(func):
|
||||||
|
"""
|
||||||
|
a decorator
|
||||||
|
return func if session is valid, else redirect to login page.
|
||||||
|
"""
|
||||||
|
def deco(self, name):
|
||||||
|
vars = web.input(redir_after_login=None)
|
||||||
|
|
||||||
|
ck = cookies()
|
||||||
|
if ck.has_key("session_id") and ck["session_id"] in SESSIONS:
|
||||||
|
return func(self, name) #ok, continue..
|
||||||
|
elif vars.redir_after_login:
|
||||||
|
seeother(url("/login",redir=self_url()))
|
||||||
|
else:
|
||||||
|
seeother("/login") #do not continue, and redirect to login page
|
||||||
|
return deco
|
||||||
|
|
||||||
|
def deluge_page(func):
|
||||||
|
return check_session(deluge_page_noauth(func))
|
||||||
|
|
||||||
|
#combi-deco's:
|
||||||
|
def auto_refreshed(func):
|
||||||
|
"decorator:adds a refresh header"
|
||||||
|
def deco(self, name):
|
||||||
|
if getcookie('auto_refresh') == '1':
|
||||||
|
web.header("Refresh", "%i ; url=%s" %
|
||||||
|
(int(getcookie('auto_refresh_secs',10)),self_url()))
|
||||||
|
return func(self, name)
|
||||||
|
return deco
|
||||||
|
|
||||||
|
def remote(func):
|
||||||
|
"decorator for remote api's"
|
||||||
|
def deco(self, name):
|
||||||
|
try:
|
||||||
|
print func(self, name)
|
||||||
|
except Exception, e:
|
||||||
|
print 'error:' + e.message
|
||||||
|
print '-'*20
|
||||||
|
print traceback.format_exc()
|
||||||
|
return deco
|
||||||
|
|
||||||
|
#template-defs:
|
||||||
|
def template_crop(text, end):
|
||||||
|
if len(text) > end:
|
||||||
|
return text[0:end - 3] + '...'
|
||||||
|
return text
|
||||||
|
|
||||||
|
def template_sort_head(id,name):
|
||||||
|
#got tired of doing these complex things inside templetor..
|
||||||
|
vars = web.input(sort=None, order=None)
|
||||||
|
active_up = False
|
||||||
|
active_down = False
|
||||||
|
order = 'down'
|
||||||
|
|
||||||
|
if vars.sort == id:
|
||||||
|
if vars.order == 'down':
|
||||||
|
order = 'up'
|
||||||
|
active_down = True
|
||||||
|
else:
|
||||||
|
active_up = True
|
||||||
|
|
||||||
|
return ws.render.sort_column_head(id, name, order, active_up, active_down)
|
||||||
|
|
||||||
|
|
||||||
|
def get_config(var):
|
||||||
|
return ws.config.get(var)
|
||||||
|
|
||||||
|
template.Template.globals.update({
|
||||||
|
'sort_head': template_sort_head,
|
||||||
|
'crop': template_crop,
|
||||||
|
'_': _ , #gettext/translations
|
||||||
|
'str': str, #because % in templetor is broken.
|
||||||
|
'sorted': sorted,
|
||||||
|
'get_config': get_config,
|
||||||
|
'self_url': self_url,
|
||||||
|
'fspeed': common.fspeed,
|
||||||
|
'fsize': common.fsize,
|
||||||
|
'render': ws.render, #for easy resuse of templates
|
||||||
|
'rev': 'rev.%s' % (REVNO, ),
|
||||||
|
'version': VERSION,
|
||||||
|
'getcookie':getcookie,
|
||||||
|
'get': lambda (var): getattr(web.input(**{var:None}),var) # unreadable :-(
|
||||||
|
})
|
||||||
|
#/template-defs
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
#Some copy and paste from web.py
|
||||||
|
#mostly caused by /static
|
||||||
|
#TODO : FIX THIS.
|
||||||
|
#static-files serving should be moved to the normal webserver!
|
||||||
|
from SimpleHTTPServer import SimpleHTTPRequestHandler
|
||||||
|
from BaseHTTPServer import BaseHTTPRequestHandler
|
||||||
|
from gtk_cherrypy_wsgiserver import CherryPyWSGIServer
|
||||||
|
from BaseHTTPServer import BaseHTTPRequestHandler
|
||||||
|
|
||||||
|
from webpy022.request import webpyfunc
|
||||||
|
from webpy022 import webapi
|
||||||
|
import os
|
||||||
|
|
||||||
|
import posixpath
|
||||||
|
import urllib
|
||||||
|
import urlparse
|
||||||
|
|
||||||
|
class RelativeHandler(SimpleHTTPRequestHandler):
|
||||||
|
def translate_path(self, path):
|
||||||
|
"""Translate a /-separated PATH to the local filename syntax.
|
||||||
|
|
||||||
|
Components that mean special things to the local file system
|
||||||
|
(e.g. drive or directory names) are ignored. (XXX They should
|
||||||
|
probably be diagnosed.)
|
||||||
|
|
||||||
|
"""
|
||||||
|
# abandon query parameters
|
||||||
|
path = urlparse.urlparse(path)[2]
|
||||||
|
path = posixpath.normpath(urllib.unquote(path))
|
||||||
|
words = path.split('/')
|
||||||
|
words = filter(None, words)
|
||||||
|
path = os.path.dirname(__file__)
|
||||||
|
for word in words:
|
||||||
|
drive, word = os.path.splitdrive(word)
|
||||||
|
head, word = os.path.split(word)
|
||||||
|
if word in (os.curdir, os.pardir): continue
|
||||||
|
path = os.path.join(path, word)
|
||||||
|
return path
|
||||||
|
|
||||||
|
class StaticApp(RelativeHandler):
|
||||||
|
"""WSGI application for serving static files."""
|
||||||
|
def __init__(self, environ, start_response):
|
||||||
|
self.headers = []
|
||||||
|
self.environ = environ
|
||||||
|
self.start_response = start_response
|
||||||
|
|
||||||
|
def send_response(self, status, msg=""):
|
||||||
|
self.status = str(status) + " " + msg
|
||||||
|
|
||||||
|
def send_header(self, name, value):
|
||||||
|
self.headers.append((name, value))
|
||||||
|
|
||||||
|
def end_headers(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def log_message(*a): pass
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
environ = self.environ
|
||||||
|
|
||||||
|
self.path = environ.get('PATH_INFO', '')
|
||||||
|
self.client_address = environ.get('REMOTE_ADDR','-'), \
|
||||||
|
environ.get('REMOTE_PORT','-')
|
||||||
|
self.command = environ.get('REQUEST_METHOD', '-')
|
||||||
|
|
||||||
|
from cStringIO import StringIO
|
||||||
|
self.wfile = StringIO() # for capturing error
|
||||||
|
|
||||||
|
f = self.send_head()
|
||||||
|
self.start_response(self.status, self.headers)
|
||||||
|
|
||||||
|
if f:
|
||||||
|
block_size = 16 * 1024
|
||||||
|
while True:
|
||||||
|
buf = f.read(block_size)
|
||||||
|
if not buf:
|
||||||
|
break
|
||||||
|
yield buf
|
||||||
|
f.close()
|
||||||
|
else:
|
||||||
|
value = self.wfile.getvalue()
|
||||||
|
yield value
|
||||||
|
|
||||||
|
class WSGIWrapper(BaseHTTPRequestHandler):
|
||||||
|
"""WSGI wrapper for logging the status and serving static files."""
|
||||||
|
def __init__(self, app):
|
||||||
|
self.app = app
|
||||||
|
self.format = '%s - - [%s] "%s %s %s" - %s'
|
||||||
|
|
||||||
|
def __call__(self, environ, start_response):
|
||||||
|
def xstart_response(status, response_headers, *args):
|
||||||
|
write = start_response(status, response_headers, *args)
|
||||||
|
self.log(status, environ)
|
||||||
|
return write
|
||||||
|
|
||||||
|
path = environ.get('PATH_INFO', '')
|
||||||
|
if path.startswith('/static/'):
|
||||||
|
return StaticApp(environ, xstart_response)
|
||||||
|
else:
|
||||||
|
return self.app(environ, xstart_response)
|
||||||
|
|
||||||
|
def log(self, status, environ):
|
||||||
|
#mvoncken,no logging..
|
||||||
|
return
|
||||||
|
|
||||||
|
outfile = environ.get('wsgi.errors', web.debug)
|
||||||
|
req = environ.get('PATH_INFO', '_')
|
||||||
|
protocol = environ.get('ACTUAL_SERVER_PROTOCOL', '-')
|
||||||
|
method = environ.get('REQUEST_METHOD', '-')
|
||||||
|
host = "%s:%s" % (environ.get('REMOTE_ADDR','-'),
|
||||||
|
environ.get('REMOTE_PORT','-'))
|
||||||
|
|
||||||
|
#@@ It is really bad to extend from
|
||||||
|
#@@ BaseHTTPRequestHandler just for this method
|
||||||
|
time = self.log_date_time_string()
|
||||||
|
|
||||||
|
print >> outfile, self.format % (host, time, protocol,
|
||||||
|
method, req, status)
|
||||||
|
|
||||||
|
def create_webserver(urls,methods):
|
||||||
|
func = webapi.wsgifunc(webpyfunc(urls,methods, False))
|
||||||
|
server_address=("0.0.0.0",ws.config.get('port'))
|
||||||
|
|
||||||
|
func = WSGIWrapper(func)
|
||||||
|
server = CherryPyWSGIServer(server_address, func, server_name="localhost")
|
||||||
|
|
||||||
|
|
||||||
|
print "(created) http://%s:%d/" % server_address
|
||||||
|
|
||||||
|
return server
|
||||||
|
|
||||||
|
#------
|
||||||
|
__all__ = ['deluge_page_noauth', 'deluge_page', 'remote',
|
||||||
|
'auto_refreshed', 'check_session',
|
||||||
|
'do_redirect', 'error_page','start_session','getcookie'
|
||||||
|
,'create_webserver']
|
||||||
|
|
||||||
|
|
||||||
TORRENT_KEYS = ['distributed_copies', 'download_payload_rate',
|
|
||||||
'download_rate', 'eta', 'is_seed', 'name', 'next_announce',
|
|
||||||
'num_files', 'num_peers', 'num_pieces', 'num_seeds', 'paused',
|
|
||||||
'piece_length','progress', 'ratio', 'total_done', 'total_download',
|
|
||||||
'total_payload_download', 'total_payload_upload', 'total_peers',
|
|
||||||
'total_seeds', 'total_size', 'total_upload', 'total_wanted',
|
|
||||||
'tracker_status', 'upload_payload_rate', 'upload_rate',
|
|
||||||
'uploaded_memory','tracker','state']
|
|
||||||
|
|
||||||
STATE_MESSAGES = (_("Queued"),
|
|
||||||
_("Checking"),
|
|
||||||
_("Connecting"),
|
|
||||||
_("Downloading Metadata"),
|
|
||||||
_("Downloading"),
|
|
||||||
_("Finished"),
|
|
||||||
_("Seeding"),
|
|
||||||
_("Allocating"))
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user