deluge/plugins/WebUi/deluge_webserver.py

312 lines
8.6 KiB
Python

#!/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.
from webserver_common import TORRENT_KEYS, STATE_MESSAGES
import webserver_common as ws
from webserver_framework import *
import webpy022 as web
from webpy022.http import seeother, url
from webpy022.webapi import setcookie
from webpy022.utils import Storage
from md5 import md5
import base64
from deluge.common import fsize
from operator import attrgetter
#utils:
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 ws.proxy.get_torrent_status with some extra data
"""
status = ws.proxy.get_torrent_status(torrent_id,TORRENT_KEYS)
status["id"] = torrent_id
#for naming the status-images
status["calc_state_str"] = "downloading"
if status["paused"]:
status["calc_state_str"] = "inactive"
elif status["is_seed"]:
status["calc_state_str"] = "seeding"
#action for torrent_pause
if status["calc_state_str"] == "inactive":
status["action"] = "start"
else:
status["action"] = "stop"
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" : (fsize(status["total_done"])
+ " (" + fsize(status["total_download"]) + ")"),
"calc_total_uploaded": (fsize(status['uploaded_memory']
+ status["total_payload_upload"]) + " ("
+ fsize(status["total_upload"]) + ")"),
})
return Storage(status) #Storage for easy templating.
#/utils
#routing:
urls = (
"/login(.*)", "login",
"/index(.*)", "index",
"/torrent/info/(.*)", "torrent_info",
"/torrent/pause(.*)", "torrent_pause",
"/torrent/add(.*)", "torrent_add",
"/torrent/delete/(.*)", "torrent_delete",
"/torrent/queue/up/(.*)", "torrent_queue_up",
"/torrent/queue/down/(.*)", "torrent_queue_down",
"/pause_all(.*)", "pause_all",
"/resume_all(.*)", "resume_all",
"/refresh/set(.*)", "refresh_set",
"/refresh/(.*)", "refresh",
"/home(.*)", "home",
"/about(.*)", "about",
#default-pages
"/", "login",
"", "login",
#remote-api:
"/remote/torrent/add(.*)", "remote_torrent_add"
)
#/routing
#pages:
class login:
@deluge_page_noauth
def GET(self, name):
vars = web.input(error = None)
return ws.render.login(vars.error)
def POST(self, name):
vars = web.input(pwd = None ,redir = None)
if check_pwd(vars.pwd):
#start new session
start_session()
do_redirect()
elif vars.redir:
seeother(url('/login',error=1,redir=vars.redir))
else:
seeother('/login?error=1')
class home:
@check_session
def GET(self, name):
do_redirect()
class index:
"page containing the torrent list."
@auto_refreshed
@deluge_page
def GET(self, name):
vars = web.input(sort=None, order=None)
status_rows = [get_torrent_status(torrent_id)
for torrent_id in ws.proxy.get_torrent_state()]
#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)
return ws.render.index(status_rows)
class torrent_info:
"torrent details"
@auto_refreshed
@deluge_page
def GET(self, torrent_id):
return ws.render.torrent_info(get_torrent_status(torrent_id))
class torrent_pause:
"start/stop a torrent"
@check_session
def POST(self, name):
vars = web.input(stop = None, start = None, redir = None)
if vars.stop:
ws.proxy.pause_torrent(vars.stop)
elif vars.start:
ws.proxy.resume_torrent(vars.start)
do_redirect()
class torrent_add:
@deluge_page
def GET(self, name):
return ws.render.torrent_add()
@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:
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
ws.proxy.add_torrent_filecontent(vars.torrent.filename,data_b64)
do_redirect()
else:
error_page(_("no data."))
class remote_torrent_add:
"""
For use in remote scripts etc.
POST pwd and torrent
"""
@remote
def POST(self, name):
vars = web.input(pwd = None, torrent = {})
if not check_pwd(vars.pwd):
return 'error:wrong password'
data_b64 = base64.b64encode(vars.torrent.file.read())
ws.proxy.add_torrent_filecontent(vars.torrent.filename,data_b64)
return 'ok'
class torrent_delete:
@deluge_page
def GET(self, torrent_id):
return ws.render.torrent_delete(get_torrent_status(torrent_id))
@check_session
def POST(self, name):
torrent_id = name
vars = web.input(data_also = None, torrent_also = None)
data_also = bool(vars.data_also)
torrent_also = bool(vars.torrent_also)
ws.proxy.remove_torrent(torrent_id, data_also, torrent_also)
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:
@check_session
def POST(self, name):
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 ws.proxy.get_torrent_state():
ws.proxy.resume_torrent(torrent_id)
do_redirect()
class refresh:
@check_session
def POST(self, name):
auto_refresh = {'off':'0', 'on':'1'}[name]
setcookie('auto_refresh',auto_refresh)
do_redirect()
class refresh_set:
@deluge_page
def GET(self, name):
return ws.render.refresh_form()
@check_session
def POST(self, name):
vars = web.input(refresh = 0)
refresh = int(vars.refresh)
if refresh > 0:
setcookie('auto_refresh','1')
setcookie('auto_refresh_secs', str(refresh))
do_redirect()
else:
error_page(_('refresh must be > 0'))
class about:
@deluge_page_noauth
def GET(self, name):
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__":
run()