From 4c2ec1b8fb4cc6ba82793d9a1f5d475e85c36e31 Mon Sep 17 00:00:00 2001 From: Andrew Resch Date: Tue, 12 Feb 2008 21:29:39 +0000 Subject: [PATCH] Change torrent saving/loading to use torrent options and update the state format to support new options. Some minor modifications to CoreProxy in client -- only run the do_multicall timer when 'connected' to a core. --- TODO | 2 - deluge/component.py | 4 +- deluge/core/core.py | 8 +-- deluge/core/torrent.py | 10 ++-- deluge/core/torrentmanager.py | 101 +++++++++++++++++++++++----------- deluge/ui/client.py | 20 +++++-- 6 files changed, 92 insertions(+), 53 deletions(-) diff --git a/TODO b/TODO index c9c94eafd..f3a5b1dec 100644 --- a/TODO +++ b/TODO @@ -19,8 +19,6 @@ * Implement caching in core * Use the batch torrent status info as a cache for other torrent status requests * Don't save fastresume files on exit for finished or paused torrents -* Clean-up TorrentManager and state saving.. Maybe use an 'options' dictionary - similar to one used when adding new torrents. * Add Files and Peers tabs, but make them optional through View menu * Add per-torrent speed settings to the torrent menu * Add per-torrent settings to the details pane.. max_download_speed, etc.. So diff --git a/deluge/component.py b/deluge/component.py index 3f87b9cfe..dce2f2997 100644 --- a/deluge/component.py +++ b/deluge/component.py @@ -62,11 +62,11 @@ class Component: pass def _stop(self): + self._state = COMPONENT_STATE.index("Stopped") try: gobject.source_remove(self._timer) except: pass - self._state = COMPONENT_STATE.index("Stopped") def shutdown(self): pass @@ -121,7 +121,7 @@ class ComponentRegistry: self.stop_component(component) def stop_component(self, component): - if self.components[component].get_state != \ + if self.components[component].get_state() != \ COMPONENT_STATE.index("Stopped"): log.debug("Stopping component %s..", component) self.components[component].stop() diff --git a/deluge/core/core.py b/deluge/core/core.py index 45c67d6b8..5107e94ad 100644 --- a/deluge/core/core.py +++ b/deluge/core/core.py @@ -287,19 +287,15 @@ class Core( """De-registers a client with the signal manager.""" self.signals.deregister_client(self.client_address) - def export_add_torrent_file(self, filename, save_path, filedump, options): + 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 """ - if save_path == "": - save_path = None - # Make sure we are sending a string to add() if not isinstance(filedump, str): filedump = filedump.data - torrent_id = self.torrents.add(filename, filedump=filedump, - save_path=save_path, options=options) + torrent_id = self.torrents.add(filename, filedump=filedump, options=options) # Run the plugin hooks for 'post_torrent_add' self.plugins.run_post_torrent_add(torrent_id) diff --git a/deluge/core/torrent.py b/deluge/core/torrent.py index b2fd84b7b..1be3c66b7 100644 --- a/deluge/core/torrent.py +++ b/deluge/core/torrent.py @@ -83,7 +83,7 @@ class Torrent: self.max_upload_speed = -1 self.max_download_speed = -1 self.private = False - self.prioritize = False + self.prioritize_first_last = False # The tracker status self.tracker_status = "" @@ -98,10 +98,12 @@ class Torrent: self.trackers.append(tracker) else: self.trackers = trackers - + self.set_trackers(self.trackers) + # Files dictionary self.files = self.get_files() - self.file_priorities = [] + # Set the default file priorities to normal + self.file_priorities = [1]* len(self.files) def set_tracker_status(self, status): """Sets the tracker status""" @@ -128,7 +130,7 @@ class Torrent: self.handle.torrent_info().set_priv(private) def set_prioritize_first_last(self, prioritize): - pass + self.prioritize_first_last = prioritize def set_save_path(self, save_path): self.save_path = save_path diff --git a/deluge/core/torrentmanager.py b/deluge/core/torrentmanager.py index 36f38e182..ff4ac45f4 100644 --- a/deluge/core/torrentmanager.py +++ b/deluge/core/torrentmanager.py @@ -48,15 +48,36 @@ from deluge.core.torrent import Torrent from deluge.log import LOG as log class TorrentState: - def __init__(self, torrent_id, filename, compact, paused, save_path, - total_uploaded, trackers): - self.torrent_id = torrent_id + def __init__(self, + filename, + total_uploaded, + trackers, + compact, + paused, + save_path, + max_connections, + max_upload_slots, + max_upload_speed, + max_download_speed, + prioritize_first_last, + private, + file_priorities + ): self.filename = filename + self.total_uploaded = total_uploaded + self.trackers = trackers + + # Options self.compact = compact self.paused = paused self.save_path = save_path - self.total_uploaded = total_uploaded - self.trackers = trackers + self.max_connections = max_connections + self.max_upload_slots = max_upload_slots + self.max_upload_speed = max_upload_speed + self.max_download_speed = max_download_speed + self.prioritize_first_last = prioritize_first_last + self.private = private + self.file_priorities = file_priorities class TorrentManagerState: def __init__(self): @@ -130,9 +151,7 @@ class TorrentManager(component.Component): """Returns a list of torrent_ids""" return self.torrents.keys() - def add(self, filename, filedump=None, options=None, - compact=None, paused=None, save_path=None, total_uploaded=0, - trackers=None): + def add(self, filename, filedump=None, options=None, total_uploaded=0, trackers=None): """Add a torrent to the manager and returns it's torrent_id""" log.info("Adding torrent: %s", filename) log.debug("options: %s", options) @@ -193,20 +212,9 @@ class TorrentManager(component.Component): for key in options_keys: if not options.has_key(key): options[key] = self.config[key] - - if paused is None: - paused = options["add_paused"] - - # Make sure we have a valid download_location - if save_path is None: - save_path = options["download_location"] - - # Make sure we are adding it with the correct allocation method. - if compact is None: - compact = options["compact_allocation"] # Set the right storage_mode - if compact: + if options["compact_allocation"]: storage_mode = lt.storage_mode_t(2) else: storage_mode = lt.storage_mode_t(1) @@ -214,7 +222,7 @@ class TorrentManager(component.Component): try: handle = self.session.add_torrent( lt.torrent_info(filedump), - str(save_path), + str(options["download_location"]), resume_data=fastresume, storage_mode=storage_mode, paused=True) @@ -226,15 +234,11 @@ class TorrentManager(component.Component): return None # Create a Torrent object - torrent = Torrent(filename, handle, compact, - save_path, total_uploaded, trackers) + torrent = Torrent(filename, handle, options["compact_allocation"], + options["download_location"], total_uploaded, trackers) # Add the torrent object to the dictionary self.torrents[torrent.torrent_id] = torrent - - # Set the trackers - if trackers != None: - torrent.set_trackers(trackers) # Set per-torrent options torrent.set_max_connections(options["max_connections_per_torrent"]) @@ -252,7 +256,7 @@ class TorrentManager(component.Component): torrent.set_file_priorities(options["file_priorities"]) # Resume the torrent if needed - if paused == False: + if options["add_paused"] == False: handle.resume() # Save the torrent file @@ -408,17 +412,48 @@ class TorrentManager(component.Component): # Try to add the torrents in the state to the session for torrent_state in state.torrents: - self.add(torrent_state.filename, compact=torrent_state.compact, - paused=torrent_state.paused, save_path=torrent_state.save_path, - total_uploaded=torrent_state.total_uploaded, - trackers=torrent_state.trackers) + try: + options = { + "compact_allocation": torrent_state.compact, + "max_connections_per_torrent": torrent_state.max_connections, + "max_upload_slots_per_torrent": torrent_state.max_upload_slots, + "max_upload_speed_per_torrent": torrent_state.max_upload_speed, + "max_download_speed_per_torrent": torrent_state.max_download_speed, + "prioritize_first_last_pieces": torrent_state.prioritize_first_last, + "download_location": torrent_state.save_path, + "add_paused": torrent_state.paused, + "default_private": torrent_state.private, + "file_priorities": torrent_state.file_priorities + } + self.add( + torrent_state.filename, + options=options, + total_uploaded=torrent_state.total_uploaded, + trackers=torrent_state.trackers) + except AttributeError, e: + log.error("Torrent state file is either corrupt or incompatible!") + break def save_state(self): """Save the state of the TorrentManager to the torrents.state file""" state = TorrentManagerState() # Create the state for each Torrent and append to the list for torrent in self.torrents.values(): - torrent_state = TorrentState(*torrent.get_save_info()) + torrent_state = TorrentState( + torrent.filename, + torrent.get_status(["total_uploaded"])["total_uploaded"], + torrent.trackers, + torrent.compact, + torrent.get_status(["paused"])["paused"], + torrent.save_path, + torrent.max_connections, + torrent.max_upload_slots, + torrent.max_upload_speed, + torrent.max_download_speed, + torrent.prioritize_first_last, + torrent.private, + torrent.file_priorities + ) state.torrents.append(torrent_state) # Pickle the TorrentManagerState object diff --git a/deluge/ui/client.py b/deluge/ui/client.py index dc94df27c..341b8f508 100644 --- a/deluge/ui/client.py +++ b/deluge/ui/client.py @@ -58,7 +58,7 @@ class CoreProxy(gobject.GObject): self._core = None self._multi = None self._callbacks = [] - gobject.timeout_add(200, self.do_multicall) + self._multi_timer = None def call(self, func, callback, *args): if self._core is None or self._multi is None: @@ -84,7 +84,7 @@ class CoreProxy(gobject.GObject): if len(self._callbacks) == 0: return True - if self._multi is not None: + if self._multi is not None and self._core is not None: try: try: for i, ret in enumerate(self._multi()): @@ -109,15 +109,23 @@ class CoreProxy(gobject.GObject): log.info("Setting core uri as %s", uri) if uri == None and self._uri != None: - self.emit("no_core") self._uri = None self._core = None self._multi = None + try: + gobject.source_remove(self._multi_timer) + except: + pass + self.emit("no_core") return if uri != self._uri and self._uri != None: self._core = None self._multi = None + try: + gobject.source_remove(self._multi_timer) + except: + pass self.emit("no_core") self._uri = uri @@ -133,6 +141,7 @@ class CoreProxy(gobject.GObject): log.debug("Creating ServerProxy..") self._core = xmlrpclib.ServerProxy(self._uri, allow_none=True) self._multi = xmlrpclib.MultiCall(self._core) + self._multi_timer = gobject.timeout_add(200, self.do_multicall) # Call any callbacks registered self.emit("new_core") @@ -189,8 +198,7 @@ def shutdown(): try: get_core().call("shutdown", None) force_call(block=False) - except: - # Ignore everything + finally: set_core_uri(None) def force_call(block=True): @@ -231,7 +239,7 @@ def add_torrent_file(torrent_files, torrent_options=None): options = None get_core().call("add_torrent_file", None, - filename, str(), fdump, options) + filename, fdump, options) def add_torrent_url(torrent_url, options=None): """Adds torrents to the core via url"""