diff --git a/ChangeLog b/ChangeLog index bbbcd6013..5730b816b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +Deluge 1.0.4 (In Development) + Core: + * Fix #560 force an int value for global max connections + Deluge 1.0.3 (18 October 2008) Core: * Fix upnp - it should work on more routers now too @@ -12,7 +16,7 @@ Deluge 1.0.3 (18 October 2008) WebUI: * Fix White template for Opera - + Misc: * Deluge will now use a system libtorrent library if available. * The build system will no longer build libtorrent if a system library is @@ -42,7 +46,7 @@ Deluge 1.0.1 (10 October 2008) GtkUI: * Improve performance of files tab by only updating when values change - + Misc: * Fix #187 set a 5 second timer to save the config file after a config value has been changed. @@ -51,7 +55,7 @@ Deluge 1.0.1 (10 October 2008) WebUI: * Add enable "Auto Add" checkbox - + Deluge 1.0.0 - "Sharks Are Bulletproof" (21 September 2008) Core: * Include GeoIP database for country look-ups @@ -64,7 +68,7 @@ Deluge 0.9.09 - "1.0.0_RC9" (15 September 2008) * Fix fastresume issue causing loss of data by deleting the fastresume file before writing a new one * Fix #475 the use of unicode paths when adding torrents - + GtkUI: * Fix add torrent dialog closing preventing another dialog from being shown * Fix various issues when not using English @@ -74,15 +78,15 @@ Deluge 0.9.08 - "1.0.0_RC8" (27 August 2008) Core: * Attempt to automatically upgrade a 0.5.x state file to new format * Tracker errors now change the tracker status - + Plugins: * Fix bug in Blocklist that prevented downloading a new file every X days - + GtkUI: * Sort filenames alphabetically in add torrent dialog * Fix setting file priorities on folders * Fix #453 allow showing of text in the toolbar buttons - + Deluge 0.9.07 - "1.0.0_RC7" (18 August 2008) Core: * Fix loading torrents from state when fastresume file is missing @@ -102,35 +106,35 @@ Deluge 0.9.07 - "1.0.0_RC7" (18 August 2008) Null: * Fix #415 crash when using 'config-set' with no parameters - + Windows: * Fix Vista slowness issue * Fix properly shutting Deluge down when system shuts down * Fix opening folders/files - + Deluge 0.9.06 - "1.0.0_RC6" (13 August 2008) Core: * Fix CPU spikes GtkUI: * Fix move storage dialog when connected to a remote daemon - + Deluge 0.9.05 - "1.0.0_RC5" (04 August 2008) Core: * Fix deluged running with ssh X forwarding by removing the Gnome lib import * Save resume data periodically to help prevent data loss * Fix queue order shuffling on restart - + GtkUI: * Handle shutting down more cleanly * Add translators to credits - + Plugins: * Improve the Blocklist plugin preferences page. - + Windows: * Fix drag n' drop support - + Deluge 0.9.04 - "1.0.0_RC4" (29 July 2008) Core: * Fix building with gcc 4.3 @@ -145,14 +149,14 @@ Deluge 0.9.04 - "1.0.0_RC4" (29 July 2008) * Fix displaying of torrents when language is not English * Fix the view options to be persistent between sessions * Fix signalreceiver when switching between daemons - + Deluge 0.9.03 - "1.0.0_RC3" (21 July 2008) Core: * File progress fixes from libtorrent * Fix building on FreeBSD * Fix #350 stop seeds when stop ratio is reached * Fix #358 properly emit torrent_removed signal when remove_at_ratio happens - + UI: * Default to gtkui when running 'deluge' instead of defaulting to last used. @@ -162,13 +166,13 @@ Deluge 0.9.03 - "1.0.0_RC3" (21 July 2008) Windows: * Fix torrent file association and adding files from command line - + Plugins: * Blocklist plugin has been rewritten - + Misc: * Some changes for python 2.6 compatibility - + Deluge 0.9.02 - "1.0.0_RC2" (15 July 2008) Core: * Fix displaying of file progress diff --git a/deluge/core/core.py b/deluge/core/core.py index b6ac437f9..1f6990bcc 100644 --- a/deluge/core/core.py +++ b/deluge/core/core.py @@ -2,19 +2,19 @@ # core.py # # Copyright (C) 2007, 2008 Andrew Resch ('andar') -# +# # Deluge is free software. -# +# # You may redistribute it and/or modify it under the terms of the # GNU General Public License, as published by the Free Software # Foundation; either version 3 of the License, or (at your option) # any later version. -# +# # deluge is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. -# +# # You should have received a copy of the GNU General Public License # along with deluge. If not, write to: # The Free Software Foundation, Inc., @@ -50,7 +50,7 @@ try: import libtorrent as lt except ImportError: import deluge.libtorrent as lt - + import deluge.configmanager import deluge.common import deluge.component as component @@ -60,7 +60,7 @@ from deluge.core.alertmanager import AlertManager from deluge.core.signalmanager import SignalManager from deluge.core.autoadd import AutoAdd from deluge.log import LOG as log - + DEFAULT_PREFS = { "config_location": deluge.configmanager.get_config_dir(), "send_info": False, @@ -89,7 +89,7 @@ DEFAULT_PREFS = { "max_upload_speed": -1.0, "max_download_speed": -1.0, "max_upload_slots_global": 4, - "max_half_open_connections": (lambda: deluge.common.windows_check() and + "max_half_open_connections": (lambda: deluge.common.windows_check() and (lambda: deluge.common.vista_check() and 4 or 8)() or -1)(), "max_connections_per_second": 20, "ignore_limits_on_local_network": True, @@ -117,27 +117,27 @@ DEFAULT_PREFS = { "move_completed_path": deluge.common.get_default_download_dir(), "new_release_check": True, } - + class Core( - ThreadingMixIn, + ThreadingMixIn, SimpleXMLRPCServer.SimpleXMLRPCServer, component.Component): def __init__(self, port): log.debug("Core init..") component.Component.__init__(self, "Core") self.client_address = None - + # Get config self.config = deluge.configmanager.ConfigManager("core.conf", DEFAULT_PREFS) if port == None: port = self.config["daemon_port"] - + if self.config["allow_remote"]: hostname = "" else: hostname = "127.0.0.1" - + # Setup the xmlrpc server try: log.info("Starting XMLRPC server on port %s", port) @@ -148,20 +148,20 @@ class Core( sys.exit(0) self.register_multicall_functions() - + # Register all export_* functions for func in dir(self): if func.startswith("export_"): self.register_function(getattr(self, "%s" % func), func[7:]) self.register_introspection_functions() - + # Initialize gettext if deluge.common.windows_check() or deluge.common.osx_check(): locale.setlocale(locale.LC_ALL, '') else: locale.setlocale(locale.LC_MESSAGES, '') - locale.bindtextdomain("deluge", + locale.bindtextdomain("deluge", pkg_resources.resource_filename( "deluge", "i18n")) locale.textdomain("deluge") @@ -176,7 +176,7 @@ class Core( # Setup signals signal.signal(signal.SIGINT, self._shutdown) signal.signal(signal.SIGTERM, self._shutdown) - if not deluge.common.windows_check(): + if not deluge.common.windows_check(): signal.signal(signal.SIGHUP, self._shutdown) else: from win32api import SetConsoleCtrlHandler @@ -198,7 +198,7 @@ class Core( request, client_address = self.socket.accept() self.client_address = client_address[0] return (request, client_address) - + def run(self): """Starts the core""" @@ -209,11 +209,11 @@ class Core( while len(version) < 4: version.append(0) fingerprint = lt.fingerprint("DE", *version) - + # Start the libtorrent session log.debug("Starting libtorrent session..") self.session = lt.session(fingerprint, flags=0) - + # Set the user agent self.settings = lt.session_settings() self.settings.user_agent = "Deluge %s" % deluge.common.get_version() @@ -221,12 +221,12 @@ class Core( # Load the GeoIP DB for country look-ups self.session.load_country_db( pkg_resources.resource_filename("deluge", os.path.join("data", "GeoIP.dat"))) - + # Set session settings self.settings.lazy_bitfields = 1 self.settings.send_redundant_have = True self.session.set_settings(self.settings) - + # Create an ip filter self.ip_filter = lt.ip_filter() # This keeps track of the timer to set the ip filter.. We do this a few @@ -241,7 +241,7 @@ class Core( self._on_set_torrentfiles_location) self.config.register_set_function("state_location", self._on_set_state_location) - self.config.register_set_function("listen_ports", + self.config.register_set_function("listen_ports", self._on_set_listen_ports) self.config.register_set_function("random_port", self._on_set_random_port) @@ -296,23 +296,23 @@ class Core( self.config.register_change_callback(self._on_config_value_change) # Start the AlertManager self.alerts = AlertManager(self.session) - + # Start the SignalManager - self.signals = SignalManager() + self.signals = SignalManager() # Load plugins self.plugins = PluginManager(self) # Start the TorrentManager self.torrents = TorrentManager(self.session, self.alerts) - + # Create the AutoAdd component - self.autoadd = AutoAdd() + self.autoadd = AutoAdd() component.start() - + self._should_shutdown = False - + self.listen_thread = threading.Thread(target=self.handle_thread) self.listen_thread.setDaemon(False) self.listen_thread.start() @@ -329,10 +329,10 @@ class Core( while not self._should_shutdown: self.handle_request() self._should_shutdown = False - + except Exception, e: log.debug("handle_thread: %s", e) - + def _shutdown(self, *data): """This is called by a thread from shutdown()""" log.info("Shutting down core..") @@ -364,7 +364,7 @@ class Core( def export_ping(self): """A method to see if the core is running""" return True - + def export_shutdown(self): """Shutdown the core""" # Make shutdown an async call @@ -376,34 +376,34 @@ class Core( self.signals.register_client(self.client_address, port) if self.config["new_release_check"]: self.check_new_release() - + def export_deregister_client(self): """De-registers a client with the signal manager.""" self.signals.deregister_client(self.client_address) - + def export_add_torrent_file(self, filename, filedump, options): """Adds a torrent file to the libtorrent session This requires the torrents filename and a dump of it's content """ gobject.idle_add(self._add_torrent_file, filename, filedump, options) - + def _add_torrent_file(self, filename, filedump, options): # Turn the filedump into a torrent_info if not isinstance(filedump, str): filedump = filedump.data - + if len(filedump) == 0: log.warning("Torrent file is corrupt!") return - + try: torrent_info = lt.torrent_info(lt.bdecode(filedump)) except RuntimeError, e: log.warning("Unable to decode torrent file: %s", e) return None - + torrent_id = self.torrents.add(filedump=filedump, options=options, filename=filename) - + # Run the plugin hooks for 'post_torrent_add' self.plugins.run_post_torrent_add(torrent_id) @@ -415,7 +415,7 @@ class Core( def fetch_torrent_url_thread(self, callback, url, options): # Get the actual filename of the torrent from the url provided. filename = url.split("/")[-1] - + # Get the .torrent file from the url torrent_file = deluge.common.fetch_url(url) if torrent_file is None: @@ -430,14 +430,14 @@ class Core( # Add the torrent to session return callback(filename, filedump, options) - + def export_remove_torrent(self, torrent_ids, remove_torrent, remove_data): log.debug("Removing torrent %s from the core.", torrent_ids) for torrent_id in torrent_ids: if self.torrents.remove(torrent_id, remove_torrent, remove_data): # Run the plugin hooks for 'post_torrent_remove' self.plugins.run_post_torrent_remove(torrent_id) - + def export_force_reannounce(self, torrent_ids): log.debug("Forcing reannouncment to: %s", torrent_ids) for torrent_id in torrent_ids: @@ -448,24 +448,24 @@ class Core( for torrent_id in torrent_ids: if not self.torrents[torrent_id].pause(): log.warning("Error pausing torrent %s", torrent_id) - + def export_move_storage(self, torrent_ids, dest): log.debug("Moving storage %s to %s", torrent_ids, dest) for torrent_id in torrent_ids: if not self.torrents[torrent_id].move_storage(dest): log.warning("Error moving torrent %s to %s", torrent_id, dest) - + def export_pause_all_torrents(self): """Pause all torrents in the session""" if not self.torrents.pause_all(): log.warning("Error pausing all torrents..") - + def export_resume_all_torrents(self): """Resume all torrents in the session""" if self.torrents.resume_all(): # Emit the 'torrent_all_resumed' signal self.torrent_all_resumed() - + def export_resume_torrent(self, torrent_ids): log.debug("Resuming: %s", torrent_ids) for torrent_id in torrent_ids: @@ -479,13 +479,13 @@ class Core( except KeyError: # The torrent_id is not found in the torrentmanager, so return None return None - + # Get the leftover fields and ask the plugin manager to fill them leftover_fields = list(set(keys) - set(status.keys())) if len(leftover_fields) > 0: status.update(self.plugins.get_status(torrent_id, leftover_fields)) return status - + def export_get_torrents_status(self, torrent_ids, keys): status_dict = {}.fromkeys(torrent_ids) @@ -500,25 +500,25 @@ class Core( if len(leftover_fields) > 0: status.update( self.plugins.get_status(torrent_id, leftover_fields)) - + status_dict[torrent_id] = status # Emit the torrent_status signal to the clients return status_dict - + def export_get_session_state(self): """Returns a list of torrent_ids in the session.""" # Get the torrent list from the TorrentManager return self.torrents.get_torrent_list() - + def export_save_state(self): """Save the current session state to file.""" # Have the TorrentManager save it's state self.torrents.save_state() - + def export_get_config(self): """Get all the preferences as a dictionary""" return self.config.get_config() - + def export_get_config_value(self, key): """Get the config value for key""" try: @@ -536,15 +536,15 @@ class Core( if isinstance(config[key], unicode) or isinstance(config[key], str): config[key] = config[key].encode("utf8") self.config[key] = config[key] - + def export_get_listen_port(self): """Returns the active listen port""" return self.session.listen_port() - + def export_get_num_connections(self): """Returns the current number of connections""" return self.session.num_connections() - + def export_get_dht_nodes(self): """Returns the number of dht nodes""" return self.session.status().dht_nodes @@ -556,7 +556,7 @@ class Core( def export_get_upload_rate(self): """Returns the payload upload rate""" return self.session.status().payload_upload_rate - + def export_get_available_plugins(self): """Returns a list of plugins available in the core""" return self.plugins.get_available_plugins() @@ -568,64 +568,64 @@ class Core( def export_enable_plugin(self, plugin): self.plugins.enable_plugin(plugin) return None - + def export_disable_plugin(self, plugin): self.plugins.disable_plugin(plugin) return None - + def export_force_recheck(self, torrent_ids): """Forces a data recheck on torrent_ids""" for torrent_id in torrent_ids: self.torrents[torrent_id].force_recheck() - + def export_set_torrent_trackers(self, torrent_id, trackers): """Sets a torrents tracker list. trackers will be [{"url", "tier"}]""" return self.torrents[torrent_id].set_trackers(trackers) - + def export_set_torrent_max_connections(self, torrent_id, value): """Sets a torrents max number of connections""" return self.torrents[torrent_id].set_max_connections(value) - + def export_set_torrent_max_upload_slots(self, torrent_id, value): """Sets a torrents max number of upload slots""" return self.torrents[torrent_id].set_max_upload_slots(value) - + def export_set_torrent_max_upload_speed(self, torrent_id, value): """Sets a torrents max upload speed""" return self.torrents[torrent_id].set_max_upload_speed(value) - + def export_set_torrent_max_download_speed(self, torrent_id, value): """Sets a torrents max download speed""" return self.torrents[torrent_id].set_max_download_speed(value) - + def export_set_torrent_file_priorities(self, torrent_id, priorities): """Sets a torrents file priorities""" return self.torrents[torrent_id].set_file_priorities(priorities) - + def export_set_torrent_prioritize_first_last(self, torrent_id, value): """Sets a higher priority to the first and last pieces""" return self.torrents[torrent_id].set_prioritize_first_last(value) - + def export_set_torrent_auto_managed(self, torrent_id, value): """Sets the auto managed flag for queueing purposes""" return self.torrents[torrent_id].set_auto_managed(value) - + def export_set_torrent_stop_at_ratio(self, torrent_id, value): """Sets the torrent to stop at 'stop_ratio'""" return self.torrents[torrent_id].set_stop_at_ratio(value) - + def export_set_torrent_stop_ratio(self, torrent_id, value): """Sets the ratio when to stop a torrent if 'stop_at_ratio' is set""" return self.torrents[torrent_id].set_stop_ratio(value) - + def export_set_torrent_remove_at_ratio(self, torrent_id, value): """Sets the torrent to be removed at 'stop_ratio'""" return self.torrents[torrent_id].set_remove_at_ratio(value) - + def export_block_ip_range(self, range): """Block an ip range""" self.ip_filter.add_rule(range[0], range[1], 1) - + # Start a 2 second timer (and remove the previous one if it exists) if self._set_ip_filter_timer: gobject.source_remove(self._set_ip_filter_timer) @@ -635,7 +635,7 @@ class Core( """Clears the ip filter""" self.ip_filter = lt.ip_filter() self.session.set_ip_filter(self.ip_filter) - + def export_get_health(self): """Returns True if we have established incoming connections""" return self.session.status().has_incoming_connections @@ -690,7 +690,7 @@ class Core( """Emitted when a torrent has been removed from the core""" log.debug("torrent_remove signal emitted") self.signals.emit("torrent_removed", torrent_id) - + def torrent_paused(self, torrent_id): """Emitted when a torrent is paused""" log.debug("torrent_paused signal emitted") @@ -720,31 +720,31 @@ class Core( """Emitted when a torrent queue position is changed""" log.debug("torrent_queue_changed signal emitted") self.signals.emit("torrent_queue_changed") - + # Config set functions def _on_config_value_change(self, key, value): self.config_value_changed(key, value) - + def _on_set_torrentfiles_location(self, key, value): if self.config["copy_torrent_file"]: try: os.makedirs(value) except Exception, e: log.debug("Unable to make directory: %s", e) - + def _on_set_state_location(self, key, value): if not os.access(value, os.F_OK): try: os.makedirs(value) except Exception, e: log.debug("Unable to make directory: %s", e) - + def _on_set_listen_ports(self, key, value): # Only set the listen ports if random_port is not true if self.config["random_port"] is not True: log.debug("listen port range set to %s-%s", value[0], value[1]) self.session.listen_on(value[0], value[1]) - + def _on_set_random_port(self, key, value): log.debug("random port value set to %s", value) # We need to check if the value has been changed to true and false @@ -757,12 +757,12 @@ class Core( listen_ports.append(listen_ports[0]+10) else: listen_ports = self.config["listen_ports"] - + # Set the listen ports - log.debug("listen port range set to %s-%s", listen_ports[0], + log.debug("listen port range set to %s-%s", listen_ports[0], listen_ports[1]) self.session.listen_on(listen_ports[0], listen_ports[1]) - + def _on_set_dht(self, key, value): log.debug("dht value set to %s", value) if value: @@ -772,14 +772,14 @@ class Core( self.session.add_dht_router("router.bitcomet.com", 6881) else: self.session.stop_dht() - + def _on_set_upnp(self, key, value): log.debug("upnp value set to %s", value) if value: self.session.start_upnp() else: self.session.stop_upnp() - + def _on_set_natpmp(self, key, value): log.debug("natpmp value set to %s", value) if value: @@ -793,7 +793,7 @@ class Core( self.session.start_lsd() else: self.session.stop_lsd() - + def _on_set_utpex(self, key, value): log.debug("utpex value set to %s", value) if value: @@ -810,7 +810,7 @@ class Core( self.session.set_pe_settings(pe_settings) set = self.session.get_pe_settings() log.debug("encryption settings:\n\t\t\tout_policy: %s\n\t\t\ - in_policy: %s\n\t\t\tlevel: %s\n\t\t\tprefer_rc4: %s", + in_policy: %s\n\t\t\tlevel: %s\n\t\t\tprefer_rc4: %s", set.out_enc_policy, set.in_enc_policy, set.allowed_enc_level, @@ -818,8 +818,12 @@ class Core( def _on_set_max_connections_global(self, key, value): log.debug("max_connections_global set to %s..", value) - self.session.set_max_connections(value) - + # Add this in to overwrite bad float values in the config, to prevent + # future issues with 1.1 + if type(value) is not int: + self.config[key] = int(value) + self.session.set_max_connections(int(value)) + def _on_set_max_upload_speed(self, key, value): log.debug("max_upload_speed set to %s..", value) # We need to convert Kb/s to B/s @@ -829,22 +833,22 @@ class Core( log.debug("max_download_speed set to %s..", value) # We need to convert Kb/s to B/s self.session.set_download_rate_limit(int(value * 1024)) - + def _on_set_max_upload_slots_global(self, key, value): log.debug("max_upload_slots_global set to %s..", value) self.session.set_max_uploads(value) def _on_set_max_half_open_connections(self, key, value): self.session.set_max_half_open_connections(value) - + def _on_set_max_connections_per_second(self, key, value): self.settings.connection_speed = value self.session.set_settings(self.settings) - + def _on_ignore_limits_on_local_network(self, key, value): self.settings.ignore_limits_on_local_network = value self.session.set_settings(self.settings) - + def _on_set_share_ratio_limit(self, key, value): log.debug("%s set to %s..", key, value) self.settings.share_ratio_limit = value @@ -878,7 +882,7 @@ class Core( log.debug("active_limit: %s", self.settings.active_limit) self.settings.active_limit = value self.session.set_settings(self.settings) - + def _on_set_dont_count_slow_torrents(self, key, value): log.debug("%s set to %s..", key, value) self.settings.dont_count_slow_torrents = value @@ -924,7 +928,7 @@ class Core( log.debug("Unable to get release info from website: %s", e) return self.check_new_release() - + def check_new_release(self): if self.new_release: log.debug("new_release: %s", self.new_release) @@ -932,7 +936,7 @@ class Core( self.signals.emit("new_version_available", self.new_release) return self.new_release return False - + def _on_new_release_check(self, key, value): if value: log.debug("Checking for new release..") diff --git a/deluge/ui/gtkui/statusbar.py b/deluge/ui/gtkui/statusbar.py index 06615585d..8aff0199e 100644 --- a/deluge/ui/gtkui/statusbar.py +++ b/deluge/ui/gtkui/statusbar.py @@ -2,19 +2,19 @@ # statusbar.py # # Copyright (C) 2007, 2008 Andrew Resch ('andar') -# +# # Deluge is free software. -# +# # You may redistribute it and/or modify it under the terms of the # GNU General Public License, as published by the Free Software # Foundation; either version 3 of the License, or (at your option) # any later version. -# +# # deluge is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. -# +# # You should have received a copy of the GNU General Public License # along with deluge. If not, write to: # The Free Software Foundation, Inc., @@ -62,40 +62,40 @@ class StatusBarItem: # Add text if text != None: self.set_text(text) - + if callback != None: self.set_callback(callback) - + self.show_all() - + def set_callback(self, callback): self._ebox.connect("button-press-event", callback) - + def show_all(self): self._ebox.show() self._hbox.show() self._image.show() self._label.show() - + def set_image_from_file(self, image): self._image.set_from_file(image) - + def set_image_from_stock(self, stock): self._image.set_from_stock(stock, gtk.ICON_SIZE_MENU) - + def set_text(self, text): if self._label.get_text() != text: self._label.set_text(text) - + def get_widgets(self): return self._widgets() - + def get_eventbox(self): return self._ebox - + def get_text(self): return self._label.get_text() - + class StatusBar(component.Component): def __init__(self): component.Component.__init__(self, "StatusBar", interval=3000) @@ -103,7 +103,7 @@ class StatusBar(component.Component): self.statusbar = self.window.main_glade.get_widget("statusbar") self.tooltips = gtk.Tooltips() self.config = ConfigManager("gtkui.conf") - + # Status variables that are updated via callback self.max_connections = -1 self.num_connections = 0 @@ -114,7 +114,7 @@ class StatusBar(component.Component): self.dht_nodes = 0 self.dht_status = False self.health = False - + self.config_value_changed_dict = { "max_connections_global": self._on_max_connections_global, "max_download_speed": self._on_max_download_speed, @@ -131,11 +131,11 @@ class StatusBar(component.Component): self.statusbar.show_all() # Create the not connected item self.not_connected_item = StatusBarItem( - stock=gtk.STOCK_STOP, text=_("Not Connected"), + stock=gtk.STOCK_STOP, text=_("Not Connected"), callback=self._on_notconnected_item_clicked) # Show the not connected status bar self.show_not_connected() - + # Hide if necessary self.visible(self.config["show_statusbar"]) @@ -168,7 +168,7 @@ class StatusBar(component.Component): callback=self._on_health_icon_clicked) self.health = False - + # Get some config values client.get_config_value( self._on_max_connections_global, "max_connections_global") @@ -179,9 +179,9 @@ class StatusBar(component.Component): client.get_config_value( self._on_dht, "dht") client.get_health(self._on_get_health) - + self.send_status_request() - + def stop(self): # When stopped, we just show the not connected thingy try: @@ -193,8 +193,8 @@ class StatusBar(component.Component): self.remove_item(self.health_item) except Exception, e: log.debug("Unable to remove StatusBar item: %s", e) - self.show_not_connected() - + self.show_not_connected() + def visible(self, visible): if visible: self.statusbar.show() @@ -202,11 +202,11 @@ class StatusBar(component.Component): self.statusbar.hide() self.config["show_statusbar"] = visible - + def show_not_connected(self): self.hbox.pack_start( self.not_connected_item.get_eventbox(), expand=False, fill=False) - + def add_item(self, image=None, stock=None, text=None, callback=None, tooltip=None): """Adds an item to the status bar""" # The return tuple.. we return whatever widgets we add @@ -215,7 +215,7 @@ class StatusBar(component.Component): if tooltip: self.tooltips.set_tip(item.get_eventbox(), tooltip) return item - + def remove_item(self, item): """Removes an item from the statusbar""" if item.get_eventbox() in self.hbox.get_children(): @@ -229,7 +229,7 @@ class StatusBar(component.Component): item = self.add_item(image, stock, text, callback) # Start a timer to remove this item in seconds gobject.timeout_add(seconds * 1000, self.remove_item, item) - + def display_warning(self, text, callback=None): """Displays a warning to the user in the status bar""" if text not in self.current_warnings: @@ -237,16 +237,16 @@ class StatusBar(component.Component): stock=gtk.STOCK_DIALOG_WARNING, text=text, callback=callback) self.current_warnings.append(text) gobject.timeout_add(3000, self.remove_warning, item) - + def remove_warning(self, item): self.current_warnings.remove(item.get_text()) self.remove_item(item) - + def clear_statusbar(self): def remove(child): self.hbox.remove(child) self.hbox.foreach(remove) - + def send_status_request(self): # Sends an async request for data from the core client.get_num_connections(self._on_get_num_connections) @@ -261,22 +261,22 @@ class StatusBar(component.Component): def config_value_changed(self, key, value): """This is called when we received a config_value_changed signal from the core.""" - + if key in self.config_value_changed_dict.keys(): self.config_value_changed_dict[key](value) - + def _on_max_connections_global(self, max_connections): self.max_connections = max_connections self.update_connections_label() - + def _on_get_num_connections(self, num_connections): self.num_connections = num_connections self.update_connections_label() - + def _on_get_dht_nodes(self, dht_nodes): self.dht_nodes = dht_nodes self.update_dht_label() - + def _on_dht(self, value): self.dht_status = value if value: @@ -289,7 +289,7 @@ class StatusBar(component.Component): def _on_max_download_speed(self, max_download_speed): self.max_download_speed = max_download_speed self.update_download_label() - + def _on_get_download_rate(self, download_rate): self.download_rate = deluge.common.fsize(download_rate) self.update_download_label() @@ -297,16 +297,16 @@ class StatusBar(component.Component): def _on_max_upload_speed(self, max_upload_speed): self.max_upload_speed = max_upload_speed self.update_upload_label() - + def _on_get_upload_rate(self, upload_rate): self.upload_rate = deluge.common.fsize(upload_rate) self.update_upload_label() - + def _on_get_health(self, value): self.health = value if self.health: - self.remove_item(self.health_item) - + self.remove_item(self.health_item) + def update_connections_label(self): # Set the max connections label if self.max_connections < 0: @@ -315,11 +315,11 @@ class StatusBar(component.Component): label_string = "%s (%s)" % (self.num_connections, self.max_connections) self.connections_item.set_text(label_string) - + def update_dht_label(self): # Set the max connections label self.dht_item.set_text("%s" % (self.dht_nodes)) - + def update_download_label(self): # Set the download speed label if self.max_download_speed < 0: @@ -329,7 +329,7 @@ class StatusBar(component.Component): self.download_rate, self.max_download_speed, _("KiB/s")) self.download_item.set_text(label_string) - + def update_upload_label(self): # Set the upload speed label if self.max_upload_speed < 0: @@ -337,16 +337,16 @@ class StatusBar(component.Component): else: label_string = "%s/s (%s %s)" % ( self.upload_rate, self.max_upload_speed, _("KiB/s")) - + self.upload_item.set_text(label_string) - + def update(self): # Send status request self.send_status_request() - + def _on_download_item_clicked(self, widget, event): menu = deluge.common.build_menu_radio_list( - self.config["tray_download_speed_list"], + self.config["tray_download_speed_list"], self._on_set_download_speed, self.max_download_speed, _("KiB/s"), show_notset=True, show_other=True) @@ -367,14 +367,14 @@ class StatusBar(component.Component): value = float(widget.get_children()[0].get_text().split(" ")[0]) log.debug("value: %s", value) - - # Set the config in the core + + # Set the config in the core if value != self.max_download_speed: client.set_config({"max_download_speed": value}) def _on_upload_item_clicked(self, widget, event): menu = deluge.common.build_menu_radio_list( - self.config["tray_upload_speed_list"], + self.config["tray_upload_speed_list"], self._on_set_upload_speed, self.max_upload_speed, _("KiB/s"), show_notset=True, show_other=True) @@ -395,38 +395,38 @@ class StatusBar(component.Component): value = float(widget.get_children()[0].get_text().split(" ")[0]) log.debug("value: %s", value) - + # Set the config in the core if value != self.max_upload_speed: client.set_config({"max_upload_speed": value}) def _on_connection_item_clicked(self, widget, event): menu = deluge.common.build_menu_radio_list( - self.config["connection_limit_list"], + self.config["connection_limit_list"], self._on_set_connection_limit, self.max_connections, show_notset=True, show_other=True) menu.show_all() menu.popup(None, None, None, event.button, event.time) - + def _on_set_connection_limit(self, widget): log.debug("_on_set_connection_limit") - + if widget.get_name() == _("Unlimited"): value = -1 elif widget.get_name() == _("Other..."): - value = deluge.common.show_other_dialog( - _("Connection Limit:"), self.max_connections) + value = int(deluge.common.show_other_dialog( + _("Connection Limit:"), self.max_connections)) if value == None: return else: value = int(widget.get_children()[0].get_text().split(" ")[0]) log.debug("value: %s", value) - - # Set the config in the core + + # Set the config in the core if value != self.max_connections: client.set_config({"max_connections_global": value}) - + def _on_health_icon_clicked(self, widget, event): component.get("Preferences").show("Network")