2007-09-28 01:47:12 +00:00
|
|
|
#!/usr/bin/env python
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
#
|
|
|
|
# deluge_webserver.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.
|
|
|
|
|
2007-10-05 21:16:46 +00:00
|
|
|
import webserver_common as ws
|
|
|
|
from webserver_framework import *
|
|
|
|
|
|
|
|
import webpy022 as web
|
2007-09-28 01:47:12 +00:00
|
|
|
from webpy022.http import seeother, url
|
2007-10-03 02:40:30 +00:00
|
|
|
|
|
|
|
import base64
|
2007-09-28 01:47:12 +00:00
|
|
|
from operator import attrgetter
|
2007-10-28 01:35:27 +00:00
|
|
|
import os
|
2007-09-28 01:47:12 +00:00
|
|
|
|
|
|
|
#routing:
|
|
|
|
urls = (
|
2007-11-06 23:34:23 +00:00
|
|
|
"/login", "login",
|
|
|
|
"/index", "index",
|
2007-09-28 01:47:12 +00:00
|
|
|
"/torrent/info/(.*)", "torrent_info",
|
2007-11-06 23:34:23 +00:00
|
|
|
"/torrent/pause", "torrent_pause",
|
2007-10-31 03:46:36 +00:00
|
|
|
"/torrent/reannounce/(.*)", "torrent_reannounce",
|
2007-11-06 23:34:23 +00:00
|
|
|
"/torrent/add", "torrent_add",
|
2007-09-28 01:47:12 +00:00
|
|
|
"/torrent/delete/(.*)", "torrent_delete",
|
2007-10-07 04:56:01 +00:00
|
|
|
"/torrent/queue/up/(.*)", "torrent_queue_up",
|
|
|
|
"/torrent/queue/down/(.*)", "torrent_queue_down",
|
2007-10-31 03:46:36 +00:00
|
|
|
"/pause_all", "pause_all",
|
|
|
|
"/resume_all", "resume_all",
|
2007-11-06 23:34:23 +00:00
|
|
|
"/refresh/set", "refresh_set",
|
2007-09-28 01:47:12 +00:00
|
|
|
"/refresh/(.*)", "refresh",
|
2007-11-06 23:34:23 +00:00
|
|
|
"/config", "config",
|
2007-10-31 03:46:36 +00:00
|
|
|
"/home", "home",
|
|
|
|
"/about", "about",
|
|
|
|
"/logout", "logout",
|
2007-09-29 06:39:06 +00:00
|
|
|
#remote-api:
|
2007-10-28 01:35:27 +00:00
|
|
|
"/remote/torrent/add(.*)", "remote_torrent_add",
|
|
|
|
#static:
|
2007-11-06 23:34:23 +00:00
|
|
|
"/static/(.*)", "static",
|
|
|
|
"/template/static/(.*)", "template_static",
|
|
|
|
#"/downloads/(.*)","downloads" disabled until it can handle large downloads
|
2007-10-29 20:01:37 +00:00
|
|
|
#default-pages
|
2007-10-31 03:46:36 +00:00
|
|
|
"/", "home",
|
|
|
|
"", "home"
|
2007-10-28 01:35:27 +00:00
|
|
|
)
|
2007-09-28 01:47:12 +00:00
|
|
|
#/routing
|
|
|
|
|
|
|
|
#pages:
|
|
|
|
class login:
|
|
|
|
@deluge_page_noauth
|
|
|
|
def GET(self, name):
|
2007-09-29 06:39:06 +00:00
|
|
|
vars = web.input(error = None)
|
2007-10-05 21:16:46 +00:00
|
|
|
return ws.render.login(vars.error)
|
2007-09-28 01:47:12 +00:00
|
|
|
|
2007-11-06 23:34:23 +00:00
|
|
|
def POST(self):
|
|
|
|
vars = web.input(pwd = None, redir = None)
|
2007-09-28 01:47:12 +00:00
|
|
|
|
2007-10-05 21:16:46 +00:00
|
|
|
if check_pwd(vars.pwd):
|
2007-09-28 01:47:12 +00:00
|
|
|
#start new session
|
2007-10-05 21:16:46 +00:00
|
|
|
start_session()
|
2007-09-28 01:47:12 +00:00
|
|
|
do_redirect()
|
2007-09-30 08:20:14 +00:00
|
|
|
elif vars.redir:
|
2007-11-06 23:34:23 +00:00
|
|
|
seeother(url('/login', error=1, redir=vars.redir))
|
2007-09-28 01:47:12 +00:00
|
|
|
else:
|
2007-09-29 06:39:06 +00:00
|
|
|
seeother('/login?error=1')
|
2007-09-28 01:47:12 +00:00
|
|
|
|
|
|
|
class index:
|
|
|
|
"page containing the torrent list."
|
|
|
|
@deluge_page
|
2007-10-31 03:46:36 +00:00
|
|
|
@auto_refreshed
|
2007-09-28 01:47:12 +00:00
|
|
|
def GET(self, name):
|
|
|
|
vars = web.input(sort=None, order=None)
|
|
|
|
|
|
|
|
status_rows = [get_torrent_status(torrent_id)
|
2007-10-28 01:35:27 +00:00
|
|
|
for torrent_id in ws.proxy.get_session_state()]
|
2007-09-28 01:47:12 +00:00
|
|
|
|
|
|
|
#sorting:
|
|
|
|
if vars.sort:
|
|
|
|
status_rows.sort(key=attrgetter(vars.sort))
|
|
|
|
if vars.order == 'up':
|
|
|
|
status_rows = reversed(status_rows)
|
|
|
|
|
|
|
|
setcookie("order", vars.order)
|
|
|
|
setcookie("sort", vars.sort)
|
|
|
|
|
2007-10-05 21:16:46 +00:00
|
|
|
return ws.render.index(status_rows)
|
2007-09-28 01:47:12 +00:00
|
|
|
|
|
|
|
class torrent_info:
|
|
|
|
@deluge_page
|
2007-10-31 03:46:36 +00:00
|
|
|
@auto_refreshed
|
2007-09-28 01:47:12 +00:00
|
|
|
def GET(self, torrent_id):
|
2007-10-05 21:16:46 +00:00
|
|
|
return ws.render.torrent_info(get_torrent_status(torrent_id))
|
2007-09-28 01:47:12 +00:00
|
|
|
|
|
|
|
class torrent_pause:
|
|
|
|
@check_session
|
|
|
|
def POST(self, name):
|
|
|
|
vars = web.input(stop = None, start = None, redir = None)
|
|
|
|
if vars.stop:
|
2007-10-28 01:35:27 +00:00
|
|
|
ws.proxy.pause_torrent([vars.stop])
|
2007-09-28 01:47:12 +00:00
|
|
|
elif vars.start:
|
2007-10-28 01:35:27 +00:00
|
|
|
ws.proxy.resume_torrent([vars.start])
|
2007-10-31 03:46:36 +00:00
|
|
|
do_redirect()
|
2007-09-28 01:47:12 +00:00
|
|
|
|
2007-10-31 03:46:36 +00:00
|
|
|
class torrent_reannounce:
|
|
|
|
@check_session
|
|
|
|
def POST(self, torrent_id):
|
|
|
|
ws.proxy.force_reannounce([torrent_id])
|
2007-09-28 01:47:12 +00:00
|
|
|
do_redirect()
|
|
|
|
|
|
|
|
class torrent_add:
|
|
|
|
@deluge_page
|
|
|
|
def GET(self, name):
|
2007-10-05 21:16:46 +00:00
|
|
|
return ws.render.torrent_add()
|
2007-09-28 01:47:12 +00:00
|
|
|
|
|
|
|
@check_session
|
|
|
|
def POST(self, name):
|
|
|
|
vars = web.input(url = None, torrent = {})
|
|
|
|
|
|
|
|
if vars.url and vars.torrent.filename:
|
|
|
|
error_page(_("Choose an url or a torrent, not both."))
|
|
|
|
if vars.url:
|
2007-11-06 23:34:23 +00:00
|
|
|
ws.proxy.add_torrent_url(vars.url)
|
2007-09-28 01:47:12 +00:00
|
|
|
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
|
2007-11-06 23:34:23 +00:00
|
|
|
ws.proxy.add_torrent_filecontent(vars.torrent.filename, data_b64)
|
2007-09-28 01:47:12 +00:00
|
|
|
do_redirect()
|
|
|
|
else:
|
|
|
|
error_page(_("no data."))
|
|
|
|
|
2007-09-29 06:39:06 +00:00
|
|
|
class remote_torrent_add:
|
|
|
|
"""
|
|
|
|
For use in remote scripts etc.
|
2007-09-30 08:20:14 +00:00
|
|
|
POST pwd and torrent
|
2007-09-29 06:39:06 +00:00
|
|
|
"""
|
|
|
|
@remote
|
|
|
|
def POST(self, name):
|
|
|
|
vars = web.input(pwd = None, torrent = {})
|
|
|
|
|
2007-10-05 21:16:46 +00:00
|
|
|
if not check_pwd(vars.pwd):
|
2007-09-29 06:39:06 +00:00
|
|
|
return 'error:wrong password'
|
|
|
|
|
|
|
|
data_b64 = base64.b64encode(vars.torrent.file.read())
|
2007-11-06 23:34:23 +00:00
|
|
|
ws.proxy.add_torrent_filecontent(vars.torrent.filename, data_b64)
|
2007-09-29 06:39:06 +00:00
|
|
|
return 'ok'
|
|
|
|
|
2007-09-28 01:47:12 +00:00
|
|
|
class torrent_delete:
|
|
|
|
@deluge_page
|
|
|
|
def GET(self, torrent_id):
|
2007-10-05 21:16:46 +00:00
|
|
|
return ws.render.torrent_delete(get_torrent_status(torrent_id))
|
2007-09-28 01:47:12 +00:00
|
|
|
|
|
|
|
@check_session
|
2007-10-28 01:35:27 +00:00
|
|
|
def POST(self, torrent_id):
|
2007-09-28 01:47:12 +00:00
|
|
|
vars = web.input(data_also = None, torrent_also = None)
|
|
|
|
data_also = bool(vars.data_also)
|
|
|
|
torrent_also = bool(vars.torrent_also)
|
2007-10-05 21:16:46 +00:00
|
|
|
ws.proxy.remove_torrent(torrent_id, data_also, torrent_also)
|
2007-09-28 01:47:12 +00:00
|
|
|
do_redirect()
|
|
|
|
|
2007-10-07 04:56:01 +00:00
|
|
|
class torrent_queue_up:
|
|
|
|
@check_session
|
2007-10-28 01:35:27 +00:00
|
|
|
def POST(self, torrent_id):
|
2007-10-07 04:56:01 +00:00
|
|
|
ws.proxy.queue_up(torrent_id)
|
|
|
|
do_redirect()
|
|
|
|
|
|
|
|
class torrent_queue_down:
|
|
|
|
@check_session
|
2007-10-28 01:35:27 +00:00
|
|
|
def POST(self, torrent_id):
|
2007-10-07 04:56:01 +00:00
|
|
|
ws.proxy.queue_down(torrent_id)
|
|
|
|
do_redirect()
|
|
|
|
|
2007-09-28 01:47:12 +00:00
|
|
|
class pause_all:
|
|
|
|
@check_session
|
|
|
|
def POST(self, name):
|
2007-10-28 01:35:27 +00:00
|
|
|
ws.proxy.pause_torrent(ws.proxy.get_session_state())
|
2007-09-28 01:47:12 +00:00
|
|
|
do_redirect()
|
|
|
|
|
|
|
|
class resume_all:
|
|
|
|
@check_session
|
|
|
|
def POST(self, name):
|
2007-10-28 01:35:27 +00:00
|
|
|
ws.proxy.resume_torrent(ws.proxy.get_session_state())
|
2007-09-28 01:47:12 +00:00
|
|
|
do_redirect()
|
|
|
|
|
|
|
|
class refresh:
|
|
|
|
@check_session
|
|
|
|
def POST(self, name):
|
2007-11-06 23:34:23 +00:00
|
|
|
auto_refresh = {'off': '0', 'on': '1'}[name]
|
|
|
|
setcookie('auto_refresh', auto_refresh)
|
|
|
|
if not getcookie('auto_refresh_secs'):
|
|
|
|
setcookie('auto_refresh_secs', 10)
|
2007-09-28 01:47:12 +00:00
|
|
|
do_redirect()
|
|
|
|
|
|
|
|
class refresh_set:
|
|
|
|
@deluge_page
|
|
|
|
def GET(self, name):
|
2007-10-05 21:16:46 +00:00
|
|
|
return ws.render.refresh_form()
|
2007-09-28 01:47:12 +00:00
|
|
|
|
|
|
|
@check_session
|
|
|
|
def POST(self, name):
|
|
|
|
vars = web.input(refresh = 0)
|
|
|
|
refresh = int(vars.refresh)
|
|
|
|
if refresh > 0:
|
2007-11-06 23:34:23 +00:00
|
|
|
setcookie('auto_refresh', '1')
|
2007-10-05 21:16:46 +00:00
|
|
|
setcookie('auto_refresh_secs', str(refresh))
|
2007-09-28 01:47:12 +00:00
|
|
|
do_redirect()
|
|
|
|
else:
|
|
|
|
error_page(_('refresh must be > 0'))
|
|
|
|
|
2007-10-28 01:35:27 +00:00
|
|
|
class config:
|
|
|
|
"""core config
|
|
|
|
TODO:good validation.
|
|
|
|
"""
|
|
|
|
cfg_form = web.form.Form(
|
|
|
|
web.form.Dropdown('max_download', ws.SPEED_VALUES,
|
|
|
|
description=_('Download Speed Limit'),
|
|
|
|
post='%s Kib/sec' % ws.proxy.get_config_value('max_download_speed')
|
|
|
|
)
|
|
|
|
,web.form.Dropdown('max_upload', ws.SPEED_VALUES,
|
|
|
|
description=_('Upload Speed Limit'),
|
|
|
|
post='%s Kib/sec' % ws.proxy.get_config_value('max_upload_speed')
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
@deluge_page
|
|
|
|
def GET(self, name):
|
|
|
|
return ws.render.config(self.cfg_form())
|
|
|
|
|
|
|
|
def POST(self, name):
|
|
|
|
vars = web.input(max_download=None, max_upload=None)
|
|
|
|
|
|
|
|
#self.config.set("max_download_speed", float(str_bwdown))
|
|
|
|
raise NotImplementedError('todo')
|
|
|
|
|
|
|
|
class home:
|
|
|
|
@check_session
|
|
|
|
def GET(self, name):
|
|
|
|
do_redirect()
|
|
|
|
|
2007-09-29 06:39:06 +00:00
|
|
|
class about:
|
|
|
|
@deluge_page_noauth
|
|
|
|
def GET(self, name):
|
2007-10-05 21:16:46 +00:00
|
|
|
return ws.render.about()
|
2007-09-29 06:39:06 +00:00
|
|
|
|
2007-10-28 01:35:27 +00:00
|
|
|
class logout:
|
2007-11-06 23:34:23 +00:00
|
|
|
@check_session
|
2007-10-28 01:35:27 +00:00
|
|
|
def POST(self, name):
|
|
|
|
end_session()
|
|
|
|
seeother('/login')
|
|
|
|
|
|
|
|
class static(static_handler):
|
2007-11-06 23:34:23 +00:00
|
|
|
base_dir = os.path.join(os.path.dirname(__file__), 'static')
|
2007-10-03 00:05:09 +00:00
|
|
|
|
2007-10-28 01:35:27 +00:00
|
|
|
class template_static(static_handler):
|
|
|
|
def get_base_dir(self):
|
|
|
|
return os.path.join(os.path.dirname(__file__),
|
|
|
|
'templates/%s/static' % ws.config.get('template'))
|
|
|
|
|
|
|
|
class downloads(static_handler):
|
|
|
|
def GET(self, name):
|
|
|
|
self.base_dir = ws.proxy.get_config_value('default_download_path')
|
|
|
|
if not ws.config.get('share_downloads'):
|
|
|
|
raise Exception('Access to downloads is forbidden.')
|
|
|
|
return static_handler.GET(self, name)
|
|
|
|
#/pages
|
2007-10-03 02:40:30 +00:00
|
|
|
|
2007-10-05 21:16:46 +00:00
|
|
|
def WebServer():
|
|
|
|
return create_webserver(urls, globals())
|
|
|
|
|
|
|
|
def run():
|
|
|
|
server = WebServer()
|
|
|
|
try:
|
|
|
|
server.start()
|
|
|
|
except KeyboardInterrupt:
|
|
|
|
server.stop()
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
run()
|