diff options
author | Marcos Pinto <markybob@dipconsultants.com> | 2007-11-24 16:22:49 +0000 |
---|---|---|
committer | Marcos Pinto <markybob@dipconsultants.com> | 2007-11-24 16:22:49 +0000 |
commit | cda1b3aa98b0f9386caddc203c61cbd1bc4abb71 (patch) | |
tree | f3d3d05c0ec3f8d5e53d613184325128e5e6d557 | |
parent | ced47db339748e9ba8f3730dfccf86558ff7d1be (diff) | |
download | deluge-cda1b3aa98b0f9386caddc203c61cbd1bc4abb71.tar.gz deluge-cda1b3aa98b0f9386caddc203c61cbd1bc4abb71.tar.bz2 deluge-cda1b3aa98b0f9386caddc203c61cbd1bc4abb71.zip |
update webui, show error on permission failure, differentiate queued vs paused
27 files changed, 958 insertions, 462 deletions
@@ -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 diff --git a/plugins/WebUi/__init__.py b/plugins/WebUi/__init__.py index 4202d21ba..2d6f3ad4a 100644 --- a/plugins/WebUi/__init__.py +++ b/plugins/WebUi/__init__.py @@ -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 diff --git a/plugins/WebUi/dbus_interface.py b/plugins/WebUi/dbus_interface.py index f14a382e0..9f0f826bc 100644 --- a/plugins/WebUi/dbus_interface.py +++ b/plugins/WebUi/dbus_interface.py @@ -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 diff --git a/plugins/WebUi/deluge_webserver.py b/plugins/WebUi/deluge_webserver.py index 69ddb495c..618802143 100644 --- a/plugins/WebUi/deluge_webserver.py +++ b/plugins/WebUi/deluge_webserver.py @@ -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): + torrent_ids = name.split(',') + ws.proxy.resume_torrent(torrent_ids) + do_redirect() + +class torrent_stop: @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.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: diff --git a/plugins/WebUi/revno b/plugins/WebUi/revno index c75acbe2f..bb7936535 100644 --- a/plugins/WebUi/revno +++ b/plugins/WebUi/revno @@ -1 +1 @@ -127 +155 diff --git a/plugins/WebUi/ssl/deluge.key b/plugins/WebUi/ssl/deluge.key new file mode 100644 index 000000000..a9d5db5ce --- /dev/null +++ b/plugins/WebUi/ssl/deluge.key @@ -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----- diff --git a/plugins/WebUi/ssl/deluge.pem b/plugins/WebUi/ssl/deluge.pem new file mode 100644 index 000000000..effef476e --- /dev/null +++ b/plugins/WebUi/ssl/deluge.pem @@ -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----- diff --git a/plugins/WebUi/static/images/tango/details.png b/plugins/WebUi/static/images/tango/details.png Binary files differnew file mode 100644 index 000000000..8dd48c494 --- /dev/null +++ b/plugins/WebUi/static/images/tango/details.png diff --git a/plugins/WebUi/static/simple_site_style.css b/plugins/WebUi/static/simple_site_style.css index 16d65480e..3776994e8 100755 --- a/plugins/WebUi/static/simple_site_style.css +++ b/plugins/WebUi/static/simple_site_style.css @@ -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 */
\ No newline at end of file +/*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 */
diff --git a/plugins/WebUi/templates/advanced/index.html b/plugins/WebUi/templates/advanced/index.html index 637aa6bdc..0bdd937ea 100644 --- a/plugins/WebUi/templates/advanced/index.html +++ b/plugins/WebUi/templates/advanced/index.html @@ -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: + + </td> + <td> + $if (torrent.upload_rate): + $fspeed(torrent.upload_rate) + $else: + + </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'> diff --git a/plugins/WebUi/templates/advanced/part_categories.html b/plugins/WebUi/templates/advanced/part_categories.html new file mode 100644 index 000000000..64ca21f8c --- /dev/null +++ b/plugins/WebUi/templates/advanced/part_categories.html @@ -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> + + + + diff --git a/plugins/WebUi/templates/advanced/static/advanced.css b/plugins/WebUi/templates/advanced/static/advanced.css index d197ad0fc..3e7753080 100644 --- a/plugins/WebUi/templates/advanced/static/advanced.css +++ b/plugins/WebUi/templates/advanced/static/advanced.css @@ -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 */
\ No newline at end of file +#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 */ + + diff --git a/plugins/WebUi/templates/advanced/static/deluge.js b/plugins/WebUi/templates/advanced/static/deluge.js index 33e7cbdc4..88d4aa0ac 100644 --- a/plugins/WebUi/templates/advanced/static/deluge.js +++ b/plugins/WebUi/templates/advanced/static/deluge.js @@ -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')) { diff --git a/plugins/WebUi/templates/deluge/index.html b/plugins/WebUi/templates/deluge/index.html index b177c7b8c..ac06375dd 100644 --- a/plugins/WebUi/templates/deluge/index.html +++ b/plugins/WebUi/templates/deluge/index.html @@ -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> diff --git a/plugins/WebUi/templates/deluge/part_stats.html b/plugins/WebUi/templates/deluge/part_stats.html index 55a2a74b5..342b8049f 100644 --- a/plugins/WebUi/templates/deluge/part_stats.html +++ b/plugins/WebUi/templates/deluge/part_stats.html @@ -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> diff --git a/plugins/WebUi/templates/deluge/sort_column_head.html b/plugins/WebUi/templates/deluge/sort_column_head.html index 1de008a79..d354a6c4f 100644 --- a/plugins/WebUi/templates/deluge/sort_column_head.html +++ b/plugins/WebUi/templates/deluge/sort_column_head.html @@ -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" /> diff --git a/plugins/WebUi/templates/deluge/tab_meta.html b/plugins/WebUi/templates/deluge/tab_meta.html index e69de29bb..6a1de18de 100644 --- a/plugins/WebUi/templates/deluge/tab_meta.html +++ b/plugins/WebUi/templates/deluge/tab_meta.html @@ -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"> </td> +<td class="info_value"> </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"> </td> +<td class="info_value"> </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> diff --git a/plugins/WebUi/templates/deluge/torrent_delete.html b/plugins/WebUi/templates/deluge/torrent_delete.html index 77f32949a..a9aceb551 100644 --- a/plugins/WebUi/templates/deluge/torrent_delete.html +++ b/plugins/WebUi/templates/deluge/torrent_delete.html @@ -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 diff --git a/plugins/WebUi/templates/deluge/torrent_info.html b/plugins/WebUi/templates/deluge/torrent_info.html index a9ba83b10..660273e1a 100644 --- a/plugins/WebUi/templates/deluge/torrent_info.html +++ b/plugins/WebUi/templates/deluge/torrent_info.html @@ -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;"> - - $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> - -</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> +$:render.tab_meta(torrent) -</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') -</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() diff --git a/plugins/WebUi/templates/hacking-templates.txt b/plugins/WebUi/templates/hacking-templates.txt index f69e47c73..600ba907e 100644 --- a/plugins/WebUi/templates/hacking-templates.txt +++ b/plugins/WebUi/templates/hacking-templates.txt @@ -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. diff --git a/plugins/WebUi/tests/test_all.py b/plugins/WebUi/tests/test_all.py index 7bf7c4265..f6c750fea 100644 --- a/plugins/WebUi/tests/test_all.py +++ b/plugins/WebUi/tests/test_all.py @@ -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: diff --git a/plugins/WebUi/version b/plugins/WebUi/version index a7debb432..afa9f2464 100644 --- a/plugins/WebUi/version +++ b/plugins/WebUi/version @@ -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 diff --git a/plugins/WebUi/webserver_common.py b/plugins/WebUi/webserver_common.py index 1e209ea56..67b0ad47b 100644 --- a/plugins/WebUi/webserver_common.py +++ b/plugins/WebUi/webserver_common.py @@ -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"), diff --git a/plugins/WebUi/webserver_framework.py b/plugins/WebUi/webserver_framework.py index 6735802d1..595ae2047 100644 --- a/plugins/WebUi/webserver_framework.py +++ b/plugins/WebUi/webserver_framework.py @@ -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'] diff --git a/po/deluge.pot b/po/deluge.pot index bac3d7ba1..06c23e890 100644 --- a/po/deluge.pot +++ b/po/deluge.pot @@ -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>" -msgstr "" - -#: glade/delugegtk.glade:183 -msgid "<b>Pieces:</b>" -msgstr "" - -#: glade/delugegtk.glade:200 -msgid "<b>ETA:</b>" +#: glade/delugegtk.glade:29 plugins/WebUi/scripts/template_strings.py:3 +msgid "Add Torrent" msgstr "" -#: glade/delugegtk.glade:221 -msgid "<b>Peers:</b>" +#: glade/delugegtk.glade:30 +msgid "Add" msgstr "" -#: glade/delugegtk.glade:242 glade/delugegtk.glade:263 -msgid "<b>Speed:</b>" +#: glade/delugegtk.glade:43 glade/dgtkpopups.glade:6 +msgid "Remove Torrent" msgstr "" -#: glade/delugegtk.glade:281 -msgid "<b>Share Ratio:</b>" +#: glade/delugegtk.glade:44 plugins/WebUi/scripts/template_strings.py:40 +msgid "Remove" msgstr "" -#: glade/delugegtk.glade:299 -msgid "<b>Seeders:</b>" +#: glade/delugegtk.glade:56 +msgid "Clear Seeding Torrents" msgstr "" -#: glade/delugegtk.glade:317 -msgid "<b>Uploaded:</b>" +#: glade/delugegtk.glade:57 +msgid "Clear" msgstr "" -#: glade/delugegtk.glade:335 -msgid "<b>Downloaded:</b>" +#: glade/delugegtk.glade:79 +msgid "Start or Resume Torrent" msgstr "" -#: glade/delugegtk.glade:447 -msgid "<b>Statistics</b>" +#: glade/delugegtk.glade:80 +msgid "Resume" msgstr "" -#: glade/delugegtk.glade:503 -msgid "<b>Path:</b>" +#: glade/delugegtk.glade:93 +msgid "Pause Torrent" msgstr "" -#: glade/delugegtk.glade:537 -msgid "<b>Total Size:</b>" +#: glade/delugegtk.glade:94 +msgid "Pause" msgstr "" -#: glade/delugegtk.glade:599 -msgid "<b>Tracker Status:</b>" +#: glade/delugegtk.glade:106 +msgid "Queue Torrent Up" msgstr "" -#: glade/delugegtk.glade:632 -msgid "<b>Next Announce:</b>" +#: glade/delugegtk.glade:107 +msgid "Up" msgstr "" -#: glade/delugegtk.glade:671 -msgid "<b># of files:</b>" +#: glade/delugegtk.glade:120 +msgid "Queue Torrent Down" msgstr "" -#: glade/delugegtk.glade:699 -msgid "<b>Tracker:</b>" +#: glade/delugegtk.glade:121 +msgid "Down" msgstr "" -#: glade/delugegtk.glade:723 -msgid "<b>Name:</b>" +#: glade/delugegtk.glade:142 +msgid "Change Deluge preferences" msgstr "" -#: glade/delugegtk.glade:740 -msgid "<b>Torrent Info</b>" +#: glade/delugegtk.glade:143 +msgid "Preferences" msgstr "" -#: glade/delugegtk.glade:766 plugins/WebUi/scripts/template_strings.py:14 -msgid "Details" +#: glade/delugegtk.glade:156 glade/dgtkpopups.glade:209 +#: glade/preferences_dialog.glade:2965 +msgid "Plugins" 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 -#: plugins/MoveTorrent/movetorrent.glade:35 -msgid "Select A Folder" +#: glade/preferences_dialog.glade:75 glade/preferences_dialog.glade:76 +msgid "Store all downloads in:" msgstr "" -#: glade/preferences_dialog.glade:88 glade/preferences_dialog.glade:89 -msgid "Store all downloads in:" +#: 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: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." +#: 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:1201 glade/preferences_dialog.glade:1287 -#: glade/preferences_dialog.glade:1307 glade/wizard.glade:277 +#: glade/preferences_dialog.glade:1207 glade/wizard.glade:435 +msgid "Maximum Half-Open Connections:" +msgstr "" + +#: 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:1220 glade/preferences_dialog.glade:1237 -msgid "The maximum download speed for all torrents. Set -1 for unlimited." +#: glade/preferences_dialog.glade:1227 glade/preferences_dialog.glade:1450 +#: glade/wizard.glade:258 +msgid "Maximum Upload Slots:" msgstr "" -#: glade/preferences_dialog.glade:1239 -msgid "Maximum Download Speed (KiB/s):" +#: glade/preferences_dialog.glade:1247 glade/wizard.glade:278 +msgid "Maximum Upload Speed (KiB/s):" msgstr "" -#: glade/preferences_dialog.glade:1250 glade/preferences_dialog.glade:1269 +#: 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:1271 glade/preferences_dialog.glade:1456 +#: glade/preferences_dialog.glade:1267 glade/preferences_dialog.glade:1435 #: glade/wizard.glade:298 msgid "Maximum Connections:" msgstr "" -#: glade/preferences_dialog.glade:1289 glade/wizard.glade:278 -msgid "Maximum Upload Speed (KiB/s):" +#: 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:1309 glade/preferences_dialog.glade:1437 -#: glade/wizard.glade:258 -msgid "Maximum Upload Slots:" +#: glade/preferences_dialog.glade:1295 +msgid "Maximum Download Speed (KiB/s):" msgstr "" -#: glade/preferences_dialog.glade:1327 glade/preferences_dialog.glade:1343 -#: glade/wizard.glade:434 glade/wizard.glade:455 +#: 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 half-open connections. A high value may crash some cheap " -"routers. Set -1 for unlimited." +"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:1329 glade/wizard.glade:435 -msgid "Maximum Half-Open Connections:" +#: glade/preferences_dialog.glade:1361 +msgid "Maximum Connection Attempts per Second:" msgstr "" -#: glade/preferences_dialog.glade:1363 +#: 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." +#: 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:1417 glade/preferences_dialog.glade:1454 -msgid "The maximum number of connections per torrent. Set -1 for unlimited." +#: 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:1469 +#: 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: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:1641 glade/preferences_dialog.glade:1836 -#: glade/preferences_dialog.glade:2031 glade/preferences_dialog.glade:2226 +#: 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" -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:1688 glade/preferences_dialog.glade:1883 +#: glade/preferences_dialog.glade:2078 glade/preferences_dialog.glade:2273 +msgid "Server" msgstr "" -#: glade/preferences_dialog.glade:1679 glade/preferences_dialog.glade:1874 -#: glade/preferences_dialog.glade:2069 glade/preferences_dialog.glade:2264 -msgid "Proxy type" +#: 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: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 " diff --git a/src/core.py b/src/core.py index 14d558886..03908a459 100644 --- a/src/core.py +++ b/src/core.py @@ -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", diff --git a/src/interface.py b/src/interface.py index f25c9b68b..38c057fac 100644 --- a/src/interface.py +++ b/src/interface.py @@ -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, |