diff --git a/deluge/core/daemon.py b/deluge/core/daemon.py index 968534900..383264dbd 100644 --- a/deluge/core/daemon.py +++ b/deluge/core/daemon.py @@ -191,17 +191,6 @@ class Daemon(object): except twisted.internet.error.ReactorNotRunning: log.debug("Tried to stop the reactor but it is not running..") - @export() - def info(self): - """ - Returns some info from the daemon. - - :returns: str, the version number - """ - print '\n\ndaemon.info called\n\n' - - return deluge.common.get_version() - @export() def get_method_list(self): """ diff --git a/deluge/core/rpcserver.py b/deluge/core/rpcserver.py index 9beb2c201..60e190593 100644 --- a/deluge/core/rpcserver.py +++ b/deluge/core/rpcserver.py @@ -56,11 +56,12 @@ 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 +from deluge.error import DelugeError, NotAuthorizedError, AuthenticationRequired RPC_RESPONSE = 1 RPC_ERROR = 2 RPC_EVENT = 3 +RPC_EVENT_AUTH = 4 log = logging.getLogger(__name__) @@ -261,6 +262,8 @@ class DelugeRPCProtocol(Protocol): if ret: self.factory.authorized_sessions[self.transport.sessionno] = (ret, args[0]) self.factory.session_protocols[self.transport.sessionno] = self + except AuthenticationRequired, err: + self.sendData((RPC_EVENT_AUTH, request_id, err.message, args[0])) except Exception, e: sendError() log.exception(e) diff --git a/deluge/error.py b/deluge/error.py index eed5309f4..055d6b338 100644 --- a/deluge/error.py +++ b/deluge/error.py @@ -56,6 +56,23 @@ class BadLoginError(DelugeError): pass class AuthenticationRequired(BadLoginError): + 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 _get_username(self): + return self._username + def _set_username(self, username): + self._username = username + username = property(_get_username, _set_username) + del _get_username, _set_username + + def __init__(self, message, username): super(AuthenticationRequired, self).__init__(message) + self.message = message self.username = username + diff --git a/deluge/ui/client.py b/deluge/ui/client.py index f71956175..60e51dbf0 100644 --- a/deluge/ui/client.py +++ b/deluge/ui/client.py @@ -46,6 +46,8 @@ import zlib import deluge.common import deluge.component as component from deluge.log import LOG as log +from deluge.error import AuthenticationRequired +from deluge.event import known_events if deluge.common.windows_check(): import win32api @@ -55,6 +57,7 @@ else: RPC_RESPONSE = 1 RPC_ERROR = 2 RPC_EVENT = 3 +RPC_EVENT_AUTH = 4 log = logging.getLogger(__name__) @@ -184,6 +187,8 @@ class DelugeRPCProtocol(Protocol): if message_type == RPC_RESPONSE: # Run the callbacks registered with this Deferred object d.callback(request[2]) + elif message_type == RPC_EVENT_AUTH: + d.errback(AuthenticationRequired(request[2], request[3])) elif message_type == RPC_ERROR: # Create the DelugeRPCError to pass to the errback r = self.__rpc_requests[request_id] @@ -382,8 +387,19 @@ class DaemonSSLProxy(DaemonProxy): :param error_data: this is passed from the deferred errback with error.value containing a `:class:DelugeRPCError` object. """ + try: + if error_data.check(AuthenticationRequired): + print error_data.value.__dict__ + return error_data + except: + pass + +# print 1234567, error_data # Get the DelugeRPCError object from the error_data error = error_data.value + +# if error.exception_type == "AuthenticationRequired": +# return # Create a delugerpcrequest to print out a nice RPCRequest string r = DelugeRPCRequest() r.method = error.method @@ -545,7 +561,8 @@ class Client(object): self.disconnect_callback = None self.__started_in_classic = False - def connect(self, host="127.0.0.1", port=58846, username="", password=""): + def connect(self, host="127.0.0.1", port=58846, username="", password="", + skip_authentication=False): """ Connects to a daemon process. @@ -573,7 +590,7 @@ class Client(object): return result d.addErrback(on_connect_fail) - if username or password: + if not skip_authentication: auth_deferred = defer.Deferred() def on_authenticate(result, daemon_info): diff --git a/deluge/ui/gtkui/connectionmanager.py b/deluge/ui/gtkui/connectionmanager.py index 5066c067c..7af987bd9 100644 --- a/deluge/ui/gtkui/connectionmanager.py +++ b/deluge/ui/gtkui/connectionmanager.py @@ -48,6 +48,8 @@ from deluge.ui.client import client import deluge.ui.client import deluge.ui.common from deluge.configmanager import ConfigManager +from deluge.error import AuthenticationRequired +from deluge.log import LOG as log import dialogs log = logging.getLogger(__name__) @@ -234,7 +236,11 @@ class ConnectionManager(component.Component): # Grab the hosts from the liststore self.config["hosts"] = [] for row in self.liststore: - self.config["hosts"].append((row[HOSTLIST_COL_ID], row[HOSTLIST_COL_HOST], row[HOSTLIST_COL_PORT], row[HOSTLIST_COL_USER], row[HOSTLIST_COL_PASS])) + self.config["hosts"].append((row[HOSTLIST_COL_ID], + row[HOSTLIST_COL_HOST], + row[HOSTLIST_COL_PORT], + row[HOSTLIST_COL_USER], + row[HOSTLIST_COL_PASS])) self.config.save() @@ -250,6 +256,7 @@ class ConnectionManager(component.Component): self.liststore[new_row][HOSTLIST_COL_USER] = host[3] self.liststore[new_row][HOSTLIST_COL_PASS] = host[4] self.liststore[new_row][HOSTLIST_COL_STATUS] = _("Offline") + self.liststore[new_row][HOSTLIST_COL_VERSION] = "" def __get_host_row(self, host_id): """ @@ -300,7 +307,7 @@ class ConnectionManager(component.Component): row = self.__get_host_row(host_id) if row: row[HOSTLIST_COL_STATUS] = _("Offline") -# row[HOSTLIST_COL_VERSION] = "" + row[HOSTLIST_COL_VERSION] = "" self.__update_buttons() for row in self.liststore: @@ -312,21 +319,15 @@ class ConnectionManager(component.Component): if client.connected() and \ (host, port, "localclient" if not user and host in ("127.0.0.1", "localhost") else user) == client.connection_info(): def on_info(info): - log.debug("\n\nClient connected, query info: %s:%s\n\n", info, self.running) if not self.running: return + log.debug("Client connected, query info: %s", info) row[HOSTLIST_COL_VERSION] = info self.__update_buttons() - print row[HOSTLIST_COL_ID], row[HOSTLIST_COL_HOST], row[HOSTLIST_COL_PORT], row[HOSTLIST_COL_USER], row[HOSTLIST_COL_VERSION] - - def on_info_fail(reason): - print '\n\n' - log.exception(reason) - print '\n\n' row[HOSTLIST_COL_STATUS] = _("Connected") log.debug("\n\nquery daemons info\n\n") - client.daemon.info().addCallback(on_info).addErrback(on_info_fail) + client.daemon.info().addCallback(on_info) continue # Create a new Client instance @@ -446,7 +447,8 @@ that you forgot to install the deluged package or it's not in your PATH.")).run( # Signal handlers def __connect(self, host_id, host, port, username, password): def do_connect(*args): - d = client.connect(host, port, username, password) + d = client.connect(host, port, username, password, + skip_authentication=False) d.addCallback(self.__on_connected, host_id) d.addErrback(self.__on_connected_failed, host_id, host, port, username) return d @@ -457,27 +459,19 @@ that you forgot to install the deluged package or it's not in your PATH.")).run( return do_connect() def __on_connected(self, daemon_info, host_id): -# log.debug("__on_connected called for hostid: %s connector: %s", -# host_id, daemon_info) if self.gtkui_config["autoconnect"]: self.gtkui_config["autoconnect_host_id"] = host_id -# row = self.__get_host_row(host_id) -# row[HOSTLIST_COL_STATUS] = _("Connected") -# row[HOSTLIST_COL_VERSION] = daemon_info -# -# # Update the status of the hosts -# self.__update_list() - self.connection_manager.response(gtk.RESPONSE_OK) - component.start() def __on_connected_failed(self, reason, host_id, host, port, user): - log.exception(reason) - if reason.value.exception_type == "PasswordRequired": + log.exception(reason.value) +# log.debug(reason.__dict__) +# log.debug(reason.value.__dict__) + if reason.check(AuthenticationRequired): log.debug("PasswordRequired exception") - dialog = dialogs.AuthenticationDialog(reason.value.exception_msg) + dialog = dialogs.AuthenticationDialog(reason.value.message) def dialog_finished(response_id, host, port, user): if response_id == gtk.RESPONSE_OK: self.__connect(host_id, host, port, user, diff --git a/deluge/ui/gtkui/dialogs.py b/deluge/ui/gtkui/dialogs.py index d4be76e08..b936c17a7 100644 --- a/deluge/ui/gtkui/dialogs.py +++ b/deluge/ui/gtkui/dialogs.py @@ -197,7 +197,7 @@ class AuthenticationDialog(BaseDialog): When run(), it will return either a gtk.RESPONSE_CANCEL or a gtk.RESPONSE_OK. """ - def __init__(self, err_msg="", parent=None): + def __init__(self, err_msg="", username=None, parent=None): """ :param err_msg: the error message we got back from the server :type err_msg: string