From f769429e1de1744895a1d5b2ee1665bf881dc8d1 Mon Sep 17 00:00:00 2001 From: Andrew Resch Date: Sun, 15 Jun 2008 02:43:06 +0000 Subject: [PATCH] Add move storage on completed download option --- TODO | 5 - deluge/core/core.py | 4 +- deluge/core/torrent.py | 20 +- deluge/core/torrentmanager.py | 24 +- .../ui/gtkui/glade/preferences_dialog.glade | 520 ++++++++++-------- deluge/ui/gtkui/preferences.py | 19 + 6 files changed, 339 insertions(+), 253 deletions(-) diff --git a/TODO b/TODO index f4594252b..c65f792e8 100644 --- a/TODO +++ b/TODO @@ -1,17 +1,12 @@ For 0.6 release: -* Implement open folder -* Add a 'move storage' on completion option * Address issue where torrents will redownload if the storage is moved outside of deluge. -* Implement prioritize first/last pieces * Anonymous stats * Update checking * Translations * Implement add by hash * Implement 'Classic' mode -* Add tabs to view menu * Add progress bars for downloading and importing lists instead of hanging (blocklist) -* Remember view options (show side bar, etc) After 0.6 release: * Figure out easy way for user-made plugins to add i18n support. diff --git a/deluge/core/core.py b/deluge/core/core.py index 480a9a497..c8d8d68fd 100644 --- a/deluge/core/core.py +++ b/deluge/core/core.py @@ -99,7 +99,9 @@ DEFAULT_PREFS = { "share_ratio_limit": 2.00, "seed_time_ratio_limit": 7.00, "seed_time_limit": 180, - "auto_managed": True + "auto_managed": True, + "move_completed": False, + "move_completed_path": os.path.join(deluge.common.get_default_download_dir(), "completed"), } class Core( diff --git a/deluge/core/torrent.py b/deluge/core/torrent.py index defab6c6e..12fc8a556 100644 --- a/deluge/core/torrent.py +++ b/deluge/core/torrent.py @@ -76,7 +76,11 @@ class Torrent: # Set default auto_managed value self.set_auto_managed(options["auto_managed"]) - + + # We need to keep track if the torrent is finished in the state to prevent + # some weird things on state load. + self.is_finished = False + # Load values from state if we have it if state is not None: # This is for saving the total uploaded between sessions @@ -85,6 +89,7 @@ class Torrent: self.set_trackers(state.trackers) # Set the filename self.filename = state.filename + self.is_finished = state.is_finished else: # Tracker list self.trackers = [] @@ -117,7 +122,7 @@ class Torrent: # The tracker status self.tracker_status = "" - + log.debug("Torrent object created.") def set_tracker_status(self, status): @@ -159,14 +164,15 @@ class Torrent: def set_file_priorities(self, file_priorities): log.debug("setting %s's file priorities: %s", self.torrent_id, file_priorities) - if 0 in self.file_priorities: + # XXX: I don't think this is needed anymore since we have torrent_resumed alert + # if 0 in self.file_priorities: # We have previously marked a file 'Do Not Download' # Check to see if we have changed any 0's to >0 and change state accordingly - for index, priority in enumerate(self.file_priorities): - if priority == 0 and file_priorities[index] > 0: + # for index, priority in enumerate(self.file_priorities): + # if priority == 0 and file_priorities[index] > 0: # We have a changed 'Do Not Download' to a download priority - self.set_state("Downloading") - break + # self.is_finished = False + # break self.file_priorities = file_priorities self.handle.prioritize_files(file_priorities) diff --git a/deluge/core/torrentmanager.py b/deluge/core/torrentmanager.py index 1ff77ebec..946c4bc93 100644 --- a/deluge/core/torrentmanager.py +++ b/deluge/core/torrentmanager.py @@ -64,13 +64,15 @@ class TorrentState: prioritize_first_last=None, file_priorities=None, queue=None, - auto_managed=None + auto_managed=None, + is_finished=False ): self.torrent_id = torrent_id self.filename = filename self.total_uploaded = total_uploaded self.trackers = trackers self.queue = queue + self.is_finished = is_finished # Options self.compact = compact @@ -501,7 +503,8 @@ class TorrentManager(component.Component): torrent.prioritize_first_last, torrent.file_priorities, torrent.get_queue_position(), - torrent.auto_managed + torrent.auto_managed, + torrent.is_finished ) state.torrents.append(torrent_state) @@ -578,10 +581,16 @@ class TorrentManager(component.Component): log.debug("on_alert_torrent_finished") # Get the torrent_id torrent_id = str(alert.handle.info_hash()) + torrent = self.torrents[torrent_id] log.debug("%s is finished..", torrent_id) - self.torrents[torrent_id].update_state() - # Write the fastresume file - self.torrents[torrent_id].write_fastresume() + # Move completed download to completed folder if needed + if self.config["move_completed"] and not torrent.is_finished: + if torrent.save_path != self.config["move_completed_path"]: + torrent.move_storage(self.config["move_completed_path"]) + + torrent.is_finished = True + torrent.update_state() + torrent.write_fastresume() def on_alert_torrent_paused(self, alert): log.debug("on_alert_torrent_paused") @@ -669,5 +678,6 @@ class TorrentManager(component.Component): def on_alert_torrent_resumed(self, alert): log.debug("on_alert_torrent_resumed") - torrent_id = str(alert.handle.info_hash()) - self.torrents[torrent_id].update_state() + torrent = self.torrents[str(alert.handle.info_hash())] + torrent.is_finished = torrent.handle.is_seed() + torrent.update_state() diff --git a/deluge/ui/gtkui/glade/preferences_dialog.glade b/deluge/ui/gtkui/glade/preferences_dialog.glade index 7e44820b2..b04d79342 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 @@ -164,50 +164,104 @@ 0 GTK_SHADOW_NONE - + True - 2 - 2 - 12 - + True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 5 + 2 + 2 + 12 - + True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Default download location: + 5 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Default download location: + + + False + False + + + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER + Select A Folder + + + 1 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + 2 + + - - False - False - - - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER - Select A Folder - - - 1 - - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - - - 2 - + + + True + 2 + 2 + 12 + + + True + + + True + True + Move completed to: + 0 + True + + + False + False + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER + Select A Folder + + + 1 + + + + + True + True + + + 2 + + + + + + + 1 + + @@ -463,7 +517,7 @@ True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK Prioritize first and last pieces of files in torrent - Prioritize first and last pieces of files in torrent + Prioritize first and last pieces of torrent 0 True @@ -1104,40 +1158,71 @@ Disabled 2 15 - + True - True - The maximum upload slots for all torrents. Set -1 for unlimited. - 1 - -1 -1 9000 1 10 10 - 1 - True - True + The maximum upload speed for all torrents. Set -1 for unlimited. + 0 + Maximum Upload Speed (KiB/s): + + + 3 + 4 + GTK_FILL + + + + + True + The maximum number of connections allowed. Set -1 for unlimited. + 0 + Maximum Connections: + + + GTK_FILL + + + + + True + The maximum upload speed for all torrents. Set -1 for unlimited. + 0 + Maximum Upload Slots: - 1 - 2 1 2 GTK_FILL - + True True - The maximum upload speed for all torrents. Set -1 for unlimited. + The maximum number of connections allowed. Set -1 for unlimited. + 4 1 -1 -1 9000 1 10 10 1 - 1 + True True + GTK_UPDATE_IF_VALID 1 2 - 3 - 4 + GTK_FILL + + + + + True + The maximum download speed for all torrents. Set -1 for unlimited. + 0 + Maximum Download Speed (KiB/s): + + + 2 + 3 GTK_FILL @@ -1162,74 +1247,43 @@ Disabled - + True - The maximum download speed for all torrents. Set -1 for unlimited. - 0 - Maximum Download Speed (KiB/s): + True + The maximum upload speed for all torrents. Set -1 for unlimited. + 1 + -1 -1 9000 1 10 10 + 1 + 1 + True - 2 - 3 + 1 + 2 + 3 + 4 GTK_FILL - + True True - The maximum number of connections allowed. Set -1 for unlimited. - 4 + The maximum upload slots for all torrents. Set -1 for unlimited. 1 -1 -1 9000 1 10 10 1 True True - GTK_UPDATE_IF_VALID 1 2 - GTK_FILL - - - - - True - The maximum upload speed for all torrents. Set -1 for unlimited. - 0 - Maximum Upload Slots: - - 1 2 GTK_FILL - - - True - The maximum number of connections allowed. Set -1 for unlimited. - 0 - Maximum Connections: - - - GTK_FILL - - - - - True - The maximum upload speed for all torrents. Set -1 for unlimited. - 0 - Maximum Upload Speed (KiB/s): - - - 3 - 4 - GTK_FILL - - @@ -1273,85 +1327,18 @@ Disabled 2 15 - - True - True - The maximum upload slots per torrent. Set -1 for unlimited. - 1 - -1 -1 9000 1 10 10 - 1 - True - True - - - 1 - 2 - 1 - 2 - GTK_FILL - - - - + True True The maximum number of connections per torrent. Set -1 for unlimited. 1 -1 -1 9000 1 10 10 - True + 1 True 1 2 - GTK_FILL - - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 0 - Maximum Connections: - - - GTK_FILL - - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 0 - Maximum Upload Slots: - - - 1 - 2 - GTK_FILL - - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 0 - Maximum Download Speed (KiB/s): - - - 2 - 3 - GTK_FILL - - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 0 - Maximum Upload Speed (KiB/s): - - 3 4 GTK_FILL @@ -1376,20 +1363,87 @@ Disabled - + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + Maximum Upload Speed (KiB/s): + + + 3 + 4 + GTK_FILL + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + Maximum Download Speed (KiB/s): + + + 2 + 3 + GTK_FILL + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + Maximum Upload Slots: + + + 1 + 2 + GTK_FILL + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + Maximum Connections: + + + GTK_FILL + + + + True True The maximum number of connections per torrent. Set -1 for unlimited. 1 -1 -1 9000 1 10 10 - 1 + True True 1 2 - 3 - 4 + GTK_FILL + + + + + True + True + The maximum upload slots per torrent. Set -1 for unlimited. + 1 + -1 -1 9000 1 10 10 + 1 + True + True + + + 1 + 2 + 1 + 2 GTK_FILL @@ -2156,13 +2210,33 @@ Disabled 2 10 - + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 1 + 0 -1 9999 1 10 10 + True + True + + + 1 + 2 + 1 + 2 + + + + + True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 0 - Total active downloading: + Total active seeding: + 1 + 2 GTK_FILL @@ -2183,36 +2257,16 @@ Disabled - + True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 0 - Total active seeding: + Total active downloading: - 1 - 2 GTK_FILL - - - True - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 1 - 0 -1 9999 1 10 10 - True - True - - - 1 - 2 - 1 - 2 - - - @@ -2259,51 +2313,18 @@ Disabled 2 10 - - True - 0 - Share Ratio Limit: - - - GTK_FILL - - - - - True - 0 - Seed Time Ratio: - - - 1 - 2 - GTK_FILL - - - - - True - 0 - Seed Time (m): - - - 2 - 3 - GTK_FILL - - - - + True True 6 1 - 1.5 -1 100 0.10000000000000001 10 10 - 2 + 6 -1 100 1 10 10 1 2 + 2 + 3 @@ -2325,19 +2346,52 @@ Disabled - + True True 6 1 - 6 -1 100 1 10 10 + 1.5 -1 100 0.10000000000000001 10 10 + 2 1 2 + + + + + + True + 0 + Seed Time (m): + + 2 3 - + GTK_FILL + + + + + True + 0 + Seed Time Ratio: + + + 1 + 2 + GTK_FILL + + + + + True + 0 + Share Ratio Limit: + + + GTK_FILL diff --git a/deluge/ui/gtkui/preferences.py b/deluge/ui/gtkui/preferences.py index 39d04c8d6..f92e1d985 100644 --- a/deluge/ui/gtkui/preferences.py +++ b/deluge/ui/gtkui/preferences.py @@ -189,6 +189,10 @@ class Preferences(component.Component): core_widgets = { "download_path_button": \ ("filename", self.core_config["download_location"]), + "chk_move_completed": \ + ("active", self.core_config["move_completed"]), + "move_completed_path_button": \ + ("filename", self.core_config["move_completed_path"]), "chk_copy_torrent_file": \ ("active", self.core_config["copy_torrent_file"]), "torrent_files_button": \ @@ -256,6 +260,11 @@ class Preferences(component.Component): core_widgets.pop("download_path_button") core_widgets["entry_download_path"] = ("text", self.core_config["download_location"]) + self.glade.get_widget("entry_move_completed_path").show() + self.glade.get_widget("move_completed_path_button").hide() + core_widgets.pop("move_completed_path_button") + core_widgets["entry_move_completed_path"] = ("text", self.core_config["move_completed_path"]) + self.glade.get_widget("entry_torrents_path").show() self.glade.get_widget("torrent_files_button").hide() core_widgets.pop("torrent_files_button") @@ -268,6 +277,8 @@ class Preferences(component.Component): else: self.glade.get_widget("entry_download_path").hide() self.glade.get_widget("download_path_button").show() + self.glade.get_widget("entry_move_completed_path").hide() + self.glade.get_widget("move_completed_path_button").show() self.glade.get_widget("entry_torrents_path").hide() self.glade.get_widget("torrent_files_button").show() self.glade.get_widget("entry_autoadd").hide() @@ -300,6 +311,8 @@ class Preferences(component.Component): else: core_widget_list = [ "download_path_button", + "chk_move_completed", + "move_completed_path_button", "chk_copy_torrent_file", "torrent_files_button", "chk_autoadd", @@ -403,14 +416,20 @@ class Preferences(component.Component): 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() + new_core_config["move_completed"] = \ + self.glade.get_widget("chk_move_completed").get_active() if client.is_localhost(): new_core_config["download_location"] = \ self.glade.get_widget("download_path_button").get_filename() + new_core_config["move_completed_path"] = \ + self.glade.get_widget("move_completed_path_button").get_filename() new_core_config["torrentfiles_location"] = \ self.glade.get_widget("torrent_files_button").get_filename() else: new_core_config["download_location"] = \ self.glade.get_widget("entry_download_path").get_text() + new_core_config["move_completed_path"] = \ + self.glade.get_widget("entry_move_completed_path").get_text() new_core_config["torrentfiles_location"] = \ self.glade.get_widget("entry_torrents_path").get_text()