mirror of
https://github.com/codex-storage/deluge.git
synced 2025-02-28 19:10:35 +00:00
webui-rev73
This commit is contained in:
parent
20d63448cb
commit
24fbfccfb0
@ -31,17 +31,31 @@
|
||||
plugin_name = "Web User Interface"
|
||||
plugin_author = "Martijn Voncken"
|
||||
plugin_version = "rev."
|
||||
plugin_description = "A Web based User Interface\n"
|
||||
plugin_description = """A Web based User Interface
|
||||
|
||||
Firefox greasemonkey script: http://userscripts.org/scripts/show/12639
|
||||
|
||||
Remotely add a file: "curl -F torrent=@./test1.torrent -F pwd=deluge http://localhost:8112/remote/torrent/add"
|
||||
|
||||
There is support for multiple templates, but just one is included.
|
||||
|
||||
Other contributors:
|
||||
*somedude : template enhancements.
|
||||
|
||||
"""
|
||||
|
||||
import deluge.common
|
||||
import deluge.pref
|
||||
from deluge.dialogs import show_popup_warning
|
||||
from dbus_interface import DbusManager
|
||||
from dbus_interface import get_dbus_manager
|
||||
import webserver_common
|
||||
import time
|
||||
|
||||
import gtk
|
||||
import os
|
||||
from subprocess import Popen
|
||||
from md5 import md5
|
||||
from threading import Thread
|
||||
import random
|
||||
random.seed()
|
||||
|
||||
@ -49,10 +63,6 @@ plugin_version += open(os.path.join(os.path.dirname(__file__),'revno')).read()
|
||||
plugin_description += (
|
||||
open(os.path.join(os.path.dirname(__file__),'version')).read())
|
||||
|
||||
#not found a way to stop a dbus manager.
|
||||
#global so it does not get started twice.
|
||||
dbus_manager = None
|
||||
|
||||
def deluge_init(deluge_path):
|
||||
global path
|
||||
path = deluge_path
|
||||
@ -61,15 +71,13 @@ def enable(core, interface):
|
||||
global path
|
||||
return plugin_WebUi(path, core, interface)
|
||||
|
||||
class plugin_WebUi:
|
||||
class plugin_WebUi(object):
|
||||
def __init__(self, path, deluge_core, deluge_interface):
|
||||
global dbus_manager
|
||||
self.path = path
|
||||
self.core = deluge_core
|
||||
self.interface = deluge_interface
|
||||
self.proc = None
|
||||
|
||||
|
||||
self.web_server = None
|
||||
|
||||
self.config_file = deluge.common.CONFIG_DIR + "/webui.conf"
|
||||
self.config = deluge.pref.Preferences(self.config_file, False)
|
||||
@ -98,19 +106,17 @@ class plugin_WebUi:
|
||||
if self.config.get("cache_templates") == None:
|
||||
self.config.set("cache_templates", True)
|
||||
|
||||
if self.config.get("run_in_thread") == None:
|
||||
self.config.set("run_in_thread", True)
|
||||
|
||||
if not dbus_manager:
|
||||
dbus_manager = self.dbusManager = DbusManager(deluge_core, deluge_interface
|
||||
, self.config, self.config_file)
|
||||
|
||||
self.dbus_manager = dbus_manager
|
||||
self.dbus_manager = get_dbus_manager(deluge_core, deluge_interface,
|
||||
self.config, self.config_file)
|
||||
|
||||
self.start_server()
|
||||
|
||||
def unload(self):
|
||||
print 'WebUI:unload..'
|
||||
self.kill_server()
|
||||
#self.dbusManager.
|
||||
|
||||
def update(self):
|
||||
pass
|
||||
@ -124,18 +130,38 @@ class plugin_WebUi:
|
||||
|
||||
def start_server(self):
|
||||
self.kill_server()
|
||||
print 'start Webui..'
|
||||
|
||||
if self.config.get("run_in_thread"):
|
||||
print 'start Webui(inside gtk)..'
|
||||
webserver_common.init() #reload changed config.
|
||||
from deluge_webserver import WebServer #only import in threaded mode
|
||||
|
||||
|
||||
self.web_server = WebServer()
|
||||
self.web_server.start_gtk()
|
||||
|
||||
else:
|
||||
print 'start Webui(in process)..'
|
||||
path = os.path.dirname(__file__)
|
||||
server_bin = path + '/run_webserver'
|
||||
port = str(self.config.get('port'))
|
||||
self.proc = Popen((server_bin, port),cwd=path)
|
||||
|
||||
def kill_server(self):
|
||||
if self.web_server:
|
||||
print "webserver: stop"
|
||||
self.web_server.stop_gtk()
|
||||
self.web_server = None
|
||||
if self.proc:
|
||||
print "webserver: kill %i"%self.proc.pid
|
||||
os.system("kill %i"%self.proc.pid)
|
||||
print "webserver: kill %i" % self.proc.pid
|
||||
os.system("kill %i" % self.proc.pid)
|
||||
time.sleep(1) #safe time to wait for kill to finish.
|
||||
self.proc = None
|
||||
|
||||
def __del__(self):
|
||||
self.kill_server()
|
||||
|
||||
|
||||
|
||||
class ConfigDialog(gtk.Dialog):
|
||||
"""
|
||||
@ -160,12 +186,15 @@ class ConfigDialog(gtk.Dialog):
|
||||
self.template = self.add_widget(_('Template'), gtk.combo_box_new_text())
|
||||
self.button_style = self.add_widget(_('Button Style'),
|
||||
gtk.combo_box_new_text())
|
||||
self.cache_templates = self.add_widget(_('Cache Templates'),
|
||||
gtk.CheckButton())
|
||||
self.download_dir = self.add_widget(_('Download Directory'),
|
||||
gtk.FileChooserButton(_('Download Directory')))
|
||||
self.torrent_dir = self.add_widget(_('Torrent Directory'),
|
||||
gtk.FileChooserButton(_('Torrent Directory')))
|
||||
self.cache_templates = self.add_widget(_('Cache Templates'),
|
||||
gtk.CheckButton())
|
||||
self.run_in_thread = self.add_widget(_('Run inside gtk'),
|
||||
gtk.CheckButton())
|
||||
|
||||
|
||||
self.download_dir.set_action(gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER)
|
||||
self.torrent_dir.set_action(gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER)
|
||||
@ -189,10 +218,13 @@ class ConfigDialog(gtk.Dialog):
|
||||
self.template.set_active(
|
||||
self.templates.index(self.config.get("template")))
|
||||
self.button_style.set_active(self.config.get("button_style"))
|
||||
self.cache_templates.set_active(self.config.get("cache_templates"))
|
||||
|
||||
self.torrent_dir.set_filename(self.config.get("torrent_dir"))
|
||||
self.download_dir.set_filename(self.config.get("download_dir"))
|
||||
|
||||
self.run_in_thread.set_active(self.config.get("run_in_thread"))
|
||||
self.cache_templates.set_active(self.config.get("cache_templates"))
|
||||
|
||||
self.vbox.pack_start(self.vb, True, True, 0)
|
||||
self.vb.show_all()
|
||||
|
||||
@ -226,17 +258,9 @@ class ConfigDialog(gtk.Dialog):
|
||||
self.config.set("port", int(self.port.get_value()))
|
||||
self.config.set("template", self.template.get_active_text())
|
||||
self.config.set("button_style", self.button_style.get_active())
|
||||
self.config.set("cache_templates", self.cache_templates.get_active())
|
||||
self.config.set("torrent_dir", self.torrent_dir.get_filename())
|
||||
self.config.set("download_dir",self.download_dir.get_filename())
|
||||
self.config.set("cache_templates", self.cache_templates.get_active())
|
||||
self.config.set("run_in_thread", self.run_in_thread.get_active())
|
||||
self.config.save(self.plugin.config_file)
|
||||
self.plugin.start_server() #restarts server
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -32,20 +32,25 @@
|
||||
# this exception statement from your version. If you delete this exception
|
||||
# statement from all source files in the program, then also delete it here.
|
||||
|
||||
|
||||
import os
|
||||
import gtk
|
||||
import dbus
|
||||
import deluge.common as common
|
||||
from dbus_pythonize import pythonize
|
||||
import base64
|
||||
from md5 import md5
|
||||
import random
|
||||
random.seed()
|
||||
|
||||
dbus_interface="org.deluge_torrent.dbusplugin"
|
||||
dbus_service="/org/deluge_torrent/DelugeDbusPlugin"
|
||||
|
||||
dbus_manager = None
|
||||
def get_dbus_manager(*args):
|
||||
#another way to make a singleton.
|
||||
global dbus_manager
|
||||
if not dbus_manager:
|
||||
dbus_manager = DbusManager(*args)
|
||||
return dbus_manager
|
||||
|
||||
class DbusManager(dbus.service.Object):
|
||||
def __init__(self, core, interface,config,config_file):
|
||||
@ -103,7 +108,6 @@ class DbusManager(dbus.service.Object):
|
||||
"eta": common.estimate_eta(state),
|
||||
"ratio": self.interface.manager.calc_ratio(torrent_id,state),
|
||||
#non 0.6 values follow here:
|
||||
"message": self.interface.get_message_from_state(state),
|
||||
"tracker_status": state.get("tracker_status","?"),
|
||||
"uploaded_memory": torrent.uploaded_memory,
|
||||
}
|
||||
@ -175,39 +179,6 @@ class DbusManager(dbus.service.Object):
|
||||
self._add_torrent(filename)
|
||||
return True
|
||||
|
||||
@dbus.service.method(dbus_interface=dbus_interface,
|
||||
in_signature="s",out_signature="v")
|
||||
def get_webui_config(self,key):
|
||||
"""
|
||||
return data from wevbui config.
|
||||
not in 0.6
|
||||
"""
|
||||
retval = self.config.get(str(key))
|
||||
#print 'get webui config:', str(key), retval
|
||||
if retval == None:
|
||||
retval = False #dbus does not accept None :(
|
||||
|
||||
return retval
|
||||
|
||||
@dbus.service.method(dbus_interface=dbus_interface,
|
||||
in_signature="sv",out_signature="")
|
||||
def set_webui_config(self, key, value):
|
||||
"""
|
||||
return data from wevbui config.
|
||||
not in 0.6
|
||||
"""
|
||||
#print 'set webui config:', str(key), pythonize(value)
|
||||
self.config.set(str(key), pythonize(value))
|
||||
self.config.save(self.config_file)
|
||||
|
||||
@dbus.service.method(dbus_interface=dbus_interface,
|
||||
in_signature="s",out_signature="b")
|
||||
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'))
|
||||
|
||||
#internal
|
||||
def _add_torrent(self, filename):
|
||||
#dbus types break pickle, again.....
|
||||
|
@ -31,149 +31,35 @@
|
||||
# this exception statement from your version. If you delete this exception
|
||||
# statement from all source files in the program, then also delete it here.
|
||||
|
||||
"""
|
||||
Todo's before stable:
|
||||
-__init__:kill->restart is not waiting for kill to be finished.
|
||||
--later/features:---
|
||||
-alternating rows?
|
||||
-set prio
|
||||
-clear finished?
|
||||
-torrent files.
|
||||
"""
|
||||
|
||||
from webserver_common import TORRENT_KEYS, STATE_MESSAGES
|
||||
import webserver_common as ws
|
||||
from webserver_framework import *
|
||||
|
||||
|
||||
import webpy022 as web
|
||||
|
||||
from webpy022.webapi import cookies, setcookie
|
||||
from webpy022.http import seeother, url
|
||||
from webpy022.webapi import setcookie
|
||||
from webpy022.utils import Storage
|
||||
from webpy022.net import urlquote
|
||||
from webpy022 import template, changequery as self_url
|
||||
|
||||
import dbus
|
||||
|
||||
import gettext, os, platform, locale, traceback
|
||||
import random
|
||||
from md5 import md5
|
||||
import base64
|
||||
from deluge.common import fsize
|
||||
from operator import attrgetter
|
||||
|
||||
from deluge import common
|
||||
from deluge.common import INSTALL_PREFIX
|
||||
|
||||
|
||||
#init:
|
||||
APP = 'deluge'
|
||||
DIR = os.path.join(INSTALL_PREFIX, 'share', 'locale')
|
||||
if platform.system() != "Windows":
|
||||
locale.setlocale(locale.LC_MESSAGES, '')
|
||||
locale.bindtextdomain(APP, DIR)
|
||||
locale.textdomain(APP)
|
||||
else:
|
||||
locale.setlocale(locale.LC_ALL, '')
|
||||
gettext.bindtextdomain(APP, DIR)
|
||||
gettext.textdomain(APP)
|
||||
gettext.install(APP, DIR)
|
||||
|
||||
random.seed()
|
||||
bus = dbus.SessionBus()
|
||||
proxy = bus.get_object("org.deluge_torrent.dbusplugin"
|
||||
, "/org/deluge_torrent/DelugeDbusPlugin")
|
||||
|
||||
web.webapi.internalerror = web.debugerror
|
||||
|
||||
render = template.render('templates/%s/' % proxy.get_webui_config('template')
|
||||
,cache=proxy.get_webui_config('cache_templates'))
|
||||
#/init
|
||||
|
||||
#framework:
|
||||
|
||||
SESSIONS = {}
|
||||
|
||||
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 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("/login?redir=" + urlquote(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))
|
||||
|
||||
def auto_refreshed(func):
|
||||
"decorator:adds a refresh header"
|
||||
def deco(self, name):
|
||||
if proxy.get_webui_config('auto_refresh'):
|
||||
web.header("Refresh", "%i ; url=%s" %
|
||||
(proxy.get_webui_config('auto_refresh_secs'),self_url()))
|
||||
return func(self, name)
|
||||
return deco
|
||||
|
||||
def error_page(error):
|
||||
web.header("Content-Type", "text/html; charset=utf-8")
|
||||
web.header("Cache-Control", "no-cache, must-revalidate")
|
||||
print render.error(error)
|
||||
|
||||
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
|
||||
|
||||
#/framework
|
||||
|
||||
#utils:
|
||||
torrent_keys = ['distributed_copies', 'download_payload_rate',
|
||||
'download_rate', 'eta', 'is_seed', 'message', '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']
|
||||
def check_pwd(pwd):
|
||||
m = md5()
|
||||
m.update(ws.config.get('pwd_salt'))
|
||||
m.update(pwd)
|
||||
return (m.digest() == ws.config.get('pwd_md5'))
|
||||
|
||||
def get_torrent_status(torrent_id):
|
||||
"""
|
||||
helper method.
|
||||
enhance proxy.get_torrent_status with some extra data
|
||||
enhance ws.proxy.get_torrent_status with some extra data
|
||||
"""
|
||||
status = proxy.get_torrent_status(torrent_id,torrent_keys)
|
||||
status = ws.proxy.get_torrent_status(torrent_id,TORRENT_KEYS)
|
||||
status["id"] = torrent_id
|
||||
|
||||
#for naming the status-images
|
||||
@ -189,63 +75,25 @@ def get_torrent_status(torrent_id):
|
||||
else:
|
||||
status["action"] = "stop"
|
||||
|
||||
status["message"] += str(status["state"])
|
||||
if status["paused"]:
|
||||
status["message"] = _("Paused %s%%") % status['progress']
|
||||
else:
|
||||
status["message"] = "%s %i%%" % (STATE_MESSAGES[status["state"]]
|
||||
, status['progress'])
|
||||
|
||||
#add some pre-calculated values
|
||||
status.update({
|
||||
"calc_total_downloaded" : (common.fsize(status["total_done"])
|
||||
+ " (" + common.fsize(status["total_download"]) + ")"),
|
||||
"calc_total_uploaded": (common.fsize(status['uploaded_memory']
|
||||
"calc_total_downloaded" : (fsize(status["total_done"])
|
||||
+ " (" + fsize(status["total_download"]) + ")"),
|
||||
"calc_total_uploaded": (fsize(status['uploaded_memory']
|
||||
+ status["total_payload_upload"]) + " ("
|
||||
+ common.fsize(status["total_upload"]) + ")"),
|
||||
+ fsize(status["total_upload"]) + ")"),
|
||||
})
|
||||
|
||||
return Storage(status) #Storage for easy templating.
|
||||
|
||||
#/utils
|
||||
|
||||
#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 render.sort_column_head(id, name, order, active_up, active_down)
|
||||
|
||||
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': proxy.get_webui_config,
|
||||
'self_url': self_url,
|
||||
'fspeed': common.fspeed,
|
||||
'fsize': common.fsize,
|
||||
'render': render, #for easy resuse of templates
|
||||
'button_style': (proxy.get_webui_config('button_style')),
|
||||
'rev': ('rev.' +
|
||||
open(os.path.join(os.path.dirname(__file__),'revno')).read()),
|
||||
'version': (
|
||||
open(os.path.join(os.path.dirname(__file__),'version')).read()),
|
||||
'get': lambda (var): getattr(web.input(**{var:None}),var) # unreadable :-(
|
||||
})
|
||||
#/template-defs
|
||||
|
||||
#routing:
|
||||
urls = (
|
||||
"/login(.*)", "login",
|
||||
@ -274,19 +122,17 @@ class login:
|
||||
@deluge_page_noauth
|
||||
def GET(self, name):
|
||||
vars = web.input(error = None)
|
||||
return render.login(vars.error)
|
||||
return ws.render.login(vars.error)
|
||||
|
||||
def POST(self, name):
|
||||
vars = web.input(pwd = None ,redir = None)
|
||||
|
||||
if proxy.check_pwd(vars.pwd):
|
||||
if check_pwd(vars.pwd):
|
||||
#start new session
|
||||
session_id = str(random.random())
|
||||
SESSIONS[session_id] = {"not":"used"}
|
||||
setcookie("session_id", session_id)
|
||||
start_session()
|
||||
do_redirect()
|
||||
elif vars.redir:
|
||||
seeother('/login?error=1&redir=' + urlquote(vars.redir))
|
||||
seeother(url('/login',error=1,redir=vars.redir))
|
||||
else:
|
||||
seeother('/login?error=1')
|
||||
|
||||
@ -303,7 +149,7 @@ class index:
|
||||
vars = web.input(sort=None, order=None)
|
||||
|
||||
status_rows = [get_torrent_status(torrent_id)
|
||||
for torrent_id in proxy.get_torrent_state()]
|
||||
for torrent_id in ws.proxy.get_torrent_state()]
|
||||
|
||||
#sorting:
|
||||
if vars.sort:
|
||||
@ -314,14 +160,14 @@ class index:
|
||||
setcookie("order", vars.order)
|
||||
setcookie("sort", vars.sort)
|
||||
|
||||
return render.index(status_rows)
|
||||
return ws.render.index(status_rows)
|
||||
|
||||
class torrent_info:
|
||||
"torrent details"
|
||||
@auto_refreshed
|
||||
@deluge_page
|
||||
def GET(self, torrent_id):
|
||||
return render.torrent_info(get_torrent_status(torrent_id))
|
||||
return ws.render.torrent_info(get_torrent_status(torrent_id))
|
||||
|
||||
class torrent_pause:
|
||||
"start/stop a torrent"
|
||||
@ -329,16 +175,16 @@ class torrent_pause:
|
||||
def POST(self, name):
|
||||
vars = web.input(stop = None, start = None, redir = None)
|
||||
if vars.stop:
|
||||
proxy.pause_torrent(vars.stop)
|
||||
ws.proxy.pause_torrent(vars.stop)
|
||||
elif vars.start:
|
||||
proxy.resume_torrent(vars.start)
|
||||
ws.proxy.resume_torrent(vars.start)
|
||||
|
||||
do_redirect()
|
||||
|
||||
class torrent_add:
|
||||
@deluge_page
|
||||
def GET(self, name):
|
||||
return render.torrent_add()
|
||||
return ws.render.torrent_add()
|
||||
|
||||
@check_session
|
||||
def POST(self, name):
|
||||
@ -347,13 +193,13 @@ class torrent_add:
|
||||
if vars.url and vars.torrent.filename:
|
||||
error_page(_("Choose an url or a torrent, not both."))
|
||||
if vars.url:
|
||||
proxy.add_torrent_url(vars.url)
|
||||
ws.proxy.add_torrent_url(vars.url)
|
||||
do_redirect()
|
||||
elif vars.torrent.filename:
|
||||
data = vars.torrent.file.read()
|
||||
data_b64 = base64.b64encode(data)
|
||||
#b64 because of strange bug-reports related to binary data
|
||||
proxy.add_torrent_filecontent(vars.torrent.filename,data_b64)
|
||||
ws.proxy.add_torrent_filecontent(vars.torrent.filename,data_b64)
|
||||
do_redirect()
|
||||
else:
|
||||
error_page(_("no data."))
|
||||
@ -362,23 +208,22 @@ class remote_torrent_add:
|
||||
"""
|
||||
For use in remote scripts etc.
|
||||
POST pwd and torrent
|
||||
Example : curl -F torrent=@./test1.torrent -F pwd=deluge http://localhost:8112/remote/torrent/add"
|
||||
"""
|
||||
@remote
|
||||
def POST(self, name):
|
||||
vars = web.input(pwd = None, torrent = {})
|
||||
|
||||
if not proxy.check_pwd(vars.pwd):
|
||||
if not check_pwd(vars.pwd):
|
||||
return 'error:wrong password'
|
||||
|
||||
data_b64 = base64.b64encode(vars.torrent.file.read())
|
||||
proxy.add_torrent_filecontent(vars.torrent.filename,data_b64)
|
||||
ws.proxy.add_torrent_filecontent(vars.torrent.filename,data_b64)
|
||||
return 'ok'
|
||||
|
||||
class torrent_delete:
|
||||
@deluge_page
|
||||
def GET(self, torrent_id):
|
||||
return render.torrent_delete(get_torrent_status(torrent_id))
|
||||
return ws.render.torrent_delete(get_torrent_status(torrent_id))
|
||||
|
||||
@check_session
|
||||
def POST(self, name):
|
||||
@ -386,42 +231,42 @@ class torrent_delete:
|
||||
vars = web.input(data_also = None, torrent_also = None)
|
||||
data_also = bool(vars.data_also)
|
||||
torrent_also = bool(vars.torrent_also)
|
||||
proxy.remove_torrent(torrent_id, data_also, torrent_also)
|
||||
ws.proxy.remove_torrent(torrent_id, data_also, torrent_also)
|
||||
do_redirect()
|
||||
|
||||
class pause_all:
|
||||
@check_session
|
||||
def POST(self, name):
|
||||
for torrent_id in proxy.get_torrent_state():
|
||||
proxy.pause_torrent(torrent_id)
|
||||
for torrent_id in ws.proxy.get_torrent_state():
|
||||
ws.proxy.pause_torrent(torrent_id)
|
||||
do_redirect()
|
||||
|
||||
class resume_all:
|
||||
@check_session
|
||||
def POST(self, name):
|
||||
for torrent_id in proxy.get_torrent_state():
|
||||
proxy.resume_torrent(torrent_id)
|
||||
for torrent_id in ws.proxy.get_torrent_state():
|
||||
ws.proxy.resume_torrent(torrent_id)
|
||||
do_redirect()
|
||||
|
||||
class refresh:
|
||||
@check_session
|
||||
def POST(self, name):
|
||||
auto_refresh = {'off':False, 'on':True}[name]
|
||||
proxy.set_webui_config('auto_refresh', auto_refresh)
|
||||
auto_refresh = {'off':'0', 'on':'1'}[name]
|
||||
setcookie('auto_refresh',auto_refresh)
|
||||
do_redirect()
|
||||
|
||||
class refresh_set:
|
||||
@deluge_page
|
||||
def GET(self, name):
|
||||
return render.refresh_form()
|
||||
return ws.render.refresh_form()
|
||||
|
||||
@check_session
|
||||
def POST(self, name):
|
||||
vars = web.input(refresh = 0)
|
||||
refresh = int(vars.refresh)
|
||||
if refresh > 0:
|
||||
proxy.set_webui_config('refresh', refresh)
|
||||
proxy.set_webui_config('auto_refresh', True)
|
||||
setcookie('auto_refresh','1')
|
||||
setcookie('auto_refresh_secs', str(refresh))
|
||||
do_redirect()
|
||||
else:
|
||||
error_page(_('refresh must be > 0'))
|
||||
@ -429,11 +274,21 @@ class refresh_set:
|
||||
class about:
|
||||
@deluge_page_noauth
|
||||
def GET(self, name):
|
||||
return render.about()
|
||||
return ws.render.about()
|
||||
|
||||
#/pages
|
||||
|
||||
|
||||
def WebServer():
|
||||
return create_webserver(urls, globals())
|
||||
|
||||
def run():
|
||||
server = WebServer()
|
||||
try:
|
||||
server.start()
|
||||
except KeyboardInterrupt:
|
||||
server.stop()
|
||||
|
||||
if __name__ == "__main__":
|
||||
web.run(urls, globals())
|
||||
|
||||
run()
|
||||
|
||||
|
1077
plugins/WebUi/gtk_cheerypy_wsgiserever.py
Normal file
1077
plugins/WebUi/gtk_cheerypy_wsgiserever.py
Normal file
File diff suppressed because it is too large
Load Diff
@ -3,18 +3,18 @@ $def with (method, url, title, image='')
|
||||
<form method="$method" action="$url" class="deluge_button">
|
||||
<button type="submit" class="deluge_button">
|
||||
<input type="hidden" name="redir" value="$self_url()">
|
||||
$if (button_style == 0):
|
||||
$if (get_config('button_style') == 0):
|
||||
$title
|
||||
$if image:
|
||||
<image src="/static/images/$image" class="button" alt="$title"/>
|
||||
|
||||
$if (button_style == 1):
|
||||
$if (get_config('button_style') == 1):
|
||||
$if image:
|
||||
<image src="/static/images/$image" class="button" alt="$title"/>
|
||||
$else:
|
||||
$title
|
||||
|
||||
$if (button_style == 2):
|
||||
$if (get_config('button_style') == 2):
|
||||
$title
|
||||
|
||||
</button>
|
||||
|
@ -1,8 +1,8 @@
|
||||
<div id='refresh_panel'>
|
||||
<div class="panel" >
|
||||
$_('Auto refresh:')
|
||||
$if get_config('auto_refresh'):
|
||||
($(get_config('refresh')) $_('seconds'))
|
||||
$if getcookie('auto_refresh') == '1':
|
||||
($getcookie('auto_refresh_secs')) $_('seconds'))
|
||||
$:render.part_button('GET', '/refresh/set', _('Set'), 'tango/preferences-system.png')
|
||||
$:render.part_button('POST', '/refresh/off', _('Disable'), 'tango/process-stop.png')
|
||||
$else:
|
||||
|
@ -2,7 +2,8 @@ $:render.header(_('Set Timeout'))
|
||||
<div class="panel">
|
||||
<form action="/refresh/set" method="POST">
|
||||
$_('Refresh page every:')
|
||||
<input type="text" name="refresh" value="$get_config('refresh')" size="3">
|
||||
<input type="text" name="refresh" value="$getcookie('auto_refresh_secs')"
|
||||
size="3">
|
||||
$_('seconds')
|
||||
<input type="submit" value="$_('Set')">
|
||||
</form>
|
||||
|
81
plugins/WebUi/webserver_common.py
Normal file
81
plugins/WebUi/webserver_common.py
Normal file
@ -0,0 +1,81 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# 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.
|
||||
|
||||
import os
|
||||
import deluge
|
||||
from deluge.common import INSTALL_PREFIX
|
||||
import random
|
||||
import pickle
|
||||
from webpy022 import template
|
||||
|
||||
random.seed()
|
||||
|
||||
config_file = deluge.common.CONFIG_DIR + "/webui.conf"
|
||||
|
||||
#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()
|
||||
VERSION = open(os.path.join(os.path.dirname(__file__),'version')).read()
|
||||
|
||||
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"))
|
81
plugins/WebUi/webserver_framework.py
Normal file
81
plugins/WebUi/webserver_framework.py
Normal file
@ -0,0 +1,81 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# 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.
|
||||
|
||||
import os
|
||||
import deluge
|
||||
from deluge.common import INSTALL_PREFIX
|
||||
import random
|
||||
import pickle
|
||||
from webpy022 import template
|
||||
|
||||
random.seed()
|
||||
|
||||
config_file = deluge.common.CONFIG_DIR + "/webui.conf"
|
||||
|
||||
#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()
|
||||
VERSION = open(os.path.join(os.path.dirname(__file__),'version')).read()
|
||||
|
||||
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