diff --git a/TODO b/TODO index e500c1687..b051d6fd0 100644 --- a/TODO +++ b/TODO @@ -5,8 +5,6 @@ For 0.6 release: * Add a 'move storage' on completion option * Address issue where torrents will redownload if the storage is moved outside of deluge. -* Use the alert icon for file alerts from libtorrent -* Add a torrent status message to the details tab to indicate errors (with alert icon) * Implement prioritize first/last pieces * Anonymous stats * Update checking diff --git a/deluge/core/torrent.py b/deluge/core/torrent.py index 51219fa3f..a3e9484c4 100644 --- a/deluge/core/torrent.py +++ b/deluge/core/torrent.py @@ -69,6 +69,8 @@ class Torrent: 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" # Holds status info so that we don't need to keep getting it from lt self.status = self.handle.status() @@ -161,7 +163,10 @@ class Torrent: # Update the torrentqueue on any state changes self.torrentqueue.update_queue() - + + def set_status_message(self, message): + self.statusmsg = message + def get_eta(self): """Returns the ETA in seconds for this torrent""" if self.status == None: @@ -291,7 +296,8 @@ 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 + "private": self.private, + "message": self.statusmsg } fns = { @@ -343,8 +349,10 @@ class Torrent: def resume(self): """Resumes this torrent""" - if self.state == "Paused": - + if self.state == "Paused" or self.state == "Error": + # Reset the status message just in case of resuming an Error'd torrent + self.set_status_message("OK") + if self.handle.is_seed(): # If the torrent has already reached it's 'stop_seed_ratio' then do not do anything if self.config["stop_seed_at_ratio"]: diff --git a/deluge/core/torrentmanager.py b/deluge/core/torrentmanager.py index d8eb4cbd0..6c4cd4bac 100644 --- a/deluge/core/torrentmanager.py +++ b/deluge/core/torrentmanager.py @@ -138,6 +138,7 @@ class TorrentManager(component.Component): self.on_alert_tracker_warning) self.alerts.register_handler("storage_moved_alert", self.on_alert_storage_moved) + self.alerts.register_handler("file_error_alert", self.on_alert_file_error) # Create the AutoAdd component self.autoadd = AutoAdd() @@ -302,7 +303,7 @@ class TorrentManager(component.Component): # Resume the torrent if needed if state == "Queued": torrent.state = "Queued" - elif state == "Paused": + elif state == "Paused" or state == "Error": torrent.state = "Paused" if state == None and not options["add_paused"]: torrent.handle.resume() @@ -498,7 +499,7 @@ class TorrentManager(component.Component): "file_priorities": torrent_state.file_priorities } # We need to resume all non-add_paused torrents after plugin hook - if torrent_state.state == "Paused" or torrent_state.state == "Queued": + if torrent_state.state == "Paused" or torrent_state.state == "Queued" or torrent_state.state == "Error": log.debug("torrent state: %s", torrent_state.state) add_paused[torrent_state.torrent_id] = True else: @@ -697,4 +698,10 @@ class TorrentManager(component.Component): self.torrents[torrent_id].set_save_path(alert.handle.save_path()) except KeyError: log.debug("torrent_id doesn't exist.") - + + def on_alert_file_error(self, alert): + log.debug("on_alert_file_error") + 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/ui/gtkui/details_tab.py b/deluge/ui/gtkui/details_tab.py index 2c188191e..e50344325 100644 --- a/deluge/ui/gtkui/details_tab.py +++ b/deluge/ui/gtkui/details_tab.py @@ -49,7 +49,8 @@ class DetailsTab: (glade.get_widget("summary_num_files"), str, ("num_files",)), (glade.get_widget("summary_tracker"), None, ("tracker",)), (glade.get_widget("summary_torrent_path"), None, ("save_path",)), - (glade.get_widget("summary_private"), str, ("private",)) + (glade.get_widget("summary_private"), str, ("private",)), + (glade.get_widget("summary_message"), str, ("message",)) ] def update(self): @@ -65,7 +66,7 @@ class DetailsTab: # Get the torrent status status_keys = ["name", "total_size", "num_files", - "tracker", "save_path", "private"] + "tracker", "save_path", "private", "message"] client.get_torrent_status( self._on_get_torrent_status, selected, status_keys) diff --git a/deluge/ui/gtkui/glade/main_window.glade b/deluge/ui/gtkui/glade/main_window.glade index db89fa378..842761d9e 100644 --- a/deluge/ui/gtkui/glade/main_window.glade +++ b/deluge/ui/gtkui/glade/main_window.glade @@ -533,183 +533,137 @@ - + True 0 - True - True 1 2 - 3 - 4 GTK_FILL - + True 0 3 4 - 3 - 4 GTK_FILL - + True 0 - True - PANGO_WRAP_CHAR - True 1 2 - 4 - 5 + 1 + 2 GTK_FILL - - True - 0 - <b>Tracker Status:</b> - True - - - 4 - 5 - GTK_FILL - - - - - - True - 0 - True - PANGO_WRAP_WORD_CHAR - - - 5 - 6 - 2 - 3 - GTK_FILL - - - - - - True - 0 - 1 - <b>Availability:</b> - True - - - 4 - 5 - 2 - 3 - GTK_FILL - - - - + True 0 3 4 - 2 - 3 - GTK_FILL - - - - - True - 0 - - - 1 - 2 - 2 - 3 - GTK_FILL - - - - - True - 0 - - - 5 - 6 1 2 GTK_FILL - + True - 0 - <b>Peers:</b> - True + 5 + + + True + 0 + <b>Downloaded:</b> + True + + + + + GTK_FILL + + + + + True + 5 + + + True + 0 + <b>Uploaded:</b> + True + + - 4 - 5 1 2 GTK_FILL - + True - 0 + 5 + + + True + 0 + <b>Share Ratio:</b> + True + + - 5 - 6 + 2 + 3 GTK_FILL - + True - 0 - <b>Seeders:</b> - True + 5 + + + True + 0 + <b>Next Announce:</b> + True + + - 4 - 5 + 3 + 4 GTK_FILL - + True 15 5 - + True 0 - <b>Pieces:</b> + <b>Speed:</b> True @@ -717,30 +671,6 @@ 2 3 - 3 - 4 - GTK_FILL - - - - - True - 15 - 5 - - - True - 0 - <b>ETA:</b> - True - - - - - 2 - 3 - 2 - 3 GTK_FILL @@ -767,15 +697,15 @@ - + True 15 5 - + True 0 - <b>Speed:</b> + <b>ETA:</b> True @@ -783,128 +713,198 @@ 2 3 - GTK_FILL - - - - - True - 5 - - - True - 0 - <b>Next Announce:</b> - True - - - - - 3 - 4 - GTK_FILL - - - - - True - 5 - - - True - 0 - <b>Share Ratio:</b> - True - - - - 2 3 GTK_FILL - + True + 15 5 - + True 0 - <b>Uploaded:</b> + <b>Pieces:</b> True - 1 - 2 + 2 + 3 + 3 + 4 GTK_FILL - + True - 5 - - - True - 0 - <b>Downloaded:</b> - True - - + 0 + <b>Seeders:</b> + True + 4 + 5 GTK_FILL - + True 0 - 3 - 4 + 5 + 6 + GTK_FILL + + + + + True + 0 + <b>Peers:</b> + True + + + 4 + 5 1 2 GTK_FILL - + + True + 0 + + + 5 + 6 + 1 + 2 + GTK_FILL + + + + True 0 1 2 - 1 - 2 + 2 + 3 GTK_FILL - + True 0 3 4 + 2 + 3 GTK_FILL - + True 0 + 1 + <b>Availability:</b> + True + + + 4 + 5 + 2 + 3 + GTK_FILL + + + + + True + 0 + True + PANGO_WRAP_WORD_CHAR + + + 5 + 6 + 2 + 3 + GTK_FILL + + + + + + True + 0 + <b>Tracker Status:</b> + True + + + 4 + 5 + GTK_FILL + + + + + + True + 0 + True + PANGO_WRAP_CHAR + True 1 2 + 4 + 5 + GTK_FILL + + + + + True + 0 + + + 3 + 4 + 3 + 4 + GTK_FILL + + + + + True + 0 + True + True + + + 1 + 2 + 3 + 4 GTK_FILL @@ -975,93 +975,41 @@ True - 6 + 7 2 2 - + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 0 - True - PANGO_WRAP_CHAR - True 1 2 - 4 - 5 + 6 + 7 GTK_FILL - + True 0 1 - <b>Tracker:</b> + <b>Status:</b> True - 4 - 5 + 6 + 7 GTK_FILL - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 5 - - - True - 0 - 1 - <b># of files:</b> - True - - - - - 3 - 4 - GTK_FILL - - - - - - True - 0 - True - - - 1 - 2 - 3 - 4 - - - - - - True - 0 - True - - - 1 - 2 - 2 - 3 - - - - - + True 0 True @@ -1071,52 +1019,44 @@ 1 2 - - - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 5 - - - True - 0 - 1 - <b>Total Size:</b> - True - - - - - 2 - 3 + 5 + 6 GTK_FILL - + True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 5 - - - True - 0 - 0 - 1 - <b>Name:</b> - True - - + 0 + 1 + <b>Private:</b> + True + 5 + 6 GTK_FILL + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + True + PANGO_WRAP_CHAR + True + + + 1 + 2 + 1 + 2 + + + True @@ -1140,39 +1080,50 @@ - + True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 0 - True - PANGO_WRAP_CHAR - True + 5 + + + True + 0 + 0 + 1 + <b>Name:</b> + True + + - 1 - 2 - 1 - 2 - - - - - - True - 0 - 1 - <b>Private:</b> - True - - - 5 - 6 GTK_FILL - + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 5 + + + True + 0 + 1 + <b>Total Size:</b> + True + + + + + 2 + 3 + GTK_FILL + + + + + True 0 True @@ -1182,8 +1133,87 @@ 1 2 - 5 - 6 + + + + + + True + 0 + True + + + 1 + 2 + 2 + 3 + + + + + + True + 0 + True + + + 1 + 2 + 3 + 4 + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 5 + + + True + 0 + 1 + <b># of files:</b> + True + + + + + 3 + 4 + GTK_FILL + + + + + + True + 0 + 1 + <b>Tracker:</b> + True + + + 4 + 5 + GTK_FILL + + + + + + True + 0 + True + PANGO_WRAP_CHAR + True + + + 1 + 2 + 4 + 5 GTK_FILL diff --git a/deluge/ui/gtkui/sidebar.py b/deluge/ui/gtkui/sidebar.py index a48dc2f22..05f2e8006 100644 --- a/deluge/ui/gtkui/sidebar.py +++ b/deluge/ui/gtkui/sidebar.py @@ -63,6 +63,9 @@ class SideBar(component.Component): self.liststore.append([_("Paused"), gtk.gdk.pixbuf_new_from_file( deluge.common.get_pixmap("inactive16.png"))]) + self.liststore.append([_("Error"), + gtk.gdk.pixbuf_new_from_file( + deluge.common.get_pixmap("alert16.png"))]) # Create the column column = gtk.TreeViewColumn(_("Labels")) column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) @@ -112,4 +115,6 @@ class SideBar(component.Component): component.get("TorrentView").set_filter("state", "Queued") if value == "Paused": component.get("TorrentView").set_filter("state", "Paused") + if value == "Error": + component.get("TorrentView").set_filter("state", "Error") diff --git a/deluge/ui/gtkui/toolbar.py b/deluge/ui/gtkui/toolbar.py index 4681f381c..df8974e16 100644 --- a/deluge/ui/gtkui/toolbar.py +++ b/deluge/ui/gtkui/toolbar.py @@ -191,7 +191,7 @@ class ToolBar(component.Component): except KeyError, e: log.debug("Error getting torrent state: %s", e) continue - if status == "Paused": + if status == "Paused" or status == "Error": resume = True else: pause = True