From dd3f78bd368b8821590c73dd36796b4e3508a50b Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Sat, 30 Apr 2011 07:42:06 +0100 Subject: [PATCH] More changes related to automatic connections. Auto-connecting on start of the gtk ui is now fully working. Auto-staring localhost if needed is now also working. Authentication failures now get passed correctly to the client implementation which will allow the user to enter username and/or password to complete authentication. It's now possible to shutdown the daemon from the connection manager even if not on localhost, it just needs all required information to be present on the liststore. --- deluge/core/rpcserver.py | 4 +- deluge/core/torrentmanager.py | 4 +- deluge/error.py | 32 +- deluge/ui/client.py | 58 +-- deluge/ui/gtkui/connectionmanager.py | 87 ++-- .../ui/gtkui/glade/connection_manager.glade | 379 +++++++++++------- deluge/ui/gtkui/gtkui.py | 107 ++--- 7 files changed, 375 insertions(+), 296 deletions(-) diff --git a/deluge/core/rpcserver.py b/deluge/core/rpcserver.py index 9e8823279..274aeae48 100644 --- a/deluge/core/rpcserver.py +++ b/deluge/core/rpcserver.py @@ -56,7 +56,7 @@ except ImportError: import deluge.component as component import deluge.configmanager from deluge.core.authmanager import AUTH_LEVEL_NONE, AUTH_LEVEL_DEFAULT, AUTH_LEVEL_ADMIN -from deluge.error import DelugeError, NotAuthorizedError, __PassthroughError +from deluge.error import DelugeError, NotAuthorizedError, _PassthroughError RPC_RESPONSE = 1 RPC_ERROR = 2 @@ -266,7 +266,7 @@ class DelugeRPCProtocol(Protocol): self.factory.authorized_sessions[self.transport.sessionno] = (ret, args[0]) self.factory.session_protocols[self.transport.sessionno] = self except Exception, e: - if isinstance(e, __PassthroughError): + if isinstance(e, _PassthroughError): self.sendData( (RPC_EVENT_AUTH, request_id, e.__class__.__name__, diff --git a/deluge/core/torrentmanager.py b/deluge/core/torrentmanager.py index ad2033588..a59a742b4 100644 --- a/deluge/core/torrentmanager.py +++ b/deluge/core/torrentmanager.py @@ -448,7 +448,9 @@ class TorrentManager(component.Component): # Set auto_managed to False because the torrent is paused handle.auto_managed(False) # Create a Torrent object - owner = state.owner if state else (owner if owner else component.get("RPCServer").get_session_user()) + owner = state.owner if state else ( + owner if owner else component.get("RPCServer").get_session_user() + ) account_exists = component.get("AuthManager").has_account(owner) if not account_exists: owner = 'localclient' diff --git a/deluge/error.py b/deluge/error.py index 95d00fce8..c75091639 100644 --- a/deluge/error.py +++ b/deluge/error.py @@ -50,14 +50,23 @@ class InvalidTorrentError(DelugeError): class InvalidPathError(DelugeError): pass -class __PassthroughError(DelugeError): +class _PassthroughError(DelugeError): + + def _get_message(self): + return self._message + def _set_message(self, message): + self._message = message + message = property(_get_message, _set_message) + del _get_message, _set_message + def __new__(cls, *args, **kwargs): - inst = super(__PassthroughError, cls).__new__(cls, *args, **kwargs) + inst = super(_PassthroughError, cls).__new__(cls, *args, **kwargs) inst._args = args inst._kwargs = kwargs return inst -class NotAuthorizedError(__PassthroughError): +class NotAuthorizedError(_PassthroughError): + def __init__(self, current_level, required_level): self.message = _( "Auth level too low: %(current_level)s < %(required_level)s" % @@ -67,14 +76,7 @@ class NotAuthorizedError(__PassthroughError): self.required_level = required_level -class __UsernameBasedPasstroughError(__PassthroughError): - - def _get_message(self): - return self._message - def _set_message(self, message): - self._message = message - message = property(_get_message, _set_message) - del _get_message, _set_message +class _UsernameBasedPasstroughError(_PassthroughError): def _get_username(self): return self._username @@ -84,16 +86,16 @@ class __UsernameBasedPasstroughError(__PassthroughError): del _get_username, _set_username def __init__(self, message, username): - super(__UsernameBasedPasstroughError, self).__init__(message) + super(_UsernameBasedPasstroughError, self).__init__(message) self.message = message self.username = username -class BadLoginError(__UsernameBasedPasstroughError): +class BadLoginError(_UsernameBasedPasstroughError): pass -class AuthenticationRequired(__UsernameBasedPasstroughError): +class AuthenticationRequired(_UsernameBasedPasstroughError): pass -class AuthManagerError(__UsernameBasedPasstroughError): +class AuthManagerError(_UsernameBasedPasstroughError): pass diff --git a/deluge/ui/client.py b/deluge/ui/client.py index dc39fb192..58928024b 100644 --- a/deluge/ui/client.py +++ b/deluge/ui/client.py @@ -421,7 +421,7 @@ class DaemonSSLProxy(DaemonProxy): # Still log these errors log.error(error_data.value.logable()) return error_data - if isinstance(error_data.value, error.__PassthroughError): + if isinstance(error_data.value, error._PassthroughError): return error_data except: pass @@ -472,7 +472,7 @@ class DaemonSSLProxy(DaemonProxy): self.login_deferred.callback(result) def __on_login_fail(self, result): - log.debug("_on_login_fail(): %s", result) + log.debug("_on_login_fail(): %s", result.value) self.login_deferred.errback(result) def __on_auth_levels_mappings(self, result): @@ -529,12 +529,14 @@ class DaemonClassicProxy(DaemonProxy): log.exception(e) return defer.fail(e) else: - return defer.maybeDeferred(m, *copy.deepcopy(args), **copy.deepcopy(kwargs)) + return defer.maybeDeferred( + m, *copy.deepcopy(args), **copy.deepcopy(kwargs) + ) def register_event_handler(self, event, handler): """ - Registers a handler function to be called when `:param:event` is received - from the daemon. + Registers a handler function to be called when `:param:event` is + received from the daemon. :param event: the name of the event to handle :type event: str @@ -604,37 +606,39 @@ class Client(object): :returns: a Deferred object that will be called once the connection has been established or fails """ + self._daemon_proxy = DaemonSSLProxy(dict(self.__event_handlers)) self._daemon_proxy.set_disconnect_callback(self.__on_disconnect) + d = self._daemon_proxy.connect(host, port) - auth_deferred = defer.Deferred() def on_connect_fail(reason): self.disconnect() - auth_deferred.errback(reason) return reason + + def on_authenticate(result, daemon_info): + log.debug("Authentication sucessfull: %s", result) + return result + + def on_authenticate_fail(reason): + log.debug("Failed to authenticate: %s", reason.value) + return reason + + def on_connected(daemon_version): + log.debug("Client.connect.on_connected. Daemon version: %s", + daemon_version) + return daemon_version + + def authenticate(daemon_version, username, password): + d = self._daemon_proxy.authenticate(username, password) + d.addCallback(on_authenticate, daemon_version) + d.addErrback(on_authenticate_fail) + return d + + d.addCallback(on_connected) d.addErrback(on_connect_fail) - if not skip_authentication: - - def on_authenticate(result, daemon_info): - log.debug("Authentication sucessfull: %s", result) - auth_deferred.callback(daemon_info) - - def on_authenticate_fail(reason): - log.debug("Failed to authenticate") - log.exception(reason) - auth_deferred.errback(reason) - - def on_connected(daemon_version): - log.debug("Client.connect.on_connected. Daemon version: %s", - daemon_version) - d = self._daemon_proxy.authenticate(username, password) - d.addCallback(on_authenticate, daemon_version) - d.addErrback(on_authenticate_fail) - - d.addCallback(on_connected) - return auth_deferred + d.addCallback(authenticate, username, password) return d def disconnect(self): diff --git a/deluge/ui/gtkui/connectionmanager.py b/deluge/ui/gtkui/connectionmanager.py index 09341c8b6..c61fe4a6c 100644 --- a/deluge/ui/gtkui/connectionmanager.py +++ b/deluge/ui/gtkui/connectionmanager.py @@ -48,8 +48,7 @@ from deluge.ui.common import get_localhost_auth from deluge.ui.client import client import deluge.ui.client from deluge.configmanager import ConfigManager -from deluge.error import AuthenticationRequired -from deluge.log import LOG as log +from deluge.error import AuthenticationRequired, BadLoginError import dialogs log = logging.getLogger(__name__) @@ -187,6 +186,9 @@ class ConnectionManager(component.Component): # Connect the signals to the handlers self.glade.signal_autoconnect(self) + self.hostlist.get_selection().connect( + "changed", self.on_hostlist_selection_changed + ) # Load any saved host entries self.__load_hostlist() @@ -361,7 +363,9 @@ class ConnectionManager(component.Component): """ Set the widgets to show the correct options from the config. """ - self.autoconnect_host_id = self.gtkui_config['autoconnect_host_id'] + self.glade.get_widget("chk_autoconnect").set_active( + self.gtkui_config["autoconnect"] + ) self.glade.get_widget("chk_autostart").set_active( self.gtkui_config["autostart_localhost"] ) @@ -389,25 +393,20 @@ class ConnectionManager(component.Component): self.glade.get_widget("image_startdaemon").set_from_stock( gtk.STOCK_EXECUTE, gtk.ICON_SIZE_MENU) self.glade.get_widget("label_startdaemon").set_text("_Start Daemon") - self.glade.get_widget("chk_autoconnect").set_sensitive(False) model, row = self.hostlist.get_selection().get_selected() if not row: self.glade.get_widget("button_edithost").set_sensitive(False) - self.glade.get_widget("chk_autoconnect").set_sensitive(False) return self.glade.get_widget("button_edithost").set_sensitive(True) - self.glade.get_widget("chk_autoconnect").set_sensitive(True) # Get some values about the selected host status = model[row][HOSTLIST_COL_STATUS] - hostid = model[row][HOSTLIST_COL_ID] host = model[row][HOSTLIST_COL_HOST] - - self.glade.get_widget("chk_autoconnect").set_active( - hostid == self.gtkui_config["autoconnect_host_id"] - ) + port = model[row][HOSTLIST_COL_PORT] + user = model[row][HOSTLIST_COL_USER] + passwd = model[row][HOSTLIST_COL_PASS] log.debug("Status: %s", status) # Check to see if we have a localhost entry selected @@ -445,8 +444,14 @@ class ConnectionManager(component.Component): self.glade.get_widget("label_startdaemon").set_text( _("_Start Daemon")) - if not localhost: - # An offline host + if client.connected() and (host, port, user) == client.connection_info(): + # If we're connected, we can stop the dameon + self.glade.get_widget("button_startdaemon").set_sensitive(True) + elif user and passwd: + # In this case we also have all the info to shutdown the dameon + self.glade.get_widget("button_startdaemon").set_sensitive(True) + else: + # Can't stop non localhost daemons, specially without the necessary info self.glade.get_widget("button_startdaemon").set_sensitive(False) # Make sure label is displayed correctly using mnemonics @@ -493,16 +498,16 @@ class ConnectionManager(component.Component): def __on_connected(self, daemon_info, host_id): if self.gtkui_config["autoconnect"]: self.gtkui_config["autoconnect_host_id"] = host_id - self.connection_manager.response(gtk.RESPONSE_OK) component.start() def __on_connected_failed(self, reason, host_id, host, port, user): log.debug("Failed to connect: %s", reason) - if reason.check(AuthenticationRequired): + if reason.check(AuthenticationRequired, BadLoginError): log.debug("PasswordRequired exception") - dialog = dialogs.AuthenticationDialog(reason.value.message, - reason.value.username) + dialog = dialogs.AuthenticationDialog( + reason.value.message, reason.value.username + ) def dialog_finished(response_id, host, port, user): if response_id == gtk.RESPONSE_OK: self.__connect(host_id, host, port, @@ -547,6 +552,7 @@ class ConnectionManager(component.Component): time.sleep(0.5) do_retry_connect(try_counter) return result + def do_retry_connect(try_counter): d = client.connect(host, port, user, password) d.addCallback(self.__on_connected, host_id) @@ -657,9 +663,11 @@ class ConnectionManager(component.Component): log.debug("on_button_startdaemon_clicked") if self.liststore.iter_n_children(None) < 1: # There is nothing in the list, so lets create a localhost entry - self.add_host(DEFAULT_HOST, DEFAULT_PORT) + self.add_host(DEFAULT_HOST, DEFAULT_PORT, *get_localhost_auth()) # ..and start the daemon. - self.start_daemon(DEFAULT_PORT, deluge.configmanager.get_config_dir()) + self.start_daemon( + DEFAULT_PORT, deluge.configmanager.get_config_dir() + ) return paths = self.hostlist.get_selection().get_selected_rows()[1] @@ -681,9 +689,10 @@ class ConnectionManager(component.Component): def on_daemon_shutdown(d): # Update display to show change self.__update_list() + if client.connected() and client.connection_info() == (host, port, user): client.daemon.shutdown().addCallback(on_daemon_shutdown) - else: + elif user and password: # Create a new client instance c = deluge.ui.client.Client() def on_connect(d, c): @@ -712,44 +721,6 @@ class ConnectionManager(component.Component): def on_askpassword_dialog_entry_activate(self, entry): self.askpassword_dialog.response(gtk.RESPONSE_OK) - def on_hostlist_cursor_changed(self, widget): - paths = self.hostlist.get_selection().get_selected_rows()[1] - if len(paths) < 1: - self.glade.get_widget("chk_autoconnect").set_sensitive(False) - return - else: - self.glade.get_widget("chk_autoconnect").set_sensitive(True) - - hostid = self.liststore[paths[0]][HOSTLIST_COL_ID] - self.glade.get_widget("chk_autoconnect").set_active( - hostid == self.gtkui_config["autoconnect_host_id"] - ) - - def on_chk_autoconnect_toggled(self, widget): - paths = self.hostlist.get_selection().get_selected_rows()[1] - if len(paths) < 1: - self.glade.get_widget("chk_autoconnect").set_sensitive(False) - self.glade.get_widget("chk_autostart").set_sensitive(False) - return - else: - self.glade.get_widget("chk_autoconnect").set_sensitive(True) - - self.glade.get_widget("chk_autostart").set_sensitive(widget.get_active()) - - hostid = self.liststore[paths[0]][HOSTLIST_COL_ID] - - if widget.get_active(): - if self.autoconnect_host_id != hostid: - self.gtkui_config["autoconnect_host_id"] = hostid - self.autoconnect_host_id = hostid - self.gtkui_config.save() - return - - if self.autoconnect_host_id == hostid: - self.gtkui_config["autoconnect_host_id"] = None - self.autoconnect_host_id = None - self.gtkui_config.save() - def __migrate_config_1_to_2(self, config): localclient_username, localclient_password = get_localhost_auth() if not localclient_username: diff --git a/deluge/ui/gtkui/glade/connection_manager.glade b/deluge/ui/gtkui/glade/connection_manager.glade index 35cea0e4c..cd343c81e 100644 --- a/deluge/ui/gtkui/glade/connection_manager.glade +++ b/deluge/ui/gtkui/glade/connection_manager.glade @@ -1,8 +1,9 @@ - + + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 5 Add Host @@ -13,16 +14,83 @@ True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 2 + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + end + + + gtk-cancel + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False + True + + + False + False + 0 + + + + + gtk-add + 1 + True + True + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False + True + + + False + False + 1 + + + + + gtk-save + 2 + True + True + False + True + + + False + False + 2 + + + + + False + True + end + 0 + + True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 5 True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK Hostname: @@ -35,6 +103,7 @@ True + False 1 @@ -42,16 +111,23 @@ True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True + False + False + True + True + True + True 1 True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK Port: @@ -69,6 +145,10 @@ 5 5 1 + False + False + True + True 58846 0 65535 1 10 0 1 True @@ -89,17 +169,23 @@ True + False 2 2 True + False 5 True True False + False + False + True + True @@ -113,11 +199,16 @@ True + False 5 True True + False + False + True + True @@ -129,6 +220,7 @@ True + False Password: @@ -140,6 +232,7 @@ True + False Username: @@ -149,25 +242,46 @@ False + True 2 + + + + + False + 5 + Password Required + True + center-on-parent + 320 + True + dialog + True + + + True + False + 2 - + True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False end - - gtk-cancel + + gtk-connect + 1 True True True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False True + False @@ -175,49 +289,61 @@ 0 + + + False + True + end + 0 + + + + + True + False - - gtk-add - 1 + True - True - True - True - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - True + False + gtk-dialog-authentication + 6 - False - False - 1 + True + True + 0 - - gtk-save - 2 + + True True - True - True + False + + False + False + True + True + - False - False - 2 + True + True + 1 - False - end - 0 + True + True + 1 + False True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK @@ -232,16 +358,33 @@ True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 2 + + + False + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + end + + + False + False + end + 0 + + True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 5 True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK gtk-missing-image @@ -254,18 +397,21 @@ True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK <big><b>Connection Manager</b></big> True False + True 1 False + True 5 1 @@ -273,11 +419,13 @@ True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 5 True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK queue @@ -292,7 +440,6 @@ True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - @@ -300,16 +447,20 @@ + True + True 0 True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK start @@ -319,6 +470,7 @@ True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False True @@ -332,9 +484,9 @@ gtk-edit True - False True True + False True @@ -351,6 +503,7 @@ True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False True @@ -367,51 +520,44 @@ 0 - - - gtk-refresh - True - True - True - True - - - - False - False - 2 - - True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 2 True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK gtk-execute + True + True 0 True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK _Start local daemon True + True + True 1 @@ -425,6 +571,22 @@ 1 + + + gtk-refresh + True + True + True + False + True + + + + False + False + 2 + + False @@ -434,6 +596,8 @@ + True + True 10 2 @@ -446,6 +610,7 @@ True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 5 5 @@ -454,6 +619,7 @@ True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK @@ -462,31 +628,30 @@ True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False True + True + True 0 - + + Automatically start localhost if needed True - 15 - - - Automatically start localhost if needed - True - False - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - True - - - + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False + True + + True + True 1 @@ -497,10 +662,13 @@ True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False True + True + True 2 @@ -511,6 +679,7 @@ True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK Options @@ -521,12 +690,14 @@ False + True 3 True + False end @@ -535,6 +706,7 @@ True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False True @@ -550,6 +722,7 @@ True True True + False True @@ -566,92 +739,6 @@ 4 - - - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - end - - - False - False - end - 0 - - - - - - - 5 - Password Required - True - center-on-parent - 320 - True - dialog - True - - - True - 2 - - - True - - - True - gtk-dialog-authentication - 6 - - - 0 - - - - - True - True - False - - - - - 1 - - - - - 1 - - - - - True - end - - - gtk-connect - 1 - True - True - True - True - - - - False - False - 0 - - - - - False - end - 0 - - diff --git a/deluge/ui/gtkui/gtkui.py b/deluge/ui/gtkui/gtkui.py index 849660542..b87c56a2f 100644 --- a/deluge/ui/gtkui/gtkui.py +++ b/deluge/ui/gtkui/gtkui.py @@ -327,14 +327,30 @@ Please see the details below for more information."), details=traceback.format_e def __start_non_classic(self): # Autoconnect to a host if self.config["autoconnect"]: - for host in self.connectionmanager.config["hosts"]: - if host[0] == self.config["autoconnect_host_id"]: + + def update_connection_manager(): + if not self.connectionmanager.running: + return + self.connectionmanager.glade.get_widget( + "button_refresh" + ).emit("clicked") + + def close_connection_manager(): + if not self.connectionmanager.running: + return + self.connectionmanager.glade.get_widget( + "button_close" + ).emit("clicked") + + for host_config in self.connectionmanager.config["hosts"]: + hostid, host, port, user, passwd = host_config + if hostid == self.config["autoconnect_host_id"]: try_connect = True # Check to see if we need to start the localhost daemon - if self.config["autostart_localhost"] and host[1] in ("localhost", "127.0.0.1"): - log.debug("Autostarting localhost:%s", host[2]) + if self.config["autostart_localhost"] and host in ("localhost", "127.0.0.1"): + log.debug("Autostarting localhost:%s", host) try_connect = client.start_daemon( - host[2], deluge.configmanager.get_config_dir() + port, deluge.configmanager.get_config_dir() ) log.debug("Localhost started: %s", try_connect) if not try_connect: @@ -345,57 +361,54 @@ Please see the details below for more information."), details=traceback.format_e "to see if there is an error.") ).run() -# def refresh_connection_manager_list(): -# try: -# self.connectionmanager.glade.get_widget( -# "button_refresh" -# ).emit("clicked") -# except: -# pass -# -# reactor.callLatter(1, refresh_connection_manager_list) - - def update_connection_manager(): - if not self.connectionmanager.running: - return - self.connectionmanager.glade.get_widget( - "button_refresh" - ).emit("clicked") - - def close_connection_manager(): - if not self.connectionmanager.running: - return - self.connectionmanager.glade.get_widget( - "button_close" - ).emit("clicked") - + # Daemon Started, let's update it's info + reactor.callLater(0.5, update_connection_manager) def on_connect(connector): - print 'ON GTK UI CONNECT!!!!\n\n' component.start() - reactor.callLater(0.5, update_connection_manager) - reactor.callLater(1, close_connection_manager) + reactor.callLater(0.2, update_connection_manager) + reactor.callLater(0.5, close_connection_manager) + + def on_connect_fail(reason, try_counter, + host, port, user, passwd): + if not try_counter: + return + + if reason.check(deluge.error.AuthenticationRequired, + deluge.error.BadLoginError): + log.debug("PasswordRequired exception") + dialog = dialogs.AuthenticationDialog( + reason.value.message, reason.value.username + ) + def dialog_finished(response_id, host, port): + if response_id == gtk.RESPONSE_OK: + reactor.callLater( + 0.5, do_connect, try_counter-1, + host, port, dialog.get_username(), + dialog.get_password()) + dialog.run().addCallback(dialog_finished, + host, port) + return - def on_connect_fail(result, try_counter): log.error("Connection to host failed..") - # We failed connecting to the daemon, but lets try again - if try_counter: - log.info("Retrying connection.. Retries left: " - "%s", try_counter) - try_counter -= 1 - import time - time.sleep(0.5) - do_connect(try_counter) - reactor.callLater(0.5, update_connection_manager) - return result + log.info("Retrying connection.. Retries left: " + "%s", try_counter) + reactor.callLater(0.5, update_connection_manager) + reactor.callLater(0.5, do_connect, try_counter-1, + host, port, user, passwd) - def do_connect(try_counter): - d = client.connect(*host[1:]) + def do_connect(try_counter, host, port, user, passwd): + log.debug("Trying to connect to %s@%s:%s", + user, host, port) + d = client.connect(host, port, user, passwd) d.addCallback(on_connect) - d.addErrback(on_connect_fail, try_counter) + d.addErrback(on_connect_fail, try_counter, + host, port, user, passwd) if try_connect: - do_connect(6) + reactor.callLater( + 0.5, do_connect, 6, host, port, user, passwd + ) break if self.config["show_connection_manager_on_start"]: