update webui, show error on permission failure, differentiate queued vs paused

This commit is contained in:
Marcos Pinto 2007-11-24 16:22:49 +00:00
parent ced47db339
commit cda1b3aa98
27 changed files with 977 additions and 481 deletions

View File

@ -7,7 +7,7 @@ Deluge 0.5.7 (xx November 2007)
* Add torrent in paused state option
* Add advanced progress bar
* Fix bug in merging trackers
* Various updates to WebUI by vonck7
* Various updates to WebUI, including https support and advanced template by vonck7
* Add maximum connection attempts per second preference
* Fix bug where loaded plugins were forgotten if Deluge crashed
* Fix ratio bugs (hopefully for the last time)
@ -22,6 +22,9 @@ Deluge 0.5.7 (xx November 2007)
* Add preference for the location of torrent files
* Add autoload folder
* Copy translator credits from Launchpad to our about->credits
* Differentiate between queued and paused torrents. Able to pause queued
torrents - patch by yobbobandana
* Show error when writing/permission problems occur
Deluge 0.5.6.2 (31 October 2007)
* Set default piece size to 256-KiB in TorrentCreator plugin and add 2048KiB

View File

@ -37,7 +37,9 @@ 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.
Advanced template is only tested on firefox and garanteed not to work in IE6
ssl keys are located in WebUi/ssl/
Other contributors:
*somedude : template enhancements.
@ -45,13 +47,20 @@ Other contributors:
"""
import deluge.common
import deluge.pref
from deluge.dialogs import show_popup_warning
try:
import deluge.pref
from deluge.dialogs import show_popup_warning
import webserver_common
except ImportError:
print 'WebUi:not imported as a plugin'
try:
from dbus_interface import get_dbus_manager
except:
pass #for unit-test.
import webserver_common
import time
import gtk
@ -117,6 +126,9 @@ class plugin_WebUi(object):
else:
self.config.set("run_in_thread", False)
if self.config.get("use_https") == None:
self.config.set("use_https", False)
self.dbus_manager = get_dbus_manager(deluge_core, deluge_interface,
self.config, self.config_file)
@ -167,8 +179,6 @@ class plugin_WebUi(object):
def __del__(self):
self.kill_server()
class ConfigDialog(gtk.Dialog):
"""
sorry, can't get used to gui builders.
@ -195,6 +205,9 @@ class ConfigDialog(gtk.Dialog):
gtk.combo_box_new_text())
self.cache_templates = self.add_widget(_('Cache Templates'),
gtk.CheckButton())
self.use_https = self.add_widget(_('https://'),
gtk.CheckButton())
#self.share_downloads = self.add_widget(_('Share Download Directory'),
# gtk.CheckButton())
@ -222,6 +235,7 @@ class ConfigDialog(gtk.Dialog):
# bool(self.config.get("share_downloads")))
self.cache_templates.set_active(self.config.get("cache_templates"))
self.use_https.set_active(self.config.get("use_https"))
self.vbox.pack_start(self.vb, True, True, 0)
self.vb.show_all()
@ -257,6 +271,7 @@ class ConfigDialog(gtk.Dialog):
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("use_https", self.use_https.get_active())
#self.config.set("share_downloads", self.share_downloads.get_active())
self.config.save(self.plugin.config_file)
self.plugin.start_server() #restarts server

View File

@ -95,7 +95,8 @@ class DbusManager(dbus.service.Object):
"total_size": state["total_size"],
"num_pieces": state["num_pieces"],
"state": state['state'],
"paused": self.core.is_user_paused(torrent_id),
"user_paused": self.core.is_user_paused(torrent_id),
"paused":state['is_paused'],
"progress": int(state["progress"] * 100),
"next_announce": state["next_announce"],
"total_payload_download":state["total_payload_download"],
@ -153,16 +154,22 @@ class DbusManager(dbus.service.Object):
self.core.update_tracker(torrent_id)
@dbus.service.method(dbus_interface=dbus_interface,
in_signature="sbb", out_signature="")
def remove_torrent(self, torrent_id, data_also, torrent_also):
in_signature="asbb", out_signature="")
def remove_torrent(self, torrent_ids, data_also, torrent_also):
"""remove a torrent,and optionally data and torrent
additions compared to 0.6 interface: (data_also, torrent_also)
"""
torrent_id = int(torrent_id)
self.core.remove_torrent(torrent_id, bool(data_also)
,bool( torrent_also))
#this should not be needed:
self.interface.torrent_model_remove(torrent_id)
for torrent_id in torrent_ids:
torrent_id = int(torrent_id)
self.core.remove_torrent(torrent_id, bool(data_also)
,bool( torrent_also))
#this should not be needed:
gtk.gdk.threads_enter()
try:
self.interface.torrent_model_remove(torrent_id)
except:
pass
@dbus.service.method(dbus_interface=dbus_interface,
in_signature="s", out_signature="b")
@ -174,7 +181,6 @@ class DbusManager(dbus.service.Object):
@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

View File

@ -46,9 +46,11 @@ urls = (
"/login", "login",
"/index", "index",
"/torrent/info/(.*)", "torrent_info",
"/torrent/pause", "torrent_pause",
"/torrent/info_inner/(.*)", "torrent_info_inner",
"/torrent/stop/(.*)", "torrent_stop",
"/torrent/start/(.*)", "torrent_start",
"/torrent/reannounce/(.*)", "torrent_reannounce",
"/torrent/add", "torrent_add",
"/torrent/add(.*)", "torrent_add",
"/torrent/delete/(.*)", "torrent_delete",
"/torrent/queue/up/(.*)", "torrent_queue_up",
"/torrent/queue/down/(.*)", "torrent_queue_down",
@ -96,38 +98,72 @@ class index:
@deluge_page
@auto_refreshed
def GET(self, name):
vars = web.input(sort=None, order=None)
vars = web.input(sort=None, order=None ,filter=None , category=None)
status_rows = [get_torrent_status(torrent_id)
torrent_list = [get_torrent_status(torrent_id)
for torrent_id in ws.proxy.get_session_state()]
all_torrents = torrent_list[:]
#filter-state
if vars.filter:
torrent_list = filter_torrent_state(torrent_list, vars.filter)
setcookie("filter", vars.filter)
else:
setcookie("filter", "")
#filter-cat
if vars.category:
torrent_list = [t for t in torrent_list if t.category == vars.category]
setcookie("category", vars.category)
else:
setcookie("category", "")
#sorting:
if vars.sort:
status_rows.sort(key=attrgetter(vars.sort))
torrent_list.sort(key=attrgetter(vars.sort))
if vars.order == 'up':
status_rows = reversed(status_rows)
torrent_list = reversed(torrent_list)
setcookie("order", vars.order)
setcookie("sort", vars.sort)
return ws.render.index(status_rows)
return ws.render.index(torrent_list, all_torrents)
class torrent_info:
@deluge_page
@auto_refreshed
def GET(self, torrent_id):
def GET(self, name):
torrent_id = name.split(',')[0]
return ws.render.torrent_info(get_torrent_status(torrent_id))
class torrent_pause:
class torrent_info_inner:
@deluge_page
def GET(self, torrent_ids):
torrent_ids = torrent_ids.split(',')
info = get_torrent_status(torrent_ids[0])
if len(torrent_ids) > 1:
#todo : hmm, lots of manual stuff here :(
pass
return ws.render.torrent_info_inner(info)
class torrent_start:
@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])
torrent_ids = name.split(',')
ws.proxy.resume_torrent(torrent_ids)
do_redirect()
class torrent_stop:
@check_session
def POST(self, name):
torrent_ids = name.split(',')
ws.proxy.pause_torrent(torrent_ids)
do_redirect()
class torrent_reannounce:
@check_session
def POST(self, torrent_id):
@ -175,27 +211,42 @@ class remote_torrent_add:
class torrent_delete:
@deluge_page
def GET(self, torrent_id):
return ws.render.torrent_delete(get_torrent_status(torrent_id))
def GET(self, name):
torrent_ids = name.split(',')
torrent_list = [get_torrent_status(id) for id in torrent_ids]
return ws.render.torrent_delete(name, torrent_list)
@check_session
def POST(self, torrent_id):
def POST(self, name):
torrent_ids = name.split(',')
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)
ws.proxy.remove_torrent(torrent_ids, data_also, torrent_also)
do_redirect()
class torrent_queue_up:
@check_session
def POST(self, torrent_id):
ws.proxy.queue_up(torrent_id)
def POST(self, name):
#a bit too verbose..
torrent_ids = name.split(',')
torrents = [get_torrent_status(id) for id in torrent_ids]
torrents.sort(lambda x, y : x.queue_pos - y.queue_pos)
torrent_ids = [t.id for t in torrents]
for torrent_id in torrent_ids:
ws.proxy.queue_up(torrent_id)
do_redirect()
class torrent_queue_down:
@check_session
def POST(self, torrent_id):
ws.proxy.queue_down(torrent_id)
def POST(self, name):
#a bit too verbose..
torrent_ids = name.split(',')
torrents = [get_torrent_status(id) for id in torrent_ids]
torrents.sort(lambda x, y : x.queue_pos - y.queue_pos)
torrent_ids = [t.id for t in torrents]
for torrent_id in reversed(torrent_ids):
ws.proxy.queue_down(torrent_id)
do_redirect()
class pause_all:

View File

@ -1 +1 @@
127
155

View File

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEA1sPXr1O6l2J9NAEvEYQ/JFDSVcJHh9YxP7kPdjsu7k9Ih845
BHMX52A3Ypbe5MHe2bCj/8dRYCixRdF1KUTAKXdzc7mw9prgf3sS3RvmfcRsln6u
x7XRg7YprZJ46hFmcHiUPRgtTFLuFO2YWBnqxu/caTtAxx3PdoK6LDVnuVjHYofC
8uD4A9k6yL/jj3Yrkf8WYQqJ6pJcMAz/2c8ZXlBuiUCb9j5xKTzYoJaiUkKN2YrA
hoxRxfI7Zc7MH2yWw8/fTZJbGXo8nrfek7coSE7yQS1M6ciwkYk5VO2mBVJBJgAT
QUR/jGfLzEqNKXghQ564v9wmuFmUMd99a0tkVwIDAQABAoIBACID6sluLYOEqefu
uBHCLG4IDwheOQ4esrYxDW3gedJs5EP+ObGmuQaAisUmuC7rNeysuYzteMoOJ+Wz
AyeCKB1pOfP+WTT12tDWIWq73InW7ov3jJ89AO4nj/pZ1KTeFKeDsZbrmWEZUXQn
HZX2pOTVYMeaBuyCoDVZBzuxSbhlON4wS6ClMhem+eBOxg351CDTZa2cbq7Ffcos
VP7LY2ORQYNDTQSLguV/dJrFSotB8Eoz2xIpg5XR7msp6lzPzyAd+Aoz/T1lYxCY
IFZCJYKnIpgoYQvmtUlhQrdD8P0J4Kth7I8NgkWvXCKazQjhpUm+wojLKD0G7Kcz
9znIV+ECgYEA+qfp1C8jWbaAn1yAeORUA9aB6aGIURfOpZjnCvtMWM0Nu0nAJYDv
X7L5GRa1ulfKhfUG1Jv/ynMKXYuBUDhyccYLpP7BHpd29Arr7YAgb52KaD1PoKNa
Z45c61dj4sFoCmJEbDoL21UGb0LX3mc4XzPzwWs8AKfLW4aZh1NwCisCgYEA21gJ
Hy3egBgMT9+nVjqsgtIXgJOnzQRhvRwT7IFf392ZyFi8iM+pDUsx1yj0zSG4XNPw
NY8VtZuTBUlG73RKcrrz31jhCMfLCnoRkQeweZv0QWzbLU3V8DleUYdjFc/t0me5
4NBR9lBlwYHgyU3GQ814vum+m0IAH0Ng1UxAVIUCgYAFOHwZTEYLN07kgtO2MOND
FTOtfwzMy5clQdMGGofTjanMjdOvtEjIEH05tYxhbjSsp5bV1M32FIFRw3cVCafw
kLRrYlb5YSQ8HwIc9z81s+1PEH/ZE63tXDy5Nh/BeE/Hb5aHPopCrjmtFZJTcojt
CrL4A1jDlrsYk+wcsnMx8wKBgEhJJQhvd2pDgps4G8+hGoUqc7Bd+OjpzsQh4rcI
k+4U+7847zkvJolJBK3hw3tu53FAL2OXOhJVqQgO9B+p9XcGAaTTh6X7IgDb5bok
DJanPMHq+/hcNGssnNbFhXQEyF2U7X8XaEuCh2ZURR5SUUq7BlX0dmp4P84NyHXC
4Vh5AoGAZYWkXxQUGzVm+H3fPpmETWGRNFDTimzi+6N+/uHkqkiDa3LGSnabmKh+
voKm//DUjEVGlAZ3CGOjO/5SlZc/zjkgh1vg7KOU4x7DqVOuZjom5Tx3ZI4xVVVt
tVtvK0qjzUTVcwAQALN/PNak+gs9534e954rmA9kmc3xBe4ho9M=
-----END RSA PRIVATE KEY-----

View File

@ -0,0 +1,22 @@
-----BEGIN CERTIFICATE-----
MIIDlzCCAn+gAwIBAgIJAPnW/GEzRy8xMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNV
BAYTAkFVMRUwEwYDVQQIEwxUaGUgSW50ZXJuZXQxFTATBgNVBAoTDERlbHVnZSBX
ZWJ1aTAeFw0wNzExMjQxMDAzNDRaFw0wODExMjMxMDAzNDRaMDsxCzAJBgNVBAYT
AkFVMRUwEwYDVQQIEwxUaGUgSW50ZXJuZXQxFTATBgNVBAoTDERlbHVnZSBXZWJ1
aTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANbD169TupdifTQBLxGE
PyRQ0lXCR4fWMT+5D3Y7Lu5PSIfOOQRzF+dgN2KW3uTB3tmwo//HUWAosUXRdSlE
wCl3c3O5sPaa4H97Et0b5n3EbJZ+rse10YO2Ka2SeOoRZnB4lD0YLUxS7hTtmFgZ
6sbv3Gk7QMcdz3aCuiw1Z7lYx2KHwvLg+APZOsi/4492K5H/FmEKieqSXDAM/9nP
GV5QbolAm/Y+cSk82KCWolJCjdmKwIaMUcXyO2XOzB9slsPP302SWxl6PJ633pO3
KEhO8kEtTOnIsJGJOVTtpgVSQSYAE0FEf4xny8xKjSl4IUOeuL/cJrhZlDHffWtL
ZFcCAwEAAaOBnTCBmjAdBgNVHQ4EFgQU1BbX1/4WtAKRKmWI1gqryIoj7BQwawYD
VR0jBGQwYoAU1BbX1/4WtAKRKmWI1gqryIoj7BShP6Q9MDsxCzAJBgNVBAYTAkFV
MRUwEwYDVQQIEwxUaGUgSW50ZXJuZXQxFTATBgNVBAoTDERlbHVnZSBXZWJ1aYIJ
APnW/GEzRy8xMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAEoiSz5x
hRCplxUG34g3F5yJe0QboqzJ/XmECfO80a980C/WVeivM2Kb1uafsKNp+WK7wD8g
mei+todYXG+fD8WmG41LG87Xi2Xe4SlAcemEpGcC5F1bpCdvqnVAWFnqoF88FOHx
NDlrq5H5lhMH9wVrX9qJvxL+StaDJ0sFk4kMGWEN+bdSYfFdBQzF903nPtm+PlvO
1Uo6gCuRTMYM5J1DC/GpNpo/Fzrkgm8mMf1MYy3rljiNgMt2rnxhtwi6jugwyMui
id6Of6gYAtvhi7kmaUpdI5PHO35dqRK7pHXH+YXaulosCPw/+bSRptFTykeEMrBj
CzotqJ+74MwXZyM=
-----END CERTIFICATE-----

Binary file not shown.

After

Width:  |  Height:  |  Size: 498 B

View File

@ -4,7 +4,10 @@
div.progress_bar_outer { /*used in table-view*/
width:150px;
}
td.progress_bar { white-space: nowrap; } td.info_label { font-weight: bold; } td { font-size: 10pt; color: #d1dae5; white-space: nowrap; } tr { font-size: 10pt; color: #d1dae5; }
td.progress_bar { white-space: nowrap; } td.info_label { font-weight: bold; } td { font-size: 10pt; color: #d1dae5; white-space: nowrap; } tr {
font-size: 10pt;
color: #d1dae5;
}
div.panel {
padding:10px;
@ -26,11 +29,16 @@ form.deluge_button {
}
button.deluge_button {
background-color: #37506f;
border:1px solid #23344b;
border:1px solid #68a;
background: #99acc3;
color: #000;
vertical-align:middle;
-moz-border-radius:7px;
}
button.deluge_button:hover {
background-color:#68a;
}
div.error {
background-color:#FFFFFF;
color:#AA0000;
@ -42,4 +50,42 @@ div.error {
}
/* Hides from IE-mac \*/ * html .clearfix {height: 1%;} .clearfix {display: block;} /* End hide from IE-mac */
/*tr.torrent_table:hover {
background-color:#68a;
}*/
tr.torrent_table_selected {
background-color:#900;
}
img.button {
margin-bottom:0px;
padding:0px;
position:relative;
top:2px;
}
body.inner {
background:none;
}
form.pause_resume {
margin:0;
padding:0;
border:0;
}
th {
background: #1f3044;
font-size: 14px;
border: 0px;
white-space: nowrap;
}
#torrent_table {
border: #2a425c 1px solid;
}
/* Hides from IE-mac \*/ * html .clearfix {height: 1%;} .clearfix {display: block;} /* End hide from IE-mac */

View File

@ -1,14 +1,49 @@
$def with (torrent_list)
$def with (torrent_list, all_torrents)
$:render.header(_('Torrent list'))
<div class="panel" id="toolbar">
<a href='/torrent/add' >[Add]</a>
<a href='#' onclick=' toolbar_post("/torrent/queue/up/")'>[Up]</a>
<a href='#' onclick=' toolbar_post("/torrent/queue/down/")'>[Down]</a>
<a href='#' onclick=' toolbar_get("/torrent/delete/")'>[Delete]</a>
<a href='#' onclick=' toolbar_get("/torrent/info/")'>[Info]</a>
<a href='#' onclick=' toolbar_post("/torrent/stop/")'>[Pause]</a>
<a href='#' onclick=' toolbar_post("/torrent/start/")'>[Start]</a>
<a class='toolbar_btn' href="#"
onclick='toolbar_get("/torrent/add/")'
title='$_("Add")'><img class='toolbar_btn'
src='/static/images/tango/list-add.png'></a>
<a class='toolbar_btn' href="#"
onclick='toolbar_get("/torrent/delete/")'><img class='toolbar_btn'
src='/static/images/tango/list-remove.png'
title='$_("Remove")'></a>
<a class='toolbar_btn' href="#"
onclick='toolbar_post("/torrent/stop/")'
title='$_("Pause")'><img class='toolbar_btn'
src='/static/images/tango/pause.png'
></a>
<a class='toolbar_btn' href="#"
onclick='toolbar_post("/torrent/start/")'
title='$_("Start")'><img class='toolbar_btn'
src='/static/images/tango/start.png'></a>
<a class='toolbar_btn' href="#"
onclick='toolbar_post("/torrent/queue/up/")'
title='$_("Up")'><img class='toolbar_btn'
src='/static/images/tango/queue-up.png'></a>
<a class='toolbar_btn' href="#"
onclick='toolbar_post("/torrent/queue/down/")'
title='$_("Down")'><img class='toolbar_btn'
src='/static/images/tango/queue-down.png'></a>
<a class='toolbar_btn' href="#"
onclick='toolbar_get("/torrent/info/")'
title='$_("Details")'><img class='toolbar_btn'
src='/static/images/tango/details.png'></a>
$:category_tabs(all_torrents)
</div>
<!--
@ -21,10 +56,10 @@ $#end
-->
<form action="/torrent/pause" method="POST">
<div id="tableContainer" class="tableContainer">
<table class="torrent_list" border=1>
<table class="torrent_list" border=1 id="torrent_list">
<thead class="fixedHeader">
<tr>
$:(sort_head('calc_state_str', 'S'))
@ -45,11 +80,14 @@ $#end
$#4-space indentation is mandatory for for-loops in templetor!
$for torrent in torrent_list:
<tr class="torrent_table" onclick="on_click_row(event, '$torrent.id')" id="torrent_$torrent.id">
<td><input type="image"
src="/static/images/$(torrent.calc_state_str)16.png"
name="$torrent.action" value="$torrent.id"
onclick="state.row_js_continue = false;">
</td>
<td>
<form action="/torrent/$torrent.action/$torrent.id" method="POST"
class="pause_resume">
<input type="image"
src="/static/images/$(torrent.calc_state_str)16.png"
name="pauseresume" value="submit" />
</form>
</td>
<td>$torrent.queue_pos</td>
<td style="width:100px; overflow:hidden;white-space: nowrap">
$(crop(torrent.name, 40))</td>
@ -63,8 +101,18 @@ $for torrent in torrent_list:
</td>
<td>$torrent.num_seeds ($torrent.total_seeds)</td>
<td>$torrent.num_peers ($torrent.total_peers)</td>
<td>$fspeed(torrent.download_rate)</td>
<td>$fspeed(torrent.upload_rate)</td>
<td>
$if (torrent.download_rate):
$fspeed(torrent.download_rate)
$else:
&nbsp;
</td>
<td>
$if (torrent.upload_rate):
$fspeed(torrent.upload_rate)
$else:
&nbsp;
</td>
<td>$torrent.eta</td>
<td>$("%.3f" % torrent.distributed_copies)</td>
<td>$("%.3f" % torrent.ratio)</td\>
@ -73,7 +121,6 @@ $for torrent in torrent_list:
</table>
</div>
</form>
$:part_stats()
@ -84,6 +131,8 @@ $:part_stats()
</iframe>
</div>
<br />
<script language='javascript'>

View File

@ -0,0 +1,30 @@
$def with (filter_tabs, category_tabs)
<form method="GET" id="category_form" style="display:inline;position:relative;top:-5px;padding-left:50px;>
<input type="hidden" name="sort" value="$get('sort')">
<input type="hidden" name="order" value="$get('order')">
<select name='filter' id='filter'
onchange="document.getElementById('category_form').submit()">
$for tab in filter_tabs:
<option value="$tab.filter"
$if tab.filter == get('filter'):
selected
>
$tab.title
</option>
</select>
<select name='category' id='category'
onchange="document.getElementById('category_form').submit()">
$for tab in category_tabs:
<option value="$tab.category"
$if tab.category == get('category'):
selected
>
$tab.title
</option>
</select>
</form>

View File

@ -8,7 +8,7 @@ td {font-family: Bitstream Vera;} /* STRUCTURE */ #page { min-width: 800px;
margin: 0;
padding:0; } #simple_logo { background:url(../../static/images/simple_logo.jpg) no-repeat; } #main {
margin: 0;
padding:0; padding-top: 20px; color: #fff; } #main form table { border: #2a425c 1px solid; } #main form table tr { border: 0px; } #main form table tr th { background: #1f3044; font-size: 16px; border: 0px;
padding:0; padding-top: 6px; color: #fff; } #main form table { border: #2a425c 1px solid; } #main form table tr { border: 0px; } #main form table tr th { background: #1f3044; font-size: 16px; border: 0px;
white-space: nowrap; } #main form table tr td{ border: 0px; color: #fff; font-size: 12px; white-space: nowrap; } #main form table tr th a { color: #8fa6c3; font-size: 16px; white-space: nowrap; } #main form table tr th a, a:active, a:visited { color: #8fa6c3; text-decoration: none; } #main form table tr th a:hover {color: #fff; text-decoration: underline;} #main form table tr td a { color: #fff; font-size: 12px; white-space: nowrap; } #main form table tr td a, a:active, a:visited { color: #fff; text-decoration: none;} #main form table tr td a:hover {color: #fff; text-decoration: underline;} #main a { color: #fff; font-size: 12px; } #main a, a:active, a:visited { color: #fff; text-decoration: none;} #main a:hover {color: #fff; text-decoration: underline;} .info { text-align: right; padding: 0 50px 0 0; color: #8fa6c3; font-size: 16px; letter-spacing: 4px; font-weight: bold; } .title { color: #dce4ee; font-size: 32px; padding: 10px 50px 0 0; text-align: right; } .title a, a:active, a:visited { color: #dce4ee; text-decoration: none;} .title a:hover {color: #fff; text-decoration: underline;} #button { border:1px solid #23344b; background: #99acc3; color: #000;
font-family: Bitstream Vera; font-size:10px; margin-top:5px; } INPUT{ border:1px solid #23344b; background: #99acc3; color: #000; } TEXTAREA{ border:1px solid #23344b; background: #99acc3; width:480px; } .footertext a { color: #c0c0c0; text-decoration:none;} .footertext a:visited { color: #c0c0c0; text-decoration:none;} .footertext a:active { color: #c0c0c0; text-decoration:none;} .footertext a:hover {color: #fff; text-decoration: underline;} .footertext { text-align: center; padding: 60px 0 0 0; font-size: 8pt; left: -100px; font-family: Bitstream Vera; color: #fff; position: relative; } .clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } div.progress_bar{ background-color:#4573a5; /*color:blue;*/ -moz-border-radius:5px; /*ff only setting*/ }
@ -92,6 +92,12 @@ body.inner {
padding:0;
text-align:left;
height:20px;
background-color:#ddd;
color:#000;
border-style:solid;
border:0;
border-top:1px;
border-color:#000;
}
#about {
@ -110,15 +116,18 @@ body.inner {
#refresh_panel {
-moz-border-radius:0px;
width:100%;
width:350px;
position:fixed;
bottom:20px;
left:0px;
bottom:0px;
right:0px;
background-color:#304663;
margin: 0;
padding:0;
text-align:right;
height:20px;
background-color:#ddd;
color:#000;
z-index:999;
}
#refresh_panel button {
@ -128,9 +137,68 @@ body.inner {
position:relative;
top:0px;
height:20px;
background-color:#ddd;
color:#000;
}
#refresh_panel button:hover {
text-decoration: underline;
}
/* Hides from IE-mac \*/ * html .clearfix {height: 1%;} .clearfix {display: block;} /* End hide from IE-mac */
#category_panel {
margin-bottom:0;
padding-bottom:0;
-moz-border-radius-bottomleft:0px;
-moz-border-radius-bottomright:0px;
padding-right:32px;
}
#toolbar {
text-align:left;
margin-top:0;
padding-top:0;
margin-bottom: 30px;
-moz-border-radius-topleft:0px;
-moz-border-radius-topright:0px;
padding-top:5px;
padding-bottom:5px;
margin-bottom: 15px;
padding-left:32px;
height:16px;
}
#toolbar select{
/*border:1px solid #68a;*/
border:0;
background-color: #37506f;
color: #FFF;
}
#toolbar select:hover{
background-color:#68a;
}
a.toolbar_btn {
width:20px;
height:20px;
padding-left:3px;
padding-top:7px;
padding-right:3px;
text-decoration: none;
}
a.toolbar_btn:hover {
background-color:#68a;
-moz-border-radius:5px;
text-decoration: none;
}
form { /*all forms!*/
margin:0;
padding:0;
border:0;
}
#torrent_list {
-moz-border-radius:7px;
}
/* Hides from IE-mac \*/ * html .clearfix {height: 1%;} .clearfix {display: block;} /* End hide from IE-mac */

View File

@ -29,10 +29,17 @@ function on_click_row(e,id) {
function on_click_row_js(e, id) {
/*real onClick event*/
if (!e.ctrlKey) {
deselect_rows();
deselect_all_rows();
select_row(id);
open_inner_details(id);
}
else if (state.selected_rows.indexOf(id) != -1) {
deselect_row(id);
}
else{
select_row(id);
open_inner_details(id);
}
select_row(id);
open_inner_details(id);
}
function select_row(id){
@ -43,19 +50,30 @@ function select_row(id){
setCookie('selected_rows',state.selected_rows);
}
}
function deselect_rows(){
for (i in state.selected_rows) {
deselect_row(state.selected_rows[i]);
}
state.selected_rows = new Array();
}
function deselect_row(id){
var row = get_row(id);
if (row) {
row.className = 'torrent_table'
/*TODO : remove from state.selected_rows*/
/*remove from state.selected_rows*/
var idx = state.selected_rows.indexOf(id);
state.selected_rows.splice(idx,1);
setCookie('selected_rows',state.selected_rows);
}
}
function deselect_all_rows(){
/*unbind state.selected_rows from for..in:
there must be a better way to do this*/
var a = new Array()
for (i in state.selected_rows) {
a[a.length] = state.selected_rows[i];
}
for (i in a){
deselect_row(a[i]);
}
}
function reselect_rows(){
var selected_rows = getCookie('selected_rows').split(',');
for (i in getCookie('selected_rows')) {

View File

@ -1,8 +1,7 @@
$def with (torrent_list)
$def with (torrent_list, all_torrents)
$:render.header(_('Torrent list'))
<form action="/torrent/pause" method="POST">
<table class="torrent_list" border=1>
<table class="torrent_list" border=0 id='torrent_table'>
<tr>
$:(sort_head('calc_state_str', 'S'))
$:(sort_head('queue_pos', '#'))
@ -19,14 +18,16 @@ $:render.header(_('Torrent list'))
</tr>
$#4-space indentation is mandatory for for-loops in templetor!
$for torrent in torrent_list:
<tr>
<td><input type="image"
src="/static/images/$(torrent.calc_state_str)16.png"
name="$torrent.action" value="$torrent.id">
</td>
<tr class="torrent_table" id="torrent_$torrent.id">
<td>
<form action="/torrent/$torrent.action/$torrent.id" method="POST" class="pause_resume">
<input type="image"
src="/static/images/$(torrent.calc_state_str)16.png"
name="pauseresume" value="submit" /></form></td>
<td>$torrent.queue_pos</td>
<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 class="progress_bar">
<div class="progress_bar_outer">
@ -45,12 +46,12 @@ $for torrent in torrent_list:
</tr>
</table>
</form>
<div class="panel">
$:render.part_button('GET', '/torrent/add', _('Add torrent'), 'tango/list-add.png')
$:render.part_button('POST', '/pause_all', _('Pause all'), 'tango/media-playback-pause.png')
$:render.part_button('POST', '/resume_all', _('Resume all'), 'tango/media-playback-start.png')
$:render.part_button('POST', '/pause_all', _('Pause all'), 'tango/pause.png')
$:render.part_button('POST', '/resume_all', _('Resume all'), 'tango/start.png')
<!--$:render.part_button('POST', '/logout', _('Logout'), 'tango/system-log-out.png')-->
</div>

View File

@ -14,7 +14,7 @@ $else:
$#end
</div>
<div class="panel" id='refresh_panel'>
<div class="panel" id='stats_panel'>
<!--<a href='/config'>-->
$_('Connections') : $stats.num_connections ($stats.max_num_connections)
@ -26,8 +26,9 @@ $#end
<!--</a>-->
(<a href='/about'>$_('About')</a>)
<span id=#about>
(<a href='/about'>$_('About')</a>)
</span>
</div>

View File

@ -1,6 +1,6 @@
$def with (column_id, column_name, order, active_up, active_down)
<th>
<a href="/index?sort=$column_id&order=$order">
<th class="torrent_table">
<a href="/index?sort=$column_id&order=$order&filter=$get('filter')&category=$get('category')">
$column_name\
$if active_up:
<img src="/static/images/tango/up.png" />

View File

@ -0,0 +1,85 @@
$def with (torrent)
<table width="100%"><tr>
<td colspan=3 style="background-color:#999;-moz-border-radius:5px;">
<div class="progress_bar" style="width:$torrent.progress%;
text-align:center;font-weight:bold;">
$torrent.progress %</div>
</td>
</tr><td width=30%%>
<table>
<tr><td class="info_label">$_('Downloaded'):</td>
<td class="info_value">$torrent.calc_total_downloaded</td></tr>
<tr><td class="info_label">$_('Uploaded'):</td>
<td class="info_value">$torrent.calc_total_uploaded</td>
</tr>
<tr><td class="info_label">$_('Seeders'):</td>
<td class="info_value">$torrent.num_seeds ($torrent.total_seeds )</td></tr>
<tr><td class="info_label">$_('Share Ratio'):</td>
<td class="info_value">$("%.3f" % torrent.ratio)</td></tr>
<tr><td class="info_label">$_('Pieces'):</td>
<td class="info_value">$torrent.num_pieces x $fsize(torrent.piece_length) </td>
</tr>
<tr><td class="info_label">&nbsp;</td>
<td class="info_value">&nbsp; </td>
</table>
</td><td width=30%%>
<table>
<tr><td class="info_label">$_('Speed'):</td><td class="info_value">
$fspeed(torrent.download_rate)</td></td></tr>
<tr><td class="info_label">$_('Speed'):</td>
<td class="info_value">$fspeed(torrent.upload_rate)</td></tr>
<tr><td class="info_label">$_('Peers'):</td>
<td class="info_value">$torrent.num_peers ($torrent.total_peers )</td></tr>
<tr><td class="info_label">$_('ETA'):</td>
<td class="info_value">$torrent.eta </td></tr>
<tr><td class="info_label">$_('Availability'):</td>
<td class="info_value">$("%.3f" % torrent.distributed_copies)</td></td></tr>
<tr><td class="info_label">&nbsp;</td>
<td class="info_value">&nbsp; </td>
</tr>
</table>
</td><td width=30%%>
<table>
<tr><td class="info_label">$_('Total Size'):</td>
<td class="info_value">$fspeed(torrent.total_size)</td></tr>
<tr><td class="info_label">$_('# Of Files'):</td>
<td class="info_value">$torrent.num_files</td></tr>
<tr><td class="info_label">$_('Tracker'):</td>
<td class="info_value">$(crop(torrent.tracker, 30))</td></tr>
<tr><td class="info_label">$_('Tracker Status'):</td>
<td class="info_value">$torrent.tracker_status </td></tr>
<tr><td class="info_label">$_('Next Announce'):</td>
<td class="info_value">$torrent.next_announce </td></tr>
<tr><td class="info_label">$_('Queue Position'):</td>
<td class="info_value">$torrent.queue_pos </td>
</tr>
</table>
</table>

View File

@ -1,10 +1,15 @@
$def with (torrent)
$:render.header(_("Remove %s ") % torrent.name)
$def with (torrent_ids, torrent_list)
$:render.header(_("Remove torrent"))
<div class="panel">
<form method="POST" action='/torrent/delete/$torrent.id'>
<form method="POST" action='/torrent/delete/$torrent_ids'>
<div id="del_torrent">
$(_("Remove %s?") % torrent.name)
<h2>$_("Remove torrent")</h2>
<ul>
$for torrent in torrent_list:
<li>$torrent.name</li>
</ul>
<div class="form_row2">
<span class="form_label2">
<input type="checkbox" name="torrent_also" class="form_input" checked

View File

@ -1,88 +1,23 @@
$def with (torrent)
$:(render.header(torrent.message + '/' + torrent.name))
<div class="panel">
<h3>$_('Details')</h3>
<table width="100%"><tr>
<td colspan=3 style="background-color:#999;-moz-border-radius:5px;">
<div class="progress_bar" style="width:$torrent.progress%;
text-align:center;font-weight:bold;">
$:render.tab_meta(torrent)
$torrent.progress %</div>
</td>
</tr><td width=30%%>
<table>
$if (torrent.action == 'start'):
$:render.part_button('POST', '/torrent/start/' + str(torrent.id), _('Resume'), 'tango/start.png')
$else:
$:render.part_button('POST', '/torrent/stop/' + str(torrent.id), _('Pause'), 'tango/pause.png')
<tr><td class="info_label">$_('Downloaded'):</td>
<td class="info_value">$torrent.calc_total_downloaded</td></tr>
<tr><td class="info_label">$_('Uploaded'):</td>
<td class="info_value">$torrent.calc_total_uploaded</td>
</tr>
<tr><td class="info_label">$_('Seeders'):</td>
<td class="info_value">$torrent.num_seeds ($torrent.total_seeds )</td></tr>
<tr><td class="info_label">$_('Share Ratio'):</td>
<td class="info_value">$("%.3f" % torrent.ratio)</td></tr>
<tr><td class="info_label">$_('Pieces'):</td>
<td class="info_value">$torrent.num_pieces x $fsize(torrent.piece_length) </td>
</tr>
</table>
</td><td width=30%%>
<table>
<tr><td class="info_label">$_('Speed'):</td><td class="info_value">
$fspeed(torrent.download_rate)</td></td></tr>
<tr><td class="info_label">$_('Speed'):</td>
<td class="info_value">$fspeed(torrent.upload_rate)</td></tr>
<tr><td class="info_label">$_('Peers'):</td>
<td class="info_value">$torrent.num_peers ($torrent.total_peers )</td></tr>
<tr><td class="info_label">$_('ETA'):</td>
<td class="info_value">$torrent.eta </td></tr>
<tr><td class="info_label">$_('Availability'):</td>
<td class="info_value">$("%.3f" % torrent.distributed_copies)</td></td></tr>
</table>
</td><td width=30%%>
<table>
<tr><td class="info_label">$_('Total Size'):</td>
<td class="info_value">$fspeed(torrent.total_size)</td></tr>
<tr><td class="info_label">$_('# Of Files'):</td>
<td class="info_value">$torrent.num_files</td></tr>
<tr><td class="info_label">$_('Tracker'):</td>
<td class="info_value">$(crop(torrent.tracker, 30))</td></tr>
<tr><td class="info_label">$_('Tracker Status'):</td>
<td class="info_value">$torrent.tracker_status </td></tr>
<tr><td class="info_label">$_('Next Announce'):</td>
<td class="info_value">$torrent.next_announce </td></tr>
</table>
</table>
<form action="/torrent/pause?redir=/torrent/info/$torrent.id" method="POST"
class="deluge_button">
<input type="image" src="/static/images/$(torrent.calc_state_str)16.png"
name="$torrent.action" value="$torrent.id">
</form>
$: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/list-remove.png')
$:render.part_button('POST', '/torrent/reannounce/' + str(torrent.id), _('Reannounce'), 'tango/view-refresh.png')
$:render.part_button('POST', '/torrent/queue/up/' + str(torrent.id), _('Queue Up'), 'tango/queue-up.png')
$:render.part_button('POST', '/torrent/queue/down/' + str(torrent.id), _('Queue Down'), 'tango/queue-down.png')
<br>
<!--
[<a onclick="javascript:toggle_dump()">$_('Debug:Data Dump')</a>]
@ -109,13 +44,6 @@ function toggle_dump(){
<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>
$:part_stats()

View File

@ -3,28 +3,35 @@ Just copy and rename an existing template.
-The settings panel will see all directory's in this folder ,and let you choose your new template.
-Clicking Ok in the settings panel will restart the webserver and reload your template.
Limited "Subclassing":
All templates are "subclassed" from the /deluge/ template.
If a html file is not found in the template dir, the file from /deluge/ will be used.
Notes:
Please configure your editor to use 4-space indents instead of tabs.
Or use scite and my config: http://mvoncken.sohosted.com/deluge/SciTEUser.properties.txt
template language: http://webpy.org/templetor
Exposed methods and variables (c&p from deluge_webserver):
Exposed methods and variables (c&p from webserver_framework.py):
template.Template.globals.update({
'sort_head': template_sort_head,
'part_stats':template_part_stats,
'crop': template_crop,
'_': _ , #gettext/translations
'str': str, #because % in templetor is broken.
'sorted': sorted,
'get_config': proxy.get_webui_config,
'self_url': web.changequery,
'get_config': get_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())
'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 :-(
})
I will update this file if there is interest in making templates.

View File

@ -9,7 +9,11 @@ import cookielib, urllib2 , urllib
import WebUi.webserver_common as ws
import operator
ws.init_05()
print 'test-env=',ws.ENV
#CONFIG:
BASE_URL = 'http://localhost:8112'
@ -37,6 +41,7 @@ class TestWebUiBase(unittest.TestCase):
def open_url(self, page, post=None):
url = BASE_URL + page
if post == 1:
post = {'Force_a_post' : 'spam'}
if post:
@ -92,6 +97,10 @@ class TestWebUiBase(unittest.TestCase):
else:
pass
first_torrent_id = property(lambda self: ws.proxy.get_session_state()[0])
first_torrent = property(lambda self: get_status(self.first_torrent_id))
class TestNoAuth(TestWebUiBase):
def test303(self):
self.assert_303('/','/login')
@ -202,7 +211,7 @@ class TestIntegration(TestWebUiBase):
#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)
ws.proxy.remove_torrent([torrent], False, False)
torrent_ids = ws.proxy.get_session_state()
self.assertEqual(torrent_ids, [])
@ -217,33 +226,37 @@ class TestIntegration(TestWebUiBase):
else:
#test correctness of existing-list
#The setup makes 0.6 fail everything, added an else..
for url in self.urls:
self.assert_500('/torrent/add',{'url':url,'torrent':None})
if ws.ENV.startswith('0.5'):
self.assert_500('/torrent/add',{'url':url,'torrent':None})
else:
self.assert_303('/torrent/add','/index',{'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()]
pause_status = [get_status(id)["user_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()]
pause_status = [get_status(id)["user_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]
torrent_id = self.first_torrent_id
#single resume.
self.assert_303('/torrent/pause','/index', post={'start':torrent_id})
self.assertEqual(get_status(torrent_id)["paused"] ,False)
self.assert_303('/torrent/start/%s' % torrent_id ,'/index', post=1)
self.assertEqual(get_status(torrent_id)["user_paused"] ,False)
#single pause
self.assert_303('/torrent/pause','/index', post={'stop':torrent_id})
self.assertEqual(get_status(torrent_id)["paused"] , True)
self.assert_303('/torrent/stop/%s' % torrent_id,'/index', post=1)
self.assertEqual(get_status(torrent_id)["user_paused"] , True)
def testQueue(self):
#find last:
@ -297,8 +310,6 @@ class TestIntegration(TestWebUiBase):
#add torrrent-file
#./test01.torrent
def testReannounce(self):
pass
def test_do_redirect(self):
self.assert_303('/home','/index')
@ -314,17 +325,16 @@ class TestIntegration(TestWebUiBase):
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})
torrent_id = self.first_torrent_id
self.assert_303('/torrent/stop/%s' % torrent_id,
'/index?sort=name&order=down', post=1)
#redir in details 1
self.assert_303('/torrent/pause?redir=/torrent/info/' + torrent_id
,'/torrent/info/' + torrent_id, post = {'stop':torrent_id})
self.assert_303('/torrent/stop/%s?redir=/torrent/info/%s' %(torrent_id,torrent_id)
,'/torrent/info/' + torrent_id, post = 1)
#redir in details 2
self.assert_303('/torrent/pause'
self.assert_303('/torrent/stop/%s' % torrent_id
,'/torrent/info/' + torrent_id ,
post={'stop':torrent_id,
'redir': '/torrent/info/' + torrent_id})
post={'redir': '/torrent/info/' + torrent_id})
def testRemote(self):
pass
@ -332,6 +342,26 @@ class TestIntegration(TestWebUiBase):
def test_redir_after_login(self):
pass
def testReannounce(self):
torrent_id = self.first_torrent_id
self.assert_303(
'/torrent/reannounce/%(id)s?redir=/torrent/info/%(id)s'
% {'id':torrent_id}
,'/torrent/info/' + torrent_id, post = 1)
def testRecheck(self):
#add test before writing code..
#RELEASE-->disable
"""
torrent_id = self.first_torrent_id
self.assert_303(
'/torrent/recheck/%(id)s?redir=/torrent/info/%(id)s'
% {'id':torrent_id}
,'/torrent/info/' + torrent_id, post = 1)
"""
#
if False:

View File

@ -1,5 +1,5 @@
revision-id: mvoncken@gmail.com-20070930083408-sv8mo0mi1rbjnfvk
date: 2007-11-06 15:10:08 +0200
build-date: 2007-11-06 15:34:50 +0200
revno: 127
revno: 155
branch-nick: WebUi

View File

@ -42,7 +42,9 @@ import pickle
import sys
from webpy022 import template
random.seed()
path = os.path.dirname(__file__)
webui_path = os.path.dirname(__file__)
ENV = 'UNKNOWN'
try:
_('translate something')
@ -66,11 +68,11 @@ class subclassed_render(object):
"""
def __init__(self, template_dirname, cache=False):
self.base_template = template.render(
os.path.join(path, 'templates/deluge/'),
os.path.join(webui_path, 'templates/deluge/'),
cache=cache)
self.sub_template = template.render(
os.path.join(path, 'templates/%s/' % template_dirname),
os.path.join(webui_path, 'templates/%s/' % template_dirname),
cache=cache)
def __getattr__(self, attr):
@ -90,6 +92,7 @@ def init_06():
init_process()
globals()['proxy'] = proxy
globals()['ENV'] = '0.6'
def init_05():
import dbus
@ -98,6 +101,7 @@ def init_05():
proxy = bus.get_object("org.deluge_torrent.dbusplugin"
, "/org/deluge_torrent/DelugeDbusPlugin")
globals()['proxy'] = proxy
globals()['ENV'] = '0.5_process'
def init_gtk_05():
#appy possibly changed config-vars, only called in when runing inside gtk.
@ -106,12 +110,16 @@ def init_gtk_05():
globals()['config'] = deluge.pref.Preferences(config_file, False)
globals()['render'] = subclassed_render(config.get('template'),
config.get('cache_templates'))
globals()['ENV'] = '0.5_gtk'
#hacks to determine environment, TODO: clean up.
if 'env=0.5' in sys.argv:
init_05()
elif not hasattr(deluge, 'common'):
elif 'env=0.6' in sys.argv:
init_06()
elif hasattr(deluge, 'ui'):
init_06()
elif not hasattr(deluge,'pref'):
init_05()
@ -128,7 +136,7 @@ TORRENT_KEYS = ['distributed_copies', 'download_payload_rate',
'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','queue_pos']
'uploaded_memory','tracker','state','queue_pos','user_paused']
STATE_MESSAGES = (_("Queued"),
_("Checking"),

View File

@ -56,6 +56,7 @@ from operator import attrgetter
import datetime
import pickle
from md5 import md5
from urlparse import urlparse
from deluge import common
from webserver_common import REVNO, VERSION
@ -97,13 +98,20 @@ def do_redirect():
"""for redirects after a POST"""
vars = web.input(redir = None)
ck = cookies()
url_vars = {}
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"))
return
#todo:cleanup
if ("order" in ck and "sort" in ck):
url_vars.update({'sort':ck['sort'] ,'order':ck['order'] })
if ("filter" in ck) and ck['filter']:
url_vars['filter'] = ck['filter']
if ("category" in ck) and ck['category']:
url_vars['category'] = ck['category']
seeother(url("/index", **url_vars))
def error_page(error):
web.header("Content-Type", "text/html; charset=utf-8")
@ -211,6 +219,12 @@ def get_torrent_status(torrent_id):
status["id"] = torrent_id
url = urlparse(status.tracker)
if hasattr(url,'hostname'):
status.category = url.hostname
else:
status.category = 'No-tracker'
#for naming the status-images
status.calc_state_str = "downloading"
if status.paused:
@ -219,13 +233,15 @@ def get_torrent_status(torrent_id):
status.calc_state_str = "seeding"
#action for torrent_pause
if status.calc_state_str == "inactive":
if status.user_paused:
status.action = "start"
else:
status.action = "stop"
if status.paused:
if status.user_paused:
status.message = _("Paused %s%%") % status.progress
elif status.paused:
status.message = _("Queued %s%%") % status.progress
else:
status.message = "%s %i%%" % (ws.STATE_MESSAGES[status.state]
, status.progress)
@ -248,9 +264,59 @@ def get_torrent_status(torrent_id):
raise Exception('Non Unicode for key:%s' % (k, ))
return status
def get_categories(torrent_list):
trackers = [torrent['category'] for torrent in torrent_list]
categories = {}
for tracker in trackers:
categories[tracker] = categories.get(tracker,0) + 1
return categories
def filter_torrent_state(torrent_list,filter_name):
filters = {
'downloading': lambda t: (not t.paused and not t.is_seed)
,'queued':lambda t: (t.paused and not t.user_paused)
,'paused':lambda t: (t.user_paused)
,'seeding':lambda t:(t.is_seed and not t.paused )
}
filter_func = filters[filter_name]
return [t for t in torrent_list if filter_func(t)]
#/utils
#template-defs:
def category_tabs(torrent_list):
categories = get_categories(torrent_list)
filter_tabs = [Storage(title='All (%s)' % len(torrent_list),
filter=None, category=None)]
#static filters
for title, filter_name in [
(_('Downloading'),'downloading') ,
(_('Queued'),'queued') ,
(_('Paused'),'paused') ,
(_('Seeding'),'seeding')
]:
title += ' (%s)' % (
len(filter_torrent_state(torrent_list, filter_name)), )
filter_tabs.append(Storage(title=title, filter=filter_name))
categories = [x for x in get_categories(torrent_list).iteritems()]
categories.sort()
#trackers:
category_tabs = []
category_tabs.append(
Storage(title=_('Trackers'),category=None))
for title,count in categories:
category = title
title += ' (%s)' % (count, )
category_tabs.append(Storage(title=title, category=category))
return ws.render.part_categories(filter_tabs, category_tabs)
def template_crop(text, end):
if len(text) > end:
return text[0:end - 3] + '...'
@ -281,6 +347,7 @@ def get_config(var):
template.Template.globals.update({
'sort_head': template_sort_head,
'part_stats':template_part_stats,
'category_tabs':category_tabs,
'crop': template_crop,
'_': _ , #gettext/translations
'str': str, #because % in templetor is broken.
@ -301,10 +368,16 @@ def create_webserver(urls, methods):
from webpy022.request import webpyfunc
from webpy022 import webapi
from gtk_cherrypy_wsgiserver import CherryPyWSGIServer
import os
func = webapi.wsgifunc(webpyfunc(urls, methods, False))
server_address=("0.0.0.0", int(ws.config.get('port')))
server = CherryPyWSGIServer(server_address, func, server_name="localhost")
if ws.config.get('use_https'):
server.ssl_certificate = os.path.join(ws.webui_path,'ssl/deluge.pem')
server.ssl_private_key = os.path.join(ws.webui_path,'ssl/deluge.key')
print "http://%s:%d/" % server_address
return server
@ -313,4 +386,5 @@ __all__ = ['deluge_page_noauth', 'deluge_page', 'remote',
'auto_refreshed', 'check_session',
'do_redirect', 'error_page','start_session','getcookie'
,'setcookie','create_webserver','end_session',
'get_torrent_status', 'check_pwd','static_handler']
'get_torrent_status', 'check_pwd','static_handler','get_categories'
,'template','filter_torrent_state']

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2007-11-22 11:29-0600\n"
"POT-Creation-Date: 2007-11-23 21:57-0600\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -16,262 +16,262 @@ msgstr ""
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
#: glade/delugegtk.glade:147
msgid "<b>Availability:</b>"
#: glade/delugegtk.glade:29 plugins/WebUi/scripts/template_strings.py:3
msgid "Add Torrent"
msgstr ""
#: glade/delugegtk.glade:183
msgid "<b>Pieces:</b>"
#: glade/delugegtk.glade:30
msgid "Add"
msgstr ""
#: glade/delugegtk.glade:200
msgid "<b>ETA:</b>"
#: glade/delugegtk.glade:43 glade/dgtkpopups.glade:6
msgid "Remove Torrent"
msgstr ""
#: glade/delugegtk.glade:221
msgid "<b>Peers:</b>"
#: glade/delugegtk.glade:44 plugins/WebUi/scripts/template_strings.py:40
msgid "Remove"
msgstr ""
#: glade/delugegtk.glade:242 glade/delugegtk.glade:263
msgid "<b>Speed:</b>"
#: glade/delugegtk.glade:56
msgid "Clear Seeding Torrents"
msgstr ""
#: glade/delugegtk.glade:281
msgid "<b>Share Ratio:</b>"
#: glade/delugegtk.glade:57
msgid "Clear"
msgstr ""
#: glade/delugegtk.glade:299
msgid "<b>Seeders:</b>"
#: glade/delugegtk.glade:79
msgid "Start or Resume Torrent"
msgstr ""
#: glade/delugegtk.glade:317
msgid "<b>Uploaded:</b>"
#: glade/delugegtk.glade:80
msgid "Resume"
msgstr ""
#: glade/delugegtk.glade:335
msgid "<b>Downloaded:</b>"
#: glade/delugegtk.glade:93
msgid "Pause Torrent"
msgstr ""
#: glade/delugegtk.glade:447
msgid "<b>Statistics</b>"
#: glade/delugegtk.glade:94
msgid "Pause"
msgstr ""
#: glade/delugegtk.glade:503
msgid "<b>Path:</b>"
#: glade/delugegtk.glade:106
msgid "Queue Torrent Up"
msgstr ""
#: glade/delugegtk.glade:537
msgid "<b>Total Size:</b>"
#: glade/delugegtk.glade:107
msgid "Up"
msgstr ""
#: glade/delugegtk.glade:599
msgid "<b>Tracker Status:</b>"
#: glade/delugegtk.glade:120
msgid "Queue Torrent Down"
msgstr ""
#: glade/delugegtk.glade:632
msgid "<b>Next Announce:</b>"
#: glade/delugegtk.glade:121
msgid "Down"
msgstr ""
#: glade/delugegtk.glade:671
msgid "<b># of files:</b>"
#: glade/delugegtk.glade:142
msgid "Change Deluge preferences"
msgstr ""
#: glade/delugegtk.glade:699
msgid "<b>Tracker:</b>"
#: glade/delugegtk.glade:143
msgid "Preferences"
msgstr ""
#: glade/delugegtk.glade:723
msgid "<b>Name:</b>"
#: glade/delugegtk.glade:156 glade/dgtkpopups.glade:209
#: glade/preferences_dialog.glade:2965
msgid "Plugins"
msgstr ""
#: glade/delugegtk.glade:740
msgid "<b>Torrent Info</b>"
msgstr ""
#: glade/delugegtk.glade:766 plugins/WebUi/scripts/template_strings.py:14
msgid "Details"
msgstr ""
#: glade/delugegtk.glade:805
#: glade/delugegtk.glade:177
msgid "_File"
msgstr ""
#: glade/delugegtk.glade:812 glade/tray_menu.glade:61
#: glade/delugegtk.glade:184 glade/tray_menu.glade:61
msgid "_Add Torrent"
msgstr ""
#: glade/delugegtk.glade:827
#: glade/delugegtk.glade:199
msgid "Add _URL"
msgstr ""
#: glade/delugegtk.glade:835
#: glade/delugegtk.glade:207
msgid "_Clear Completed"
msgstr ""
#: glade/delugegtk.glade:868
#: glade/delugegtk.glade:240
msgid "_Edit"
msgstr ""
#: glade/delugegtk.glade:877
#: glade/delugegtk.glade:249
msgid "gtk-select-all"
msgstr ""
#: glade/delugegtk.glade:893
#: glade/delugegtk.glade:265
msgid "Plu_gins"
msgstr ""
#: glade/delugegtk.glade:921
#: glade/delugegtk.glade:293
msgid "_Torrent"
msgstr ""
#: glade/delugegtk.glade:928
#: glade/delugegtk.glade:300
msgid "_View"
msgstr ""
#: glade/delugegtk.glade:936
#: glade/delugegtk.glade:308
msgid "_Toolbar"
msgstr ""
#: glade/delugegtk.glade:945
#: glade/delugegtk.glade:317
msgid "_Details"
msgstr ""
#: glade/delugegtk.glade:954
#: glade/delugegtk.glade:326
msgid "_Columns"
msgstr ""
#: glade/delugegtk.glade:962 src/interface.py:623 src/files.py:80
#: glade/delugegtk.glade:334 src/interface.py:623 src/files.py:80
#: plugins/WebUi/scripts/template_strings.py:48
msgid "Size"
msgstr ""
#: glade/delugegtk.glade:971 src/interface.py:627
#: glade/delugegtk.glade:343 src/interface.py:627
#: plugins/FlexRSS/FlexRSS.glade:138
msgid "Status"
msgstr ""
#: glade/delugegtk.glade:980 src/interface.py:629
#: glade/delugegtk.glade:352 src/interface.py:629
#: plugins/WebUi/scripts/template_strings.py:44
msgid "Seeders"
msgstr ""
#: glade/delugegtk.glade:989 src/interface.py:632
#: glade/delugegtk.glade:361 src/interface.py:632
#: plugins/TorrentPeers/__init__.py:84
#: plugins/WebUi/scripts/template_strings.py:31
msgid "Peers"
msgstr ""
#: glade/delugegtk.glade:998 src/interface.py:635 src/interface.py:1192
#: glade/delugegtk.glade:370 src/interface.py:635 src/interface.py:1192
#: src/interface.py:1223 plugins/TorrentPeers/tab_peers.py:89
#: plugins/WebUi/scripts/template_strings.py:16
msgid "Down Speed"
msgstr ""
#: glade/delugegtk.glade:1007 src/interface.py:638 src/interface.py:1193
#: glade/delugegtk.glade:379 src/interface.py:638 src/interface.py:1193
#: src/interface.py:1224 plugins/TorrentPeers/tab_peers.py:91
#: plugins/WebUi/scripts/template_strings.py:55
msgid "Up Speed"
msgstr ""
#: glade/delugegtk.glade:1016
#: glade/delugegtk.glade:388
msgid "Time Remaining"
msgstr ""
#: glade/delugegtk.glade:1025 plugins/WebUi/scripts/template_strings.py:8
#: glade/delugegtk.glade:397 plugins/WebUi/scripts/template_strings.py:8
msgid "Availability"
msgstr ""
#: glade/delugegtk.glade:1034 plugins/WebUi/scripts/template_strings.py:47
#: glade/delugegtk.glade:406 plugins/WebUi/scripts/template_strings.py:47
msgid "Share Ratio"
msgstr ""
#: glade/delugegtk.glade:1051
#: glade/delugegtk.glade:423
msgid "_Help"
msgstr ""
#: glade/delugegtk.glade:1059
#: glade/delugegtk.glade:431
msgid "Help translate this application"
msgstr ""
#: glade/delugegtk.glade:1060
#: glade/delugegtk.glade:432
msgid "_Translate This Application..."
msgstr ""
#: glade/delugegtk.glade:1083
#: glade/delugegtk.glade:455
msgid "Runs the first-time configuration wizard"
msgstr ""
#: glade/delugegtk.glade:1084
#: glade/delugegtk.glade:456
msgid "_Run Configuration Wizard"
msgstr ""
#: glade/delugegtk.glade:1157 plugins/WebUi/scripts/template_strings.py:3
msgid "Add Torrent"
#: glade/delugegtk.glade:593
msgid "<b>Name:</b>"
msgstr ""
#: glade/delugegtk.glade:1158
msgid "Add"
#: glade/delugegtk.glade:617
msgid "<b>Tracker:</b>"
msgstr ""
#: glade/delugegtk.glade:1171 glade/dgtkpopups.glade:6
msgid "Remove Torrent"
#: glade/delugegtk.glade:645
msgid "<b># of files:</b>"
msgstr ""
#: glade/delugegtk.glade:1172 plugins/WebUi/scripts/template_strings.py:40
msgid "Remove"
#: glade/delugegtk.glade:681
msgid "<b>Next Announce:</b>"
msgstr ""
#: glade/delugegtk.glade:1184
msgid "Clear Seeding Torrents"
#: glade/delugegtk.glade:715
msgid "<b>Tracker Status:</b>"
msgstr ""
#: glade/delugegtk.glade:1185
msgid "Clear"
#: glade/delugegtk.glade:776
msgid "<b>Total Size:</b>"
msgstr ""
#: glade/delugegtk.glade:1207
msgid "Start or Resume Torrent"
#: glade/delugegtk.glade:811
msgid "<b>Path:</b>"
msgstr ""
#: glade/delugegtk.glade:1208
msgid "Resume"
#: glade/delugegtk.glade:843
msgid "<b>Torrent Info</b>"
msgstr ""
#: glade/delugegtk.glade:1221
msgid "Pause Torrent"
#: glade/delugegtk.glade:1005
msgid "<b>Downloaded:</b>"
msgstr ""
#: glade/delugegtk.glade:1222
msgid "Pause"
#: glade/delugegtk.glade:1019
msgid "<b>Uploaded:</b>"
msgstr ""
#: glade/delugegtk.glade:1234
msgid "Queue Torrent Up"
#: glade/delugegtk.glade:1037
msgid "<b>Seeders:</b>"
msgstr ""
#: glade/delugegtk.glade:1235
msgid "Up"
#: glade/delugegtk.glade:1055
msgid "<b>Share Ratio:</b>"
msgstr ""
#: glade/delugegtk.glade:1248
msgid "Queue Torrent Down"
#: glade/delugegtk.glade:1074 glade/delugegtk.glade:1093
msgid "<b>Speed:</b>"
msgstr ""
#: glade/delugegtk.glade:1249
msgid "Down"
#: glade/delugegtk.glade:1114
msgid "<b>Peers:</b>"
msgstr ""
#: glade/delugegtk.glade:1270
msgid "Change Deluge preferences"
#: glade/delugegtk.glade:1135
msgid "<b>ETA:</b>"
msgstr ""
#: glade/delugegtk.glade:1271
msgid "Preferences"
#: glade/delugegtk.glade:1152
msgid "<b>Pieces:</b>"
msgstr ""
#: glade/delugegtk.glade:1284 glade/dgtkpopups.glade:209
#: glade/preferences_dialog.glade:2936
msgid "Plugins"
#: glade/delugegtk.glade:1190
msgid "<b>Availability:</b>"
msgstr ""
#: glade/delugegtk.glade:1231
msgid "<b>Statistics</b>"
msgstr ""
#: glade/delugegtk.glade:1256 plugins/WebUi/scripts/template_strings.py:14
msgid "Details"
msgstr ""
#: glade/dgtkpopups.glade:41
@ -312,19 +312,19 @@ msgstr ""
msgid "Unselect All"
msgstr ""
#: glade/file_tab_menu.glade:68 src/core.py:101
#: glade/file_tab_menu.glade:68 src/core.py:102
msgid "Don't download"
msgstr ""
#: glade/file_tab_menu.glade:83 src/core.py:102
#: glade/file_tab_menu.glade:83 src/core.py:103
msgid "Normal"
msgstr ""
#: glade/file_tab_menu.glade:98 src/core.py:103
#: glade/file_tab_menu.glade:98 src/core.py:104
msgid "High"
msgstr ""
#: glade/file_tab_menu.glade:113 src/core.py:104
#: glade/file_tab_menu.glade:113 src/core.py:105
msgid "Highest"
msgstr ""
@ -346,17 +346,17 @@ msgstr ""
msgid "Ask where to save each download"
msgstr ""
#: glade/preferences_dialog.glade:76 glade/preferences_dialog.glade:125
#: glade/preferences_dialog.glade:196 glade/wizard.glade:187
#: glade/preferences_dialog.glade:75 glade/preferences_dialog.glade:76
msgid "Store all downloads in:"
msgstr ""
#: glade/preferences_dialog.glade:90 glade/preferences_dialog.glade:118
#: glade/preferences_dialog.glade:186 glade/wizard.glade:187
#: plugins/MoveTorrent/movetorrent.glade:35
msgid "Select A Folder"
msgstr ""
#: glade/preferences_dialog.glade:88 glade/preferences_dialog.glade:89
msgid "Store all downloads in:"
msgstr ""
#: glade/preferences_dialog.glade:112
#: glade/preferences_dialog.glade:131
msgid "Store all torrent files in:"
msgstr ""
@ -364,7 +364,7 @@ msgstr ""
msgid "<b>Download Location</b>"
msgstr ""
#: glade/preferences_dialog.glade:182
#: glade/preferences_dialog.glade:200
msgid "Autoload all torrent files in:"
msgstr ""
@ -565,101 +565,117 @@ msgstr ""
msgid "<b>Seeding</b>"
msgstr ""
#: glade/preferences_dialog.glade:1138 src/core.py:92
#: glade/preferences_dialog.glade:1138 src/core.py:93
#: plugins/WebUi/webserver_common.py:139
msgid "Seeding"
msgstr ""
#: glade/preferences_dialog.glade:1184 glade/wizard.glade:257
#: glade/wizard.glade:318
msgid "The maximum upload slots for all torrents. Set -1 for unlimited."
msgstr ""
#: glade/preferences_dialog.glade:1201 glade/preferences_dialog.glade:1287
#: glade/preferences_dialog.glade:1307 glade/wizard.glade:277
#: glade/wizard.glade:341
msgid "The maximum upload speed for all torrents. Set -1 for unlimited."
msgstr ""
#: glade/preferences_dialog.glade:1220 glade/preferences_dialog.glade:1237
msgid "The maximum download speed for all torrents. Set -1 for unlimited."
msgstr ""
#: glade/preferences_dialog.glade:1239
msgid "Maximum Download Speed (KiB/s):"
msgstr ""
#: glade/preferences_dialog.glade:1250 glade/preferences_dialog.glade:1269
#: glade/wizard.glade:297 glade/wizard.glade:364
msgid "The maximum number of connections allowed. Set -1 for unlimited."
msgstr ""
#: glade/preferences_dialog.glade:1271 glade/preferences_dialog.glade:1456
#: glade/wizard.glade:298
msgid "Maximum Connections:"
msgstr ""
#: glade/preferences_dialog.glade:1289 glade/wizard.glade:278
msgid "Maximum Upload Speed (KiB/s):"
msgstr ""
#: glade/preferences_dialog.glade:1309 glade/preferences_dialog.glade:1437
#: glade/wizard.glade:258
msgid "Maximum Upload Slots:"
msgstr ""
#: glade/preferences_dialog.glade:1327 glade/preferences_dialog.glade:1343
#: glade/preferences_dialog.glade:1184 glade/preferences_dialog.glade:1205
#: glade/wizard.glade:434 glade/wizard.glade:455
msgid ""
"The maximum half-open connections. A high value may crash some cheap "
"routers. Set -1 for unlimited."
msgstr ""
#: glade/preferences_dialog.glade:1329 glade/wizard.glade:435
#: glade/preferences_dialog.glade:1207 glade/wizard.glade:435
msgid "Maximum Half-Open Connections:"
msgstr ""
#: glade/preferences_dialog.glade:1363
#: glade/preferences_dialog.glade:1225 glade/preferences_dialog.glade:1245
#: glade/preferences_dialog.glade:1325 glade/wizard.glade:277
#: glade/wizard.glade:341
msgid "The maximum upload speed for all torrents. Set -1 for unlimited."
msgstr ""
#: glade/preferences_dialog.glade:1227 glade/preferences_dialog.glade:1450
#: glade/wizard.glade:258
msgid "Maximum Upload Slots:"
msgstr ""
#: glade/preferences_dialog.glade:1247 glade/wizard.glade:278
msgid "Maximum Upload Speed (KiB/s):"
msgstr ""
#: glade/preferences_dialog.glade:1265 glade/preferences_dialog.glade:1279
#: glade/wizard.glade:297 glade/wizard.glade:364
msgid "The maximum number of connections allowed. Set -1 for unlimited."
msgstr ""
#: glade/preferences_dialog.glade:1267 glade/preferences_dialog.glade:1435
#: glade/wizard.glade:298
msgid "Maximum Connections:"
msgstr ""
#: glade/preferences_dialog.glade:1293 glade/preferences_dialog.glade:1307
msgid "The maximum download speed for all torrents. Set -1 for unlimited."
msgstr ""
#: glade/preferences_dialog.glade:1295
msgid "Maximum Download Speed (KiB/s):"
msgstr ""
#: glade/preferences_dialog.glade:1343 glade/wizard.glade:257
#: glade/wizard.glade:318
msgid "The maximum upload slots for all torrents. Set -1 for unlimited."
msgstr ""
#: glade/preferences_dialog.glade:1359 glade/preferences_dialog.glade:1372
msgid ""
"The maximum number of connection attempts per second. A high value may "
"crash some cheap routers. Set -1 for unlimited."
msgstr ""
#: glade/preferences_dialog.glade:1361
msgid "Maximum Connection Attempts per Second:"
msgstr ""
#: glade/preferences_dialog.glade:1392
msgid "<b>Global Bandwidth Usage</b>"
msgstr ""
#: glade/preferences_dialog.glade:1400 glade/preferences_dialog.glade:1435
msgid "The maximum upload slots per torrent. Set -1 for unlimited."
msgstr ""
#: glade/preferences_dialog.glade:1417 glade/preferences_dialog.glade:1454
#: glade/preferences_dialog.glade:1433 glade/preferences_dialog.glade:1463
msgid "The maximum number of connections per torrent. Set -1 for unlimited."
msgstr ""
#: glade/preferences_dialog.glade:1469
#: glade/preferences_dialog.glade:1448 glade/preferences_dialog.glade:1477
msgid "The maximum upload slots per torrent. Set -1 for unlimited."
msgstr ""
#: glade/preferences_dialog.glade:1498
msgid "<b>Per Torrent Bandwidth Usage</b>"
msgstr ""
#: glade/preferences_dialog.glade:1495
#: glade/preferences_dialog.glade:1524
msgid "Bandwidth"
msgstr ""
#: glade/preferences_dialog.glade:1541 glade/preferences_dialog.glade:1736
#: glade/preferences_dialog.glade:1931 glade/preferences_dialog.glade:2126
#: glade/preferences_dialog.glade:1570 glade/preferences_dialog.glade:1765
#: glade/preferences_dialog.glade:1960 glade/preferences_dialog.glade:2155
msgid "Affects regular bittorrent peers"
msgstr ""
#: glade/preferences_dialog.glade:1542
#: glade/preferences_dialog.glade:1571
msgid "Peer Proxy"
msgstr ""
#: glade/preferences_dialog.glade:1587 glade/preferences_dialog.glade:1782
#: glade/preferences_dialog.glade:1977 glade/preferences_dialog.glade:2172
msgid "Port"
#: glade/preferences_dialog.glade:1613 glade/preferences_dialog.glade:1808
#: glade/preferences_dialog.glade:2003 glade/preferences_dialog.glade:2198
msgid "Proxy type"
msgstr ""
#: glade/preferences_dialog.glade:1600 glade/preferences_dialog.glade:1795
#: glade/preferences_dialog.glade:1990 glade/preferences_dialog.glade:2185
msgid "Server"
#: glade/preferences_dialog.glade:1620 glade/preferences_dialog.glade:1815
#: glade/preferences_dialog.glade:2010 glade/preferences_dialog.glade:2205
msgid "Username"
msgstr ""
#: glade/preferences_dialog.glade:1641 glade/preferences_dialog.glade:1836
#: glade/preferences_dialog.glade:2031 glade/preferences_dialog.glade:2226
#: glade/preferences_dialog.glade:1631 glade/preferences_dialog.glade:1826
#: glade/preferences_dialog.glade:2021 glade/preferences_dialog.glade:2216
#: plugins/WebUi/scripts/template_strings.py:28
msgid "Password"
msgstr ""
#: glade/preferences_dialog.glade:1643 glade/preferences_dialog.glade:1838
#: glade/preferences_dialog.glade:2033 glade/preferences_dialog.glade:2228
msgid ""
"None\n"
"Socksv4\n"
@ -669,87 +685,73 @@ msgid ""
"HTTP W/ Auth"
msgstr ""
#: glade/preferences_dialog.glade:1657 glade/preferences_dialog.glade:1852
#: glade/preferences_dialog.glade:2047 glade/preferences_dialog.glade:2242
#: plugins/WebUi/scripts/template_strings.py:28
msgid "Password"
#: glade/preferences_dialog.glade:1688 glade/preferences_dialog.glade:1883
#: glade/preferences_dialog.glade:2078 glade/preferences_dialog.glade:2273
msgid "Server"
msgstr ""
#: glade/preferences_dialog.glade:1668 glade/preferences_dialog.glade:1863
#: glade/preferences_dialog.glade:2058 glade/preferences_dialog.glade:2253
msgid "Username"
#: glade/preferences_dialog.glade:1699 glade/preferences_dialog.glade:1894
#: glade/preferences_dialog.glade:2089 glade/preferences_dialog.glade:2284
msgid "Port"
msgstr ""
#: glade/preferences_dialog.glade:1679 glade/preferences_dialog.glade:1874
#: glade/preferences_dialog.glade:2069 glade/preferences_dialog.glade:2264
msgid "Proxy type"
msgstr ""
#: glade/preferences_dialog.glade:1704
#: glade/preferences_dialog.glade:1733
msgid "<b>Peer Proxy</b>"
msgstr ""
#: glade/preferences_dialog.glade:1737
#: glade/preferences_dialog.glade:1766
msgid "Tracker Proxy"
msgstr ""
#: glade/preferences_dialog.glade:1899
#: glade/preferences_dialog.glade:1928
msgid "<b>Tracker Proxy</b>"
msgstr ""
#: glade/preferences_dialog.glade:1932
#: glade/preferences_dialog.glade:1961
msgid "DHT Proxy"
msgstr ""
#: glade/preferences_dialog.glade:2094
#: glade/preferences_dialog.glade:2123
msgid "<b>DHT Proxy</b>"
msgstr ""
#: glade/preferences_dialog.glade:2127
#: glade/preferences_dialog.glade:2156
msgid "Web Seed Proxy"
msgstr ""
#: glade/preferences_dialog.glade:2289
#: glade/preferences_dialog.glade:2318
msgid "<b>Web Seed Proxy</b>"
msgstr ""
#: glade/preferences_dialog.glade:2316
#: glade/preferences_dialog.glade:2345
msgid "Proxies"
msgstr ""
#: glade/preferences_dialog.glade:2345
#: glade/preferences_dialog.glade:2374
msgid "Enable system tray icon"
msgstr ""
#: glade/preferences_dialog.glade:2361
#: glade/preferences_dialog.glade:2390
msgid "Minimize to tray on close"
msgstr ""
#: glade/preferences_dialog.glade:2380
#: glade/preferences_dialog.glade:2409
msgid "Start in tray"
msgstr ""
#: glade/preferences_dialog.glade:2404
#: glade/preferences_dialog.glade:2433
msgid "Password protect system tray"
msgstr ""
#: glade/preferences_dialog.glade:2422
#: glade/preferences_dialog.glade:2451
msgid "Password:"
msgstr ""
#: glade/preferences_dialog.glade:2464
#: glade/preferences_dialog.glade:2493
msgid "<b>System Tray</b>"
msgstr ""
#: glade/preferences_dialog.glade:2507
msgid "Open folder with:"
msgstr ""
#: glade/preferences_dialog.glade:2524
msgid "Custom:"
msgstr ""
#: glade/preferences_dialog.glade:2547
#: glade/preferences_dialog.glade:2557
msgid ""
"Auto-detect (xdg-open)\n"
"Konqueror\n"
@ -757,58 +759,66 @@ msgid ""
"Thunar"
msgstr ""
#: glade/preferences_dialog.glade:2594
#: glade/preferences_dialog.glade:2578
msgid "Custom:"
msgstr ""
#: glade/preferences_dialog.glade:2601
msgid "Open folder with:"
msgstr ""
#: glade/preferences_dialog.glade:2623
msgid "<b>Desktop File Manager</b> - only for non-Windows platforms"
msgstr ""
#: glade/preferences_dialog.glade:2626
#: glade/preferences_dialog.glade:2655
msgid "GUI update interval (seconds)"
msgstr ""
#: glade/preferences_dialog.glade:2654
#: glade/preferences_dialog.glade:2683
msgid "<b>Performance</b>"
msgstr ""
#: glade/preferences_dialog.glade:2685
#: glade/preferences_dialog.glade:2714
msgid "Use the advanced progress bar (uses slightly more CPU/RAM)"
msgstr ""
#: glade/preferences_dialog.glade:2696
#: glade/preferences_dialog.glade:2725
msgid "<b>Detailed Progress Bar</b>"
msgstr ""
#: glade/preferences_dialog.glade:2730
#: glade/preferences_dialog.glade:2759
msgid ""
"Deluge will check our servers and will tell you if a newer version has been "
"released"
msgstr ""
#: glade/preferences_dialog.glade:2731
#: glade/preferences_dialog.glade:2760
msgid "Be alerted about new releases"
msgstr ""
#: glade/preferences_dialog.glade:2748
#: glade/preferences_dialog.glade:2777
msgid "<b>Updates</b>"
msgstr ""
#: glade/preferences_dialog.glade:2778
#: glade/preferences_dialog.glade:2807
msgid ""
"Help us improve Deluge by sending us your Python and PyGTK\n"
"versions, OS and processor types. Absolutely no other\n"
"information is sent."
msgstr ""
#: glade/preferences_dialog.glade:2791
#: glade/preferences_dialog.glade:2820
msgid "<b>System Information</b>"
msgstr ""
#: glade/preferences_dialog.glade:2814
#: glade/preferences_dialog.glade:2843
#: plugins/EventLogging/event_logging_preferences.glade:52
#: plugins/EventLogging/tab_log.py:218
msgid "Other"
msgstr ""
#: glade/preferences_dialog.glade:2908
#: glade/preferences_dialog.glade:2937
msgid "gtk-preferences"
msgstr ""
@ -1102,107 +1112,107 @@ msgid ""
"torrent file is corrupted."
msgstr ""
#: src/interface.py:1374
#: src/interface.py:1377
msgid "Unknown duplicate torrent error."
msgstr ""
#: src/interface.py:1379
#: src/interface.py:1382
msgid ""
"There is not enough free disk space to complete your download."
msgstr ""
#: src/interface.py:1381
#: src/interface.py:1384
msgid "Space Needed:"
msgstr ""
#: src/interface.py:1382
#: src/interface.py:1385
msgid "Available Space:"
msgstr ""
#: src/interface.py:1399
#: src/interface.py:1402
msgid "Add torrent from URL"
msgstr ""
#: src/interface.py:1403
#: src/interface.py:1406
msgid "Enter the URL of the .torrent to download"
msgstr ""
#: src/interface.py:1464
#: src/interface.py:1467
msgid "Warning - all downloaded files for this torrent will be deleted!"
msgstr ""
#: src/interface.py:1480
#: src/interface.py:1483
msgid "Are you sure that you want to remove all seeding torrents?"
msgstr ""
#: src/core.py:86 plugins/WebUi/webserver_common.py:133
#: src/core.py:87 plugins/WebUi/webserver_common.py:133
msgid "Queued"
msgstr ""
#: src/core.py:87 plugins/WebUi/webserver_common.py:134
#: src/core.py:88 plugins/WebUi/webserver_common.py:134
msgid "Checking"
msgstr ""
#: src/core.py:88 plugins/WebUi/webserver_common.py:135
#: src/core.py:89 plugins/WebUi/webserver_common.py:135
msgid "Connecting"
msgstr ""
#: src/core.py:89 plugins/WebUi/webserver_common.py:136
#: src/core.py:90 plugins/WebUi/webserver_common.py:136
msgid "Downloading Metadata"
msgstr ""
#: src/core.py:90 plugins/BlocklistImport/ui.py:117
#: src/core.py:91 plugins/BlocklistImport/ui.py:117
#: plugins/WebUi/webserver_common.py:137
msgid "Downloading"
msgstr ""
#: src/core.py:91 plugins/WebUi/webserver_common.py:138
#: src/core.py:92 plugins/WebUi/webserver_common.py:138
msgid "Finished"
msgstr ""
#: src/core.py:93 plugins/WebUi/webserver_common.py:140
#: src/core.py:94 plugins/WebUi/webserver_common.py:140
msgid "Allocating"
msgstr ""
#: src/core.py:136
#: src/core.py:137
msgid "bytes needed"
msgstr ""
#: src/core.py:383
#: src/core.py:384
msgid "File was not found"
msgstr ""
#: src/core.py:426
#: src/core.py:427
msgid "Asked for a torrent that doesn't exist"
msgstr ""
#: src/core.py:549
#: src/core.py:550
msgid ""
"You're out of HD space! Oops!\n"
"We had to pause at least one torrent"
msgstr ""
#: src/core.py:637
#: src/core.py:638
msgid "Announce sent"
msgstr ""
#: src/core.py:641
#: src/core.py:642
msgid "Announce OK"
msgstr ""
#: src/core.py:647
#: src/core.py:648
msgid "Alert"
msgstr ""
#: src/core.py:648
#: src/core.py:649
msgid "HTTP code"
msgstr ""
#: src/core.py:649
#: src/core.py:650
msgid "times in a row"
msgstr ""
#: src/core.py:656
#: src/core.py:657
msgid "Warning"
msgstr ""
@ -1229,7 +1239,7 @@ msgstr ""
msgid "Enabled"
msgstr ""
#: src/dialogs.py:459
#: src/dialogs.py:461
msgid ""
"Deluge is free software, you can redistribute it and/or\n"
"modify it under the terms of the GNU General Public\n"
@ -1246,15 +1256,15 @@ msgid ""
"1301 USA"
msgstr ""
#: src/dialogs.py:500
#: src/dialogs.py:502
msgid "Choose a .torrent file"
msgstr ""
#: src/dialogs.py:505
#: src/dialogs.py:507
msgid "Torrent files"
msgstr ""
#: src/dialogs.py:509
#: src/dialogs.py:511
msgid "All files"
msgstr ""
@ -1930,7 +1940,7 @@ msgstr ""
msgid "Choose a directory to move files to"
msgstr ""
#: plugins/MoveTorrent/__init__.py:129
#: plugins/MoveTorrent/__init__.py:124
msgid ""
"You cannot move torrent to a different partition. Please check your "
"preferences. Also, you cannot move a torrent's files to the same directory "

View File

@ -635,6 +635,13 @@ free disk space to complete your download.") + "\n" + _("Space Needed:") + " " \
# seed if client crashes
self.save_fastresume_data(event['unique_ID'])
elif event['event_type'] is self.constants['EVENT_FILE_ERROR']:
import gtk
import dialogs
gtk.gdk.threads_enter()
dialogs.show_popup_warning(None, event['message'])
gtk.gdk.threads_leave()
elif event['event_type'] is self.constants['EVENT_TRACKER_ANNOUNCE']:
self.set_supp_torrent_state_val(event['unique_ID'],
"tracker_status",

View File

@ -820,9 +820,9 @@ window, please enter your password"))
unique_ids = self.get_selected_torrent_rows()
try:
for uid in unique_ids:
self.manager.set_user_pause(uid, True, True)
torrent_state = self.manager.get_torrent_state(uid)
if torrent_state["is_paused"] == 0:
self.manager.set_user_pause(uid, True, True)
self.manager.save_fastresume_data(uid)
self.update()
@ -937,13 +937,16 @@ window, please enter your password"))
int(self.config.get("web_proxy_port")), self.config.get(
"web_proxy_type"), "web")
def get_message_from_state(self, torrent_state):
def get_message_from_state(self, unique_id, torrent_state):
state = torrent_state['state']
is_paused = torrent_state['is_paused']
progress = torrent_state['progress']
progress = '%d%%' % int(progress * 100)
if is_paused:
message = _("Paused %s") % progress
if self.manager.is_user_paused(unique_id):
message = _("Paused %s") % progress
else:
message = _("Queued %s") % progress
else:
try:
message = core.STATE_MESSAGES[state]
@ -960,7 +963,7 @@ window, please enter your password"))
name = state['name']
size = state['total_wanted']
progress = float(state['progress'] * 100)
message = self.get_message_from_state(state)
message = self.get_message_from_state(unique_id, state)
availability = state['distributed_copies']
share = self.manager.calc_ratio(unique_id, state)
@ -1140,11 +1143,13 @@ window, please enter your password"))
state = self.manager.get_torrent_state(unique_id)
if previosly_paused and state['is_paused']:
# For previosly and still paused torrents update only
# queue pos and selected files size, all the rest
# columns are unchanged for them.
dgtk.update_store(self.torrent_model, itr, (1, 4),
# queue pos, selected files size and status message.
# All the other columns are unchanged.
message = self.get_message_from_state(unique_id, state)
dgtk.update_store(self.torrent_model, itr, (1, 4, 6),
(state['queue_pos'],
state['total_wanted']))
state['total_wanted'],
message))
else:
tlist = self.get_torrent_state_list(unique_id, state)
dgtk.update_store(self.torrent_model, itr,