From cda1b3aa98b0f9386caddc203c61cbd1bc4abb71 Mon Sep 17 00:00:00 2001 From: Marcos Pinto Date: Sat, 24 Nov 2007 16:22:49 +0000 Subject: [PATCH] update webui, show error on permission failure, differentiate queued vs paused --- ChangeLog | 5 +- plugins/WebUi/__init__.py | 27 +- plugins/WebUi/dbus_interface.py | 24 +- plugins/WebUi/deluge_webserver.py | 95 +++- plugins/WebUi/revno | 2 +- plugins/WebUi/ssl/deluge.key | 27 + plugins/WebUi/ssl/deluge.pem | 22 + plugins/WebUi/static/images/tango/details.png | Bin 0 -> 498 bytes plugins/WebUi/static/simple_site_style.css | 54 +- plugins/WebUi/templates/advanced/index.html | 85 ++- .../templates/advanced/part_categories.html | 30 + .../templates/advanced/static/advanced.css | 78 ++- .../WebUi/templates/advanced/static/deluge.js | 38 +- plugins/WebUi/templates/deluge/index.html | 25 +- .../WebUi/templates/deluge/part_stats.html | 7 +- .../templates/deluge/sort_column_head.html | 4 +- plugins/WebUi/templates/deluge/tab_meta.html | 85 +++ .../templates/deluge/torrent_delete.html | 13 +- .../WebUi/templates/deluge/torrent_info.html | 92 +--- plugins/WebUi/templates/hacking-templates.txt | 25 +- plugins/WebUi/tests/test_all.py | 68 ++- plugins/WebUi/version | 2 +- plugins/WebUi/webserver_common.py | 18 +- plugins/WebUi/webserver_framework.py | 88 ++- po/deluge.pot | 516 +++++++++--------- src/core.py | 7 + src/interface.py | 21 +- 27 files changed, 977 insertions(+), 481 deletions(-) create mode 100644 plugins/WebUi/ssl/deluge.key create mode 100644 plugins/WebUi/ssl/deluge.pem create mode 100644 plugins/WebUi/static/images/tango/details.png create mode 100644 plugins/WebUi/templates/advanced/part_categories.html diff --git a/ChangeLog b/ChangeLog index d032571e5..91b735e58 100644 --- a/ChangeLog +++ b/ChangeLog @@ -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): - 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: 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 new file mode 100644 index 0000000000000000000000000000000000000000..8dd48c494924874a088590a749193994d075c22f GIT binary patch literal 498 zcmVl*+}S4tk-SEw(HMMH$UOFgT8OyWIuox(>z|!eNT?Q)#FJN+p=4fyzsz3(&M5 z1Oj8QEH>2c<<$iq9`D@|1fH*+ou9fEhcV03wkV2NSzd)@nNYt}lHgoRaN9}vHG1pg5Cj3DD1s1zdc6*S;N$b%7N-)ik literal 0 HcmV?d00001 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')) +
-[Add] -[Up] -[Down] -[Delete] -[Info] -[Pause] -[Start] + + + + + + + + + + + + + + + + + $:category_tabs(all_torrents) + +
-
+
- +
$:(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: - + @@ -63,8 +101,18 @@ $for torrent in torrent_list: - - + +
- + + + + $torrent.queue_pos $(crop(torrent.name, 40)) $torrent.num_seeds ($torrent.total_seeds) $torrent.num_peers ($torrent.total_peers)$fspeed(torrent.download_rate)$fspeed(torrent.upload_rate) + $if (torrent.download_rate): + $fspeed(torrent.download_rate) + $else: +   + + $if (torrent.upload_rate): + $fspeed(torrent.upload_rate) + $else: +   + $torrent.eta $("%.3f" % torrent.distributed_copies) $("%.3f" % torrent.ratio) @@ -73,7 +121,6 @@ $for torrent in torrent_list:
- $:part_stats() @@ -84,6 +131,8 @@ $:part_stats() +
+