summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--ChangeLog67
-rw-r--r--DEPENDS3
-rw-r--r--deluge/_libtorrent.py4
-rw-r--r--deluge/common.py141
-rw-r--r--deluge/component.py32
-rw-r--r--deluge/core/alertmanager.py6
-rw-r--r--deluge/core/authmanager.py6
-rw-r--r--deluge/core/core.py2
-rw-r--r--deluge/core/filtermanager.py5
-rw-r--r--deluge/core/rpcserver.py2
-rw-r--r--deluge/core/torrent.py196
-rw-r--r--deluge/core/torrentmanager.py246
-rw-r--r--deluge/main.py98
-rw-r--r--deluge/plugins/AutoAdd/deluge/plugins/autoadd/gtkui.py5
-rw-r--r--deluge/plugins/Extractor/deluge/plugins/extractor/gtkui.py4
-rw-r--r--deluge/plugins/Notifications/deluge/plugins/notifications/gtkui.py6
-rw-r--r--deluge/plugins/Scheduler/deluge/plugins/scheduler/gtkui.py4
-rw-r--r--deluge/plugins/WebUi/deluge/plugins/webui/gtkui.py4
-rw-r--r--deluge/rencode.py25
-rw-r--r--deluge/tests/dir_with_6_files.torrentbin0 -> 9630 bytes
-rw-r--r--deluge/tests/test_component.py38
-rw-r--r--deluge/tests/test_torrent.py127
-rw-r--r--deluge/tests/test_transfer.py (renamed from tests/test_transfer.py)0
-rw-r--r--deluge/tests/test_ui_common.py30
-rw-r--r--deluge/tests/unicode_filenames.torrentbin0 -> 34298 bytes
-rw-r--r--deluge/transfer.py2
-rw-r--r--deluge/ui/client.py16
-rw-r--r--deluge/ui/common.py15
-rw-r--r--deluge/ui/console/commands/manage.py17
-rw-r--r--deluge/ui/console/modes/torrent_actions.py2
-rw-r--r--deluge/ui/console/modes/torrentdetail.py37
-rw-r--r--deluge/ui/gtkui/addtorrentdialog.py29
-rw-r--r--deluge/ui/gtkui/common.py4
-rw-r--r--deluge/ui/gtkui/createtorrentdialog.py4
-rw-r--r--deluge/ui/gtkui/glade/preferences_dialog.ui15
-rw-r--r--deluge/ui/gtkui/glade/tray_menu.ui3
-rw-r--r--deluge/ui/gtkui/gtkui.py6
-rw-r--r--deluge/ui/gtkui/ipcinterface.py68
-rw-r--r--deluge/ui/gtkui/mainwindow.py16
-rw-r--r--deluge/ui/gtkui/pluginmanager.py1
-rw-r--r--deluge/ui/gtkui/preferences.py10
-rw-r--r--deluge/ui/gtkui/queuedtorrents.py2
-rw-r--r--deluge/ui/gtkui/statusbar.py12
-rw-r--r--deluge/ui/gtkui/systemtray.py79
-rw-r--r--deluge/ui/gtkui/torrentdetails.py19
-rw-r--r--deluge/ui/sessionproxy.py2
-rw-r--r--deluge/ui/ui.py4
-rw-r--r--deluge/ui/web/TODO4
-rw-r--r--deluge/ui/web/auth.py1
-rwxr-xr-xdeluge/ui/web/build4
-rw-r--r--deluge/ui/web/css/deluge.css49
-rwxr-xr-x[-rw-r--r--]deluge/ui/web/gen_gettext.py11
-rw-r--r--deluge/ui/web/gettext.js580
-rw-r--r--deluge/ui/web/icons/readme.txt2
-rw-r--r--deluge/ui/web/images/debugerror.pngbin9489 -> 0 bytes
-rw-r--r--deluge/ui/web/images/deluge-icon.pngbin722 -> 0 bytes
-rw-r--r--deluge/ui/web/images/deluge16.pngbin722 -> 0 bytes
-rw-r--r--deluge/ui/web/images/deluge32.pngbin1888 -> 0 bytes
-rw-r--r--deluge/ui/web/images/deluge_icon.gifbin588 -> 0 bytes
-rw-r--r--deluge/ui/web/js/deluge-all-debug.js200
-rw-r--r--deluge/ui/web/js/deluge-all.js48
-rw-r--r--deluge/ui/web/js/deluge-all/Client.js55
-rw-r--r--deluge/ui/web/js/deluge-all/EventsManager.js16
-rw-r--r--deluge/ui/web/js/deluge-all/LoginWindow.js9
-rw-r--r--deluge/ui/web/js/deluge-all/Menus.js6
-rw-r--r--deluge/ui/web/js/deluge-all/Plugin.js1
-rw-r--r--deluge/ui/web/js/deluge-all/TorrentGrid.js2
-rw-r--r--deluge/ui/web/js/deluge-all/UI.js2
-rw-r--r--deluge/ui/web/js/deluge-all/add/FilesTab.js4
-rw-r--r--deluge/ui/web/js/deluge-all/add/OptionsPanel.js2
-rw-r--r--deluge/ui/web/js/deluge-all/add/OptionsTab.js38
-rw-r--r--deluge/ui/web/js/deluge-all/add/UrlWindow.js2
-rw-r--r--deluge/ui/web/js/deluge-all/data/SortTypes.js8
-rw-r--r--deluge/ui/web/js/deluge-all/data/TorrentRecord.js5
-rw-r--r--deluge/ui/web/js/deluge-all/details/DetailsTab.js2
-rw-r--r--deluge/ui/web/js/deluge-all/details/FilesTab.js17
-rw-r--r--deluge/ui/web/js/deluge-all/details/PeersTab.js2
-rw-r--r--deluge/ui/web/js/deluge-all/preferences/ProxyField.js15
-rw-r--r--deluge/ui/web/js/deluge-all/preferences/ProxyPage.js23
-rw-r--r--deluge/ui/web/js/ext-extensions-debug.js4
-rw-r--r--deluge/ui/web/js/ext-extensions.js4
-rw-r--r--deluge/ui/web/js/ext-extensions/form/SpinnerGroup.js4
-rw-r--r--deluge/ui/web/json_api.py83
-rw-r--r--deluge/ui/web/themes/images/vista/basic-dialog/bg-center.gifbin865 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/vista/basic-dialog/bg-left.gifbin1039 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/vista/basic-dialog/bg-right.gifbin1039 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/vista/basic-dialog/close.gifbin350 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/vista/basic-dialog/collapse.gifbin333 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/vista/basic-dialog/dlg-bg.gifbin27857 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/vista/basic-dialog/e-handle.gifbin995 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/vista/basic-dialog/expand.gifbin351 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/vista/basic-dialog/hd-sprite.gifbin462 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/vista/basic-dialog/s-handle.gifbin992 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/vista/basic-dialog/se-handle.gifbin833 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/vista/basic-dialog/w-handle.gifbin817 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/vista/gradient-bg.gifbin1472 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/vista/grid/grid-split.gifbin817 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/vista/grid/grid-vista-hd.gifbin829 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/vista/layout/collapse.gifbin842 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/vista/layout/expand.gifbin842 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/vista/layout/gradient-bg.gifbin1202 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/vista/layout/ns-collapse.gifbin842 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/vista/layout/ns-expand.gifbin843 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/vista/layout/panel-close.gifbin829 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/vista/layout/panel-title-bg.gifbin888 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/vista/layout/panel-title-light-bg.gifbin846 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/vista/layout/stick.gifbin872 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/vista/layout/tab-close-on.gifbin880 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/vista/layout/tab-close.gifbin844 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/vista/qtip/bg.gifbin1024 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/vista/qtip/tip-sprite.gifbin4183 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/vista/s.gifbin43 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/vista/sizer/e-handle-dark.gifbin1062 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/vista/sizer/e-handle.gifbin1586 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/vista/sizer/ne-handle-dark.gifbin839 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/vista/sizer/ne-handle.gifbin854 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/vista/sizer/nw-handle-dark.gifbin839 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/vista/sizer/nw-handle.gifbin853 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/vista/sizer/s-handle-dark.gifbin1060 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/vista/sizer/s-handle.gifbin1318 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/vista/sizer/se-handle-dark.gifbin838 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/vista/sizer/se-handle.gifbin853 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/vista/sizer/sw-handle-dark.gifbin839 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/vista/sizer/sw-handle.gifbin855 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/vista/tabs/tab-btm-inactive-left-bg.gifbin879 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/vista/tabs/tab-btm-inactive-right-bg.gifbin1609 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/vista/tabs/tab-btm-left-bg.gifbin895 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/vista/tabs/tab-btm-right-bg.gifbin1608 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/vista/tabs/tab-sprite.gifbin3150 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/vista/toolbar/gray-bg.gifbin839 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/vista/toolbar/tb-btn-sprite.gifbin1110 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/README.txt2
-rw-r--r--deluge/ui/web/themes/images/yourtheme/box/corners-blue.gifbin1010 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/box/corners.gifbin1005 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/box/l-blue.gifbin810 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/box/l.gifbin810 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/box/r-blue.gifbin810 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/box/r.gifbin810 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/box/tb-blue.gifbin851 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/box/tb.gifbin839 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/button/arrow.gifbin828 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/button/btn.gifbin4298 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/button/group-cs.gifbin2459 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/button/group-lr.gifbin861 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/button/group-tb.gifbin846 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/button/s-arrow-b-noline.gifbin898 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/button/s-arrow-b.gifbin937 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/button/s-arrow-bo.gifbin139 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/button/s-arrow-noline.gifbin863 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/button/s-arrow-o.gifbin937 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/button/s-arrow.gifbin937 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/dd/drop-add.gifbin1001 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/dd/drop-no.gifbin949 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/dd/drop-yes.gifbin1016 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/editor/tb-sprite.gifbin2072 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/form/checkbox.gifbin2061 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/form/clear-trigger.gifbin1988 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/form/clear-trigger.psdbin11804 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/form/date-trigger.gifbin1603 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/form/date-trigger.psdbin12377 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/form/error-tip-corners.gifbin4183 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/form/exclamation.gifbin996 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/form/radio.gifbin1746 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/form/search-trigger.gifbin2182 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/form/search-trigger.psdbin15601 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/form/text-bg.gifbin819 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/form/trigger-square.gifbin1810 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/form/trigger-square.psdbin36542 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/form/trigger-tpl.gifbin1487 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/form/trigger.gifbin1816 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/form/trigger.psdbin37599 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/gradient-bg.gifbin1472 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/arrow-left-white.gifbin825 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/arrow-right-white.gifbin825 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/col-move-bottom.gifbin868 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/col-move-top.gifbin869 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/columns.gifbin962 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/dirty.gifbin832 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/done.gifbin133 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/drop-no.gifbin947 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/drop-yes.gifbin860 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/footer-bg.gifbin834 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/grid-blue-hd.gifbin829 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/grid-blue-split.gifbin817 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/grid-hrow.gifbin855 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/grid-loading.gifbin701 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/grid-split.gifbin817 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/grid-vista-hd.gifbin829 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/grid3-hd-btn.gifbin1229 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/grid3-hrow-over.gifbin823 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/grid3-hrow.gifbin836 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/grid3-special-col-bg.gifbin837 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/grid3-special-col-sel-bg.gifbin843 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/group-by.gifbin917 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/group-collapse.gifbin881 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/group-expand-sprite.gifbin955 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/group-expand.gifbin884 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/hd-pop.gifbin839 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/hmenu-asc.gifbin931 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/hmenu-desc.gifbin930 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/hmenu-lock.gifbin955 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/hmenu-lock.pngbin648 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/hmenu-unlock.gifbin971 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/hmenu-unlock.pngbin697 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/invalid_line.gifbin815 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/loading.gifbin771 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/mso-hd.gifbin875 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/nowait.gifbin884 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/page-first-disabled.gifbin925 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/page-first.gifbin925 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/page-last-disabled.gifbin923 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/page-last.gifbin923 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/page-next-disabled.gifbin875 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/page-next.gifbin875 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/page-prev-disabled.gifbin879 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/page-prev.gifbin879 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/pick-button.gifbin1036 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/refresh.gifbin977 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/row-check-sprite.gifbin1083 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/row-expand-sprite.gifbin955 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/row-over.gifbin823 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/row-sel.gifbin823 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/sort-hd.gifbin1473 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/sort_asc.gifbin830 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/sort_desc.gifbin833 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/grid/wait.gifbin1100 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/layout/collapse.gifbin842 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/layout/expand.gifbin842 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/layout/gradient-bg.gifbin1472 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/layout/mini-bottom.gifbin856 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/layout/mini-left.gifbin871 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/layout/mini-right.gifbin872 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/layout/mini-top.gifbin856 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/layout/ns-collapse.gifbin842 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/layout/ns-expand.gifbin843 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/layout/panel-close.gifbin829 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/layout/panel-title-bg.gifbin838 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/layout/panel-title-light-bg.gifbin835 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/layout/stick.gifbin874 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/layout/stuck.gifbin92 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/layout/tab-close-on.gifbin880 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/layout/tab-close.gifbin859 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/menu/checked.gifbin959 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/menu/group-checked.gifbin891 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/menu/item-over.gifbin820 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/menu/menu-parent.gifbin854 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/menu/menu.gifbin834 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/menu/unchecked.gifbin941 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/panel/corners-sprite.gifbin1418 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/panel/left-right.gifbin815 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/panel/light-hd.gifbin827 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/panel/tool-sprite-tpl.gifbin971 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/panel/tool-sprites.gifbin4392 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/panel/tools-sprites-trans.gifbin2843 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/panel/top-bottom.gifbin875 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/panel/top-bottom.pngbin218 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/panel/white-corners-sprite.gifbin1366 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/panel/white-left-right.gifbin815 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/panel/white-top-bottom.gifbin872 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/progress/progress-bg.gifbin834 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/qtip/bg.gifbin1091 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/qtip/close.gifbin972 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/qtip/tip-anchor-sprite.gifbin951 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/qtip/tip-sprite.gifbin4271 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/s.gifbin43 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/shadow-c.pngbin118 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/shadow-lr.pngbin135 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/shadow.pngbin311 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/shared/blue-loading.gifbin3236 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/shared/calendar.gifbin979 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/shared/glass-bg.gifbin873 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/shared/hd-sprite.gifbin1099 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/shared/large-loading.gifbin3236 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/shared/left-btn.gifbin870 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/shared/loading-balls.gifbin2118 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/shared/right-btn.gifbin871 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/shared/warning.gifbin960 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/sizer/e-handle-dark.gifbin1062 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/sizer/e-handle.gifbin1586 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/sizer/ne-handle-dark.gifbin839 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/sizer/ne-handle.gifbin854 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/sizer/nw-handle-dark.gifbin839 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/sizer/nw-handle.gifbin853 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/sizer/s-handle-dark.gifbin1060 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/sizer/s-handle.gifbin1318 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/sizer/se-handle-dark.gifbin838 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/sizer/se-handle.gifbin853 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/sizer/square.gifbin864 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/sizer/sw-handle-dark.gifbin839 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/sizer/sw-handle.gifbin855 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/slider/slider-bg.pngbin300 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/slider/slider-thumb.pngbin933 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/slider/slider-v-bg.pngbin288 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/slider/slider-v-thumb.pngbin883 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/tabs/scroll-left.gifbin1295 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/tabs/scroll-right.gifbin1300 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/tabs/scroller-bg.gifbin1100 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/tabs/tab-btm-inactive-left-bg.gifbin886 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/tabs/tab-btm-inactive-right-bg.gifbin1386 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/tabs/tab-btm-left-bg.gifbin1402 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/tabs/tab-btm-over-left-bg.gifbin191 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/tabs/tab-btm-over-right-bg.gifbin638 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/tabs/tab-btm-right-bg.gifbin863 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/tabs/tab-close.gifbin896 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/tabs/tab-strip-bg.gifbin835 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/tabs/tab-strip-bg.pngbin259 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/tabs/tab-strip-btm-bg.gifbin826 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/tabs/tabs-sprite.gifbin2120 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/toolbar/bg.gifbin904 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/toolbar/btn-arrow-light.gifbin916 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/toolbar/btn-arrow.gifbin919 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/toolbar/btn-over-bg.gifbin837 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/toolbar/gray-bg.gifbin832 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/toolbar/more.gifbin845 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/toolbar/tb-bg.gifbin862 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/toolbar/tb-btn-sprite.gifbin1127 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/toolbar/tb-xl-btn-sprite.gifbin1663 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/toolbar/tb-xl-sep.gifbin810 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/tree/arrows.gifbin617 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/tree/drop-add.gifbin1001 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/tree/drop-between.gifbin907 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/tree/drop-no.gifbin949 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/tree/drop-over.gifbin911 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/tree/drop-under.gifbin911 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/tree/drop-yes.gifbin1016 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/tree/elbow-end-minus-nl.gifbin898 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/tree/elbow-end-minus.gifbin905 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/tree/elbow-end-plus-nl.gifbin900 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/tree/elbow-end-plus.gifbin907 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/tree/elbow-end.gifbin844 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/tree/elbow-line.gifbin846 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/tree/elbow-minus-nl.gifbin898 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/tree/elbow-minus.gifbin908 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/tree/elbow-plus-nl.gifbin900 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/tree/elbow-plus.gifbin910 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/tree/elbow.gifbin850 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/tree/folder-open.gifbin956 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/tree/folder.gifbin952 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/tree/leaf.gifbin945 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/tree/loading.gifbin771 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/tree/s.gifbin43 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/window/icon-error.gifbin1669 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/window/icon-info.gifbin1586 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/window/icon-question.gifbin1607 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/window/icon-warning.gifbin1483 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/window/left-corners.pngbin200 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/window/left-corners.psdbin15576 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/window/left-right.pngbin152 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/window/left-right.psdbin24046 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/window/right-corners.pngbin256 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/window/right-corners.psdbin15530 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/window/top-bottom.pngbin180 -> 0 bytes
-rw-r--r--deluge/ui/web/themes/images/yourtheme/window/top-bottom.psdbin32128 -> 0 bytes
-rwxr-xr-xsetup.py3
355 files changed, 1594 insertions, 1029 deletions
diff --git a/.gitignore b/.gitignore
index 2a7eb4d80..cf7a67e64 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,3 +9,4 @@ dist
_trial_temp
deluge/i18n/*/
*.desktop
+.build_data*
diff --git a/ChangeLog b/ChangeLog
index 1077fbfea..3af70b95a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -32,6 +32,7 @@
* Implemented sequential downloads UI handling.
* #378: Allow showing a pieces bar instead of a regular progress bar in a
torrent's status tab.
+ * #2093: Make torrent opening compatible with all unicode paths.
==== Blocklist Plugin ====
* #1382: Implemented whitelist support to both core and GTK UI.
@@ -44,6 +45,72 @@
=== Deluge 1.3.6 (In Development) ===
==== Core ====
* Catch & log KeyError when removing a torrent from the queued torrents set
+ * Fix moving/renaming torrents issues when using libtorrent 0.16
+ * Make sure queue order is preserved when restarting
+ * #2160: Disable use of python bindings for libtorrent extensions and replace with session flag
+ * #2163: Fix unable add torrent file with empty (0:) encoding tag
+ * #2201: Fix error in authmanager if auth file has extra newlines
+ * #2109: Fix the Proxy settings not being cleared by setting None
+ * #2110: Fix accepting magnet uris with xt param anywhere within them
+ * #2204: Fix daemon shutdown hang with large numbers of torrents
+
+==== Client ====
+ * Fix keyerrors after removing torrents from UIs
+
+==== GtkUI ====
+ * Add move completed option to add torrent dialog
+ * Prevent jitter in torrent view
+ * Fix torrent creation with non-ascii characters
+ * Fix #2100 : Add option not to bring main window to front when adding torrents through ipcinterface
+ * Add Quit Dialog when toggling classic mode in preferences and only show connection manager when not in classic mode.
+ * #2169: Fix 'Download Location' in the Add Torrent Dialog not set correctly when folder typed into Other->Location field
+ * #2171: Fix the Add Peer dialog not responding if empty or invalid values entered
+ * #2104: Fix no title set for the appindicator
+ * #2086: Fix submenus and icons for appindicator
+ * #2146: Fix missing translations in View|Tabs submenu
+ * Fix torrent names on libtorrent 0.16 on windows
+ * #2147: Fix missing translations for plugin preferences page
+ * #1474: Fix the on_show_prefs hook not being executed immediatly after enabling a plugin
+ * #1946: Fix ReactorNotRestartable error when set as startup application
+ * #2130: Fix same name can be given to different files in Add Torrent dialog
+ * #2129: Fix empty filename able to be set in AddTorrent dialog
+ * #2228: Fix Apply-To-All in AddTorrent Dialog copying file renames to other torrents
+
+==== Console ====
+ * LP#1004793: Enable use of connect command in non-interactive mode
+ * Ensure console commands are executed in order
+ * #2065: Fix crash with missing closing quote
+ * #1397: Add support for -s STATE in info command
+
+==== WebUI ====
+ * Add move completed option to add torrent dialog
+ * #2112: Fix world readable tmp directory in json_api
+ * #2069: Fix login window layout problem when using larger than default font size
+ * #1890: Fix columns in files and peers view could use some spacing
+ * #2103: Fix sorting by name is case-sensitive [sedulous]
+ * #2120: Fix manually entered values not being saved in spinners
+ * #2212: Fix unable to scroll in proxy preferences page
+ * Fix autoconnecting to the default host
+ * #2046: Fix plugins not enabling properly until after refreshing page
+ * #2125: Fix plugin methods not being available when enabled until restart
+ * #2085: Fix not showing torrents in sidebar for categories other than 'All' in classic mode
+ * #2232: Fix flag icon path in Peers Tab missing deluge.config.base
+ * Fix submenus closing upon mouse click
+
+==== Windows OS ====
+ * Hide the cmd windows when running deluged.exe or deluge-web.exe
+ * Add deluged-debug.exe and deluge-web-debug.exe that still show the cmd window
+ * Add gtk locale files to fix untranslated text
+ * Fix the Open Folder option not working with non-ascii paths
+ * Fix the daemon starting with config dir containing spaces
+ * Fix Windows tray submenu items requiring right-click instead of left-click
+ * Fix issue with adding some torrents with illegal characters via url in gtk client
+
+==== OS X ====
+ * Fix Open File/Folder option
+
+==== Execute ====
+ * Fix execute plugin not working with unicode torrent names
=== Deluge 1.3.5 (09 April 2012) ===
==== GtkUI ====
diff --git a/DEPENDS b/DEPENDS
index a74440609..97d5870e8 100644
--- a/DEPENDS
+++ b/DEPENDS
@@ -1,5 +1,5 @@
=== Core ===
- * python >= 2.5
+ * python >= 2.6
* twisted >= 8.1
* twisted-web >= 8.1
* pyopenssl
@@ -11,6 +11,7 @@
* chardet
* geoip-database (optional)
* setproctitle (optional)
+ * rencode >= 1.0.2 (optional), a pure python version is included
* libtorrent >= 0.16.1, or build the included version
diff --git a/deluge/_libtorrent.py b/deluge/_libtorrent.py
index ab782d67a..898cfb150 100644
--- a/deluge/_libtorrent.py
+++ b/deluge/_libtorrent.py
@@ -45,9 +45,9 @@ supports.
"""
-REQUIRED_VERSION = "0.14.9.0"
+REQUIRED_VERSION = "0.16.1.0"
-def check_version(LT):
+def check_version(lt):
from deluge.common import VersionSplit
if VersionSplit(lt.version) < VersionSplit(REQUIRED_VERSION):
raise ImportError("This version of Deluge requires libtorrent >=%s!" % REQUIRED_VERSION)
diff --git a/deluge/common.py b/deluge/common.py
index ea615df20..f3236dea5 100644
--- a/deluge/common.py
+++ b/deluge/common.py
@@ -37,17 +37,23 @@
"""Common functions for various parts of Deluge to use."""
import os
+import sys
import time
import subprocess
import platform
import chardet
import logging
+import pkg_resources
+import gettext
+import locale
try:
import json
except ImportError:
import simplejson as json
+from deluge.error import *
+
log = logging.getLogger(__name__)
# Do a little hack here just in case the user has json-py installed since it
@@ -65,12 +71,6 @@ if not hasattr(json, "dumps"):
json.dump = dump
json.load = load
-import pkg_resources
-import gettext
-import locale
-
-from deluge.error import *
-
LT_TORRENT_STATE = {
"Queued": 0,
"Checking": 1,
@@ -90,7 +90,6 @@ LT_TORRENT_STATE = {
7: "Checking Resume Data"
}
-
TORRENT_STATE = [
"Allocating",
"Checking",
@@ -134,17 +133,26 @@ def get_default_config_dir(filename=None):
:rtype: string
"""
+
if windows_check():
- if filename:
- return os.path.join(os.environ.get("APPDATA"), "deluge", filename)
- else:
- return os.path.join(os.environ.get("APPDATA"), "deluge")
+ def save_config_path(resource):
+ appDataPath = os.environ.get("APPDATA")
+ if not appDataPath:
+ import _winreg
+ hkey = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders")
+ appDataReg = _winreg.QueryValueEx(hkey, "AppData")
+ appDataPath = appDataReg[0]
+ _winreg.CloseKey(hkey)
+ return os.path.join(appDataPath, resource)
else:
- import xdg.BaseDirectory
- if filename:
- return os.path.join(xdg.BaseDirectory.save_config_path("deluge"), filename)
- else:
- return xdg.BaseDirectory.save_config_path("deluge")
+ from xdg.BaseDirectory import save_config_path
+ if not filename:
+ filename = ''
+ try:
+ return os.path.join(save_config_path("deluge"), filename)
+ except OSError, e:
+ log.error("Unable to use default config directory, exiting... (%s)", e)
+ sys.exit(1)
def get_default_download_dir():
"""
@@ -231,7 +239,7 @@ def open_file(path):
"""
if windows_check():
- os.startfile("%s" % path)
+ os.startfile(path.decode("utf8"))
elif osx_check():
subprocess.Popen(["open", "%s" % path])
else:
@@ -448,7 +456,9 @@ def is_magnet(uri):
True
"""
- if uri[:20] == "magnet:?xt=urn:btih:":
+ magnet_scheme = 'magnet:?'
+ xt_param = 'xt=urn:btih:'
+ if uri.startswith(magnet_scheme) and xt_param in uri:
return True
return False
@@ -516,9 +526,8 @@ def free_space(path):
raise InvalidPathError("%s is not a valid path" % path)
if windows_check():
- import win32file
- sectors, bytes, free, total = map(long, win32file.GetDiskFreeSpace(path))
- return (free * sectors * bytes)
+ from win32file import GetDiskFreeSpaceEx
+ return GetDiskFreeSpaceEx(path)[0]
else:
disk_data = os.statvfs(path.encode("utf8"))
block_size = disk_data.f_frsize
@@ -542,15 +551,23 @@ def is_ip(ip):
import socket
#first we test ipv4
try:
- if socket.inet_pton(socket.AF_INET, "%s" % (ip)):
- return True
+ if windows_check():
+ if socket.inet_aton("%s" % (ip)):
+ return True
+ else:
+ if socket.inet_pton(socket.AF_INET, "%s" % (ip)):
+ return True
except socket.error:
if not socket.has_ipv6:
return False
#now test ipv6
try:
- if socket.inet_pton(socket.AF_INET6, "%s" % (ip)):
+ if windows_check():
+ log.warning("ipv6 check unavailable on windows")
return True
+ else:
+ if socket.inet_pton(socket.AF_INET6, "%s" % (ip)):
+ return True
except socket.error:
return False
@@ -608,37 +625,55 @@ def xml_encode(string):
def decode_string(s, encoding="utf8"):
"""
- Decodes a string and re-encodes it in utf8. If it cannot decode using
- `:param:encoding` then it will try to detect the string encoding and
- decode it.
+ Decodes a string and return unicode. If it cannot decode using
+ `:param:encoding` then it will try latin1, and if that fails,
+ try to detect the string encoding. If that fails, decode with
+ ignore.
:param s: string to decode
:type s: string
:keyword encoding: the encoding to use in the decoding
:type encoding: string
+ :returns: s converted to unicode
+ :rtype: unicode
"""
+ if not s:
+ return u''
+ elif isinstance(s, unicode):
+ return s
- try:
- s = s.decode(encoding).encode("utf8", "ignore")
- except UnicodeDecodeError:
- s = s.decode(chardet.detect(s)["encoding"], "ignore").encode("utf8", "ignore")
- return s
+ encodings = [lambda: ("utf8", 'strict'),
+ lambda: ("iso-8859-1", 'strict'),
+ lambda: (chardet.detect(s)["encoding"], 'strict'),
+ lambda: (chardet.detect(s)["encoding"], 'ignore')]
-def utf8_encoded(s):
+ if not encoding is "utf8":
+ encodings.insert(0, lambda: (encoding, 'strict'))
+
+ for l in encodings:
+ try:
+ return s.decode(*l())
+ except UnicodeDecodeError:
+ pass
+ return u''
+
+def utf8_encoded(s, encoding="utf8"):
"""
Returns a utf8 encoded string of s
:param s: (unicode) string to (re-)encode
:type s: basestring
+ :keyword encoding: the encoding to use in the decoding
+ :type encoding: string
:returns: a utf8 encoded string of s
:rtype: str
"""
if isinstance(s, str):
- s = decode_string(s)
+ s = decode_string(s, encoding).encode("utf8")
elif isinstance(s, unicode):
- s = s.encode("utf8", "ignore")
+ s = s.encode("utf8")
return s
class VersionSplit(object):
@@ -741,3 +776,39 @@ def setup_translations(setup_pygtk=False):
log.exception(e)
import __builtin__
__builtin__.__dict__["_"] = lambda x: x
+
+def unicode_argv():
+ """ Gets sys.argv as list of unicode objects on any platform."""
+ if windows_check():
+ # Versions 2.x of Python don't support Unicode in sys.argv on
+ # Windows, with the underlying Windows API instead replacing multi-byte
+ # characters with '?'.
+ from ctypes import POINTER, byref, cdll, c_int, windll
+ from ctypes.wintypes import LPCWSTR, LPWSTR
+
+ GetCommandLineW = cdll.kernel32.GetCommandLineW
+ GetCommandLineW.argtypes = []
+ GetCommandLineW.restype = LPCWSTR
+
+ CommandLineToArgvW = windll.shell32.CommandLineToArgvW
+ CommandLineToArgvW.argtypes = [LPCWSTR, POINTER(c_int)]
+ CommandLineToArgvW.restype = POINTER(LPWSTR)
+
+ cmd = GetCommandLineW()
+ argc = c_int(0)
+ argv = CommandLineToArgvW(cmd, byref(argc))
+ if argc.value > 0:
+ # Remove Python executable and commands if present
+ start = argc.value - len(sys.argv)
+ return [argv[i] for i in
+ xrange(start, argc.value)]
+ else:
+ # On other platforms, we have to find the likely encoding of the args and decode
+ # First check if sys.stdout or stdin have encoding set
+ encoding = getattr(sys.stdout, "encoding") or getattr(sys.stdin, "encoding")
+ # If that fails, check what the locale is set to
+ encoding = encoding or locale.getpreferredencoding()
+ # As a last resort, just default to utf-8
+ encoding = encoding or "utf-8"
+
+ return [arg.decode(encoding) for arg in sys.argv]
diff --git a/deluge/component.py b/deluge/component.py
index 538d2f9f6..6085db277 100644
--- a/deluge/component.py
+++ b/deluge/component.py
@@ -34,6 +34,7 @@
#
import logging
+from collections import defaultdict
from twisted.internet.defer import maybeDeferred, succeed, DeferredList, fail
from twisted.internet.task import LoopingCall
@@ -225,6 +226,8 @@ class ComponentRegistry(object):
"""
def __init__(self):
self.components = {}
+ # Stores all of the components that are dependent on a particular component
+ self.dependents = defaultdict(list)
def register(self, obj):
"""
@@ -243,6 +246,9 @@ class ComponentRegistry(object):
"Component already registered with name %s" % name)
self.components[obj._component_name] = obj
+ if obj._component_depend:
+ for depend in obj._component_depend:
+ self.dependents[depend].append(name)
def deregister(self, obj):
"""
@@ -317,11 +323,23 @@ class ComponentRegistry(object):
elif isinstance(names, str):
names = [names]
+ def on_dependents_stopped(result, name):
+ return self.components[name]._component_stop()
+
+ stopped_in_deferred = set()
deferreds = []
for name in names:
+ if name in stopped_in_deferred:
+ continue
if name in self.components:
- deferreds.append(self.components[name]._component_stop())
+ if name in self.dependents:
+ # If other components depend on this component, stop them first
+ d = self.stop(self.dependents[name]).addCallback(on_dependents_stopped, name)
+ deferreds.append(d)
+ stopped_in_deferred.update(self.dependents[name])
+ else:
+ deferreds.append(self.components[name]._component_stop())
return DeferredList(deferreds)
@@ -360,7 +378,7 @@ class ComponentRegistry(object):
:param names: a list of Components to resume
:type names: list
- :returns: a Deferred object that will fire once all Components have been sucessfully resumed
+ :returns: a Deferred object that will fire once all Components have been successfully resumed
:rtype: twisted.internet.defer.Deferred
"""
@@ -384,16 +402,14 @@ class ComponentRegistry(object):
be called when the program is exiting to ensure all Components have a
chance to properly shutdown.
- :returns: a Deferred object that will fire once all Components have been sucessfully resumed
+ :returns: a Deferred object that will fire once all Components have been successfully shut down
:rtype: twisted.internet.defer.Deferred
"""
- deferreds = []
+ def on_stopped(result):
+ return DeferredList(map(lambda c: c._component_shutdown(), self.components.values()))
- for component in self.components.values():
- deferreds.append(component._component_shutdown())
-
- return DeferredList(deferreds)
+ return self.stop(self.components.keys()).addCallback(on_stopped)
def update(self):
"""
diff --git a/deluge/core/alertmanager.py b/deluge/core/alertmanager.py
index e2ff6c865..a4464eb8c 100644
--- a/deluge/core/alertmanager.py
+++ b/deluge/core/alertmanager.py
@@ -46,6 +46,7 @@ from twisted.internet import reactor
import deluge.component as component
from deluge._libtorrent import lt
+from deluge.common import decode_string
log = logging.getLogger(__name__)
@@ -75,7 +76,8 @@ class AlertManager(component.Component):
def stop(self):
for dc in self.delayed_calls:
- dc.cancel()
+ if dc.active():
+ dc.cancel()
self.delayed_calls = []
def register_handler(self, alert_type, handler):
@@ -121,7 +123,7 @@ class AlertManager(component.Component):
while alert is not None:
alert_type = type(alert).__name__
# Display the alert message
- log.debug("%s: %s", alert_type, alert.message())
+ log.debug("%s: %s", alert_type, decode_string(alert.message()))
# Call any handlers for this alert type
if alert_type in self.handlers:
for handler in self.handlers[alert_type]:
diff --git a/deluge/core/authmanager.py b/deluge/core/authmanager.py
index 771043e8b..f8cffbb7c 100644
--- a/deluge/core/authmanager.py
+++ b/deluge/core/authmanager.py
@@ -236,10 +236,10 @@ class AuthManager(component.Component):
f = open(auth_file, "r").readlines()
for line in f:
- if line.startswith("#"):
- # This is a comment line
- continue
line = line.strip()
+ if line.startswith("#") or not line:
+ # This line is a comment or empty
+ continue
try:
lsplit = line.split(":")
except Exception, e:
diff --git a/deluge/core/core.py b/deluge/core/core.py
index e69944790..242359a9d 100644
--- a/deluge/core/core.py
+++ b/deluge/core/core.py
@@ -94,6 +94,8 @@ class Core(component.Component):
self.settings.user_agent = "Deluge/%(deluge_version)s Libtorrent/%(lt_version)s" % \
{ 'deluge_version': deluge.common.get_version(),
'lt_version': self.get_libtorrent_version().rpartition(".")[0] }
+ # Increase the alert queue size so that alerts don't get lost
+ self.settings.alert_queue_size = 10000
# Set session settings
self.settings.send_redundant_have = True
diff --git a/deluge/core/filtermanager.py b/deluge/core/filtermanager.py
index 25ae4be1b..53e95030c 100644
--- a/deluge/core/filtermanager.py
+++ b/deluge/core/filtermanager.py
@@ -153,9 +153,8 @@ class FilterManager(component.Component):
#sanitize input: filter-value must be a list of strings
for key, value in filter_dict.items():
- if isinstance(value, str):
- filter_dict[key] = [value]
-
+ if isinstance(value, basestring):
+ filter_dict[key] = [value]
if "id"in filter_dict: #optimized filter for id:
torrent_ids = list(filter_dict["id"])
diff --git a/deluge/core/rpcserver.py b/deluge/core/rpcserver.py
index 3ecbd39e8..649c2ce29 100644
--- a/deluge/core/rpcserver.py
+++ b/deluge/core/rpcserver.py
@@ -509,7 +509,7 @@ class RPCServer(component.Component):
"""
log.debug("intevents: %s", self.factory.interested_events)
# Find sessions interested in this event
- for session_id, interest in self.factory.interested_events.iteritems():
+ for session_id, interest in self.factory.interested_events.items():
if event.name in interest:
log.debug("Emit Event: %s %s", event.name, event.args)
# This session is interested so send a RPC_EVENT
diff --git a/deluge/core/torrent.py b/deluge/core/torrent.py
index cafec162c..c5fd81955 100644
--- a/deluge/core/torrent.py
+++ b/deluge/core/torrent.py
@@ -37,9 +37,12 @@
import os
import time
import logging
+import re
from urllib import unquote
from urlparse import urlparse
+from twisted.internet.defer import Deferred, DeferredList
+from twisted.internet.task import LoopingCall
from deluge._libtorrent import lt
import deluge.common
@@ -116,7 +119,6 @@ class Torrent(object):
# We use this to return dicts that only contain changes from the previous
# {session_id: status_dict, ...}
self.prev_status = {}
- from twisted.internet.task import LoopingCall
self.prev_status_cleanup_loop = LoopingCall(self.cleanup_prev_status)
self.prev_status_cleanup_loop.start(10)
@@ -125,14 +127,10 @@ class Torrent(object):
# Set the torrent_id for this torrent
self.torrent_id = str(handle.info_hash())
- # Let's us know if we're waiting on a lt alert
- self.waiting_on_resume_data = False
-
- # Keep a list of file indexes we're waiting for file_rename alerts on
- # This also includes the old_folder and new_folder to know what signal to send
+ # Keep a list of Deferreds for file indexes we're waiting for file_rename alerts on
# This is so we can send one folder_renamed signal instead of multiple
# file_renamed signals.
- # [(old_folder, new_folder, [*indexes]), ...]
+ # [{index: Deferred, ...}, ...]
self.waiting_on_folder_rename = []
# We store the filename just in case we need to make a copy of the torrentfile
@@ -177,13 +175,7 @@ class Torrent(object):
# Tracker list
self.trackers = []
# Create a list of trackers
- for value in self.handle.trackers():
- if lt.version_minor < 15:
- tracker = {}
- tracker["url"] = value.url
- tracker["tier"] = value.tier
- else:
- tracker = value
+ for tracker in self.handle.trackers():
self.trackers.append(tracker)
# Various torrent options
@@ -240,8 +232,13 @@ class Torrent(object):
"max_upload_speed": self.set_max_upload_speed,
"prioritize_first_last_pieces": self.set_prioritize_first_last,
"sequential_download": self.set_sequential_download
-
}
+
+ # set_prioritize_first_last is called by set_file_priorities,
+ # so remove if file_priorities is set in options.
+ if "file_priorities" in options:
+ del OPTIONS_FUNCS["prioritize_first_last_pieces"]
+
for (key, value) in options.items():
if OPTIONS_FUNCS.has_key(key):
OPTIONS_FUNCS[key](value)
@@ -252,7 +249,7 @@ class Torrent(object):
def get_name(self):
if self.handle.has_metadata():
- name = self.torrent_info.file_at(0).path.split("/", 1)[0]
+ name = self.torrent_info.file_at(0).path.replace("\\", "/", 1).split("/", 1)[0]
if not name:
name = self.torrent_info.name()
try:
@@ -304,26 +301,44 @@ class Torrent(object):
def set_prioritize_first_last(self, prioritize):
self.options["prioritize_first_last_pieces"] = prioritize
- if self.handle.has_metadata():
- if self.options["compact_allocation"]:
- log.debug("Setting first/last priority with compact "
- "allocation does not work!")
- return
-
- paths = {}
- ti = self.handle.get_torrent_info()
- for n in range(ti.num_pieces()):
- slices = ti.map_block(n, 0, ti.piece_size(n))
- for slice in slices:
- if self.handle.file_priority(slice.file_index):
- paths.setdefault(slice.file_index, []).append(n)
-
- priorities = self.handle.piece_priorities()
- for pieces in paths.itervalues():
- two_percent = int(0.02*len(pieces)) or 1
- for piece in pieces[:two_percent]+pieces[-two_percent:]:
- priorities[piece] = 7 if prioritize else 1
- self.handle.prioritize_pieces(priorities)
+ if not prioritize:
+ # If we are turning off this option, call set_file_priorities to
+ # reset all the piece priorities
+ self.set_file_priorities(self.options["file_priorities"])
+ return
+ if not self.handle.has_metadata():
+ return
+ if self.options["compact_allocation"]:
+ log.debug("Setting first/last priority with compact "
+ "allocation does not work!")
+ return
+ # A list of priorities for each piece in the torrent
+ priorities = self.handle.piece_priorities()
+ prioritized_pieces = []
+ ti = self.handle.get_torrent_info()
+ for i in range(ti.num_files()):
+ f = ti.file_at(i)
+ two_percent_bytes = int(0.02 * f.size)
+ # Get the pieces for the byte offsets
+ first_start = ti.map_file(i, 0, 0).piece
+ first_end = ti.map_file(i, two_percent_bytes, 0).piece
+ last_start = ti.map_file(i, f.size - two_percent_bytes, 0).piece
+ last_end = ti.map_file(i, max(f.size - 1, 0), 0).piece
+
+ first_end += 1
+ last_end += 1
+ prioritized_pieces.append((first_start, first_end))
+ prioritized_pieces.append((last_start, last_end))
+
+ # Creating two lists with priorites for the first/last pieces
+ # of this file, and insert the priorities into the list
+ first_list = [7] * (first_end - first_start)
+ last_list = [7] * (last_end - last_start)
+ priorities[first_start:first_end] = first_list
+ priorities[last_start:last_end] = last_list
+ # Setting the priorites for all the pieces of this torrent
+ self.handle.prioritize_pieces(priorities)
+ return prioritized_pieces, priorities
def set_sequential_download(self, set_sequencial):
self.options["sequential_download"] = set_sequencial
@@ -380,7 +395,8 @@ class Torrent(object):
log.warning("File priorities were not set for this torrent")
# Set the first/last priorities if needed
- self.set_prioritize_first_last(self.options["prioritize_first_last_pieces"])
+ if self.options["prioritize_first_last_pieces"]:
+ self.set_prioritize_first_last(self.options["prioritize_first_last_pieces"])
def set_trackers(self, trackers):
"""Sets trackers"""
@@ -885,31 +901,32 @@ class Torrent(object):
def move_storage(self, dest):
"""Move a torrent's storage location"""
-
- if deluge.common.windows_check():
- # Attempt to convert utf8 path to unicode
- # Note: Inconsistent encoding for 'dest', needs future investigation
- try:
- dest_u = unicode(dest, "utf-8")
- except TypeError:
- # String is already unicode
- dest_u = dest
- else:
- dest_u = dest
+ try:
+ dest = unicode(dest, "utf-8")
+ except TypeError:
+ # String is already unicode
+ pass
- if not os.path.exists(dest_u):
+ if not os.path.exists(dest):
try:
# Try to make the destination path if it doesn't exist
- os.makedirs(dest_u)
+ os.makedirs(dest)
except IOError, e:
log.exception(e)
log.error("Could not move storage for torrent %s since %s does "
"not exist and could not create the directory.",
- self.torrent_id, dest_u)
+ self.torrent_id, dest)
return False
+
+ dest_bytes = dest.encode('utf-8')
try:
- self.handle.move_storage(dest_u)
- except:
+ # libtorrent needs unicode object if wstrings are enabled, utf8 bytestring otherwise
+ try:
+ self.handle.move_storage(dest)
+ except TypeError:
+ self.handle.move_storage(dest_bytes)
+ except Exception, e:
+ log.error("Error calling libtorrent move_storage: %s" % e)
return False
return True
@@ -918,7 +935,6 @@ class Torrent(object):
"""Signals libtorrent to build resume data for this torrent, it gets
returned in a libtorrent alert"""
self.handle.save_resume_data()
- self.waiting_on_resume_data = True
def write_torrentfile(self):
"""Writes the torrent file"""
@@ -985,12 +1001,26 @@ class Torrent(object):
"""Renames files in the torrent. 'filenames' should be a list of
(index, filename) pairs."""
for index, filename in filenames:
+ # Make sure filename is a unicode object
+ try:
+ filename = unicode(filename, "utf-8")
+ except TypeError:
+ pass
filename = sanitize_filepath(filename)
- self.handle.rename_file(index, filename.encode("utf-8"))
+ # libtorrent needs unicode object if wstrings are enabled, utf8 bytestring otherwise
+ try:
+ self.handle.rename_file(index, filename)
+ except TypeError:
+ self.handle.rename_file(index, filename.encode("utf-8"))
def rename_folder(self, folder, new_folder):
- """Renames a folder within a torrent. This basically does a file rename
- on all of the folders children."""
+ """
+ Renames a folder within a torrent. This basically does a file rename
+ on all of the folders children.
+
+ :returns: A deferred which fires when the rename is complete
+ :rtype: twisted.internet.defer.Deferred
+ """
log.debug("attempting to rename folder: %s to %s", folder, new_folder)
if len(new_folder) < 1:
log.error("Attempting to rename a folder with an invalid folder name: %s", new_folder)
@@ -998,13 +1028,57 @@ class Torrent(object):
new_folder = sanitize_filepath(new_folder, folder=True)
- wait_on_folder = (folder, new_folder, [])
+ def on_file_rename_complete(result, wait_dict, index):
+ wait_dict.pop(index, None)
+
+ wait_on_folder = {}
+ self.waiting_on_folder_rename.append(wait_on_folder)
for f in self.get_files():
if f["path"].startswith(folder):
- # Keep a list of filerenames we're waiting on
- wait_on_folder[2].append(f["index"])
+ # Keep track of filerenames we're waiting on
+ wait_on_folder[f["index"]] = Deferred().addBoth(on_file_rename_complete, wait_on_folder, f["index"])
self.handle.rename_file(f["index"], f["path"].replace(folder, new_folder, 1).encode("utf-8"))
- self.waiting_on_folder_rename.append(wait_on_folder)
+
+ def on_folder_rename_complete(result, torrent, folder, new_folder):
+ component.get("EventManager").emit(TorrentFolderRenamedEvent(torrent.torrent_id, folder, new_folder))
+ # Empty folders are removed after libtorrent folder renames
+ self.remove_empty_folders(folder)
+ torrent.waiting_on_folder_rename = filter(None, torrent.waiting_on_folder_rename)
+ component.get("TorrentManager").save_resume_data((self.torrent_id,))
+
+ d = DeferredList(wait_on_folder.values())
+ d.addBoth(on_folder_rename_complete, self, folder, new_folder)
+ return d
+
+ def remove_empty_folders(self, folder):
+ """
+ Recursively removes folders but only if they are empty.
+ Cleans up after libtorrent folder renames.
+
+ """
+ info = self.get_status(['save_path'])
+ # Regex removes leading slashes that causes join function to ignore save_path
+ folder_full_path = os.path.join(info['save_path'], re.sub("^/*", "", folder))
+ folder_full_path = os.path.normpath(folder_full_path)
+
+ try:
+ if not os.listdir(folder_full_path):
+ os.removedirs(folder_full_path)
+ log.debug("Removed Empty Folder %s", folder_full_path)
+ else:
+ for root, dirs, files in os.walk(folder_full_path, topdown=False):
+ for name in dirs:
+ try:
+ os.removedirs(os.path.join(root, name))
+ log.debug("Removed Empty Folder %s", os.path.join(root, name))
+ except OSError as (errno, strerror):
+ from errno import ENOTEMPTY
+ if errno == ENOTEMPTY:
+ # Error raised if folder is not empty
+ log.debug("%s", strerror)
+
+ except OSError as (errno, strerror):
+ log.debug("Cannot Remove Folder: %s (ErrNo %s)", strerror, errno)
def cleanup_prev_status(self):
"""
diff --git a/deluge/core/torrentmanager.py b/deluge/core/torrentmanager.py
index b3c6d4cba..9a8d8a59c 100644
--- a/deluge/core/torrentmanager.py
+++ b/deluge/core/torrentmanager.py
@@ -38,13 +38,12 @@
import cPickle
import os
-import time
import shutil
import operator
import logging
-import re
from twisted.internet.task import LoopingCall
+from twisted.internet.defer import Deferred, DeferredList
from deluge._libtorrent import lt
@@ -56,7 +55,7 @@ from deluge.core.authmanager import AUTH_LEVEL_ADMIN
from deluge.core.torrent import Torrent
from deluge.core.torrent import TorrentOptions
import deluge.core.oldstateupgrader
-from deluge.common import utf8_encoded
+from deluge.common import utf8_encoded, decode_string
log = logging.getLogger(__name__)
@@ -133,7 +132,7 @@ class TorrentManager(component.Component):
def __init__(self):
component.Component.__init__(self, "TorrentManager", interval=5,
- depend=["CorePluginManager"])
+ depend=["CorePluginManager", "AlertManager"])
log.debug("TorrentManager init..")
# Set the libtorrent session
self.session = component.get("Core").session
@@ -151,15 +150,11 @@ class TorrentManager(component.Component):
self.last_seen_complete_loop = None
self.queued_torrents = set()
- # This is a list of torrent_id when we shutdown the torrentmanager.
- # We use this list to determine if all active torrents have been paused
- # and that their resume data has been written.
- self.shutdown_torrent_pause_list = []
+ # This is a map of torrent_ids to Deferreds used to track needed resume data.
+ # The Deferreds will be completed when resume data has been saved.
+ self.waiting_on_resume_data = {}
- # self.num_resume_data used to save resume_data in bulk
- self.num_resume_data = 0
-
- # Keeps track of resume data that needs to be saved to disk
+ # Keeps track of resume data
self.resume_data = {}
# Register set functions
@@ -216,11 +211,14 @@ class TorrentManager(component.Component):
# Try to load the state from file
self.load_state()
- # Save the state every 5 minutes
+ # Save the state periodically
self.save_state_timer = LoopingCall(self.save_state)
self.save_state_timer.start(200, False)
self.save_resume_data_timer = LoopingCall(self.save_resume_data)
- self.save_resume_data_timer.start(190)
+ self.save_resume_data_timer.start(190, False)
+ # Force update for all resume data a bit less frequently
+ self.save_all_resume_data_timer = LoopingCall(self.save_resume_data, self.torrents.keys())
+ self.save_all_resume_data_timer.start(900, False)
if self.last_seen_complete_loop:
self.last_seen_complete_loop.start(60)
@@ -233,45 +231,21 @@ class TorrentManager(component.Component):
if self.save_resume_data_timer.running:
self.save_resume_data_timer.stop()
+ if self.save_all_resume_data_timer.running:
+ self.save_all_resume_data_timer.stop()
+
if self.last_seen_complete_loop:
self.last_seen_complete_loop.stop()
# Save state on shutdown
self.save_state()
- # Make another list just to make sure all paused torrents will be
- # passed to self.save_resume_data(). With
- # self.shutdown_torrent_pause_list it is possible to have a case when
- # torrent_id is removed from it in self.on_alert_torrent_paused()
- # before we call self.save_resume_data() here.
- save_resume_data_list = []
+ self.session.pause()
for key in self.torrents:
# Stop the status cleanup LoopingCall here
self.torrents[key].prev_status_cleanup_loop.stop()
- if not self.torrents[key].handle.is_paused():
- # We set auto_managed false to prevent lt from resuming the torrent
- self.torrents[key].handle.auto_managed(False)
- self.torrents[key].handle.pause()
- self.shutdown_torrent_pause_list.append(key)
- save_resume_data_list.append(key)
-
- self.save_resume_data(save_resume_data_list)
-
- # We have to wait for all torrents to pause and write their resume data
- wait = True
- while wait:
- if self.shutdown_torrent_pause_list:
- wait = True
- else:
- wait = False
- for torrent in self.torrents.values():
- if torrent.waiting_on_resume_data:
- wait = True
- break
- time.sleep(0.01)
- # Wait for all alerts
- self.alerts.handle_alerts(True)
+ return self.save_resume_data(self.torrents.keys())
def update(self):
for torrent_id, torrent in self.torrents.items():
@@ -409,7 +383,8 @@ class TorrentManager(component.Component):
resume_data = self.legacy_get_resume_data_from_file(state.torrent_id)
self.legacy_delete_resume_data(state.torrent_id)
- add_torrent_params["resume_data"] = resume_data
+ if resume_data:
+ add_torrent_params["resume_data"] = resume_data
else:
# We have a torrent_info object or magnet uri so we're not loading from state.
if torrent_info:
@@ -452,9 +427,16 @@ class TorrentManager(component.Component):
# before adding to the session.
if options["mapped_files"]:
for index, fname in options["mapped_files"].items():
+ try:
+ fname = unicode(fname, "utf-8")
+ except TypeError:
+ pass
fname = deluge.core.torrent.sanitize_filepath(fname)
log.debug("renaming file index %s to %s", index, fname)
- torrent_info.rename_file(index, utf8_encoded(fname))
+ try:
+ torrent_info.rename_file(index, fname)
+ except TypeError:
+ torrent_info.rename_file(index, fname.encode("utf-8"))
add_torrent_params["ti"] = torrent_info
@@ -589,12 +571,11 @@ class TorrentManager(component.Component):
:raises InvalidTorrentError: if the torrent_id is not in the session
"""
-
- if torrent_id not in self.torrents:
+ try:
+ torrent_name = self.torrents[torrent_id].get_status(["name"])["name"]
+ except KeyError:
raise InvalidTorrentError("torrent_id not in session")
- torrent_name = self.torrents[torrent_id].get_status(["name"])["name"]
-
# Emit the signal to the clients
component.get("EventManager").emit(PreTorrentRemovedEvent(torrent_id))
@@ -606,9 +587,7 @@ class TorrentManager(component.Component):
return False
# Remove fastresume data if it is exists
- resume_data = self.load_resume_data_file()
- resume_data.pop(torrent_id, None)
- self.save_resume_data_file(resume_data)
+ self.resume_data.pop(torrent_id, None)
# Remove the .torrent file in the state
self.torrents[torrent_id].delete_torrentfile()
@@ -678,7 +657,7 @@ class TorrentManager(component.Component):
# Reorder the state.torrents list to add torrents in the correct queue
# order.
- state.torrents.sort(key=operator.attrgetter("queue"))
+ state.torrents.sort(key=operator.attrgetter("queue"), reverse=self.config["queue_new_to_top"])
resume_data = self.load_resume_data_file()
@@ -770,17 +749,34 @@ class TorrentManager(component.Component):
def save_resume_data(self, torrent_ids=None):
"""
- Saves resume data for list of torrent_ids or for all torrents if
- torrent_ids is None
+ Saves resume data for list of torrent_ids or for all torrents
+ needing resume data updated if torrent_ids is None
+
+ :returns: A Deferred whose callback will be invoked when save is complete
+ :rtype: twisted.internet.defer.Deferred
"""
if torrent_ids is None:
- torrent_ids = self.torrents.keys()
+ torrent_ids = (t[0] for t in self.torrents.iteritems() if t[1].handle.need_save_resume_data())
+
+ deferreds = []
+
+ def on_torrent_resume_save(result, torrent_id):
+ self.waiting_on_resume_data.pop(torrent_id, None)
for torrent_id in torrent_ids:
+ d = self.waiting_on_resume_data.get(torrent_id)
+ if not d:
+ d = Deferred().addBoth(on_torrent_resume_save, torrent_id)
+ self.waiting_on_resume_data[torrent_id] = d
+ deferreds.append(d)
self.torrents[torrent_id].save_resume_data()
- self.num_resume_data = len(torrent_ids)
+ def on_all_resume_data_finished(result):
+ if result:
+ self.save_resume_data_file()
+
+ return DeferredList(deferreds).addBoth(on_all_resume_data_finished)
def load_resume_data_file(self):
resume_data = {}
@@ -800,73 +796,22 @@ class TorrentManager(component.Component):
return resume_data
- def save_resume_data_file(self, resume_data=None):
+ def save_resume_data_file(self):
"""
- Saves the resume data file with the contents of self.resume_data. If
- `resume_data` is None, then we grab the resume_data from the file on
- disk, else, we update `resume_data` with self.resume_data and save
- that to disk.
-
- :param resume_data: the current resume_data, this will be loaded from disk if not provided
- :type resume_data: dict
-
+ Saves the resume data file with the contents of self.resume_data.
"""
- # Check to see if we're waiting on more resume data
- if self.num_resume_data or not self.resume_data:
- return
-
path = os.path.join(get_config_dir(), "state", "torrents.fastresume")
- # First step is to load the existing file and update the dictionary
- if resume_data is None:
- resume_data = self.load_resume_data_file()
-
- resume_data.update(self.resume_data)
- self.resume_data = {}
-
try:
log.debug("Saving fastresume file: %s", path)
fastresume_file = open(path, "wb")
- fastresume_file.write(lt.bencode(resume_data))
+ fastresume_file.write(lt.bencode(self.resume_data))
fastresume_file.flush()
os.fsync(fastresume_file.fileno())
fastresume_file.close()
except IOError:
log.warning("Error trying to save fastresume file")
- def remove_empty_folders(self, torrent_id, folder):
- """
- Recursively removes folders but only if they are empty.
- Cleans up after libtorrent folder renames.
-
- """
- if torrent_id not in self.torrents:
- raise InvalidTorrentError("torrent_id is not in session")
-
- info = self.torrents[torrent_id].get_status(['save_path'])
- # Regex removes leading slashes that causes join function to ignore save_path
- folder_full_path = os.path.join(info['save_path'], re.sub("^/*", "", folder))
- folder_full_path = os.path.normpath(folder_full_path)
-
- try:
- if not os.listdir(folder_full_path):
- os.removedirs(folder_full_path)
- log.debug("Removed Empty Folder %s", folder_full_path)
- else:
- for root, dirs, files in os.walk(folder_full_path, topdown=False):
- for name in dirs:
- try:
- os.removedirs(os.path.join(root, name))
- log.debug("Removed Empty Folder %s", os.path.join(root, name))
- except OSError as (errno, strerror):
- from errno import ENOTEMPTY
- if errno == ENOTEMPTY:
- # Error raised if folder is not empty
- log.debug("%s", strerror)
-
- except OSError as (errno, strerror):
- log.debug("Cannot Remove Folder: %s (ErrNo %s)", strerror, errno)
-
def get_queue_position(self, torrent_id):
"""Get queue position of torrent"""
return self.torrents[torrent_id].get_queue_position()
@@ -981,14 +926,9 @@ class TorrentManager(component.Component):
if torrent.state != old_state:
component.get("EventManager").emit(TorrentStateChangedEvent(torrent_id, torrent.state))
- # Don't save resume data for each torrent after self.stop() was called.
- # We save resume data in bulk in self.stop() in this case.
- if self.save_resume_data_timer.running:
- # Write the fastresume file
- self.save_resume_data((torrent_id, ))
-
- if torrent_id in self.shutdown_torrent_pause_list:
- self.shutdown_torrent_pause_list.remove(torrent_id)
+ # Write the fastresume file if we are not waiting on a bulk write
+ if torrent_id not in self.waiting_on_resume_data:
+ self.save_resume_data((torrent_id,))
def on_alert_torrent_checked(self, alert):
log.debug("on_alert_torrent_checked")
@@ -1008,15 +948,14 @@ class TorrentManager(component.Component):
torrent.update_state()
def on_alert_tracker_reply(self, alert):
- log.debug("on_alert_tracker_reply: %s", alert.message().decode("utf8"))
+ log.debug("on_alert_tracker_reply: %s", decode_string(alert.message()))
try:
torrent = self.torrents[str(alert.handle.info_hash())]
except:
return
# Set the tracker status for the torrent
- if alert.message() != "Got peers from DHT":
- torrent.set_tracker_status(_("Announce OK"))
+ torrent.set_tracker_status(_("Announce OK"))
# Check to see if we got any peer information from the tracker
if alert.handle.status().num_complete == -1 or \
@@ -1040,7 +979,7 @@ class TorrentManager(component.Component):
torrent = self.torrents[str(alert.handle.info_hash())]
except:
return
- tracker_status = '%s: %s' % (_("Warning"), str(alert.message()))
+ tracker_status = '%s: %s' % (_("Warning"), decode_string(alert.message()))
# Set the tracker status for the torrent
torrent.set_tracker_status(tracker_status)
@@ -1050,7 +989,7 @@ class TorrentManager(component.Component):
torrent = self.torrents[str(alert.handle.info_hash())]
except:
return
- tracker_status = "%s: %s" % (_("Error"), alert.msg)
+ tracker_status = "%s: %s" % (_("Error"), decode_string(alert.msg))
torrent.set_tracker_status(tracker_status)
def on_alert_storage_moved(self, alert):
@@ -1098,32 +1037,21 @@ class TorrentManager(component.Component):
def on_alert_save_resume_data(self, alert):
log.debug("on_alert_save_resume_data")
- try:
- torrent_id = str(alert.handle.info_hash())
- torrent = self.torrents[torrent_id]
- except:
- return
+ torrent_id = str(alert.handle.info_hash())
- # Libtorrent in add_torrent() expects resume_data to be bencoded
- self.resume_data[torrent_id] = lt.bencode(alert.resume_data)
- self.num_resume_data -= 1
+ if torrent_id in self.torrents:
+ # Libtorrent in add_torrent() expects resume_data to be bencoded
+ self.resume_data[torrent_id] = lt.bencode(alert.resume_data)
- torrent.waiting_on_resume_data = False
-
- self.save_resume_data_file()
+ if torrent_id in self.waiting_on_resume_data:
+ self.waiting_on_resume_data[torrent_id].callback(None)
def on_alert_save_resume_data_failed(self, alert):
- log.debug("on_alert_save_resume_data_failed: %s", alert.message())
- try:
- torrent = self.torrents[str(alert.handle.info_hash())]
- except:
- return
-
- self.num_resume_data -= 1
- torrent.waiting_on_resume_data = False
-
- self.save_resume_data_file()
+ log.debug("on_alert_save_resume_data_failed: %s", decode_string(alert.message()))
+ torrent_id = str(alert.handle.info_hash())
+ if torrent_id in self.waiting_on_resume_data:
+ self.waiting_on_resume_data[torrent_id].errback(Exception(decode_string(alert.message())))
def on_alert_file_renamed(self, alert):
log.debug("on_alert_file_renamed")
@@ -1134,24 +1062,12 @@ class TorrentManager(component.Component):
except:
return
- # We need to see if this file index is in a waiting_on_folder list
- folder_rename = False
- for i, wait_on_folder in enumerate(torrent.waiting_on_folder_rename):
- if alert.index in wait_on_folder[2]:
- folder_rename = True
- if len(wait_on_folder[2]) == 1:
- # This is the last alert we were waiting for, time to send signal
- component.get("EventManager").emit(TorrentFolderRenamedEvent(torrent_id, wait_on_folder[0], wait_on_folder[1]))
- # Empty folders are removed after libtorrent folder renames
- self.remove_empty_folders(torrent_id, wait_on_folder[0])
- del torrent.waiting_on_folder_rename[i]
- self.save_resume_data((torrent_id,))
- break
- # This isn't the last file to be renamed in this folder, so just
- # remove the index and continue
- torrent.waiting_on_folder_rename[i][2].remove(alert.index)
-
- if not folder_rename:
+ # We need to see if this file index is in a waiting_on_folder dict
+ for wait_on_folder in torrent.waiting_on_folder_rename:
+ if alert.index in wait_on_folder:
+ wait_on_folder[alert.index].callback(None)
+ break
+ else:
# This is just a regular file rename so send the signal
component.get("EventManager").emit(TorrentFileRenamedEvent(torrent_id, alert.index, alert.name))
self.save_resume_data((torrent_id,))
@@ -1165,7 +1081,7 @@ class TorrentManager(component.Component):
torrent.write_torrentfile()
def on_alert_file_error(self, alert):
- log.debug("on_alert_file_error: %s", alert.message())
+ log.debug("on_alert_file_error: %s", decode_string(alert.message()))
try:
torrent = self.torrents[str(alert.handle.info_hash())]
except:
@@ -1173,7 +1089,7 @@ class TorrentManager(component.Component):
torrent.update_state()
def on_alert_file_completed(self, alert):
- log.debug("file_completed_alert: %s", alert.message())
+ log.debug("file_completed_alert: %s", decode_string(alert.message()))
try:
torrent_id = str(alert.handle.info_hash())
except:
diff --git a/deluge/main.py b/deluge/main.py
index a966356de..c68ab3d5e 100644
--- a/deluge/main.py
+++ b/deluge/main.py
@@ -43,8 +43,10 @@
import os
import sys
from optparse import OptionParser
+from logging import FileHandler, getLogger
+from errno import EEXIST
-import deluge.log
+from deluge.log import setupLogger
import deluge.error
def version_callback(option, opt_str, value, parser):
@@ -86,21 +88,18 @@ def start_ui():
help="Rotate logfiles.", action="store_true", default=False)
# Get the options and args from the OptionParser
- (options, args) = parser.parse_args()
+ (options, args) = parser.parse_args(deluge.common.unicode_argv()[1:])
+ # Setup the logger
if options.quiet:
options.loglevel = "none"
-
if options.loglevel:
options.loglevel = options.loglevel.lower()
-
logfile_mode = 'w'
if options.rotate_logs:
logfile_mode = 'a'
-
- # Setup the logger
- deluge.log.setupLogger(level=options.loglevel, filename=options.logfile,
- filemode=logfile_mode)
+ setupLogger(level=options.loglevel, filename=options.logfile, filemode=logfile_mode)
+ log = getLogger(__name__)
if options.config:
if not os.path.exists(options.config):
@@ -110,7 +109,7 @@ def start_ui():
except Exception, e:
pass
elif not os.path.isdir(options.config):
- print "Config option needs to be a directory!"
+ log.error("Config option needs to be a directory!")
sys.exit(1)
else:
if not os.path.exists(deluge.common.get_default_config_dir()):
@@ -129,8 +128,6 @@ def start_ui():
version = deluge.common.get_version()
- import logging
- log = logging.getLogger(__name__)
log.info("Deluge ui %s", version)
log.debug("options: %s", options)
log.debug("args: %s", args)
@@ -188,27 +185,35 @@ this should be an IP address", metavar="IFACE",
# Get the options and args from the OptionParser
(options, args) = parser.parse_args()
+ # Setup the logger
if options.quiet:
options.loglevel = "none"
-
+ if options.logfile:
+ # Try to create the logfile's directory if it doesn't exist
+ try:
+ os.makedirs(os.path.abspath(os.path.dirname(options.logfile)))
+ except OSError, e:
+ if e.errno != EEXIST:
+ print "There was an error creating the log directory, exiting... (%s)" % e
+ sys.exit(1)
logfile_mode = 'w'
if options.rotate_logs:
logfile_mode = 'a'
-
- # Setup the logger
- deluge.log.setupLogger(level=options.loglevel, filename=options.logfile,
- filemode=logfile_mode)
+ setupLogger(level=options.loglevel, filename=options.logfile, filemode=logfile_mode)
+ log = getLogger(__name__)
import deluge.configmanager
if options.config:
if not deluge.configmanager.set_config_dir(options.config):
- print("There was an error setting the config dir! Exiting..")
+ log.error("There was an error setting the config directory! Exiting...")
sys.exit(1)
# Sets the options.logfile to point to the default location
def open_logfile():
if not options.logfile:
options.logfile = deluge.configmanager.get_config_dir("deluged.log")
+ file_handler = FileHandler(options.logfile)
+ log.addHandler(file_handler)
# Writes out a pidfile if necessary
def write_pidfile():
@@ -242,37 +247,32 @@ this should be an IP address", metavar="IFACE",
open_logfile()
- # Setup the logger
- try:
- # Try to make the logfile's directory if it doesn't exist
- os.makedirs(os.path.abspath(os.path.dirname(options.logfile)))
- except:
- pass
-
- import logging
- log = logging.getLogger(__name__)
+ def run_daemon(options, args):
+ try:
+ from deluge.core.daemon import Daemon
+ Daemon(options, args)
+ except deluge.error.DaemonRunningError, e:
+ log.error(e)
+ log.error("You cannot run multiple daemons with the same config directory set.")
+ log.error("If you believe this is an error, you can force a start by deleting %s.", deluge.configmanager.get_config_dir("deluged.pid"))
+ sys.exit(1)
+ except Exception, e:
+ log.exception(e)
+ sys.exit(1)
if options.profile:
- import hotshot
- hsp = hotshot.Profile(deluge.configmanager.get_config_dir("deluged.profile"))
- hsp.start()
- try:
- from deluge.core.daemon import Daemon
- Daemon(options, args)
- except deluge.error.DaemonRunningError, e:
- log.error(e)
- log.error("You cannot run multiple daemons with the same config directory set.")
- log.error("If you believe this is an error, you can force a start by deleting %s.", deluge.configmanager.get_config_dir("deluged.pid"))
- sys.exit(1)
- except Exception, e:
- log.exception(e)
- sys.exit(1)
- finally:
- if options.profile:
- hsp.stop()
- hsp.close()
- import hotshot.stats
- stats = hotshot.stats.load(deluge.configmanager.get_config_dir("deluged.profile"))
- stats.strip_dirs()
- stats.sort_stats("time", "calls")
- stats.print_stats(400)
+ import cProfile
+ profiler = cProfile.Profile()
+ profile_output = deluge.configmanager.get_config_dir("deluged.profile")
+
+ # Twisted catches signals to terminate
+ def save_profile_stats():
+ profiler.dump_stats(profile_output)
+ print "Profile stats saved to %s" % profile_output
+
+ from twisted.internet import reactor
+ reactor.addSystemEventTrigger("before", "shutdown", save_profile_stats)
+ print "Running with profiler..."
+ profiler.runcall(run_daemon, options, args)
+ else:
+ run_daemon(options, args)
diff --git a/deluge/plugins/AutoAdd/deluge/plugins/autoadd/gtkui.py b/deluge/plugins/AutoAdd/deluge/plugins/autoadd/gtkui.py
index 6803755d2..b369fc124 100644
--- a/deluge/plugins/AutoAdd/deluge/plugins/autoadd/gtkui.py
+++ b/deluge/plugins/AutoAdd/deluge/plugins/autoadd/gtkui.py
@@ -403,12 +403,11 @@ class GtkUI(GtkPluginBase):
sw.add(self.treeView)
sw.show_all()
component.get("Preferences").add_page(
- "AutoAdd", self.glade.get_widget("prefs_box")
+ _("AutoAdd"), self.glade.get_widget("prefs_box")
)
- self.on_show_prefs()
def disable(self):
- component.get("Preferences").remove_page("AutoAdd")
+ component.get("Preferences").remove_page(_("AutoAdd"))
component.get("PluginManager").deregister_hook(
"on_apply_prefs", self.on_apply_prefs
)
diff --git a/deluge/plugins/Extractor/deluge/plugins/extractor/gtkui.py b/deluge/plugins/Extractor/deluge/plugins/extractor/gtkui.py
index 6f0469200..8ee08ee92 100644
--- a/deluge/plugins/Extractor/deluge/plugins/extractor/gtkui.py
+++ b/deluge/plugins/Extractor/deluge/plugins/extractor/gtkui.py
@@ -54,13 +54,13 @@ class GtkUI(GtkPluginBase):
def enable(self):
self.glade = gtk.glade.XML(get_resource("extractor_prefs.glade"))
- component.get("Preferences").add_page("Extractor", self.glade.get_widget("extractor_prefs_box"))
+ component.get("Preferences").add_page(_("Extractor"), self.glade.get_widget("extractor_prefs_box"))
component.get("PluginManager").register_hook("on_apply_prefs", self.on_apply_prefs)
component.get("PluginManager").register_hook("on_show_prefs", self.on_show_prefs)
self.on_show_prefs()
def disable(self):
- component.get("Preferences").remove_page("Extractor")
+ component.get("Preferences").remove_page(_("Extractor"))
component.get("PluginManager").deregister_hook("on_apply_prefs", self.on_apply_prefs)
component.get("PluginManager").deregister_hook("on_show_prefs", self.on_show_prefs)
del self.glade
diff --git a/deluge/plugins/Notifications/deluge/plugins/notifications/gtkui.py b/deluge/plugins/Notifications/deluge/plugins/notifications/gtkui.py
index 2400c7966..44558fda4 100644
--- a/deluge/plugins/Notifications/deluge/plugins/notifications/gtkui.py
+++ b/deluge/plugins/Notifications/deluge/plugins/notifications/gtkui.py
@@ -242,7 +242,7 @@ class GtkUiNotifications(CustomNotifications):
log.debug("Handler for TorrentFinishedEvent GTKUI called. "
"Got Torrent Status")
title = _("Finished Torrent")
- message = _("The torrent \"%(name)s\" including %(num_files)i "
+ message = _("The torrent \"%(name)s\" including %(num_files)i file(s) "
"has finished downloading.") % torrent_status
return title, message
@@ -287,7 +287,7 @@ class GtkUI(GtkPluginBase, GtkUiNotifications):
if parent:
parent.remove(self.prefs)
index = prefs.notebook.append_page(self.prefs)
- prefs.liststore.append([index, "Notifications"])
+ prefs.liststore.append([index, _("Notifications")])
component.get("PluginManager").register_hook("on_apply_prefs",
self.on_apply_prefs)
@@ -320,7 +320,7 @@ class GtkUI(GtkPluginBase, GtkUiNotifications):
def disable(self):
GtkUiNotifications.disable(self)
- component.get("Preferences").remove_page("Notifications")
+ component.get("Preferences").remove_page(_("Notifications"))
component.get("PluginManager").deregister_hook("on_apply_prefs",
self.on_apply_prefs)
component.get("PluginManager").deregister_hook("on_show_prefs",
diff --git a/deluge/plugins/Scheduler/deluge/plugins/scheduler/gtkui.py b/deluge/plugins/Scheduler/deluge/plugins/scheduler/gtkui.py
index 580eba2d8..5d16e660a 100644
--- a/deluge/plugins/Scheduler/deluge/plugins/scheduler/gtkui.py
+++ b/deluge/plugins/Scheduler/deluge/plugins/scheduler/gtkui.py
@@ -170,7 +170,7 @@ class GtkUI(GtkPluginBase):
client.register_event_handler("SchedulerEvent", self.on_scheduler_event)
def disable(self):
- component.get("Preferences").remove_page("Scheduler")
+ component.get("Preferences").remove_page(_("Scheduler"))
# Remove status item
component.get("StatusBar").remove_item(self.status_item)
del self.status_item
@@ -294,4 +294,4 @@ class GtkUI(GtkPluginBase):
vbox.pack_start(frame, False, False)
vbox.show_all()
- component.get("Preferences").add_page("Scheduler", vbox)
+ component.get("Preferences").add_page(_("Scheduler"), vbox)
diff --git a/deluge/plugins/WebUi/deluge/plugins/webui/gtkui.py b/deluge/plugins/WebUi/deluge/plugins/webui/gtkui.py
index 978ac5fe4..c13f0b755 100644
--- a/deluge/plugins/WebUi/deluge/plugins/webui/gtkui.py
+++ b/deluge/plugins/WebUi/deluge/plugins/webui/gtkui.py
@@ -53,14 +53,14 @@ class GtkUI(GtkPluginBase):
def enable(self):
self.glade = gtk.glade.XML(get_resource("config.glade"))
- component.get("Preferences").add_page("WebUi", self.glade.get_widget("prefs_box"))
+ component.get("Preferences").add_page(_("WebUi"), self.glade.get_widget("prefs_box"))
component.get("PluginManager").register_hook("on_apply_prefs", self.on_apply_prefs)
component.get("PluginManager").register_hook("on_show_prefs", self.on_show_prefs)
client.webui.get_config().addCallback(self.cb_get_config)
client.webui.got_deluge_web().addCallback(self.cb_chk_deluge_web)
def disable(self):
- component.get("Preferences").remove_page("WebUi")
+ component.get("Preferences").remove_page(_("WebUi"))
component.get("PluginManager").deregister_hook("on_apply_prefs", self.on_apply_prefs)
component.get("PluginManager").deregister_hook("on_show_prefs", self.on_show_prefs)
diff --git a/deluge/rencode.py b/deluge/rencode.py
index a0a6eec35..7c0f7d8b1 100644
--- a/deluge/rencode.py
+++ b/deluge/rencode.py
@@ -19,7 +19,7 @@ rencode module versions, so you should check that you are using the
same rencode version throughout your project.
"""
-__version__ = '1.0.1'
+__version__ = '1.0.2'
__all__ = ['dumps', 'loads']
# Original bencode module by Petru Paler, et al.
@@ -107,6 +107,9 @@ STR_FIXED_COUNT = 64
LIST_FIXED_START = STR_FIXED_START+STR_FIXED_COUNT
LIST_FIXED_COUNT = 64
+# Whether strings should be decoded when loading
+_decode_utf8 = False
+
def decode_int(x, f):
f += 1
newf = x.index(CHR_TERM, f)
@@ -159,12 +162,8 @@ def decode_string(x, f):
raise ValueError
colon += 1
s = x[colon:colon+n]
- try:
- t = s.decode("utf8")
- if len(t) != len(s):
- s = t
- except UnicodeDecodeError:
- pass
+ if _decode_utf8:
+ s = s.decode('utf8')
return (s, colon+n)
def decode_list(x, f):
@@ -218,12 +217,8 @@ def make_fixed_length_string_decoders():
def make_decoder(slen):
def f(x, f):
s = x[f+1:f+1+slen]
- try:
- t = s.decode("utf8")
- if len(t) != len(s):
- s = t
- except UnicodeDecodeError:
- pass
+ if _decode_utf8:
+ s = s.decode("utf8")
return (s, f+1+slen)
return f
for i in range(STR_FIXED_COUNT):
@@ -279,7 +274,9 @@ def encode_dict(x,r):
r.append(CHR_TERM)
-def loads(x):
+def loads(x, decode_utf8=False):
+ global _decode_utf8
+ _decode_utf8 = decode_utf8
try:
r, l = decode_func[x[0]](x, 0)
except (IndexError, KeyError):
diff --git a/deluge/tests/dir_with_6_files.torrent b/deluge/tests/dir_with_6_files.torrent
new file mode 100644
index 000000000..2c6b5fb02
--- /dev/null
+++ b/deluge/tests/dir_with_6_files.torrent
Binary files differ
diff --git a/deluge/tests/test_component.py b/deluge/tests/test_component.py
index ab5e4d534..6f13eeca2 100644
--- a/deluge/tests/test_component.py
+++ b/deluge/tests/test_component.py
@@ -3,8 +3,8 @@ from twisted.internet import threads
import deluge.component as component
class testcomponent(component.Component):
- def __init__(self, name):
- component.Component.__init__(self, name)
+ def __init__(self, name, depend=None):
+ component.Component.__init__(self, name, depend=depend)
self.start_count = 0
self.stop_count = 0
@@ -51,6 +51,7 @@ class testcomponent_shutdown(component.Component):
class ComponentTestClass(unittest.TestCase):
def tearDown(self):
+ component.stop()
component._ComponentRegistry.components = {}
def test_start_component(self):
@@ -63,16 +64,22 @@ class ComponentTestClass(unittest.TestCase):
d.addCallback(on_start, c)
return d
- def test_start_depends(self):
+ def test_start_stop_depends(self):
+ def on_stop(result, c1, c2):
+ self.assertEquals(c1._component_state, "Stopped")
+ self.assertEquals(c2._component_state, "Stopped")
+ self.assertEquals(c1.stop_count, 1)
+ self.assertEquals(c2.stop_count, 1)
+
def on_start(result, c1, c2):
self.assertEquals(c1._component_state, "Started")
self.assertEquals(c2._component_state, "Started")
self.assertEquals(c1.start_count, 1)
self.assertEquals(c2.start_count, 1)
+ return component.stop(["test_start_depends_c1"]).addCallback(on_stop, c1, c2)
c1 = testcomponent("test_start_depends_c1")
- c2 = testcomponent("test_start_depends_c2")
- c2._component_depend = ["test_start_depends_c1"]
+ c2 = testcomponent("test_start_depends_c2", depend=["test_start_depends_c1"])
d = component.start(["test_start_depends_c2"])
d.addCallback(on_start, c1, c2)
@@ -80,15 +87,12 @@ class ComponentTestClass(unittest.TestCase):
def start_with_depends(self):
c1 = testcomponent_delaystart("test_start_all_c1")
- c2 = testcomponent("test_start_all_c2")
- c3 = testcomponent_delaystart("test_start_all_c3")
- c4 = testcomponent("test_start_all_c4")
+ c2 = testcomponent("test_start_all_c2", depend=["test_start_all_c4"])
+ c3 = testcomponent_delaystart("test_start_all_c3",
+ depend=["test_start_all_c5", "test_start_all_c1"])
+ c4 = testcomponent("test_start_all_c4", depend=["test_start_all_c3"])
c5 = testcomponent("test_start_all_c5")
- c3._component_depend = ["test_start_all_c5", "test_start_all_c1"]
- c4._component_depend = ["test_start_all_c3"]
- c2._component_depend = ["test_start_all_c4"]
-
d = component.start()
return (d, c1, c2, c3, c4, c5)
@@ -130,15 +134,15 @@ class ComponentTestClass(unittest.TestCase):
return d
def test_stop_all(self):
- def on_stop(*args):
- for c in args[1:]:
+ def on_stop(result, *args):
+ for c in args:
self.assertEquals(c._component_state, "Stopped")
self.assertEquals(c.stop_count, 1)
- def on_start(*args):
- for c in args[1:]:
+ def on_start(result, *args):
+ for c in args:
self.assertEquals(c._component_state, "Started")
- return component.stop().addCallback(on_stop, *args[1:])
+ return component.stop().addCallback(on_stop, *args)
ret = self.start_with_depends()
ret[0].addCallback(on_start, *ret[1:])
diff --git a/deluge/tests/test_torrent.py b/deluge/tests/test_torrent.py
new file mode 100644
index 000000000..f55b4d4e2
--- /dev/null
+++ b/deluge/tests/test_torrent.py
@@ -0,0 +1,127 @@
+from twisted.trial import unittest
+import os
+
+import deluge.core.torrent
+import test_torrent
+import common
+from deluge.core.rpcserver import RPCServer
+from deluge.core.core import Core
+
+deluge.core.torrent.component = test_torrent
+
+from deluge._libtorrent import lt
+
+import deluge.component as component
+from deluge.core.torrent import Torrent
+
+config_setup = False
+core = None
+rpcserver = None
+
+# This is called by torrent.py when calling component.get("...")
+def get(key):
+ if key is "Core":
+ return core
+ elif key is "RPCServer":
+ return rpcserver
+ else:
+ return None
+
+class TorrentTestCase(unittest.TestCase):
+
+ def setup_config(self):
+ global config_setup
+ config_setup = True
+ config_dir = common.set_tmp_config_dir()
+ core_config = deluge.config.Config("core.conf", defaults=deluge.core.preferencesmanager.DEFAULT_PREFS, config_dir=config_dir)
+ core_config.save()
+
+ def setUp(self):
+ self.setup_config()
+ global rpcserver
+ global core
+ rpcserver = RPCServer(listen=False)
+ core = Core()
+ self.session = lt.session()
+ self.torrent = None
+ return component.start()
+
+ def tearDown(self):
+ if self.torrent:
+ self.torrent.prev_status_cleanup_loop.stop()
+
+ def on_shutdown(result):
+ component._ComponentRegistry.components = {}
+ return component.shutdown().addCallback(on_shutdown)
+
+ def print_priority_list(self, priorities):
+ tmp = ''
+ for i, p in enumerate(priorities):
+ if i % 100 == 0:
+ print tmp
+ tmp = ''
+ tmp += "%s" % p
+ print tmp
+
+ def get_torrent_atp(self, filename):
+ filename = os.path.join(os.path.dirname(__file__), filename)
+ e = lt.bdecode(open(filename, 'rb').read())
+ info = lt.torrent_info(e)
+ atp = {"ti": info}
+ atp["save_path"] = os.getcwd()
+ atp["storage_mode"] = lt.storage_mode_t.storage_mode_sparse
+ atp["add_paused"] = False
+ atp["auto_managed"] = True
+ atp["duplicate_is_error"] = True
+ return atp
+
+ def test_set_prioritize_first_last(self):
+ piece_indexes = [(0,1), (0,1), (0,1), (0,1), (0,2), (50,52),
+ (51,53), (110,112), (111,114), (200,203),
+ (202,203), (212,213), (212,218), (457,463)]
+ self.run_test_set_prioritize_first_last("dir_with_6_files.torrent", piece_indexes)
+
+ def run_test_set_prioritize_first_last(self, torrent_file, prioritized_piece_indexes):
+ atp = self.get_torrent_atp(torrent_file)
+ handle = self.session.add_torrent(atp)
+
+ self.torrent = Torrent(handle, {})
+ priorities_original = handle.piece_priorities()
+ prioritized_pieces, new_priorites = self.torrent.set_prioritize_first_last(True)
+ priorities = handle.piece_priorities()
+ non_prioritized_pieces = list(range(len(priorities)))
+
+ # The prioritized indexes are the same as we expect
+ self.assertEquals(prioritized_pieces, prioritized_piece_indexes)
+
+ # Test the priority of the prioritized pieces
+ for first, last in prioritized_pieces:
+ for i in range(first, last):
+ if i in non_prioritized_pieces:
+ non_prioritized_pieces.remove(i)
+ self.assertEquals(priorities[i], 7)
+
+ # Test the priority of all the non-prioritized pieces
+ for i in non_prioritized_pieces:
+ self.assertEquals(priorities[i], 1)
+
+ # The length of the list of new priorites is the same as the original
+ self.assertEquals(len(priorities_original), len(new_priorites))
+
+ #self.print_priority_list(priorities)
+
+ def test_set_prioritize_first_last_false(self):
+ atp = self.get_torrent_atp("dir_with_6_files.torrent")
+ handle = self.session.add_torrent(atp)
+ self.torrent = Torrent(handle, {})
+ # First set some pieces prioritized
+ self.torrent.set_prioritize_first_last(True)
+ # Reset pirorities
+ self.torrent.set_prioritize_first_last(False)
+ priorities = handle.piece_priorities()
+
+ # Test the priority of the prioritized pieces
+ for i in priorities:
+ self.assertEquals(priorities[i], 1)
+
+ #self.print_priority_list(priorities)
diff --git a/tests/test_transfer.py b/deluge/tests/test_transfer.py
index cd9a271d5..cd9a271d5 100644
--- a/tests/test_transfer.py
+++ b/deluge/tests/test_transfer.py
diff --git a/deluge/tests/test_ui_common.py b/deluge/tests/test_ui_common.py
new file mode 100644
index 000000000..14d58e7b4
--- /dev/null
+++ b/deluge/tests/test_ui_common.py
@@ -0,0 +1,30 @@
+# -*- coding: utf-8 -*-
+from twisted.trial import unittest
+import os
+from deluge.ui.common import TorrentInfo
+
+class UICommonTestCase(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+ def test_utf8_encoded_paths(self):
+ filename = os.path.join(os.path.dirname(__file__), "test.torrent")
+ ti = TorrentInfo(filename)
+ self.assertTrue(ti.files_tree.has_key("azcvsupdater_2.6.2.jar"))
+
+ def test_utf8_encoded_paths2(self):
+ filename = os.path.join(os.path.dirname(__file__), "unicode_filenames.torrent")
+ ti = TorrentInfo(filename)
+
+ files = ti.files_tree["unicode_filenames"]
+ self.assertTrue(files.has_key("\xe3\x83\x86\xe3\x82\xaf\xe3\x82\xb9\xe3\x83\xbb\xe3\x83"
+ "\x86\xe3\x82\xaf\xe3\x82\xb5\xe3\x83\xb3.mkv"))
+ self.assertTrue(files.has_key("\xd0\x9c\xd0\xb8\xd1\x85\xd0\xb0\xd0\xb8\xd0\xbb \xd0\x93"
+ "\xd0\xbe\xd1\x80\xd0\xb1\xd0\xb0\xd1\x87\xd1\x91\xd0\xb2.mkv"))
+ self.assertTrue(files.has_key("Alisher ibn G'iyosiddin Navoiy.mkv"))
+ self.assertTrue(files.has_key("Ascii title.mkv"))
+ self.assertTrue(files.has_key("\xe0\xa6\xb8\xe0\xa7\x81\xe0\xa6\x95\xe0\xa7\x81\xe0\xa6"
+ "\xae\xe0\xa6\xbe\xe0\xa6\xb0 \xe0\xa6\xb0\xe0\xa6\xbe\xe0\xa7\x9f.mkv"))
diff --git a/deluge/tests/unicode_filenames.torrent b/deluge/tests/unicode_filenames.torrent
new file mode 100644
index 000000000..e34f055df
--- /dev/null
+++ b/deluge/tests/unicode_filenames.torrent
Binary files differ
diff --git a/deluge/transfer.py b/deluge/transfer.py
index c89f89e4f..a09ad98a5 100644
--- a/deluge/transfer.py
+++ b/deluge/transfer.py
@@ -140,7 +140,7 @@ class DelugeTransferProtocol(Protocol):
"""
try:
- self.message_received(rencode.loads(zlib.decompress(data)))
+ self.message_received(rencode.loads(zlib.decompress(data), decode_utf8=True))
except Exception, e:
log.warn("Failed to decompress (%d bytes) and load serialized data "\
"with rencode: %s" % (len(data), str(e)))
diff --git a/deluge/ui/client.py b/deluge/ui/client.py
index 3feba4c57..342480e20 100644
--- a/deluge/ui/client.py
+++ b/deluge/ui/client.py
@@ -37,17 +37,14 @@
import logging
from twisted.internet.protocol import ClientFactory
from twisted.internet import reactor, ssl, defer
+import sys
+import subprocess
import deluge.common
from deluge import error
from deluge.event import known_events
from deluge.transfer import DelugeTransferProtocol
-if deluge.common.windows_check():
- import win32api
-else:
- import subprocess
-
RPC_RESPONSE = 1
RPC_ERROR = 2
RPC_EVENT = 3
@@ -628,13 +625,10 @@ class Client(object):
:raises OSError: received from subprocess.call()
"""
+ # subprocess.popen does not work with unicode args (with non-ascii characters) on windows
+ config = config.encode(sys.getfilesystemencoding())
try:
- if deluge.common.windows_check():
- win32api.WinExec("deluged --port=%s --config=\"%s\"" % (port, config))
- elif deluge.common.osx_check():
- subprocess.call(["nohup", "deluged", "--port=%s" % port, "--config=%s" % config])
- else:
- subprocess.call(["deluged", "--port=%s" % port, "--config=%s" % config])
+ subprocess.Popen(["deluged", "--port=%s" % port, "--config=%s" % config])
except OSError, e:
from errno import ENOENT
if e.errno == ENOENT:
diff --git a/deluge/ui/common.py b/deluge/ui/common.py
index 3b754cef7..795fdcda8 100644
--- a/deluge/ui/common.py
+++ b/deluge/ui/common.py
@@ -51,7 +51,7 @@ except ImportError:
from sha import sha
from deluge import bencode
-from deluge.common import decode_string, path_join
+from deluge.common import utf8_encoded, path_join
import deluge.configmanager
log = logging.getLogger(__name__)
@@ -88,9 +88,9 @@ class TorrentInfo(object):
# Check if 'name.utf-8' is in the torrent and if not try to decode the string
# using the encoding found.
if "name.utf-8" in self.__m_metadata["info"]:
- self.__m_name = decode_string(self.__m_metadata["info"]["name.utf-8"])
+ self.__m_name = utf8_encoded(self.__m_metadata["info"]["name.utf-8"])
else:
- self.__m_name = decode_string(self.__m_metadata["info"]["name"], self.encoding)
+ self.__m_name = utf8_encoded(self.__m_metadata["info"]["name"], self.encoding)
# Get list of files from torrent info
paths = {}
@@ -104,10 +104,13 @@ class TorrentInfo(object):
if "path.utf-8" in f:
path = os.path.join(prefix, *f["path.utf-8"])
else:
- path = decode_string(os.path.join(prefix, decode_string(os.path.join(*f["path"]), self.encoding)), self.encoding)
+ path = utf8_encoded(os.path.join(prefix, utf8_encoded(os.path.join(*f["path"]), self.encoding)), self.encoding)
f["index"] = index
+ if "sha1" in f and len(f["sha1"]) == 20:
+ f["sha1"] = f["sha1"].encode('hex')
+ if "ed2k" in f and len(f["ed2k"]) == 16:
+ f["ed2k"] = f["ed2k"].encode('hex')
paths[path] = f
-
dirname = os.path.dirname(path)
while dirname:
dirinfo = dirs.setdefault(dirname, {})
@@ -160,7 +163,7 @@ class TorrentInfo(object):
if "path.utf-8" in f:
path = os.path.join(prefix, *f["path.utf-8"])
else:
- path = decode_string(os.path.join(prefix, decode_string(os.path.join(*f["path"]), self.encoding)), self.encoding)
+ path = utf8_encoded(os.path.join(prefix, utf8_encoded(os.path.join(*f["path"]), self.encoding)), self.encoding)
self.__m_files.append({
'path': path,
'size': f["length"],
diff --git a/deluge/ui/console/commands/manage.py b/deluge/ui/console/commands/manage.py
index ab781b768..ef66829d4 100644
--- a/deluge/ui/console/commands/manage.py
+++ b/deluge/ui/console/commands/manage.py
@@ -133,7 +133,22 @@ class Command(BaseCommand):
deferred.callback(True)
self.console.write("Setting %s to %s for torrents %s.." % (key, val, torrent_ids))
- client.core.set_torrent_options(torrent_ids, {key: val}).addCallback(on_set_config)
+
+
+ for tid in torrent_ids:
+ if key == "move_on_completed_path":
+ client.core.set_torrent_move_completed_path(tid, val).addCallback(on_set_config)
+ elif key == "move_on_completed":
+ client.core.set_torrent_move_completed(tid, val).addCallback(on_set_config)
+ elif key == "is_auto_managed":
+ client.core.set_torrent_auto_managed(tid, val).addCallback(on_set_config)
+ elif key == "remove_at_ratio":
+ client.core.set_torrent_remove_at_ratio(tid, val).addCallback(on_set_config)
+ elif key == "prioritize_first_last":
+ client.core.set_torrent_prioritize_first_last(tid, val).addCallback(on_set_config)
+ else:
+ client.core.set_torrent_options(torrent_ids, {key: val}).addCallback(on_set_config)
+ break
return deferred
def complete(self, line):
diff --git a/deluge/ui/console/modes/torrent_actions.py b/deluge/ui/console/modes/torrent_actions.py
index 2988245e1..fb6a9f4cd 100644
--- a/deluge/ui/console/modes/torrent_actions.py
+++ b/deluge/ui/console/modes/torrent_actions.py
@@ -250,6 +250,8 @@ def torrent_action(idx, data, mode, ids):
for tid in ids:
if "move_on_completed_path" in options:
client.core.set_torrent_move_completed_path(tid, options["move_on_completed_path"])
+ if "move_on_completed" in options:
+ client.core.set_torrent_move_completed(tid, options["move_on_completed"])
if "is_auto_managed" in options:
client.core.set_torrent_auto_managed(tid, options["is_auto_managed"])
if "remove_at_ratio" in options:
diff --git a/deluge/ui/console/modes/torrentdetail.py b/deluge/ui/console/modes/torrentdetail.py
index 13ec757b9..4252c4e17 100644
--- a/deluge/ui/console/modes/torrentdetail.py
+++ b/deluge/ui/console/modes/torrentdetail.py
@@ -310,6 +310,8 @@ class TorrentDetail(BaseMode, component.Component):
color_partially_selected = "magenta"
color_highlighted = "white"
for fl in files:
+ #from sys import stderr
+ #print >> stderr, fl[6]
# kick out if we're going to draw too low on the screen
if (off >= self.rows-1):
self.more_to_draw = True
@@ -317,18 +319,34 @@ class TorrentDetail(BaseMode, component.Component):
self.file_limit = idx
- if idx >= self.file_off:
- # set fg/bg colors based on if we are selected/marked or not
- # default values
- fg = "white"
- bg = "black"
+ # default color values
+ fg = "white"
+ bg = "black"
+ attr = ""
+
+ if fl[6] == -2: priority = -1 #Mixed
+ elif fl[6] == 0:
+ priority = 0 #Do Not Download
+ fg = "red"
+ elif fl[6] == 1:
+ priority = 1 #Normal
+ elif fl[6] <= 6:
+ priority = 2 #High
+ fg = "yellow"
+ elif fl[6] == 7:
+ priority = 3 #Highest
+ fg = "green"
+
+ if idx >= self.file_off:
+ # set fg/bg colors based on whether the file is selected/marked or not
if fl[1] in self.marked:
bg = color_selected
if fl[3]:
if self.marked[fl[1]] < self.__get_contained_files_count(file_list=fl[3]):
bg = color_partially_selected
+ attr = "bold"
if idx == self.current_file_idx:
self.current_file = fl
@@ -339,9 +357,14 @@ class TorrentDetail(BaseMode, component.Component):
if self.marked[fl[1]] < self.__get_contained_files_count(file_list = fl[3]):
fg = color_partially_selected
else:
- fg = "black"
+ if fg == "white":
+ fg = "black"
+ attr = "bold"
- color_string = "{!%s,%s!}"%(fg,bg)
+ if attr:
+ color_string = "{!%s,%s,%s!}"%(fg, bg, attr)
+ else:
+ color_string = "{!%s,%s!}"%(fg, bg)
#actually draw the dir/file string
if fl[3] and fl[4]: # this is an expanded directory
diff --git a/deluge/ui/gtkui/addtorrentdialog.py b/deluge/ui/gtkui/addtorrentdialog.py
index 84ea16e57..13ac640d6 100644
--- a/deluge/ui/gtkui/addtorrentdialog.py
+++ b/deluge/ui/gtkui/addtorrentdialog.py
@@ -180,7 +180,11 @@ class AddTorrentDialog(component.Component):
self.builder.get_object("button_move_completed_location").hide()
self.builder.get_object("entry_move_completed_path").show()
- self.dialog.set_transient_for(component.get("MainWindow").window)
+ if component.get("MainWindow").is_on_active_workspace():
+ self.dialog.set_transient_for(component.get("MainWindow").window)
+ else:
+ self.dialog.set_transient_for(None)
+
self.dialog.present()
if focus:
self.dialog.window.focus()
@@ -213,9 +217,6 @@ class AddTorrentDialog(component.Component):
new_row = None
for filename in filenames:
- # Convert the path to unicode
- filename = unicode(filename)
-
# Get the torrent data from the torrent file
try:
info = deluge.ui.common.TorrentInfo(filename)
@@ -693,8 +694,7 @@ class AddTorrentDialog(component.Component):
# Create a tmp file path
import tempfile
- import os.path
- tmp_file = os.path.join(tempfile.gettempdir(), url.split("/")[-1])
+ (tmp_handle, tmp_file) = tempfile.mkstemp()
def on_part(data, current_length, total_length):
if total_length:
@@ -825,14 +825,15 @@ class AddTorrentDialog(component.Component):
self.save_torrent_options(row)
- # The options we want all the torrents to have
- options = self.options[model.get_value(row, 0)]
+ # The options, except file renames, we want all the torrents to have
+ options = self.options[model.get_value(row, 0)].copy()
+ options.pop("mapped_files", None)
# Set all the torrent options
row = model.get_iter_first()
while row != None:
torrent_id = model.get_value(row, 0)
- self.options[torrent_id] = options
+ self.options[torrent_id].update(options)
row = model.iter_next(row)
def _on_button_revert_clicked(self, widget):
@@ -863,7 +864,7 @@ class AddTorrentDialog(component.Component):
def _on_filename_edited(self, renderer, path, new_text):
index = self.files_treestore[path][3]
- new_text = new_text.strip(os.path.sep)
+ new_text = new_text.strip(os.path.sep).strip()
# Return if the text hasn't changed
if new_text == self.files_treestore[path][1]:
@@ -881,9 +882,15 @@ class AddTorrentDialog(component.Component):
if index > -1:
# We're renaming a file! Yay! That's easy!
+ if not new_text:
+ return
parent = self.files_treestore.iter_parent(itr)
file_path = os.path.join(self.get_file_path(parent), new_text)
-
+ # Don't rename if filename exists
+ if parent:
+ for row in self.files_treestore[parent].iterchildren():
+ if new_text == row[1]:
+ return
if os.path.sep in new_text:
# There are folders in this path, so we need to create them
# and then move the file iter to top
diff --git a/deluge/ui/gtkui/common.py b/deluge/ui/gtkui/common.py
index 4b56048e5..088223803 100644
--- a/deluge/ui/gtkui/common.py
+++ b/deluge/ui/gtkui/common.py
@@ -111,7 +111,7 @@ def build_menu_radio_list(value_list, callback, pref_value=None,
if show_notset:
menuitem = gtk.RadioMenuItem(group, notset_label)
- menuitem.set_name(notset_label)
+ menuitem.set_name("unlimited")
if pref_value < notset_lessthan and pref_value != None:
menuitem.set_active(True)
if show_activated and pref_value == 1:
@@ -124,7 +124,7 @@ def build_menu_radio_list(value_list, callback, pref_value=None,
menuitem = gtk.SeparatorMenuItem()
menu.append(menuitem)
menuitem = gtk.MenuItem(_("Other..."))
- menuitem.set_name(_("Other..."))
+ menuitem.set_name("other")
menuitem.connect("activate", callback)
menu.append(menuitem)
diff --git a/deluge/ui/gtkui/createtorrentdialog.py b/deluge/ui/gtkui/createtorrentdialog.py
index acfc06097..435cba0a6 100644
--- a/deluge/ui/gtkui/createtorrentdialog.py
+++ b/deluge/ui/gtkui/createtorrentdialog.py
@@ -174,7 +174,7 @@ class CreateTorrentDialog:
chooser.destroy()
return
- path = result.decode('utf-8').encode(sys.getfilesystemencoding())
+ path = result.decode('utf-8')
self.files_treestore.clear()
self.files_treestore.append(None, [result, gtk.STOCK_FILE, deluge.common.get_path_size(path)])
@@ -202,7 +202,7 @@ class CreateTorrentDialog:
chooser.destroy()
return
- path = result.decode('utf-8').encode(sys.getfilesystemencoding())
+ path = result.decode('utf-8')
self.files_treestore.clear()
self.files_treestore.append(None, [result, gtk.STOCK_OPEN, deluge.common.get_path_size(path)])
diff --git a/deluge/ui/gtkui/glade/preferences_dialog.ui b/deluge/ui/gtkui/glade/preferences_dialog.ui
index e9f526d38..09a6ea5de 100644
--- a/deluge/ui/gtkui/glade/preferences_dialog.ui
+++ b/deluge/ui/gtkui/glade/preferences_dialog.ui
@@ -2466,6 +2466,19 @@ used sparingly.</property>
</packing>
</child>
<child>
+ <object class="GtkCheckButton" id="chk_focus_main_window_on_add">
+ <property name="label" translatable="yes">Focus window when adding torrent</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
<object class="GtkCheckButton" id="piecesbar_toggle">
<property name="visible">True</property>
<property name="can_focus">True</property>
@@ -2491,7 +2504,7 @@ status tab (&lt;b&gt;EXPERIMENTAL!!!&lt;/b&gt;)</property>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
- <property name="position">1</property>
+ <property name="position">2</property>
</packing>
</child>
<child>
diff --git a/deluge/ui/gtkui/glade/tray_menu.ui b/deluge/ui/gtkui/glade/tray_menu.ui
index c92797cd2..b621e5fd4 100644
--- a/deluge/ui/gtkui/glade/tray_menu.ui
+++ b/deluge/ui/gtkui/glade/tray_menu.ui
@@ -61,6 +61,7 @@
<property name="use_underline">True</property>
<property name="image">menu-item-image1</property>
<property name="use_stock">False</property>
+ <property name="always_show_image">True</property>
<signal name="activate" handler="on_menuitem_add_torrent_activate" swapped="no"/>
</object>
</child>
@@ -109,6 +110,7 @@
<property name="use_underline">True</property>
<property name="image">download-limit-image</property>
<property name="use_stock">False</property>
+ <property name="always_show_image">True</property>
</object>
</child>
<child>
@@ -120,6 +122,7 @@
<property name="use_underline">True</property>
<property name="image">upload-limit-image</property>
<property name="use_stock">False</property>
+ <property name="always_show_image">True</property>
</object>
</child>
<child>
diff --git a/deluge/ui/gtkui/gtkui.py b/deluge/ui/gtkui/gtkui.py
index 53072e2ac..685ed45a5 100644
--- a/deluge/ui/gtkui/gtkui.py
+++ b/deluge/ui/gtkui/gtkui.py
@@ -149,6 +149,7 @@ DEFAULT_PREFS = {
"pieces_color_waiting": [4874, 56494, 0],
"pieces_color_downloading": [65535, 55255, 0],
"pieces_color_completed": [4883, 26985, 56540],
+ "focus_main_window_on_add": True,
}
class GtkUI(object):
@@ -245,9 +246,8 @@ class GtkUI(object):
component.stop()
# Process any pending gtk events since the mainloop has been quit
- if not deluge.common.windows_check():
- while gtk.events_pending() and reactor.running:
- reactor.doIteration(0)
+ while gtk.events_pending():
+ gtk.main_iteration(0)
# Shutdown all components
component.shutdown()
diff --git a/deluge/ui/gtkui/ipcinterface.py b/deluge/ui/gtkui/ipcinterface.py
index cb7259cc5..f8eab61da 100644
--- a/deluge/ui/gtkui/ipcinterface.py
+++ b/deluge/ui/gtkui/ipcinterface.py
@@ -40,6 +40,8 @@ import base64
import logging
from urllib import url2pathname
from urlparse import urlparse
+from glob import glob
+from tempfile import mkstemp
try:
import rencode
@@ -59,8 +61,10 @@ log = logging.getLogger(__name__)
class IPCProtocolServer(Protocol):
def dataReceived(self, data):
- data = rencode.loads(data)
- component.get("MainWindow").present()
+ config = ConfigManager("gtkui.conf")
+ data = rencode.loads(data, decode_utf8=True)
+ if not data or config["focus_main_window_on_add"]:
+ component.get("MainWindow").present()
process_args(data)
class IPCProtocolClient(Protocol):
@@ -75,23 +79,20 @@ class IPCProtocolClient(Protocol):
class IPCClientFactory(ClientFactory):
protocol = IPCProtocolClient
- def __init__(self, args, connect_failed):
+ def __init__(self):
self.stop = False
- self.args = args
- self.connect_failed = connect_failed
def clientConnectionFailed(self, connector, reason):
- log.info("Connection to running instance failed. Starting new one..")
+ log.warning("Connection to running instance failed.")
reactor.stop()
class IPCInterface(component.Component):
def __init__(self, args):
component.Component.__init__(self, "IPCInterface")
- if not os.path.exists(deluge.configmanager.get_config_dir("ipc")):
- os.makedirs(deluge.configmanager.get_config_dir("ipc"))
-
- socket = os.path.join(deluge.configmanager.get_config_dir("ipc"), "deluge-gtk")
-
+ ipc_dir = deluge.configmanager.get_config_dir("ipc")
+ if not os.path.exists(ipc_dir):
+ os.makedirs(ipc_dir)
+ socket = os.path.join(ipc_dir, "deluge-gtk")
if deluge.common.windows_check():
# If we're on windows we need to check the global mutex to see if deluge is
# already running.
@@ -120,6 +121,10 @@ class IPCInterface(component.Component):
reactor.run()
sys.exit(0)
else:
+ # Find and remove any restart tempfiles
+ old_tempfile = glob(os.path.join(ipc_dir, 'tmp*deluge'))
+ for f in old_tempfile:
+ os.remove(f)
lockfile = socket + ".lock"
log.debug("Checking if lockfile exists: %s", lockfile)
if os.path.lexists(lockfile):
@@ -138,45 +143,28 @@ class IPCInterface(component.Component):
self.factory.protocol = IPCProtocolServer
reactor.listenUNIX(socket, self.factory, wantPID=True)
except twisted.internet.error.CannotListenError, e:
- log.info("Deluge is already running! Sending arguments to running instance..")
- self.factory = IPCClientFactory(args, self.connect_failed)
+ log.info("Deluge is already running! Sending arguments to running instance...")
+ self.factory = IPCClientFactory()
+ self.factory.args = args
reactor.connectUNIX(socket, self.factory, checkPID=True)
reactor.run()
if self.factory.stop:
+ log.info("Success sending arguments to running Deluge.")
import gtk
gtk.gdk.notify_startup_complete()
sys.exit(0)
else:
- self.connect_failed(args)
+ if old_tempfile:
+ log.error("Deluge restart failed: %s", e)
+ sys.exit(1)
+ else:
+ log.warning('Restarting Deluge... (%s)', e)
+ # Create a tempfile to keep track of restart
+ mkstemp('deluge', dir=ipc_dir)
+ os.execv(sys.argv[0], sys.argv)
else:
process_args(args)
- def connect_failed(self, args):
- # This gets called when we're unable to do a connectUNIX to the ipc
- # socket. We'll delete the lock and socket files and start up Deluge.
-
- socket = os.path.join(deluge.configmanager.get_config_dir("ipc"), "deluge-gtk")
- if os.path.exists(socket):
- try:
- os.remove(socket)
- except Exception, e:
- log.error("Unable to remove socket file: %s", e)
-
- lock = socket + ".lock"
- if os.path.lexists(lock):
- try:
- os.remove(lock)
- except Exception, e:
- log.error("Unable to remove lock file: %s", e)
- try:
- self.factory = Factory()
- self.factory.protocol = IPCProtocolServer
- reactor.listenUNIX(socket, self.factory, wantPID=True)
- except Exception, e:
- log.error("Unable to start IPC listening socket: %s", e)
- finally:
- process_args(args)
-
def shutdown(self):
if deluge.common.windows_check():
import win32api
diff --git a/deluge/ui/gtkui/mainwindow.py b/deluge/ui/gtkui/mainwindow.py
index d491441d0..4d07a5750 100644
--- a/deluge/ui/gtkui/mainwindow.py
+++ b/deluge/ui/gtkui/mainwindow.py
@@ -42,6 +42,11 @@ import gtk
import logging
import urllib
+try:
+ import wnck
+except ImportError:
+ wnck = None
+
from deluge.ui.client import client
import deluge.component as component
from deluge.configmanager import ConfigManager
@@ -76,6 +81,8 @@ class _GtkBuilderSignalsHolder(object):
class MainWindow(component.Component):
def __init__(self):
+ if wnck:
+ self.screen = wnck.screen_get_default()
component.Component.__init__(self, "MainWindow", interval=2)
self.config = ConfigManager("gtkui.conf")
self.gtk_builder_signals_holder = _GtkBuilderSignalsHolder()
@@ -167,7 +174,6 @@ class MainWindow(component.Component):
component.resume("TorrentDetails")
except:
pass
-
self.window.show()
@@ -324,3 +330,11 @@ class MainWindow(component.Component):
def on_torrentfinished_event(self, torrent_id):
from deluge.ui.gtkui.notification import Notification
Notification().notify(torrent_id)
+
+ def is_on_active_workspace(self):
+ # Returns True if mainwindow is on active workspace or wnck module not available
+ if not wnck:
+ return True
+ for win in self.screen.get_windows():
+ if win.get_xid() == self.window.window.xid:
+ return win.is_on_workspace(win.get_screen().get_active_workspace())
diff --git a/deluge/ui/gtkui/pluginmanager.py b/deluge/ui/gtkui/pluginmanager.py
index b5169977d..a5bfcc819 100644
--- a/deluge/ui/gtkui/pluginmanager.py
+++ b/deluge/ui/gtkui/pluginmanager.py
@@ -93,6 +93,7 @@ class PluginManager(deluge.pluginmanagerbase.PluginManagerBase,
def _on_plugin_enabled_event(self, name):
self.enable_plugin(name)
+ self.run_on_show_prefs()
def _on_plugin_disabled_event(self, name):
self.disable_plugin(name)
diff --git a/deluge/ui/gtkui/preferences.py b/deluge/ui/gtkui/preferences.py
index 34f8da6f0..2755a330c 100644
--- a/deluge/ui/gtkui/preferences.py
+++ b/deluge/ui/gtkui/preferences.py
@@ -121,7 +121,8 @@ class Preferences(component.Component):
self.accounts_frame = self.builder.get_object("AccountsFrame")
# Setup plugin tab listview
- self.plugin_liststore = gtk.ListStore(str, bool)
+ # The third entry is for holding translated plugin names
+ self.plugin_liststore = gtk.ListStore(str, bool, str)
self.plugin_liststore.set_sort_column_id(0, gtk.SORT_ASCENDING)
self.plugin_listview = self.builder.get_object("plugin_listview")
self.plugin_listview.set_model(self.plugin_liststore)
@@ -131,7 +132,7 @@ class Preferences(component.Component):
self.plugin_listview.append_column(
gtk.TreeViewColumn(_("Enabled"), render, active=1))
self.plugin_listview.append_column(
- gtk.TreeViewColumn(_("Plugin"), gtk.CellRendererText(), text=0))
+ gtk.TreeViewColumn(_("Plugin"), gtk.CellRendererText(), text=2))
# Connect to the 'changed' event of TreeViewSelection to get selection
# changes.
@@ -552,6 +553,8 @@ class Preferences(component.Component):
self.gtkui_config["classic_mode"])
self.builder.get_object("chk_show_rate_in_title").set_active(
self.gtkui_config["show_rate_in_title"])
+ self.builder.get_object("chk_focus_main_window_on_add").set_active(
+ self.gtkui_config["focus_main_window_on_add"])
self.builder.get_object("piecesbar_toggle").set_active(
self.gtkui_config["show_piecesbar"]
)
@@ -583,6 +586,7 @@ class Preferences(component.Component):
row = self.plugin_liststore.append()
self.plugin_liststore.set_value(row, 0, plugin)
self.plugin_liststore.set_value(row, 1, enabled)
+ self.plugin_liststore.set_value(row, 2, _(plugin))
# Now show the dialog
self.pref_dialog.show()
@@ -739,6 +743,8 @@ class Preferences(component.Component):
new_gtkui_config["show_rate_in_title"] = \
self.builder.get_object("chk_show_rate_in_title").get_active()
+ new_gtkui_config["focus_main_window_on_add"] = \
+ self.builder.get_object("chk_focus_main_window_on_add").get_active()
## Other tab ##
new_gtkui_config["show_new_releases"] = \
diff --git a/deluge/ui/gtkui/queuedtorrents.py b/deluge/ui/gtkui/queuedtorrents.py
index 3b63934c5..7eeaaa78b 100644
--- a/deluge/ui/gtkui/queuedtorrents.py
+++ b/deluge/ui/gtkui/queuedtorrents.py
@@ -173,7 +173,7 @@ class QueuedTorrents(component.Component):
def on_button_add_clicked(self, widget):
# Add all the torrents in the liststore
def add_torrent(model, path, iter, data):
- torrent_path = model.get_value(iter, 1)
+ torrent_path = model.get_value(iter, 1).decode('utf-8')
process_args([torrent_path])
self.liststore.foreach(add_torrent, None)
diff --git a/deluge/ui/gtkui/statusbar.py b/deluge/ui/gtkui/statusbar.py
index c433b2834..f4219900c 100644
--- a/deluge/ui/gtkui/statusbar.py
+++ b/deluge/ui/gtkui/statusbar.py
@@ -392,9 +392,9 @@ class StatusBar(component.Component):
def _on_set_download_speed(self, widget):
log.debug("_on_set_download_speed")
- if widget.get_name() == _("Unlimited"):
+ if widget.get_name() == "unlimited":
value = -1
- elif widget.get_name() == _("Other..."):
+ elif widget.get_name() == "other":
value = common.show_other_dialog(
_("Set Maximum Download Speed"), _("KiB/s"), None, "downloading.svg", self.max_download_speed)
if value == None:
@@ -420,9 +420,9 @@ class StatusBar(component.Component):
def _on_set_upload_speed(self, widget):
log.debug("_on_set_upload_speed")
- if widget.get_name() == _("Unlimited"):
+ if widget.get_name() == "unlimited":
value = -1
- elif widget.get_name() == _("Other..."):
+ elif widget.get_name() == "other":
value = common.show_other_dialog(
_("Set Maximum Upload Speed"), _("KiB/s"), None, "seeding.svg", self.max_upload_speed)
if value == None:
@@ -447,9 +447,9 @@ class StatusBar(component.Component):
def _on_set_connection_limit(self, widget):
log.debug("_on_set_connection_limit")
- if widget.get_name() == _("Unlimited"):
+ if widget.get_name() == "unlimited":
value = -1
- elif widget.get_name() == _("Other..."):
+ elif widget.get_name() == "other":
value = common.show_other_dialog(
_("Set Maximum Connections"), "", gtk.STOCK_NETWORK, None, self.max_connections)
if value == None:
diff --git a/deluge/ui/gtkui/systemtray.py b/deluge/ui/gtkui/systemtray.py
index c54b0943a..553ebb354 100644
--- a/deluge/ui/gtkui/systemtray.py
+++ b/deluge/ui/gtkui/systemtray.py
@@ -138,10 +138,9 @@ class SystemTray(component.Component):
self.tray.connect("activate", self.on_tray_clicked)
self.tray.connect("popup-menu", self.on_tray_popup)
- # For some reason these icons do not display in appindicator
- self.builder.get_object("download-limit-image").set_from_file(
+ self.builder.get_object("download-limit-image").set_from_file(
deluge.common.get_pixmap("downloading16.png"))
- self.builder.get_object("upload-limit-image").set_from_file(
+ self.builder.get_object("upload-limit-image").set_from_file(
deluge.common.get_pixmap("seeding16.png"))
client.register_event_handler("ConfigValueChangedEvent", self.config_value_changed)
@@ -157,21 +156,14 @@ class SystemTray(component.Component):
if self.config["enable_system_tray"]:
if self.config["classic_mode"]:
- self.hide_widget_list.remove("menuitem_quitdaemon")
- self.hide_widget_list.remove("separatormenuitem4")
+ try:
+ self.hide_widget_list.remove("menuitem_quitdaemon")
+ self.hide_widget_list.remove("separatormenuitem4")
+ except ValueError:
+ pass
self.builder.get_object("menuitem_quitdaemon").hide()
self.builder.get_object("separatormenuitem4").hide()
- # These do not work with appindicator currently and can crash Deluge.
- # Related to Launchpad bug #608219
- if appindicator and self.config["enable_appindicator"]:
- self.hide_widget_list.remove("menuitem_download_limit")
- self.hide_widget_list.remove("menuitem_upload_limit")
- self.hide_widget_list.remove("separatormenuitem3")
- self.builder.get_object("menuitem_download_limit").hide()
- self.builder.get_object("menuitem_upload_limit").hide()
- self.builder.get_object("separatormenuitem3").hide()
-
# Show widgets in the hide list because we've connected to a host
for widget in self.hide_widget_list:
self.builder.get_object(widget).show()
@@ -266,16 +258,15 @@ class SystemTray(component.Component):
def build_tray_bwsetsubmenu(self):
# Create the Download speed list sub-menu
submenu_bwdownset = common.build_menu_radio_list(
- self.config["tray_download_speed_list"], self.tray_setbwdown,
+ self.config["tray_download_speed_list"], self.on_tray_setbwdown,
self.max_download_speed,
_("KiB/s"), show_notset=True, show_other=True)
# Create the Upload speed list sub-menu
submenu_bwupset = common.build_menu_radio_list(
- self.config["tray_upload_speed_list"], self.tray_setbwup,
+ self.config["tray_upload_speed_list"], self.on_tray_setbwup,
self.max_upload_speed,
_("KiB/s"), show_notset=True, show_other=True)
-
# Add the sub-menus to the tray menu
self.builder.get_object("menuitem_download_limit").set_submenu(
submenu_bwdownset)
@@ -286,10 +277,6 @@ class SystemTray(component.Component):
submenu_bwdownset.show_all()
submenu_bwupset.show_all()
- # Re-set the menu to partly work around Launchpad bug #608219
- if appindicator and self.config["enable_appindicator"]:
- self.indicator.set_menu(self.tray_menu)
-
def disable(self,invert_app_ind_conf=False):
"""Disables the system tray icon or appindicator."""
try:
@@ -360,6 +347,7 @@ class SystemTray(component.Component):
popup_function = gtk.status_icon_position_menu
if deluge.common.windows_check():
popup_function = None
+ button = 0
self.tray_menu.popup(None, None, popup_function,
button, activate_time, status_icon)
@@ -399,10 +387,22 @@ class SystemTray(component.Component):
self.window.quit(shutdown=True)
- def tray_setbwdown(self, widget, data=None):
+ def on_tray_setbwdown(self, widget, data=None):
+ if isinstance(widget, gtk.RadioMenuItem):
+ #ignore previous radiomenuitem value
+ if not widget.get_active():
+ return
self.setbwlimit(widget, _("Set Maximum Download Speed"), "max_download_speed",
"tray_download_speed_list", self.max_download_speed, "downloading.svg")
+ def on_tray_setbwup(self, widget, data=None):
+ if isinstance(widget, gtk.RadioMenuItem):
+ #ignore previous radiomenuitem value
+ if not widget.get_active():
+ return
+ self.setbwlimit(widget, _("Set Maximum Upload Speed"), "max_upload_speed",
+ "tray_upload_speed_list", self.max_upload_speed, "seeding.svg")
+
def _on_window_hide(self, widget, data=None):
"""_on_window_hide - update the menuitem's status"""
log.debug("_on_window_hide")
@@ -413,26 +413,21 @@ class SystemTray(component.Component):
log.debug("_on_window_show")
self.builder.get_object("menuitem_show_deluge").set_active(True)
- def tray_setbwup(self, widget, data=None):
- self.setbwlimit(widget, _("Set Maximum Upload Speed"), "max_upload_speed",
- "tray_upload_speed_list", self.max_upload_speed, "seeding.svg")
-
def setbwlimit(self, widget, string, core_key, ui_key, default, image):
"""Sets the bandwidth limit based on the user selection."""
- value = widget.get_children()[0].get_text().rstrip(" " + _("KiB/s"))
- if value == _("Unlimited"):
+ value = widget.get_children()[0].get_text().split(" ")[0]
+ log.debug('setbwlimit: %s', value)
+ if widget.get_name() == "unlimited":
value = -1
-
- if value == _("Other..."):
+ if widget.get_name() == "other":
value = common.show_other_dialog(string, _("KiB/s"), None, image, default)
if value == None:
return
-
+ elif value == 0:
+ value = -1
# Set the config in the core
client.core.set_config({core_key: value})
- self.build_tray_bwsetsubmenu()
-
def unlock_tray(self, is_showing_dlg=[False]):
try:
from hashlib import sha1 as sha_hash
@@ -450,13 +445,13 @@ class SystemTray(component.Component):
entered_pass.set_width_chars(25)
entered_pass.set_visibility(False)
- tray_lock = gtk.Dialog(title="", parent=self.window.window,
+ self.tray_lock = gtk.Dialog(title="", parent=self.window.window,
buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK,
gtk.RESPONSE_OK))
- tray_lock.set_default_response(gtk.RESPONSE_OK)
- tray_lock.set_has_separator(False)
+ self.tray_lock.set_default_response(gtk.RESPONSE_OK)
+ self.tray_lock.set_has_separator(False)
- tray_lock.set_border_width(5)
+ self.tray_lock.set_border_width(5)
hbox = gtk.HBox(spacing=5)
@@ -481,15 +476,15 @@ class SystemTray(component.Component):
vbox.pack_start(entered_pass)
- tray_lock.vbox.pack_start(hbox)
+ self.tray_lock.vbox.pack_start(hbox)
def on_response(dialog, response_id):
if response_id == gtk.RESPONSE_OK:
if self.config["tray_password"] == sha_hash(entered_pass.get_text()).hexdigest():
self.window.present()
- tray_lock.destroy()
+ self.tray_lock.destroy()
is_showing_dlg[0] = False
- tray_lock.connect("response", on_response)
- tray_lock.show_all()
+ self.tray_lock.connect("response", on_response)
+ self.tray_lock.show_all()
diff --git a/deluge/ui/gtkui/torrentdetails.py b/deluge/ui/gtkui/torrentdetails.py
index 36fc92270..6c11af8f6 100644
--- a/deluge/ui/gtkui/torrentdetails.py
+++ b/deluge/ui/gtkui/torrentdetails.py
@@ -113,6 +113,15 @@ class TorrentDetails(component.Component):
("Options", True)
]
+ self.translate_tabs = {
+ "All" : _("_All"),
+ "Status" : _("_Status"),
+ "Details" : _("_Details"),
+ "Files" : _("_Files"),
+ "Peers" : _("_Peers"),
+ "Options" : _("_Options")
+ }
+
# Get the state from saved file
state = self.load_state()
@@ -242,8 +251,8 @@ class TorrentDetails(component.Component):
def hide_tab(self, tab_name):
"""Hides tab by name"""
- self.notebook.remove_page(self.tabs[tab_name].position)
self.tabs[tab_name].is_visible = False
+ self.notebook.remove_page(self.tabs[tab_name].position)
self.regenerate_positions()
self.generate_menu()
@@ -275,7 +284,8 @@ class TorrentDetails(component.Component):
"""Generates the checklist menu for all the tabs and attaches it"""
menu = gtk.Menu()
# Create 'All' menuitem and a separator
- menuitem = gtk.CheckMenuItem("All")
+ menuitem = gtk.CheckMenuItem(self.translate_tabs["All"], True)
+ menuitem.set_name("All")
all_tabs = True
for key in self.tabs:
@@ -297,7 +307,8 @@ class TorrentDetails(component.Component):
menuitem_list.sort()
for pos, name in menuitem_list:
- menuitem = gtk.CheckMenuItem(name)
+ menuitem = gtk.CheckMenuItem(self.translate_tabs[name], True)
+ menuitem.set_name(name)
menuitem.set_active(self.tabs[name].is_visible)
menuitem.connect("toggled", self._on_menuitem_toggled)
menu.append(menuitem)
@@ -386,7 +397,7 @@ class TorrentDetails(component.Component):
def _on_menuitem_toggled(self, widget):
# Get the tab name
- name = widget.get_child().get_text()
+ name = widget.get_name()
if name == "All":
if widget.get_active():
self.show_all_tabs()
diff --git a/deluge/ui/sessionproxy.py b/deluge/ui/sessionproxy.py
index d861afdc6..b7acd890f 100644
--- a/deluge/ui/sessionproxy.py
+++ b/deluge/ui/sessionproxy.py
@@ -67,11 +67,11 @@ class SessionProxy(component.Component):
# Holds the time of the last key update.. {torrent_id: {key1, time, ...}, ...}
self.cache_times = {}
+ def start(self):
client.register_event_handler("TorrentStateChangedEvent", self.on_torrent_state_changed)
client.register_event_handler("TorrentRemovedEvent", self.on_torrent_removed)
client.register_event_handler("TorrentAddedEvent", self.on_torrent_added)
- def start(self):
def on_get_session_state(torrent_ids):
for torrent_id in torrent_ids:
# Let's at least store the torrent ids with empty statuses
diff --git a/deluge/ui/ui.py b/deluge/ui/ui.py
index 792f416c2..46a597a5f 100644
--- a/deluge/ui/ui.py
+++ b/deluge/ui/ui.py
@@ -107,7 +107,9 @@ class _UI(object):
return self.__args
def start(self):
- (self.__options, self.__args) = self.__parser.parse_args()
+ # Make sure all arguments are unicode
+ argv = deluge.common.unicode_argv()[1:]
+ (self.__options, self.__args) = self.__parser.parse_args(argv)
if self.__options.quiet:
self.__options.loglevel = "none"
diff --git a/deluge/ui/web/TODO b/deluge/ui/web/TODO
deleted file mode 100644
index 6861a65f1..000000000
--- a/deluge/ui/web/TODO
+++ /dev/null
@@ -1,4 +0,0 @@
-* Add Window torrent options
- - Add an options manager
-* Preferences window options
- - Add an options manager
diff --git a/deluge/ui/web/auth.py b/deluge/ui/web/auth.py
index 5cd345e2c..e26eab486 100644
--- a/deluge/ui/web/auth.py
+++ b/deluge/ui/web/auth.py
@@ -322,4 +322,5 @@ class Auth(JSONComponent):
if self.check_password(password):
return self._create_session(__request__)
else:
+ log.error('Login failed (ClientIP %s)', __request__.getClientIP())
return False
diff --git a/deluge/ui/web/build b/deluge/ui/web/build
index 0c196770e..ad8944285 100755
--- a/deluge/ui/web/build
+++ b/deluge/ui/web/build
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/sh
BASE_DIR="${PWD}/`dirname ${0}`"
BASE_DIR=`readlink -f "$BASE_DIR"`
@@ -32,7 +32,7 @@ check_file()
FILE=$1
LAST_BUILD=`grep $FILE $BUILD_DATA`
- if [ $? == 1 ]; then return 1; fi;
+ if [ $? = 1 ]; then return 1; fi;
CURRENT=`grep $FILE $BUILD_DATA.tmp`
diff --git a/deluge/ui/web/css/deluge.css b/deluge/ui/web/css/deluge.css
index 4701d7e66..ab02a4536 100644
--- a/deluge/ui/web/css/deluge.css
+++ b/deluge/ui/web/css/deluge.css
@@ -244,10 +244,57 @@ dl.singleline dd {
}
/* Files TreeGrid */
+.x-treegrid-root-table {
+ border-right: 1px solid;
+}
+
+.x-treegrid-root-node {
+ overflow: auto;
+}
+
+.x-treegrid-hd-hidden {
+ visibility: hidden;
+ border: 0;
+ width: 0;
+}
+
.x-treegrid-col {
- overflow: hidden;
+ border-bottom: 1px solid;
+ height: 20px;
+ overflow: hidden;
+ vertical-align: top;
+ -o-text-overflow: ellipsis;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.x-treegrid-text {
+ padding-left: 4px;
+ -moz-user-select: none;
+ -khtml-user-select: none;
+}
+
+.x-treegrid-resizer {
+ border-left:1px solid;
+ border-right:1px solid;
+ position:absolute;
+ left:0;
+ top:0;
+}
+
+.x-treegrid-header-inner {
+ overflow: hidden;
}
+.x-treegrid-root-table,
+.x-treegrid-col {
+ border-color: #ededed;
+}
+
+.x-treegrid-resizer {
+ border-left-color:#555;
+ border-right-color:#555;
+}
/* Options Tab Styles */
.x-deluge-options-label {
diff --git a/deluge/ui/web/gen_gettext.py b/deluge/ui/web/gen_gettext.py
index 05025aec5..b2518d74b 100644..100755
--- a/deluge/ui/web/gen_gettext.py
+++ b/deluge/ui/web/gen_gettext.py
@@ -2,15 +2,14 @@
"""
Script to go through the javascript files and dynamically generate gettext.js
"""
-
import os
import re
-import glob
-import cStringIO as StringIO
+output_file = "gettext.js"
string_re = re.compile('_\\(\'(.*?)\'\\)')
strings = {}
+
gettext_tpl = """## -*- coding: utf-8 -*-
/*
* Script: gettext.js
@@ -59,10 +58,10 @@ for root, dnames, files in os.walk('js/deluge-all'):
keys = strings.keys()
keys.sort()
-fp = StringIO.StringIO()
+fp = open(output_file, 'w')
fp.write(gettext_tpl)
for key in keys:
fp.write('// %s\n' % ', '.join(map(lambda x: '%s:%s' % x, strings[key])))
fp.write("GetText.add('%(key)s', '${escape(_(\"%(key)s\"))}')\n\n" % locals())
-fp.seek(0)
-print fp.read()
+fp.close()
+
diff --git a/deluge/ui/web/gettext.js b/deluge/ui/web/gettext.js
index 7bed3e588..acef95a7b 100644
--- a/deluge/ui/web/gettext.js
+++ b/deluge/ui/web/gettext.js
@@ -26,739 +26,819 @@ function _(string) {
return GetText.get(string);
}
-// Deluge.Torrents.js:117
+// TorrentGrid.js:109
GetText.add('#', '${escape(_("#"))}')
-// Deluge.Menus.js:167
+// DetailsTab.js:50
+GetText.add('# of files', '${escape(_("# of files"))}')
+
+// Menus.js:166
GetText.add('0', '${escape(_("0"))}')
-// Deluge.Menus.js:169
+// Menus.js:168
GetText.add('1', '${escape(_("1"))}')
-// Deluge.Menus.js:115, Deluge.Menus.js:133
+// Menus.js:111, Menus.js:130
GetText.add('10 KiB/s', '${escape(_("10 KiB/s"))}')
-// Deluge.Menus.js:151
+// Menus.js:149
GetText.add('100', '${escape(_("100"))}')
-// Deluge.Menus.js:171
+// Menus.js:170
GetText.add('2', '${escape(_("2"))}')
-// Deluge.Menus.js:153
+// Menus.js:151
GetText.add('200', '${escape(_("200"))}')
-// Deluge.Menus.js:173
+// Menus.js:172
GetText.add('3', '${escape(_("3"))}')
-// Deluge.Menus.js:117, Deluge.Menus.js:135
+// Menus.js:113, Menus.js:132
GetText.add('30 KiB/s', '${escape(_("30 KiB/s"))}')
-// Deluge.Menus.js:155
+// Menus.js:153
GetText.add('300', '${escape(_("300"))}')
-// Deluge.Menus.js:121, Deluge.Menus.js:139
+// Menus.js:117, Menus.js:136
GetText.add('300 KiB/s', '${escape(_("300 KiB/s"))}')
-// Deluge.Menus.js:175
+// Menus.js:174
GetText.add('5', '${escape(_("5"))}')
-// Deluge.Menus.js:113, Deluge.Menus.js:131
+// Menus.js:109, Menus.js:128
GetText.add('5 KiB/s', '${escape(_("5 KiB/s"))}')
-// Deluge.Menus.js:149
+// Menus.js:147
GetText.add('50', '${escape(_("50"))}')
-// Deluge.Menus.js:157
+// Menus.js:155
GetText.add('500', '${escape(_("500"))}')
-// Deluge.Menus.js:119, Deluge.Menus.js:137
+// Menus.js:115, Menus.js:134
GetText.add('80 KiB/s', '${escape(_("80 KiB/s"))}')
-// Deluge.Preferences.Queue.js:70
+// QueuePage.js:69
GetText.add('Active Torrents', '${escape(_("Active Torrents"))}')
-// Deluge.ConnectionManager.js:64, Deluge.ConnectionManager.js:222, Deluge.Add.Url.js:55, Deluge.Toolbar.js:51, Deluge.Add.js:384, Deluge.EditTrackers.js:58, Deluge.EditTrackers.js:237, Deluge.Add.File.js:55
+// EditTrackersWindow.js:112, ConnectionManager.js:100, AddConnectionWindow.js:56, Toolbar.js:58, AddTrackerWindow.js:57, UrlWindow.js:50, FileWindow.js:53, AddWindow.js:52
GetText.add('Add', '${escape(_("Add"))}')
-// Deluge.ConnectionManager.js:52
+// AddConnectionWindow.js:40
GetText.add('Add Connection', '${escape(_("Add Connection"))}')
-// Deluge.Add.js:184
+// OptionsTab.js:144
GetText.add('Add In Paused State', '${escape(_("Add In Paused State"))}')
-// Deluge.Add.js:366
+// AddWindow.js:37
GetText.add('Add Torrents', '${escape(_("Add Torrents"))}')
-// Deluge.EditTrackers.js:39
+// AddTrackerWindow.js:40
GetText.add('Add Tracker', '${escape(_("Add Tracker"))}')
-// Deluge.Add.File.js:47
+// FileWindow.js:40
GetText.add('Add from File', '${escape(_("Add from File"))}')
-// Deluge.Add.Url.js:47
+// UrlWindow.js:36
GetText.add('Add from Url', '${escape(_("Add from Url"))}')
-// Deluge.Preferences.Downloads.js:142
+// DownloadsPage.js:146
GetText.add('Add torrents in Paused state', '${escape(_("Add torrents in Paused state"))}')
-// Deluge.Torrents.js:184
+// TorrentGrid.js:180
GetText.add('Added', '${escape(_("Added"))}')
-// Deluge.Sidebar.js:198
+// FilterPanel.js:124
GetText.add('All', '${escape(_("All"))}')
-// Deluge.Add.js:114, Deluge.Preferences.Downloads.js:97
+// OptionsTab.js:77, DownloadsPage.js:100
GetText.add('Allocation', '${escape(_("Allocation"))}')
-// Deluge.Preferences.Daemon.js:81
+// DaemonPage.js:77
GetText.add('Allow Remote Connections', '${escape(_("Allow Remote Connections"))}')
-// Deluge.Details.Options.js:347, Deluge.Preferences.js:91
+// InterfacePage.js:78
+GetText.add('Allow the use of multiple filters at once', '${escape(_("Allow the use of multiple filters at once"))}')
+
+// OptionsTab.js:347, PreferencesWindow.js:107
GetText.add('Apply', '${escape(_("Apply"))}')
-// Deluge.Menus.js:182, Deluge.Details.Options.js:215
+// Menus.js:181, OptionsTab.js:215
GetText.add('Auto Managed', '${escape(_("Auto Managed"))}')
-// Deluge.Preferences.Downloads.js:88
+// DownloadsPage.js:91
GetText.add('Autoadd .torrent files from', '${escape(_("Autoadd .torrent files from"))}')
-// Deluge.Torrents.js:178
+// TorrentGrid.js:173
GetText.add('Avail', '${escape(_("Avail"))}')
-// Deluge.Add.js:144, Deluge.Details.Options.js:88, Deluge.Preferences.Bandwidth.js:39
+// FileBrowser.js:47
+GetText.add('Back', '${escape(_("Back"))}')
+
+// OptionsTab.js:88, OptionsTab.js:107, BandwidthPage.js:42
GetText.add('Bandwidth', '${escape(_("Bandwidth"))}')
-// Deluge.Preferences.Other.js:63
+// OtherPage.js:66
GetText.add('Be alerted about new releases', '${escape(_("Be alerted about new releases"))}')
-// Deluge.Menus.js:210
+// Menus.js:210
GetText.add('Bottom', '${escape(_("Bottom"))}')
-// Deluge.Preferences.Plugins.js:74, Deluge.Add.File.js:70
+// MoveStorage.js:73, FileWindow.js:70, InstallPluginWindow.js:69
GetText.add('Browse', '${escape(_("Browse"))}')
-// Deluge.Preferences.Cache.js:39
+// CachePage.js:41
GetText.add('Cache', '${escape(_("Cache"))}')
-// Deluge.Preferences.Cache.js:71
+// CachePage.js:69
GetText.add('Cache Expiry (seconds)', '${escape(_("Cache Expiry (seconds)"))}')
-// Deluge.Preferences.Cache.js:59
+// CachePage.js:63
GetText.add('Cache Size (16 KiB Blocks)', '${escape(_("Cache Size (16 KiB Blocks)"))}')
-// Deluge.Add.js:383, Deluge.MoveStorage.js:56, Deluge.EditTrackers.js:57, Deluge.EditTrackers.js:116, Deluge.EditTrackers.js:178, Deluge.Remove.js:53
+// EditTrackersWindow.js:56, OtherLimitWindow.js:72, RemoveWindow.js:55, MoveStorage.js:55, EditTrackerWindow.js:56, AddTrackerWindow.js:56, AddWindow.js:51
GetText.add('Cancel', '${escape(_("Cancel"))}')
-// Deluge.Preferences.js:55
+// PreferencesWindow.js:85
GetText.add('Categories', '${escape(_("Categories"))}')
-// Deluge.Preferences.Interface.js:180
+// InterfacePage.js:173
GetText.add('Certificate', '${escape(_("Certificate"))}')
-// Deluge.Preferences.Interface.js:118
+// InterfacePage.js:117
GetText.add('Change', '${escape(_("Change"))}')
-// Deluge.Preferences.Interface.js:227
+// InterfacePage.js:224
GetText.add('Change Successful', '${escape(_("Change Successful"))}')
-// Deluge.ConnectionManager.js:63, Deluge.ConnectionManager.js:171, Deluge.Preferences.js:90
+// ConnectionManager.js:54, AddConnectionWindow.js:55, PreferencesWindow.js:106
GetText.add('Close', '${escape(_("Close"))}')
-// Deluge.Add.js:137
+// DetailsTab.js:51
+GetText.add('Comment', '${escape(_("Comment"))}')
+
+// OptionsTab.js:100
GetText.add('Compact', '${escape(_("Compact"))}')
-// Deluge.Preferences.Interface.js:106
+// InterfacePage.js:105
GetText.add('Confirm Password', '${escape(_("Confirm Password"))}')
-// Deluge.ConnectionManager.js:172, Deluge.ConnectionManager.js:284
+// ConnectionManager.js:55, ConnectionManager.js:184
GetText.add('Connect', '${escape(_("Connect"))}')
-// Deluge.ConnectionManager.js:277, Deluge.ConnectionManager.js:322
+// ConnectionManager.js:177, ConnectionManager.js:225
GetText.add('Connected', '${escape(_("Connected"))}')
-// Deluge.Menus.js:145
+// Menus.js:142
GetText.add('Connection Limit', '${escape(_("Connection Limit"))}')
-// Deluge.ConnectionManager.js:159, Deluge.Toolbar.js:99
+// ConnectionManager.js:43, Toolbar.js:100
GetText.add('Connection Manager', '${escape(_("Connection Manager"))}')
-// Deluge.Statusbar.js:25, Deluge.Preferences.Daemon.js:72
+// UI.js:151
+GetText.add('Connection restored', '${escape(_("Connection restored"))}')
+
+// Statusbar.js:57, DaemonPage.js:68
GetText.add('Connections', '${escape(_("Connections"))}')
-// Deluge.Add.Url.js:73
+// UrlWindow.js:68
GetText.add('Cookies', '${escape(_("Cookies"))}')
-// Deluge.Preferences.Downloads.js:80
+// DownloadsPage.js:83
GetText.add('Copy of .torrent files to', '${escape(_("Copy of .torrent files to"))}')
-// Deluge.Toolbar.js:44
+// Toolbar.js:52
GetText.add('Create', '${escape(_("Create"))}')
-// Deluge.Menus.js:109
+// Menus.js:104
GetText.add('D/L Speed Limit', '${escape(_("D/L Speed Limit"))}')
-// Deluge.Preferences.Network.js:229, Deluge.Preferences.Proxy.js:202
+// NetworkPage.js:225, ProxyPage.js:70
GetText.add('DHT', '${escape(_("DHT"))}')
-// Deluge.Statusbar.js:52
+// Statusbar.js:210
GetText.add('DHT Nodes', '${escape(_("DHT Nodes"))}')
-// Deluge.Preferences.Daemon.js:39
+// DaemonPage.js:41
GetText.add('Daemon', '${escape(_("Daemon"))}')
-// Deluge.Preferences.Daemon.js:58
+// DaemonPage.js:57
GetText.add('Daemon port', '${escape(_("Daemon port"))}')
-// Deluge.Details.Details.js:36
+// Toolbar.js:45
+GetText.add('Deluge', '${escape(_("Deluge"))}')
+
+// DetailsTab.js:36
GetText.add('Details', '${escape(_("Details"))}')
-// Deluge.Preferences.Encryption.js:66, Deluge.Preferences.Encryption.js:82
+// EncryptionPage.js:65, EncryptionPage.js:82
GetText.add('Disabled', '${escape(_("Disabled"))}')
-// Deluge.ConnectionManager.js:279
+// ConnectionManager.js:179
GetText.add('Disconnect', '${escape(_("Disconnect"))}')
-// Deluge.Menus.js:410, Deluge.js:107
+// Menus.js:257, Deluge.js:156
GetText.add('Do Not Download', '${escape(_("Do Not Download"))}')
-// Deluge.Preferences.Queue.js:117
+// QueuePage.js:107
GetText.add('Do not count slow torrents', '${escape(_("Do not count slow torrents"))}')
-// Deluge.Toolbar.js:86, Deluge.Menus.js:204, Deluge.EditTrackers.js:231
+// EditTrackersWindow.js:107, Menus.js:204, Toolbar.js:89
GetText.add('Down', '${escape(_("Down"))}')
-// Deluge.Torrents.js:154
+// TorrentGrid.js:241
+GetText.add('Down Limit', '${escape(_("Down Limit"))}')
+
+// TorrentGrid.js:148
GetText.add('Down Speed', '${escape(_("Down Speed"))}')
-// Deluge.Add.js:94
+// FilesTab.js:63
+GetText.add('Download', '${escape(_("Download"))}')
+
+// OptionsTab.js:55
GetText.add('Download Location', '${escape(_("Download Location"))}')
-// Deluge.Statusbar.js:32
+// Statusbar.js:104
GetText.add('Download Speed', '${escape(_("Download Speed"))}')
-// Deluge.Preferences.Downloads.js:66
+// DownloadsPage.js:69
GetText.add('Download to', '${escape(_("Download to"))}')
-// Deluge.Preferences.Downloads.js:39
+// TorrentGrid.js:227
+GetText.add('Downloaded', '${escape(_("Downloaded"))}')
+
+// DownloadsPage.js:42
GetText.add('Downloads', '${escape(_("Downloads"))}')
-// Deluge.Torrents.js:166
+// TorrentGrid.js:160
GetText.add('ETA', '${escape(_("ETA"))}')
-// Deluge.EditTrackers.js:243
+// EditTrackersWindow.js:117
GetText.add('Edit', '${escape(_("Edit"))}')
-// Deluge.EditTrackers.js:98
+// EditTrackerWindow.js:40
GetText.add('Edit Tracker', '${escape(_("Edit Tracker"))}')
-// Deluge.Menus.js:224, Deluge.Details.Options.js:329, Deluge.EditTrackers.js:160
+// EditTrackersWindow.js:40, Menus.js:224, OptionsTab.js:332
GetText.add('Edit Trackers', '${escape(_("Edit Trackers"))}')
-// Deluge.Preferences.Encryption.js:98
+// EncryptionPage.js:99
GetText.add('Either', '${escape(_("Either"))}')
-// Deluge.Preferences.Plugins.js:157, Deluge.Preferences.Encryption.js:65, Deluge.Preferences.Encryption.js:81
+// EncryptionPage.js:64, EncryptionPage.js:81, PluginsPage.js:81
GetText.add('Enabled', '${escape(_("Enabled"))}')
-// Deluge.Preferences.Encryption.js:110
+// EncryptionPage.js:112
GetText.add('Encrypt entire stream', '${escape(_("Encrypt entire stream"))}')
-// Deluge.Preferences.Encryption.js:39
+// EncryptionPage.js:41
GetText.add('Encryption', '${escape(_("Encryption"))}')
-// Deluge.ConnectionManager.js:128, Deluge.ConnectionManager.js:391, Deluge.ConnectionManager.js:447, Deluge.Add.js:541
+// ConnectionManager.js:308, ConnectionManager.js:364, AddConnectionWindow.js:103, AddWindow.js:209
GetText.add('Error', '${escape(_("Error"))}')
-// Deluge.Menus.js:406
+// Menus.js:253
GetText.add('Expand All', '${escape(_("Expand All"))}')
-// Deluge.Add.js:431, Deluge.Add.File.js:67
+// FileWindow.js:67, AddWindow.js:98
GetText.add('File', '${escape(_("File"))}')
-// Deluge.Add.js:63, Deluge.Details.Files.js:53
+// FileBrowser.js:36
+GetText.add('File Browser', '${escape(_("File Browser"))}')
+
+// OptionsPanel.js:143
+GetText.add('File prioritization is unavailable when using Compact allocation. Would you like to switch to Full allocation?', '${escape(_("File prioritization is unavailable when using Compact allocation. Would you like to switch to Full allocation?"))}')
+
+// FilesTab.js:40, FilesTab.js:50
GetText.add('Filename', '${escape(_("Filename"))}')
-// Deluge.Add.js:54, Deluge.Details.Files.js:47
+// FilesTab.js:35, FilesTab.js:41
GetText.add('Files', '${escape(_("Files"))}')
-// Deluge.Sidebar.js:75
+// Sidebar.js:55
GetText.add('Filters', '${escape(_("Filters"))}')
-// Deluge.Preferences.Plugins.js:191
+// PluginsPage.js:118
GetText.add('Find More', '${escape(_("Find More"))}')
-// Deluge.Preferences.Downloads.js:54
+// DownloadsPage.js:57
GetText.add('Folders', '${escape(_("Folders"))}')
-// Deluge.Menus.js:236
+// Menus.js:236
GetText.add('Force Recheck', '${escape(_("Force Recheck"))}')
-// Deluge.Preferences.Encryption.js:64, Deluge.Preferences.Encryption.js:80
+// EncryptionPage.js:63, EncryptionPage.js:80
GetText.add('Forced', '${escape(_("Forced"))}')
-// Deluge.Statusbar.js:58
+// FileBrowser.js:50
+GetText.add('Forward', '${escape(_("Forward"))}')
+
+// Statusbar.js:216
GetText.add('Freespace in download location', '${escape(_("Freespace in download location"))}')
-// Deluge.Add.js:130
+// OptionsTab.js:93
GetText.add('Full', '${escape(_("Full"))}')
-// Deluge.Preferences.Encryption.js:97
+// EncryptionPage.js:98
GetText.add('Full Stream', '${escape(_("Full Stream"))}')
-// Deluge.Preferences.Queue.js:53, Deluge.Add.js:177, Deluge.Details.Options.js:281
+// OptionsTab.js:293, OptionsTab.js:137, QueuePage.js:52
GetText.add('General', '${escape(_("General"))}')
-// Deluge.Preferences.Other.js:94
+// OtherPage.js:97
GetText.add('GeoIP Database', '${escape(_("GeoIP Database"))}')
-// Deluge.Preferences.Bandwidth.js:53
+// BandwidthPage.js:56
GetText.add('Global Bandwidth Usage', '${escape(_("Global Bandwidth Usage"))}')
-// Deluge.Preferences.Proxy.js:61
+// ProxyField.js:59
GetText.add('HTTP', '${escape(_("HTTP"))}')
-// Deluge.Preferences.Proxy.js:62
+// ProxyField.js:60
GetText.add('HTTP with Auth', '${escape(_("HTTP with Auth"))}')
-// Deluge.Preferences.Encryption.js:96
+// EncryptionPage.js:97
GetText.add('Handshake', '${escape(_("Handshake"))}')
-// Deluge.Toolbar.js:107
+// DetailsTab.js:47
+GetText.add('Hash', '${escape(_("Hash"))}')
+
+// Toolbar.js:107
GetText.add('Help', '${escape(_("Help"))}')
-// Deluge.Menus.js:420, Deluge.js:109
+// Menus.js:267, Deluge.js:158
GetText.add('High Priority', '${escape(_("High Priority"))}')
-// Deluge.Menus.js:425, Deluge.js:110
+// Menus.js:272, Deluge.js:159
GetText.add('Highest Priority', '${escape(_("Highest Priority"))}')
-// Deluge.ConnectionManager.js:77, Deluge.ConnectionManager.js:193, Deluge.Preferences.Proxy.js:73
+// FileBrowser.js:56
+GetText.add('Home', '${escape(_("Home"))}')
+
+// ConnectionManager.js:74, AddConnectionWindow.js:66, ProxyField.js:71
GetText.add('Host', '${escape(_("Host"))}')
-// Deluge.Preferences.Bandwidth.js:145
+// BandwidthPage.js:122
GetText.add('Ignore limits on local network', '${escape(_("Ignore limits on local network"))}')
-// Deluge.Preferences.Encryption.js:58
+// EncryptionPage.js:57
GetText.add('Inbound', '${escape(_("Inbound"))}')
-// Deluge.Preferences.Network.js:53
+// NetworkPage.js:51
GetText.add('Incoming Ports', '${escape(_("Incoming Ports"))}')
-// Deluge.Preferences.Plugins.js:203
+// PluginsPage.js:135
GetText.add('Info', '${escape(_("Info"))}')
-// Deluge.Add.js:444
+// AddWindow.js:107
GetText.add('Infohash', '${escape(_("Infohash"))}')
-// Deluge.Preferences.Plugins.js:59, Deluge.Preferences.Plugins.js:186
+// InstallPluginWindow.js:54, PluginsPage.js:113
GetText.add('Install', '${escape(_("Install"))}')
-// Deluge.Preferences.Plugins.js:55
+// InstallPluginWindow.js:40
GetText.add('Install Plugin', '${escape(_("Install Plugin"))}')
-// Deluge.Preferences.Interface.js:39, Deluge.Preferences.Interface.js:54
+// InterfacePage.js:41, InterfacePage.js:53
GetText.add('Interface', '${escape(_("Interface"))}')
-// Deluge.Preferences.Interface.js:202
+// InterfacePage.js:199
GetText.add('Invalid Password', '${escape(_("Invalid Password"))}')
-// Deluge.Details.Options.js:114, Deluge.Details.Options.js:141
+// OptionsTab.js:114, OptionsTab.js:141
GetText.add('KiB/s', '${escape(_("KiB/s"))}')
-// Deluge.Preferences.Network.js:223
+// Statusbar.js:144, Statusbar.js:192
+GetText.add('Kib/s', '${escape(_("Kib/s"))}')
+
+// NetworkPage.js:219
GetText.add('LSD', '${escape(_("LSD"))}')
-// Deluge.Preferences.Encryption.js:90
+// TorrentGrid.js:187
+GetText.add('Last Seen Complete', '${escape(_("Last Seen Complete"))}')
+
+// EncryptionPage.js:91
GetText.add('Level', '${escape(_("Level"))}')
-// Deluge.Details.Status.js:57, Deluge.Details.Details.js:43
+// StatusTab.js:61
GetText.add('Loading', '${escape(_("Loading"))}')
-// Deluge.MoveStorage.js:68, Deluge.Preferences.Other.js:101
+// MoveStorage.js:67, OtherPage.js:104
GetText.add('Location', '${escape(_("Location"))}')
-// Deluge.Login.js:52, Deluge.Login.js:63
+// LoginWindow.js:45, LoginWindow.js:54
GetText.add('Login', '${escape(_("Login"))}')
-// Deluge.Login.js:139
+// LoginWindow.js:130
GetText.add('Login Failed', '${escape(_("Login Failed"))}')
-// Deluge.Toolbar.js:115
+// Toolbar.js:114
GetText.add('Logout', '${escape(_("Logout"))}')
-// Deluge.Add.js:164, Deluge.Details.Options.js:150
+// OptionsTab.js:150, OptionsTab.js:126
GetText.add('Max Connections', '${escape(_("Max Connections"))}')
-// Deluge.Add.js:152
+// OptionsTab.js:116
GetText.add('Max Down Speed', '${escape(_("Max Down Speed"))}')
-// Deluge.Details.Options.js:97
+// OptionsTab.js:97
GetText.add('Max Download Speed', '${escape(_("Max Download Speed"))}')
-// Deluge.Add.js:158
+// OptionsTab.js:121
GetText.add('Max Up Speed', '${escape(_("Max Up Speed"))}')
-// Deluge.Add.js:170, Deluge.Details.Options.js:173
+// OptionsTab.js:173, OptionsTab.js:131
GetText.add('Max Upload Slots', '${escape(_("Max Upload Slots"))}')
-// Deluge.Details.Options.js:123
+// OptionsTab.js:123
GetText.add('Max Upload Speed', '${escape(_("Max Upload Speed"))}')
-// Deluge.Preferences.Bandwidth.js:121
+// BandwidthPage.js:103
GetText.add('Maximum Connection Attempts per Second', '${escape(_("Maximum Connection Attempts per Second"))}')
-// Deluge.Preferences.Bandwidth.js:61, Deluge.Preferences.Bandwidth.js:166
+// BandwidthPage.js:68, BandwidthPage.js:147
GetText.add('Maximum Connections', '${escape(_("Maximum Connections"))}')
-// Deluge.Preferences.Bandwidth.js:85, Deluge.Preferences.Bandwidth.js:190
+// BandwidthPage.js:82, BandwidthPage.js:161
GetText.add('Maximum Download Speed (KiB/s)', '${escape(_("Maximum Download Speed (KiB/s)"))}')
-// Deluge.Preferences.Bandwidth.js:109
+// BandwidthPage.js:96
GetText.add('Maximum Half-Open Connections', '${escape(_("Maximum Half-Open Connections"))}')
-// Deluge.Preferences.Bandwidth.js:73, Deluge.Preferences.Bandwidth.js:178
+// BandwidthPage.js:75, BandwidthPage.js:154
GetText.add('Maximum Upload Slots', '${escape(_("Maximum Upload Slots"))}')
-// Deluge.Preferences.Bandwidth.js:97, Deluge.Preferences.Bandwidth.js:202
+// BandwidthPage.js:89, BandwidthPage.js:168
GetText.add('Maximum Upload Speed (KiB/s)', '${escape(_("Maximum Upload Speed (KiB/s)"))}')
-// Deluge.MoveStorage.js:57
+// MoveStorage.js:56
GetText.add('Move', '${escape(_("Move"))}')
-// Deluge.Details.Options.js:262
+// OptionsTab.js:262
GetText.add('Move Completed', '${escape(_("Move Completed"))}')
-// Deluge.Menus.js:242, Deluge.MoveStorage.js:39
+// Menus.js:242, MoveStorage.js:38
GetText.add('Move Storage', '${escape(_("Move Storage"))}')
-// Deluge.Preferences.Downloads.js:72
+// DownloadsPage.js:75
GetText.add('Move completed to', '${escape(_("Move completed to"))}')
-// Deluge.Preferences.Network.js:209
+// NetworkPage.js:205
GetText.add('NAT-PMP', '${escape(_("NAT-PMP"))}')
-// Deluge.Torrents.js:124
+// TorrentGrid.js:116, DetailsTab.js:46
GetText.add('Name', '${escape(_("Name"))}')
-// Deluge.Preferences.Network.js:40
+// NetworkPage.js:42
GetText.add('Network', '${escape(_("Network"))}')
-// Deluge.Preferences.Network.js:192
+// NetworkPage.js:188
GetText.add('Network Extras', '${escape(_("Network Extras"))}')
-// Deluge.Preferences.Network.js:161
+// NetworkPage.js:157
GetText.add('Network Interface', '${escape(_("Network Interface"))}')
-// Deluge.Preferences.Interface.js:102
+// InterfacePage.js:101
GetText.add('New Password', '${escape(_("New Password"))}')
-// Deluge.Preferences.Proxy.js:57
+// ProxyField.js:55
GetText.add('None', '${escape(_("None"))}')
-// Deluge.Menus.js:415, Deluge.js:108
+// Menus.js:262, Deluge.js:157
GetText.add('Normal Priority', '${escape(_("Normal Priority"))}')
-// Deluge.Statusbar.js:7
+// Statusbar.js:39
GetText.add('Not Connected', '${escape(_("Not Connected"))}')
-// Deluge.Add.js:542
+// AddWindow.js:210
GetText.add('Not a valid torrent', '${escape(_("Not a valid torrent"))}')
-// Deluge.Preferences.Notification.js:1
-GetText.add('Notification', '${escape(_("Notification"))}')
-
-// Deluge.ConnectionManager.js:280, Deluge.ConnectionManager.js:288
+// ConnectionManager.js:180, ConnectionManager.js:188
GetText.add('Offline', '${escape(_("Offline"))}')
-// Deluge.EditTrackers.js:179, Deluge.Preferences.js:92
+// EditTrackersWindow.js:57, OtherLimitWindow.js:73, PreferencesWindow.js:108
GetText.add('Ok', '${escape(_("Ok"))}')
-// Deluge.Preferences.Interface.js:98
+// InterfacePage.js:97
GetText.add('Old Password', '${escape(_("Old Password"))}')
-// Deluge.Add.js:85, Deluge.Menus.js:105, Deluge.Details.Options.js:50, Deluge.Preferences.Downloads.js:125
+// Menus.js:99, OptionsTab.js:49, OptionsTab.js:40, DownloadsPage.js:129
GetText.add('Options', '${escape(_("Options"))}')
-// Deluge.Menus.js:301, Deluge.Menus.js:348, Deluge.Menus.js:395, Deluge.Preferences.Daemon.js:88, Deluge.Preferences.Other.js:39
+// Statusbar.js:90, Statusbar.js:138, Statusbar.js:186, OtherPage.js:42, DaemonPage.js:84
GetText.add('Other', '${escape(_("Other"))}')
-// Deluge.Preferences.Encryption.js:74
+// EncryptionPage.js:74
GetText.add('Outbound', '${escape(_("Outbound"))}')
-// Deluge.Preferences.Network.js:108
+// NetworkPage.js:104
GetText.add('Outgoing Ports', '${escape(_("Outgoing Ports"))}')
-// Deluge.ConnectionManager.js:109, Deluge.Preferences.Interface.js:85, Deluge.Preferences.Interface.js:217, Deluge.Preferences.Proxy.js:100, Deluge.Login.js:75
+// TorrentGrid.js:207
+GetText.add('Owner', '${escape(_("Owner"))}')
+
+// AddConnectionWindow.js:88, LoginWindow.js:70, ProxyField.js:95, InterfacePage.js:84, InterfacePage.js:214
GetText.add('Password', '${escape(_("Password"))}')
-// Deluge.Toolbar.js:65, Deluge.Menus.js:93
+// DetailsTab.js:48
+GetText.add('Path', '${escape(_("Path"))}')
+
+// Menus.js:88, Toolbar.js:70
GetText.add('Pause', '${escape(_("Pause"))}')
-// Deluge.Preferences.Proxy.js:184
+// ProxyPage.js:52
GetText.add('Peer', '${escape(_("Peer"))}')
-// Deluge.Preferences.Network.js:216
+// NetworkPage.js:212
GetText.add('Peer Exchange', '${escape(_("Peer Exchange"))}')
-// Deluge.Preferences.Network.js:185
+// NetworkPage.js:181
GetText.add('Peer TOS Byte', '${escape(_("Peer TOS Byte"))}')
-// Deluge.Details.Peers.js:64, Deluge.Torrents.js:148
+// TorrentGrid.js:141, TorrentGrid.js:255, PeersTab.js:61
GetText.add('Peers', '${escape(_("Peers"))}')
-// Deluge.Preferences.Bandwidth.js:158
+// BandwidthPage.js:135
GetText.add('Per Torrent Bandwidth Usage', '${escape(_("Per Torrent Bandwidth Usage"))}')
-// Deluge.Preferences.Daemon.js:97
+// DaemonPage.js:93
GetText.add('Periodically check the website for new releases', '${escape(_("Periodically check the website for new releases"))}')
-// Deluge.Preferences.Plugins.js:164
+// PluginsPage.js:92
GetText.add('Plugin', '${escape(_("Plugin"))}')
-// Deluge.Preferences.Plugins.js:71
+// InstallPluginWindow.js:66
GetText.add('Plugin Egg', '${escape(_("Plugin Egg"))}')
-// Deluge.Preferences.Plugins.js:113
+// PluginsPage.js:41
GetText.add('Plugins', '${escape(_("Plugins"))}')
-// Deluge.ConnectionManager.js:85, Deluge.Preferences.Interface.js:151, Deluge.Preferences.Proxy.js:80, Deluge.Preferences.Daemon.js:53
+// AddConnectionWindow.js:72, ProxyField.js:78, DaemonPage.js:52, InterfacePage.js:147
GetText.add('Port', '${escape(_("Port"))}')
-// Deluge.Toolbar.js:92, Deluge.Preferences.js:50
+// QueuePage.js:114
+GetText.add('Prefer Seeding over Downloading', '${escape(_("Prefer Seeding over Downloading"))}')
+
+// Toolbar.js:94, PreferencesWindow.js:47
GetText.add('Preferences', '${escape(_("Preferences"))}')
-// Deluge.Details.Options.js:296
+// OptionsTab.js:308
GetText.add('Prioritize First/Last', '${escape(_("Prioritize First/Last"))}')
-// Deluge.Add.js:190
+// OptionsTab.js:150
GetText.add('Prioritize First/Last Pieces', '${escape(_("Prioritize First/Last Pieces"))}')
-// Deluge.Preferences.Downloads.js:136
+// DownloadsPage.js:140
GetText.add('Prioritize first and last pieces of torrent', '${escape(_("Prioritize first and last pieces of torrent"))}')
-// Deluge.Details.Files.js:67
+// FilesTab.js:60
GetText.add('Priority', '${escape(_("Priority"))}')
-// Deluge.Details.Options.js:288
+// OptionsTab.js:300
GetText.add('Private', '${escape(_("Private"))}')
-// Deluge.Preferences.Interface.js:173
+// InterfacePage.js:166
GetText.add('Private Key', '${escape(_("Private Key"))}')
-// Deluge.Details.Files.js:62, Deluge.Torrents.js:136
+// TorrentGrid.js:128, FilesTab.js:52
GetText.add('Progress', '${escape(_("Progress"))}')
-// Deluge.Statusbar.js:46
+// Statusbar.js:200
GetText.add('Protocol Traffic Download/Upload', '${escape(_("Protocol Traffic Download/Upload"))}')
-// Deluge.Preferences.Proxy.js:175
+// ProxyPage.js:42
GetText.add('Proxy', '${escape(_("Proxy"))}')
-// Deluge.Preferences.Queue.js:39, Deluge.Menus.js:187, Deluge.Details.Options.js:196
+// TorrentGrid.js:213
+GetText.add('Public', '${escape(_("Public"))}')
+
+// Menus.js:186, OptionsTab.js:196, QueuePage.js:41
GetText.add('Queue', '${escape(_("Queue"))}')
-// Deluge.Preferences.Queue.js:63
+// QueuePage.js:62
GetText.add('Queue new torrents to top', '${escape(_("Queue new torrents to top"))}')
-// Deluge.Preferences.Bandwidth.js:152
+// BandwidthPage.js:129
GetText.add('Rate limit IP overhead', '${escape(_("Rate limit IP overhead"))}')
-// Deluge.Torrents.js:172
+// TorrentGrid.js:166
GetText.add('Ratio', '${escape(_("Ratio"))}')
-// Deluge.ConnectionManager.js:229, Deluge.Toolbar.js:58, Deluge.Add.js:450, Deluge.EditTrackers.js:249
+// EditTrackersWindow.js:122, ConnectionManager.js:107, Toolbar.js:64, AddWindow.js:112
GetText.add('Remove', '${escape(_("Remove"))}')
-// Deluge.Menus.js:230, Deluge.Remove.js:38, Deluge.Remove.js:55
+// Menus.js:230, RemoveWindow.js:39, RemoveWindow.js:57
GetText.add('Remove Torrent', '${escape(_("Remove Torrent"))}')
-// Deluge.Remove.js:54
+// RemoveWindow.js:56
GetText.add('Remove With Data', '${escape(_("Remove With Data"))}')
-// Deluge.Details.Options.js:253
+// OptionsTab.js:253
GetText.add('Remove at ratio', '${escape(_("Remove at ratio"))}')
-// Deluge.Preferences.Queue.js:209
+// QueuePage.js:198
GetText.add('Remove torrent when share ratio is reached', '${escape(_("Remove torrent when share ratio is reached"))}')
-// Deluge.Toolbar.js:72, Deluge.Menus.js:99
+// Menus.js:94, Toolbar.js:76
GetText.add('Resume', '${escape(_("Resume"))}')
-// Deluge.EditTrackers.js:117
+// EditTrackerWindow.js:57
GetText.add('Save', '${escape(_("Save"))}')
-// Deluge.Preferences.Queue.js:154
+// TorrentGrid.js:200
+GetText.add('Save Path', '${escape(_("Save Path"))}')
+
+// QueuePage.js:149
GetText.add('Seed Time (m)', '${escape(_("Seed Time (m)"))}')
-// Deluge.Torrents.js:142
+// TorrentGrid.js:134, TorrentGrid.js:255
GetText.add('Seeders', '${escape(_("Seeders"))}')
-// Deluge.Preferences.Queue.js:123
+// QueuePage.js:120
GetText.add('Seeding', '${escape(_("Seeding"))}')
-// Deluge.Add.File.js:66
+// FileWindow.js:66
GetText.add('Select a torrent', '${escape(_("Select a torrent"))}')
-// Deluge.Preferences.Plugins.js:70
+// InstallPluginWindow.js:65
GetText.add('Select an egg', '${escape(_("Select an egg"))}')
-// Deluge.Preferences.Interface.js:130
+// InterfacePage.js:129
GetText.add('Server', '${escape(_("Server"))}')
-// Deluge.Preferences.Interface.js:141
+// InterfacePage.js:140
GetText.add('Session Timeout', '${escape(_("Session Timeout"))}')
-// Deluge.Preferences.Cache.js:53, Deluge.Preferences.Encryption.js:53
+// Statusbar.js:96
+GetText.add('Set Maximum Connections', '${escape(_("Set Maximum Connections"))}')
+
+// Statusbar.js:143
+GetText.add('Set Maximum Download Speed', '${escape(_("Set Maximum Download Speed"))}')
+
+// Statusbar.js:191
+GetText.add('Set Maximum Upload Speed', '${escape(_("Set Maximum Upload Speed"))}')
+
+// EncryptionPage.js:51, CachePage.js:52
GetText.add('Settings', '${escape(_("Settings"))}')
-// Deluge.Preferences.Queue.js:130
+// QueuePage.js:127
GetText.add('Share Ratio Limit', '${escape(_("Share Ratio Limit"))}')
-// Deluge.Preferences.Queue.js:142
+// QueuePage.js:138
GetText.add('Share Time Ratio', '${escape(_("Share Time Ratio"))}')
-// Deluge.Preferences.Interface.js:72
+// TorrentGrid.js:220
+GetText.add('Shared', '${escape(_("Shared"))}')
+
+// InterfacePage.js:71
GetText.add('Show filters with zero torrents', '${escape(_("Show filters with zero torrents"))}')
-// Deluge.Preferences.Interface.js:65
+// InterfacePage.js:64
GetText.add('Show session speed in titlebar', '${escape(_("Show session speed in titlebar"))}')
-// Deluge.Preferences.Interface.js:79
-GetText.add('Show trackers with zero torrents', '${escape(_("Show trackers with zero torrents"))}')
-
-// Deluge.Add.js:67, Deluge.Details.Files.js:57, Deluge.Torrents.js:130
+// TorrentGrid.js:122, FilesTab.js:44, FilesTab.js:54
GetText.add('Size', '${escape(_("Size"))}')
-// Deluge.Preferences.Proxy.js:58
+// ProxyField.js:56
GetText.add('Socksv4', '${escape(_("Socksv4"))}')
-// Deluge.Preferences.Proxy.js:59
+// ProxyField.js:57
GetText.add('Socksv5', '${escape(_("Socksv5"))}')
-// Deluge.Preferences.Proxy.js:60
+// ProxyField.js:58
GetText.add('Socksv5 with Auth', '${escape(_("Socksv5 with Auth"))}')
-// Deluge.ConnectionManager.js:291
+// ConnectionManager.js:191
GetText.add('Start Daemon', '${escape(_("Start Daemon"))}')
-// Deluge.Sidebar.js:37
+// Sidebar.js:34
GetText.add('State', '${escape(_("State"))}')
-// Deluge.ConnectionManager.js:186, Deluge.Details.Status.js:35
+// ConnectionManager.js:68, StatusTab.js:39, DetailsTab.js:52
GetText.add('Status', '${escape(_("Status"))}')
-// Deluge.ConnectionManager.js:237, Deluge.ConnectionManager.js:297, Deluge.ConnectionManager.js:415
+// ConnectionManager.js:115, ConnectionManager.js:197, ConnectionManager.js:328
GetText.add('Stop Daemon', '${escape(_("Stop Daemon"))}')
-// Deluge.Details.Options.js:225
+// OptionsTab.js:225
GetText.add('Stop seed at ratio', '${escape(_("Stop seed at ratio"))}')
-// Deluge.Preferences.Queue.js:183
+// QueuePage.js:175
GetText.add('Stop seeding when share ratio reaches:', '${escape(_("Stop seeding when share ratio reaches:"))}')
-// Deluge.Preferences.Other.js:69
+// OtherPage.js:72
GetText.add('System Information', '${escape(_("System Information"))}')
-// Deluge.Preferences.Network.js:177
+// NetworkPage.js:173
GetText.add('TOS', '${escape(_("TOS"))}')
-// Deluge.EditTrackers.js:198
+// EditTrackersWindow.js:76
GetText.add('Tier', '${escape(_("Tier"))}')
-// Deluge.Menus.js:192
+// Menus.js:192
GetText.add('Top', '${escape(_("Top"))}')
-// Deluge.Preferences.Queue.js:77
+// QueuePage.js:76
GetText.add('Total Active', '${escape(_("Total Active"))}')
-// Deluge.Preferences.Queue.js:89
+// QueuePage.js:85
GetText.add('Total Active Downloading', '${escape(_("Total Active Downloading"))}')
-// Deluge.Preferences.Queue.js:101
+// QueuePage.js:94
GetText.add('Total Active Seeding', '${escape(_("Total Active Seeding"))}')
-// Deluge.Preferences.Proxy.js:196, Deluge.Torrents.js:190, Deluge.EditTrackers.js:126, Deluge.EditTrackers.js:205
+// DetailsTab.js:49
+GetText.add('Total Size', '${escape(_("Total Size"))}')
+
+// EditTrackersWindow.js:80, TorrentGrid.js:193, EditTrackerWindow.js:66, DetailsTab.js:53, ProxyPage.js:64
GetText.add('Tracker', '${escape(_("Tracker"))}')
-// Deluge.Sidebar.js:38
+// Sidebar.js:35
GetText.add('Tracker Host', '${escape(_("Tracker Host"))}')
-// Deluge.EditTrackers.js:67
+// AddTrackerWindow.js:66
GetText.add('Trackers', '${escape(_("Trackers"))}')
-// Deluge.Preferences.Proxy.js:50
+// ProxyField.js:48
GetText.add('Type', '${escape(_("Type"))}')
-// Deluge.Menus.js:127
+// Menus.js:123
GetText.add('U/L Speed Limit', '${escape(_("U/L Speed Limit"))}')
-// Deluge.Preferences.Network.js:203
+// NetworkPage.js:199
GetText.add('UPnP', '${escape(_("UPnP"))}')
-// Deluge.Menus.js:123, Deluge.Menus.js:141, Deluge.Menus.js:159, Deluge.Menus.js:177, Deluge.Menus.js:295, Deluge.Menus.js:342, Deluge.Menus.js:389
+// OptionsPanel.js:142
+GetText.add('Unable to set file priority!', '${escape(_("Unable to set file priority!"))}')
+
+// Statusbar.js:85, Statusbar.js:133, Statusbar.js:181, Menus.js:119, Menus.js:138, Menus.js:157, Menus.js:176
GetText.add('Unlimited', '${escape(_("Unlimited"))}')
-// Deluge.Toolbar.js:79, Deluge.Menus.js:198, Deluge.EditTrackers.js:225
+// EditTrackersWindow.js:102, Menus.js:198, Toolbar.js:83, FileBrowser.js:53
GetText.add('Up', '${escape(_("Up"))}')
-// Deluge.Torrents.js:160
+// TorrentGrid.js:248
+GetText.add('Up Limit', '${escape(_("Up Limit"))}')
+
+// TorrentGrid.js:154
GetText.add('Up Speed', '${escape(_("Up Speed"))}')
-// Deluge.Menus.js:218
+// Menus.js:218
GetText.add('Update Tracker', '${escape(_("Update Tracker"))}')
-// Deluge.Preferences.Other.js:53
+// OtherPage.js:56
GetText.add('Updates', '${escape(_("Updates"))}')
-// Deluge.Menus.js:163
+// Menus.js:161
GetText.add('Upload Slot Limit', '${escape(_("Upload Slot Limit"))}')
-// Deluge.Statusbar.js:39
+// Statusbar.js:152
GetText.add('Upload Speed', '${escape(_("Upload Speed"))}')
-// Deluge.Preferences.Plugins.js:83
+// TorrentGrid.js:234
+GetText.add('Uploaded', '${escape(_("Uploaded"))}')
+
+// InstallPluginWindow.js:78
GetText.add('Uploading your plugin...', '${escape(_("Uploading your plugin..."))}')
-// Deluge.Add.File.js:81
+// FileWindow.js:82
GetText.add('Uploading your torrent...', '${escape(_("Uploading your torrent..."))}')
-// Deluge.Add.Url.js:65, Deluge.Add.js:437
+// UrlWindow.js:60, AddWindow.js:102
GetText.add('Url', '${escape(_("Url"))}')
-// Deluge.Preferences.Downloads.js:117
+// DownloadsPage.js:121
GetText.add('Use Compact', '${escape(_("Use Compact"))}')
-// Deluge.Preferences.Downloads.js:114
+// DownloadsPage.js:118
GetText.add('Use Full', '${escape(_("Use Full"))}')
-// Deluge.Preferences.Network.js:62, Deluge.Preferences.Network.js:117
+// NetworkPage.js:60, NetworkPage.js:113
GetText.add('Use Random Ports', '${escape(_("Use Random Ports"))}')
-// Deluge.Preferences.Interface.js:165
+// InterfacePage.js:158
GetText.add('Use SSL (paths relative to Deluge config folder)', '${escape(_("Use SSL (paths relative to Deluge config folder)"))}')
-// Deluge.ConnectionManager.js:101, Deluge.Preferences.Proxy.js:93
+// AddConnectionWindow.js:83, ProxyField.js:88
GetText.add('Username', '${escape(_("Username"))}')
-// Deluge.ConnectionManager.js:199
+// ConnectionManager.js:80
GetText.add('Version', '${escape(_("Version"))}')
-// Deluge.Preferences.Proxy.js:190
+// ProxyPage.js:58
GetText.add('Web Seed', '${escape(_("Web Seed"))}')
-// Deluge.Preferences.Other.js:87
+// OtherPage.js:90
GetText.add('Yes, please send anonymous statistics', '${escape(_("Yes, please send anonymous statistics"))}')
-// Deluge.Login.js:140
+// LoginWindow.js:131
GetText.add('You entered an incorrect password', '${escape(_("You entered an incorrect password"))}')
-// Deluge.Preferences.Interface.js:218
+// InterfacePage.js:215
GetText.add('Your old password was incorrect!', '${escape(_("Your old password was incorrect!"))}')
-// Deluge.Preferences.Interface.js:228
+// InterfacePage.js:225
GetText.add('Your password was successfully changed!', '${escape(_("Your password was successfully changed!"))}')
-// Deluge.Preferences.Interface.js:203
+// InterfacePage.js:200
GetText.add('Your passwords don\'t match!', '${escape(_("Your passwords don\'t match!"))}')
-
diff --git a/deluge/ui/web/icons/readme.txt b/deluge/ui/web/icons/readme.txt
deleted file mode 100644
index 66049b810..000000000
--- a/deluge/ui/web/icons/readme.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-images from the fruge icon set.
-See LICENSE for a list of icons not taken from fruge.
diff --git a/deluge/ui/web/images/debugerror.png b/deluge/ui/web/images/debugerror.png
deleted file mode 100644
index fedb1a724..000000000
--- a/deluge/ui/web/images/debugerror.png
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/images/deluge-icon.png b/deluge/ui/web/images/deluge-icon.png
deleted file mode 100644
index e39cd0c7e..000000000
--- a/deluge/ui/web/images/deluge-icon.png
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/images/deluge16.png b/deluge/ui/web/images/deluge16.png
deleted file mode 100644
index e39cd0c7e..000000000
--- a/deluge/ui/web/images/deluge16.png
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/images/deluge32.png b/deluge/ui/web/images/deluge32.png
deleted file mode 100644
index 2d272f2ea..000000000
--- a/deluge/ui/web/images/deluge32.png
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/images/deluge_icon.gif b/deluge/ui/web/images/deluge_icon.gif
deleted file mode 100644
index f00149312..000000000
--- a/deluge/ui/web/images/deluge_icon.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/js/deluge-all-debug.js b/deluge/ui/web/js/deluge-all-debug.js
index 390f3f970..9a18fedf6 100644
--- a/deluge/ui/web/js/deluge-all-debug.js
+++ b/deluge/ui/web/js/deluge-all-debug.js
@@ -1,6 +1,6 @@
/*!
* Deluge.data.SortTypes.js
- *
+ *
* Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -39,7 +39,7 @@ Ext.namespace('Deluge.data');
*
* @class Deluge.data.SortTypes
* @singleton
- */
+ */
Deluge.data.SortTypes = {
asIPAddress: function(value) {
var d = value.match(/(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\:(\d+)/);
@@ -48,6 +48,10 @@ Deluge.data.SortTypes = {
asQueuePosition: function(value) {
return (value > -1) ? value : Number.MAX_VALUE;
+ },
+
+ asName: function(value) {
+ return String(value).toLowerCase();
}
}
/*!
@@ -121,7 +125,7 @@ Deluge.data.Peer = Ext.data.Record.create([
]);
/*!
* Deluge.data.TorrentRecord.js
- *
+ *
* Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -168,7 +172,8 @@ Deluge.data.Torrent = Ext.data.Record.create([{
type: 'int'
}, {
name: 'name',
- type: 'string'
+ type: 'string',
+ sortType: Deluge.data.SortTypes.asName
}, {
name: 'total_size',
type: 'int'
@@ -349,7 +354,7 @@ Deluge.details.DetailsTab = Ext.extend(Ext.Panel, {
title: _('Details'),
fields: {},
-
+ autoScroll: true,
queuedItems: {},
oldData: {},
@@ -428,7 +433,7 @@ Deluge.details.DetailsTab = Ext.extend(Ext.Panel, {
});
/*!
* Deluge.details.FilesTab.js
- *
+ *
* Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -457,12 +462,11 @@ Deluge.details.DetailsTab = Ext.extend(Ext.Panel, {
* this exception statement from your version. If you delete this exception
* statement from all source files in the program, then also delete it here.
*/
-
+
Deluge.details.FilesTab = Ext.extend(Ext.ux.tree.TreeGrid, {
title: _('Files'),
- autoScroll: true,
rootVisible: false,
columns: [{
@@ -502,7 +506,7 @@ Deluge.details.FilesTab = Ext.extend(Ext.ux.tree.TreeGrid, {
}
})
}],
-
+
selModel: new Ext.tree.MultiSelectionModel(),
initComponent: function() {
@@ -558,7 +562,7 @@ Deluge.details.FilesTab = Ext.extend(Ext.ux.tree.TreeGrid, {
this.clear();
this.torrentId = torrentId;
}
-
+
deluge.client.web.get_torrent_files(torrentId, {
success: this.onRequestComplete,
scope: this,
@@ -591,7 +595,7 @@ Deluge.details.FilesTab = Ext.extend(Ext.ux.tree.TreeGrid, {
folderSort: true
});
},
-
+
onContextMenu: function(node, e) {
e.stopEvent();
var selModel = this.getSelectionModel();
@@ -601,7 +605,7 @@ Deluge.details.FilesTab = Ext.extend(Ext.ux.tree.TreeGrid, {
}
deluge.menus.filePriorities.showAt(e.getPoint());
},
-
+
onItemClick: function(baseItem, e) {
switch (baseItem.id) {
case 'expandAll':
@@ -628,7 +632,7 @@ Deluge.details.FilesTab = Ext.extend(Ext.ux.tree.TreeGrid, {
return;
}
});
-
+
var priorities = new Array(Ext.keys(indexes).length);
for (var index in indexes) {
priorities[index] = indexes[index];
@@ -645,7 +649,7 @@ Deluge.details.FilesTab = Ext.extend(Ext.ux.tree.TreeGrid, {
break;
}
},
-
+
onRequestComplete: function(files, options) {
if (!this.getRootNode().hasChildNodes()) {
this.createFileTree(files);
@@ -1127,7 +1131,7 @@ Deluge.details.OptionsTab = Ext.extend(Ext.form.FormPanel, {
if (!value.replace(' ', '').replace(' ', '')){
return '';
}
- return String.format('<img src="flag/{0}" />', value);
+ return String.format('<img src="{0}flag/{1}" />', deluge.config.base, value);
}
function peerAddressRenderer(value, p, record) {
var seed = (record.data['seed'] == 1024) ? 'x-deluge-seed' : 'x-deluge-peer';
@@ -1544,6 +1548,7 @@ Deluge.add.AddWindow = Ext.extend(Deluge.add.Window, {
}, {
text: _('Infohash'),
iconCls: 'icon-add-magnet',
+ hidden: true,
disabled: true
}, '->', {
text: _('Remove'),
@@ -1783,7 +1788,7 @@ Deluge.add.FileWindow = Ext.extend(Deluge.add.Window, {
});
/*!
* Deluge.add.FilesTab.js
- *
+ *
* Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -1823,7 +1828,7 @@ Deluge.add.FilesTab = Ext.extend(Ext.ux.tree.TreeGrid, {
layout: 'fit',
title: _('Files'),
- autoScroll: true,
+ autoScroll: false,
animate: false,
border: false,
disabled: true,
@@ -2099,7 +2104,7 @@ Deluge.add.OptionsPanel = Ext.extend(Ext.TabPanel, {
});
/*!
* Deluge.add.OptionsPanel.js
- *
+ *
* Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -2166,7 +2171,7 @@ Deluge.add.OptionsTab = Ext.extend(Ext.form.FormPanel, {
width: 400,
labelSeparator: ''
}));
-
+
var panel = this.add({
border: false,
layout: 'column',
@@ -2177,7 +2182,6 @@ Deluge.add.OptionsTab = Ext.extend(Ext.form.FormPanel, {
border: false,
autoHeight: true,
defaultType: 'radio',
- width: 100
});
this.optionsManager.bind('compact_allocation', fieldset.add({
@@ -2185,6 +2189,7 @@ Deluge.add.OptionsTab = Ext.extend(Ext.form.FormPanel, {
columns: 1,
vertical: true,
labelSeparator: '',
+ width: 80,
items: [{
name: 'compact_allocation',
value: false,
@@ -2206,35 +2211,32 @@ Deluge.add.OptionsTab = Ext.extend(Ext.form.FormPanel, {
title: _('Bandwidth'),
border: false,
autoHeight: true,
- labelWidth: 100,
+ bodyStyle: 'margin-left: 7px',
+ labelWidth: 105,
width: 200,
defaultType: 'spinnerfield'
});
this.optionsManager.bind('max_download_speed', fieldset.add({
fieldLabel: _('Max Down Speed'),
- labelStyle: 'margin-left: 10px',
name: 'max_download_speed',
width: 60
}));
this.optionsManager.bind('max_upload_speed', fieldset.add({
fieldLabel: _('Max Up Speed'),
- labelStyle: 'margin-left: 10px',
name: 'max_upload_speed',
width: 60
}));
this.optionsManager.bind('max_connections', fieldset.add({
fieldLabel: _('Max Connections'),
- labelStyle: 'margin-left: 10px',
name: 'max_connections',
width: 60
}));
this.optionsManager.bind('max_upload_slots', fieldset.add({
fieldLabel: _('Max Upload Slots'),
- labelStyle: 'margin-left: 10px',
name: 'max_upload_slots',
width: 60
}));
-
+
fieldset = panel.add({
title: _('General'),
border: false,
@@ -2364,7 +2366,7 @@ Deluge.add.UrlWindow = Ext.extend(Deluge.add.Window, {
var cookies = this.cookieField.getValue();
var torrentId = this.createTorrentId();
- if (url.substring(0,20) == 'magnet:?xt=urn:btih:') {
+ if (url.indexOf('magnet:?') == 0 && url.indexOf('xt=urn:btih') > -1) {
deluge.client.web.get_magnet_info(url, {
success: this.onGotInfo,
scope: this,
@@ -4392,7 +4394,7 @@ Deluge.preferences.ProxyField = Ext.extend(Ext.form.FieldSet, {
});
/*!
* Deluge.preferences.ProxyPage.js
- *
+ *
* Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -4432,11 +4434,12 @@ Deluge.preferences.Proxy = Ext.extend(Ext.form.FormPanel, {
config = Ext.apply({
border: false,
title: _('Proxy'),
- layout: 'form'
+ layout: 'form',
+ autoScroll: true
}, config);
Deluge.preferences.Proxy.superclass.constructor.call(this, config);
},
-
+
initComponent: function() {
Deluge.preferences.Proxy.superclass.initComponent.call(this);
this.peer = this.add(new Deluge.preferences.ProxyField({
@@ -4444,28 +4447,28 @@ Deluge.preferences.Proxy = Ext.extend(Ext.form.FormPanel, {
name: 'peer'
}));
this.peer.on('change', this.onProxyChange, this);
-
+
this.web_seed = this.add(new Deluge.preferences.ProxyField({
title: _('Web Seed'),
name: 'web_seed'
}));
this.web_seed.on('change', this.onProxyChange, this);
-
+
this.tracker = this.add(new Deluge.preferences.ProxyField({
title: _('Tracker'),
name: 'tracker'
}));
this.tracker.on('change', this.onProxyChange, this);
-
+
this.dht = this.add(new Deluge.preferences.ProxyField({
title: _('DHT'),
name: 'dht'
}));
this.dht.on('change', this.onProxyChange, this);
-
+
deluge.preferences.getOptionsManager().bind('proxies', this);
},
-
+
getValue: function() {
return {
'dht': this.dht.getValue(),
@@ -4474,18 +4477,18 @@ Deluge.preferences.Proxy = Ext.extend(Ext.form.FormPanel, {
'web_seed': this.web_seed.getValue()
}
},
-
+
setValue: function(value) {
for (var proxy in value) {
this[proxy].setValue(value[proxy]);
}
},
-
+
onProxyChange: function(field, newValue, oldValue) {
var newValues = this.getValue();
var oldValues = Ext.apply({}, newValues);
oldValues[field.getName()] = oldValue;
-
+
this.fireEvent('change', this, newValues, oldValues);
}
});
@@ -5343,20 +5346,20 @@ Ext.namespace('Ext.ux.util');
Ext.ux.util.RpcClient = Ext.extend(Ext.util.Observable, {
_components: [],
-
+
_methods: [],
-
+
_requests: {},
-
+
_url: null,
-
+
_optionKeys: ['scope', 'success', 'failure'],
-
+
constructor: function(config) {
Ext.ux.util.RpcClient.superclass.constructor.call(this, config);
this._url = config.url || null;
this._id = 0;
-
+
this.addEvents(
// raw events
/**
@@ -5365,16 +5368,13 @@ Ext.ux.util.RpcClient = Ext.extend(Ext.util.Observable, {
* @param {Ext.ux.util.RpcClient} this
*/
'connected',
-
+
'error'
);
this.reloadMethods();
},
-
+
reloadMethods: function() {
- Ext.each(this._components, function(component) {
- delete this[component];
- }, this);
this._execute('system.listMethods', {
success: this._setMethods,
scope: this
@@ -5385,14 +5385,14 @@ Ext.ux.util.RpcClient = Ext.extend(Ext.util.Observable, {
options = options || {};
options.params = options.params || [];
options.id = this._id;
-
+
var request = Ext.encode({
method: method,
params: options.params,
id: options.id
});
this._id++;
-
+
return Ext.Ajax.request({
url: this._url,
method: 'POST',
@@ -5403,7 +5403,7 @@ Ext.ux.util.RpcClient = Ext.extend(Ext.util.Observable, {
options: options
});
},
-
+
_onFailure: function(response, requestOptions) {
var options = requestOptions.options;
errorObj = {
@@ -5414,23 +5414,23 @@ Ext.ux.util.RpcClient = Ext.extend(Ext.util.Observable, {
code: 255
}
}
-
+
this.fireEvent('error', errorObj, response, requestOptions)
-
+
if (Ext.type(options.failure) != 'function') return;
if (options.scope) {
options.failure.call(options.scope, errorObj, response, requestOptions);
} else {
options.failure(errorObj, response, requestOptions);
- }
+ }
},
-
+
_onSuccess: function(response, requestOptions) {
var responseObj = Ext.decode(response.responseText);
var options = requestOptions.options;
if (responseObj.error) {
this.fireEvent('error', responseObj, response, requestOptions);
-
+
if (Ext.type(options.failure) != 'function') return;
if (options.scope) {
options.failure.call(options.scope, responseObj, response, requestOptions);
@@ -5446,21 +5446,21 @@ Ext.ux.util.RpcClient = Ext.extend(Ext.util.Observable, {
}
}
},
-
+
_parseArgs: function(args) {
var params = [];
Ext.each(args, function(arg) {
params.push(arg);
});
-
+
var options = params[params.length - 1];
if (Ext.type(options) == 'object') {
var keys = Ext.keys(options), isOption = false;
-
+
Ext.each(this._optionKeys, function(key) {
if (keys.indexOf(key) > -1) isOption = true;
});
-
+
if (isOption) {
params.remove(options)
} else {
@@ -5475,11 +5475,11 @@ Ext.ux.util.RpcClient = Ext.extend(Ext.util.Observable, {
_setMethods: function(methods) {
var components = {}, self = this;
-
+
Ext.each(methods, function(method) {
var parts = method.split('.');
var component = components[parts[0]] || {};
-
+
var fn = function() {
var options = self._parseArgs(arguments);
return self._execute(method, options);
@@ -5487,11 +5487,15 @@ Ext.ux.util.RpcClient = Ext.extend(Ext.util.Observable, {
component[parts[1]] = fn;
components[parts[0]] = component;
});
-
+
for (var name in components) {
self[name] = components[name];
}
-
+ Ext.each(this._components, function(component) {
+ if (!component in components) {
+ delete this[component];
+ }
+ }, this);
this._components = Ext.keys(components);
this.fireEvent('connected', this);
}
@@ -6479,13 +6483,15 @@ Deluge.EventsManager = Ext.extend(Ext.util.Observable, {
},
onGetEventsSuccess: function(events) {
- if (!events) return;
- Ext.each(events, function(event) {
- var name = event[0], args = event[1];
- args.splice(0, 0, name);
- this.fireEvent.apply(this, args);
- }, this);
- if (this.running) this.getEvents();
+ if (!this.running) return;
+ if (events) {
+ Ext.each(events, function(event) {
+ var name = event[0], args = event[1];
+ args.splice(0, 0, name);
+ this.fireEvent.apply(this, args);
+ }, this);
+ }
+ this.getEvents();
},
// private
@@ -7039,7 +7045,7 @@ Ext.each(Deluge.Keys.Grid, function(key) {
});
/*!
* Deluge.LoginWindow.js
- *
+ *
* Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -7070,7 +7076,7 @@ Ext.each(Deluge.Keys.Grid, function(key) {
*/
Deluge.LoginWindow = Ext.extend(Ext.Window, {
-
+
firstShow: true,
bodyStyle: 'padding: 10px 5px;',
buttonAlign: 'center',
@@ -7084,36 +7090,39 @@ Deluge.LoginWindow = Ext.extend(Ext.Window, {
title: _('Login'),
width: 300,
height: 120,
-
+
initComponent: function() {
Deluge.LoginWindow.superclass.initComponent.call(this);
this.on('show', this.onShow, this);
-
+
this.addButton({
text: _('Login'),
handler: this.onLogin,
scope: this
});
-
+
this.form = this.add({
xtype: 'form',
baseCls: 'x-plain',
- labelWidth: 55,
- width: 300,
- defaults: {width: 200},
+ labelWidth: 120,
+ labelAlign: 'right',
+ defaults: {width: 110},
defaultType: 'textfield'
});
this.passwordField = this.form.add({
xtype: 'textfield',
fieldLabel: _('Password'),
+ grow: true,
+ growMin: '110',
+ growMax: '145',
id: '_password',
name: 'password',
inputType: 'password'
});
this.passwordField.on('specialkey', this.onSpecialKey, this);
},
-
+
logout: function() {
deluge.events.fire('logout');
deluge.client.auth.delete_session({
@@ -7123,17 +7132,17 @@ Deluge.LoginWindow = Ext.extend(Ext.Window, {
scope: this
});
},
-
+
show: function(skipCheck) {
if (this.firstShow) {
deluge.client.on('error', this.onClientError, this);
this.firstShow = false;
}
-
+
if (skipCheck) {
return Deluge.LoginWindow.superclass.show.call(this);
}
-
+
deluge.client.auth.check_session({
success: function(result) {
if (result) {
@@ -7148,11 +7157,11 @@ Deluge.LoginWindow = Ext.extend(Ext.Window, {
scope: this
});
},
-
+
onSpecialKey: function(field, e) {
if (e.getKey() == 13) this.onLogin();
},
-
+
onLogin: function() {
var passwordField = this.passwordField;
deluge.client.auth.login(passwordField.getValue(), {
@@ -7178,16 +7187,16 @@ Deluge.LoginWindow = Ext.extend(Ext.Window, {
scope: this
});
},
-
+
onClientError: function(errorObj, response, requestOptions) {
if (errorObj.error.code == 1) {
deluge.events.fire('logout');
this.show(true);
}
},
-
+
onShow: function() {
- this.passwordField.focus(true, 100);
+ this.passwordField.focus(true, 300);
}
});
/*!
@@ -7290,10 +7299,12 @@ deluge.menus.torrent = new Ext.menu.Menu({
}, '-', {
text: _('Options'),
iconCls: 'icon-options',
+ hideOnClick: false,
menu: new Ext.menu.Menu({
items: [{
text: _('D/L Speed Limit'),
iconCls: 'x-deluge-downloading',
+ hideOnClick: false,
menu: new Ext.menu.Menu({
items: [{
text: _('5 KiB/s')
@@ -7312,6 +7323,7 @@ deluge.menus.torrent = new Ext.menu.Menu({
}, {
text: _('U/L Speed Limit'),
iconCls: 'x-deluge-seeding',
+ hideOnClick: false,
menu: new Ext.menu.Menu({
items: [{
text: _('5 KiB/s')
@@ -7330,6 +7342,7 @@ deluge.menus.torrent = new Ext.menu.Menu({
}, {
text: _('Connection Limit'),
iconCls: 'x-deluge-connections',
+ hideOnClick: false,
menu: new Ext.menu.Menu({
items: [{
text: _('50')
@@ -7348,6 +7361,7 @@ deluge.menus.torrent = new Ext.menu.Menu({
}, {
text: _('Upload Slot Limit'),
iconCls: 'icon-upload-slots',
+ hideOnClick: false,
menu: new Ext.menu.Menu({
items: [{
text: _('0')
@@ -7372,6 +7386,7 @@ deluge.menus.torrent = new Ext.menu.Menu({
}, '-', {
text: _('Queue'),
iconCls: 'icon-queue',
+ hideOnClick: false,
menu: new Ext.menu.Menu({
items: [{
torrentAction: 'top',
@@ -7956,6 +7971,7 @@ Deluge.Plugin = Ext.extend(Ext.util.Observable, {
* then executes the plugins setup method, onEnabled.
*/
enable: function() {
+ deluge.client.reloadMethods();
this.fireEvent("enable", this);
if (this.onEnable) this.onEnable();
},
@@ -9046,7 +9062,7 @@ Deluge.Toolbar = Ext.extend(Ext.Toolbar, {
idProperty: 'id',
fields: [
{name: 'queue', sortType: Deluge.data.SortTypes.asQueuePosition},
- {name: 'name'},
+ {name: 'name', sortType: Deluge.data.SortTypes.asName},
{name: 'total_size', type: 'int'},
{name: 'state'},
{name: 'progress', type: 'float'},
@@ -9055,7 +9071,7 @@ Deluge.Toolbar = Ext.extend(Ext.Toolbar, {
{name: 'num_peers', type: 'int'},
{name: 'total_peers', type: 'int'},
{name: 'download_payload_rate', type: 'int'},
- {name: 'upload_payload_speed', type: 'int'},
+ {name: 'upload_payload_rate', type: 'int'},
{name: 'eta', type: 'int', sortType: etaSorter},
{name: 'ratio', type: 'float'},
{name: 'distributed_copies', type: 'float'},
@@ -9495,7 +9511,7 @@ deluge.ui = {
},
onPluginDisabled: function(pluginName) {
- deluge.plugins[pluginName].disable();
+ if (deluge.plugins[pluginName]) deluge.plugins[pluginName].disable();
},
onPluginLoaded: function(options) {
diff --git a/deluge/ui/web/js/deluge-all.js b/deluge/ui/web/js/deluge-all.js
index 7348b402f..c06a1865c 100644
--- a/deluge/ui/web/js/deluge-all.js
+++ b/deluge/ui/web/js/deluge-all.js
@@ -1,6 +1,6 @@
/*
* Deluge.data.SortTypes.js
- *
+ *
* Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -29,7 +29,7 @@
* this exception statement from your version. If you delete this exception
* statement from all source files in the program, then also delete it here.
*/
-Ext.namespace("Deluge.data");Deluge.data.SortTypes={asIPAddress:function(a){var b=a.match(/(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\:(\d+)/);return((((((+b[1])*256)+(+b[2]))*256)+(+b[3]))*256)+(+b[4])},asQueuePosition:function(a){return(a>-1)?a:Number.MAX_VALUE}}
+Ext.namespace("Deluge.data");Deluge.data.SortTypes={asIPAddress:function(a){var b=a.match(/(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\:(\d+)/);return((((((+b[1])*256)+(+b[2]))*256)+(+b[3]))*256)+(+b[4])},asQueuePosition:function(a){return(a>-1)?a:Number.MAX_VALUE},asName:function(a){return String(a).toLowerCase()}}
/*
* Deluge.data.PeerRecord.js
*
@@ -64,7 +64,7 @@ Ext.namespace("Deluge.data");Deluge.data.SortTypes={asIPAddress:function(a){var
;Ext.namespace("Deluge.data");Deluge.data.Peer=Ext.data.Record.create([{name:"country",type:"string"},{name:"ip",type:"string",sortType:Deluge.data.SortTypes.asIPAddress},{name:"client",type:"string"},{name:"progress",type:"float"},{name:"down_speed",type:"int"},{name:"up_speed",type:"int"},{name:"seed",type:"int"}]);
/*
* Deluge.data.TorrentRecord.js
- *
+ *
* Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -93,7 +93,7 @@ Ext.namespace("Deluge.data");Deluge.data.SortTypes={asIPAddress:function(a){var
* this exception statement from your version. If you delete this exception
* statement from all source files in the program, then also delete it here.
*/
-Ext.namespace("Deluge.data");Deluge.data.Torrent=Ext.data.Record.create([{name:"queue",type:"int"},{name:"name",type:"string"},{name:"total_size",type:"int"},{name:"state",type:"string"},{name:"progress",type:"int"},{name:"num_seeds",type:"int"},{name:"total_seeds",type:"int"},{name:"num_peers",type:"int"},{name:"total_peers",type:"int"},{name:"download_payload_rate",type:"int"},{name:"upload_payload_rate",type:"int"},{name:"eta",type:"int"},{name:"ratio",type:"float"},{name:"distributed_copies",type:"float"},{name:"time_added",type:"int"},{name:"tracker_host",type:"string"}]);
+Ext.namespace("Deluge.data");Deluge.data.Torrent=Ext.data.Record.create([{name:"queue",type:"int"},{name:"name",type:"string",sortType:Deluge.data.SortTypes.asName},{name:"total_size",type:"int"},{name:"state",type:"string"},{name:"progress",type:"int"},{name:"num_seeds",type:"int"},{name:"total_seeds",type:"int"},{name:"num_peers",type:"int"},{name:"total_peers",type:"int"},{name:"download_payload_rate",type:"int"},{name:"upload_payload_rate",type:"int"},{name:"eta",type:"int"},{name:"ratio",type:"float"},{name:"distributed_copies",type:"float"},{name:"time_added",type:"int"},{name:"tracker_host",type:"string"}]);
/*
* Deluge.details.DetailsPanel.js
*
@@ -125,10 +125,10 @@ Ext.namespace("Deluge.data");Deluge.data.Torrent=Ext.data.Record.create([{name:"
* this exception statement from your version. If you delete this exception
* statement from all source files in the program, then also delete it here.
*/
-Ext.namespace("Deluge.details");Deluge.details.DetailsPanel=Ext.extend(Ext.TabPanel,{id:"torrentDetails",activeTab:0,initComponent:function(){Deluge.details.DetailsPanel.superclass.initComponent.call(this);this.add(new Deluge.details.StatusTab());this.add(new Deluge.details.DetailsTab());this.add(new Deluge.details.FilesTab());this.add(new Deluge.details.PeersTab());this.add(new Deluge.details.OptionsTab())},clear:function(){this.items.each(function(a){if(a.clear){a.clear.defer(100,a);a.disable()}})},update:function(a){var b=deluge.torrents.getSelected();if(!b){this.clear();return}this.items.each(function(c){if(c.disabled){c.enable()}});a=a||this.getActiveTab();if(a.update){a.update(b.id)}},onRender:function(b,a){Deluge.details.DetailsPanel.superclass.onRender.call(this,b,a);deluge.events.on("disconnect",this.clear,this);deluge.torrents.on("rowclick",this.onTorrentsClick,this);this.on("tabchange",this.onTabChange,this);deluge.torrents.getSelectionModel().on("selectionchange",function(c){if(!c.hasSelection()){this.clear()}},this)},onTabChange:function(a,b){this.update(b)},onTorrentsClick:function(a,c,b){this.update()}});Deluge.details.DetailsTab=Ext.extend(Ext.Panel,{title:_("Details"),fields:{},queuedItems:{},oldData:{},initComponent:function(){Deluge.details.DetailsTab.superclass.initComponent.call(this);this.addItem("torrent_name",_("Name"));this.addItem("hash",_("Hash"));this.addItem("path",_("Path"));this.addItem("size",_("Total Size"));this.addItem("files",_("# of files"));this.addItem("comment",_("Comment"));this.addItem("status",_("Status"));this.addItem("tracker",_("Tracker"))},onRender:function(b,a){Deluge.details.DetailsTab.superclass.onRender.call(this,b,a);this.body.setStyle("padding","10px");this.dl=Ext.DomHelper.append(this.body,{tag:"dl"},true);for(var c in this.queuedItems){this.doAddItem(c,this.queuedItems[c])}},addItem:function(b,a){if(!this.rendered){this.queuedItems[b]=a}else{this.doAddItem(b,a)}},doAddItem:function(b,a){Ext.DomHelper.append(this.dl,{tag:"dt",cls:b,html:a+":"});this.fields[b]=Ext.DomHelper.append(this.dl,{tag:"dd",cls:b,html:""},true)},clear:function(){if(!this.fields){return}for(var a in this.fields){this.fields[a].dom.innerHTML=""}this.oldData={}},update:function(a){deluge.client.web.get_torrent_status(a,Deluge.Keys.Details,{success:this.onRequestComplete,scope:this,torrentId:a})},onRequestComplete:function(e,c,a,b){var d={torrent_name:e.name,hash:b.options.torrentId,path:e.save_path,size:fsize(e.total_size),files:e.num_files,status:e.message,tracker:e.tracker,comment:e.comment};for(var f in this.fields){if(!Ext.isDefined(d[f])){continue}if(d[f]==this.oldData[f]){continue}this.fields[f].dom.innerHTML=Ext.escapeHTML(d[f])}this.oldData=d}});
+Ext.namespace("Deluge.details");Deluge.details.DetailsPanel=Ext.extend(Ext.TabPanel,{id:"torrentDetails",activeTab:0,initComponent:function(){Deluge.details.DetailsPanel.superclass.initComponent.call(this);this.add(new Deluge.details.StatusTab());this.add(new Deluge.details.DetailsTab());this.add(new Deluge.details.FilesTab());this.add(new Deluge.details.PeersTab());this.add(new Deluge.details.OptionsTab())},clear:function(){this.items.each(function(a){if(a.clear){a.clear.defer(100,a);a.disable()}})},update:function(a){var b=deluge.torrents.getSelected();if(!b){this.clear();return}this.items.each(function(c){if(c.disabled){c.enable()}});a=a||this.getActiveTab();if(a.update){a.update(b.id)}},onRender:function(b,a){Deluge.details.DetailsPanel.superclass.onRender.call(this,b,a);deluge.events.on("disconnect",this.clear,this);deluge.torrents.on("rowclick",this.onTorrentsClick,this);this.on("tabchange",this.onTabChange,this);deluge.torrents.getSelectionModel().on("selectionchange",function(c){if(!c.hasSelection()){this.clear()}},this)},onTabChange:function(a,b){this.update(b)},onTorrentsClick:function(a,c,b){this.update()}});Deluge.details.DetailsTab=Ext.extend(Ext.Panel,{title:_("Details"),fields:{},autoScroll:true,queuedItems:{},oldData:{},initComponent:function(){Deluge.details.DetailsTab.superclass.initComponent.call(this);this.addItem("torrent_name",_("Name"));this.addItem("hash",_("Hash"));this.addItem("path",_("Path"));this.addItem("size",_("Total Size"));this.addItem("files",_("# of files"));this.addItem("comment",_("Comment"));this.addItem("status",_("Status"));this.addItem("tracker",_("Tracker"))},onRender:function(b,a){Deluge.details.DetailsTab.superclass.onRender.call(this,b,a);this.body.setStyle("padding","10px");this.dl=Ext.DomHelper.append(this.body,{tag:"dl"},true);for(var c in this.queuedItems){this.doAddItem(c,this.queuedItems[c])}},addItem:function(b,a){if(!this.rendered){this.queuedItems[b]=a}else{this.doAddItem(b,a)}},doAddItem:function(b,a){Ext.DomHelper.append(this.dl,{tag:"dt",cls:b,html:a+":"});this.fields[b]=Ext.DomHelper.append(this.dl,{tag:"dd",cls:b,html:""},true)},clear:function(){if(!this.fields){return}for(var a in this.fields){this.fields[a].dom.innerHTML=""}this.oldData={}},update:function(a){deluge.client.web.get_torrent_status(a,Deluge.Keys.Details,{success:this.onRequestComplete,scope:this,torrentId:a})},onRequestComplete:function(e,c,a,b){var d={torrent_name:e.name,hash:b.options.torrentId,path:e.save_path,size:fsize(e.total_size),files:e.num_files,status:e.message,tracker:e.tracker,comment:e.comment};for(var f in this.fields){if(!Ext.isDefined(d[f])){continue}if(d[f]==this.oldData[f]){continue}this.fields[f].dom.innerHTML=Ext.escapeHTML(d[f])}this.oldData=d}});
/*
* Deluge.details.FilesTab.js
- *
+ *
* Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -157,7 +157,7 @@ Ext.namespace("Deluge.details");Deluge.details.DetailsPanel=Ext.extend(Ext.TabPa
* this exception statement from your version. If you delete this exception
* statement from all source files in the program, then also delete it here.
*/
-Deluge.details.FilesTab=Ext.extend(Ext.ux.tree.TreeGrid,{title:_("Files"),autoScroll:true,rootVisible:false,columns:[{header:_("Filename"),width:330,dataIndex:"filename"},{header:_("Size"),width:150,dataIndex:"size",tpl:new Ext.XTemplate("{size:this.fsize}",{fsize:function(a){return fsize(a)}})},{xtype:"tgrendercolumn",header:_("Progress"),width:150,dataIndex:"progress",renderer:function(a){var b=a*100;return Deluge.progressBar(b,this.col.width,b.toFixed(2)+"%",0)}},{header:_("Priority"),width:150,dataIndex:"priority",tpl:new Ext.XTemplate('<tpl if="!isNaN(priority)"><div class="{priority:this.getClass}">{priority:this.getName}</div></tpl>',{getClass:function(a){return FILE_PRIORITY_CSS[a]},getName:function(a){return _(FILE_PRIORITY[a])}})}],selModel:new Ext.tree.MultiSelectionModel(),initComponent:function(){Deluge.details.FilesTab.superclass.initComponent.call(this);this.setRootNode(new Ext.tree.TreeNode({text:"Files"}))},clear:function(){var a=this.getRootNode();if(!a.hasChildNodes()){return}a.cascade(function(c){var b=c.parentNode;if(!b){return}if(!b.ownerTree){return}b.removeChild(c)})},createFileTree:function(c){function b(g,d){for(var e in g.contents){var f=g.contents[e];if(f.type=="dir"){b(f,d.appendChild(new Ext.tree.TreeNode({text:e,filename:e,size:f.size,progress:f.progress,priority:f.priority})))}else{d.appendChild(new Ext.tree.TreeNode({text:e,filename:e,fileIndex:f.index,size:f.size,progress:f.progress,priority:f.priority,leaf:true,iconCls:"x-deluge-file",uiProvider:Ext.ux.tree.TreeGridNodeUI}))}}}var a=this.getRootNode();b(c,a);a.firstChild.expand()},update:function(a){if(this.torrentId!=a){this.clear();this.torrentId=a}deluge.client.web.get_torrent_files(a,{success:this.onRequestComplete,scope:this,torrentId:a})},updateFileTree:function(b){function a(g,c){for(var d in g.contents){var f=g.contents[d];var e=c.findChild("filename",d);e.attributes.size=f.size;e.attributes.progress=f.progress;e.attributes.priority=f.priority;e.ui.updateColumns();if(f.type=="dir"){a(f,e)}}}a(b,this.getRootNode())},onRender:function(b,a){Deluge.details.FilesTab.superclass.onRender.call(this,b,a);deluge.menus.filePriorities.on("itemclick",this.onItemClick,this);this.on("contextmenu",this.onContextMenu,this);this.sorter=new Ext.tree.TreeSorter(this,{folderSort:true})},onContextMenu:function(b,c){c.stopEvent();var a=this.getSelectionModel();if(a.getSelectedNodes().length<2){a.clearSelections();b.select()}deluge.menus.filePriorities.showAt(c.getPoint())},onItemClick:function(h,g){switch(h.id){case"expandAll":this.expandAll();break;default:var f={};function a(e){if(Ext.isEmpty(e.attributes.fileIndex)){return}f[e.attributes.fileIndex]=e.attributes.priority}this.getRootNode().cascade(a);var b=this.getSelectionModel().getSelectedNodes();Ext.each(b,function(i){if(!i.isLeaf()){function e(j){if(Ext.isEmpty(j.attributes.fileIndex)){return}f[j.attributes.fileIndex]=h.filePriority}i.cascade(e)}else{if(!Ext.isEmpty(i.attributes.fileIndex)){f[i.attributes.fileIndex]=h.filePriority;return}}});var d=new Array(Ext.keys(f).length);for(var c in f){d[c]=f[c]}deluge.client.core.set_torrent_file_priorities(this.torrentId,d,{success:function(){Ext.each(b,function(e){e.setColumnValue(3,h.filePriority)})},scope:this});break}},onRequestComplete:function(b,a){if(!this.getRootNode().hasChildNodes()){this.createFileTree(b)}else{this.updateFileTree(b)}}});
+Deluge.details.FilesTab=Ext.extend(Ext.ux.tree.TreeGrid,{title:_("Files"),rootVisible:false,columns:[{header:_("Filename"),width:330,dataIndex:"filename"},{header:_("Size"),width:150,dataIndex:"size",tpl:new Ext.XTemplate("{size:this.fsize}",{fsize:function(a){return fsize(a)}})},{xtype:"tgrendercolumn",header:_("Progress"),width:150,dataIndex:"progress",renderer:function(a){var b=a*100;return Deluge.progressBar(b,this.col.width,b.toFixed(2)+"%",0)}},{header:_("Priority"),width:150,dataIndex:"priority",tpl:new Ext.XTemplate('<tpl if="!isNaN(priority)"><div class="{priority:this.getClass}">{priority:this.getName}</div></tpl>',{getClass:function(a){return FILE_PRIORITY_CSS[a]},getName:function(a){return _(FILE_PRIORITY[a])}})}],selModel:new Ext.tree.MultiSelectionModel(),initComponent:function(){Deluge.details.FilesTab.superclass.initComponent.call(this);this.setRootNode(new Ext.tree.TreeNode({text:"Files"}))},clear:function(){var a=this.getRootNode();if(!a.hasChildNodes()){return}a.cascade(function(c){var b=c.parentNode;if(!b){return}if(!b.ownerTree){return}b.removeChild(c)})},createFileTree:function(c){function b(g,d){for(var e in g.contents){var f=g.contents[e];if(f.type=="dir"){b(f,d.appendChild(new Ext.tree.TreeNode({text:e,filename:e,size:f.size,progress:f.progress,priority:f.priority})))}else{d.appendChild(new Ext.tree.TreeNode({text:e,filename:e,fileIndex:f.index,size:f.size,progress:f.progress,priority:f.priority,leaf:true,iconCls:"x-deluge-file",uiProvider:Ext.ux.tree.TreeGridNodeUI}))}}}var a=this.getRootNode();b(c,a);a.firstChild.expand()},update:function(a){if(this.torrentId!=a){this.clear();this.torrentId=a}deluge.client.web.get_torrent_files(a,{success:this.onRequestComplete,scope:this,torrentId:a})},updateFileTree:function(b){function a(g,c){for(var d in g.contents){var f=g.contents[d];var e=c.findChild("filename",d);e.attributes.size=f.size;e.attributes.progress=f.progress;e.attributes.priority=f.priority;e.ui.updateColumns();if(f.type=="dir"){a(f,e)}}}a(b,this.getRootNode())},onRender:function(b,a){Deluge.details.FilesTab.superclass.onRender.call(this,b,a);deluge.menus.filePriorities.on("itemclick",this.onItemClick,this);this.on("contextmenu",this.onContextMenu,this);this.sorter=new Ext.tree.TreeSorter(this,{folderSort:true})},onContextMenu:function(b,c){c.stopEvent();var a=this.getSelectionModel();if(a.getSelectedNodes().length<2){a.clearSelections();b.select()}deluge.menus.filePriorities.showAt(c.getPoint())},onItemClick:function(h,g){switch(h.id){case"expandAll":this.expandAll();break;default:var f={};function a(e){if(Ext.isEmpty(e.attributes.fileIndex)){return}f[e.attributes.fileIndex]=e.attributes.priority}this.getRootNode().cascade(a);var b=this.getSelectionModel().getSelectedNodes();Ext.each(b,function(i){if(!i.isLeaf()){function e(j){if(Ext.isEmpty(j.attributes.fileIndex)){return}f[j.attributes.fileIndex]=h.filePriority}i.cascade(e)}else{if(!Ext.isEmpty(i.attributes.fileIndex)){f[i.attributes.fileIndex]=h.filePriority;return}}});var d=new Array(Ext.keys(f).length);for(var c in f){d[c]=f[c]}deluge.client.core.set_torrent_file_priorities(this.torrentId,d,{success:function(){Ext.each(b,function(e){e.setColumnValue(3,h.filePriority)})},scope:this});break}},onRequestComplete:function(b,a){if(!this.getRootNode().hasChildNodes()){this.createFileTree(b)}else{this.updateFileTree(b)}}});
/*
* Deluge.details.OptionsTab.js
*
@@ -221,7 +221,7 @@ Deluge.details.OptionsTab=Ext.extend(Ext.form.FormPanel,{constructor:function(a)
* this exception statement from your version. If you delete this exception
* statement from all source files in the program, then also delete it here.
*/
-(function(){function a(d){if(!d.replace(" ","").replace(" ","")){return""}return String.format('<img src="flag/{0}" />',d)}function b(g,h,e){var d=(e.data.seed==1024)?"x-deluge-seed":"x-deluge-peer";if(peer_ip.length>2){var f=peer_ip.pop();var i=peer_ip.join(":");g="["+i+"]:"+f}return String.format('<div class="{0}">{1}</div>',d,g)}function c(e){var d=(e*100).toFixed(0);return Deluge.progressBar(d,this.width-8,d+"%")}Deluge.details.PeersTab=Ext.extend(Ext.grid.GridPanel,{peers:{},constructor:function(d){d=Ext.apply({title:_("Peers"),cls:"x-deluge-peers",store:new Ext.data.Store({reader:new Ext.data.JsonReader({idProperty:"ip",root:"peers"},Deluge.data.Peer)}),columns:[{header:"&nbsp;",width:30,sortable:true,renderer:a,dataIndex:"country"},{header:"Address",width:125,sortable:true,renderer:b,dataIndex:"ip"},{header:"Client",width:125,sortable:true,renderer:fplain,dataIndex:"client"},{header:"Progress",width:150,sortable:true,renderer:c,dataIndex:"progress"},{header:"Down Speed",width:100,sortable:true,renderer:fspeed,dataIndex:"down_speed"},{header:"Up Speed",width:100,sortable:true,renderer:fspeed,dataIndex:"up_speed"}],stripeRows:true,deferredRender:false,autoScroll:true},d);Deluge.details.PeersTab.superclass.constructor.call(this,d)},clear:function(){this.getStore().removeAll();this.peers={}},update:function(d){deluge.client.web.get_torrent_status(d,Deluge.Keys.Peers,{success:this.onRequestComplete,scope:this})},onRequestComplete:function(h,g){if(!h){return}var f=this.getStore();var e=[];var i={};Ext.each(h.peers,function(m){if(this.peers[m.ip]){var j=f.getById(m.ip);j.beginEdit();for(var l in m){if(j.get(l)!=m[l]){j.set(l,m[l])}}j.endEdit()}else{this.peers[m.ip]=1;e.push(new Deluge.data.Peer(m,m.ip))}i[m.ip]=1},this);f.add(e);f.each(function(j){if(!i[j.id]){f.remove(j);delete this.peers[j.id]}},this);f.commitChanges();var d=f.getSortState();if(!d){return}f.sort(d.field,d.direction)}})})();
+(function(){function a(d){if(!d.replace(" ","").replace(" ","")){return""}return String.format('<img src="{0}flag/{1}" />',deluge.config.base,d)}function b(g,h,e){var d=(e.data.seed==1024)?"x-deluge-seed":"x-deluge-peer";if(peer_ip.length>2){var f=peer_ip.pop();var i=peer_ip.join(":");g="["+i+"]:"+f}return String.format('<div class="{0}">{1}</div>',d,g)}function c(e){var d=(e*100).toFixed(0);return Deluge.progressBar(d,this.width-8,d+"%")}Deluge.details.PeersTab=Ext.extend(Ext.grid.GridPanel,{peers:{},constructor:function(d){d=Ext.apply({title:_("Peers"),cls:"x-deluge-peers",store:new Ext.data.Store({reader:new Ext.data.JsonReader({idProperty:"ip",root:"peers"},Deluge.data.Peer)}),columns:[{header:"&nbsp;",width:30,sortable:true,renderer:a,dataIndex:"country"},{header:"Address",width:125,sortable:true,renderer:b,dataIndex:"ip"},{header:"Client",width:125,sortable:true,renderer:fplain,dataIndex:"client"},{header:"Progress",width:150,sortable:true,renderer:c,dataIndex:"progress"},{header:"Down Speed",width:100,sortable:true,renderer:fspeed,dataIndex:"down_speed"},{header:"Up Speed",width:100,sortable:true,renderer:fspeed,dataIndex:"up_speed"}],stripeRows:true,deferredRender:false,autoScroll:true},d);Deluge.details.PeersTab.superclass.constructor.call(this,d)},clear:function(){this.getStore().removeAll();this.peers={}},update:function(d){deluge.client.web.get_torrent_status(d,Deluge.Keys.Peers,{success:this.onRequestComplete,scope:this})},onRequestComplete:function(h,g){if(!h){return}var f=this.getStore();var e=[];var i={};Ext.each(h.peers,function(m){if(this.peers[m.ip]){var j=f.getById(m.ip);j.beginEdit();for(var l in m){if(j.get(l)!=m[l]){j.set(l,m[l])}}j.endEdit()}else{this.peers[m.ip]=1;e.push(new Deluge.data.Peer(m,m.ip))}i[m.ip]=1},this);f.add(e);f.each(function(j){if(!i[j.id]){f.remove(j);delete this.peers[j.id]}},this);f.commitChanges();var d=f.getSortState();if(!d){return}f.sort(d.field,d.direction)}})})();
/*
* Deluge.details.StatusTab.js
*
@@ -317,7 +317,7 @@ Ext.ns("Deluge.add");Deluge.add.Window=Ext.extend(Ext.Window,{initComponent:func
* this exception statement from your version. If you delete this exception
* statement from all source files in the program, then also delete it here.
*/
-Ext.namespace("Deluge.add");Deluge.add.AddWindow=Ext.extend(Deluge.add.Window,{title:_("Add Torrents"),layout:"border",width:470,height:450,bodyStyle:"padding: 10px 5px;",buttonAlign:"right",closeAction:"hide",closable:true,plain:true,iconCls:"x-deluge-add-window-icon",initComponent:function(){Deluge.add.AddWindow.superclass.initComponent.call(this);this.addButton(_("Cancel"),this.onCancelClick,this);this.addButton(_("Add"),this.onAddClick,this);function a(c,d,b){if(b.data.info_hash){return String.format('<div class="x-deluge-add-torrent-name">{0}</div>',c)}else{return String.format('<div class="x-deluge-add-torrent-name-loading">{0}</div>',c)}}this.list=new Ext.list.ListView({store:new Ext.data.SimpleStore({fields:[{name:"info_hash",mapping:1},{name:"text",mapping:2}],id:0}),columns:[{id:"torrent",width:150,sortable:true,renderer:a,dataIndex:"text"}],stripeRows:true,singleSelect:true,listeners:{selectionchange:{fn:this.onSelect,scope:this}},hideHeaders:true,autoExpandColumn:"torrent",height:"100%",autoScroll:true});this.add({region:"center",items:[this.list],margins:"5 5 5 5",bbar:new Ext.Toolbar({items:[{iconCls:"x-deluge-add-file",text:_("File"),handler:this.onFile,scope:this},{text:_("Url"),iconCls:"icon-add-url",handler:this.onUrl,scope:this},{text:_("Infohash"),iconCls:"icon-add-magnet",disabled:true},"->",{text:_("Remove"),iconCls:"icon-remove",handler:this.onRemove,scope:this}]})});this.optionsPanel=this.add(new Deluge.add.OptionsPanel());this.on("hide",this.onHide,this);this.on("show",this.onShow,this)},clear:function(){this.list.getStore().removeAll();this.optionsPanel.clear()},onAddClick:function(){var a=[];if(!this.list){return}this.list.getStore().each(function(b){var c=b.get("info_hash");a.push({path:this.optionsPanel.getFilename(c),options:this.optionsPanel.getOptions(c)})},this);deluge.client.web.add_torrents(a,{success:function(b){}});this.clear();this.hide()},onCancelClick:function(){this.clear();this.hide()},onFile:function(){if(!this.file){this.file=new Deluge.add.FileWindow()}this.file.show()},onHide:function(){this.optionsPanel.setActiveTab(0);this.optionsPanel.files.setDisabled(true);this.optionsPanel.form.setDisabled(true)},onRemove:function(){if(!this.list.getSelectionCount()){return}var a=this.list.getSelectedRecords()[0];this.list.getStore().remove(a);this.optionsPanel.clear();if(this.torrents&&this.torrents[a.id]){delete this.torrents[a.id]}},onSelect:function(c,b){if(b.length){var a=this.list.getRecord(b[0]);this.optionsPanel.setTorrent(a.get("info_hash"))}else{this.optionsPanel.files.setDisabled(true);this.optionsPanel.form.setDisabled(true)}},onShow:function(){if(!this.url){this.url=new Deluge.add.UrlWindow();this.url.on("beforeadd",this.onTorrentBeforeAdd,this);this.url.on("add",this.onTorrentAdd,this)}if(!this.file){this.file=new Deluge.add.FileWindow();this.file.on("beforeadd",this.onTorrentBeforeAdd,this);this.file.on("add",this.onTorrentAdd,this)}this.optionsPanel.form.getDefaults()},onTorrentBeforeAdd:function(b,c){var a=this.list.getStore();a.loadData([[b,null,c]],true)},onTorrentAdd:function(a,c){var b=this.list.getStore().getById(a);if(!c){Ext.MessageBox.show({title:_("Error"),msg:_("Not a valid torrent"),buttons:Ext.MessageBox.OK,modal:false,icon:Ext.MessageBox.ERROR,iconCls:"x-deluge-icon-error"});this.list.getStore().remove(b)}else{b.set("info_hash",c.info_hash);b.set("text",c.name);this.list.getStore().commitChanges();this.optionsPanel.addTorrent(c);this.list.select(b)}},onUrl:function(a,b){this.url.show()}});
+Ext.namespace("Deluge.add");Deluge.add.AddWindow=Ext.extend(Deluge.add.Window,{title:_("Add Torrents"),layout:"border",width:470,height:450,bodyStyle:"padding: 10px 5px;",buttonAlign:"right",closeAction:"hide",closable:true,plain:true,iconCls:"x-deluge-add-window-icon",initComponent:function(){Deluge.add.AddWindow.superclass.initComponent.call(this);this.addButton(_("Cancel"),this.onCancelClick,this);this.addButton(_("Add"),this.onAddClick,this);function a(c,d,b){if(b.data.info_hash){return String.format('<div class="x-deluge-add-torrent-name">{0}</div>',c)}else{return String.format('<div class="x-deluge-add-torrent-name-loading">{0}</div>',c)}}this.list=new Ext.list.ListView({store:new Ext.data.SimpleStore({fields:[{name:"info_hash",mapping:1},{name:"text",mapping:2}],id:0}),columns:[{id:"torrent",width:150,sortable:true,renderer:a,dataIndex:"text"}],stripeRows:true,singleSelect:true,listeners:{selectionchange:{fn:this.onSelect,scope:this}},hideHeaders:true,autoExpandColumn:"torrent",height:"100%",autoScroll:true});this.add({region:"center",items:[this.list],margins:"5 5 5 5",bbar:new Ext.Toolbar({items:[{iconCls:"x-deluge-add-file",text:_("File"),handler:this.onFile,scope:this},{text:_("Url"),iconCls:"icon-add-url",handler:this.onUrl,scope:this},{text:_("Infohash"),iconCls:"icon-add-magnet",hidden:true,disabled:true},"->",{text:_("Remove"),iconCls:"icon-remove",handler:this.onRemove,scope:this}]})});this.optionsPanel=this.add(new Deluge.add.OptionsPanel());this.on("hide",this.onHide,this);this.on("show",this.onShow,this)},clear:function(){this.list.getStore().removeAll();this.optionsPanel.clear()},onAddClick:function(){var a=[];if(!this.list){return}this.list.getStore().each(function(b){var c=b.get("info_hash");a.push({path:this.optionsPanel.getFilename(c),options:this.optionsPanel.getOptions(c)})},this);deluge.client.web.add_torrents(a,{success:function(b){}});this.clear();this.hide()},onCancelClick:function(){this.clear();this.hide()},onFile:function(){if(!this.file){this.file=new Deluge.add.FileWindow()}this.file.show()},onHide:function(){this.optionsPanel.setActiveTab(0);this.optionsPanel.files.setDisabled(true);this.optionsPanel.form.setDisabled(true)},onRemove:function(){if(!this.list.getSelectionCount()){return}var a=this.list.getSelectedRecords()[0];this.list.getStore().remove(a);this.optionsPanel.clear();if(this.torrents&&this.torrents[a.id]){delete this.torrents[a.id]}},onSelect:function(c,b){if(b.length){var a=this.list.getRecord(b[0]);this.optionsPanel.setTorrent(a.get("info_hash"))}else{this.optionsPanel.files.setDisabled(true);this.optionsPanel.form.setDisabled(true)}},onShow:function(){if(!this.url){this.url=new Deluge.add.UrlWindow();this.url.on("beforeadd",this.onTorrentBeforeAdd,this);this.url.on("add",this.onTorrentAdd,this)}if(!this.file){this.file=new Deluge.add.FileWindow();this.file.on("beforeadd",this.onTorrentBeforeAdd,this);this.file.on("add",this.onTorrentAdd,this)}this.optionsPanel.form.getDefaults()},onTorrentBeforeAdd:function(b,c){var a=this.list.getStore();a.loadData([[b,null,c]],true)},onTorrentAdd:function(a,c){var b=this.list.getStore().getById(a);if(!c){Ext.MessageBox.show({title:_("Error"),msg:_("Not a valid torrent"),buttons:Ext.MessageBox.OK,modal:false,icon:Ext.MessageBox.ERROR,iconCls:"x-deluge-icon-error"});this.list.getStore().remove(b)}else{b.set("info_hash",c.info_hash);b.set("text",c.name);this.list.getStore().commitChanges();this.optionsPanel.addTorrent(c);this.list.select(b)}},onUrl:function(a,b){this.url.show()}});
/*
* Deluge.add.File.js
*
@@ -352,7 +352,7 @@ Ext.namespace("Deluge.add");Deluge.add.AddWindow=Ext.extend(Deluge.add.Window,{t
Ext.ns("Deluge.add");Deluge.add.FileWindow=Ext.extend(Deluge.add.Window,{title:_("Add from File"),layout:"fit",width:350,height:115,modal:true,plain:true,buttonAlign:"center",closeAction:"hide",bodyStyle:"padding: 10px 5px;",iconCls:"x-deluge-add-file",initComponent:function(){Deluge.add.FileWindow.superclass.initComponent.call(this);this.addButton(_("Add"),this.onAddClick,this);this.form=this.add({xtype:"form",baseCls:"x-plain",labelWidth:35,autoHeight:true,fileUpload:true,items:[{xtype:"fileuploadfield",id:"torrentFile",width:280,height:24,emptyText:_("Select a torrent"),fieldLabel:_("File"),name:"file",buttonCfg:{text:_("Browse")+"..."}}]})},onAddClick:function(c,b){if(this.form.getForm().isValid()){this.torrentId=this.createTorrentId();this.form.getForm().submit({url:deluge.config.base+"upload",waitMsg:_("Uploading your torrent..."),failure:this.onUploadFailure,success:this.onUploadSuccess,scope:this});var a=this.form.getForm().findField("torrentFile").value;a=a.split("\\").slice(-1)[0];this.fireEvent("beforeadd",this.torrentId,a)}},onGotInfo:function(d,c,a,b){d.filename=b.options.filename;this.fireEvent("add",this.torrentId,d)},onUploadFailure:function(a,b){this.hide()},onUploadSuccess:function(c,b){this.hide();if(b.result.success){var a=b.result.files[0];this.form.getForm().findField("torrentFile").setValue("");deluge.client.web.get_torrent_info(a,{success:this.onGotInfo,scope:this,filename:a})}}});
/*
* Deluge.add.FilesTab.js
- *
+ *
* Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -381,7 +381,7 @@ Ext.ns("Deluge.add");Deluge.add.FileWindow=Ext.extend(Deluge.add.Window,{title:_
* this exception statement from your version. If you delete this exception
* statement from all source files in the program, then also delete it here.
*/
-Ext.ns("Deluge.add");Deluge.add.FilesTab=Ext.extend(Ext.ux.tree.TreeGrid,{layout:"fit",title:_("Files"),autoScroll:true,animate:false,border:false,disabled:true,rootVisible:false,columns:[{header:_("Filename"),width:295,dataIndex:"filename"},{header:_("Size"),width:60,dataIndex:"size",tpl:new Ext.XTemplate("{size:this.fsize}",{fsize:function(a){return fsize(a)}})},{header:_("Download"),width:65,dataIndex:"download",tpl:new Ext.XTemplate("{download:this.format}",{format:function(a){return'<div rel="chkbox" class="x-grid3-check-col'+(a?"-on":"")+'"> </div>'}})}],initComponent:function(){Deluge.add.FilesTab.superclass.initComponent.call(this);this.on("click",this.onNodeClick,this)},clearFiles:function(){var a=this.getRootNode();if(!a.hasChildNodes()){return}a.cascade(function(b){if(!b.parentNode||!b.getOwnerTree()){return}b.remove()})},setDownload:function(b,c,d){b.attributes.download=c;b.ui.updateColumns();if(b.isLeaf()){if(!d){return this.fireEvent("fileschecked",[b],c,!c)}}else{var a=[b];b.cascade(function(e){e.attributes.download=c;e.ui.updateColumns();a.push(e)},this);if(!d){return this.fireEvent("fileschecked",a,c,!c)}}},onNodeClick:function(b,c){var a=new Ext.Element(c.target);if(a.getAttribute("rel")=="chkbox"){this.setDownload(b,!b.attributes.download)}}});
+Ext.ns("Deluge.add");Deluge.add.FilesTab=Ext.extend(Ext.ux.tree.TreeGrid,{layout:"fit",title:_("Files"),autoScroll:false,animate:false,border:false,disabled:true,rootVisible:false,columns:[{header:_("Filename"),width:295,dataIndex:"filename"},{header:_("Size"),width:60,dataIndex:"size",tpl:new Ext.XTemplate("{size:this.fsize}",{fsize:function(a){return fsize(a)}})},{header:_("Download"),width:65,dataIndex:"download",tpl:new Ext.XTemplate("{download:this.format}",{format:function(a){return'<div rel="chkbox" class="x-grid3-check-col'+(a?"-on":"")+'"> </div>'}})}],initComponent:function(){Deluge.add.FilesTab.superclass.initComponent.call(this);this.on("click",this.onNodeClick,this)},clearFiles:function(){var a=this.getRootNode();if(!a.hasChildNodes()){return}a.cascade(function(b){if(!b.parentNode||!b.getOwnerTree()){return}b.remove()})},setDownload:function(b,c,d){b.attributes.download=c;b.ui.updateColumns();if(b.isLeaf()){if(!d){return this.fireEvent("fileschecked",[b],c,!c)}}else{var a=[b];b.cascade(function(e){e.attributes.download=c;e.ui.updateColumns();a.push(e)},this);if(!d){return this.fireEvent("fileschecked",a,c,!c)}}},onNodeClick:function(b,c){var a=new Ext.Element(c.target);if(a.getAttribute("rel")=="chkbox"){this.setDownload(b,!b.attributes.download)}}});
/*
* Deluge.add.Infohash.js
*
@@ -448,7 +448,7 @@ Ext.namespace("Ext.deluge.add");
Ext.ns("Deluge.add");Deluge.add.OptionsPanel=Ext.extend(Ext.TabPanel,{torrents:{},region:"south",margins:"5 5 5 5",activeTab:0,height:220,initComponent:function(){Deluge.add.OptionsPanel.superclass.initComponent.call(this);this.files=this.add(new Deluge.add.FilesTab());this.form=this.add(new Deluge.add.OptionsTab());this.files.on("fileschecked",this.onFilesChecked,this)},addTorrent:function(c){this.torrents[c.info_hash]=c;var b={};this.walkFileTree(c.files_tree,function(e,g,h,f){if(g!="file"){return}b[h.index]=h.download},this);var a=[];Ext.each(Ext.keys(b),function(e){a[e]=b[e]});var d=this.form.optionsManager.changeId(c.info_hash,true);this.form.optionsManager.setDefault("file_priorities",a);this.form.optionsManager.changeId(d,true)},clear:function(){this.files.clearFiles();this.form.optionsManager.resetAll()},getFilename:function(a){return this.torrents[a]["filename"]},getOptions:function(a){var c=this.form.optionsManager.changeId(a,true);var b=this.form.optionsManager.get();this.form.optionsManager.changeId(c,true);Ext.each(b.file_priorities,function(e,d){b.file_priorities[d]=(e)?1:0});return b},setTorrent:function(b){if(!b){return}this.torrentId=b;this.form.optionsManager.changeId(b);this.files.clearFiles();var a=this.files.getRootNode();var c=this.form.optionsManager.get("file_priorities");this.form.setDisabled(false);if(this.torrents[b]["files_tree"]){this.walkFileTree(this.torrents[b]["files_tree"],function(e,f,h,d){var g=new Ext.tree.TreeNode({download:(h.index)?c[h.index]:true,filename:e,fileindex:h.index,leaf:f!="dir",size:h.length});d.appendChild(g);if(f=="dir"){return g}},this,a);a.firstChild.expand();this.files.setDisabled(false);this.files.show()}else{this.form.show();this.files.setDisabled(true)}},walkFileTree:function(g,h,e,a){for(var b in g.contents){var f=g.contents[b];var d=f.type;if(e){var c=h.apply(e,[b,d,f,a])}else{var c=h(b,d,f,a)}if(d=="dir"){this.walkFileTree(f,h,e,c)}}},onFilesChecked:function(a,c,b){if(this.form.optionsManager.get("compact_allocation")){Ext.Msg.show({title:_("Unable to set file priority!"),msg:_("File prioritization is unavailable when using Compact allocation. Would you like to switch to Full allocation?"),buttons:Ext.Msg.YESNO,fn:function(d){if(d=="yes"){this.form.optionsManager.update("compact_allocation",false);Ext.each(a,function(f){if(f.attributes.fileindex<0){return}var e=this.form.optionsManager.get("file_priorities");e[f.attributes.fileindex]=c;this.form.optionsManager.update("file_priorities",e)},this)}else{this.files.setDownload(a[0],b,true)}},scope:this,icon:Ext.MessageBox.QUESTION})}else{Ext.each(a,function(e){if(e.attributes.fileindex<0){return}var d=this.form.optionsManager.get("file_priorities");d[e.attributes.fileindex]=c;this.form.optionsManager.update("file_priorities",d)},this)}}});
/*
* Deluge.add.OptionsPanel.js
- *
+ *
* Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -477,7 +477,7 @@ Ext.ns("Deluge.add");Deluge.add.OptionsPanel=Ext.extend(Ext.TabPanel,{torrents:{
* this exception statement from your version. If you delete this exception
* statement from all source files in the program, then also delete it here.
*/
-Ext.ns("Deluge.add");Deluge.add.OptionsTab=Ext.extend(Ext.form.FormPanel,{title:_("Options"),height:170,border:false,bodyStyle:"padding: 5px",disabled:true,labelWidth:1,initComponent:function(){Deluge.add.OptionsTab.superclass.initComponent.call(this);this.optionsManager=new Deluge.MultiOptionsManager();var a=this.add({xtype:"fieldset",title:_("Download Location"),border:false,autoHeight:true,defaultType:"textfield",labelWidth:1,fieldLabel:"",style:"padding-bottom: 5px; margin-bottom: 0px;"});this.optionsManager.bind("download_location",a.add({fieldLabel:"",name:"download_location",width:400,labelSeparator:""}));var b=this.add({border:false,layout:"column",defaultType:"fieldset"});a=b.add({title:_("Allocation"),border:false,autoHeight:true,defaultType:"radio",width:100});this.optionsManager.bind("compact_allocation",a.add({xtype:"radiogroup",columns:1,vertical:true,labelSeparator:"",items:[{name:"compact_allocation",value:false,inputValue:false,boxLabel:_("Full"),fieldLabel:"",labelSeparator:""},{name:"compact_allocation",value:true,inputValue:true,boxLabel:_("Compact"),fieldLabel:"",labelSeparator:""}]}));a=b.add({title:_("Bandwidth"),border:false,autoHeight:true,labelWidth:100,width:200,defaultType:"spinnerfield"});this.optionsManager.bind("max_download_speed",a.add({fieldLabel:_("Max Down Speed"),labelStyle:"margin-left: 10px",name:"max_download_speed",width:60}));this.optionsManager.bind("max_upload_speed",a.add({fieldLabel:_("Max Up Speed"),labelStyle:"margin-left: 10px",name:"max_upload_speed",width:60}));this.optionsManager.bind("max_connections",a.add({fieldLabel:_("Max Connections"),labelStyle:"margin-left: 10px",name:"max_connections",width:60}));this.optionsManager.bind("max_upload_slots",a.add({fieldLabel:_("Max Upload Slots"),labelStyle:"margin-left: 10px",name:"max_upload_slots",width:60}));a=b.add({title:_("General"),border:false,autoHeight:true,defaultType:"checkbox"});this.optionsManager.bind("add_paused",a.add({name:"add_paused",boxLabel:_("Add In Paused State"),fieldLabel:"",labelSeparator:""}));this.optionsManager.bind("prioritize_first_last_pieces",a.add({name:"prioritize_first_last_pieces",boxLabel:_("Prioritize First/Last Pieces"),fieldLabel:"",labelSeparator:""}))},getDefaults:function(){var a=["add_paused","compact_allocation","download_location","max_connections_per_torrent","max_download_speed_per_torrent","max_upload_slots_per_torrent","max_upload_speed_per_torrent","prioritize_first_last_pieces"];deluge.client.core.get_config_values(a,{success:function(c){var b={file_priorities:[],add_paused:c.add_paused,compact_allocation:c.compact_allocation,download_location:c.download_location,max_connections:c.max_connections_per_torrent,max_download_speed:c.max_download_speed_per_torrent,max_upload_slots:c.max_upload_slots_per_torrent,max_upload_speed:c.max_upload_speed_per_torrent,prioritize_first_last_pieces:c.prioritize_first_last_pieces};this.optionsManager.options=b;this.optionsManager.resetAll()},scope:this})}});
+Ext.ns("Deluge.add");Deluge.add.OptionsTab=Ext.extend(Ext.form.FormPanel,{title:_("Options"),height:170,border:false,bodyStyle:"padding: 5px",disabled:true,labelWidth:1,initComponent:function(){Deluge.add.OptionsTab.superclass.initComponent.call(this);this.optionsManager=new Deluge.MultiOptionsManager();var a=this.add({xtype:"fieldset",title:_("Download Location"),border:false,autoHeight:true,defaultType:"textfield",labelWidth:1,fieldLabel:"",style:"padding-bottom: 5px; margin-bottom: 0px;"});this.optionsManager.bind("download_location",a.add({fieldLabel:"",name:"download_location",width:400,labelSeparator:""}));var b=this.add({border:false,layout:"column",defaultType:"fieldset"});a=b.add({title:_("Allocation"),border:false,autoHeight:true,defaultType:"radio",});this.optionsManager.bind("compact_allocation",a.add({xtype:"radiogroup",columns:1,vertical:true,labelSeparator:"",width:80,items:[{name:"compact_allocation",value:false,inputValue:false,boxLabel:_("Full"),fieldLabel:"",labelSeparator:""},{name:"compact_allocation",value:true,inputValue:true,boxLabel:_("Compact"),fieldLabel:"",labelSeparator:""}]}));a=b.add({title:_("Bandwidth"),border:false,autoHeight:true,bodyStyle:"margin-left: 7px",labelWidth:105,width:200,defaultType:"spinnerfield"});this.optionsManager.bind("max_download_speed",a.add({fieldLabel:_("Max Down Speed"),name:"max_download_speed",width:60}));this.optionsManager.bind("max_upload_speed",a.add({fieldLabel:_("Max Up Speed"),name:"max_upload_speed",width:60}));this.optionsManager.bind("max_connections",a.add({fieldLabel:_("Max Connections"),name:"max_connections",width:60}));this.optionsManager.bind("max_upload_slots",a.add({fieldLabel:_("Max Upload Slots"),name:"max_upload_slots",width:60}));a=b.add({title:_("General"),border:false,autoHeight:true,defaultType:"checkbox"});this.optionsManager.bind("add_paused",a.add({name:"add_paused",boxLabel:_("Add In Paused State"),fieldLabel:"",labelSeparator:""}));this.optionsManager.bind("prioritize_first_last_pieces",a.add({name:"prioritize_first_last_pieces",boxLabel:_("Prioritize First/Last Pieces"),fieldLabel:"",labelSeparator:""}))},getDefaults:function(){var a=["add_paused","compact_allocation","download_location","max_connections_per_torrent","max_download_speed_per_torrent","max_upload_slots_per_torrent","max_upload_speed_per_torrent","prioritize_first_last_pieces"];deluge.client.core.get_config_values(a,{success:function(c){var b={file_priorities:[],add_paused:c.add_paused,compact_allocation:c.compact_allocation,download_location:c.download_location,max_connections:c.max_connections_per_torrent,max_download_speed:c.max_download_speed_per_torrent,max_upload_slots:c.max_upload_slots_per_torrent,max_upload_speed:c.max_upload_speed_per_torrent,prioritize_first_last_pieces:c.prioritize_first_last_pieces};this.optionsManager.options=b;this.optionsManager.resetAll()},scope:this})}});
/*
* Deluge.add.UrlWindow.js
*
@@ -509,7 +509,7 @@ Ext.ns("Deluge.add");Deluge.add.OptionsTab=Ext.extend(Ext.form.FormPanel,{title:
* this exception statement from your version. If you delete this exception
* statement from all source files in the program, then also delete it here.
*/
-Ext.namespace("Deluge.add");Deluge.add.UrlWindow=Ext.extend(Deluge.add.Window,{title:_("Add from Url"),modal:true,plain:true,layout:"fit",width:350,height:155,buttonAlign:"center",closeAction:"hide",bodyStyle:"padding: 10px 5px;",iconCls:"x-deluge-add-url-window-icon",initComponent:function(){Deluge.add.UrlWindow.superclass.initComponent.call(this);this.addButton(_("Add"),this.onAddClick,this);var a=this.add({xtype:"form",defaultType:"textfield",baseCls:"x-plain",labelWidth:55});this.urlField=a.add({fieldLabel:_("Url"),id:"url",name:"url",width:"97%"});this.urlField.on("specialkey",this.onAdd,this);this.cookieField=a.add({fieldLabel:_("Cookies"),id:"cookies",name:"cookies",width:"97%"});this.cookieField.on("specialkey",this.onAdd,this)},onAddClick:function(f,d){if((f.id=="url"||f.id=="cookies")&&d.getKey()!=d.ENTER){return}var f=this.urlField;var b=f.getValue();var c=this.cookieField.getValue();var a=this.createTorrentId();if(b.substring(0,20)=="magnet:?xt=urn:btih:"){deluge.client.web.get_magnet_info(b,{success:this.onGotInfo,scope:this,filename:b,torrentId:a})}else{deluge.client.web.download_torrent_from_url(b,c,{success:this.onDownload,scope:this,torrentId:a})}this.hide();this.urlField.setValue("");this.fireEvent("beforeadd",a,b)},onDownload:function(a,c,d,b){deluge.client.web.get_torrent_info(a,{success:this.onGotInfo,scope:this,filename:a,torrentId:b.options.torrentId})},onGotInfo:function(d,c,a,b){d.filename=b.options.filename;this.fireEvent("add",b.options.torrentId,d)}});
+Ext.namespace("Deluge.add");Deluge.add.UrlWindow=Ext.extend(Deluge.add.Window,{title:_("Add from Url"),modal:true,plain:true,layout:"fit",width:350,height:155,buttonAlign:"center",closeAction:"hide",bodyStyle:"padding: 10px 5px;",iconCls:"x-deluge-add-url-window-icon",initComponent:function(){Deluge.add.UrlWindow.superclass.initComponent.call(this);this.addButton(_("Add"),this.onAddClick,this);var a=this.add({xtype:"form",defaultType:"textfield",baseCls:"x-plain",labelWidth:55});this.urlField=a.add({fieldLabel:_("Url"),id:"url",name:"url",width:"97%"});this.urlField.on("specialkey",this.onAdd,this);this.cookieField=a.add({fieldLabel:_("Cookies"),id:"cookies",name:"cookies",width:"97%"});this.cookieField.on("specialkey",this.onAdd,this)},onAddClick:function(f,d){if((f.id=="url"||f.id=="cookies")&&d.getKey()!=d.ENTER){return}var f=this.urlField;var b=f.getValue();var c=this.cookieField.getValue();var a=this.createTorrentId();if(b.indexOf("magnet:?")==0&&b.indexOf("xt=urn:btih")>-1){deluge.client.web.get_magnet_info(b,{success:this.onGotInfo,scope:this,filename:b,torrentId:a})}else{deluge.client.web.download_torrent_from_url(b,c,{success:this.onDownload,scope:this,torrentId:a})}this.hide();this.urlField.setValue("");this.fireEvent("beforeadd",a,b)},onDownload:function(a,c,d,b){deluge.client.web.get_torrent_info(a,{success:this.onGotInfo,scope:this,filename:a,torrentId:b.options.torrentId})},onGotInfo:function(d,c,a,b){d.filename=b.options.filename;this.fireEvent("add",b.options.torrentId,d)}});
/*
* Deluge.preferences.BandwidthPage.js
*
@@ -896,7 +896,7 @@ Ext.namespace("Deluge.preferences");PreferencesRecord=Ext.data.Record.create([{n
Ext.ns("Deluge.preferences");Deluge.preferences.ProxyField=Ext.extend(Ext.form.FieldSet,{border:false,autoHeight:true,labelWidth:70,initComponent:function(){Deluge.preferences.ProxyField.superclass.initComponent.call(this);this.proxyType=this.add({xtype:"combo",fieldLabel:_("Type"),name:"proxytype",mode:"local",width:150,store:new Ext.data.ArrayStore({fields:["id","text"],data:[[0,_("None")],[1,_("Socksv4")],[2,_("Socksv5")],[3,_("Socksv5 with Auth")],[4,_("HTTP")],[5,_("HTTP with Auth")]]}),editable:false,triggerAction:"all",valueField:"id",displayField:"text"});this.hostname=this.add({xtype:"textfield",name:"hostname",fieldLabel:_("Host"),width:220});this.port=this.add({xtype:"spinnerfield",name:"port",fieldLabel:_("Port"),width:80,decimalPrecision:0,minValue:-1,maxValue:99999});this.username=this.add({xtype:"textfield",name:"username",fieldLabel:_("Username"),width:220});this.password=this.add({xtype:"textfield",name:"password",fieldLabel:_("Password"),inputType:"password",width:220});this.proxyType.on("change",this.onFieldChange,this);this.proxyType.on("select",this.onTypeSelect,this);this.setting=false},getName:function(){return this.initialConfig.name},getValue:function(){return{type:this.proxyType.getValue(),hostname:this.hostname.getValue(),port:Number(this.port.getValue()),username:this.username.getValue(),password:this.password.getValue()}},setValue:function(c){this.setting=true;this.proxyType.setValue(c.type);var b=this.proxyType.getStore().find("id",c.type);var a=this.proxyType.getStore().getAt(b);this.hostname.setValue(c.hostname);this.port.setValue(c.port);this.username.setValue(c.username);this.password.setValue(c.password);this.onTypeSelect(this.type,a,b);this.setting=false},onFieldChange:function(e,d,c){if(this.setting){return}var b=this.getValue();var a=Ext.apply({},b);a[e.getName()]=c;this.fireEvent("change",this,b,a)},onTypeSelect:function(d,a,b){var c=a.get("id");if(c>0){this.hostname.show();this.port.show()}else{this.hostname.hide();this.port.hide()}if(c==3||c==5){this.username.show();this.password.show()}else{this.username.hide();this.password.hide()}}});
/*
* Deluge.preferences.ProxyPage.js
- *
+ *
* Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -925,7 +925,7 @@ Ext.ns("Deluge.preferences");Deluge.preferences.ProxyField=Ext.extend(Ext.form.F
* this exception statement from your version. If you delete this exception
* statement from all source files in the program, then also delete it here.
*/
-Ext.namespace("Deluge.preferences");Deluge.preferences.Proxy=Ext.extend(Ext.form.FormPanel,{constructor:function(a){a=Ext.apply({border:false,title:_("Proxy"),layout:"form"},a);Deluge.preferences.Proxy.superclass.constructor.call(this,a)},initComponent:function(){Deluge.preferences.Proxy.superclass.initComponent.call(this);this.peer=this.add(new Deluge.preferences.ProxyField({title:_("Peer"),name:"peer"}));this.peer.on("change",this.onProxyChange,this);this.web_seed=this.add(new Deluge.preferences.ProxyField({title:_("Web Seed"),name:"web_seed"}));this.web_seed.on("change",this.onProxyChange,this);this.tracker=this.add(new Deluge.preferences.ProxyField({title:_("Tracker"),name:"tracker"}));this.tracker.on("change",this.onProxyChange,this);this.dht=this.add(new Deluge.preferences.ProxyField({title:_("DHT"),name:"dht"}));this.dht.on("change",this.onProxyChange,this);deluge.preferences.getOptionsManager().bind("proxies",this)},getValue:function(){return{dht:this.dht.getValue(),peer:this.peer.getValue(),tracker:this.tracker.getValue(),web_seed:this.web_seed.getValue()}},setValue:function(b){for(var a in b){this[a].setValue(b[a])}},onProxyChange:function(e,d,c){var b=this.getValue();var a=Ext.apply({},b);a[e.getName()]=c;this.fireEvent("change",this,b,a)}});
+Ext.namespace("Deluge.preferences");Deluge.preferences.Proxy=Ext.extend(Ext.form.FormPanel,{constructor:function(a){a=Ext.apply({border:false,title:_("Proxy"),layout:"form",autoScroll:true},a);Deluge.preferences.Proxy.superclass.constructor.call(this,a)},initComponent:function(){Deluge.preferences.Proxy.superclass.initComponent.call(this);this.peer=this.add(new Deluge.preferences.ProxyField({title:_("Peer"),name:"peer"}));this.peer.on("change",this.onProxyChange,this);this.web_seed=this.add(new Deluge.preferences.ProxyField({title:_("Web Seed"),name:"web_seed"}));this.web_seed.on("change",this.onProxyChange,this);this.tracker=this.add(new Deluge.preferences.ProxyField({title:_("Tracker"),name:"tracker"}));this.tracker.on("change",this.onProxyChange,this);this.dht=this.add(new Deluge.preferences.ProxyField({title:_("DHT"),name:"dht"}));this.dht.on("change",this.onProxyChange,this);deluge.preferences.getOptionsManager().bind("proxies",this)},getValue:function(){return{dht:this.dht.getValue(),peer:this.peer.getValue(),tracker:this.tracker.getValue(),web_seed:this.web_seed.getValue()}},setValue:function(b){for(var a in b){this[a].setValue(b[a])}},onProxyChange:function(e,d,c){var b=this.getValue();var a=Ext.apply({},b);a[e.getName()]=c;this.fireEvent("change",this,b,a)}});
/*
* Deluge.preferences.QueuePage.js
*
@@ -1117,7 +1117,7 @@ Ext.ns("Deluge");Deluge.AddTrackerWindow=Ext.extend(Ext.Window,{title:_("Add Tra
* this exception statement from your version. If you delete this exception
* statement from all source files in the program, then also delete it here.
*/
-Ext.namespace("Ext.ux.util");Ext.ux.util.RpcClient=Ext.extend(Ext.util.Observable,{_components:[],_methods:[],_requests:{},_url:null,_optionKeys:["scope","success","failure"],constructor:function(a){Ext.ux.util.RpcClient.superclass.constructor.call(this,a);this._url=a.url||null;this._id=0;this.addEvents("connected","error");this.reloadMethods()},reloadMethods:function(){Ext.each(this._components,function(a){delete this[a]},this);this._execute("system.listMethods",{success:this._setMethods,scope:this})},_execute:function(c,a){a=a||{};a.params=a.params||[];a.id=this._id;var b=Ext.encode({method:c,params:a.params,id:a.id});this._id++;return Ext.Ajax.request({url:this._url,method:"POST",success:this._onSuccess,failure:this._onFailure,scope:this,jsonData:b,options:a})},_onFailure:function(b,a){var c=a.options;errorObj={id:c.id,result:null,error:{msg:"HTTP: "+b.status+" "+b.statusText,code:255}};this.fireEvent("error",errorObj,b,a);if(Ext.type(c.failure)!="function"){return}if(c.scope){c.failure.call(c.scope,errorObj,b,a)}else{c.failure(errorObj,b,a)}},_onSuccess:function(c,a){var b=Ext.decode(c.responseText);var d=a.options;if(b.error){this.fireEvent("error",b,c,a);if(Ext.type(d.failure)!="function"){return}if(d.scope){d.failure.call(d.scope,b,c,a)}else{d.failure(b,c,a)}}else{if(Ext.type(d.success)!="function"){return}if(d.scope){d.success.call(d.scope,b.result,b,c,a)}else{d.success(b.result,b,c,a)}}},_parseArgs:function(c){var e=[];Ext.each(c,function(f){e.push(f)});var b=e[e.length-1];if(Ext.type(b)=="object"){var d=Ext.keys(b),a=false;Ext.each(this._optionKeys,function(f){if(d.indexOf(f)>-1){a=true}});if(a){e.remove(b)}else{b={}}}else{b={}}b.params=e;return b},_setMethods:function(b){var d={},a=this;Ext.each(b,function(h){var g=h.split(".");var e=d[g[0]]||{};var f=function(){var i=a._parseArgs(arguments);return a._execute(h,i)};e[g[1]]=f;d[g[0]]=e});for(var c in d){a[c]=d[c]}this._components=Ext.keys(d);this.fireEvent("connected",this)}});
+Ext.namespace("Ext.ux.util");Ext.ux.util.RpcClient=Ext.extend(Ext.util.Observable,{_components:[],_methods:[],_requests:{},_url:null,_optionKeys:["scope","success","failure"],constructor:function(a){Ext.ux.util.RpcClient.superclass.constructor.call(this,a);this._url=a.url||null;this._id=0;this.addEvents("connected","error");this.reloadMethods()},reloadMethods:function(){this._execute("system.listMethods",{success:this._setMethods,scope:this})},_execute:function(c,a){a=a||{};a.params=a.params||[];a.id=this._id;var b=Ext.encode({method:c,params:a.params,id:a.id});this._id++;return Ext.Ajax.request({url:this._url,method:"POST",success:this._onSuccess,failure:this._onFailure,scope:this,jsonData:b,options:a})},_onFailure:function(b,a){var c=a.options;errorObj={id:c.id,result:null,error:{msg:"HTTP: "+b.status+" "+b.statusText,code:255}};this.fireEvent("error",errorObj,b,a);if(Ext.type(c.failure)!="function"){return}if(c.scope){c.failure.call(c.scope,errorObj,b,a)}else{c.failure(errorObj,b,a)}},_onSuccess:function(c,a){var b=Ext.decode(c.responseText);var d=a.options;if(b.error){this.fireEvent("error",b,c,a);if(Ext.type(d.failure)!="function"){return}if(d.scope){d.failure.call(d.scope,b,c,a)}else{d.failure(b,c,a)}}else{if(Ext.type(d.success)!="function"){return}if(d.scope){d.success.call(d.scope,b.result,b,c,a)}else{d.success(b.result,b,c,a)}}},_parseArgs:function(c){var e=[];Ext.each(c,function(f){e.push(f)});var b=e[e.length-1];if(Ext.type(b)=="object"){var d=Ext.keys(b),a=false;Ext.each(this._optionKeys,function(f){if(d.indexOf(f)>-1){a=true}});if(a){e.remove(b)}else{b={}}}else{b={}}b.params=e;return b},_setMethods:function(b){var d={},a=this;Ext.each(b,function(h){var g=h.split(".");var e=d[g[0]]||{};var f=function(){var i=a._parseArgs(arguments);return a._execute(h,i)};e[g[1]]=f;d[g[0]]=e});for(var c in d){a[c]=d[c]}Ext.each(this._components,function(e){if(!e in d){delete this[e]}},this);this._components=Ext.keys(d);this.fireEvent("connected",this)}});
/*
* Deluge.ConnectionManager.js
*
@@ -1277,7 +1277,7 @@ Ext.ns("Deluge");Deluge.EditTrackersWindow=Ext.extend(Ext.Window,{title:_("Edit
* this exception statement from your version. If you delete this exception
* statement from all source files in the program, then also delete it here.
*/
-Deluge.EventsManager=Ext.extend(Ext.util.Observable,{constructor:function(){this.toRegister=[];this.on("login",this.onLogin,this);Deluge.EventsManager.superclass.constructor.call(this)},addListener:function(a,c,b,d){this.addEvents(a);if(/[A-Z]/.test(a.substring(0,1))){if(!deluge.client){this.toRegister.push(a)}else{deluge.client.web.register_event_listener(a)}}Deluge.EventsManager.superclass.addListener.call(this,a,c,b,d)},getEvents:function(){deluge.client.web.get_events({success:this.onGetEventsSuccess,failure:this.onGetEventsFailure,scope:this})},start:function(){Ext.each(this.toRegister,function(a){deluge.client.web.register_event_listener(a)});this.running=true;this.errorCount=0;this.getEvents()},stop:function(){this.running=false},onLogin:function(){this.start()},onGetEventsSuccess:function(a){if(!a){return}Ext.each(a,function(d){var c=d[0],b=d[1];b.splice(0,0,c);this.fireEvent.apply(this,b)},this);if(this.running){this.getEvents()}},onGetEventsFailure:function(a,b){if(!this.running){return}if(!b.isTimeout&&this.errorCount++>=3){this.stop();return}this.getEvents()}});Deluge.EventsManager.prototype.on=Deluge.EventsManager.prototype.addListener;Deluge.EventsManager.prototype.fire=Deluge.EventsManager.prototype.fireEvent;deluge.events=new Deluge.EventsManager();
+Deluge.EventsManager=Ext.extend(Ext.util.Observable,{constructor:function(){this.toRegister=[];this.on("login",this.onLogin,this);Deluge.EventsManager.superclass.constructor.call(this)},addListener:function(a,c,b,d){this.addEvents(a);if(/[A-Z]/.test(a.substring(0,1))){if(!deluge.client){this.toRegister.push(a)}else{deluge.client.web.register_event_listener(a)}}Deluge.EventsManager.superclass.addListener.call(this,a,c,b,d)},getEvents:function(){deluge.client.web.get_events({success:this.onGetEventsSuccess,failure:this.onGetEventsFailure,scope:this})},start:function(){Ext.each(this.toRegister,function(a){deluge.client.web.register_event_listener(a)});this.running=true;this.errorCount=0;this.getEvents()},stop:function(){this.running=false},onLogin:function(){this.start()},onGetEventsSuccess:function(a){if(!this.running){return}if(a){Ext.each(a,function(d){var c=d[0],b=d[1];b.splice(0,0,c);this.fireEvent.apply(this,b)},this)}this.getEvents()},onGetEventsFailure:function(a,b){if(!this.running){return}if(!b.isTimeout&&this.errorCount++>=3){this.stop();return}this.getEvents()}});Deluge.EventsManager.prototype.on=Deluge.EventsManager.prototype.addListener;Deluge.EventsManager.prototype.fire=Deluge.EventsManager.prototype.fireEvent;deluge.events=new Deluge.EventsManager();
/*
* Deluge.FileBrowser.js
*
@@ -1408,7 +1408,7 @@ Ext.ns("Deluge");Deluge.FilterPanel=Ext.extend(Ext.Panel,{autoScroll:true,border
Deluge.Keys={Grid:["queue","name","total_size","state","progress","num_seeds","total_seeds","num_peers","total_peers","download_payload_rate","upload_payload_rate","eta","ratio","distributed_copies","is_auto_managed","time_added","tracker_host","save_path","last_seen_complete","total_done","total_uploaded","max_download_speed","max_upload_speed","seeds_peers_ratio"],Status:["total_done","total_payload_download","total_uploaded","total_payload_upload","next_announce","tracker_status","num_pieces","piece_length","is_auto_managed","active_time","seeding_time","seed_rank","last_seen_complete","owner","public","shared"],Files:["files","file_progress","file_priorities"],Peers:["peers"],Details:["name","save_path","total_size","num_files","message","tracker","comment"],Options:["max_download_speed","max_upload_speed","max_connections","max_upload_slots","is_auto_managed","stop_at_ratio","stop_ratio","remove_at_ratio","private","prioritize_first_last","move_completed","move_completed_path"]};Ext.each(Deluge.Keys.Grid,function(a){Deluge.Keys.Status.push(a)});
/*
* Deluge.LoginWindow.js
- *
+ *
* Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -1437,7 +1437,7 @@ Deluge.Keys={Grid:["queue","name","total_size","state","progress","num_seeds","t
* this exception statement from your version. If you delete this exception
* statement from all source files in the program, then also delete it here.
*/
-Deluge.LoginWindow=Ext.extend(Ext.Window,{firstShow:true,bodyStyle:"padding: 10px 5px;",buttonAlign:"center",closable:false,closeAction:"hide",iconCls:"x-deluge-login-window-icon",layout:"fit",modal:true,plain:true,resizable:false,title:_("Login"),width:300,height:120,initComponent:function(){Deluge.LoginWindow.superclass.initComponent.call(this);this.on("show",this.onShow,this);this.addButton({text:_("Login"),handler:this.onLogin,scope:this});this.form=this.add({xtype:"form",baseCls:"x-plain",labelWidth:55,width:300,defaults:{width:200},defaultType:"textfield"});this.passwordField=this.form.add({xtype:"textfield",fieldLabel:_("Password"),id:"_password",name:"password",inputType:"password"});this.passwordField.on("specialkey",this.onSpecialKey,this)},logout:function(){deluge.events.fire("logout");deluge.client.auth.delete_session({success:function(a){this.show(true)},scope:this})},show:function(a){if(this.firstShow){deluge.client.on("error",this.onClientError,this);this.firstShow=false}if(a){return Deluge.LoginWindow.superclass.show.call(this)}deluge.client.auth.check_session({success:function(b){if(b){deluge.events.fire("login")}else{this.show(true)}},failure:function(b){this.show(true)},scope:this})},onSpecialKey:function(b,a){if(a.getKey()==13){this.onLogin()}},onLogin:function(){var a=this.passwordField;deluge.client.auth.login(a.getValue(),{success:function(b){if(b){deluge.events.fire("login");this.hide();a.setRawValue("")}else{Ext.MessageBox.show({title:_("Login Failed"),msg:_("You entered an incorrect password"),buttons:Ext.MessageBox.OK,modal:false,fn:function(){a.focus(true,10)},icon:Ext.MessageBox.WARNING,iconCls:"x-deluge-icon-warning"})}},scope:this})},onClientError:function(c,b,a){if(c.error.code==1){deluge.events.fire("logout");this.show(true)}},onShow:function(){this.passwordField.focus(true,100)}});
+Deluge.LoginWindow=Ext.extend(Ext.Window,{firstShow:true,bodyStyle:"padding: 10px 5px;",buttonAlign:"center",closable:false,closeAction:"hide",iconCls:"x-deluge-login-window-icon",layout:"fit",modal:true,plain:true,resizable:false,title:_("Login"),width:300,height:120,initComponent:function(){Deluge.LoginWindow.superclass.initComponent.call(this);this.on("show",this.onShow,this);this.addButton({text:_("Login"),handler:this.onLogin,scope:this});this.form=this.add({xtype:"form",baseCls:"x-plain",labelWidth:120,labelAlign:"right",defaults:{width:110},defaultType:"textfield"});this.passwordField=this.form.add({xtype:"textfield",fieldLabel:_("Password"),grow:true,growMin:"110",growMax:"145",id:"_password",name:"password",inputType:"password"});this.passwordField.on("specialkey",this.onSpecialKey,this)},logout:function(){deluge.events.fire("logout");deluge.client.auth.delete_session({success:function(a){this.show(true)},scope:this})},show:function(a){if(this.firstShow){deluge.client.on("error",this.onClientError,this);this.firstShow=false}if(a){return Deluge.LoginWindow.superclass.show.call(this)}deluge.client.auth.check_session({success:function(b){if(b){deluge.events.fire("login")}else{this.show(true)}},failure:function(b){this.show(true)},scope:this})},onSpecialKey:function(b,a){if(a.getKey()==13){this.onLogin()}},onLogin:function(){var a=this.passwordField;deluge.client.auth.login(a.getValue(),{success:function(b){if(b){deluge.events.fire("login");this.hide();a.setRawValue("")}else{Ext.MessageBox.show({title:_("Login Failed"),msg:_("You entered an incorrect password"),buttons:Ext.MessageBox.OK,modal:false,fn:function(){a.focus(true,10)},icon:Ext.MessageBox.WARNING,iconCls:"x-deluge-icon-warning"})}},scope:this})},onClientError:function(c,b,a){if(c.error.code==1){deluge.events.fire("logout");this.show(true)}},onShow:function(){this.passwordField.focus(true,300)}});
/*
* Deluge.Menus.js
*
@@ -1469,7 +1469,7 @@ Deluge.LoginWindow=Ext.extend(Ext.Window,{firstShow:true,bodyStyle:"padding: 10p
* this exception statement from your version. If you delete this exception
* statement from all source files in the program, then also delete it here.
*/
-deluge.menus={onTorrentAction:function(b,d){var a=deluge.torrents.getSelectedIds();var c=b.initialConfig.torrentAction;switch(c){case"pause":case"resume":deluge.client.core[c+"_torrent"](a,{success:function(){deluge.ui.update()}});break;case"top":case"up":case"down":case"bottom":deluge.client.core["queue_"+c](a,{success:function(){deluge.ui.update()}});break;case"edit_trackers":deluge.editTrackers.show();break;case"update":deluge.client.core.force_reannounce(a,{success:function(){deluge.ui.update()}});break;case"remove":deluge.removeWindow.show(a);break;case"recheck":deluge.client.core.force_recheck(a,{success:function(){deluge.ui.update()}});break;case"move":deluge.moveStorage.show(a);break}}};deluge.menus.torrent=new Ext.menu.Menu({id:"torrentMenu",items:[{torrentAction:"pause",text:_("Pause"),iconCls:"icon-pause",handler:deluge.menus.onTorrentAction,scope:deluge.menus},{torrentAction:"resume",text:_("Resume"),iconCls:"icon-resume",handler:deluge.menus.onTorrentAction,scope:deluge.menus},"-",{text:_("Options"),iconCls:"icon-options",menu:new Ext.menu.Menu({items:[{text:_("D/L Speed Limit"),iconCls:"x-deluge-downloading",menu:new Ext.menu.Menu({items:[{text:_("5 KiB/s")},{text:_("10 KiB/s")},{text:_("30 KiB/s")},{text:_("80 KiB/s")},{text:_("300 KiB/s")},{text:_("Unlimited")}]})},{text:_("U/L Speed Limit"),iconCls:"x-deluge-seeding",menu:new Ext.menu.Menu({items:[{text:_("5 KiB/s")},{text:_("10 KiB/s")},{text:_("30 KiB/s")},{text:_("80 KiB/s")},{text:_("300 KiB/s")},{text:_("Unlimited")}]})},{text:_("Connection Limit"),iconCls:"x-deluge-connections",menu:new Ext.menu.Menu({items:[{text:_("50")},{text:_("100")},{text:_("200")},{text:_("300")},{text:_("500")},{text:_("Unlimited")}]})},{text:_("Upload Slot Limit"),iconCls:"icon-upload-slots",menu:new Ext.menu.Menu({items:[{text:_("0")},{text:_("1")},{text:_("2")},{text:_("3")},{text:_("5")},{text:_("Unlimited")}]})},{id:"auto_managed",text:_("Auto Managed"),checked:false}]})},"-",{text:_("Queue"),iconCls:"icon-queue",menu:new Ext.menu.Menu({items:[{torrentAction:"top",text:_("Top"),iconCls:"icon-top",handler:deluge.menus.onTorrentAction,scope:deluge.menus},{torrentAction:"up",text:_("Up"),iconCls:"icon-up",handler:deluge.menus.onTorrentAction,scope:deluge.menus},{torrentAction:"down",text:_("Down"),iconCls:"icon-down",handler:deluge.menus.onTorrentAction,scope:deluge.menus},{torrentAction:"bottom",text:_("Bottom"),iconCls:"icon-bottom",handler:deluge.menus.onTorrentAction,scope:deluge.menus}]})},"-",{torrentAction:"update",text:_("Update Tracker"),iconCls:"icon-update-tracker",handler:deluge.menus.onTorrentAction,scope:deluge.menus},{torrentAction:"edit_trackers",text:_("Edit Trackers"),iconCls:"icon-edit-trackers",handler:deluge.menus.onTorrentAction,scope:deluge.menus},"-",{torrentAction:"remove",text:_("Remove Torrent"),iconCls:"icon-remove",handler:deluge.menus.onTorrentAction,scope:deluge.menus},"-",{torrentAction:"recheck",text:_("Force Recheck"),iconCls:"icon-recheck",handler:deluge.menus.onTorrentAction,scope:deluge.menus},{torrentAction:"move",text:_("Move Storage"),iconCls:"icon-move",handler:deluge.menus.onTorrentAction,scope:deluge.menus}]});deluge.menus.filePriorities=new Ext.menu.Menu({id:"filePrioritiesMenu",items:[{id:"expandAll",text:_("Expand All"),iconCls:"icon-expand-all"},"-",{id:"no_download",text:_("Do Not Download"),iconCls:"icon-do-not-download",filePriority:FILE_PRIORITY["Do Not Download"]},{id:"normal",text:_("Normal Priority"),iconCls:"icon-normal",filePriority:FILE_PRIORITY["Normal Priority"]},{id:"high",text:_("High Priority"),iconCls:"icon-high",filePriority:FILE_PRIORITY["High Priority"]},{id:"highest",text:_("Highest Priority"),iconCls:"icon-highest",filePriority:FILE_PRIORITY["Highest Priority"]}]});
+deluge.menus={onTorrentAction:function(b,d){var a=deluge.torrents.getSelectedIds();var c=b.initialConfig.torrentAction;switch(c){case"pause":case"resume":deluge.client.core[c+"_torrent"](a,{success:function(){deluge.ui.update()}});break;case"top":case"up":case"down":case"bottom":deluge.client.core["queue_"+c](a,{success:function(){deluge.ui.update()}});break;case"edit_trackers":deluge.editTrackers.show();break;case"update":deluge.client.core.force_reannounce(a,{success:function(){deluge.ui.update()}});break;case"remove":deluge.removeWindow.show(a);break;case"recheck":deluge.client.core.force_recheck(a,{success:function(){deluge.ui.update()}});break;case"move":deluge.moveStorage.show(a);break}}};deluge.menus.torrent=new Ext.menu.Menu({id:"torrentMenu",items:[{torrentAction:"pause",text:_("Pause"),iconCls:"icon-pause",handler:deluge.menus.onTorrentAction,scope:deluge.menus},{torrentAction:"resume",text:_("Resume"),iconCls:"icon-resume",handler:deluge.menus.onTorrentAction,scope:deluge.menus},"-",{text:_("Options"),iconCls:"icon-options",hideOnClick:false,menu:new Ext.menu.Menu({items:[{text:_("D/L Speed Limit"),iconCls:"x-deluge-downloading",hideOnClick:false,menu:new Ext.menu.Menu({items:[{text:_("5 KiB/s")},{text:_("10 KiB/s")},{text:_("30 KiB/s")},{text:_("80 KiB/s")},{text:_("300 KiB/s")},{text:_("Unlimited")}]})},{text:_("U/L Speed Limit"),iconCls:"x-deluge-seeding",hideOnClick:false,menu:new Ext.menu.Menu({items:[{text:_("5 KiB/s")},{text:_("10 KiB/s")},{text:_("30 KiB/s")},{text:_("80 KiB/s")},{text:_("300 KiB/s")},{text:_("Unlimited")}]})},{text:_("Connection Limit"),iconCls:"x-deluge-connections",hideOnClick:false,menu:new Ext.menu.Menu({items:[{text:_("50")},{text:_("100")},{text:_("200")},{text:_("300")},{text:_("500")},{text:_("Unlimited")}]})},{text:_("Upload Slot Limit"),iconCls:"icon-upload-slots",hideOnClick:false,menu:new Ext.menu.Menu({items:[{text:_("0")},{text:_("1")},{text:_("2")},{text:_("3")},{text:_("5")},{text:_("Unlimited")}]})},{id:"auto_managed",text:_("Auto Managed"),checked:false}]})},"-",{text:_("Queue"),iconCls:"icon-queue",hideOnClick:false,menu:new Ext.menu.Menu({items:[{torrentAction:"top",text:_("Top"),iconCls:"icon-top",handler:deluge.menus.onTorrentAction,scope:deluge.menus},{torrentAction:"up",text:_("Up"),iconCls:"icon-up",handler:deluge.menus.onTorrentAction,scope:deluge.menus},{torrentAction:"down",text:_("Down"),iconCls:"icon-down",handler:deluge.menus.onTorrentAction,scope:deluge.menus},{torrentAction:"bottom",text:_("Bottom"),iconCls:"icon-bottom",handler:deluge.menus.onTorrentAction,scope:deluge.menus}]})},"-",{torrentAction:"update",text:_("Update Tracker"),iconCls:"icon-update-tracker",handler:deluge.menus.onTorrentAction,scope:deluge.menus},{torrentAction:"edit_trackers",text:_("Edit Trackers"),iconCls:"icon-edit-trackers",handler:deluge.menus.onTorrentAction,scope:deluge.menus},"-",{torrentAction:"remove",text:_("Remove Torrent"),iconCls:"icon-remove",handler:deluge.menus.onTorrentAction,scope:deluge.menus},"-",{torrentAction:"recheck",text:_("Force Recheck"),iconCls:"icon-recheck",handler:deluge.menus.onTorrentAction,scope:deluge.menus},{torrentAction:"move",text:_("Move Storage"),iconCls:"icon-move",handler:deluge.menus.onTorrentAction,scope:deluge.menus}]});deluge.menus.filePriorities=new Ext.menu.Menu({id:"filePrioritiesMenu",items:[{id:"expandAll",text:_("Expand All"),iconCls:"icon-expand-all"},"-",{id:"no_download",text:_("Do Not Download"),iconCls:"icon-do-not-download",filePriority:FILE_PRIORITY["Do Not Download"]},{id:"normal",text:_("Normal Priority"),iconCls:"icon-normal",filePriority:FILE_PRIORITY["Normal Priority"]},{id:"high",text:_("High Priority"),iconCls:"icon-high",filePriority:FILE_PRIORITY["High Priority"]},{id:"highest",text:_("Highest Priority"),iconCls:"icon-highest",filePriority:FILE_PRIORITY["Highest Priority"]}]});
/*
* Deluge.MoveStorage.js
*
@@ -1597,7 +1597,7 @@ Ext.ns("Deluge");Deluge.OtherLimitWindow=Ext.extend(Ext.Window,{layout:"fit",wid
* this exception statement from your version. If you delete this exception
* statement from all source files in the program, then also delete it here.
*/
-Ext.ns("Deluge");Deluge.Plugin=Ext.extend(Ext.util.Observable,{name:null,constructor:function(a){this.isDelugePlugin=true;this.addEvents({enabled:true,disabled:true});Deluge.Plugin.superclass.constructor.call(this,a)},disable:function(){this.fireEvent("disabled",this);if(this.onDisable){this.onDisable()}},enable:function(){this.fireEvent("enable",this);if(this.onEnable){this.onEnable()}},registerTorrentStatus:function(b,f,a){a=a||{};var e=a.colCfg||{},d=a.storeCfg||{};d=Ext.apply(d,{name:b});deluge.torrents.meta.fields.push(d);deluge.torrents.getStore().reader.onMetaChange(deluge.torrents.meta);e=Ext.apply(e,{header:f,dataIndex:b});var c=deluge.torrents.columns.slice(0);c.push(e);deluge.torrents.colModel.setConfig(c);deluge.torrents.columns=c;Deluge.Keys.Grid.push(b);deluge.torrents.getView().refresh(true)},deregisterTorrentStatus:function(b){var a=[];Ext.each(deluge.torrents.meta.fields,function(e){if(e.name!=b){a.push(e)}});deluge.torrents.meta.fields=a;deluge.torrents.getStore().reader.onMetaChange(deluge.torrents.meta);var d=[];Ext.each(deluge.torrents.columns,function(e){if(e.dataIndex!=b){d.push(e)}});deluge.torrents.colModel.setConfig(d);deluge.torrents.columns=d;var c=[];Ext.each(Deluge.Keys.Grid,function(e){if(e==b){c.push(e)}});Deluge.Keys.Grid=c;deluge.torrents.getView().refresh(true)}});Ext.ns("Deluge.plugins");
+Ext.ns("Deluge");Deluge.Plugin=Ext.extend(Ext.util.Observable,{name:null,constructor:function(a){this.isDelugePlugin=true;this.addEvents({enabled:true,disabled:true});Deluge.Plugin.superclass.constructor.call(this,a)},disable:function(){this.fireEvent("disabled",this);if(this.onDisable){this.onDisable()}},enable:function(){deluge.client.reloadMethods();this.fireEvent("enable",this);if(this.onEnable){this.onEnable()}},registerTorrentStatus:function(b,f,a){a=a||{};var e=a.colCfg||{},d=a.storeCfg||{};d=Ext.apply(d,{name:b});deluge.torrents.meta.fields.push(d);deluge.torrents.getStore().reader.onMetaChange(deluge.torrents.meta);e=Ext.apply(e,{header:f,dataIndex:b});var c=deluge.torrents.columns.slice(0);c.push(e);deluge.torrents.colModel.setConfig(c);deluge.torrents.columns=c;Deluge.Keys.Grid.push(b);deluge.torrents.getView().refresh(true)},deregisterTorrentStatus:function(b){var a=[];Ext.each(deluge.torrents.meta.fields,function(e){if(e.name!=b){a.push(e)}});deluge.torrents.meta.fields=a;deluge.torrents.getStore().reader.onMetaChange(deluge.torrents.meta);var d=[];Ext.each(deluge.torrents.columns,function(e){if(e.dataIndex!=b){d.push(e)}});deluge.torrents.colModel.setConfig(d);deluge.torrents.columns=d;var c=[];Ext.each(Deluge.Keys.Grid,function(e){if(e==b){c.push(e)}});Deluge.Keys.Grid=c;deluge.torrents.getView().refresh(true)}});Ext.ns("Deluge.plugins");
/*
* Deluge.RemoveWindow.js
*
@@ -1757,7 +1757,7 @@ Deluge.Toolbar=Ext.extend(Ext.Toolbar,{constructor:function(a){a=Ext.apply({item
* this exception statement from your version. If you delete this exception
* statement from all source files in the program, then also delete it here.
*/
-(function(){function c(l){return(l==-1)?"":l+1}function f(m,n,l){return String.format('<div class="torrent-name x-deluge-{0}">{1}</div>',l.data.state.toLowerCase(),m)}function g(l){if(!l){return}return fspeed(l)}function i(l){if(l==-1){return""}return fspeed(l*1024)}function k(q,s,o){q=new Number(q);var l=q;var t=o.data.state+" "+q.toFixed(2)+"%";if(this.style){var n=this.style}else{var n=s.style}var m=new Number(n.match(/\w+:\s*(\d+)\w+/)[1]);return Deluge.progressBar(q,m-8,t)}function a(m,n,l){if(l.data.total_seeds>-1){return String.format("{0} ({1})",m,l.data.total_seeds)}else{return m}}function e(m,n,l){if(l.data.total_peers>-1){return String.format("{0} ({1})",m,l.data.total_peers)}else{return m}}function b(m,n,l){return(m<0)?"&infin;":parseFloat(new Number(m).toFixed(3))}function d(m,n,l){return String.format('<div style="background: url('+deluge.config.base+'tracker/{0}) no-repeat; padding-left: 20px;">{0}</div>',m)}function h(l){return l*-1}function j(l){return l>0?fdate(l):"Never"}Deluge.TorrentGrid=Ext.extend(Ext.grid.GridPanel,{torrents:{},columns:[{id:"queue",header:_("#"),width:30,sortable:true,renderer:c,dataIndex:"queue"},{id:"name",header:_("Name"),width:150,sortable:true,renderer:f,dataIndex:"name"},{header:_("Size"),width:75,sortable:true,renderer:fsize,dataIndex:"total_size"},{header:_("Progress"),width:150,sortable:true,renderer:k,dataIndex:"progress"},{header:_("Seeders"),hidden:true,width:60,sortable:true,renderer:a,dataIndex:"num_seeds"},{header:_("Peers"),hidden:true,width:60,sortable:true,renderer:e,dataIndex:"num_peers"},{header:_("Down Speed"),width:80,sortable:true,renderer:g,dataIndex:"download_payload_rate"},{header:_("Up Speed"),width:80,sortable:true,renderer:g,dataIndex:"upload_payload_rate"},{header:_("ETA"),width:60,sortable:true,renderer:ftime,dataIndex:"eta"},{header:_("Ratio"),hidden:true,width:60,sortable:true,renderer:b,dataIndex:"ratio"},{header:_("Avail"),hidden:true,width:60,sortable:true,renderer:b,dataIndex:"distributed_copies"},{header:_("Added"),hidden:true,width:80,sortable:true,renderer:fdate,dataIndex:"time_added"},{header:_("Last Seen Complete"),width:80,sortable:true,renderer:j,dataIndex:"last_seen_complete"},{header:_("Tracker"),hidden:true,width:120,sortable:true,renderer:d,dataIndex:"tracker_host"},{header:_("Save Path"),hidden:true,width:120,sortable:true,renderer:fplain,dataIndex:"save_path"},{header:_("Owner"),width:80,sortable:true,renderer:fplain,dataIndex:"owner"},{header:_("Public"),hidden:true,width:80,sortable:true,renderer:fplain,dataIndex:"public"},{header:_("Shared"),hidden:true,width:80,sortable:true,renderer:fplain,dataIndex:"shared"},{header:_("Downloaded"),hidden:true,width:75,sortable:true,renderer:fsize,dataIndex:"total_done"},{header:_("Uploaded"),hidden:true,width:75,sortable:true,renderer:fsize,dataIndex:"total_uploaded"},{header:_("Down Limit"),hidden:true,width:75,sortable:true,renderer:i,dataIndex:"max_download_speed"},{header:_("Up Limit"),hidden:true,width:75,sortable:true,renderer:i,dataIndex:"max_upload_speed"},{header:_("Seeders")+"/"+_("Peers"),hidden:true,width:75,sortable:true,renderer:b,dataIndex:"seeds_peers_ratio"}],meta:{root:"torrents",idProperty:"id",fields:[{name:"queue",sortType:Deluge.data.SortTypes.asQueuePosition},{name:"name"},{name:"total_size",type:"int"},{name:"state"},{name:"progress",type:"float"},{name:"num_seeds",type:"int"},{name:"total_seeds",type:"int"},{name:"num_peers",type:"int"},{name:"total_peers",type:"int"},{name:"download_payload_rate",type:"int"},{name:"upload_payload_speed",type:"int"},{name:"eta",type:"int",sortType:h},{name:"ratio",type:"float"},{name:"distributed_copies",type:"float"},{name:"time_added",type:"int"},{name:"tracker_host"},{name:"save_path"},{name:"total_done",type:"int"},{name:"total_uploaded",type:"int"},{name:"max_download_speed",type:"int"},{name:"max_upload_speed",type:"int"},{name:"seeds_peers_ratio",type:"float"}]},keys:[{key:"a",ctrl:true,stopEvent:true,handler:function(){deluge.torrents.getSelectionModel().selectAll()}},{key:[46],stopEvent:true,handler:function(){ids=deluge.torrents.getSelectedIds();deluge.removeWindow.show(ids)}}],constructor:function(l){l=Ext.apply({id:"torrentGrid",store:new Ext.data.JsonStore(this.meta),columns:this.columns,keys:this.keys,region:"center",cls:"deluge-torrents",stripeRows:true,autoExpandColumn:"name",autoExpandMin:150,deferredRender:false,autoScroll:true,margins:"5 5 0 0",stateful:true,view:new Ext.ux.grid.BufferView({rowHeight:26,scrollDelay:false})},l);Deluge.TorrentGrid.superclass.constructor.call(this,l)},initComponent:function(){Deluge.TorrentGrid.superclass.initComponent.call(this);deluge.events.on("torrentRemoved",this.onTorrentRemoved,this);deluge.events.on("disconnect",this.onDisconnect,this);this.on("rowcontextmenu",function(l,o,n){n.stopEvent();var m=l.getSelectionModel();if(!m.hasSelection()){m.selectRow(o)}deluge.menus.torrent.showAt(n.getPoint())})},getTorrent:function(l){return this.getStore().getAt(l)},getSelected:function(){return this.getSelectionModel().getSelected()},getSelections:function(){return this.getSelectionModel().getSelections()},getSelectedId:function(){return this.getSelectionModel().getSelected().id},getSelectedIds:function(){var l=[];Ext.each(this.getSelectionModel().getSelections(),function(m){l.push(m.id)});return l},update:function(o,m){var q=this.getStore();if(m){q.removeAll();this.torrents={}}var p=[];for(var r in o){var u=o[r];if(this.torrents[r]){var n=q.getById(r);n.beginEdit();for(var l in u){if(n.get(l)!=u[l]){n.set(l,u[l])}}n.endEdit()}else{var n=new Deluge.data.Torrent(u);n.id=r;this.torrents[r]=1;p.push(n)}}q.add(p);q.each(function(t){if(!o[t.id]){q.remove(t);delete this.torrents[t.id]}},this);q.commitChanges();var s=q.getSortState();if(!s){return}q.sort(s.field,s.direction)},onDisconnect:function(){this.getStore().removeAll();this.torrents={}},onTorrentRemoved:function(m){var l=this.getSelectionModel();Ext.each(m,function(o){var n=this.getStore().getById(o);if(l.isSelected(n)){l.deselectRow(this.getStore().indexOf(n))}this.getStore().remove(n);delete this.torrents[o]},this)}});deluge.torrents=new Deluge.TorrentGrid()})();
+(function(){function c(l){return(l==-1)?"":l+1}function f(m,n,l){return String.format('<div class="torrent-name x-deluge-{0}">{1}</div>',l.data.state.toLowerCase(),m)}function g(l){if(!l){return}return fspeed(l)}function i(l){if(l==-1){return""}return fspeed(l*1024)}function k(q,s,o){q=new Number(q);var l=q;var t=o.data.state+" "+q.toFixed(2)+"%";if(this.style){var n=this.style}else{var n=s.style}var m=new Number(n.match(/\w+:\s*(\d+)\w+/)[1]);return Deluge.progressBar(q,m-8,t)}function a(m,n,l){if(l.data.total_seeds>-1){return String.format("{0} ({1})",m,l.data.total_seeds)}else{return m}}function e(m,n,l){if(l.data.total_peers>-1){return String.format("{0} ({1})",m,l.data.total_peers)}else{return m}}function b(m,n,l){return(m<0)?"&infin;":parseFloat(new Number(m).toFixed(3))}function d(m,n,l){return String.format('<div style="background: url('+deluge.config.base+'tracker/{0}) no-repeat; padding-left: 20px;">{0}</div>',m)}function h(l){return l*-1}function j(l){return l>0?fdate(l):"Never"}Deluge.TorrentGrid=Ext.extend(Ext.grid.GridPanel,{torrents:{},columns:[{id:"queue",header:_("#"),width:30,sortable:true,renderer:c,dataIndex:"queue"},{id:"name",header:_("Name"),width:150,sortable:true,renderer:f,dataIndex:"name"},{header:_("Size"),width:75,sortable:true,renderer:fsize,dataIndex:"total_size"},{header:_("Progress"),width:150,sortable:true,renderer:k,dataIndex:"progress"},{header:_("Seeders"),hidden:true,width:60,sortable:true,renderer:a,dataIndex:"num_seeds"},{header:_("Peers"),hidden:true,width:60,sortable:true,renderer:e,dataIndex:"num_peers"},{header:_("Down Speed"),width:80,sortable:true,renderer:g,dataIndex:"download_payload_rate"},{header:_("Up Speed"),width:80,sortable:true,renderer:g,dataIndex:"upload_payload_rate"},{header:_("ETA"),width:60,sortable:true,renderer:ftime,dataIndex:"eta"},{header:_("Ratio"),hidden:true,width:60,sortable:true,renderer:b,dataIndex:"ratio"},{header:_("Avail"),hidden:true,width:60,sortable:true,renderer:b,dataIndex:"distributed_copies"},{header:_("Added"),hidden:true,width:80,sortable:true,renderer:fdate,dataIndex:"time_added"},{header:_("Last Seen Complete"),width:80,sortable:true,renderer:j,dataIndex:"last_seen_complete"},{header:_("Tracker"),hidden:true,width:120,sortable:true,renderer:d,dataIndex:"tracker_host"},{header:_("Save Path"),hidden:true,width:120,sortable:true,renderer:fplain,dataIndex:"save_path"},{header:_("Owner"),width:80,sortable:true,renderer:fplain,dataIndex:"owner"},{header:_("Public"),hidden:true,width:80,sortable:true,renderer:fplain,dataIndex:"public"},{header:_("Shared"),hidden:true,width:80,sortable:true,renderer:fplain,dataIndex:"shared"},{header:_("Downloaded"),hidden:true,width:75,sortable:true,renderer:fsize,dataIndex:"total_done"},{header:_("Uploaded"),hidden:true,width:75,sortable:true,renderer:fsize,dataIndex:"total_uploaded"},{header:_("Down Limit"),hidden:true,width:75,sortable:true,renderer:i,dataIndex:"max_download_speed"},{header:_("Up Limit"),hidden:true,width:75,sortable:true,renderer:i,dataIndex:"max_upload_speed"},{header:_("Seeders")+"/"+_("Peers"),hidden:true,width:75,sortable:true,renderer:b,dataIndex:"seeds_peers_ratio"}],meta:{root:"torrents",idProperty:"id",fields:[{name:"queue",sortType:Deluge.data.SortTypes.asQueuePosition},{name:"name",sortType:Deluge.data.SortTypes.asName},{name:"total_size",type:"int"},{name:"state"},{name:"progress",type:"float"},{name:"num_seeds",type:"int"},{name:"total_seeds",type:"int"},{name:"num_peers",type:"int"},{name:"total_peers",type:"int"},{name:"download_payload_rate",type:"int"},{name:"upload_payload_rate",type:"int"},{name:"eta",type:"int",sortType:h},{name:"ratio",type:"float"},{name:"distributed_copies",type:"float"},{name:"time_added",type:"int"},{name:"tracker_host"},{name:"save_path"},{name:"total_done",type:"int"},{name:"total_uploaded",type:"int"},{name:"max_download_speed",type:"int"},{name:"max_upload_speed",type:"int"},{name:"seeds_peers_ratio",type:"float"}]},keys:[{key:"a",ctrl:true,stopEvent:true,handler:function(){deluge.torrents.getSelectionModel().selectAll()}},{key:[46],stopEvent:true,handler:function(){ids=deluge.torrents.getSelectedIds();deluge.removeWindow.show(ids)}}],constructor:function(l){l=Ext.apply({id:"torrentGrid",store:new Ext.data.JsonStore(this.meta),columns:this.columns,keys:this.keys,region:"center",cls:"deluge-torrents",stripeRows:true,autoExpandColumn:"name",autoExpandMin:150,deferredRender:false,autoScroll:true,margins:"5 5 0 0",stateful:true,view:new Ext.ux.grid.BufferView({rowHeight:26,scrollDelay:false})},l);Deluge.TorrentGrid.superclass.constructor.call(this,l)},initComponent:function(){Deluge.TorrentGrid.superclass.initComponent.call(this);deluge.events.on("torrentRemoved",this.onTorrentRemoved,this);deluge.events.on("disconnect",this.onDisconnect,this);this.on("rowcontextmenu",function(l,o,n){n.stopEvent();var m=l.getSelectionModel();if(!m.hasSelection()){m.selectRow(o)}deluge.menus.torrent.showAt(n.getPoint())})},getTorrent:function(l){return this.getStore().getAt(l)},getSelected:function(){return this.getSelectionModel().getSelected()},getSelections:function(){return this.getSelectionModel().getSelections()},getSelectedId:function(){return this.getSelectionModel().getSelected().id},getSelectedIds:function(){var l=[];Ext.each(this.getSelectionModel().getSelections(),function(m){l.push(m.id)});return l},update:function(o,m){var q=this.getStore();if(m){q.removeAll();this.torrents={}}var p=[];for(var r in o){var u=o[r];if(this.torrents[r]){var n=q.getById(r);n.beginEdit();for(var l in u){if(n.get(l)!=u[l]){n.set(l,u[l])}}n.endEdit()}else{var n=new Deluge.data.Torrent(u);n.id=r;this.torrents[r]=1;p.push(n)}}q.add(p);q.each(function(t){if(!o[t.id]){q.remove(t);delete this.torrents[t.id]}},this);q.commitChanges();var s=q.getSortState();if(!s){return}q.sort(s.field,s.direction)},onDisconnect:function(){this.getStore().removeAll();this.torrents={}},onTorrentRemoved:function(m){var l=this.getSelectionModel();Ext.each(m,function(o){var n=this.getStore().getById(o);if(l.isSelected(n)){l.deselectRow(this.getStore().indexOf(n))}this.getStore().remove(n);delete this.torrents[o]},this)}});deluge.torrents=new Deluge.TorrentGrid()})();
/*
* Deluge.UI.js
*
@@ -1789,4 +1789,4 @@ Deluge.Toolbar=Ext.extend(Ext.Toolbar,{constructor:function(a){a=Ext.apply({item
* this exception statement from your version. If you delete this exception
* statement from all source files in the program, then also delete it here.
*/
-deluge.ui={errorCount:0,filters:null,initialize:function(){deluge.add=new Deluge.add.AddWindow();deluge.details=new Deluge.details.DetailsPanel();deluge.connectionManager=new Deluge.ConnectionManager();deluge.editTrackers=new Deluge.EditTrackersWindow();deluge.login=new Deluge.LoginWindow();deluge.preferences=new Deluge.preferences.PreferencesWindow();deluge.sidebar=new Deluge.Sidebar();deluge.statusbar=new Deluge.Statusbar();deluge.toolbar=new Deluge.Toolbar();this.detailsPanel=new Ext.Panel({id:"detailsPanel",cls:"detailsPanel",region:"south",split:true,height:215,minSize:100,collapsible:true,margins:"0 5 5 5",cmargins:"0 5 5 5",layout:"fit",items:[deluge.details],});this.MainPanel=new Ext.Panel({id:"mainPanel",iconCls:"x-deluge-main-panel",layout:"border",border:false,tbar:deluge.toolbar,items:[deluge.sidebar,this.detailsPanel,deluge.torrents],bbar:deluge.statusbar});this.Viewport=new Ext.Viewport({layout:"fit",items:[this.MainPanel]});deluge.events.on("connect",this.onConnect,this);deluge.events.on("disconnect",this.onDisconnect,this);deluge.events.on("PluginDisabledEvent",this.onPluginDisabled,this);deluge.events.on("PluginEnabledEvent",this.onPluginEnabled,this);deluge.client=new Ext.ux.util.RpcClient({url:deluge.config.base+"json"});for(var a in Deluge.pluginStore){a=Deluge.createPlugin(a);a.enable();deluge.plugins[a.name]=a}Ext.QuickTips.init();deluge.client.on("connected",function(b){deluge.login.show()},this,{single:true});this.update=this.update.createDelegate(this);this.checkConnection=this.checkConnection.createDelegate(this);this.originalTitle=document.title},checkConnection:function(){deluge.client.web.connected({success:this.onConnectionSuccess,failure:this.onConnectionError,scope:this})},update:function(){var a=deluge.sidebar.getFilterStates();this.oldFilters=this.filters;this.filters=a;deluge.client.web.update_ui(Deluge.Keys.Grid,a,{success:this.onUpdate,failure:this.onUpdateError,scope:this});deluge.details.update()},onConnectionError:function(a){},onConnectionSuccess:function(a){deluge.statusbar.setStatus({iconCls:"x-deluge-statusbar icon-ok",text:_("Connection restored")});clearInterval(this.checking);if(!a){deluge.connectionManager.show()}},onUpdateError:function(a){if(this.errorCount==2){Ext.MessageBox.show({title:"Lost Connection",msg:"The connection to the webserver has been lost!",buttons:Ext.MessageBox.OK,icon:Ext.MessageBox.ERROR});deluge.events.fire("disconnect");deluge.statusbar.setStatus({text:"Lost connection to webserver"});this.checking=setInterval(this.checkConnection,2000)}this.errorCount++},onUpdate:function(a){if(!a.connected){deluge.connectionManager.disconnect(true);return}if(deluge.config.show_session_speed){document.title="D: "+fsize_short(a.stats.download_rate,true)+" U: "+fsize_short(a.stats.upload_rate,true)+" - "+this.originalTitle}if(Ext.areObjectsEqual(this.filters,this.oldFilters)){deluge.torrents.update(a.torrents)}else{deluge.torrents.update(a.torrents,true)}deluge.statusbar.update(a.stats);deluge.sidebar.update(a.filters);this.errorCount=0},onConnect:function(){if(!this.running){this.running=setInterval(this.update,2000);this.update()}deluge.client.web.get_plugins({success:this.onGotPlugins,scope:this})},onDisconnect:function(){this.stop()},onGotPlugins:function(a){Ext.each(a.enabled_plugins,function(b){if(deluge.plugins[b]){return}deluge.client.web.get_plugin_resources(b,{success:this.onGotPluginResources,scope:this})},this)},onPluginEnabled:function(a){if(deluge.plugins[a]){deluge.plugins[a].enable()}else{deluge.client.web.get_plugin_resources(a,{success:this.onGotPluginResources,scope:this})}},onGotPluginResources:function(b){var a=(Deluge.debug)?b.debug_scripts:b.scripts;Ext.each(a,function(c){Ext.ux.JSLoader({url:deluge.config.base+c,onLoad:this.onPluginLoaded,pluginName:b.name})},this)},onPluginDisabled:function(a){deluge.plugins[a].disable()},onPluginLoaded:function(a){if(!Deluge.hasPlugin(a.pluginName)){return}plugin=Deluge.createPlugin(a.pluginName);plugin.enable();deluge.plugins[plugin.name]=plugin},stop:function(){if(this.running){clearInterval(this.running);this.running=false;deluge.torrents.getStore().removeAll()}}};Ext.onReady(function(a){deluge.ui.initialize()}); \ No newline at end of file
+deluge.ui={errorCount:0,filters:null,initialize:function(){deluge.add=new Deluge.add.AddWindow();deluge.details=new Deluge.details.DetailsPanel();deluge.connectionManager=new Deluge.ConnectionManager();deluge.editTrackers=new Deluge.EditTrackersWindow();deluge.login=new Deluge.LoginWindow();deluge.preferences=new Deluge.preferences.PreferencesWindow();deluge.sidebar=new Deluge.Sidebar();deluge.statusbar=new Deluge.Statusbar();deluge.toolbar=new Deluge.Toolbar();this.detailsPanel=new Ext.Panel({id:"detailsPanel",cls:"detailsPanel",region:"south",split:true,height:215,minSize:100,collapsible:true,margins:"0 5 5 5",cmargins:"0 5 5 5",layout:"fit",items:[deluge.details],});this.MainPanel=new Ext.Panel({id:"mainPanel",iconCls:"x-deluge-main-panel",layout:"border",border:false,tbar:deluge.toolbar,items:[deluge.sidebar,this.detailsPanel,deluge.torrents],bbar:deluge.statusbar});this.Viewport=new Ext.Viewport({layout:"fit",items:[this.MainPanel]});deluge.events.on("connect",this.onConnect,this);deluge.events.on("disconnect",this.onDisconnect,this);deluge.events.on("PluginDisabledEvent",this.onPluginDisabled,this);deluge.events.on("PluginEnabledEvent",this.onPluginEnabled,this);deluge.client=new Ext.ux.util.RpcClient({url:deluge.config.base+"json"});for(var a in Deluge.pluginStore){a=Deluge.createPlugin(a);a.enable();deluge.plugins[a.name]=a}Ext.QuickTips.init();deluge.client.on("connected",function(b){deluge.login.show()},this,{single:true});this.update=this.update.createDelegate(this);this.checkConnection=this.checkConnection.createDelegate(this);this.originalTitle=document.title},checkConnection:function(){deluge.client.web.connected({success:this.onConnectionSuccess,failure:this.onConnectionError,scope:this})},update:function(){var a=deluge.sidebar.getFilterStates();this.oldFilters=this.filters;this.filters=a;deluge.client.web.update_ui(Deluge.Keys.Grid,a,{success:this.onUpdate,failure:this.onUpdateError,scope:this});deluge.details.update()},onConnectionError:function(a){},onConnectionSuccess:function(a){deluge.statusbar.setStatus({iconCls:"x-deluge-statusbar icon-ok",text:_("Connection restored")});clearInterval(this.checking);if(!a){deluge.connectionManager.show()}},onUpdateError:function(a){if(this.errorCount==2){Ext.MessageBox.show({title:"Lost Connection",msg:"The connection to the webserver has been lost!",buttons:Ext.MessageBox.OK,icon:Ext.MessageBox.ERROR});deluge.events.fire("disconnect");deluge.statusbar.setStatus({text:"Lost connection to webserver"});this.checking=setInterval(this.checkConnection,2000)}this.errorCount++},onUpdate:function(a){if(!a.connected){deluge.connectionManager.disconnect(true);return}if(deluge.config.show_session_speed){document.title="D: "+fsize_short(a.stats.download_rate,true)+" U: "+fsize_short(a.stats.upload_rate,true)+" - "+this.originalTitle}if(Ext.areObjectsEqual(this.filters,this.oldFilters)){deluge.torrents.update(a.torrents)}else{deluge.torrents.update(a.torrents,true)}deluge.statusbar.update(a.stats);deluge.sidebar.update(a.filters);this.errorCount=0},onConnect:function(){if(!this.running){this.running=setInterval(this.update,2000);this.update()}deluge.client.web.get_plugins({success:this.onGotPlugins,scope:this})},onDisconnect:function(){this.stop()},onGotPlugins:function(a){Ext.each(a.enabled_plugins,function(b){if(deluge.plugins[b]){return}deluge.client.web.get_plugin_resources(b,{success:this.onGotPluginResources,scope:this})},this)},onPluginEnabled:function(a){if(deluge.plugins[a]){deluge.plugins[a].enable()}else{deluge.client.web.get_plugin_resources(a,{success:this.onGotPluginResources,scope:this})}},onGotPluginResources:function(b){var a=(Deluge.debug)?b.debug_scripts:b.scripts;Ext.each(a,function(c){Ext.ux.JSLoader({url:deluge.config.base+c,onLoad:this.onPluginLoaded,pluginName:b.name})},this)},onPluginDisabled:function(a){if(deluge.plugins[a]){deluge.plugins[a].disable()}},onPluginLoaded:function(a){if(!Deluge.hasPlugin(a.pluginName)){return}plugin=Deluge.createPlugin(a.pluginName);plugin.enable();deluge.plugins[plugin.name]=plugin},stop:function(){if(this.running){clearInterval(this.running);this.running=false;deluge.torrents.getStore().removeAll()}}};Ext.onReady(function(a){deluge.ui.initialize()}); \ No newline at end of file
diff --git a/deluge/ui/web/js/deluge-all/Client.js b/deluge/ui/web/js/deluge-all/Client.js
index 658cf7127..979099bea 100644
--- a/deluge/ui/web/js/deluge-all/Client.js
+++ b/deluge/ui/web/js/deluge-all/Client.js
@@ -40,20 +40,20 @@ Ext.namespace('Ext.ux.util');
Ext.ux.util.RpcClient = Ext.extend(Ext.util.Observable, {
_components: [],
-
+
_methods: [],
-
+
_requests: {},
-
+
_url: null,
-
+
_optionKeys: ['scope', 'success', 'failure'],
-
+
constructor: function(config) {
Ext.ux.util.RpcClient.superclass.constructor.call(this, config);
this._url = config.url || null;
this._id = 0;
-
+
this.addEvents(
// raw events
/**
@@ -62,16 +62,13 @@ Ext.ux.util.RpcClient = Ext.extend(Ext.util.Observable, {
* @param {Ext.ux.util.RpcClient} this
*/
'connected',
-
+
'error'
);
this.reloadMethods();
},
-
+
reloadMethods: function() {
- Ext.each(this._components, function(component) {
- delete this[component];
- }, this);
this._execute('system.listMethods', {
success: this._setMethods,
scope: this
@@ -82,14 +79,14 @@ Ext.ux.util.RpcClient = Ext.extend(Ext.util.Observable, {
options = options || {};
options.params = options.params || [];
options.id = this._id;
-
+
var request = Ext.encode({
method: method,
params: options.params,
id: options.id
});
this._id++;
-
+
return Ext.Ajax.request({
url: this._url,
method: 'POST',
@@ -100,7 +97,7 @@ Ext.ux.util.RpcClient = Ext.extend(Ext.util.Observable, {
options: options
});
},
-
+
_onFailure: function(response, requestOptions) {
var options = requestOptions.options;
errorObj = {
@@ -111,23 +108,23 @@ Ext.ux.util.RpcClient = Ext.extend(Ext.util.Observable, {
code: 255
}
}
-
+
this.fireEvent('error', errorObj, response, requestOptions)
-
+
if (Ext.type(options.failure) != 'function') return;
if (options.scope) {
options.failure.call(options.scope, errorObj, response, requestOptions);
} else {
options.failure(errorObj, response, requestOptions);
- }
+ }
},
-
+
_onSuccess: function(response, requestOptions) {
var responseObj = Ext.decode(response.responseText);
var options = requestOptions.options;
if (responseObj.error) {
this.fireEvent('error', responseObj, response, requestOptions);
-
+
if (Ext.type(options.failure) != 'function') return;
if (options.scope) {
options.failure.call(options.scope, responseObj, response, requestOptions);
@@ -143,21 +140,21 @@ Ext.ux.util.RpcClient = Ext.extend(Ext.util.Observable, {
}
}
},
-
+
_parseArgs: function(args) {
var params = [];
Ext.each(args, function(arg) {
params.push(arg);
});
-
+
var options = params[params.length - 1];
if (Ext.type(options) == 'object') {
var keys = Ext.keys(options), isOption = false;
-
+
Ext.each(this._optionKeys, function(key) {
if (keys.indexOf(key) > -1) isOption = true;
});
-
+
if (isOption) {
params.remove(options)
} else {
@@ -172,11 +169,11 @@ Ext.ux.util.RpcClient = Ext.extend(Ext.util.Observable, {
_setMethods: function(methods) {
var components = {}, self = this;
-
+
Ext.each(methods, function(method) {
var parts = method.split('.');
var component = components[parts[0]] || {};
-
+
var fn = function() {
var options = self._parseArgs(arguments);
return self._execute(method, options);
@@ -184,11 +181,15 @@ Ext.ux.util.RpcClient = Ext.extend(Ext.util.Observable, {
component[parts[1]] = fn;
components[parts[0]] = component;
});
-
+
for (var name in components) {
self[name] = components[name];
}
-
+ Ext.each(this._components, function(component) {
+ if (!component in components) {
+ delete this[component];
+ }
+ }, this);
this._components = Ext.keys(components);
this.fireEvent('connected', this);
}
diff --git a/deluge/ui/web/js/deluge-all/EventsManager.js b/deluge/ui/web/js/deluge-all/EventsManager.js
index 9a799d53d..0204b3e7b 100644
--- a/deluge/ui/web/js/deluge-all/EventsManager.js
+++ b/deluge/ui/web/js/deluge-all/EventsManager.js
@@ -91,13 +91,15 @@ Deluge.EventsManager = Ext.extend(Ext.util.Observable, {
},
onGetEventsSuccess: function(events) {
- if (!events) return;
- Ext.each(events, function(event) {
- var name = event[0], args = event[1];
- args.splice(0, 0, name);
- this.fireEvent.apply(this, args);
- }, this);
- if (this.running) this.getEvents();
+ if (!this.running) return;
+ if (events) {
+ Ext.each(events, function(event) {
+ var name = event[0], args = event[1];
+ args.splice(0, 0, name);
+ this.fireEvent.apply(this, args);
+ }, this);
+ }
+ this.getEvents();
},
// private
diff --git a/deluge/ui/web/js/deluge-all/LoginWindow.js b/deluge/ui/web/js/deluge-all/LoginWindow.js
index de77fd78f..2946a0155 100644
--- a/deluge/ui/web/js/deluge-all/LoginWindow.js
+++ b/deluge/ui/web/js/deluge-all/LoginWindow.js
@@ -59,15 +59,18 @@ Deluge.LoginWindow = Ext.extend(Ext.Window, {
this.form = this.add({
xtype: 'form',
baseCls: 'x-plain',
- labelWidth: 55,
- width: 300,
- defaults: {width: 200},
+ labelWidth: 120,
+ labelAlign: 'right',
+ defaults: {width: 110},
defaultType: 'textfield'
});
this.passwordField = this.form.add({
xtype: 'textfield',
fieldLabel: _('Password'),
+ grow: true,
+ growMin: '110',
+ growMax: '145',
id: '_password',
name: 'password',
inputType: 'password'
diff --git a/deluge/ui/web/js/deluge-all/Menus.js b/deluge/ui/web/js/deluge-all/Menus.js
index c8430b615..87fab1777 100644
--- a/deluge/ui/web/js/deluge-all/Menus.js
+++ b/deluge/ui/web/js/deluge-all/Menus.js
@@ -98,10 +98,12 @@ deluge.menus.torrent = new Ext.menu.Menu({
}, '-', {
text: _('Options'),
iconCls: 'icon-options',
+ hideOnClick: false,
menu: new Ext.menu.Menu({
items: [{
text: _('D/L Speed Limit'),
iconCls: 'x-deluge-downloading',
+ hideOnClick: false,
menu: new Ext.menu.Menu({
items: [{
text: _('5 KiB/s')
@@ -120,6 +122,7 @@ deluge.menus.torrent = new Ext.menu.Menu({
}, {
text: _('U/L Speed Limit'),
iconCls: 'x-deluge-seeding',
+ hideOnClick: false,
menu: new Ext.menu.Menu({
items: [{
text: _('5 KiB/s')
@@ -138,6 +141,7 @@ deluge.menus.torrent = new Ext.menu.Menu({
}, {
text: _('Connection Limit'),
iconCls: 'x-deluge-connections',
+ hideOnClick: false,
menu: new Ext.menu.Menu({
items: [{
text: _('50')
@@ -156,6 +160,7 @@ deluge.menus.torrent = new Ext.menu.Menu({
}, {
text: _('Upload Slot Limit'),
iconCls: 'icon-upload-slots',
+ hideOnClick: false,
menu: new Ext.menu.Menu({
items: [{
text: _('0')
@@ -180,6 +185,7 @@ deluge.menus.torrent = new Ext.menu.Menu({
}, '-', {
text: _('Queue'),
iconCls: 'icon-queue',
+ hideOnClick: false,
menu: new Ext.menu.Menu({
items: [{
torrentAction: 'top',
diff --git a/deluge/ui/web/js/deluge-all/Plugin.js b/deluge/ui/web/js/deluge-all/Plugin.js
index 2453abe05..a3d544e85 100644
--- a/deluge/ui/web/js/deluge-all/Plugin.js
+++ b/deluge/ui/web/js/deluge-all/Plugin.js
@@ -76,6 +76,7 @@ Deluge.Plugin = Ext.extend(Ext.util.Observable, {
* then executes the plugins setup method, onEnabled.
*/
enable: function() {
+ deluge.client.reloadMethods();
this.fireEvent("enable", this);
if (this.onEnable) this.onEnable();
},
diff --git a/deluge/ui/web/js/deluge-all/TorrentGrid.js b/deluge/ui/web/js/deluge-all/TorrentGrid.js
index 4c41b06bc..50be33b03 100644
--- a/deluge/ui/web/js/deluge-all/TorrentGrid.js
+++ b/deluge/ui/web/js/deluge-all/TorrentGrid.js
@@ -265,7 +265,7 @@
idProperty: 'id',
fields: [
{name: 'queue', sortType: Deluge.data.SortTypes.asQueuePosition},
- {name: 'name'},
+ {name: 'name', sortType: Deluge.data.SortTypes.asName},
{name: 'total_size', type: 'int'},
{name: 'state'},
{name: 'progress', type: 'float'},
diff --git a/deluge/ui/web/js/deluge-all/UI.js b/deluge/ui/web/js/deluge-all/UI.js
index b4305c06f..08774afc2 100644
--- a/deluge/ui/web/js/deluge-all/UI.js
+++ b/deluge/ui/web/js/deluge-all/UI.js
@@ -256,7 +256,7 @@ deluge.ui = {
},
onPluginDisabled: function(pluginName) {
- deluge.plugins[pluginName].disable();
+ if (deluge.plugins[pluginName]) deluge.plugins[pluginName].disable();
},
onPluginLoaded: function(options) {
diff --git a/deluge/ui/web/js/deluge-all/add/FilesTab.js b/deluge/ui/web/js/deluge-all/add/FilesTab.js
index 3e624823d..709105b1b 100644
--- a/deluge/ui/web/js/deluge-all/add/FilesTab.js
+++ b/deluge/ui/web/js/deluge-all/add/FilesTab.js
@@ -1,6 +1,6 @@
/*!
* Deluge.add.FilesTab.js
- *
+ *
* Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -40,7 +40,7 @@ Deluge.add.FilesTab = Ext.extend(Ext.ux.tree.TreeGrid, {
layout: 'fit',
title: _('Files'),
- autoScroll: true,
+ autoScroll: false,
animate: false,
border: false,
disabled: true,
diff --git a/deluge/ui/web/js/deluge-all/add/OptionsPanel.js b/deluge/ui/web/js/deluge-all/add/OptionsPanel.js
index 629c46d85..466b0a0f0 100644
--- a/deluge/ui/web/js/deluge-all/add/OptionsPanel.js
+++ b/deluge/ui/web/js/deluge-all/add/OptionsPanel.js
@@ -39,7 +39,7 @@ Deluge.add.OptionsPanel = Ext.extend(Ext.TabPanel, {
region: 'south',
margins: '5 5 5 5',
activeTab: 0,
- height: 220,
+ height: 265,
initComponent: function() {
Deluge.add.OptionsPanel.superclass.initComponent.call(this);
diff --git a/deluge/ui/web/js/deluge-all/add/OptionsTab.js b/deluge/ui/web/js/deluge-all/add/OptionsTab.js
index c65dc6f40..04ee39fac 100644
--- a/deluge/ui/web/js/deluge-all/add/OptionsTab.js
+++ b/deluge/ui/web/js/deluge-all/add/OptionsTab.js
@@ -1,6 +1,6 @@
/*!
* Deluge.add.OptionsPanel.js
- *
+ *
* Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -60,14 +60,30 @@ Deluge.add.OptionsTab = Ext.extend(Ext.form.FormPanel, {
fieldLabel: '',
style: 'padding-bottom: 5px; margin-bottom: 0px;'
});
-
this.optionsManager.bind('download_location', fieldset.add({
fieldLabel: '',
name: 'download_location',
width: 400,
labelSeparator: ''
}));
-
+ var fieldset = this.add({
+ xtype: 'fieldset',
+ title: _('Move Completed Location'),
+ border: false,
+ autoHeight: true,
+ defaultType: 'togglefield',
+ labelWidth: 1,
+ fieldLabel: '',
+ style: 'padding-bottom: 5px; margin-bottom: 0px;'
+ });
+ var field = fieldset.add({
+ fieldLabel: '',
+ name: 'move_completed_path',
+ width: 425
+ });
+ this.optionsManager.bind('move_completed', field.toggle)
+ this.optionsManager.bind('move_completed_path', field.input)
+
var panel = this.add({
border: false,
layout: 'column',
@@ -77,8 +93,7 @@ Deluge.add.OptionsTab = Ext.extend(Ext.form.FormPanel, {
title: _('Allocation'),
border: false,
autoHeight: true,
- defaultType: 'radio',
- width: 100
+ defaultType: 'radio'
});
this.optionsManager.bind('compact_allocation', fieldset.add({
@@ -86,6 +101,7 @@ Deluge.add.OptionsTab = Ext.extend(Ext.form.FormPanel, {
columns: 1,
vertical: true,
labelSeparator: '',
+ width: 80,
items: [{
name: 'compact_allocation',
value: false,
@@ -107,35 +123,32 @@ Deluge.add.OptionsTab = Ext.extend(Ext.form.FormPanel, {
title: _('Bandwidth'),
border: false,
autoHeight: true,
- labelWidth: 100,
+ bodyStyle: 'margin-left: 7px',
+ labelWidth: 105,
width: 200,
defaultType: 'spinnerfield'
});
this.optionsManager.bind('max_download_speed', fieldset.add({
fieldLabel: _('Max Down Speed'),
- labelStyle: 'margin-left: 10px',
name: 'max_download_speed',
width: 60
}));
this.optionsManager.bind('max_upload_speed', fieldset.add({
fieldLabel: _('Max Up Speed'),
- labelStyle: 'margin-left: 10px',
name: 'max_upload_speed',
width: 60
}));
this.optionsManager.bind('max_connections', fieldset.add({
fieldLabel: _('Max Connections'),
- labelStyle: 'margin-left: 10px',
name: 'max_connections',
width: 60
}));
this.optionsManager.bind('max_upload_slots', fieldset.add({
fieldLabel: _('Max Upload Slots'),
- labelStyle: 'margin-left: 10px',
name: 'max_upload_slots',
width: 60
}));
-
+
fieldset = panel.add({
title: _('General'),
border: false,
@@ -159,6 +172,7 @@ Deluge.add.OptionsTab = Ext.extend(Ext.form.FormPanel, {
getDefaults: function() {
var keys = ['add_paused','compact_allocation','download_location',
'max_connections_per_torrent','max_download_speed_per_torrent',
+ 'move_completed', 'move_completed_path',
'max_upload_slots_per_torrent','max_upload_speed_per_torrent',
'prioritize_first_last_pieces'];
@@ -169,6 +183,8 @@ Deluge.add.OptionsTab = Ext.extend(Ext.form.FormPanel, {
'add_paused': config.add_paused,
'compact_allocation': config.compact_allocation,
'download_location': config.download_location,
+ 'move_completed': config.move_completed,
+ 'move_completed_path': config.move_completed_path,
'max_connections': config.max_connections_per_torrent,
'max_download_speed': config.max_download_speed_per_torrent,
'max_upload_slots': config.max_upload_slots_per_torrent,
diff --git a/deluge/ui/web/js/deluge-all/add/UrlWindow.js b/deluge/ui/web/js/deluge-all/add/UrlWindow.js
index 3aba36c1f..8a8a1c1de 100644
--- a/deluge/ui/web/js/deluge-all/add/UrlWindow.js
+++ b/deluge/ui/web/js/deluge-all/add/UrlWindow.js
@@ -81,7 +81,7 @@ Deluge.add.UrlWindow = Ext.extend(Deluge.add.Window, {
var cookies = this.cookieField.getValue();
var torrentId = this.createTorrentId();
- if (url.substring(0,20) == 'magnet:?xt=urn:btih:') {
+ if (url.indexOf('magnet:?') == 0 && url.indexOf('xt=urn:btih') > -1) {
deluge.client.web.get_magnet_info(url, {
success: this.onGotInfo,
scope: this,
diff --git a/deluge/ui/web/js/deluge-all/data/SortTypes.js b/deluge/ui/web/js/deluge-all/data/SortTypes.js
index e404ba348..3a6de182f 100644
--- a/deluge/ui/web/js/deluge-all/data/SortTypes.js
+++ b/deluge/ui/web/js/deluge-all/data/SortTypes.js
@@ -1,6 +1,6 @@
/*!
* Deluge.data.SortTypes.js
- *
+ *
* Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -39,7 +39,7 @@ Ext.namespace('Deluge.data');
*
* @class Deluge.data.SortTypes
* @singleton
- */
+ */
Deluge.data.SortTypes = {
asIPAddress: function(value) {
var d = value.match(/(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\:(\d+)/);
@@ -48,5 +48,9 @@ Deluge.data.SortTypes = {
asQueuePosition: function(value) {
return (value > -1) ? value : Number.MAX_VALUE;
+ },
+
+ asName: function(value) {
+ return String(value).toLowerCase();
}
}
diff --git a/deluge/ui/web/js/deluge-all/data/TorrentRecord.js b/deluge/ui/web/js/deluge-all/data/TorrentRecord.js
index d13806c14..f92cfc641 100644
--- a/deluge/ui/web/js/deluge-all/data/TorrentRecord.js
+++ b/deluge/ui/web/js/deluge-all/data/TorrentRecord.js
@@ -1,6 +1,6 @@
/*!
* Deluge.data.TorrentRecord.js
- *
+ *
* Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -47,7 +47,8 @@ Deluge.data.Torrent = Ext.data.Record.create([{
type: 'int'
}, {
name: 'name',
- type: 'string'
+ type: 'string',
+ sortType: Deluge.data.SortTypes.asName
}, {
name: 'total_size',
type: 'int'
diff --git a/deluge/ui/web/js/deluge-all/details/DetailsTab.js b/deluge/ui/web/js/deluge-all/details/DetailsTab.js
index ca41478d4..82d54f3bc 100644
--- a/deluge/ui/web/js/deluge-all/details/DetailsTab.js
+++ b/deluge/ui/web/js/deluge-all/details/DetailsTab.js
@@ -36,7 +36,7 @@ Deluge.details.DetailsTab = Ext.extend(Ext.Panel, {
title: _('Details'),
fields: {},
-
+ autoScroll: true,
queuedItems: {},
oldData: {},
diff --git a/deluge/ui/web/js/deluge-all/details/FilesTab.js b/deluge/ui/web/js/deluge-all/details/FilesTab.js
index 061ed7950..31ab79f55 100644
--- a/deluge/ui/web/js/deluge-all/details/FilesTab.js
+++ b/deluge/ui/web/js/deluge-all/details/FilesTab.js
@@ -1,6 +1,6 @@
/*!
* Deluge.details.FilesTab.js
- *
+ *
* Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -29,12 +29,11 @@
* this exception statement from your version. If you delete this exception
* statement from all source files in the program, then also delete it here.
*/
-
+
Deluge.details.FilesTab = Ext.extend(Ext.ux.tree.TreeGrid, {
title: _('Files'),
- autoScroll: true,
rootVisible: false,
columns: [{
@@ -74,7 +73,7 @@ Deluge.details.FilesTab = Ext.extend(Ext.ux.tree.TreeGrid, {
}
})
}],
-
+
selModel: new Ext.tree.MultiSelectionModel(),
initComponent: function() {
@@ -130,7 +129,7 @@ Deluge.details.FilesTab = Ext.extend(Ext.ux.tree.TreeGrid, {
this.clear();
this.torrentId = torrentId;
}
-
+
deluge.client.web.get_torrent_files(torrentId, {
success: this.onRequestComplete,
scope: this,
@@ -163,7 +162,7 @@ Deluge.details.FilesTab = Ext.extend(Ext.ux.tree.TreeGrid, {
folderSort: true
});
},
-
+
onContextMenu: function(node, e) {
e.stopEvent();
var selModel = this.getSelectionModel();
@@ -173,7 +172,7 @@ Deluge.details.FilesTab = Ext.extend(Ext.ux.tree.TreeGrid, {
}
deluge.menus.filePriorities.showAt(e.getPoint());
},
-
+
onItemClick: function(baseItem, e) {
switch (baseItem.id) {
case 'expandAll':
@@ -200,7 +199,7 @@ Deluge.details.FilesTab = Ext.extend(Ext.ux.tree.TreeGrid, {
return;
}
});
-
+
var priorities = new Array(Ext.keys(indexes).length);
for (var index in indexes) {
priorities[index] = indexes[index];
@@ -217,7 +216,7 @@ Deluge.details.FilesTab = Ext.extend(Ext.ux.tree.TreeGrid, {
break;
}
},
-
+
onRequestComplete: function(files, options) {
if (!this.getRootNode().hasChildNodes()) {
this.createFileTree(files);
diff --git a/deluge/ui/web/js/deluge-all/details/PeersTab.js b/deluge/ui/web/js/deluge-all/details/PeersTab.js
index bb45d6655..490c49ff4 100644
--- a/deluge/ui/web/js/deluge-all/details/PeersTab.js
+++ b/deluge/ui/web/js/deluge-all/details/PeersTab.js
@@ -35,7 +35,7 @@
if (!value.replace(' ', '').replace(' ', '')){
return '';
}
- return String.format('<img src="flag/{0}" />', value);
+ return String.format('<img src="{0}flag/{1}" />', deluge.config.base, value);
}
function peerAddressRenderer(value, p, record) {
var seed = (record.data['seed'] == 1024) ? 'x-deluge-seed' : 'x-deluge-peer';
diff --git a/deluge/ui/web/js/deluge-all/preferences/ProxyField.js b/deluge/ui/web/js/deluge-all/preferences/ProxyField.js
index 811372128..fe969b9ba 100644
--- a/deluge/ui/web/js/deluge-all/preferences/ProxyField.js
+++ b/deluge/ui/web/js/deluge-all/preferences/ProxyField.js
@@ -1,6 +1,6 @@
/*!
* Deluge.preferences.ProxyField.js
- *
+ *
* Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -58,19 +58,23 @@ Deluge.preferences.ProxyField = Ext.extend(Ext.form.FieldSet, {
[3, _('Socksv5 with Auth')],
[4, _('HTTP')],
[5, _('HTTP with Auth')]
- ]
- }),
+ ]
+ }),
editable: false,
triggerAction: 'all',
valueField: 'id',
displayField: 'text'
});
+ this.proxyType.on('change', this.onFieldChange, this);
+ this.proxyType.on('select', this.onTypeSelect, this);
+
this.hostname = this.add({
xtype: 'textfield',
name: 'hostname',
fieldLabel: _('Host'),
width: 220
});
+ this.hostname.on('change', this.onFieldChange, this);
this.port = this.add({
xtype: 'spinnerfield',
@@ -81,6 +85,7 @@ Deluge.preferences.ProxyField = Ext.extend(Ext.form.FieldSet, {
minValue: -1,
maxValue: 99999
});
+ this.port.on('change', this.onFieldChange, this);
this.username = this.add({
xtype: 'textfield',
@@ -88,6 +93,7 @@ Deluge.preferences.ProxyField = Ext.extend(Ext.form.FieldSet, {
fieldLabel: _('Username'),
width: 220
});
+ this.username.on('change', this.onFieldChange, this);
this.password = this.add({
xtype: 'textfield',
@@ -96,9 +102,8 @@ Deluge.preferences.ProxyField = Ext.extend(Ext.form.FieldSet, {
inputType: 'password',
width: 220
});
+ this.password.on('change', this.onFieldChange, this);
- this.proxyType.on('change', this.onFieldChange, this);
- this.proxyType.on('select', this.onTypeSelect, this);
this.setting = false;
},
diff --git a/deluge/ui/web/js/deluge-all/preferences/ProxyPage.js b/deluge/ui/web/js/deluge-all/preferences/ProxyPage.js
index db4740fb6..0cb61a439 100644
--- a/deluge/ui/web/js/deluge-all/preferences/ProxyPage.js
+++ b/deluge/ui/web/js/deluge-all/preferences/ProxyPage.js
@@ -1,6 +1,6 @@
/*!
* Deluge.preferences.ProxyPage.js
- *
+ *
* Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -40,11 +40,12 @@ Deluge.preferences.Proxy = Ext.extend(Ext.form.FormPanel, {
config = Ext.apply({
border: false,
title: _('Proxy'),
- layout: 'form'
+ layout: 'form',
+ autoScroll: true
}, config);
Deluge.preferences.Proxy.superclass.constructor.call(this, config);
},
-
+
initComponent: function() {
Deluge.preferences.Proxy.superclass.initComponent.call(this);
this.peer = this.add(new Deluge.preferences.ProxyField({
@@ -52,28 +53,28 @@ Deluge.preferences.Proxy = Ext.extend(Ext.form.FormPanel, {
name: 'peer'
}));
this.peer.on('change', this.onProxyChange, this);
-
+
this.web_seed = this.add(new Deluge.preferences.ProxyField({
title: _('Web Seed'),
name: 'web_seed'
}));
this.web_seed.on('change', this.onProxyChange, this);
-
+
this.tracker = this.add(new Deluge.preferences.ProxyField({
title: _('Tracker'),
name: 'tracker'
}));
this.tracker.on('change', this.onProxyChange, this);
-
+
this.dht = this.add(new Deluge.preferences.ProxyField({
title: _('DHT'),
name: 'dht'
}));
this.dht.on('change', this.onProxyChange, this);
-
+
deluge.preferences.getOptionsManager().bind('proxies', this);
},
-
+
getValue: function() {
return {
'dht': this.dht.getValue(),
@@ -82,18 +83,18 @@ Deluge.preferences.Proxy = Ext.extend(Ext.form.FormPanel, {
'web_seed': this.web_seed.getValue()
}
},
-
+
setValue: function(value) {
for (var proxy in value) {
this[proxy].setValue(value[proxy]);
}
},
-
+
onProxyChange: function(field, newValue, oldValue) {
var newValues = this.getValue();
var oldValues = Ext.apply({}, newValues);
oldValues[field.getName()] = oldValue;
-
+
this.fireEvent('change', this, newValues, oldValues);
}
});
diff --git a/deluge/ui/web/js/ext-extensions-debug.js b/deluge/ui/web/js/ext-extensions-debug.js
index ae3841c1a..365e7618d 100644
--- a/deluge/ui/web/js/ext-extensions-debug.js
+++ b/deluge/ui/web/js/ext-extensions-debug.js
@@ -1543,7 +1543,7 @@ Ext.override(Ext.ux.form.SpinnerField, {
});
/*!
* Ext.ux.form.SpinnerGroup.js
- *
+ *
* Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -1581,6 +1581,7 @@ Ext.ux.form.SpinnerGroup = Ext.extend(Ext.form.CheckboxGroup, {
// private
defaultType: 'spinnerfield',
+ anchor: '98%',
// private
groupCls: 'x-form-spinner-group',
@@ -1697,6 +1698,7 @@ Ext.ux.form.SpinnerGroup = Ext.extend(Ext.form.CheckboxGroup, {
this.items.each(function(field) {
field.on('spin', this.onFieldChange, this);
+ field.on('change', this.onFieldChange, this);
}, this);
if (this.lazyValueSet) {
diff --git a/deluge/ui/web/js/ext-extensions.js b/deluge/ui/web/js/ext-extensions.js
index e77e6e257..be6f182cb 100644
--- a/deluge/ui/web/js/ext-extensions.js
+++ b/deluge/ui/web/js/ext-extensions.js
@@ -191,7 +191,7 @@ Ext.ns("Ext.ux.form");Ext.ux.form.SpinnerField=Ext.extend(Ext.form.NumberField,{
Ext.override(Ext.ux.form.SpinnerField,{onBlur:Ext.form.Field.prototype.onBlur});
/*
* Ext.ux.form.SpinnerGroup.js
- *
+ *
* Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -220,7 +220,7 @@ Ext.override(Ext.ux.form.SpinnerField,{onBlur:Ext.form.Field.prototype.onBlur});
* this exception statement from your version. If you delete this exception
* statement from all source files in the program, then also delete it here.
*/
-Ext.ns("Ext.ux.form");Ext.ux.form.SpinnerGroup=Ext.extend(Ext.form.CheckboxGroup,{defaultType:"spinnerfield",groupCls:"x-form-spinner-group",colCfg:{},onRender:function(h,f){if(!this.el){var o={cls:this.groupCls,layout:"column",border:false,renderTo:h};var a=Ext.apply({defaultType:this.defaultType,layout:"form",border:false,labelWidth:60,defaults:{hideLabel:true,anchor:"60%"}},this.colCfg);if(this.items[0].items){Ext.apply(o,{layoutConfig:{columns:this.items.length},defaults:this.defaults,items:this.items});for(var e=0,k=this.items.length;e<k;e++){Ext.applyIf(this.items[e],a)}}else{var d,m=[];if(typeof this.columns=="string"){this.columns=this.items.length}if(!Ext.isArray(this.columns)){var j=[];for(var e=0;e<this.columns;e++){j.push((100/this.columns)*0.01)}this.columns=j}d=this.columns.length;for(var e=0;e<d;e++){var b=Ext.apply({items:[]},a);b[this.columns[e]<=1?"columnWidth":"width"]=this.columns[e];if(this.defaults){b.defaults=Ext.apply(b.defaults||{},this.defaults)}m.push(b)}if(this.vertical){var q=Math.ceil(this.items.length/d),n=0;for(var e=0,k=this.items.length;e<k;e++){if(e>0&&e%q==0){n++}if(this.items[e].fieldLabel){this.items[e].hideLabel=false}m[n].items.push(this.items[e])}}else{for(var e=0,k=this.items.length;e<k;e++){var p=e%d;if(this.items[e].fieldLabel){this.items[e].hideLabel=false}m[p].items.push(this.items[e])}}Ext.apply(o,{layoutConfig:{columns:d},items:m})}this.panel=new Ext.Panel(o);this.el=this.panel.getEl();if(this.forId&&this.itemCls){var c=this.el.up(this.itemCls).child("label",true);if(c){c.setAttribute("htmlFor",this.forId)}}var g=this.panel.findBy(function(l){return l.isFormField},this);this.items=new Ext.util.MixedCollection();this.items.addAll(g);this.items.each(function(l){l.on("spin",this.onFieldChange,this)},this);if(this.lazyValueSet){this.setValue(this.value);delete this.value;delete this.lazyValueSet}if(this.lazyRawValueSet){this.setRawValue(this.rawValue);delete this.rawValue;delete this.lazyRawValueSet}}Ext.ux.form.SpinnerGroup.superclass.onRender.call(this,h,f)},onFieldChange:function(a){this.fireEvent("change",this,this.getValue())},initValue:Ext.emptyFn,getValue:function(){var a=[this.items.getCount()];this.items.each(function(c,b){a[b]=Number(c.getValue())});return a},getRawValue:function(){var a=[this.items.getCount()];this.items.each(function(c,b){a[b]=Number(c.getRawValue())});return a},setValue:function(a){if(!this.rendered){this.value=a;this.lazyValueSet=true}else{this.items.each(function(c,b){c.setValue(a[b])})}},setRawValue:function(a){if(!this.rendered){this.rawValue=a;this.lazyRawValueSet=true}else{this.items.each(function(c,b){c.setRawValue(a[b])})}}});Ext.reg("spinnergroup",Ext.ux.form.SpinnerGroup);
+Ext.ns("Ext.ux.form");Ext.ux.form.SpinnerGroup=Ext.extend(Ext.form.CheckboxGroup,{defaultType:"spinnerfield",anchor:"98%",groupCls:"x-form-spinner-group",colCfg:{},onRender:function(h,f){if(!this.el){var o={cls:this.groupCls,layout:"column",border:false,renderTo:h};var a=Ext.apply({defaultType:this.defaultType,layout:"form",border:false,labelWidth:60,defaults:{hideLabel:true,anchor:"60%"}},this.colCfg);if(this.items[0].items){Ext.apply(o,{layoutConfig:{columns:this.items.length},defaults:this.defaults,items:this.items});for(var e=0,k=this.items.length;e<k;e++){Ext.applyIf(this.items[e],a)}}else{var d,m=[];if(typeof this.columns=="string"){this.columns=this.items.length}if(!Ext.isArray(this.columns)){var j=[];for(var e=0;e<this.columns;e++){j.push((100/this.columns)*0.01)}this.columns=j}d=this.columns.length;for(var e=0;e<d;e++){var b=Ext.apply({items:[]},a);b[this.columns[e]<=1?"columnWidth":"width"]=this.columns[e];if(this.defaults){b.defaults=Ext.apply(b.defaults||{},this.defaults)}m.push(b)}if(this.vertical){var q=Math.ceil(this.items.length/d),n=0;for(var e=0,k=this.items.length;e<k;e++){if(e>0&&e%q==0){n++}if(this.items[e].fieldLabel){this.items[e].hideLabel=false}m[n].items.push(this.items[e])}}else{for(var e=0,k=this.items.length;e<k;e++){var p=e%d;if(this.items[e].fieldLabel){this.items[e].hideLabel=false}m[p].items.push(this.items[e])}}Ext.apply(o,{layoutConfig:{columns:d},items:m})}this.panel=new Ext.Panel(o);this.el=this.panel.getEl();if(this.forId&&this.itemCls){var c=this.el.up(this.itemCls).child("label",true);if(c){c.setAttribute("htmlFor",this.forId)}}var g=this.panel.findBy(function(l){return l.isFormField},this);this.items=new Ext.util.MixedCollection();this.items.addAll(g);this.items.each(function(l){l.on("spin",this.onFieldChange,this);l.on("change",this.onFieldChange,this)},this);if(this.lazyValueSet){this.setValue(this.value);delete this.value;delete this.lazyValueSet}if(this.lazyRawValueSet){this.setRawValue(this.rawValue);delete this.rawValue;delete this.lazyRawValueSet}}Ext.ux.form.SpinnerGroup.superclass.onRender.call(this,h,f)},onFieldChange:function(a){this.fireEvent("change",this,this.getValue())},initValue:Ext.emptyFn,getValue:function(){var a=[this.items.getCount()];this.items.each(function(c,b){a[b]=Number(c.getValue())});return a},getRawValue:function(){var a=[this.items.getCount()];this.items.each(function(c,b){a[b]=Number(c.getRawValue())});return a},setValue:function(a){if(!this.rendered){this.value=a;this.lazyValueSet=true}else{this.items.each(function(c,b){c.setValue(a[b])})}},setRawValue:function(a){if(!this.rendered){this.rawValue=a;this.lazyRawValueSet=true}else{this.items.each(function(c,b){c.setRawValue(a[b])})}}});Ext.reg("spinnergroup",Ext.ux.form.SpinnerGroup);
/*
* Ext.ux.form.ToggleField.js
*
diff --git a/deluge/ui/web/js/ext-extensions/form/SpinnerGroup.js b/deluge/ui/web/js/ext-extensions/form/SpinnerGroup.js
index 7e042fb5a..4ad3a7bf1 100644
--- a/deluge/ui/web/js/ext-extensions/form/SpinnerGroup.js
+++ b/deluge/ui/web/js/ext-extensions/form/SpinnerGroup.js
@@ -1,6 +1,6 @@
/*!
* Ext.ux.form.SpinnerGroup.js
- *
+ *
* Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -38,6 +38,7 @@ Ext.ux.form.SpinnerGroup = Ext.extend(Ext.form.CheckboxGroup, {
// private
defaultType: 'spinnerfield',
+ anchor: '98%',
// private
groupCls: 'x-form-spinner-group',
@@ -154,6 +155,7 @@ Ext.ux.form.SpinnerGroup = Ext.extend(Ext.form.CheckboxGroup, {
this.items.each(function(field) {
field.on('spin', this.onFieldChange, this);
+ field.on('change', this.onFieldChange, this);
}, this);
if (this.lazyValueSet) {
diff --git a/deluge/ui/web/json_api.py b/deluge/ui/web/json_api.py
index 8b0fc9473..4febab156 100644
--- a/deluge/ui/web/json_api.py
+++ b/deluge/ui/web/json_api.py
@@ -115,49 +115,47 @@ class JSON(resource.Resource, component.Component):
self._remote_methods = []
self._local_methods = {}
if client.is_classicmode():
- def on_got_methods(methods):
- """
- Handles receiving the method names
- """
- self._remote_methods = methods
-
- client.daemon.get_method_list().addCallback(on_got_methods)
+ self.get_remote_methods()
else:
client.disconnect_callback = self._on_client_disconnect
+ def on_get_methods(self, methods):
+ """
+ Handles receiving the method names.
+ """
+ self._remote_methods = methods
+
+ def get_remote_methods(self, result=None):
+ """
+ Updates remote methods from the daemon.
+ """
+ return client.daemon.get_method_list().addCallback(self.on_get_methods)
+
def connect(self, host="localhost", port=58846, username="", password=""):
"""
Connects the client to a daemon
"""
- d = Deferred()
- _d = client.connect(host, port, username, password)
-
- def on_get_methods(methods):
- """
- Handles receiving the method names
- """
- self._remote_methods = methods
- methods = list(self._remote_methods)
- methods.extend(self._local_methods)
- d.callback(methods)
+ d = client.connect(host, port, username, password)
def on_client_connected(connection_id):
"""
Handles the client successfully connecting to the daemon and
invokes retrieving the method names.
"""
- d = client.daemon.get_method_list()
- d.addCallback(on_get_methods)
+ d = self.get_remote_methods()
component.get("Web.PluginManager").start()
component.get("Web").start()
- _d.addCallback(on_client_connected)
- return d
+ return d
+
+ return d.addCallback(on_client_connected)
def disable(self):
if not client.is_classicmode():
client.disconnect()
def enable(self):
+ client.register_event_handler("PluginEnabledEvent", self.get_remote_methods)
+ client.register_event_handler("PluginDisabledEvent", self.get_remote_methods)
if component.get("DelugeWeb").config["default_daemon"]:
# Sort out getting the default daemon here
default = component.get("DelugeWeb").config["default_daemon"]
@@ -722,24 +720,29 @@ class WebApi(JSONComponent):
:rtype: dictionary
"""
- try:
- s = uri.split("&")[0][20:]
- if len(s) == 32:
- info_hash = base64.b32decode(s).encode("hex")
- elif len(s) == 40:
- info_hash = s
- else:
- return False
+ magnet_scheme = 'magnet:?'
+ xt_param = 'xt=urn:btih:'
+ dn_param = 'dn='
+ if uri.startswith(magnet_scheme):
name = None
- for i in uri.split("&")[1:]:
- if i[:3] == "dn=":
- name = unquote_plus(i.split("=")[1])
- if not name:
- name = info_hash
- return {"name":name, "info_hash":info_hash, "files_tree":''}
- except Exception, e:
- log.exception(e)
- return False
+ info_hash = None
+ for param in uri[len(magnet_scheme):].split('&'):
+ if param.startswith(xt_param):
+ xt_hash = param[len(xt_param):]
+ if len(xt_hash) == 32:
+ info_hash = base64.b32decode(xt_hash).encode("hex")
+ elif len(xt_hash) == 40:
+ info_hash = xt_hash
+ else:
+ break
+ elif param.startswith(dn_param):
+ name = unquote_plus(param[len(dn_param):])
+
+ if info_hash:
+ if not name:
+ name = info_hash
+ return {"name":name, "info_hash":info_hash, "files_tree":''}
+ return False
@export
def add_torrents(self, torrents):
@@ -754,7 +757,7 @@ class WebApi(JSONComponent):
>>> json_api.web.add_torrents([{
"path": "/tmp/deluge-web/some-torrent-file.torrent",
- "options": {"download_path": "/home/deluge/"}
+ "options": {"download_location": "/home/deluge/"}
}])
"""
diff --git a/deluge/ui/web/themes/images/vista/basic-dialog/bg-center.gif b/deluge/ui/web/themes/images/vista/basic-dialog/bg-center.gif
deleted file mode 100644
index 7bf4a4b41..000000000
--- a/deluge/ui/web/themes/images/vista/basic-dialog/bg-center.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/vista/basic-dialog/bg-left.gif b/deluge/ui/web/themes/images/vista/basic-dialog/bg-left.gif
deleted file mode 100644
index 94b1dafc7..000000000
--- a/deluge/ui/web/themes/images/vista/basic-dialog/bg-left.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/vista/basic-dialog/bg-right.gif b/deluge/ui/web/themes/images/vista/basic-dialog/bg-right.gif
deleted file mode 100644
index 6dadaf683..000000000
--- a/deluge/ui/web/themes/images/vista/basic-dialog/bg-right.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/vista/basic-dialog/close.gif b/deluge/ui/web/themes/images/vista/basic-dialog/close.gif
deleted file mode 100644
index 4278db983..000000000
--- a/deluge/ui/web/themes/images/vista/basic-dialog/close.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/vista/basic-dialog/collapse.gif b/deluge/ui/web/themes/images/vista/basic-dialog/collapse.gif
deleted file mode 100644
index b07e297e5..000000000
--- a/deluge/ui/web/themes/images/vista/basic-dialog/collapse.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/vista/basic-dialog/dlg-bg.gif b/deluge/ui/web/themes/images/vista/basic-dialog/dlg-bg.gif
deleted file mode 100644
index 1a466633d..000000000
--- a/deluge/ui/web/themes/images/vista/basic-dialog/dlg-bg.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/vista/basic-dialog/e-handle.gif b/deluge/ui/web/themes/images/vista/basic-dialog/e-handle.gif
deleted file mode 100644
index 48877e748..000000000
--- a/deluge/ui/web/themes/images/vista/basic-dialog/e-handle.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/vista/basic-dialog/expand.gif b/deluge/ui/web/themes/images/vista/basic-dialog/expand.gif
deleted file mode 100644
index 5b4b0d1e9..000000000
--- a/deluge/ui/web/themes/images/vista/basic-dialog/expand.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/vista/basic-dialog/hd-sprite.gif b/deluge/ui/web/themes/images/vista/basic-dialog/hd-sprite.gif
deleted file mode 100644
index 3c2dd632d..000000000
--- a/deluge/ui/web/themes/images/vista/basic-dialog/hd-sprite.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/vista/basic-dialog/s-handle.gif b/deluge/ui/web/themes/images/vista/basic-dialog/s-handle.gif
deleted file mode 100644
index c13c9cdc0..000000000
--- a/deluge/ui/web/themes/images/vista/basic-dialog/s-handle.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/vista/basic-dialog/se-handle.gif b/deluge/ui/web/themes/images/vista/basic-dialog/se-handle.gif
deleted file mode 100644
index c4e38a2f4..000000000
--- a/deluge/ui/web/themes/images/vista/basic-dialog/se-handle.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/vista/basic-dialog/w-handle.gif b/deluge/ui/web/themes/images/vista/basic-dialog/w-handle.gif
deleted file mode 100644
index d59eafc20..000000000
--- a/deluge/ui/web/themes/images/vista/basic-dialog/w-handle.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/vista/gradient-bg.gif b/deluge/ui/web/themes/images/vista/gradient-bg.gif
deleted file mode 100644
index 8134e4994..000000000
--- a/deluge/ui/web/themes/images/vista/gradient-bg.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/vista/grid/grid-split.gif b/deluge/ui/web/themes/images/vista/grid/grid-split.gif
deleted file mode 100644
index c76a16e95..000000000
--- a/deluge/ui/web/themes/images/vista/grid/grid-split.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/vista/grid/grid-vista-hd.gif b/deluge/ui/web/themes/images/vista/grid/grid-vista-hd.gif
deleted file mode 100644
index d0972638e..000000000
--- a/deluge/ui/web/themes/images/vista/grid/grid-vista-hd.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/vista/layout/collapse.gif b/deluge/ui/web/themes/images/vista/layout/collapse.gif
deleted file mode 100644
index cbd6e081c..000000000
--- a/deluge/ui/web/themes/images/vista/layout/collapse.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/vista/layout/expand.gif b/deluge/ui/web/themes/images/vista/layout/expand.gif
deleted file mode 100644
index 8103c0dd7..000000000
--- a/deluge/ui/web/themes/images/vista/layout/expand.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/vista/layout/gradient-bg.gif b/deluge/ui/web/themes/images/vista/layout/gradient-bg.gif
deleted file mode 100644
index d311e7de6..000000000
--- a/deluge/ui/web/themes/images/vista/layout/gradient-bg.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/vista/layout/ns-collapse.gif b/deluge/ui/web/themes/images/vista/layout/ns-collapse.gif
deleted file mode 100644
index f2ad235da..000000000
--- a/deluge/ui/web/themes/images/vista/layout/ns-collapse.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/vista/layout/ns-expand.gif b/deluge/ui/web/themes/images/vista/layout/ns-expand.gif
deleted file mode 100644
index 0817ec66f..000000000
--- a/deluge/ui/web/themes/images/vista/layout/ns-expand.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/vista/layout/panel-close.gif b/deluge/ui/web/themes/images/vista/layout/panel-close.gif
deleted file mode 100644
index 4e96481a1..000000000
--- a/deluge/ui/web/themes/images/vista/layout/panel-close.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/vista/layout/panel-title-bg.gif b/deluge/ui/web/themes/images/vista/layout/panel-title-bg.gif
deleted file mode 100644
index 681f517a3..000000000
--- a/deluge/ui/web/themes/images/vista/layout/panel-title-bg.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/vista/layout/panel-title-light-bg.gif b/deluge/ui/web/themes/images/vista/layout/panel-title-light-bg.gif
deleted file mode 100644
index 23d8288b0..000000000
--- a/deluge/ui/web/themes/images/vista/layout/panel-title-light-bg.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/vista/layout/stick.gif b/deluge/ui/web/themes/images/vista/layout/stick.gif
deleted file mode 100644
index 7db68eec9..000000000
--- a/deluge/ui/web/themes/images/vista/layout/stick.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/vista/layout/tab-close-on.gif b/deluge/ui/web/themes/images/vista/layout/tab-close-on.gif
deleted file mode 100644
index 556e905b1..000000000
--- a/deluge/ui/web/themes/images/vista/layout/tab-close-on.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/vista/layout/tab-close.gif b/deluge/ui/web/themes/images/vista/layout/tab-close.gif
deleted file mode 100644
index 0a6f01987..000000000
--- a/deluge/ui/web/themes/images/vista/layout/tab-close.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/vista/qtip/bg.gif b/deluge/ui/web/themes/images/vista/qtip/bg.gif
deleted file mode 100644
index 5c0e8c92a..000000000
--- a/deluge/ui/web/themes/images/vista/qtip/bg.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/vista/qtip/tip-sprite.gif b/deluge/ui/web/themes/images/vista/qtip/tip-sprite.gif
deleted file mode 100644
index a1862865d..000000000
--- a/deluge/ui/web/themes/images/vista/qtip/tip-sprite.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/vista/s.gif b/deluge/ui/web/themes/images/vista/s.gif
deleted file mode 100644
index 1d11fa9ad..000000000
--- a/deluge/ui/web/themes/images/vista/s.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/vista/sizer/e-handle-dark.gif b/deluge/ui/web/themes/images/vista/sizer/e-handle-dark.gif
deleted file mode 100644
index eac9662ea..000000000
--- a/deluge/ui/web/themes/images/vista/sizer/e-handle-dark.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/vista/sizer/e-handle.gif b/deluge/ui/web/themes/images/vista/sizer/e-handle.gif
deleted file mode 100644
index f2c9f5382..000000000
--- a/deluge/ui/web/themes/images/vista/sizer/e-handle.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/vista/sizer/ne-handle-dark.gif b/deluge/ui/web/themes/images/vista/sizer/ne-handle-dark.gif
deleted file mode 100644
index c9c041c45..000000000
--- a/deluge/ui/web/themes/images/vista/sizer/ne-handle-dark.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/vista/sizer/ne-handle.gif b/deluge/ui/web/themes/images/vista/sizer/ne-handle.gif
deleted file mode 100644
index 942ae8253..000000000
--- a/deluge/ui/web/themes/images/vista/sizer/ne-handle.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/vista/sizer/nw-handle-dark.gif b/deluge/ui/web/themes/images/vista/sizer/nw-handle-dark.gif
deleted file mode 100644
index 23fced98b..000000000
--- a/deluge/ui/web/themes/images/vista/sizer/nw-handle-dark.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/vista/sizer/nw-handle.gif b/deluge/ui/web/themes/images/vista/sizer/nw-handle.gif
deleted file mode 100644
index d39b0c38d..000000000
--- a/deluge/ui/web/themes/images/vista/sizer/nw-handle.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/vista/sizer/s-handle-dark.gif b/deluge/ui/web/themes/images/vista/sizer/s-handle-dark.gif
deleted file mode 100644
index ddc2e18ce..000000000
--- a/deluge/ui/web/themes/images/vista/sizer/s-handle-dark.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/vista/sizer/s-handle.gif b/deluge/ui/web/themes/images/vista/sizer/s-handle.gif
deleted file mode 100644
index 827c3330a..000000000
--- a/deluge/ui/web/themes/images/vista/sizer/s-handle.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/vista/sizer/se-handle-dark.gif b/deluge/ui/web/themes/images/vista/sizer/se-handle-dark.gif
deleted file mode 100644
index 1a678e67f..000000000
--- a/deluge/ui/web/themes/images/vista/sizer/se-handle-dark.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/vista/sizer/se-handle.gif b/deluge/ui/web/themes/images/vista/sizer/se-handle.gif
deleted file mode 100644
index 69b5a9ed5..000000000
--- a/deluge/ui/web/themes/images/vista/sizer/se-handle.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/vista/sizer/sw-handle-dark.gif b/deluge/ui/web/themes/images/vista/sizer/sw-handle-dark.gif
deleted file mode 100644
index 937102c6b..000000000
--- a/deluge/ui/web/themes/images/vista/sizer/sw-handle-dark.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/vista/sizer/sw-handle.gif b/deluge/ui/web/themes/images/vista/sizer/sw-handle.gif
deleted file mode 100644
index b9e2f563a..000000000
--- a/deluge/ui/web/themes/images/vista/sizer/sw-handle.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/vista/tabs/tab-btm-inactive-left-bg.gif b/deluge/ui/web/themes/images/vista/tabs/tab-btm-inactive-left-bg.gif
deleted file mode 100644
index 667beeb32..000000000
--- a/deluge/ui/web/themes/images/vista/tabs/tab-btm-inactive-left-bg.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/vista/tabs/tab-btm-inactive-right-bg.gif b/deluge/ui/web/themes/images/vista/tabs/tab-btm-inactive-right-bg.gif
deleted file mode 100644
index 6c4e0a45f..000000000
--- a/deluge/ui/web/themes/images/vista/tabs/tab-btm-inactive-right-bg.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/vista/tabs/tab-btm-left-bg.gif b/deluge/ui/web/themes/images/vista/tabs/tab-btm-left-bg.gif
deleted file mode 100644
index 1d81e54e1..000000000
--- a/deluge/ui/web/themes/images/vista/tabs/tab-btm-left-bg.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/vista/tabs/tab-btm-right-bg.gif b/deluge/ui/web/themes/images/vista/tabs/tab-btm-right-bg.gif
deleted file mode 100644
index 47d005002..000000000
--- a/deluge/ui/web/themes/images/vista/tabs/tab-btm-right-bg.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/vista/tabs/tab-sprite.gif b/deluge/ui/web/themes/images/vista/tabs/tab-sprite.gif
deleted file mode 100644
index a16eedb82..000000000
--- a/deluge/ui/web/themes/images/vista/tabs/tab-sprite.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/vista/toolbar/gray-bg.gif b/deluge/ui/web/themes/images/vista/toolbar/gray-bg.gif
deleted file mode 100644
index 9af15c262..000000000
--- a/deluge/ui/web/themes/images/vista/toolbar/gray-bg.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/vista/toolbar/tb-btn-sprite.gif b/deluge/ui/web/themes/images/vista/toolbar/tb-btn-sprite.gif
deleted file mode 100644
index f21b0d612..000000000
--- a/deluge/ui/web/themes/images/vista/toolbar/tb-btn-sprite.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/README.txt b/deluge/ui/web/themes/images/yourtheme/README.txt
deleted file mode 100644
index acc508732..000000000
--- a/deluge/ui/web/themes/images/yourtheme/README.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-2010-03-16 jwr:
-The image directory, "yourtheme", is an exact copy of the "default" image directory. Remember to update your file paths in "css/yourtheme.css" if you make changes or add your own custom images for your custom theme. \ No newline at end of file
diff --git a/deluge/ui/web/themes/images/yourtheme/box/corners-blue.gif b/deluge/ui/web/themes/images/yourtheme/box/corners-blue.gif
deleted file mode 100644
index fa419b50a..000000000
--- a/deluge/ui/web/themes/images/yourtheme/box/corners-blue.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/box/corners.gif b/deluge/ui/web/themes/images/yourtheme/box/corners.gif
deleted file mode 100644
index 8aa8cae5c..000000000
--- a/deluge/ui/web/themes/images/yourtheme/box/corners.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/box/l-blue.gif b/deluge/ui/web/themes/images/yourtheme/box/l-blue.gif
deleted file mode 100644
index 5ed7f0043..000000000
--- a/deluge/ui/web/themes/images/yourtheme/box/l-blue.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/box/l.gif b/deluge/ui/web/themes/images/yourtheme/box/l.gif
deleted file mode 100644
index 0160f97fe..000000000
--- a/deluge/ui/web/themes/images/yourtheme/box/l.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/box/r-blue.gif b/deluge/ui/web/themes/images/yourtheme/box/r-blue.gif
deleted file mode 100644
index 3ea5cae3b..000000000
--- a/deluge/ui/web/themes/images/yourtheme/box/r-blue.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/box/r.gif b/deluge/ui/web/themes/images/yourtheme/box/r.gif
deleted file mode 100644
index 34237f629..000000000
--- a/deluge/ui/web/themes/images/yourtheme/box/r.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/box/tb-blue.gif b/deluge/ui/web/themes/images/yourtheme/box/tb-blue.gif
deleted file mode 100644
index 562fecca8..000000000
--- a/deluge/ui/web/themes/images/yourtheme/box/tb-blue.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/box/tb.gif b/deluge/ui/web/themes/images/yourtheme/box/tb.gif
deleted file mode 100644
index 435889bff..000000000
--- a/deluge/ui/web/themes/images/yourtheme/box/tb.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/button/arrow.gif b/deluge/ui/web/themes/images/yourtheme/button/arrow.gif
deleted file mode 100644
index 3ab4f71ac..000000000
--- a/deluge/ui/web/themes/images/yourtheme/button/arrow.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/button/btn.gif b/deluge/ui/web/themes/images/yourtheme/button/btn.gif
deleted file mode 100644
index 06b404dd7..000000000
--- a/deluge/ui/web/themes/images/yourtheme/button/btn.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/button/group-cs.gif b/deluge/ui/web/themes/images/yourtheme/button/group-cs.gif
deleted file mode 100644
index 3d1dca8f0..000000000
--- a/deluge/ui/web/themes/images/yourtheme/button/group-cs.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/button/group-lr.gif b/deluge/ui/web/themes/images/yourtheme/button/group-lr.gif
deleted file mode 100644
index 7c549f96d..000000000
--- a/deluge/ui/web/themes/images/yourtheme/button/group-lr.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/button/group-tb.gif b/deluge/ui/web/themes/images/yourtheme/button/group-tb.gif
deleted file mode 100644
index adeb0a4cf..000000000
--- a/deluge/ui/web/themes/images/yourtheme/button/group-tb.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/button/s-arrow-b-noline.gif b/deluge/ui/web/themes/images/yourtheme/button/s-arrow-b-noline.gif
deleted file mode 100644
index a4220ee90..000000000
--- a/deluge/ui/web/themes/images/yourtheme/button/s-arrow-b-noline.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/button/s-arrow-b.gif b/deluge/ui/web/themes/images/yourtheme/button/s-arrow-b.gif
deleted file mode 100644
index 84b647030..000000000
--- a/deluge/ui/web/themes/images/yourtheme/button/s-arrow-b.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/button/s-arrow-bo.gif b/deluge/ui/web/themes/images/yourtheme/button/s-arrow-bo.gif
deleted file mode 100644
index 548700bf4..000000000
--- a/deluge/ui/web/themes/images/yourtheme/button/s-arrow-bo.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/button/s-arrow-noline.gif b/deluge/ui/web/themes/images/yourtheme/button/s-arrow-noline.gif
deleted file mode 100644
index 0953eab5c..000000000
--- a/deluge/ui/web/themes/images/yourtheme/button/s-arrow-noline.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/button/s-arrow-o.gif b/deluge/ui/web/themes/images/yourtheme/button/s-arrow-o.gif
deleted file mode 100644
index 89c70f36f..000000000
--- a/deluge/ui/web/themes/images/yourtheme/button/s-arrow-o.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/button/s-arrow.gif b/deluge/ui/web/themes/images/yourtheme/button/s-arrow.gif
deleted file mode 100644
index 894077478..000000000
--- a/deluge/ui/web/themes/images/yourtheme/button/s-arrow.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/dd/drop-add.gif b/deluge/ui/web/themes/images/yourtheme/dd/drop-add.gif
deleted file mode 100644
index b22cd1448..000000000
--- a/deluge/ui/web/themes/images/yourtheme/dd/drop-add.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/dd/drop-no.gif b/deluge/ui/web/themes/images/yourtheme/dd/drop-no.gif
deleted file mode 100644
index 08d083355..000000000
--- a/deluge/ui/web/themes/images/yourtheme/dd/drop-no.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/dd/drop-yes.gif b/deluge/ui/web/themes/images/yourtheme/dd/drop-yes.gif
deleted file mode 100644
index 8aacb307e..000000000
--- a/deluge/ui/web/themes/images/yourtheme/dd/drop-yes.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/editor/tb-sprite.gif b/deluge/ui/web/themes/images/yourtheme/editor/tb-sprite.gif
deleted file mode 100644
index fb7057761..000000000
--- a/deluge/ui/web/themes/images/yourtheme/editor/tb-sprite.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/form/checkbox.gif b/deluge/ui/web/themes/images/yourtheme/form/checkbox.gif
deleted file mode 100644
index 835b346cc..000000000
--- a/deluge/ui/web/themes/images/yourtheme/form/checkbox.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/form/clear-trigger.gif b/deluge/ui/web/themes/images/yourtheme/form/clear-trigger.gif
deleted file mode 100644
index da78d45b3..000000000
--- a/deluge/ui/web/themes/images/yourtheme/form/clear-trigger.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/form/clear-trigger.psd b/deluge/ui/web/themes/images/yourtheme/form/clear-trigger.psd
deleted file mode 100644
index f637fa5d1..000000000
--- a/deluge/ui/web/themes/images/yourtheme/form/clear-trigger.psd
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/form/date-trigger.gif b/deluge/ui/web/themes/images/yourtheme/form/date-trigger.gif
deleted file mode 100644
index 25ef7b3ae..000000000
--- a/deluge/ui/web/themes/images/yourtheme/form/date-trigger.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/form/date-trigger.psd b/deluge/ui/web/themes/images/yourtheme/form/date-trigger.psd
deleted file mode 100644
index 74883b21c..000000000
--- a/deluge/ui/web/themes/images/yourtheme/form/date-trigger.psd
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/form/error-tip-corners.gif b/deluge/ui/web/themes/images/yourtheme/form/error-tip-corners.gif
deleted file mode 100644
index 6ea4c3838..000000000
--- a/deluge/ui/web/themes/images/yourtheme/form/error-tip-corners.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/form/exclamation.gif b/deluge/ui/web/themes/images/yourtheme/form/exclamation.gif
deleted file mode 100644
index ea31a3060..000000000
--- a/deluge/ui/web/themes/images/yourtheme/form/exclamation.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/form/radio.gif b/deluge/ui/web/themes/images/yourtheme/form/radio.gif
deleted file mode 100644
index 36bb91d0c..000000000
--- a/deluge/ui/web/themes/images/yourtheme/form/radio.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/form/search-trigger.gif b/deluge/ui/web/themes/images/yourtheme/form/search-trigger.gif
deleted file mode 100644
index db8802beb..000000000
--- a/deluge/ui/web/themes/images/yourtheme/form/search-trigger.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/form/search-trigger.psd b/deluge/ui/web/themes/images/yourtheme/form/search-trigger.psd
deleted file mode 100644
index b11f27300..000000000
--- a/deluge/ui/web/themes/images/yourtheme/form/search-trigger.psd
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/form/text-bg.gif b/deluge/ui/web/themes/images/yourtheme/form/text-bg.gif
deleted file mode 100644
index 4179607cc..000000000
--- a/deluge/ui/web/themes/images/yourtheme/form/text-bg.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/form/trigger-square.gif b/deluge/ui/web/themes/images/yourtheme/form/trigger-square.gif
deleted file mode 100644
index 3004ec589..000000000
--- a/deluge/ui/web/themes/images/yourtheme/form/trigger-square.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/form/trigger-square.psd b/deluge/ui/web/themes/images/yourtheme/form/trigger-square.psd
deleted file mode 100644
index e922ee65d..000000000
--- a/deluge/ui/web/themes/images/yourtheme/form/trigger-square.psd
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/form/trigger-tpl.gif b/deluge/ui/web/themes/images/yourtheme/form/trigger-tpl.gif
deleted file mode 100644
index e3701a383..000000000
--- a/deluge/ui/web/themes/images/yourtheme/form/trigger-tpl.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/form/trigger.gif b/deluge/ui/web/themes/images/yourtheme/form/trigger.gif
deleted file mode 100644
index f6cba375a..000000000
--- a/deluge/ui/web/themes/images/yourtheme/form/trigger.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/form/trigger.psd b/deluge/ui/web/themes/images/yourtheme/form/trigger.psd
deleted file mode 100644
index 344c76824..000000000
--- a/deluge/ui/web/themes/images/yourtheme/form/trigger.psd
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/gradient-bg.gif b/deluge/ui/web/themes/images/yourtheme/gradient-bg.gif
deleted file mode 100644
index 8134e4994..000000000
--- a/deluge/ui/web/themes/images/yourtheme/gradient-bg.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/arrow-left-white.gif b/deluge/ui/web/themes/images/yourtheme/grid/arrow-left-white.gif
deleted file mode 100644
index 63088f56e..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/arrow-left-white.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/arrow-right-white.gif b/deluge/ui/web/themes/images/yourtheme/grid/arrow-right-white.gif
deleted file mode 100644
index e9e067890..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/arrow-right-white.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/col-move-bottom.gif b/deluge/ui/web/themes/images/yourtheme/grid/col-move-bottom.gif
deleted file mode 100644
index cc1e473ec..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/col-move-bottom.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/col-move-top.gif b/deluge/ui/web/themes/images/yourtheme/grid/col-move-top.gif
deleted file mode 100644
index 58ff32cc8..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/col-move-top.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/columns.gif b/deluge/ui/web/themes/images/yourtheme/grid/columns.gif
deleted file mode 100644
index 2d3a82393..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/columns.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/dirty.gif b/deluge/ui/web/themes/images/yourtheme/grid/dirty.gif
deleted file mode 100644
index 4f217a479..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/dirty.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/done.gif b/deluge/ui/web/themes/images/yourtheme/grid/done.gif
deleted file mode 100644
index a937cb22c..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/done.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/drop-no.gif b/deluge/ui/web/themes/images/yourtheme/grid/drop-no.gif
deleted file mode 100644
index 31a332bf7..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/drop-no.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/drop-yes.gif b/deluge/ui/web/themes/images/yourtheme/grid/drop-yes.gif
deleted file mode 100644
index 926010e17..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/drop-yes.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/footer-bg.gif b/deluge/ui/web/themes/images/yourtheme/grid/footer-bg.gif
deleted file mode 100644
index 126120f71..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/footer-bg.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/grid-blue-hd.gif b/deluge/ui/web/themes/images/yourtheme/grid/grid-blue-hd.gif
deleted file mode 100644
index 862094e68..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/grid-blue-hd.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/grid-blue-split.gif b/deluge/ui/web/themes/images/yourtheme/grid/grid-blue-split.gif
deleted file mode 100644
index 5286f58f6..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/grid-blue-split.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/grid-hrow.gif b/deluge/ui/web/themes/images/yourtheme/grid/grid-hrow.gif
deleted file mode 100644
index 637410420..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/grid-hrow.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/grid-loading.gif b/deluge/ui/web/themes/images/yourtheme/grid/grid-loading.gif
deleted file mode 100644
index d112c5401..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/grid-loading.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/grid-split.gif b/deluge/ui/web/themes/images/yourtheme/grid/grid-split.gif
deleted file mode 100644
index c76a16e95..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/grid-split.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/grid-vista-hd.gif b/deluge/ui/web/themes/images/yourtheme/grid/grid-vista-hd.gif
deleted file mode 100644
index d0972638e..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/grid-vista-hd.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/grid3-hd-btn.gif b/deluge/ui/web/themes/images/yourtheme/grid/grid3-hd-btn.gif
deleted file mode 100644
index 21126075e..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/grid3-hd-btn.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/grid3-hrow-over.gif b/deluge/ui/web/themes/images/yourtheme/grid/grid3-hrow-over.gif
deleted file mode 100644
index f9c07af13..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/grid3-hrow-over.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/grid3-hrow.gif b/deluge/ui/web/themes/images/yourtheme/grid/grid3-hrow.gif
deleted file mode 100644
index 8d459a304..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/grid3-hrow.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/grid3-special-col-bg.gif b/deluge/ui/web/themes/images/yourtheme/grid/grid3-special-col-bg.gif
deleted file mode 100644
index 0b4d6ca3b..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/grid3-special-col-bg.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/grid3-special-col-sel-bg.gif b/deluge/ui/web/themes/images/yourtheme/grid/grid3-special-col-sel-bg.gif
deleted file mode 100644
index 1dfe9a69e..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/grid3-special-col-sel-bg.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/group-by.gif b/deluge/ui/web/themes/images/yourtheme/grid/group-by.gif
deleted file mode 100644
index d6075bba2..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/group-by.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/group-collapse.gif b/deluge/ui/web/themes/images/yourtheme/grid/group-collapse.gif
deleted file mode 100644
index 495bb051d..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/group-collapse.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/group-expand-sprite.gif b/deluge/ui/web/themes/images/yourtheme/grid/group-expand-sprite.gif
deleted file mode 100644
index 9c1653b48..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/group-expand-sprite.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/group-expand.gif b/deluge/ui/web/themes/images/yourtheme/grid/group-expand.gif
deleted file mode 100644
index a33ac30bd..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/group-expand.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/hd-pop.gif b/deluge/ui/web/themes/images/yourtheme/grid/hd-pop.gif
deleted file mode 100644
index eb8ba7967..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/hd-pop.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/hmenu-asc.gif b/deluge/ui/web/themes/images/yourtheme/grid/hmenu-asc.gif
deleted file mode 100644
index 8917e0eee..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/hmenu-asc.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/hmenu-desc.gif b/deluge/ui/web/themes/images/yourtheme/grid/hmenu-desc.gif
deleted file mode 100644
index f26b7c2fc..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/hmenu-desc.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/hmenu-lock.gif b/deluge/ui/web/themes/images/yourtheme/grid/hmenu-lock.gif
deleted file mode 100644
index 159612610..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/hmenu-lock.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/hmenu-lock.png b/deluge/ui/web/themes/images/yourtheme/grid/hmenu-lock.png
deleted file mode 100644
index 8b81e7ff2..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/hmenu-lock.png
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/hmenu-unlock.gif b/deluge/ui/web/themes/images/yourtheme/grid/hmenu-unlock.gif
deleted file mode 100644
index af59cf92a..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/hmenu-unlock.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/hmenu-unlock.png b/deluge/ui/web/themes/images/yourtheme/grid/hmenu-unlock.png
deleted file mode 100644
index 9dd5df34b..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/hmenu-unlock.png
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/invalid_line.gif b/deluge/ui/web/themes/images/yourtheme/grid/invalid_line.gif
deleted file mode 100644
index fb7e0f34d..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/invalid_line.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/loading.gif b/deluge/ui/web/themes/images/yourtheme/grid/loading.gif
deleted file mode 100644
index e846e1d6c..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/loading.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/mso-hd.gif b/deluge/ui/web/themes/images/yourtheme/grid/mso-hd.gif
deleted file mode 100644
index 669f3cf08..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/mso-hd.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/nowait.gif b/deluge/ui/web/themes/images/yourtheme/grid/nowait.gif
deleted file mode 100644
index 4c5862cd5..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/nowait.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/page-first-disabled.gif b/deluge/ui/web/themes/images/yourtheme/grid/page-first-disabled.gif
deleted file mode 100644
index 1e02c419f..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/page-first-disabled.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/page-first.gif b/deluge/ui/web/themes/images/yourtheme/grid/page-first.gif
deleted file mode 100644
index d84f41a91..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/page-first.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/page-last-disabled.gif b/deluge/ui/web/themes/images/yourtheme/grid/page-last-disabled.gif
deleted file mode 100644
index 869706777..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/page-last-disabled.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/page-last.gif b/deluge/ui/web/themes/images/yourtheme/grid/page-last.gif
deleted file mode 100644
index 3df5c2ba5..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/page-last.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/page-next-disabled.gif b/deluge/ui/web/themes/images/yourtheme/grid/page-next-disabled.gif
deleted file mode 100644
index 90a7756f6..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/page-next-disabled.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/page-next.gif b/deluge/ui/web/themes/images/yourtheme/grid/page-next.gif
deleted file mode 100644
index 960163530..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/page-next.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/page-prev-disabled.gif b/deluge/ui/web/themes/images/yourtheme/grid/page-prev-disabled.gif
deleted file mode 100644
index 37154d624..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/page-prev-disabled.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/page-prev.gif b/deluge/ui/web/themes/images/yourtheme/grid/page-prev.gif
deleted file mode 100644
index eb70cf8f6..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/page-prev.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/pick-button.gif b/deluge/ui/web/themes/images/yourtheme/grid/pick-button.gif
deleted file mode 100644
index 6957924a8..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/pick-button.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/refresh.gif b/deluge/ui/web/themes/images/yourtheme/grid/refresh.gif
deleted file mode 100644
index 110f6844b..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/refresh.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/row-check-sprite.gif b/deluge/ui/web/themes/images/yourtheme/grid/row-check-sprite.gif
deleted file mode 100644
index 610116465..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/row-check-sprite.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/row-expand-sprite.gif b/deluge/ui/web/themes/images/yourtheme/grid/row-expand-sprite.gif
deleted file mode 100644
index 6f4d874f5..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/row-expand-sprite.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/row-over.gif b/deluge/ui/web/themes/images/yourtheme/grid/row-over.gif
deleted file mode 100644
index b288e3873..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/row-over.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/row-sel.gif b/deluge/ui/web/themes/images/yourtheme/grid/row-sel.gif
deleted file mode 100644
index 98209e6e7..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/row-sel.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/sort-hd.gif b/deluge/ui/web/themes/images/yourtheme/grid/sort-hd.gif
deleted file mode 100644
index 45e545f74..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/sort-hd.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/sort_asc.gif b/deluge/ui/web/themes/images/yourtheme/grid/sort_asc.gif
deleted file mode 100644
index 67a2a4c66..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/sort_asc.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/sort_desc.gif b/deluge/ui/web/themes/images/yourtheme/grid/sort_desc.gif
deleted file mode 100644
index 34db47c3b..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/sort_desc.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/grid/wait.gif b/deluge/ui/web/themes/images/yourtheme/grid/wait.gif
deleted file mode 100644
index 471c1a4f9..000000000
--- a/deluge/ui/web/themes/images/yourtheme/grid/wait.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/layout/collapse.gif b/deluge/ui/web/themes/images/yourtheme/layout/collapse.gif
deleted file mode 100644
index d87b0a9dd..000000000
--- a/deluge/ui/web/themes/images/yourtheme/layout/collapse.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/layout/expand.gif b/deluge/ui/web/themes/images/yourtheme/layout/expand.gif
deleted file mode 100644
index 7b6e1c1ef..000000000
--- a/deluge/ui/web/themes/images/yourtheme/layout/expand.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/layout/gradient-bg.gif b/deluge/ui/web/themes/images/yourtheme/layout/gradient-bg.gif
deleted file mode 100644
index 8134e4994..000000000
--- a/deluge/ui/web/themes/images/yourtheme/layout/gradient-bg.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/layout/mini-bottom.gif b/deluge/ui/web/themes/images/yourtheme/layout/mini-bottom.gif
deleted file mode 100644
index c18f9e34a..000000000
--- a/deluge/ui/web/themes/images/yourtheme/layout/mini-bottom.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/layout/mini-left.gif b/deluge/ui/web/themes/images/yourtheme/layout/mini-left.gif
deleted file mode 100644
index 99f7993f2..000000000
--- a/deluge/ui/web/themes/images/yourtheme/layout/mini-left.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/layout/mini-right.gif b/deluge/ui/web/themes/images/yourtheme/layout/mini-right.gif
deleted file mode 100644
index 5b13c5a8b..000000000
--- a/deluge/ui/web/themes/images/yourtheme/layout/mini-right.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/layout/mini-top.gif b/deluge/ui/web/themes/images/yourtheme/layout/mini-top.gif
deleted file mode 100644
index a4ca2bb20..000000000
--- a/deluge/ui/web/themes/images/yourtheme/layout/mini-top.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/layout/ns-collapse.gif b/deluge/ui/web/themes/images/yourtheme/layout/ns-collapse.gif
deleted file mode 100644
index df2a77e9c..000000000
--- a/deluge/ui/web/themes/images/yourtheme/layout/ns-collapse.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/layout/ns-expand.gif b/deluge/ui/web/themes/images/yourtheme/layout/ns-expand.gif
deleted file mode 100644
index 77ab9dad2..000000000
--- a/deluge/ui/web/themes/images/yourtheme/layout/ns-expand.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/layout/panel-close.gif b/deluge/ui/web/themes/images/yourtheme/layout/panel-close.gif
deleted file mode 100644
index 2bdd62399..000000000
--- a/deluge/ui/web/themes/images/yourtheme/layout/panel-close.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/layout/panel-title-bg.gif b/deluge/ui/web/themes/images/yourtheme/layout/panel-title-bg.gif
deleted file mode 100644
index d1daef54c..000000000
--- a/deluge/ui/web/themes/images/yourtheme/layout/panel-title-bg.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/layout/panel-title-light-bg.gif b/deluge/ui/web/themes/images/yourtheme/layout/panel-title-light-bg.gif
deleted file mode 100644
index 8c2c83d82..000000000
--- a/deluge/ui/web/themes/images/yourtheme/layout/panel-title-light-bg.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/layout/stick.gif b/deluge/ui/web/themes/images/yourtheme/layout/stick.gif
deleted file mode 100644
index 5a1e8ba19..000000000
--- a/deluge/ui/web/themes/images/yourtheme/layout/stick.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/layout/stuck.gif b/deluge/ui/web/themes/images/yourtheme/layout/stuck.gif
deleted file mode 100644
index 0a8de4db9..000000000
--- a/deluge/ui/web/themes/images/yourtheme/layout/stuck.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/layout/tab-close-on.gif b/deluge/ui/web/themes/images/yourtheme/layout/tab-close-on.gif
deleted file mode 100644
index eacea39b6..000000000
--- a/deluge/ui/web/themes/images/yourtheme/layout/tab-close-on.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/layout/tab-close.gif b/deluge/ui/web/themes/images/yourtheme/layout/tab-close.gif
deleted file mode 100644
index 45db61e60..000000000
--- a/deluge/ui/web/themes/images/yourtheme/layout/tab-close.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/menu/checked.gif b/deluge/ui/web/themes/images/yourtheme/menu/checked.gif
deleted file mode 100644
index fad589372..000000000
--- a/deluge/ui/web/themes/images/yourtheme/menu/checked.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/menu/group-checked.gif b/deluge/ui/web/themes/images/yourtheme/menu/group-checked.gif
deleted file mode 100644
index d30b3e5a8..000000000
--- a/deluge/ui/web/themes/images/yourtheme/menu/group-checked.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/menu/item-over.gif b/deluge/ui/web/themes/images/yourtheme/menu/item-over.gif
deleted file mode 100644
index 016783932..000000000
--- a/deluge/ui/web/themes/images/yourtheme/menu/item-over.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/menu/menu-parent.gif b/deluge/ui/web/themes/images/yourtheme/menu/menu-parent.gif
deleted file mode 100644
index 1e375622f..000000000
--- a/deluge/ui/web/themes/images/yourtheme/menu/menu-parent.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/menu/menu.gif b/deluge/ui/web/themes/images/yourtheme/menu/menu.gif
deleted file mode 100644
index 30a2c4b6c..000000000
--- a/deluge/ui/web/themes/images/yourtheme/menu/menu.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/menu/unchecked.gif b/deluge/ui/web/themes/images/yourtheme/menu/unchecked.gif
deleted file mode 100644
index 43823e52d..000000000
--- a/deluge/ui/web/themes/images/yourtheme/menu/unchecked.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/panel/corners-sprite.gif b/deluge/ui/web/themes/images/yourtheme/panel/corners-sprite.gif
deleted file mode 100644
index aa0d0ed8f..000000000
--- a/deluge/ui/web/themes/images/yourtheme/panel/corners-sprite.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/panel/left-right.gif b/deluge/ui/web/themes/images/yourtheme/panel/left-right.gif
deleted file mode 100644
index 9fae2d594..000000000
--- a/deluge/ui/web/themes/images/yourtheme/panel/left-right.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/panel/light-hd.gif b/deluge/ui/web/themes/images/yourtheme/panel/light-hd.gif
deleted file mode 100644
index 58d6747b5..000000000
--- a/deluge/ui/web/themes/images/yourtheme/panel/light-hd.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/panel/tool-sprite-tpl.gif b/deluge/ui/web/themes/images/yourtheme/panel/tool-sprite-tpl.gif
deleted file mode 100644
index e6478670e..000000000
--- a/deluge/ui/web/themes/images/yourtheme/panel/tool-sprite-tpl.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/panel/tool-sprites.gif b/deluge/ui/web/themes/images/yourtheme/panel/tool-sprites.gif
deleted file mode 100644
index 9a3c5b9ac..000000000
--- a/deluge/ui/web/themes/images/yourtheme/panel/tool-sprites.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/panel/tools-sprites-trans.gif b/deluge/ui/web/themes/images/yourtheme/panel/tools-sprites-trans.gif
deleted file mode 100644
index ead931ef6..000000000
--- a/deluge/ui/web/themes/images/yourtheme/panel/tools-sprites-trans.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/panel/top-bottom.gif b/deluge/ui/web/themes/images/yourtheme/panel/top-bottom.gif
deleted file mode 100644
index be6c50e1c..000000000
--- a/deluge/ui/web/themes/images/yourtheme/panel/top-bottom.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/panel/top-bottom.png b/deluge/ui/web/themes/images/yourtheme/panel/top-bottom.png
deleted file mode 100644
index 578ffb609..000000000
--- a/deluge/ui/web/themes/images/yourtheme/panel/top-bottom.png
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/panel/white-corners-sprite.gif b/deluge/ui/web/themes/images/yourtheme/panel/white-corners-sprite.gif
deleted file mode 100644
index 22d4bbab4..000000000
--- a/deluge/ui/web/themes/images/yourtheme/panel/white-corners-sprite.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/panel/white-left-right.gif b/deluge/ui/web/themes/images/yourtheme/panel/white-left-right.gif
deleted file mode 100644
index d82c33784..000000000
--- a/deluge/ui/web/themes/images/yourtheme/panel/white-left-right.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/panel/white-top-bottom.gif b/deluge/ui/web/themes/images/yourtheme/panel/white-top-bottom.gif
deleted file mode 100644
index fe7dd1c1e..000000000
--- a/deluge/ui/web/themes/images/yourtheme/panel/white-top-bottom.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/progress/progress-bg.gif b/deluge/ui/web/themes/images/yourtheme/progress/progress-bg.gif
deleted file mode 100644
index 1c1abeb4b..000000000
--- a/deluge/ui/web/themes/images/yourtheme/progress/progress-bg.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/qtip/bg.gif b/deluge/ui/web/themes/images/yourtheme/qtip/bg.gif
deleted file mode 100644
index 43488afdb..000000000
--- a/deluge/ui/web/themes/images/yourtheme/qtip/bg.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/qtip/close.gif b/deluge/ui/web/themes/images/yourtheme/qtip/close.gif
deleted file mode 100644
index 69ab915e4..000000000
--- a/deluge/ui/web/themes/images/yourtheme/qtip/close.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/qtip/tip-anchor-sprite.gif b/deluge/ui/web/themes/images/yourtheme/qtip/tip-anchor-sprite.gif
deleted file mode 100644
index 9cf485060..000000000
--- a/deluge/ui/web/themes/images/yourtheme/qtip/tip-anchor-sprite.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/qtip/tip-sprite.gif b/deluge/ui/web/themes/images/yourtheme/qtip/tip-sprite.gif
deleted file mode 100644
index 9810acac5..000000000
--- a/deluge/ui/web/themes/images/yourtheme/qtip/tip-sprite.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/s.gif b/deluge/ui/web/themes/images/yourtheme/s.gif
deleted file mode 100644
index 1d11fa9ad..000000000
--- a/deluge/ui/web/themes/images/yourtheme/s.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/shadow-c.png b/deluge/ui/web/themes/images/yourtheme/shadow-c.png
deleted file mode 100644
index d435f80ae..000000000
--- a/deluge/ui/web/themes/images/yourtheme/shadow-c.png
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/shadow-lr.png b/deluge/ui/web/themes/images/yourtheme/shadow-lr.png
deleted file mode 100644
index bb88b6f2b..000000000
--- a/deluge/ui/web/themes/images/yourtheme/shadow-lr.png
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/shadow.png b/deluge/ui/web/themes/images/yourtheme/shadow.png
deleted file mode 100644
index 75c0eba3e..000000000
--- a/deluge/ui/web/themes/images/yourtheme/shadow.png
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/shared/blue-loading.gif b/deluge/ui/web/themes/images/yourtheme/shared/blue-loading.gif
deleted file mode 100644
index 3bbf639ef..000000000
--- a/deluge/ui/web/themes/images/yourtheme/shared/blue-loading.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/shared/calendar.gif b/deluge/ui/web/themes/images/yourtheme/shared/calendar.gif
deleted file mode 100644
index 133cf232b..000000000
--- a/deluge/ui/web/themes/images/yourtheme/shared/calendar.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/shared/glass-bg.gif b/deluge/ui/web/themes/images/yourtheme/shared/glass-bg.gif
deleted file mode 100644
index 26fbbae3b..000000000
--- a/deluge/ui/web/themes/images/yourtheme/shared/glass-bg.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/shared/hd-sprite.gif b/deluge/ui/web/themes/images/yourtheme/shared/hd-sprite.gif
deleted file mode 100644
index 42da1ea1a..000000000
--- a/deluge/ui/web/themes/images/yourtheme/shared/hd-sprite.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/shared/large-loading.gif b/deluge/ui/web/themes/images/yourtheme/shared/large-loading.gif
deleted file mode 100644
index b36b555b4..000000000
--- a/deluge/ui/web/themes/images/yourtheme/shared/large-loading.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/shared/left-btn.gif b/deluge/ui/web/themes/images/yourtheme/shared/left-btn.gif
deleted file mode 100644
index a0ddd9ee8..000000000
--- a/deluge/ui/web/themes/images/yourtheme/shared/left-btn.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/shared/loading-balls.gif b/deluge/ui/web/themes/images/yourtheme/shared/loading-balls.gif
deleted file mode 100644
index 9ce214beb..000000000
--- a/deluge/ui/web/themes/images/yourtheme/shared/loading-balls.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/shared/right-btn.gif b/deluge/ui/web/themes/images/yourtheme/shared/right-btn.gif
deleted file mode 100644
index dee63e211..000000000
--- a/deluge/ui/web/themes/images/yourtheme/shared/right-btn.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/shared/warning.gif b/deluge/ui/web/themes/images/yourtheme/shared/warning.gif
deleted file mode 100644
index 806d4bc09..000000000
--- a/deluge/ui/web/themes/images/yourtheme/shared/warning.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/sizer/e-handle-dark.gif b/deluge/ui/web/themes/images/yourtheme/sizer/e-handle-dark.gif
deleted file mode 100644
index b5486c1a9..000000000
--- a/deluge/ui/web/themes/images/yourtheme/sizer/e-handle-dark.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/sizer/e-handle.gif b/deluge/ui/web/themes/images/yourtheme/sizer/e-handle.gif
deleted file mode 100644
index 00ba83500..000000000
--- a/deluge/ui/web/themes/images/yourtheme/sizer/e-handle.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/sizer/ne-handle-dark.gif b/deluge/ui/web/themes/images/yourtheme/sizer/ne-handle-dark.gif
deleted file mode 100644
index 04e5ecf7d..000000000
--- a/deluge/ui/web/themes/images/yourtheme/sizer/ne-handle-dark.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/sizer/ne-handle.gif b/deluge/ui/web/themes/images/yourtheme/sizer/ne-handle.gif
deleted file mode 100644
index 09405c7ac..000000000
--- a/deluge/ui/web/themes/images/yourtheme/sizer/ne-handle.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/sizer/nw-handle-dark.gif b/deluge/ui/web/themes/images/yourtheme/sizer/nw-handle-dark.gif
deleted file mode 100644
index 6e49d6967..000000000
--- a/deluge/ui/web/themes/images/yourtheme/sizer/nw-handle-dark.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/sizer/nw-handle.gif b/deluge/ui/web/themes/images/yourtheme/sizer/nw-handle.gif
deleted file mode 100644
index 2fcea8a92..000000000
--- a/deluge/ui/web/themes/images/yourtheme/sizer/nw-handle.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/sizer/s-handle-dark.gif b/deluge/ui/web/themes/images/yourtheme/sizer/s-handle-dark.gif
deleted file mode 100644
index 4eb5f0fcc..000000000
--- a/deluge/ui/web/themes/images/yourtheme/sizer/s-handle-dark.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/sizer/s-handle.gif b/deluge/ui/web/themes/images/yourtheme/sizer/s-handle.gif
deleted file mode 100644
index bf069c243..000000000
--- a/deluge/ui/web/themes/images/yourtheme/sizer/s-handle.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/sizer/se-handle-dark.gif b/deluge/ui/web/themes/images/yourtheme/sizer/se-handle-dark.gif
deleted file mode 100644
index c4c108786..000000000
--- a/deluge/ui/web/themes/images/yourtheme/sizer/se-handle-dark.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/sizer/se-handle.gif b/deluge/ui/web/themes/images/yourtheme/sizer/se-handle.gif
deleted file mode 100644
index 972055e7b..000000000
--- a/deluge/ui/web/themes/images/yourtheme/sizer/se-handle.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/sizer/square.gif b/deluge/ui/web/themes/images/yourtheme/sizer/square.gif
deleted file mode 100644
index 14ce6f725..000000000
--- a/deluge/ui/web/themes/images/yourtheme/sizer/square.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/sizer/sw-handle-dark.gif b/deluge/ui/web/themes/images/yourtheme/sizer/sw-handle-dark.gif
deleted file mode 100644
index 77224b0c0..000000000
--- a/deluge/ui/web/themes/images/yourtheme/sizer/sw-handle-dark.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/sizer/sw-handle.gif b/deluge/ui/web/themes/images/yourtheme/sizer/sw-handle.gif
deleted file mode 100644
index 3ca0ed96d..000000000
--- a/deluge/ui/web/themes/images/yourtheme/sizer/sw-handle.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/slider/slider-bg.png b/deluge/ui/web/themes/images/yourtheme/slider/slider-bg.png
deleted file mode 100644
index 999919424..000000000
--- a/deluge/ui/web/themes/images/yourtheme/slider/slider-bg.png
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/slider/slider-thumb.png b/deluge/ui/web/themes/images/yourtheme/slider/slider-thumb.png
deleted file mode 100644
index cd654a4c1..000000000
--- a/deluge/ui/web/themes/images/yourtheme/slider/slider-thumb.png
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/slider/slider-v-bg.png b/deluge/ui/web/themes/images/yourtheme/slider/slider-v-bg.png
deleted file mode 100644
index 121450c28..000000000
--- a/deluge/ui/web/themes/images/yourtheme/slider/slider-v-bg.png
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/slider/slider-v-thumb.png b/deluge/ui/web/themes/images/yourtheme/slider/slider-v-thumb.png
deleted file mode 100644
index 7b3d7258a..000000000
--- a/deluge/ui/web/themes/images/yourtheme/slider/slider-v-thumb.png
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/tabs/scroll-left.gif b/deluge/ui/web/themes/images/yourtheme/tabs/scroll-left.gif
deleted file mode 100644
index 9f2f6d1c9..000000000
--- a/deluge/ui/web/themes/images/yourtheme/tabs/scroll-left.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/tabs/scroll-right.gif b/deluge/ui/web/themes/images/yourtheme/tabs/scroll-right.gif
deleted file mode 100644
index 4c5e7e395..000000000
--- a/deluge/ui/web/themes/images/yourtheme/tabs/scroll-right.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/tabs/scroller-bg.gif b/deluge/ui/web/themes/images/yourtheme/tabs/scroller-bg.gif
deleted file mode 100644
index 099b90d8a..000000000
--- a/deluge/ui/web/themes/images/yourtheme/tabs/scroller-bg.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/tabs/tab-btm-inactive-left-bg.gif b/deluge/ui/web/themes/images/yourtheme/tabs/tab-btm-inactive-left-bg.gif
deleted file mode 100644
index 188bf940c..000000000
--- a/deluge/ui/web/themes/images/yourtheme/tabs/tab-btm-inactive-left-bg.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/tabs/tab-btm-inactive-right-bg.gif b/deluge/ui/web/themes/images/yourtheme/tabs/tab-btm-inactive-right-bg.gif
deleted file mode 100644
index e1f5e3c51..000000000
--- a/deluge/ui/web/themes/images/yourtheme/tabs/tab-btm-inactive-right-bg.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/tabs/tab-btm-left-bg.gif b/deluge/ui/web/themes/images/yourtheme/tabs/tab-btm-left-bg.gif
deleted file mode 100644
index dde796870..000000000
--- a/deluge/ui/web/themes/images/yourtheme/tabs/tab-btm-left-bg.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/tabs/tab-btm-over-left-bg.gif b/deluge/ui/web/themes/images/yourtheme/tabs/tab-btm-over-left-bg.gif
deleted file mode 100644
index da49c100d..000000000
--- a/deluge/ui/web/themes/images/yourtheme/tabs/tab-btm-over-left-bg.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/tabs/tab-btm-over-right-bg.gif b/deluge/ui/web/themes/images/yourtheme/tabs/tab-btm-over-right-bg.gif
deleted file mode 100644
index 45346ab14..000000000
--- a/deluge/ui/web/themes/images/yourtheme/tabs/tab-btm-over-right-bg.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/tabs/tab-btm-right-bg.gif b/deluge/ui/web/themes/images/yourtheme/tabs/tab-btm-right-bg.gif
deleted file mode 100644
index e695186d5..000000000
--- a/deluge/ui/web/themes/images/yourtheme/tabs/tab-btm-right-bg.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/tabs/tab-close.gif b/deluge/ui/web/themes/images/yourtheme/tabs/tab-close.gif
deleted file mode 100644
index e69987848..000000000
--- a/deluge/ui/web/themes/images/yourtheme/tabs/tab-close.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/tabs/tab-strip-bg.gif b/deluge/ui/web/themes/images/yourtheme/tabs/tab-strip-bg.gif
deleted file mode 100644
index 34f133345..000000000
--- a/deluge/ui/web/themes/images/yourtheme/tabs/tab-strip-bg.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/tabs/tab-strip-bg.png b/deluge/ui/web/themes/images/yourtheme/tabs/tab-strip-bg.png
deleted file mode 100644
index fa8ab3f46..000000000
--- a/deluge/ui/web/themes/images/yourtheme/tabs/tab-strip-bg.png
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/tabs/tab-strip-btm-bg.gif b/deluge/ui/web/themes/images/yourtheme/tabs/tab-strip-btm-bg.gif
deleted file mode 100644
index 5eaba1eaa..000000000
--- a/deluge/ui/web/themes/images/yourtheme/tabs/tab-strip-btm-bg.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/tabs/tabs-sprite.gif b/deluge/ui/web/themes/images/yourtheme/tabs/tabs-sprite.gif
deleted file mode 100644
index e969fb0b7..000000000
--- a/deluge/ui/web/themes/images/yourtheme/tabs/tabs-sprite.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/toolbar/bg.gif b/deluge/ui/web/themes/images/yourtheme/toolbar/bg.gif
deleted file mode 100644
index 0b085bf24..000000000
--- a/deluge/ui/web/themes/images/yourtheme/toolbar/bg.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/toolbar/btn-arrow-light.gif b/deluge/ui/web/themes/images/yourtheme/toolbar/btn-arrow-light.gif
deleted file mode 100644
index b0e24b55e..000000000
--- a/deluge/ui/web/themes/images/yourtheme/toolbar/btn-arrow-light.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/toolbar/btn-arrow.gif b/deluge/ui/web/themes/images/yourtheme/toolbar/btn-arrow.gif
deleted file mode 100644
index 8acb4608d..000000000
--- a/deluge/ui/web/themes/images/yourtheme/toolbar/btn-arrow.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/toolbar/btn-over-bg.gif b/deluge/ui/web/themes/images/yourtheme/toolbar/btn-over-bg.gif
deleted file mode 100644
index ee2dd9860..000000000
--- a/deluge/ui/web/themes/images/yourtheme/toolbar/btn-over-bg.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/toolbar/gray-bg.gif b/deluge/ui/web/themes/images/yourtheme/toolbar/gray-bg.gif
deleted file mode 100644
index bd49438f3..000000000
--- a/deluge/ui/web/themes/images/yourtheme/toolbar/gray-bg.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/toolbar/more.gif b/deluge/ui/web/themes/images/yourtheme/toolbar/more.gif
deleted file mode 100644
index 02c2509fe..000000000
--- a/deluge/ui/web/themes/images/yourtheme/toolbar/more.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/toolbar/tb-bg.gif b/deluge/ui/web/themes/images/yourtheme/toolbar/tb-bg.gif
deleted file mode 100644
index 4969e4efe..000000000
--- a/deluge/ui/web/themes/images/yourtheme/toolbar/tb-bg.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/toolbar/tb-btn-sprite.gif b/deluge/ui/web/themes/images/yourtheme/toolbar/tb-btn-sprite.gif
deleted file mode 100644
index 19bbef3c6..000000000
--- a/deluge/ui/web/themes/images/yourtheme/toolbar/tb-btn-sprite.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/toolbar/tb-xl-btn-sprite.gif b/deluge/ui/web/themes/images/yourtheme/toolbar/tb-xl-btn-sprite.gif
deleted file mode 100644
index 1bc0420f0..000000000
--- a/deluge/ui/web/themes/images/yourtheme/toolbar/tb-xl-btn-sprite.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/toolbar/tb-xl-sep.gif b/deluge/ui/web/themes/images/yourtheme/toolbar/tb-xl-sep.gif
deleted file mode 100644
index 30555eecf..000000000
--- a/deluge/ui/web/themes/images/yourtheme/toolbar/tb-xl-sep.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/tree/arrows.gif b/deluge/ui/web/themes/images/yourtheme/tree/arrows.gif
deleted file mode 100644
index 268346391..000000000
--- a/deluge/ui/web/themes/images/yourtheme/tree/arrows.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/tree/drop-add.gif b/deluge/ui/web/themes/images/yourtheme/tree/drop-add.gif
deleted file mode 100644
index b22cd1448..000000000
--- a/deluge/ui/web/themes/images/yourtheme/tree/drop-add.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/tree/drop-between.gif b/deluge/ui/web/themes/images/yourtheme/tree/drop-between.gif
deleted file mode 100644
index 5c6c09d98..000000000
--- a/deluge/ui/web/themes/images/yourtheme/tree/drop-between.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/tree/drop-no.gif b/deluge/ui/web/themes/images/yourtheme/tree/drop-no.gif
deleted file mode 100644
index 9d9c6a9ce..000000000
--- a/deluge/ui/web/themes/images/yourtheme/tree/drop-no.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/tree/drop-over.gif b/deluge/ui/web/themes/images/yourtheme/tree/drop-over.gif
deleted file mode 100644
index 30d1ca710..000000000
--- a/deluge/ui/web/themes/images/yourtheme/tree/drop-over.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/tree/drop-under.gif b/deluge/ui/web/themes/images/yourtheme/tree/drop-under.gif
deleted file mode 100644
index 85f66b1e5..000000000
--- a/deluge/ui/web/themes/images/yourtheme/tree/drop-under.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/tree/drop-yes.gif b/deluge/ui/web/themes/images/yourtheme/tree/drop-yes.gif
deleted file mode 100644
index 8aacb307e..000000000
--- a/deluge/ui/web/themes/images/yourtheme/tree/drop-yes.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/tree/elbow-end-minus-nl.gif b/deluge/ui/web/themes/images/yourtheme/tree/elbow-end-minus-nl.gif
deleted file mode 100644
index 928779e92..000000000
--- a/deluge/ui/web/themes/images/yourtheme/tree/elbow-end-minus-nl.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/tree/elbow-end-minus.gif b/deluge/ui/web/themes/images/yourtheme/tree/elbow-end-minus.gif
deleted file mode 100644
index 9a8d727d7..000000000
--- a/deluge/ui/web/themes/images/yourtheme/tree/elbow-end-minus.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/tree/elbow-end-plus-nl.gif b/deluge/ui/web/themes/images/yourtheme/tree/elbow-end-plus-nl.gif
deleted file mode 100644
index 9f7f69880..000000000
--- a/deluge/ui/web/themes/images/yourtheme/tree/elbow-end-plus-nl.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/tree/elbow-end-plus.gif b/deluge/ui/web/themes/images/yourtheme/tree/elbow-end-plus.gif
deleted file mode 100644
index 5943a01bc..000000000
--- a/deluge/ui/web/themes/images/yourtheme/tree/elbow-end-plus.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/tree/elbow-end.gif b/deluge/ui/web/themes/images/yourtheme/tree/elbow-end.gif
deleted file mode 100644
index f24ddee79..000000000
--- a/deluge/ui/web/themes/images/yourtheme/tree/elbow-end.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/tree/elbow-line.gif b/deluge/ui/web/themes/images/yourtheme/tree/elbow-line.gif
deleted file mode 100644
index 75e6da4f8..000000000
--- a/deluge/ui/web/themes/images/yourtheme/tree/elbow-line.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/tree/elbow-minus-nl.gif b/deluge/ui/web/themes/images/yourtheme/tree/elbow-minus-nl.gif
deleted file mode 100644
index 928779e92..000000000
--- a/deluge/ui/web/themes/images/yourtheme/tree/elbow-minus-nl.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/tree/elbow-minus.gif b/deluge/ui/web/themes/images/yourtheme/tree/elbow-minus.gif
deleted file mode 100644
index 97dcc7110..000000000
--- a/deluge/ui/web/themes/images/yourtheme/tree/elbow-minus.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/tree/elbow-plus-nl.gif b/deluge/ui/web/themes/images/yourtheme/tree/elbow-plus-nl.gif
deleted file mode 100644
index 9f7f69880..000000000
--- a/deluge/ui/web/themes/images/yourtheme/tree/elbow-plus-nl.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/tree/elbow-plus.gif b/deluge/ui/web/themes/images/yourtheme/tree/elbow-plus.gif
deleted file mode 100644
index 698de4793..000000000
--- a/deluge/ui/web/themes/images/yourtheme/tree/elbow-plus.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/tree/elbow.gif b/deluge/ui/web/themes/images/yourtheme/tree/elbow.gif
deleted file mode 100644
index b8f420838..000000000
--- a/deluge/ui/web/themes/images/yourtheme/tree/elbow.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/tree/folder-open.gif b/deluge/ui/web/themes/images/yourtheme/tree/folder-open.gif
deleted file mode 100644
index 56ba737bc..000000000
--- a/deluge/ui/web/themes/images/yourtheme/tree/folder-open.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/tree/folder.gif b/deluge/ui/web/themes/images/yourtheme/tree/folder.gif
deleted file mode 100644
index 20412f7c1..000000000
--- a/deluge/ui/web/themes/images/yourtheme/tree/folder.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/tree/leaf.gif b/deluge/ui/web/themes/images/yourtheme/tree/leaf.gif
deleted file mode 100644
index 445769d3f..000000000
--- a/deluge/ui/web/themes/images/yourtheme/tree/leaf.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/tree/loading.gif b/deluge/ui/web/themes/images/yourtheme/tree/loading.gif
deleted file mode 100644
index e846e1d6c..000000000
--- a/deluge/ui/web/themes/images/yourtheme/tree/loading.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/tree/s.gif b/deluge/ui/web/themes/images/yourtheme/tree/s.gif
deleted file mode 100644
index 1d11fa9ad..000000000
--- a/deluge/ui/web/themes/images/yourtheme/tree/s.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/window/icon-error.gif b/deluge/ui/web/themes/images/yourtheme/window/icon-error.gif
deleted file mode 100644
index 397b655ab..000000000
--- a/deluge/ui/web/themes/images/yourtheme/window/icon-error.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/window/icon-info.gif b/deluge/ui/web/themes/images/yourtheme/window/icon-info.gif
deleted file mode 100644
index 58281c306..000000000
--- a/deluge/ui/web/themes/images/yourtheme/window/icon-info.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/window/icon-question.gif b/deluge/ui/web/themes/images/yourtheme/window/icon-question.gif
deleted file mode 100644
index 08abd82ae..000000000
--- a/deluge/ui/web/themes/images/yourtheme/window/icon-question.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/window/icon-warning.gif b/deluge/ui/web/themes/images/yourtheme/window/icon-warning.gif
deleted file mode 100644
index 27ff98b4f..000000000
--- a/deluge/ui/web/themes/images/yourtheme/window/icon-warning.gif
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/window/left-corners.png b/deluge/ui/web/themes/images/yourtheme/window/left-corners.png
deleted file mode 100644
index 1a518335d..000000000
--- a/deluge/ui/web/themes/images/yourtheme/window/left-corners.png
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/window/left-corners.psd b/deluge/ui/web/themes/images/yourtheme/window/left-corners.psd
deleted file mode 100644
index 3d7f0623e..000000000
--- a/deluge/ui/web/themes/images/yourtheme/window/left-corners.psd
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/window/left-right.png b/deluge/ui/web/themes/images/yourtheme/window/left-right.png
deleted file mode 100644
index 7586ff333..000000000
--- a/deluge/ui/web/themes/images/yourtheme/window/left-right.png
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/window/left-right.psd b/deluge/ui/web/themes/images/yourtheme/window/left-right.psd
deleted file mode 100644
index 59a3960a2..000000000
--- a/deluge/ui/web/themes/images/yourtheme/window/left-right.psd
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/window/right-corners.png b/deluge/ui/web/themes/images/yourtheme/window/right-corners.png
deleted file mode 100644
index e69a3ffc9..000000000
--- a/deluge/ui/web/themes/images/yourtheme/window/right-corners.png
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/window/right-corners.psd b/deluge/ui/web/themes/images/yourtheme/window/right-corners.psd
deleted file mode 100644
index 86d509538..000000000
--- a/deluge/ui/web/themes/images/yourtheme/window/right-corners.psd
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/window/top-bottom.png b/deluge/ui/web/themes/images/yourtheme/window/top-bottom.png
deleted file mode 100644
index 33779e76b..000000000
--- a/deluge/ui/web/themes/images/yourtheme/window/top-bottom.png
+++ /dev/null
Binary files differ
diff --git a/deluge/ui/web/themes/images/yourtheme/window/top-bottom.psd b/deluge/ui/web/themes/images/yourtheme/window/top-bottom.psd
deleted file mode 100644
index 48c5395e4..000000000
--- a/deluge/ui/web/themes/images/yourtheme/window/top-bottom.psd
+++ /dev/null
Binary files differ
diff --git a/setup.py b/setup.py
index a55567c76..a649755b3 100755
--- a/setup.py
+++ b/setup.py
@@ -152,11 +152,12 @@ else:
for include in os.environ.get("INCLUDEDIR", "").split(":"):
_include_dirs.append(include)
- _library_dirs += [sysconfig.get_config_var("LIBDIR"), '/opt/local/lib']
+ _library_dirs += [sysconfig.get_config_var("LIBDIR"), '/opt/local/lib', '/usr/local/lib']
if osx_check():
_include_dirs += [
'/opt/local/include/boost-1_35',
'/opt/local/include/boost-1_36',
+ '/usr/local/include'
'/sw/include/boost-1_35',
'/sw/include/boost'
]