def show(self, available_version): self.config = ConfigManager("gtkui.conf") glade = component.get("MainWindow").main_glade self.dialog = glade.get_object("new_release_dialog") # Set the version labels if deluge.common.windows_check() or deluge.common.osx_check(): glade.get_object("image_new_release").set_from_file( deluge.common.get_pixmap("deluge16.png")) else: glade.get_object("image_new_release").set_from_icon_name( "deluge", 4) glade.get_object("label_available_version").set_text(available_version) glade.get_object("label_client_version").set_text( deluge.common.get_version()) self.chk_not_show_dialog = glade.get_object( "chk_do_not_show_new_release") glade.get_object("button_goto_downloads").connect( "clicked", self._on_button_goto_downloads) glade.get_object("button_close_new_release").connect( "clicked", self._on_button_close_new_release) if client.connected(): def on_info(version): glade.get_object("label_server_version").set_text(version) glade.get_object("label_server_version").show() glade.get_object("label_server_version_text").show() if not client.is_classicmode(): glade.get_object("label_client_version_text").set_label( _("<i>Client Version</i>")) client.daemon.info().addCallback(on_info) self.dialog.show()
def quit(self, shutdown=False): """ Quits the GtkUI :param shutdown: whether or not to shutdown the daemon as well :type shutdown: boolean """ if shutdown: def on_daemon_shutdown(result): reactor.stop() client.daemon.shutdown().addCallback(on_daemon_shutdown) return if client.is_classicmode(): reactor.stop() return if not client.connected(): reactor.stop() return def on_client_disconnected(result): reactor.stop() client.disconnect().addCallback(on_client_disconnected)
def handle(self, *args, **options): if client.connected(): def on_disconnect(result): reactor.stop() return client.disconnect().addCallback(on_disconnect) else: reactor.stop()
def quit(self, shutdown=False): """ Quits the GtkUI :param shutdown: whether or not to shutdown the daemon as well :type shutdown: boolean """ if shutdown: def on_daemon_shutdown(result): try: reactor.stop() except ReactorNotRunning: log.debug( "Attempted to stop the reactor but it is not running..." ) client.daemon.shutdown().addCallback(on_daemon_shutdown) return if client.is_classicmode(): reactor.stop() return if not client.connected(): reactor.stop() return def on_client_disconnected(result): reactor.stop() client.disconnect().addCallback(on_client_disconnected)
def handle(self, host="127.0.0.1:58846", username="", password="", **options): self.console = component.get("ConsoleUI") try: host, port = host.split(":") except ValueError: port = 58846 else: port = int(port) def do_connect(): d = client.connect(host, port, username, password) def on_connect(result): self.console.write("{!success!}Connected to %s:%s!" % (host, port)) component.start() def on_connect_fail(result): self.console.write("{!error!}Failed to connect to %s:%s with reason: %s" % (host, port, result.value.args[0])) d.addCallback(on_connect) d.addErrback(on_connect_fail) return d if client.connected(): def on_disconnect(result): do_connect() client.disconnect().addCallback(on_disconnect) else: do_connect()
def update_statusbars(self): # Update the topbar string self.topbar = '{!status!}Deluge %s Console - ' % deluge.common.get_version() if client.connected(): info = client.connection_info() connection_info = '' # Client name if info[2] == 'localclient': connection_info += '{!white,blue!}%s' else: connection_info += '{!green,blue,bold!}%s' # Hostname if info[0] == '127.0.0.1': connection_info += '{!white,blue,bold!}@{!white,blue!}%s' else: connection_info += '{!white,blue,bold!}@{!red,blue,bold!}%s' # Port if info[1] == DEFAULT_PREFS['daemon_port']: connection_info += '{!white,blue!}:%s' else: connection_info += '{!status!}:%s' # Change color back to normal, just in case connection_info += '{!status!}' self.topbar += connection_info % (info[2], info[0], info[1]) else: self.topbar += 'Not Connected' # Update the bottombar string self.bottombar = '{!status!}C: {!white,blue!}%s{!status!}' % self.connections if self.config['max_connections_global'] > -1: self.bottombar += ' (%s)' % self.config['max_connections_global'] if self.download != '0.0 KiB': self.bottombar += ' D: {!magenta,blue,bold!}%s{!status!}' % self.download else: self.bottombar += ' D: {!white,blue!}%s{!status!}' % self.download if self.config['max_download_speed'] > -1: self.bottombar += ' (%s ' % self.config['max_download_speed'] + _('KiB/s') + ')' if self.upload != '0.0 KiB': self.bottombar += ' U: {!green,blue,bold!}%s{!status!}' % self.upload else: self.bottombar += ' U: {!white,blue!}%s{!status!}' % self.upload if self.config['max_upload_speed'] > -1: self.bottombar += ' (%s ' % self.config['max_upload_speed'] + _('KiB/s') + ')' if self.config['dht']: self.bottombar += ' ' + _('DHT') + ': {!white,blue!}%s{!status!}' % self.dht self.bottombar += ' ' + _('IP {!white,blue!}%s{!status!}') % ( self.external_ip if self.external_ip else _('n/a'))
def update_statusbars(self): # Update the topbar string self.screen.topbar = "{!status!}Deluge %s Console - " % deluge.common.get_version( ) if client.connected(): info = client.connection_info() self.screen.topbar += "%s@%s:%s" % (info[2], info[0], info[1]) else: self.screen.topbar += "Not Connected" # Update the bottombar string self.screen.bottombar = "{!status!}C: %s" % self.connections if self.config["max_connections_global"] > -1: self.screen.bottombar += " (%s)" % self.config[ "max_connections_global"] self.screen.bottombar += " D: %s" % self.download if self.config["max_download_speed"] > -1: self.screen.bottombar += " (%s " % self.config[ "max_download_speed"] + _("KiB/s") + ")" self.screen.bottombar += " U: %s" % self.upload if self.config["max_upload_speed"] > -1: self.screen.bottombar += " (%s " % self.config[ "max_upload_speed"] + _("KiB/s") + ")" if self.config["dht"]: self.screen.bottombar += " " + _("DHT") + ": %s" % self.dht self.screen.refresh()
def quit(self, shutdown=False): """ Quits the GtkUI :param shutdown: whether or not to shutdown the daemon as well :type shutdown: boolean """ def shutdown_daemon(result): return client.daemon.shutdown() def disconnect_client(result): return client.disconnect() def stop_reactor(result): try: reactor.stop() except ReactorNotRunning: log.debug("Attempted to stop the reactor but it is not running...") def log_failure(failure, action): log.error("Encountered error attempting to %s: %s" % \ (action, failure.getErrorMessage())) d = defer.succeed(None) if shutdown: d.addCallback(shutdown_daemon) d.addErrback(log_failure, "shutdown daemon") if not client.is_classicmode() and client.connected(): d.addCallback(disconnect_client) d.addErrback(log_failure, "disconnect client") d.addBoth(stop_reactor)
def handle(self, host="127.0.0.1:58846", username="", password="", **options): self.console = component.get("ConsoleUI") try: host, port = host.split(":") except ValueError: port = 58846 else: port = int(port) def do_connect(): d = client.connect(host, port, username, password) def on_connect(result): if self.console.interactive: self.console.write("{!success!}Connected to %s:%s" % (host, port)) return component.start() def on_connect_fail(result): try: msg = result.value.exception_msg except: msg = result.value.args[0] self.console.write("{!error!}Failed to connect to %s:%s with reason: %s" % (host, port, msg)) return result d.addCallback(on_connect) d.addErrback(on_connect_fail) return d if client.connected(): def on_disconnect(result): self.console.statusbars.update_statusbars() return do_connect() return client.disconnect().addCallback(on_disconnect) else: return do_connect()
def show(self, available_version): self.config = ConfigManager("gtkui.conf") glade = component.get("MainWindow").main_glade self.dialog = glade.get_widget("new_release_dialog") # Set the version labels if deluge.common.windows_check() or deluge.common.osx_check(): glade.get_widget("image_new_release").set_from_file( deluge.common.get_pixmap("deluge16.png")) else: glade.get_widget("image_new_release").set_from_icon_name("deluge", 4) glade.get_widget("label_available_version").set_text(available_version) glade.get_widget("label_client_version").set_text( deluge.common.get_version()) self.chk_not_show_dialog = glade.get_widget("chk_do_not_show_new_release") glade.get_widget("button_goto_downloads").connect( "clicked", self._on_button_goto_downloads) glade.get_widget("button_close_new_release").connect( "clicked", self._on_button_close_new_release) if client.connected(): def on_info(version): glade.get_widget("label_server_version").set_text(version) glade.get_widget("label_server_version").show() glade.get_widget("label_server_version_text").show() if not client.is_classicmode(): glade.get_widget("label_client_version_text").set_label(_("<i>Client Version</i>")) client.daemon.info().addCallback(on_info) self.dialog.show()
def quit_gtkui(): def shutdown_daemon(result): return client.daemon.shutdown() def disconnect_client(result): return client.disconnect() def stop_reactor(result): try: reactor.stop() except ReactorNotRunning: log.debug("Attempted to stop the reactor but it is not running...") def log_failure(failure, action): log.error("Encountered error attempting to %s: %s" % \ (action, failure.getErrorMessage())) d = defer.succeed(None) if shutdown: d.addCallback(shutdown_daemon) d.addErrback(log_failure, "shutdown daemon") if not client.is_classicmode() and client.connected(): d.addCallback(disconnect_client) d.addErrback(log_failure, "disconnect client") d.addBoth(stop_reactor)
def quit(self, shutdown=False): """ Quits the GtkUI :param shutdown: whether or not to shutdown the daemon as well :type shutdown: boolean """ if shutdown: def on_daemon_shutdown(result): try: reactor.stop() except ReactorNotRunning: log.debug("Attempted to stop the reactor but it is not running...") client.daemon.shutdown().addCallback(on_daemon_shutdown) return if client.is_classicmode(): reactor.stop() return if not client.connected(): reactor.stop() return def on_client_disconnected(result): reactor.stop() client.disconnect().addCallback(on_client_disconnected)
def __init__(self, parent): QtGui.QDialog.__init__( self, parent, QtCore.Qt.WindowTitleHint | QtCore.Qt.WindowSystemMenuHint) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.setupUi(self) about_text = self.label_about.text() if client.is_classicmode(): # drop the "Server Version" line about_text = re.sub(r"(?m)^.+\$server_version.*$", "", about_text) self._template = string.Template(about_text) self._variables = { "version": deluge.common.get_version(), "server_version": "...", "lt_version": "...", "qt_version": QtCore.QT_VERSION_STR, "pyqt_version": QtCore.PYQT_VERSION_STR } self.label_about.setText( self._template.safe_substitute(self._variables)) if client.connected(): self._get_versions()
def update_statusbars(self): # Update the topbar string self.screen.topbar = "{!status!}Deluge %s Console - " % deluge.common.get_version() if client.connected(): info = client.connection_info() self.screen.topbar += "%s@%s:%s" % (info[2], info[0], info[1]) else: self.screen.topbar += "Not Connected" # Update the bottombar string self.screen.bottombar = "{!status!}C: %s" % self.connections if self.config["max_connections_global"] > -1: self.screen.bottombar += " (%s)" % self.config["max_connections_global"] self.screen.bottombar += " D: %s" % self.download if self.config["max_download_speed"] > -1: self.screen.bottombar += " (%s " % self.config["max_download_speed"] + _("KiB/s") + ")" self.screen.bottombar += " U: %s" % self.upload if self.config["max_upload_speed"] > -1: self.screen.bottombar += " (%s " % self.config["max_upload_speed"] + _("KiB/s") + ")" if self.config["dht"]: self.screen.bottombar += " " + _("DHT") + ": %s" % self.dht self.screen.refresh()
def connected(self): """ The current connection state. :returns: True if the client is connected :rtype: booleon """ return client.connected()
def on_button_connect_clicked(self, checked=False): host = self.selectedItem() # NB: get it before accept closes and deletes the dialog self.accept() if client.connected(): yield client.disconnect() component.get("ConnectionManager").connect(host.config_tuple(), autostart=not host.is_alive())
def connected(self): """ The current connection state. :returns: True if the client is connected :rtype: boolean """ return client.connected()
def update_statusbars(self): # Update the topbar string self.topbar = "{!status!}Deluge %s Console - " % deluge.common.get_version() if client.connected(): info = client.connection_info() connection_info = "" #Client name if info[2] == "localclient": connection_info += "{!white,blue!}%s" else: connection_info += "{!green,blue,bold!}%s" #Hostname if info[0] == "127.0.0.1": connection_info += "{!white,blue,bold!}@{!white,blue!}%s" else: connection_info += "{!white,blue,bold!}@{!red,blue,bold!}%s" #Port if info[1] == DEFAULT_PREFS["daemon_port"]: connection_info += "{!white,blue!}:%s" else: connection_info += "{!status!}:%s" #Change color back to normal, just in case connection_info += "{!status!}" self.topbar += connection_info % (info[2], info[0], info[1]) else: self.topbar += "Not Connected" # Update the bottombar string self.bottombar = "{!status!}C: {!white,blue!}%s{!status!}" % self.connections if self.config["max_connections_global"] > -1: self.bottombar += " (%s)" % self.config["max_connections_global"] if self.download != "0.0 KiB": self.bottombar += " D: {!magenta,blue,bold!}%s{!status!}" % self.download else: self.bottombar += " D: {!white,blue!}%s{!status!}" % self.download if self.config["max_download_speed"] > -1: self.bottombar += " (%s " % self.config["max_download_speed"] + _("KiB/s") + ")" if self.upload != "0.0 KiB": self.bottombar += " U: {!green,blue,bold!}%s{!status!}" % self.upload else: self.bottombar += " U: {!white,blue!}%s{!status!}" % self.upload if self.config["max_upload_speed"] > -1: self.bottombar += " (%s " % self.config["max_upload_speed"] + _("KiB/s") + ")" if self.config["dht"]: self.bottombar += " " + _("DHT") + ": {!white,blue!}%s{!status!}" % self.dht
def get_host_status(self, host_id): """Gets the current status (online/offline) of the host Args: host_id (str): The host id to check status of. Returns: tuple: A tuple of strings (host_id, status, version). """ status_offline = (host_id, 'Offline', '') def on_connect(result, c, host_id): """Successfully connected to a daemon""" def on_info(info, c): c.disconnect() return host_id, 'Online', info def on_info_fail(reason, c): c.disconnect() return status_offline return c.daemon.info().addCallback(on_info, c).addErrback(on_info_fail, c) def on_connect_failed(reason, host_id): """Connection to daemon failed""" log.debug('Host status failed for %s: %s', host_id, reason) return status_offline try: host_id, host, port, user = self.get_host_info(host_id) except ValueError: log.warning('Problem getting host_id info from hostlist') return status_offline try: ip = gethostbyname(host) except gaierror as ex: log.error('Error resolving host %s to ip: %s', host, ex.args[1]) return status_offline host_conn_info = (ip, port, 'localclient' if not user and host in LOCALHOST else user) if client.connected() and host_conn_info == client.connection_info(): # Currently connected to host_id daemon. def on_info(info, host_id): log.debug('Client connected, query info: %s', info) return host_id, 'Connected', info return client.daemon.info().addCallback(on_info, host_id) else: # Attempt to connect to daemon with host_id details. c = Client() d = c.connect(host, port, skip_authentication=True) d.addCallback(on_connect, c, host_id) d.addErrback(on_connect_failed, host_id) return d
def process_args(args): """Process arguments sent to already running Deluge""" # Make sure args is a list args = list(args) log.debug('Processing args from other process: %s', args) if not client.connected(): # We're not connected so add these to the queue log.debug('Not connected to host.. Adding to queue.') component.get('QueuedTorrents').add_to_queue(args) return config = ConfigManager('gtkui.conf') for arg in args: if not arg.strip(): continue log.debug('arg: %s', arg) if is_url(arg): log.debug('Attempting to add url (%s) from external source...', arg) if config['interactive_add']: component.get('AddTorrentDialog').add_from_url(arg) component.get('AddTorrentDialog').show( config['focus_add_dialog']) else: client.core.add_torrent_url(arg, None) elif is_magnet(arg): log.debug('Attempting to add magnet (%s) from external source...', arg) if config['interactive_add']: component.get('AddTorrentDialog').add_from_magnets([arg]) component.get('AddTorrentDialog').show( config['focus_add_dialog']) else: client.core.add_torrent_magnet(arg, {}) else: log.debug('Attempting to add file (%s) from external source...', arg) if urlparse(arg).scheme == 'file': arg = url2pathname(urlparse(arg).path) path = os.path.abspath(decode_bytes(arg)) if not os.path.exists(path): log.error('No such file: %s', path) continue if config['interactive_add']: component.get('AddTorrentDialog').add_from_files([path]) component.get('AddTorrentDialog').show( config['focus_add_dialog']) else: with open(path, 'rb') as _file: filedump = b64encode(_file.read()) client.core.add_torrent_file( os.path.split(path)[-1], filedump, None)
def process_args(args): """Process arguments sent to already running Deluge""" # Make sure args is a list args = list(args) log.debug("Processing args from other process: %s", args) if not client.connected(): # We're not connected so add these to the queue log.debug("Not connected to host.. Adding to queue.") component.get("QueuedTorrents").add_to_queue(args) return config = ConfigManager("gtkui.conf") for arg in args: if not arg.strip(): continue log.debug("arg: %s", arg) if deluge.common.is_url(arg): log.debug("Attempting to add url (%s) from external source...", arg) if config["interactive_add"]: component.get("AddTorrentDialog").add_from_url(arg) component.get("AddTorrentDialog").show( config["focus_add_dialog"]) else: client.core.add_torrent_url(arg, None) elif deluge.common.is_magnet(arg): log.debug("Attempting to add magnet (%s) from external source...", arg) if config["interactive_add"]: component.get("AddTorrentDialog").add_from_magnets([arg]) component.get("AddTorrentDialog").show( config["focus_add_dialog"]) else: client.core.add_torrent_magnet(arg, {}) else: log.debug("Attempting to add file (%s) from external source...", arg) if urlparse(arg).scheme == "file": arg = url2pathname(urlparse(arg).path) path = os.path.abspath(deluge.common.decode_string(arg)) if not os.path.exists(path): log.error("No such file: %s", path) continue if config["interactive_add"]: component.get("AddTorrentDialog").add_from_files([path]) component.get("AddTorrentDialog").show( config["focus_add_dialog"]) else: with open(path, "rb") as _file: filedump = base64.encodestring(_file.read()) client.core.add_torrent_file( os.path.split(path)[-1], filedump, None)
def _apply_prefs(self): if self.core_config is None: return def update_conf_value(key, source_dict, dest_dict, updated): if dest_dict[key] != source_dict[key]: dest_dict[key] = source_dict[key] updated = True return updated new_core_config = {} for pane in self.panes: if not isinstance(pane, InterfacePane): pane.add_config_values(new_core_config) # Apply Core Prefs if client.connected(): # Only do this if we're connected to a daemon config_to_set = {} for key in new_core_config: # The values do not match so this needs to be updated if self.core_config[key] != new_core_config[key]: config_to_set[key] = new_core_config[key] if config_to_set: # Set each changed config value in the core client.core.set_config(config_to_set) client.force_call(True) # Update the configuration self.core_config.update(config_to_set) # Update Interface Prefs new_console_config = {} didupdate = False for pane in self.panes: # could just access panes by index, but that would break if panes # are ever reordered, so do it the slightly slower but safer way if isinstance(pane, InterfacePane): pane.add_config_values(new_console_config) for k in ['ring_bell', 'language']: didupdate = update_conf_value(k, new_console_config, self.console_config, didupdate) for k in ['separate_complete', 'move_selection']: didupdate = update_conf_value( k, new_console_config, self.console_config['torrentview'], didupdate) for k in [ 'ignore_duplicate_lines', 'save_command_history', 'third_tab_lists_all', 'torrents_per_tab_press' ]: didupdate = update_conf_value( k, new_console_config, self.console_config['cmdline'], didupdate) if didupdate: self.parent_mode.on_config_changed()
def quit(self): if client.connected(): def on_disconnect(result): reactor.stop() return client.disconnect().addCallback(on_disconnect) else: try: reactor.stop() except error.ReactorNotRunning: pass
def update(self): if not self.hidden() and client.connected(): d = client.core.get_filter_tree(True, []).addCallback( self._cb_update_filter_tree) def on_filter_tree_updated(changed): if changed: self.refresh() d.addCallback(on_filter_tree_updated)
def on_button_connect_clicked(self, checked=False): host = self.selectedItem( ) # NB: get it before accept closes and deletes the dialog self.accept() if client.connected(): yield client.disconnect() component.get("ConnectionManager").connect( host.config_tuple(), autostart=not host.is_alive())
def start(self): self.torrentview.on_config_changed() self.toggle_sidebar() if self.config['first_run']: self.push_popup(MessagePopup(self, 'Welcome to Deluge', HELP_STR, width_req=0.65)) self.config['first_run'] = False self.config.save() if client.connected(): self.torrentview.update(refresh=False)
def on_button_connect_clicked(self, widget=None): model, row = self.hostlist.get_selection().get_selected() if not row: return status = model[row][HOSTLIST_COL_STATUS] if status == "Connected": def on_disconnect(reason): self.__update_list() client.disconnect().addCallback(on_disconnect) return host_id = model[row][HOSTLIST_COL_ID] host = model[row][HOSTLIST_COL_HOST] port = model[row][HOSTLIST_COL_PORT] user = model[row][HOSTLIST_COL_USER] password = model[row][HOSTLIST_COL_PASS] if status == "Offline" and self.glade.get_widget("chk_autostart").get_active() and\ host in ("127.0.0.1", "localhost"): # We need to start this localhost self.start_daemon(port, deluge.configmanager.get_config_dir()) 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_retry_connect(try_counter) return result def do_retry_connect(try_counter): log.debug("user: %s pass: %s", user, password) d = client.connect(host, port, user, password) d.addCallback(self.__on_connected, host_id) d.addErrback(on_connect_fail, try_counter) do_retry_connect(6) def do_connect(*args): client.connect(host, port, user, password).addCallback(self.__on_connected, host_id) if client.connected(): client.disconnect().addCallback(do_connect) else: do_connect() self.connection_manager.response(gtk.RESPONSE_OK)
def enable(self): """Enables the system tray icon.""" self.builder = Builder() self.builder.add_from_file(resource_filename('deluge.ui.gtkui', os.path.join( 'glade', 'tray_menu.ui'))) self.builder.connect_signals(self) self.tray_menu = self.builder.get_object('tray_menu') if appindicator and self.config['enable_appindicator']: log.debug('Enabling the Application Indicator...') self.indicator = appindicator.Indicator('deluge', 'deluge', appindicator.CATEGORY_APPLICATION_STATUS) try: self.indicator.set_property('title', _('Deluge')) except TypeError: # Catch 'title' property error for previous appindicator versions pass # Pass the menu to the Application Indicator self.indicator.set_menu(self.tray_menu) # Make sure the status of the Show Window MenuItem is correct self._sig_win_hide = self.mainwindow.window.connect('hide', self._on_window_hide) self._sig_win_show = self.mainwindow.window.connect('show', self._on_window_show) if self.mainwindow.visible(): self.builder.get_object('menuitem_show_deluge').set_active(True) else: self.builder.get_object('menuitem_show_deluge').set_active(False) # Show the Application Indicator self.indicator.set_status(appindicator.STATUS_ACTIVE) else: log.debug('Enabling the system tray icon..') if windows_check(): self.tray = status_icon_new_from_pixbuf(get_logo(32)) else: self.tray = status_icon_new_from_icon_name('deluge') self.tray.connect('activate', self.on_tray_clicked) self.tray.connect('popup-menu', self.on_tray_popup) self.builder.get_object('download-limit-image').set_from_file(get_pixmap('downloading16.png')) self.builder.get_object('upload-limit-image').set_from_file(get_pixmap('seeding16.png')) client.register_event_handler('ConfigValueChangedEvent', self.config_value_changed) if client.connected(): # We're connected so we need to get some values from the core self.__start() else: # Hide menu widgets because we're not connected to a host. for widget in self.hide_widget_list: self.builder.get_object(widget).hide()
def _on_classic_mode(self, key, value): items = ["menuitem_quitdaemon", "separatormenuitem", "menuitem_connectionmanager"] for item in items: w = self.window.main_glade.get_widget(item) if value: w.hide() else: if client.connected() or item is "menuitem_connectionmanager": w.show() else: w.hide()
def __connect(self, host_id, host, port, username, password, skip_authentication=False, try_counter=0): def do_connect(*args): d = client.connect(host, port, username, password, skip_authentication) d.addCallback(self.__on_connected, host_id) d.addErrback(self.__on_connected_failed, host_id, host, port, username, password, try_counter) return d if client.connected(): return client.disconnect().addCallback(do_connect) else: return do_connect()
def _doRead(self): c = self.stdscr.getch() if c > 31 and c < 256: if chr(c) == 'Q': from twisted.internet import reactor if client.connected(): def on_disconnect(result): reactor.stop() client.disconnect().addCallback(on_disconnect) else: reactor.stop() return elif chr(c) == 'q': self.back_to_overview() return if c == 27: self.back_to_overview() return # TODO: Scroll event list jumplen = self.rows - 3 num_events = len( component.get("ConsoleUI").events ) if c == curses.KEY_UP: self.offset -= 1 elif c == curses.KEY_PPAGE: self.offset -= jumplen elif c == curses.KEY_HOME: self.offset = 0 elif c == curses.KEY_DOWN: self.offset += 1 elif c == curses.KEY_NPAGE: self.offset += jumplen elif c == curses.KEY_END: self.offset += num_events elif c == ord('j'): self.offset -= 1 elif c == ord('k'): self.offset += 1 if self.offset <= 0: self.offset = 0 elif num_events > self.rows - 3: if self.offset > num_events - self.rows + 3: self.offset = num_events - self.rows + 3 else: self.offset = 0 self.refresh()
def _doRead(self): c = self.stdscr.getch() if self.popup: if self.popup.handle_read(c): self.popup = None self.refresh() return if c > 31 and c < 256: if chr(c) == 'Q': from twisted.internet import reactor if client.connected(): def on_disconnect(result): reactor.stop() client.disconnect().addCallback(on_disconnect) else: reactor.stop() return elif chr(c) == 'h': self.popup = Popup(self, "Preferences Help") for l in HELP_LINES: self.popup.add_line(l) if c == 9: self.active_zone += 1 if self.active_zone > ZONE.ACTIONS: self.active_zone = ZONE.CATEGORIES elif c == 27 and self.active_zone == ZONE.CATEGORIES: self.back_to_parent() elif c == curses.KEY_BTAB: self.active_zone -= 1 if self.active_zone < ZONE.CATEGORIES: self.active_zone = ZONE.ACTIONS elif c == 114 and isinstance(self.panes[self.cur_cat], CachePane): client.core.get_cache_status().addCallback( self.panes[self.cur_cat].update_cache_status) else: if self.active_zone == ZONE.CATEGORIES: self.__category_read(c) elif self.active_zone == ZONE.PREFRENCES: self.__prefs_read(c) elif self.active_zone == ZONE.ACTIONS: self.__actions_read(c) self.refresh()
def _save_config(self): # ui config new_config = WidgetLoader.from_widgets(self, self.ui_config.config, "ui__") for key in new_config.keys(): if self.ui_config[key] != new_config[key]: self.ui_config[key] = new_config[key] # core config if self.core_config and client.connected(): new_config = WidgetLoader.from_widgets(self, self.core_config, "core__") client.core.set_config(dict((key, new_config[key]) for key in new_config.keys() if self.core_config[key] != new_config[key])) client.force_call(True) self.core_config = new_config
def quit_gtkui(): def stop_gtk_reactor(result=None): self.restart = restart try: reactor.callLater(0, reactor.fireSystemEvent, 'gtkui_close') except ReactorNotRunning: log.debug('Attempted to stop the reactor but it is not running...') if shutdown: client.daemon.shutdown().addCallback(stop_gtk_reactor) elif not client.is_standalone() and client.connected(): client.disconnect().addCallback(stop_gtk_reactor) else: stop_gtk_reactor()
def log_rpc_stats(self): """Log RPC statistics for thinclient mode.""" if not client.connected(): return t = time.time() recv = client.get_bytes_recv() sent = client.get_bytes_sent() delta_time = t - self.daemon_bps[0] delta_sent = sent - self.daemon_bps[1] delta_recv = recv - self.daemon_bps[2] self.daemon_bps = (t, sent, recv) sent_rate = fspeed(delta_sent / delta_time) recv_rate = fspeed(delta_recv / delta_time) log.debug('RPC: Sent %s (%s) Recv %s (%s)', fsize(sent), sent_rate, fsize(recv), recv_rate)
def start(self): self.torrentview.on_config_changed() self.toggle_sidebar() if self.config['first_run']: self.push_popup( MessagePopup(self, 'Welcome to Deluge', HELP_STR, width_req=0.65)) self.config['first_run'] = False self.config.save() if client.connected(): self.torrentview.update(refresh=False)
def process_args(args): """Process arguments sent to already running Deluge""" # Make sure args is a list args = list(args) log.debug("Processing args from other process: %s", args) if not client.connected(): # We're not connected so add these to the queue log.debug("Not connected to host.. Adding to queue.") component.get("QueuedTorrents").add_to_queue(args) return config = ConfigManager("gtkui.conf") for arg in args: if not arg.strip(): continue log.debug("arg: %s", arg) if deluge.common.is_url(arg): log.debug("Attempting to add url (%s) from external source...", arg) if config["interactive_add"]: component.get("AddTorrentDialog").add_from_url(arg) component.get("AddTorrentDialog").show(config["focus_add_dialog"]) else: client.core.add_torrent_url(arg, None) elif deluge.common.is_magnet(arg): log.debug("Attempting to add magnet (%s) from external source...", arg) if config["interactive_add"]: component.get("AddTorrentDialog").add_from_magnets([arg]) component.get("AddTorrentDialog").show(config["focus_add_dialog"]) else: client.core.add_torrent_magnet(arg, {}) else: log.debug("Attempting to add file (%s) from external source...", arg) if urlparse(arg).scheme == "file": arg = url2pathname(urlparse(arg).path) path = os.path.abspath(arg) if not os.path.exists(path): log.error("No such file: %s", path) continue if config["interactive_add"]: component.get("AddTorrentDialog").add_from_files([path]) component.get("AddTorrentDialog").show(config["focus_add_dialog"]) else: client.core.add_torrent_file(os.path.split(path)[-1], base64.encodestring(open(path, "rb").read()), None)
def _apply_prefs(self): if self.core_config is None: return def update_conf_value(key, source_dict, dest_dict, updated): if dest_dict[key] != source_dict[key]: dest_dict[key] = source_dict[key] updated = True return updated new_core_config = {} for pane in self.panes: if not isinstance(pane, InterfacePane): pane.add_config_values(new_core_config) # Apply Core Prefs if client.connected(): # Only do this if we're connected to a daemon config_to_set = {} for key in new_core_config: # The values do not match so this needs to be updated if self.core_config[key] != new_core_config[key]: config_to_set[key] = new_core_config[key] if config_to_set: # Set each changed config value in the core client.core.set_config(config_to_set) client.force_call(True) # Update the configuration self.core_config.update(config_to_set) # Update Interface Prefs new_console_config = {} didupdate = False for pane in self.panes: # could just access panes by index, but that would break if panes # are ever reordered, so do it the slightly slower but safer way if isinstance(pane, InterfacePane): pane.add_config_values(new_console_config) for k in ['ring_bell', 'language']: didupdate = update_conf_value(k, new_console_config, self.console_config, didupdate) for k in ['separate_complete', 'move_selection']: didupdate = update_conf_value(k, new_console_config, self.console_config['torrentview'], didupdate) for k in ['ignore_duplicate_lines', 'save_command_history', 'third_tab_lists_all', 'torrents_per_tab_press']: didupdate = update_conf_value(k, new_console_config, self.console_config['cmdline'], didupdate) if didupdate: self.parent_mode.on_config_changed()
def on_button_startdaemon_clicked(self, widget): 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, *get_localhost_auth()) # ..and start the daemon. self.start_daemon(DEFAULT_PORT, deluge.configmanager.get_config_dir()) return paths = self.hostlist.get_selection().get_selected_rows()[1] if len(paths) < 1: return status = self.liststore[paths[0]][HOSTLIST_COL_STATUS] host = self.liststore[paths[0]][HOSTLIST_COL_HOST] port = self.liststore[paths[0]][HOSTLIST_COL_PORT] user = self.liststore[paths[0]][HOSTLIST_COL_USER] password = self.liststore[paths[0]][HOSTLIST_COL_PASS] if host not in ("127.0.0.1", "localhost"): return if status in ("Online", "Connected"): # We need to stop this daemon # Call the shutdown method on the daemon 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) elif user and password: # Create a new client instance c = deluge.ui.client.Client() def on_connect(d, c): log.debug("on_connect") c.daemon.shutdown().addCallback(on_daemon_shutdown) c.connect(host, port, user, password).addCallback(on_connect, c) elif status == "Offline": self.start_daemon(port, deluge.configmanager.get_config_dir()) reactor.callLater(2.0, self.__update_list)
def do_command(self, cmd): """ Processes a command. :param cmd: str, the command string """ if not cmd: return cmd, _, line = cmd.partition(' ') try: parser = self._commands[cmd].create_parser() except KeyError: self.write("{!error!}Unknown command: %s" % cmd) return args = self._commands[cmd].split(line) # Do a little hack here to print 'command --help' properly parser._print_help = parser.print_help def print_help(f=None): if self.interactive: self.write(parser.format_help()) else: parser._print_help(f) parser.print_help = print_help # Only these commands can be run when not connected to a daemon not_connected_cmds = ["help", "connect", "quit"] aliases = [] for c in not_connected_cmds: aliases.extend(self._commands[c].aliases) not_connected_cmds.extend(aliases) if not client.connected() and cmd not in not_connected_cmds: self.write( "{!error!}Not connected to a daemon, please use the connect command first." ) return try: options, args = parser.parse_args(args) except Exception, e: self.write("{!error!}Error parsing options: %s" % e) return
def _doRead(self): c = self.stdscr.getch() if self.popup: if self.popup.handle_read(c): self.popup = None self.refresh() return if c > 31 and c < 256: if chr(c) == 'Q': from twisted.internet import reactor if client.connected(): def on_disconnect(result): reactor.stop() client.disconnect().addCallback(on_disconnect) else: reactor.stop() return elif chr(c) == 'h': self.popup = Popup(self,"Preferences Help") for l in HELP_LINES: self.popup.add_line(l) if c == 9: self.active_zone += 1 if self.active_zone > ZONE.ACTIONS: self.active_zone = ZONE.CATEGORIES elif c == curses.KEY_BTAB: self.active_zone -= 1 if self.active_zone < ZONE.CATEGORIES: self.active_zone = ZONE.ACTIONS elif c == 114 and isinstance(self.panes[self.cur_cat],CachePane): client.core.get_cache_status().addCallback(self.panes[self.cur_cat].update_cache_status) else: if self.active_zone == ZONE.CATEGORIES: self.__category_read(c) elif self.active_zone == ZONE.PREFRENCES: self.__prefs_read(c) elif self.active_zone == ZONE.ACTIONS: self.__actions_read(c) self.refresh()
def _save_config(self): # ui config new_config = WidgetLoader.from_widgets(self, self.ui_config.config, "ui__") for key in new_config.keys(): if self.ui_config[key] != new_config[key]: self.ui_config[key] = new_config[key] # core config if self.core_config and client.connected(): new_config = WidgetLoader.from_widgets(self, self.core_config, "core__") client.core.set_config( dict((key, new_config[key]) for key in new_config.keys() if self.core_config[key] != new_config[key])) client.force_call(True) self.core_config = new_config
def handle(self, host="127.0.0.1:58846", username="", password="", **options): self.console = component.get("ConsoleUI") try: host, port = host.split(":") except ValueError: port = 58846 else: port = int(port) def do_connect(): d = client.connect(host, port, username, password) def on_connect(result): if self.console.interactive: self.console.write("{!success!}Connected to %s:%s" % (host, port)) return component.start() def on_connect_fail(result): try: msg = result.value.exception_msg except: msg = result.value.args[0] self.console.write( "{!error!}Failed to connect to %s:%s with reason: %s" % (host, port, msg)) return result d.addCallback(on_connect) d.addErrback(on_connect_fail) return d if client.connected(): def on_disconnect(result): self.console.statusbars.update_statusbars() return do_connect() return client.disconnect().addCallback(on_disconnect) else: return do_connect()
def on_button_startdaemon_clicked(self, widget): 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, *get_localhost_auth()) # ..and start the daemon. self.start_daemon( DEFAULT_PORT, deluge.configmanager.get_config_dir() ) return paths = self.hostlist.get_selection().get_selected_rows()[1] if len(paths) < 1: return status = self.liststore[paths[0]][HOSTLIST_COL_STATUS] host = self.liststore[paths[0]][HOSTLIST_COL_HOST] port = self.liststore[paths[0]][HOSTLIST_COL_PORT] user = self.liststore[paths[0]][HOSTLIST_COL_USER] password = self.liststore[paths[0]][HOSTLIST_COL_PASS] if host not in ("127.0.0.1", "localhost"): return if status in (_("Online"), _("Connected")): # We need to stop this daemon # Call the shutdown method on the daemon 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) elif user and password: # Create a new client instance c = deluge.ui.client.Client() def on_connect(d, c): log.debug("on_connect") c.daemon.shutdown().addCallback(on_daemon_shutdown) c.connect(host, port, user, password).addCallback(on_connect, c) elif status == _("Offline"): self.start_daemon(port, deluge.configmanager.get_config_dir()) reactor.callLater(2.0, self.__update_list)
def on_button_startdaemon_clicked(self, widget): log.debug('on_button_startdaemon_clicked') if not self.liststore.iter_n_children(None): # There is nothing in the list, so lets create a localhost entry try: self.hostlist.add_default_host() except ValueError as ex: log.error('Error adding default host: %s', ex) else: self.start_daemon(DEFAULT_PORT, get_config_dir()) finally: return paths = self.treeview.get_selection().get_selected_rows()[1] if len(paths): __, host, port, user, password, status, __ = self.liststore[ paths[0]] else: return if host not in LOCALHOST: return def on_daemon_status_change(result): """Daemon start/stop callback""" reactor.callLater(0.7, self._update_host_status) if status in ('Online', 'Connected'): # Button will stop the daemon if status is online or connected. def on_connect(d, c): """Client callback to call daemon shutdown""" c.daemon.shutdown().addCallback(on_daemon_status_change) if client.connected() and (host, port, user) == client.connection_info(): client.daemon.shutdown().addCallback(on_daemon_status_change) elif user and password: c = Client() c.connect(host, port, user, password).addCallback(on_connect, c) else: # Otherwise button will start the daemon. self.start_daemon(port, get_config_dir())
def _connect(self, host_id, username=None, password=None, try_counter=0): def do_connect(result, username=None, password=None, *args): log.debug('Attempting to connect to daemon...') for host_entry in self.hostlist.config['hosts']: if host_entry[0] == host_id: __, host, port, host_user, host_pass = host_entry username = username if username else host_user password = password if password else host_pass d = client.connect(host, port, username, password) d.addCallback(self._on_connect, host_id) d.addErrback(self._on_connect_fail, host_id, try_counter) return d if client.connected(): return client.disconnect().addCallback(do_connect, username, password) else: return do_connect(None, username, password)
def open_file(self, osxapp, filename): # Will be raised at app launch (python opening main script) if filename.endswith("Deluge-bin"): return True def on_show(result): self.gtkui.addtorrentdialog.add_from_files([filename]) def show(): d = self.gtkui.addtorrentdialog.show(self.gtkui.config["focus_add_dialog"]) d.addCallback(on_show) if not client.connected(): log.debug("queuing file %s", filename) self.gtkui.queuedtorrents.add_to_queue([filename]) else: log.debug("opening file %s", filename) show() # doesn't look like required anymore: gobject.idle_add(show) return True
def handle(self, options): self.console = component.get('ConsoleUI') host = options.host try: host, port = host.split(':') port = int(port) except ValueError: port = 58846 def do_connect(): d = client.connect(host, port, options.username, options.password) def on_connect(result): if self.console.interactive: self.console.write('{!success!}Connected to %s:%s!' % (host, port)) return component.start() def on_connect_fail(result): try: msg = result.value.exception_msg except AttributeError: msg = result.value.message self.console.write( '{!error!}Failed to connect to %s:%s with reason: %s' % (host, port, msg)) return result d.addCallbacks(on_connect, on_connect_fail) return d if client.connected(): def on_disconnect(result): if self.console.statusbars: self.console.statusbars.update_statusbars() return do_connect() return client.disconnect().addCallback(on_disconnect) else: return do_connect()
def do_command(self, cmd): """ Processes a command. :param cmd: str, the command string """ if not cmd: return cmd, _, line = cmd.partition(' ') try: parser = self._commands[cmd].create_parser() except KeyError: self.write("{!error!}Unknown command: %s" % cmd) return args = self._commands[cmd].split(line) # Do a little hack here to print 'command --help' properly parser._print_help = parser.print_help def print_help(f=None): if self.interactive: self.write(parser.format_help()) else: parser._print_help(f) parser.print_help = print_help # Only these commands can be run when not connected to a daemon not_connected_cmds = ["help", "connect", "quit"] aliases = [] for c in not_connected_cmds: aliases.extend(self._commands[c].aliases) not_connected_cmds.extend(aliases) if not client.connected() and cmd not in not_connected_cmds: self.write("{!error!}Not connected to a daemon, please use the connect command first.") return try: options, args = parser.parse_args(args) except Exception, e: self.write("{!error!}Error parsing options: %s" % e) return
def show(self, page=None): """Page should be the string in the left list.. ie, 'Network' or 'Bandwidth'""" if page != None: for (index, string) in self.liststore: if page == string: self.treeview.get_selection().select_path(index) break component.get("PluginManager").run_on_show_prefs() # Update the preferences dialog to reflect current config settings self.core_config = {} if client.connected(): def _on_get_config(config): self.core_config = config client.core.get_available_plugins().addCallback( _on_get_available_plugins) def _on_get_available_plugins(plugins): self.all_plugins = plugins client.core.get_enabled_plugins().addCallback( _on_get_enabled_plugins) def _on_get_enabled_plugins(plugins): self.enabled_plugins = plugins client.core.get_listen_port().addCallback(_on_get_listen_port) def _on_get_listen_port(port): self.active_port = port client.core.get_cache_status().addCallback( _on_get_cache_status) def _on_get_cache_status(status): self.cache_status = status self._show() # This starts a series of client.core requests prior to showing the window client.core.get_config().addCallback(_on_get_config) else: self._show()