From 9d40380f71e4606e333af0d67497312540a0a02b Mon Sep 17 00:00:00 2001 From: Andrew Resch Date: Sat, 14 Jun 2008 02:10:23 +0000 Subject: [PATCH] New option to make a copy of torrent file added to session. Have torrentmanager handle old state files better by filling in the missing fields with defaults. --- deluge/core/autoadd.py | 2 +- deluge/core/core.py | 26 ++------ deluge/core/torrent.py | 8 ++- deluge/core/torrentmanager.py | 64 +++++++++++++------ .../ui/gtkui/glade/preferences_dialog.glade | 12 ++-- deluge/ui/gtkui/preferences.py | 12 +++- 6 files changed, 72 insertions(+), 52 deletions(-) diff --git a/deluge/core/autoadd.py b/deluge/core/autoadd.py index 78d6d1575..213539203 100644 --- a/deluge/core/autoadd.py +++ b/deluge/core/autoadd.py @@ -91,7 +91,7 @@ class AutoAdd(component.Component): continue # The torrent looks good, so lets add it to the session - component.get("TorrentManager").add(filedump=filedump) + component.get("TorrentManager").add(filedump=filedump, filename=filename) os.remove(filepath) diff --git a/deluge/core/core.py b/deluge/core/core.py index 1feb8838c..104f9a9da 100644 --- a/deluge/core/core.py +++ b/deluge/core/core.py @@ -63,7 +63,8 @@ DEFAULT_PREFS = { "compact_allocation": False, "download_location": deluge.common.get_default_download_dir(), "listen_ports": [6881, 6891], - "torrentfiles_location": os.path.join(deluge.configmanager.get_config_dir(), "torrentfiles"), + "copy_torrent_file": False, + "torrentfiles_location": os.path.join(deluge.common.get_default_download_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, @@ -86,7 +87,7 @@ DEFAULT_PREFS = { "max_upload_speed_per_torrent": -1, "max_download_speed_per_torrent": -1, "enabled_plugins": [], - "autoadd_location": "", + "autoadd_location": deluge.common.get_default_download_dir(), "autoadd_enable": False, "add_paused": False, "max_active_seeding": 5, @@ -318,14 +319,13 @@ class Core( # 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(filedump=filedump, options=options) + 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) @@ -630,29 +630,11 @@ class Core( self.config_value_changed(key, value) def _on_set_torrentfiles_location(self, key, value): - try: - old = self.config.get_previous_config()["torrentfiles_location"] - except Exception, e: - # This probably means it's not a real change but we're just loading - # the config. - log.debug("Unable to get previous torrentfiles_location: %s", e) - return - # First try to create the new directory try: os.makedirs(value) except Exception, e: log.debug("Unable to make directory: %s", e) - - # Now copy all files in the old directory to the new one - for root, dirs, files in os.walk(old): - for dir in dirs: - os.makedirs(dir) - for file in files: - try: - 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): diff --git a/deluge/core/torrent.py b/deluge/core/torrent.py index f579d1ce7..594f4a50d 100644 --- a/deluge/core/torrent.py +++ b/deluge/core/torrent.py @@ -47,7 +47,7 @@ TORRENT_STATE = deluge.common.TORRENT_STATE class Torrent: """Torrent holds information about torrents added to the libtorrent session. """ - def __init__(self, handle, options, state=None): + def __init__(self, handle, options, state=None, filename=None): log.debug("Creating torrent object %s", str(handle.info_hash())) # Get the core config self.config = ConfigManager("core.conf") @@ -59,6 +59,9 @@ class Torrent: # Set the torrent_id for this torrent self.torrent_id = str(handle.info_hash()) + # We store the filename just in case we need to make a copy of the torrentfile + self.filename = filename + # 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() @@ -80,6 +83,8 @@ class Torrent: self.total_uploaded = state.total_uploaded # Set the trackers self.set_trackers(state.trackers) + # Set the filename + self.filename = state.filename else: # Tracker list self.trackers = [] @@ -108,7 +113,6 @@ class Torrent: self.statusmsg = "OK" # The torrents state - #self.state = "" self.update_state() # The tracker status diff --git a/deluge/core/torrentmanager.py b/deluge/core/torrentmanager.py index d135c0324..ce0bc3105 100644 --- a/deluge/core/torrentmanager.py +++ b/deluge/core/torrentmanager.py @@ -50,22 +50,24 @@ from deluge.log import LOG as log class TorrentState: def __init__(self, - torrent_id, - total_uploaded, - trackers, - compact, - paused, - save_path, - max_connections, - max_upload_slots, - max_upload_speed, - max_download_speed, - prioritize_first_last, - file_priorities, - queue, - auto_managed + torrent_id=None, + filename=None, + total_uploaded=None, + trackers=None, + compact=None, + paused=None, + save_path=None, + max_connections=None, + max_upload_slots=None, + max_upload_speed=None, + max_download_speed=None, + prioritize_first_last=None, + file_priorities=None, + queue=None, + auto_managed=None ): self.torrent_id = torrent_id + self.filename = filename self.total_uploaded = total_uploaded self.trackers = trackers self.queue = queue @@ -204,7 +206,7 @@ class TorrentManager(component.Component): return fastresume def add(self, torrent_info=None, state=None, options=None, save_state=True, - filedump=None): + filedump=None, filename=None): """Add a torrent to the manager and returns it's torrent_id""" if torrent_info is None and state is None and filedump is None: @@ -307,7 +309,7 @@ class TorrentManager(component.Component): log.debug("handle id: %s", str(handle.info_hash())) # Create a Torrent object - torrent = Torrent(handle, options, state) + torrent = Torrent(handle, options, state, filename=filename) # Add the torrent object to the dictionary self.torrents[torrent.torrent_id] = torrent if self.config["queue_new_to_top"]: @@ -331,6 +333,18 @@ class TorrentManager(component.Component): except IOError, e: log.warning("Unable to save torrent file: %s", e) + # If the user has requested a copy of the torrent be saved elsewhere + # we need to do that. + if self.config["copy_torrent_file"] and filename is not None: + try: + save_file = open( + os.path.join(self.config["torrentfiles_location"], filename), + "wb") + save_file.write(filedump) + save_file.close() + except IOError, e: + log.warning("Unable to save torrent file: %s", e) + if save_state: # Save the session state self.save_state() @@ -424,16 +438,25 @@ class TorrentManager(component.Component): def load_state(self): """Load the state of the TorrentManager from the torrents.state file""" state = TorrentManagerState() - + try: log.debug("Opening torrent state file for load.") state_file = open( os.path.join(self.config["state_location"], "torrents.state"), "rb") state = cPickle.load(state_file) state_file.close() - except (EOFError, IOError): - log.warning("Unable to load state file.") - + except (EOFError, IOError, Exception), e: + log.warning("Unable to load state file: %s", e) + + # Try to use an old state + try: + if dir(state.torrents[0]) != dir(TorrentState()): + for attr in (set(dir(TorrentState())) - set(dir(state.torrents[0]))): + for s in state.torrents: + setattr(s, attr, getattr(TorrentState(), attr, None)) + except Exception, e: + log.warning("Unable to update state file to a compatible version: %s", e) + # Reorder the state.torrents list to add torrents in the correct queue # order. ordered_state = [] @@ -465,6 +488,7 @@ class TorrentManager(component.Component): torrent_state = TorrentState( torrent.torrent_id, + torrent.filename, torrent.get_status(["total_uploaded"])["total_uploaded"], torrent.trackers, torrent.compact, diff --git a/deluge/ui/gtkui/glade/preferences_dialog.glade b/deluge/ui/gtkui/glade/preferences_dialog.glade index 9c1b98b3e..7e44820b2 100644 --- a/deluge/ui/gtkui/glade/preferences_dialog.glade +++ b/deluge/ui/gtkui/glade/preferences_dialog.glade @@ -1,6 +1,6 @@ - + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK @@ -245,10 +245,12 @@ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 5 - + True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Save .torrent files to: + True + Save copy of .torrent file: + 0 + True False @@ -283,7 +285,7 @@ True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - <b>Torrent Files Location</b> + <b>Torrent File Copy</b> True diff --git a/deluge/ui/gtkui/preferences.py b/deluge/ui/gtkui/preferences.py index 2196ebb82..39d04c8d6 100644 --- a/deluge/ui/gtkui/preferences.py +++ b/deluge/ui/gtkui/preferences.py @@ -189,6 +189,8 @@ class Preferences(component.Component): core_widgets = { "download_path_button": \ ("filename", self.core_config["download_location"]), + "chk_copy_torrent_file": \ + ("active", self.core_config["copy_torrent_file"]), "torrent_files_button": \ ("filename", self.core_config["torrentfiles_location"]), "chk_autoadd": \ @@ -283,7 +285,10 @@ class Preferences(component.Component): if modifier == "filename": if value: - widget.set_current_folder(value) + try: + widget.set_current_folder(value) + except Exception, e: + log.debug("Unable to set_current_folder: %s", e) elif modifier == "active": widget.set_active(value) elif modifier == "not_active": @@ -295,6 +300,7 @@ class Preferences(component.Component): else: core_widget_list = [ "download_path_button", + "chk_copy_torrent_file", "torrent_files_button", "chk_autoadd", "folder_autoadd", @@ -395,6 +401,8 @@ class Preferences(component.Component): self.glade.get_widget("chk_show_dialog").get_active() new_gtkui_config["focus_add_dialog"] = \ self.glade.get_widget("chk_focus_dialog").get_active() + new_core_config["copy_torrent_file"] = \ + self.glade.get_widget("chk_copy_torrent_file").get_active() if client.is_localhost(): new_core_config["download_location"] = \ self.glade.get_widget("download_path_button").get_filename() @@ -585,7 +593,7 @@ class Preferences(component.Component): self.glade.get_widget("combo_file_manager").set_sensitive(not value) self.glade.get_widget("txt_open_folder_location").set_sensitive( value) - + def on_button_ok_clicked(self, data): log.debug("on_button_ok_clicked") self.set_config()