diff --git a/deluge/core/core.py b/deluge/core/core.py index 08def8c58..9d8cafc0b 100644 --- a/deluge/core/core.py +++ b/deluge/core/core.py @@ -65,6 +65,7 @@ DEFAULT_PREFS = { "listen_ports": [6881, 6891], "torrentfiles_location": os.path.join(deluge.configmanager.get_config_dir(), "torrentfiles"), "plugins_location": os.path.join(deluge.configmanager.get_config_dir(), "plugins"), + "state_location": os.path.join(deluge.configmanager.get_config_dir(), "state"), "prioritize_first_last_pieces": False, "random_port": True, "dht": False, @@ -88,7 +89,6 @@ DEFAULT_PREFS = { "autoadd_location": "", "autoadd_enable": False, "add_paused": False, - "default_private": False, "max_active_seeding": -1, "max_active_downloading": -1, "queue_new_to_top": False, @@ -207,6 +207,8 @@ class Core( # Register set functions in the Config self.config.register_set_function("torrentfiles_location", 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._on_set_listen_ports) self.config.register_set_function("random_port", @@ -300,12 +302,31 @@ class Core( """Adds a torrent file to the libtorrent session This requires the torrents filename and a dump of it's content """ - # Make sure we are sending a string to add() + # Turn the filedump into a torrent_info if not isinstance(filedump, str): filedump = filedump.data +# filedump = "".join(chr(b) for b in filedump) + try: + torrent_info = lt.torrent_info(lt.bdecode(filedump)) + except RuntimeError, e: + log.warn("Unable to decode torrent file: %s", e) + return None + + torrent_id = self.torrents.add(torrent_info=torrent_info, options=options) - torrent_id = self.torrents.add(filename, filedump=filedump, options=options) - + # Here we need to save a copy of the filedump for state purposes + # and also if the user wishes to save a copy of the torrent elsewhere. + if torrent_id: + # Write the .torrent file to the state directory + try: + save_file = open(os.path.join(self.config["state_location"], + torrent_id + ".torrent"), + "wb") + save_file.write(filedump) + save_file.close() + except IOError, e: + log.warning("Unable to save torrent file: %s", e) + # Run the plugin hooks for 'post_torrent_add' self.plugins.run_post_torrent_add(torrent_id) @@ -497,11 +518,7 @@ class Core( 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_private_flag(self, torrent_id, value): - """Sets a torrents private flag""" - return self.torrents[torrent_id].set_private_flag(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) @@ -636,7 +653,14 @@ class Core( shutil.copy2(os.path.join(root, file), value) except Exception, e: log.debug("Unable to copy file to %s: %s", value, 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: diff --git a/deluge/core/torrent.py b/deluge/core/torrent.py index 1521e499e..484fe61fb 100644 --- a/deluge/core/torrent.py +++ b/deluge/core/torrent.py @@ -47,8 +47,7 @@ TORRENT_STATE = deluge.common.TORRENT_STATE class Torrent: """Torrent holds information about torrents added to the libtorrent session. """ - def __init__(self, filename, handle, compact, save_path, total_uploaded=0, - trackers=None): + def __init__(self, handle, options, state=None): log.debug("Creating torrent object %s", str(handle.info_hash())) # Get the core config self.config = ConfigManager("core.conf") @@ -56,41 +55,32 @@ class Torrent: # Get a reference to the TorrentQueue self.torrentqueue = component.get("TorrentQueue") self.signals = component.get("SignalManager") - - # Set the filename - self.filename = filename + # Set the libtorrent handle self.handle = handle # Set the torrent_id for this torrent self.torrent_id = str(handle.info_hash()) - # This is for saving the total uploaded between sessions - self.total_uploaded = total_uploaded - # Set the allocation mode - self.compact = compact - # Where the torrent is being saved to - self.save_path = save_path - # Status message holds error info about the torrent - self.statusmsg = "OK" - - # The torrents state - self.state = "" - + # Holds status info so that we don't need to keep getting it from lt self.status = self.handle.status() self.torrent_info = self.handle.get_torrent_info() - # Various torrent options - self.max_connections = -1 - self.max_upload_slots = -1 - self.max_upload_speed = -1 - self.max_download_speed = -1 - self.private = False - self.prioritize_first_last = False + # Files dictionary + self.files = self.get_files() + # Set the default file priorities to normal + self.file_priorities = [1]* len(self.files) - # The tracker status - self.tracker_status = "" - # Tracker list - if trackers == None: + # Default total_uploaded to 0, this may be changed by the state + self.total_uploaded = 0 + + # Load values from state if we have it + if state is not None: + # This is for saving the total uploaded between sessions + self.total_uploaded = state.total_uploaded + # Set the trackers + self.set_trackers(state.trackers) + else: + # Tracker list self.trackers = [] # Create a list of trackers for value in self.handle.trackers(): @@ -98,17 +88,33 @@ class Torrent: tracker["url"] = value.url tracker["tier"] = value.tier self.trackers.append(tracker) - else: - self.trackers = trackers - self.set_trackers(self.trackers) - - # Files dictionary - self.files = self.get_files() - # Set the default file priorities to normal - self.file_priorities = [1]* len(self.files) - # Set resolve_countries to True - self.handle.resolve_countries(True) + # Various torrent options + self.set_max_connections(options["max_connections_per_torrent"]) + self.set_max_upload_slots(options["max_upload_slots_per_torrent"]) + self.set_max_upload_speed(options["max_upload_speed_per_torrent"]) + self.set_max_download_speed(options["max_download_speed_per_torrent"]) + self.set_prioritize_first_last(options["prioritize_first_last_pieces"]) + self.handle.resolve_countries(True) + if options.has_key("file_priorities"): + self.set_file_priorities(options["file_priorities"]) + + # Set the allocation mode + self.compact = options["compact_allocation"] + # Where the torrent is being saved to + self.save_path = options["download_location"] + # Status message holds error info about the torrent + self.statusmsg = "OK" + + # The torrents state + self.state = "" + + # The tracker status + self.tracker_status = "" + + # This variable is to prevent a state change to 'Paused' when it should + # be 'Queued' + self.next_pause_is_queued = False log.debug("Torrent object created.") @@ -132,10 +138,6 @@ class Torrent: self.max_download_speed = m_down_speed self.handle.set_download_limit(int(m_down_speed * 1024)) - def set_private_flag(self, private): - self.private = private - #self.handle.get_torrent_info().set_priv(private) - def set_prioritize_first_last(self, prioritize): self.prioritize_first_last = prioritize @@ -155,6 +157,30 @@ class Torrent: self.file_priorities = file_priorities self.handle.prioritize_files(file_priorities) + + def set_trackers(self, trackers): + """Sets trackers""" + if trackers == None: + trackers = [] + + log.debug("Setting trackers for %s: %s", self.torrent_id, trackers) + tracker_list = [] + + for tracker in trackers: + new_entry = lt.announce_entry(tracker["url"]) + new_entry.tier = tracker["tier"] + tracker_list.append(new_entry) + + self.handle.replace_trackers(tracker_list) + + # Print out the trackers + for t in self.handle.trackers(): + log.debug("tier: %s tracker: %s", t.tier, t.url) + # Set the tracker list in the torrent object + self.trackers = trackers + if len(trackers) > 0: + # Force a reannounce if there is at least 1 tracker + self.force_reannounce() def set_state_based_on_ltstate(self): """Updates the state based on what libtorrent's state for the torrent is""" @@ -183,8 +209,18 @@ class Torrent: if state != self.state: if state == "Queued" and not self.handle.is_paused(): - component.get("TorrentManager").append_not_state_paused(self.torrent_id) + #component.get("TorrentManager").append_not_state_paused(self.torrent_id) + self.next_pause_is_queued = True self.handle.pause() + if state == "Error" and not self.handle.is_paused(): + self.next_pause_is_queued = True + + if state == "Paused": + if self.next_pause_is_queued: + self.state = "Queued" + self.next_pause_is_queued = False + else: + self.state = "Paused" log.debug("Setting %s's state to %s", self.torrent_id, state) self.state = state @@ -256,7 +292,6 @@ class Torrent: def get_queue_position(self): # We augment the queue position + 1 so that the user sees a 1 indexed # list. - return self.torrentqueue[self.torrent_id] + 1 def get_peers(self): @@ -335,13 +370,13 @@ class Torrent: "max_upload_speed": self.max_upload_speed, "max_download_speed": self.max_download_speed, "prioritize_first_last": self.prioritize_first_last, - "private": self.private, "message": self.statusmsg, "hash": self.torrent_id } fns = { "name": self.torrent_info.name, + "private": self.torrent_info.priv, "total_size": self.torrent_info.total_size, "num_files": self.torrent_info.num_files, "num_pieces": self.torrent_info.num_pieces, @@ -372,14 +407,13 @@ class Torrent: status_dict[key] = fns[key]() return status_dict - + def apply_options(self): """Applies the per-torrent options that are set.""" self.handle.set_max_connections(self.max_connections) self.handle.set_max_uploads(self.max_upload_slots) self.handle.set_upload_limit(int(self.max_upload_speed * 1024)) self.handle.set_download_limit(int(self.max_download_speed * 1024)) - self.handle.get_torrent_info().set_priv(self.private) self.handle.prioritize_files(self.file_priorities) self.handle.resolve_countries(True) @@ -472,8 +506,8 @@ class Torrent: """Writes the .fastresume file for the torrent""" resume_data = lt.bencode(self.handle.write_resume_data()) path = "%s/%s.fastresume" % ( - self.config["torrentfiles_location"], - self.filename) + self.config["state_location"], + self.torrent_id) log.debug("Saving fastresume file: %s", path) try: fastresume = open(path, "wb") @@ -485,14 +519,25 @@ class Torrent: def delete_fastresume(self): """Deletes the .fastresume file""" path = "%s/%s.fastresume" % ( - self.config["torrentfiles_location"], - self.filename) + self.config["state_location"], + self.torrent_id) log.debug("Deleting fastresume file: %s", path) try: os.remove(path) except Exception, e: log.warning("Unable to delete the fastresume file: %s", e) + def delete_torrentfile(self): + """Deletes the .torrent file in the state""" + path = "%s/%s.torrent" % ( + self.config["state_location"], + self.torrent_id) + log.debug("Deleting torrent file: %s", path) + try: + os.remove(path) + except Exception, e: + log.warning("Unable to delete the torrent file: %s", e) + def force_reannounce(self): """Force a tracker reannounce""" try: @@ -512,52 +557,3 @@ class Torrent: return False return True - - def set_trackers(self, trackers): - """Sets trackers""" - if trackers == None: - trackers = [] - - log.debug("Setting trackers for %s: %s", self.torrent_id, trackers) - tracker_list = [] - - for tracker in trackers: - new_entry = lt.announce_entry(tracker["url"]) - new_entry.tier = tracker["tier"] - tracker_list.append(new_entry) - - self.handle.replace_trackers(tracker_list) - - # Print out the trackers - for t in self.handle.trackers(): - log.debug("tier: %s tracker: %s", t.tier, t.url) - # Set the tracker list in the torrent object - self.trackers = trackers - if len(trackers) > 0: - # Force a reannounce if there is at least 1 tracker - self.force_reannounce() - - def save_torrent_file(self, filedump=None): - """Saves a torrent file""" - log.debug("Attempting to save torrent file: %s", self.filename) - # Test if the torrentfiles_location is accessible - if os.access( - os.path.join(self.config["torrentfiles_location"]), os.F_OK) \ - is False: - # The directory probably doesn't exist, so lets create it - try: - os.makedirs(os.path.join(self.config["torrentfiles_location"])) - except IOError, e: - log.warning("Unable to create torrent files directory: %s", e) - - # Write the .torrent file to the torrent directory - try: - save_file = open(os.path.join(self.config["torrentfiles_location"], - self.filename), - "wb") - if filedump == None: - filedump = self.handle.get_torrent_info().create_torrent() - save_file.write(lt.bencode(filedump)) - save_file.close() - except IOError, e: - log.warning("Unable to save torrent file: %s", e) diff --git a/deluge/core/torrentmanager.py b/deluge/core/torrentmanager.py index 08129d5b0..1411f077c 100644 --- a/deluge/core/torrentmanager.py +++ b/deluge/core/torrentmanager.py @@ -51,8 +51,7 @@ from deluge.log import LOG as log class TorrentState: def __init__(self, - torrent_id, - filename, + torrent_id, total_uploaded, trackers, compact, @@ -63,12 +62,10 @@ class TorrentState: max_upload_speed, max_download_speed, prioritize_first_last, - private, file_priorities, queue ): self.torrent_id = torrent_id - self.filename = filename self.total_uploaded = total_uploaded self.trackers = trackers self.queue = queue @@ -82,7 +79,6 @@ class TorrentState: 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: @@ -108,9 +104,6 @@ class TorrentManager(component.Component): # Create the torrents dict { torrent_id: Torrent } self.torrents = {} - - # List of torrents to not set state 'Paused' on lt alert - self.not_state_paused = [] # Register set functions self.config.register_set_function("max_connections_per_torrent", @@ -172,105 +165,119 @@ class TorrentManager(component.Component): def get_torrent_list(self): """Returns a list of torrent_ids""" return self.torrents.keys() + + def get_torrent_info_from_file(self, filepath): + """Returns a torrent_info for the file specified or None""" + torrent_info = None + # Get the torrent data from the torrent file + try: + log.debug("Attempting to create torrent_info from %s", filepath) + _file = open(filepath, "rb") + torrent_info = lt.torrent_info(lt.bdecode(_file.read())) + _file.close() + except (IOError, RuntimeError), e: + log.warning("Unable to open %s: %s", filepath, e) + + return torrent_info - def append_not_state_paused(self, torrent_id): - """Appends to a list of torrents that we will not set state Paused to - when we receive the paused alert from libtorrent. The torrents are removed - from this list once we receive the alert they have been paused in libtorrent.""" - if torrent_id not in self.not_state_paused: - self.not_state_paused.append(torrent_id) - - def add(self, filename, filedump=None, options=None, total_uploaded=0, - trackers=None, queue=-1, state=None, save_state=True): - """Add a torrent to the manager and returns it's torrent_id""" - log.info("Adding torrent: %s", filename) - log.debug("options: %s", options) - # Make sure 'filename' is a python string - filename = str(filename) - - # Convert the filedump data array into a string of bytes - if filedump is not None: - # If the filedump is already of type str, then it's already been - # joined. - if type(filedump) is not str: - filedump = "".join(chr(b) for b in filedump) - try: - filedump = lt.bdecode(filedump) - except RuntimeError, e: - log.warn("Unable to decode torrent file: %s", e) - return None - else: - # Get the data from the file - filedump = self.load_torrent(filename) - if not filedump: - log.warning("Unable to load torrent file..") - return None - - # Attempt to load fastresume data + def get_resume_data_from_file(self, torrent_id): + """Returns an entry with the resume data or None""" + fastresume = None try: _file = open( os.path.join( - self.config["torrentfiles_location"], - filename + ".fastresume"), + self.config["state_location"], + torrent_id + ".fastresume"), "rb") try: fastresume = lt.bdecode(_file.read()) except RuntimeError, e: log.warning("Unable to bdecode fastresume file: %s", e) - fastresume = None _file.close() except IOError, e: log.debug("Unable to load .fastresume: %s", e) - fastresume = None - handle = None + return fastresume + + def add(self, torrent_info=None, state=None, options=None, save_state=True): + """Add a torrent to the manager and returns it's torrent_id""" + if torrent_info is None and state is None: + log.debug("You must specify a valid torrent_info or a torrent state object!") + return - # Check if options is None and load defaults - options_keys = [ - "compact_allocation", - "max_connections_per_torrent", - "max_upload_slots_per_torrent", - "max_upload_speed_per_torrent", - "max_download_speed_per_torrent", - "prioritize_first_last_pieces", - "download_location", - "add_paused", - "default_private" - ] + log.debug("torrentmanager.add") + add_torrent_params = {} + + if torrent_info is None: + # We have no torrent_info so we need to add the torrent with information + # from the state object. - if options == None: + # Populate the options dict from state options = {} - for key in options_keys: - options[key] = self.config[key] + options["max_connections_per_torrent"] = state.max_connections + options["max_upload_slots_per_torrent"] = state.max_upload_slots + options["max_upload_speed_per_torrent"] = state.max_upload_speed + options["max_download_speed_per_torrent"] = state.max_download_speed + options["prioritize_first_last_pieces"] = state.prioritize_first_last + options["file_priorities"] = state.file_priorities + options["compact_allocation"] = state.compact + options["download_location"] = state.save_path + + add_torrent_params["ti"] =\ + self.get_torrent_info_from_file( + os.path.join(self.config["state_location"], state.torrent_id + ".torrent")) + add_torrent_params["resume_data"] = self.get_resume_data_from_file(state.torrent_id) else: - for key in options_keys: - if not options.has_key(key): + # We have a torrent_info object so we're not loading from state. + # Check if options is None and load defaults + options_keys = [ + "compact_allocation", + "max_connections_per_torrent", + "max_upload_slots_per_torrent", + "max_upload_speed_per_torrent", + "max_download_speed_per_torrent", + "prioritize_first_last_pieces", + "download_location", + "add_paused", + ] + + if options == None: + options = {} + for key in options_keys: options[key] = self.config[key] - + else: + for key in options_keys: + if not options.has_key(key): + options[key] = self.config[key] + + add_torrent_params["ti"] = torrent_info + add_torrent_params["resume_data"] = None + + #log.info("Adding torrent: %s", filename) + log.debug("options: %s", options) + # Set the right storage_mode if options["compact_allocation"]: storage_mode = lt.storage_mode_t(2) else: storage_mode = lt.storage_mode_t(1) + # Fill in the rest of the add_torrent_params dictionary + add_torrent_params["save_path"] = str(options["download_location"]) + + add_torrent_params["storage_mode"] = storage_mode + add_torrent_params["paused"] = True + add_torrent_params["auto_managed"] = False + add_torrent_params["duplicate_is_error"] = True + # We need to pause the AlertManager momentarily to prevent alerts # for this torrent being generated before a Torrent object is created. component.pause("AlertManager") - # Create the torrent parameters struct for the torrent's options - t_params = {} - - t_params["ti"] = lt.torrent_info(filedump) - t_params["save_path"] = str(options["download_location"]) - t_params["resume_data"] = fastresume - t_params["storage_mode"] = storage_mode - t_params["paused"] = True - t_params["auto_managed"] = False - t_params["duplicate_is_error"] = True - + handle = None try: - handle = self.session.add_torrent(t_params) + handle = self.session.add_torrent(add_torrent_params) except RuntimeError, e: log.warning("Error adding torrent: %s", e) @@ -278,76 +285,59 @@ class TorrentManager(component.Component): log.debug("torrent handle is invalid!") # The torrent was not added to the session component.resume("AlertManager") - return None - + return + + log.debug("handle id: %s", str(handle.info_hash())) # Create a Torrent object - torrent = Torrent(filename, handle, options["compact_allocation"], - options["download_location"], total_uploaded, trackers) + torrent = Torrent(handle, options, state) # Add the torrent object to the dictionary self.torrents[torrent.torrent_id] = torrent component.resume("AlertManager") # Add the torrent to the queue - if queue == -1 and self.config["queue_new_to_top"]: - self.queue.insert(0, torrent.torrent_id) + if state is not None: + self.queue.insert(state.queue, torrent.torrent_id) else: - self.queue.insert(queue, torrent.torrent_id) + if self.config["queue_new_to_top"]: + self.queue.insert(0, torrent.torrent_id) + else: + self.queue.append(torrent.torrent_id) - # Set per-torrent options - torrent.set_max_connections(options["max_connections_per_torrent"]) - torrent.set_max_upload_slots(options["max_upload_slots_per_torrent"]) - torrent.set_max_upload_speed(options["max_upload_speed_per_torrent"]) - torrent.set_max_download_speed( - options["max_download_speed_per_torrent"]) - torrent.set_prioritize_first_last( - options["prioritize_first_last_pieces"]) - torrent.set_private_flag(options["default_private"]) - - if options.has_key("file_priorities"): - if options["file_priorities"] != None: - log.debug("set file priorities: %s", options["file_priorities"]) - torrent.set_file_priorities(options["file_priorities"]) - log.debug("state: %s", state) # Resume the torrent if needed - if state == "Queued": - torrent.state = "Queued" - elif state == "Paused" or state == "Error": + if state == "Paused" or state == "Error": torrent.state = "Paused" - if state == None and not options["add_paused"]: + elif state == None and not options["add_paused"]: torrent.handle.resume() # We set the state based on libtorrent's state torrent.set_state_based_on_ltstate() - if state == None and options["add_paused"]: + elif state == None and options["add_paused"]: torrent.set_state = "Paused" - - # Emit the torrent_added signal - self.signals.emit("torrent_added", torrent.torrent_id) - - # Save the torrent file - torrent.save_torrent_file(filedump) if save_state: # Save the session state self.save_state() - + + # Emit the torrent_added signal + self.signals.emit("torrent_added", torrent.torrent_id) + return torrent.torrent_id - def load_torrent(self, filename): - """Load a torrent file and return it's torrent info""" + def load_torrent(self, torrent_id): + """Load a torrent file from state and return it's torrent info""" filedump = None # Get the torrent data from the torrent file try: - log.debug("Attempting to open %s for add.", filename) + log.debug("Attempting to open %s for add.", torrent_id) _file = open( os.path.join( - self.config["torrentfiles_location"], filename), + self.config["state_location"], torrent_id + ".torrent"), "rb") filedump = lt.bdecode(_file.read()) _file.close() except (IOError, RuntimeError), e: - log.warning("Unable to open %s: %s", filename, e) + log.warning("Unable to open %s: %s", torrent_id, e) return False return filedump @@ -379,6 +369,9 @@ class TorrentManager(component.Component): # Remove the .fastresume if it exists self.torrents[torrent_id].delete_fastresume() + # Remove the .torrent file in the state + self.torrents[torrent_id].delete_torrentfile() + # Remove the torrent from the queue self.queue.remove(torrent_id) @@ -417,15 +410,12 @@ class TorrentManager(component.Component): def force_recheck(self, torrent_id): """Forces a re-check of the torrent's data""" + log.debug("force recheck is broken for the time being") + return log.debug("Doing a forced recheck on %s", torrent_id) torrent = self.torrents[torrent_id] paused = self.torrents[torrent_id].handle.is_paused() - torrent_info = None - ### Check for .torrent file prior to removing and make a copy if needed - if os.access(os.path.join(self.config["torrentfiles_location"] +\ - "/" + torrent.filename), os.F_OK) is False: - torrent_info = torrent.handle.get_torrent_info().create_torrent() - torrent.save_torrent_file() + torrent_info = torrent.handle.get_torrent_info() # We need to pause the AlertManager momentarily to prevent alerts # for this torrent being generated before a Torrent object is created. @@ -439,11 +429,11 @@ class TorrentManager(component.Component): return False # Remove the fastresume file if there - torrent.delete_fastresume() + #torrent.delete_fastresume() # Load the torrent info from file if needed if torrent_info == None: - torrent_info = self.load_torrent(torrent.filename) + torrent_info = self.load_torrent(torrent.torrent_id) # Next we re-add the torrent @@ -489,7 +479,7 @@ class TorrentManager(component.Component): try: log.debug("Opening torrent state file for load.") state_file = open( - os.path.join(self.config["config_location"], "torrents.state"), "rb") + os.path.join(self.config["state_location"], "torrents.state"), "rb") state = cPickle.load(state_file) state_file.close() except IOError: @@ -506,37 +496,20 @@ class TorrentManager(component.Component): fr_first = [] for torrent_state in state.torrents: if os.path.exists(os.path.join( - self.config["torrentfiles_location"], - torrent_state.filename, ".fastresume")): + self.config["state_location"], + torrent_state.torrent_id, ".fastresume")): fr_first.insert(0, torrent_state) else: fr_first.append(torrent_state) for torrent_state in fr_first: 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": True, - "default_private": torrent_state.private, - "file_priorities": torrent_state.file_priorities - } # We need to resume all non-add_paused torrents after plugin hook if torrent_state.state not in ["Paused", "Queued", "Error"]: resume_torrents.append(torrent_state.torrent_id) self.add( - torrent_state.filename, - options=options, - total_uploaded=torrent_state.total_uploaded, - trackers=torrent_state.trackers, - queue=torrent_state.queue, - state=torrent_state.state, + state=torrent_state, save_state=False) except AttributeError, e: @@ -559,7 +532,6 @@ class TorrentManager(component.Component): for torrent in self.torrents.values(): torrent_state = TorrentState( torrent.torrent_id, - torrent.filename, torrent.get_status(["total_uploaded"])["total_uploaded"], torrent.trackers, torrent.compact, @@ -570,7 +542,6 @@ class TorrentManager(component.Component): torrent.max_upload_speed, torrent.max_download_speed, torrent.prioritize_first_last, - torrent.private, torrent.file_priorities, torrent.get_status(["queue"])["queue"] - 1 # We subtract 1 due to augmentation ) @@ -580,7 +551,7 @@ class TorrentManager(component.Component): try: log.debug("Saving torrent state file.") state_file = open( - os.path.join(self.config["config_location"], "torrents.state"), + os.path.join(self.config["state_location"], "torrents.state"), "wb") cPickle.dump(state, state_file) state_file.close() @@ -640,13 +611,9 @@ class TorrentManager(component.Component): # Get the torrent_id torrent_id = str(alert.handle.info_hash()) # Set the torrent state - log.debug("not_state_paused: %s", self.not_state_paused) - if not torrent_id in self.not_state_paused: - log.debug("Setting state 'Paused'..") - self.torrents[torrent_id].set_state("Paused") - component.get("SignalManager").emit("torrent_paused", torrent_id) - else: - self.not_state_paused.remove(torrent_id) + log.debug("Setting state 'Paused'..") + self.torrents[torrent_id].set_state("Paused") + component.get("SignalManager").emit("torrent_paused", torrent_id) # Write the fastresume file self.torrents[torrent_id].write_fastresume() @@ -731,4 +698,4 @@ class TorrentManager(component.Component): torrent_id = str(alert.handle.info_hash()) self.torrents[torrent_id].set_state("Error") self.torrents[torrent_id].set_status_message(str(alert.msg())) - self.not_state_paused.append(torrent_id) + diff --git a/deluge/core/torrentqueue.py b/deluge/core/torrentqueue.py index bec1815cb..03cfc021a 100644 --- a/deluge/core/torrentqueue.py +++ b/deluge/core/torrentqueue.py @@ -200,7 +200,7 @@ class TorrentQueue(component.Component): try: return self.queue.index(torrent_id) except ValueError: - return None + return -1 def append(self, torrent_id): """Append torrent_id to the bottom of the queue"""