mirror of
https://git.deluge-torrent.org/deluge
synced 2025-08-04 23:48:40 +00:00
sync webui 127
This commit is contained in:
parent
047a32ef9f
commit
6b3065d2cf
14 changed files with 478 additions and 67 deletions
|
@ -47,7 +47,10 @@ Other contributors:
|
||||||
import deluge.common
|
import deluge.common
|
||||||
import deluge.pref
|
import deluge.pref
|
||||||
from deluge.dialogs import show_popup_warning
|
from deluge.dialogs import show_popup_warning
|
||||||
from dbus_interface import get_dbus_manager
|
try:
|
||||||
|
from dbus_interface import get_dbus_manager
|
||||||
|
except:
|
||||||
|
pass #for unit-test.
|
||||||
import webserver_common
|
import webserver_common
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
|
|
@ -232,6 +232,11 @@ class DbusManager(dbus.service.Object):
|
||||||
def get_upload_rate(self):
|
def get_upload_rate(self):
|
||||||
return self.core.get_state()['upload_rate']
|
return self.core.get_state()['upload_rate']
|
||||||
|
|
||||||
|
@dbus.service.method(dbus_interface=dbus_interface,
|
||||||
|
in_signature="", out_signature="v")
|
||||||
|
def get_num_connections(self):
|
||||||
|
core_state = self.core.get_state()
|
||||||
|
return core_state['num_connections']
|
||||||
|
|
||||||
#internal
|
#internal
|
||||||
def _add_torrent(self, filename):
|
def _add_torrent(self, filename):
|
||||||
|
|
|
@ -133,8 +133,11 @@ $def with (exception_type, exception_value, frames, exception_message, version_i
|
||||||
</div>
|
</div>
|
||||||
<div id="explanation">
|
<div id="explanation">
|
||||||
<p>
|
<p>
|
||||||
|
<!--ERROR-MARKER-->
|
||||||
Oops, Deluge Broke :-( , You might have found a bug, or you did something really stupid ;-).
|
Oops, Deluge Broke :-( , You might have found a bug, or you did something really stupid ;-).
|
||||||
<br />If the error persists : Try downloading the latest version at
|
<br />If the error persists :<br />
|
||||||
|
Read the <a href="http://deluge-torrent.org/faq">Faq</a>.<br />
|
||||||
|
Try downloading the latest version at
|
||||||
<a href="http://deluge-torrent.org">deluge-torrent.org</a>
|
<a href="http://deluge-torrent.org">deluge-torrent.org</a>
|
||||||
<br />Visit the <a href="http://forum.deluge-torrent.org">forum</a>
|
<br />Visit the <a href="http://forum.deluge-torrent.org">forum</a>
|
||||||
or the <a href="http://dev.deluge-torrent.org/query">buglist</a> for more info.
|
or the <a href="http://dev.deluge-torrent.org/query">buglist</a> for more info.
|
||||||
|
@ -290,7 +293,10 @@ def djangoerror():
|
||||||
exception_type, exception_value, tback = sys.exc_info()
|
exception_type, exception_value, tback = sys.exc_info()
|
||||||
|
|
||||||
exception_message = 'Error'
|
exception_message = 'Error'
|
||||||
exception_message = exception_value.message # dir(exception_value)
|
try:
|
||||||
|
exception_message = exception_value.message
|
||||||
|
except AttributeError:
|
||||||
|
exception_message = 'no message'
|
||||||
exception_type = exception_type.__name__
|
exception_type = exception_type.__name__
|
||||||
|
|
||||||
version_info = (
|
version_info = (
|
||||||
|
@ -349,8 +355,9 @@ def deluge_debugerror():
|
||||||
(Based on the beautiful 500 page from [Django](http://djangoproject.com/),
|
(Based on the beautiful 500 page from [Django](http://djangoproject.com/),
|
||||||
designed by [Wilson Miner](http://wilsonminer.com/).)
|
designed by [Wilson Miner](http://wilsonminer.com/).)
|
||||||
"""
|
"""
|
||||||
|
web.ctx.headers = [
|
||||||
web.ctx.headers = [('Content-Type', 'text/html')]
|
('Content-Type', 'text/html')
|
||||||
|
]
|
||||||
web.ctx.output = djangoerror()
|
web.ctx.output = djangoerror()
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
@ -43,29 +43,29 @@ import os
|
||||||
|
|
||||||
#routing:
|
#routing:
|
||||||
urls = (
|
urls = (
|
||||||
"/login(.*)", "login",
|
"/login", "login",
|
||||||
"/index(.*)", "index",
|
"/index", "index",
|
||||||
"/torrent/info/(.*)", "torrent_info",
|
"/torrent/info/(.*)", "torrent_info",
|
||||||
"/torrent/pause(.*)", "torrent_pause",
|
"/torrent/pause", "torrent_pause",
|
||||||
"/torrent/reannounce/(.*)", "torrent_reannounce",
|
"/torrent/reannounce/(.*)", "torrent_reannounce",
|
||||||
"/torrent/add(.*)", "torrent_add",
|
"/torrent/add", "torrent_add",
|
||||||
"/torrent/delete/(.*)", "torrent_delete",
|
"/torrent/delete/(.*)", "torrent_delete",
|
||||||
"/torrent/queue/up/(.*)", "torrent_queue_up",
|
"/torrent/queue/up/(.*)", "torrent_queue_up",
|
||||||
"/torrent/queue/down/(.*)", "torrent_queue_down",
|
"/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",
|
||||||
"/refresh/(.*)", "refresh",
|
"/refresh/(.*)", "refresh",
|
||||||
"/config","config",
|
"/config", "config",
|
||||||
"/home", "home",
|
"/home", "home",
|
||||||
"/about", "about",
|
"/about", "about",
|
||||||
"/logout", "logout",
|
"/logout", "logout",
|
||||||
#remote-api:
|
#remote-api:
|
||||||
"/remote/torrent/add(.*)", "remote_torrent_add",
|
"/remote/torrent/add(.*)", "remote_torrent_add",
|
||||||
#static:
|
#static:
|
||||||
"/static/(.*)","static",
|
"/static/(.*)", "static",
|
||||||
"/template/static/(.*)","template_static",
|
"/template/static/(.*)", "template_static",
|
||||||
#"/downloads/(.*)","downloads" disabled until it can handle large downloads.
|
#"/downloads/(.*)","downloads" disabled until it can handle large downloads
|
||||||
#default-pages
|
#default-pages
|
||||||
"/", "home",
|
"/", "home",
|
||||||
"", "home"
|
"", "home"
|
||||||
|
@ -79,15 +79,15 @@ class login:
|
||||||
vars = web.input(error = None)
|
vars = web.input(error = None)
|
||||||
return ws.render.login(vars.error)
|
return ws.render.login(vars.error)
|
||||||
|
|
||||||
def POST(self, name):
|
def POST(self):
|
||||||
vars = web.input(pwd = None ,redir = None)
|
vars = web.input(pwd = None, redir = None)
|
||||||
|
|
||||||
if check_pwd(vars.pwd):
|
if check_pwd(vars.pwd):
|
||||||
#start new session
|
#start new session
|
||||||
start_session()
|
start_session()
|
||||||
do_redirect()
|
do_redirect()
|
||||||
elif vars.redir:
|
elif vars.redir:
|
||||||
seeother(url('/login',error=1, redir=vars.redir))
|
seeother(url('/login', error=1, redir=vars.redir))
|
||||||
else:
|
else:
|
||||||
seeother('/login?error=1')
|
seeother('/login?error=1')
|
||||||
|
|
||||||
|
@ -146,13 +146,13 @@ class torrent_add:
|
||||||
if vars.url and vars.torrent.filename:
|
if vars.url and vars.torrent.filename:
|
||||||
error_page(_("Choose an url or a torrent, not both."))
|
error_page(_("Choose an url or a torrent, not both."))
|
||||||
if vars.url:
|
if vars.url:
|
||||||
ws.proxy.add_torrent_url(vars.url )
|
ws.proxy.add_torrent_url(vars.url)
|
||||||
do_redirect()
|
do_redirect()
|
||||||
elif vars.torrent.filename:
|
elif vars.torrent.filename:
|
||||||
data = vars.torrent.file.read()
|
data = vars.torrent.file.read()
|
||||||
data_b64 = base64.b64encode(data)
|
data_b64 = base64.b64encode(data)
|
||||||
#b64 because of strange bug-reports related to binary data
|
#b64 because of strange bug-reports related to binary data
|
||||||
ws.proxy.add_torrent_filecontent(vars.torrent.filename,data_b64)
|
ws.proxy.add_torrent_filecontent(vars.torrent.filename, data_b64)
|
||||||
do_redirect()
|
do_redirect()
|
||||||
else:
|
else:
|
||||||
error_page(_("no data."))
|
error_page(_("no data."))
|
||||||
|
@ -170,7 +170,7 @@ class remote_torrent_add:
|
||||||
return 'error:wrong password'
|
return 'error:wrong password'
|
||||||
|
|
||||||
data_b64 = base64.b64encode(vars.torrent.file.read())
|
data_b64 = base64.b64encode(vars.torrent.file.read())
|
||||||
ws.proxy.add_torrent_filecontent(vars.torrent.filename,data_b64)
|
ws.proxy.add_torrent_filecontent(vars.torrent.filename, data_b64)
|
||||||
return 'ok'
|
return 'ok'
|
||||||
|
|
||||||
class torrent_delete:
|
class torrent_delete:
|
||||||
|
@ -186,7 +186,6 @@ 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:
|
class torrent_queue_up:
|
||||||
@check_session
|
@check_session
|
||||||
def POST(self, torrent_id):
|
def POST(self, torrent_id):
|
||||||
|
@ -214,8 +213,10 @@ class resume_all:
|
||||||
class refresh:
|
class refresh:
|
||||||
@check_session
|
@check_session
|
||||||
def POST(self, name):
|
def POST(self, name):
|
||||||
auto_refresh = {'off':'0', 'on':'1'}[name]
|
auto_refresh = {'off': '0', 'on': '1'}[name]
|
||||||
setcookie('auto_refresh',auto_refresh)
|
setcookie('auto_refresh', auto_refresh)
|
||||||
|
if not getcookie('auto_refresh_secs'):
|
||||||
|
setcookie('auto_refresh_secs', 10)
|
||||||
do_redirect()
|
do_redirect()
|
||||||
|
|
||||||
class refresh_set:
|
class refresh_set:
|
||||||
|
@ -228,7 +229,7 @@ class refresh_set:
|
||||||
vars = web.input(refresh = 0)
|
vars = web.input(refresh = 0)
|
||||||
refresh = int(vars.refresh)
|
refresh = int(vars.refresh)
|
||||||
if refresh > 0:
|
if refresh > 0:
|
||||||
setcookie('auto_refresh','1')
|
setcookie('auto_refresh', '1')
|
||||||
setcookie('auto_refresh_secs', str(refresh))
|
setcookie('auto_refresh_secs', str(refresh))
|
||||||
do_redirect()
|
do_redirect()
|
||||||
else:
|
else:
|
||||||
|
@ -270,12 +271,13 @@ class about:
|
||||||
return ws.render.about()
|
return ws.render.about()
|
||||||
|
|
||||||
class logout:
|
class logout:
|
||||||
|
@check_session
|
||||||
def POST(self, name):
|
def POST(self, name):
|
||||||
end_session()
|
end_session()
|
||||||
seeother('/login')
|
seeother('/login')
|
||||||
|
|
||||||
class static(static_handler):
|
class static(static_handler):
|
||||||
base_dir = os.path.join(os.path.dirname(__file__),'static')
|
base_dir = os.path.join(os.path.dirname(__file__), 'static')
|
||||||
|
|
||||||
class template_static(static_handler):
|
class template_static(static_handler):
|
||||||
def get_base_dir(self):
|
def get_base_dir(self):
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
117
|
127
|
||||||
|
|
|
@ -13,8 +13,8 @@ all_strings = []
|
||||||
for filename in files:
|
for filename in files:
|
||||||
with open(filename,'r') as f:
|
with open(filename,'r') as f:
|
||||||
content = f.read()
|
content = f.read()
|
||||||
all_strings += re.findall("\$\_\(\'(.*)\'\)",content)
|
all_strings += re.findall("_\(\"(.*?)\"\)",content)
|
||||||
all_strings += re.findall("\$\_\(\"(.*)\"\)",content)
|
all_strings += re.findall("_\(\'(.*?)\'\)",content)
|
||||||
|
|
||||||
all_strings = sorted(set(all_strings))
|
all_strings = sorted(set(all_strings))
|
||||||
|
|
||||||
|
|
|
@ -1,32 +1,59 @@
|
||||||
_('# Of Files')
|
_('# Of Files')
|
||||||
_('About')
|
_('About')
|
||||||
|
_('Add Torrent')
|
||||||
|
_('Add torrent')
|
||||||
_('Apply')
|
_('Apply')
|
||||||
_('Auto refresh:')
|
_('Auto refresh:')
|
||||||
|
_('Ava')
|
||||||
_('Availability')
|
_('Availability')
|
||||||
|
_('Config')
|
||||||
|
_('Connections')
|
||||||
_('Debug:Data Dump')
|
_('Debug:Data Dump')
|
||||||
_('Delete .torrent file')
|
_('Delete .torrent file')
|
||||||
_('Delete downloaded files.')
|
_('Delete downloaded files.')
|
||||||
_('Details')
|
_('Details')
|
||||||
|
_('Disable')
|
||||||
_('Down Speed')
|
_('Down Speed')
|
||||||
|
_('Download')
|
||||||
_('Downloaded')
|
_('Downloaded')
|
||||||
_('ETA')
|
_('ETA')
|
||||||
|
_('Enable')
|
||||||
|
_('Error')
|
||||||
|
_('Eta')
|
||||||
|
_('Login')
|
||||||
|
_('Logout')
|
||||||
|
_('Name')
|
||||||
_('Next Announce')
|
_('Next Announce')
|
||||||
_('Off')
|
_('Off')
|
||||||
_('Password')
|
_('Password')
|
||||||
_('Password is invalid,try again')
|
_('Password is invalid,try again')
|
||||||
|
_('Pause all')
|
||||||
_('Peers')
|
_('Peers')
|
||||||
_('Pieces')
|
_('Pieces')
|
||||||
|
_('Progress')
|
||||||
|
_('Queue Down')
|
||||||
|
_('Queue Up')
|
||||||
|
_('Queue pos:')
|
||||||
|
_('Ratio')
|
||||||
|
_('Reannounce')
|
||||||
_('Refresh page every:')
|
_('Refresh page every:')
|
||||||
_('Remove')
|
_('Remove')
|
||||||
|
_('Remove %s ')
|
||||||
|
_('Remove %s?')
|
||||||
|
_('Resume all')
|
||||||
_('Seeders')
|
_('Seeders')
|
||||||
_('Set')
|
_('Set')
|
||||||
|
_('Set Timeout')
|
||||||
_('Share Ratio')
|
_('Share Ratio')
|
||||||
|
_('Size')
|
||||||
_('Speed')
|
_('Speed')
|
||||||
_('Submit')
|
_('Submit')
|
||||||
|
_('Torrent list')
|
||||||
_('Total Size')
|
_('Total Size')
|
||||||
_('Tracker')
|
_('Tracker')
|
||||||
_('Tracker Status')
|
_('Tracker Status')
|
||||||
_('Up Speed')
|
_('Up Speed')
|
||||||
|
_('Upload')
|
||||||
_('Upload torrent')
|
_('Upload torrent')
|
||||||
_('Uploaded')
|
_('Uploaded')
|
||||||
_('Url')
|
_('Url')
|
||||||
|
|
|
@ -25,6 +25,7 @@ $:render.header(_('About'))
|
||||||
<li>Martijn Voncken</li>
|
<li>Martijn Voncken</li>
|
||||||
<li>somedude</li>
|
<li>somedude</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h3>Deluge</h3>
|
<h3>Deluge</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Zach Tibbitts</li>
|
<li>Zach Tibbitts</li>
|
||||||
|
@ -35,6 +36,12 @@ $:render.header(_('About'))
|
||||||
<li>Andrew Resch</li>
|
<li>Andrew Resch</li>
|
||||||
<li>Alex Dedul</li>
|
<li>Alex Dedul</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<h3>Windows Port</h3>
|
||||||
|
<ul>
|
||||||
|
<li>Slurdge</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
*and all other authors/helpers/contributors I forgot to mention.
|
*and all other authors/helpers/contributors I forgot to mention.
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -16,10 +16,14 @@ $#end
|
||||||
|
|
||||||
<div class="panel" id='refresh_panel'>
|
<div class="panel" id='refresh_panel'>
|
||||||
<!--<a href='/config'>-->
|
<!--<a href='/config'>-->
|
||||||
|
|
||||||
|
$_('Connections') : $stats.num_connections ($stats.max_num_connections)
|
||||||
|
|
||||||
$_('Down Speed') : $stats.download_rate ($stats.max_download)
|
$_('Down Speed') : $stats.download_rate ($stats.max_download)
|
||||||
|
|
||||||
$_('Up Speed') : $stats.upload_rate ($stats.max_upload)
|
$_('Up Speed') : $stats.upload_rate ($stats.max_upload)
|
||||||
|
|
||||||
|
|
||||||
<!--</a>-->
|
<!--</a>-->
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@ $fspeed(torrent.download_rate)</td></td></tr>
|
||||||
<table>
|
<table>
|
||||||
|
|
||||||
<tr><td class="info_label">$_('Total Size'):</td>
|
<tr><td class="info_label">$_('Total Size'):</td>
|
||||||
<td class="info_value">$fsize(torrent.total_size)</td></tr>
|
<td class="info_value">$fspeed(torrent.total_size)</td></tr>
|
||||||
|
|
||||||
<tr><td class="info_label">$_('# Of Files'):</td>
|
<tr><td class="info_label">$_('# Of Files'):</td>
|
||||||
<td class="info_value">$torrent.num_files</td></tr>
|
<td class="info_value">$torrent.num_files</td></tr>
|
||||||
|
@ -110,7 +110,7 @@ function toggle_dump(){
|
||||||
|
|
||||||
|
|
||||||
<div class='panel'>
|
<div class='panel'>
|
||||||
Queue pos: $torrent.queue_pos
|
$_('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/up/' + str(torrent.id), _('Queue Up'), 'tango/up.png')
|
||||||
|
|
||||||
|
|
352
plugins/WebUi/tests/test_all.py
Normal file
352
plugins/WebUi/tests/test_all.py
Normal file
|
@ -0,0 +1,352 @@
|
||||||
|
"""
|
||||||
|
Testing the REST api, not the units.
|
||||||
|
unittest the right way feels so unpythonic :(
|
||||||
|
!! BIG FAT WARNING !!: this test deletes active torrents .
|
||||||
|
!! BIG FAT WARNING 2!!: this test hammers the tracker that is tested against.
|
||||||
|
"""
|
||||||
|
import unittest
|
||||||
|
import cookielib, urllib2 , urllib
|
||||||
|
import WebUi.webserver_common as ws
|
||||||
|
import operator
|
||||||
|
|
||||||
|
ws.init_05()
|
||||||
|
|
||||||
|
#CONFIG:
|
||||||
|
BASE_URL = 'http://localhost:8112'
|
||||||
|
PWD = 'deluge'
|
||||||
|
|
||||||
|
def get_status(id):
|
||||||
|
return ws.proxy.get_torrent_status(id,ws.TORRENT_KEYS)
|
||||||
|
|
||||||
|
#BASE:
|
||||||
|
#303 = see other
|
||||||
|
#404 = not found
|
||||||
|
#500 = server error
|
||||||
|
#200 = OK, page exists.
|
||||||
|
class TestWebUiBase(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
#cookie aware-opener that DOES NOT use redirects.
|
||||||
|
opener = urllib2.OpenerDirector()
|
||||||
|
self.cj = cookielib.CookieJar()
|
||||||
|
for handler in [urllib2.HTTPHandler(),urllib2.HTTPDefaultErrorHandler(),
|
||||||
|
urllib2.FileHandler(),urllib2.HTTPErrorProcessor(),
|
||||||
|
urllib2.HTTPCookieProcessor(self.cj)]:
|
||||||
|
opener.add_handler(handler)
|
||||||
|
#/opener
|
||||||
|
self.opener = opener
|
||||||
|
|
||||||
|
def open_url(self, page, post=None):
|
||||||
|
url = BASE_URL + page
|
||||||
|
if post == 1:
|
||||||
|
post = {'Force_a_post' : 'spam'}
|
||||||
|
if post:
|
||||||
|
post = urllib.urlencode(post)
|
||||||
|
r = self.opener.open(url , data = post)
|
||||||
|
|
||||||
|
|
||||||
|
#BUG: error-page does not return status 500, but status 200
|
||||||
|
#workaround...
|
||||||
|
data = r.read()
|
||||||
|
if '<!--ERROR-MARKER-->' in data:
|
||||||
|
error = IOError()
|
||||||
|
error.code = 500
|
||||||
|
#print data
|
||||||
|
raise error
|
||||||
|
if r.code <> 200:
|
||||||
|
fail('no code 200, error-code=%s' % r.code)
|
||||||
|
return r
|
||||||
|
|
||||||
|
def get_cookies(self):
|
||||||
|
return dict((c.name,c.value) for c in self.cj)
|
||||||
|
cookies = property(get_cookies)
|
||||||
|
|
||||||
|
def assert_status(self,status, page, post):
|
||||||
|
try :
|
||||||
|
r = self.open_url(page, post)
|
||||||
|
except IOError,e:
|
||||||
|
self.assertEqual(e.code, status)
|
||||||
|
else:
|
||||||
|
self.fail('page was found "%s" (%s)' % (page, r.code ))
|
||||||
|
|
||||||
|
def assert_404(self, page, post = None):
|
||||||
|
self.assert_status(404, page, post)
|
||||||
|
|
||||||
|
def assert_500(self, page, post = None):
|
||||||
|
self.assert_status(500, page, post)
|
||||||
|
|
||||||
|
def assert_303(self, page, redirect_to, post=None):
|
||||||
|
try :
|
||||||
|
r = self.open_url(page, post)
|
||||||
|
except IOError,e:
|
||||||
|
self.assertEqual(e.code, 303)
|
||||||
|
self.assertEqual(e.headers['Location'], redirect_to)
|
||||||
|
else:
|
||||||
|
#print r
|
||||||
|
self.fail('No 303!')
|
||||||
|
|
||||||
|
def assert_exists(self, page, post = None):
|
||||||
|
try :
|
||||||
|
r = self.open_url(page, post)
|
||||||
|
except IOError,e:
|
||||||
|
self.fail('page was not found "%s" (%s)' % (page, e.code))
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
|
||||||
|
class TestNoAuth(TestWebUiBase):
|
||||||
|
def test303(self):
|
||||||
|
self.assert_303('/','/login')
|
||||||
|
self.assert_303('','/login')
|
||||||
|
self.assert_303('/index','/login')
|
||||||
|
#self.assert_303('/torrent/pause/','/login')
|
||||||
|
self.assert_303('/config','/login')
|
||||||
|
self.assert_303('/torrent/info/','/login')
|
||||||
|
|
||||||
|
def test404(self):
|
||||||
|
self.assert_404('/torrent/info')
|
||||||
|
self.assert_404('/garbage')
|
||||||
|
#self.assert_404('/static/garbage')
|
||||||
|
#self.assert_404('/template/static/garbage')
|
||||||
|
self.assert_404('/torrent/pause/', post=1)
|
||||||
|
|
||||||
|
def testOpen(self):
|
||||||
|
self.assert_exists('/login')
|
||||||
|
self.assert_exists('/about')
|
||||||
|
|
||||||
|
def testStatic(self):
|
||||||
|
self.assert_exists('/static/images/simple_line.jpg')
|
||||||
|
self.assert_exists('/static/images/tango/up.png')
|
||||||
|
#test 404
|
||||||
|
|
||||||
|
#test template-static
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class TestSession(TestWebUiBase):
|
||||||
|
def testLogin(self):
|
||||||
|
self.assert_303('/home','/login')
|
||||||
|
#invalid pwd:
|
||||||
|
self.assert_303('/login','/login?error=1',{'pwd':'invalid'})
|
||||||
|
#login
|
||||||
|
self.assert_303('/login','/index',{'pwd':PWD})
|
||||||
|
#now i'm logged-in!
|
||||||
|
#there are no sort-coockies yet so the default page is /index.
|
||||||
|
self.assert_303('/home','/index')
|
||||||
|
self.assert_exists('/index')
|
||||||
|
self.assert_exists('/config')
|
||||||
|
self.assert_exists('/torrent/add')
|
||||||
|
self.assert_303('/','/index')
|
||||||
|
self.assert_303('','/index')
|
||||||
|
|
||||||
|
#logout
|
||||||
|
self.assert_303('/logout','/login', post=1)
|
||||||
|
#really logged out?
|
||||||
|
self.assert_303('/','/login')
|
||||||
|
self.assert_303('','/login')
|
||||||
|
self.assert_303('/index','/login')
|
||||||
|
self.assert_303('/torrent/add','/login')
|
||||||
|
self.assert_exists('/about')
|
||||||
|
|
||||||
|
|
||||||
|
def testRefresh(self):
|
||||||
|
#starting pos
|
||||||
|
self.assert_303('/login','/index',{'pwd':PWD})
|
||||||
|
r = self.open_url('/index')
|
||||||
|
assert not 'auto_refresh' in self.cookies
|
||||||
|
assert not 'auto_refresh_secs' in self.cookies
|
||||||
|
assert not r.headers.has_key('Refresh')
|
||||||
|
|
||||||
|
#on:
|
||||||
|
self.assert_303('/refresh/on','/index', post=1)
|
||||||
|
|
||||||
|
assert 'auto_refresh' in self.cookies
|
||||||
|
assert 'auto_refresh_secs' in self.cookies
|
||||||
|
self.assertEqual(self.cookies['auto_refresh'],'1')
|
||||||
|
self.assertEqual(self.cookies['auto_refresh_secs'],'10')
|
||||||
|
|
||||||
|
r = self.open_url('/index')
|
||||||
|
assert r.headers['Refresh'] == '10 ; url=/index'
|
||||||
|
|
||||||
|
#set:
|
||||||
|
self.assert_303('/refresh/set','/index',{'refresh':'5'})
|
||||||
|
self.assertEqual(self.cookies['auto_refresh_secs'],'5')
|
||||||
|
|
||||||
|
r = self.open_url('/index')
|
||||||
|
assert r.headers['Refresh'] == '5 ; url=/index'
|
||||||
|
self.assert_500('/refresh/set',{'refresh':'a string'})
|
||||||
|
|
||||||
|
#off:
|
||||||
|
self.assert_303('/refresh/off','/index', post=1)
|
||||||
|
self.assertEqual(self.cookies['auto_refresh'],'0')
|
||||||
|
self.assertEqual(self.cookies['auto_refresh_secs'],'5')
|
||||||
|
|
||||||
|
r = self.open_url('/index')
|
||||||
|
assert not 'Refresh' in r.headers
|
||||||
|
|
||||||
|
class TestIntegration(TestWebUiBase):
|
||||||
|
initialized = False
|
||||||
|
def setUp(self):
|
||||||
|
TestWebUiBase.setUp(self)
|
||||||
|
|
||||||
|
self.assert_303('/login','/index',{'pwd':PWD})
|
||||||
|
self.urls = sorted([
|
||||||
|
'http://torrents.aelitis.com:88/torrents/azplatform2_1.13.zip.torrent',
|
||||||
|
'http://torrents.aelitis.com:88/torrents/azplugins_2.1.4.jar.torrent',
|
||||||
|
'http://torrents.aelitis.com:88/torrents/azautoseeder_0.1.1.jar.torrent'
|
||||||
|
])
|
||||||
|
|
||||||
|
torrent_ids = ws.proxy.get_session_state()
|
||||||
|
|
||||||
|
#avoid hammering, investigate current torrent-list and do not re-add.
|
||||||
|
#correct means : 3 torrent's in list (for now)
|
||||||
|
if len(torrent_ids) <> 3:
|
||||||
|
#delete all, nice use case for refactoring delete..
|
||||||
|
torrent_ids = ws.proxy.get_session_state()
|
||||||
|
for torrent in torrent_ids:
|
||||||
|
ws.proxy.remove_torrent(torrent, False, False)
|
||||||
|
|
||||||
|
torrent_ids = ws.proxy.get_session_state()
|
||||||
|
self.assertEqual(torrent_ids, [])
|
||||||
|
|
||||||
|
#add 3 using url.
|
||||||
|
for url in self.urls:
|
||||||
|
self.assert_303('/torrent/add','/index',{'url':url,'torrent':None})
|
||||||
|
|
||||||
|
#added?
|
||||||
|
self.torrent_ids = ws.proxy.get_session_state()
|
||||||
|
self.assertEqual(len(self.torrent_ids), 3)
|
||||||
|
|
||||||
|
else:
|
||||||
|
#test correctness of existing-list
|
||||||
|
for url in self.urls:
|
||||||
|
self.assert_500('/torrent/add',{'url':url,'torrent':None})
|
||||||
|
|
||||||
|
def testPauseResume(self):
|
||||||
|
#pause all
|
||||||
|
self.assert_303('/pause_all','/index', post=1)
|
||||||
|
#pause worked?
|
||||||
|
pause_status = [get_status(id)["paused"] for id in ws.proxy.get_session_state()]
|
||||||
|
for paused in pause_status:
|
||||||
|
self.assertEqual(paused, True)
|
||||||
|
|
||||||
|
#resume all
|
||||||
|
self.assert_303('/resume_all','/index', post=1)
|
||||||
|
#resume worked?
|
||||||
|
pause_status = [get_status(id)["paused"] for id in ws.proxy.get_session_state()]
|
||||||
|
for paused in pause_status:
|
||||||
|
self.assertEqual(paused,False)
|
||||||
|
#pause again.
|
||||||
|
self.assert_303('/pause_all','/index', post=1)
|
||||||
|
|
||||||
|
torrent_id = ws.proxy.get_session_state()[0]
|
||||||
|
#single resume.
|
||||||
|
self.assert_303('/torrent/pause','/index', post={'start':torrent_id})
|
||||||
|
self.assertEqual(get_status(torrent_id)["paused"] ,False)
|
||||||
|
#single pause
|
||||||
|
self.assert_303('/torrent/pause','/index', post={'stop':torrent_id})
|
||||||
|
self.assertEqual(get_status(torrent_id)["paused"] , True)
|
||||||
|
|
||||||
|
def testQueue(self):
|
||||||
|
#find last:
|
||||||
|
torrent_id = [id for id in ws.proxy.get_session_state()
|
||||||
|
if (get_status(id)['queue_pos'] ==3 )][0]
|
||||||
|
|
||||||
|
#queue
|
||||||
|
torrent = get_status(torrent_id)
|
||||||
|
self.assertEqual(torrent['queue_pos'], 3)
|
||||||
|
#up:
|
||||||
|
self.assert_303('/torrent/queue/up/%s' % torrent_id,'/index', post=1)
|
||||||
|
torrent = get_status(torrent_id)
|
||||||
|
self.assertEqual(torrent['queue_pos'], 2)
|
||||||
|
self.assert_303('/torrent/queue/up/%s' % torrent_id,'/index', post=1)
|
||||||
|
torrent = get_status(torrent_id)
|
||||||
|
self.assertEqual(torrent['queue_pos'], 1)
|
||||||
|
self.assert_303('/torrent/queue/up/%s' % torrent_id,'/index', post=1)
|
||||||
|
#upper limit
|
||||||
|
torrent = get_status(torrent_id)
|
||||||
|
self.assertEqual(torrent['queue_pos'], 1)
|
||||||
|
#down:
|
||||||
|
self.assert_303('/torrent/queue/down/%s' % torrent_id,'/index', post=1)
|
||||||
|
torrent = get_status(torrent_id)
|
||||||
|
self.assertEqual(torrent['queue_pos'], 2)
|
||||||
|
self.assert_303('/torrent/queue/down/%s' % torrent_id,'/index', post=1)
|
||||||
|
torrent = get_status(torrent_id)
|
||||||
|
self.assertEqual(torrent['queue_pos'], 3)
|
||||||
|
self.assert_303('/torrent/queue/down/%s' % torrent_id,'/index', post=1)
|
||||||
|
#down limit
|
||||||
|
torrent = get_status(torrent_id)
|
||||||
|
self.assertEqual(torrent['queue_pos'], 3)
|
||||||
|
|
||||||
|
def testMeta(self):
|
||||||
|
#info available?
|
||||||
|
for torrent_id in ws.proxy.get_session_state():
|
||||||
|
self.assert_exists('/torrent/info/%s' % torrent_id)
|
||||||
|
self.assert_exists('/torrent/delete/%s' % torrent_id)
|
||||||
|
|
||||||
|
#no info:
|
||||||
|
self.assert_500('/torrent/info/99999999')
|
||||||
|
self.assert_500('/torrent/delete/99999999')
|
||||||
|
|
||||||
|
def testAddRemove(self):
|
||||||
|
#add a duplicate:
|
||||||
|
self.assert_500('/torrent/add', post={'url':self.urls[0],'torrent':None})
|
||||||
|
|
||||||
|
#add a 4th using url
|
||||||
|
|
||||||
|
#delete
|
||||||
|
|
||||||
|
#add torrrent-file
|
||||||
|
#./test01.torrent
|
||||||
|
|
||||||
|
def testReannounce(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def test_do_redirect(self):
|
||||||
|
self.assert_303('/home','/index')
|
||||||
|
#1
|
||||||
|
self.assert_exists('/index?sort=download_rate&order=down')
|
||||||
|
self.assert_303('/home','/index?sort=download_rate&order=down')
|
||||||
|
assert self.cookies['sort'] == 'download_rate'
|
||||||
|
assert self.cookies['order'] == 'down'
|
||||||
|
#2
|
||||||
|
self.assert_exists('/index?sort=progress&order=up')
|
||||||
|
self.assert_303('/home','/index?sort=progress&order=up')
|
||||||
|
assert self.cookies['sort'] == 'progress'
|
||||||
|
assert self.cookies['order'] == 'up'
|
||||||
|
#redir after pause-POST? in /index.
|
||||||
|
self.assert_exists('/index?sort=name&order=down')
|
||||||
|
torrent_id = ws.proxy.get_session_state()[0]
|
||||||
|
self.assert_303('/torrent/pause','/index?sort=name&order=down',
|
||||||
|
post={'stop':torrent_id})
|
||||||
|
#redir in details 1
|
||||||
|
self.assert_303('/torrent/pause?redir=/torrent/info/' + torrent_id
|
||||||
|
,'/torrent/info/' + torrent_id, post = {'stop':torrent_id})
|
||||||
|
#redir in details 2
|
||||||
|
self.assert_303('/torrent/pause'
|
||||||
|
,'/torrent/info/' + torrent_id ,
|
||||||
|
post={'stop':torrent_id,
|
||||||
|
'redir': '/torrent/info/' + torrent_id})
|
||||||
|
|
||||||
|
def testRemote(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def test_redir_after_login(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
#
|
||||||
|
|
||||||
|
if False:
|
||||||
|
suiteFew = unittest.TestSuite()
|
||||||
|
|
||||||
|
suiteFew.addTest(TestSession("testRefresh"))
|
||||||
|
|
||||||
|
unittest.TextTestRunner(verbosity=2).run(suiteFew)
|
||||||
|
|
||||||
|
elif False:
|
||||||
|
suiteFew = unittest.TestSuite()
|
||||||
|
suiteFew.addTest(TestIntegration("testDoRedirect"))
|
||||||
|
unittest.TextTestRunner(verbosity=2).run(suiteFew)
|
||||||
|
|
||||||
|
|
||||||
|
else:
|
||||||
|
unittest.main()
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
revision-id: mvoncken@gmail.com-20070930083408-sv8mo0mi1rbjnfvk
|
revision-id: mvoncken@gmail.com-20070930083408-sv8mo0mi1rbjnfvk
|
||||||
date: 2007-10-30 15:10:08 +0200
|
date: 2007-11-06 15:10:08 +0200
|
||||||
build-date: 2007-10-30 15:34:50 +0200
|
build-date: 2007-11-06 15:34:50 +0200
|
||||||
revno: 117
|
revno: 127
|
||||||
branch-nick: WebUi
|
branch-nick: WebUi
|
||||||
|
|
|
@ -152,10 +152,6 @@ SPEED_VALUES = [
|
||||||
(500, '500.0 Kib/sec')
|
(500, '500.0 Kib/sec')
|
||||||
]
|
]
|
||||||
|
|
||||||
COOKIE_DEFAULTS = {
|
|
||||||
'auto_refresh_secs':'10'
|
|
||||||
}
|
|
||||||
|
|
||||||
#try:
|
#try:
|
||||||
# SESSIONS = pickle.load(open(session_file))
|
# SESSIONS = pickle.load(open(session_file))
|
||||||
#except:
|
#except:
|
||||||
|
|
|
@ -58,7 +58,7 @@ import pickle
|
||||||
from md5 import md5
|
from md5 import md5
|
||||||
|
|
||||||
from deluge import common
|
from deluge import common
|
||||||
from webserver_common import REVNO, VERSION, COOKIE_DEFAULTS
|
from webserver_common import REVNO, VERSION
|
||||||
import webserver_common as ws
|
import webserver_common as ws
|
||||||
from debugerror import deluge_debugerror
|
from debugerror import deluge_debugerror
|
||||||
|
|
||||||
|
@ -110,13 +110,10 @@ def error_page(error):
|
||||||
web.header("Cache-Control", "no-cache, must-revalidate")
|
web.header("Cache-Control", "no-cache, must-revalidate")
|
||||||
print ws.render.error(error)
|
print ws.render.error(error)
|
||||||
|
|
||||||
def getcookie(key, default=None):
|
def getcookie(key, default = None):
|
||||||
key = str(key).strip()
|
key = str(key).strip()
|
||||||
ck = cookies()
|
ck = cookies()
|
||||||
val = ck.get(key, default)
|
return ck.get(key, default)
|
||||||
if (not val) and key in COOKIE_DEFAULTS:
|
|
||||||
return COOKIE_DEFAULTS[key]
|
|
||||||
return val
|
|
||||||
|
|
||||||
#deco's:
|
#deco's:
|
||||||
def deluge_page_noauth(func):
|
def deluge_page_noauth(func):
|
||||||
|
@ -124,7 +121,7 @@ def deluge_page_noauth(func):
|
||||||
add http headers
|
add http headers
|
||||||
print result of func
|
print result of func
|
||||||
"""
|
"""
|
||||||
def deco(self, name=None):
|
def deco(self, name = None):
|
||||||
web.header("Content-Type", "text/html; charset=utf-8")
|
web.header("Content-Type", "text/html; charset=utf-8")
|
||||||
web.header("Cache-Control", "no-cache, must-revalidate")
|
web.header("Cache-Control", "no-cache, must-revalidate")
|
||||||
res = func(self, name)
|
res = func(self, name)
|
||||||
|
@ -136,8 +133,8 @@ def check_session(func):
|
||||||
a decorator
|
a decorator
|
||||||
return func if session is valid, else redirect to login page.
|
return func if session is valid, else redirect to login page.
|
||||||
"""
|
"""
|
||||||
def deco(self, name=None):
|
def deco(self, name = None):
|
||||||
vars = web.input(redir_after_login=None)
|
vars = web.input(redir_after_login = None)
|
||||||
ck = cookies()
|
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 ws.SESSIONS:
|
||||||
return func(self, name) #ok, continue..
|
return func(self, name) #ok, continue..
|
||||||
|
@ -153,7 +150,7 @@ def deluge_page(func):
|
||||||
#combi-deco's:
|
#combi-deco's:
|
||||||
def auto_refreshed(func):
|
def auto_refreshed(func):
|
||||||
"decorator:adds a refresh header"
|
"decorator:adds a refresh header"
|
||||||
def deco(self, name=None):
|
def deco(self, name = None):
|
||||||
if getcookie('auto_refresh') == '1':
|
if getcookie('auto_refresh') == '1':
|
||||||
web.header("Refresh", "%i ; url=%s" %
|
web.header("Refresh", "%i ; url=%s" %
|
||||||
(int(getcookie('auto_refresh_secs',10)),self_url()))
|
(int(getcookie('auto_refresh_secs',10)),self_url()))
|
||||||
|
@ -162,7 +159,7 @@ def auto_refreshed(func):
|
||||||
|
|
||||||
def remote(func):
|
def remote(func):
|
||||||
"decorator for remote api's"
|
"decorator for remote api's"
|
||||||
def deco(self, name=None):
|
def deco(self, name = None):
|
||||||
try:
|
try:
|
||||||
print func(self, name)
|
print func(self, name)
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
|
@ -184,6 +181,8 @@ def get_stats():
|
||||||
'upload_rate':fspeed(ws.proxy.get_upload_rate()),
|
'upload_rate':fspeed(ws.proxy.get_upload_rate()),
|
||||||
'max_download':ws.proxy.get_config_value('max_download_speed_bps'),
|
'max_download':ws.proxy.get_config_value('max_download_speed_bps'),
|
||||||
'max_upload':ws.proxy.get_config_value('max_upload_speed_bps'),
|
'max_upload':ws.proxy.get_config_value('max_upload_speed_bps'),
|
||||||
|
'num_connections':ws.proxy.get_num_connections(),
|
||||||
|
'max_num_connections':ws.proxy.get_config_value('max_connections_global')
|
||||||
})
|
})
|
||||||
if stats.max_upload < 0:
|
if stats.max_upload < 0:
|
||||||
stats.max_upload = _("Unlimited")
|
stats.max_upload = _("Unlimited")
|
||||||
|
@ -213,33 +212,42 @@ def get_torrent_status(torrent_id):
|
||||||
status["id"] = torrent_id
|
status["id"] = torrent_id
|
||||||
|
|
||||||
#for naming the status-images
|
#for naming the status-images
|
||||||
status["calc_state_str"] = "downloading"
|
status.calc_state_str = "downloading"
|
||||||
if status["paused"]:
|
if status.paused:
|
||||||
status["calc_state_str"] = "inactive"
|
status.calc_state_str= "inactive"
|
||||||
elif status["is_seed"]:
|
elif status.is_seed:
|
||||||
status["calc_state_str"] = "seeding"
|
status.calc_state_str = "seeding"
|
||||||
|
|
||||||
#action for torrent_pause
|
#action for torrent_pause
|
||||||
if status["calc_state_str"] == "inactive":
|
if status.calc_state_str == "inactive":
|
||||||
status["action"] = "start"
|
status.action = "start"
|
||||||
else:
|
else:
|
||||||
status["action"] = "stop"
|
status.action = "stop"
|
||||||
|
|
||||||
if status["paused"]:
|
if status.paused:
|
||||||
status["message"] = _("Paused %s%%") % status['progress']
|
status.message = _("Paused %s%%") % status.progress
|
||||||
else:
|
else:
|
||||||
status["message"] = "%s %i%%" % (ws.STATE_MESSAGES[status["state"]]
|
status.message = "%s %i%%" % (ws.STATE_MESSAGES[status.state]
|
||||||
, status['progress'])
|
, status.progress)
|
||||||
|
|
||||||
#add some pre-calculated values
|
#add some pre-calculated values
|
||||||
status.update({
|
status.update({
|
||||||
"calc_total_downloaded" : (fsize(status["total_done"])
|
"calc_total_downloaded" : (fsize(status.total_done)
|
||||||
+ " (" + fsize(status["total_download"]) + ")"),
|
+ " (" + fsize(status.total_download) + ")"),
|
||||||
"calc_total_uploaded": (fsize(status['uploaded_memory']
|
"calc_total_uploaded": (fsize(status.uploaded_memory
|
||||||
+ status["total_payload_upload"]) + " ("
|
+ status.total_payload_upload) + " ("
|
||||||
+ fsize(status["total_upload"]) + ")"),
|
+ fsize(status.total_upload) + ")"),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
#no non-unicode string may enter the templates.
|
||||||
|
for k, v in status.iteritems():
|
||||||
|
if (not isinstance(v, unicode)) and isinstance(v, str):
|
||||||
|
try:
|
||||||
|
status[k] = unicode(v)
|
||||||
|
except:
|
||||||
|
raise Exception('Non Unicode for key:%s' % (k, ))
|
||||||
return status
|
return status
|
||||||
|
|
||||||
#/utils
|
#/utils
|
||||||
|
|
||||||
#template-defs:
|
#template-defs:
|
||||||
|
@ -250,7 +258,7 @@ def template_crop(text, end):
|
||||||
|
|
||||||
def template_sort_head(id,name):
|
def template_sort_head(id,name):
|
||||||
#got tired of doing these complex things inside templetor..
|
#got tired of doing these complex things inside templetor..
|
||||||
vars = web.input(sort=None, order=None)
|
vars = web.input(sort = None, order = None)
|
||||||
active_up = False
|
active_up = False
|
||||||
active_down = False
|
active_down = False
|
||||||
order = 'down'
|
order = 'down'
|
||||||
|
@ -285,7 +293,7 @@ template.Template.globals.update({
|
||||||
'rev': 'rev.%s' % (REVNO, ),
|
'rev': 'rev.%s' % (REVNO, ),
|
||||||
'version': VERSION,
|
'version': VERSION,
|
||||||
'getcookie':getcookie,
|
'getcookie':getcookie,
|
||||||
'get': lambda (var): getattr(web.input(**{var:None}),var) # unreadable :-(
|
'get': lambda (var): getattr(web.input(**{var:None}), var) # unreadable :-(
|
||||||
})
|
})
|
||||||
#/template-defs
|
#/template-defs
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue