[#1032] Keep track of torrent errors over restarts

* Add error_statusmsg to TorrentState
 * Adds a new set_error_statusmsg() method to force torrent error state.
 * Any torrent in error state will remain in that state on restart with
   additional message in status.
 * Any new libtorrent errors will override manually set ones.
This commit is contained in:
Calum Lind 2014-07-16 13:14:49 +01:00
parent 7393d31208
commit a65603e10c
2 changed files with 38 additions and 7 deletions

View file

@ -216,6 +216,11 @@ class Torrent(object):
self.set_trackers(state.trackers)
self.filename = state.filename
self.is_finished = state.is_finished
last_sess_prepend = "[Error from Previous Session] "
if state.error_statusmsg and not state.error_statusmsg.startswith(last_sess_prepend):
self.error_statusmsg = last_sess_prepend + state.error_statusmsg
else:
self.error_statusmsg = state.error_statusmsg
else:
self.trackers = [tracker for tracker in self.handle.trackers()]
self.is_finished = False
@ -224,6 +229,7 @@ class Torrent(object):
self.filename = self.torrent_id
else:
self.filename = filename
self.error_statusmsg = None
self.statusmsg = "OK"
self.state = None
@ -592,16 +598,23 @@ class Torrent(object):
log.debug("session.is_paused: %s", session_is_paused)
# First we check for an error from libtorrent, and set the state to that if any occurred.
if status.error or self.statusmsg.startswith("Error:"):
if status.error or self.error_statusmsg:
# This is an error'd torrent
self.state = "Error"
if status.error:
self.set_status_message(status.error)
if status.paused:
self.handle.auto_managed(False)
self.set_error_statusmsg(status.error)
self.set_status_message(self.error_statusmsg)
# This will be reverted upon resuming.
self.handle.auto_managed(False)
if not status.paused:
self.handle.pause()
if not status.error:
# As this is not a libtorrent Error we should emit a state changed event
component.get("EventManager").emit(TorrentStateChangedEvent(self.torrent_id, "Error"))
return
else:
self.set_status_message("OK")
self.set_error_statusmsg(None)
if self.moving_storage:
self.state = "Moving"
@ -646,6 +659,19 @@ class Torrent(object):
"""
self.statusmsg = message
def set_error_statusmsg(self, message):
"""Sets the torrent error status message.
Note:
This will force a torrent into an error state. It is used for
setting those errors that are not covered by libtorrent.
Args:
message (str): The error status message.
"""
self.error_statusmsg = message
def get_eta(self):
"""Get the ETA for this torrent.
@ -853,7 +879,9 @@ class Torrent(object):
files = [os.path.join(path, f) for f in files]
return sum(os.stat(f).st_size for f in files if os.path.exists(f))
if self.moving_storage:
if self.state == "Error":
progress = 100.0
elif self.moving_storage:
torrent_status = self.get_status(["files", "total_done"])
torrent_files = [f['path'] for f in torrent_status["files"]]
dest_path_size = get_size(torrent_files, self.moving_storage_dest_path)
@ -1026,6 +1054,7 @@ class Torrent(object):
# Reset the status message just in case of resuming an Error'd torrent
self.set_status_message("OK")
self.set_error_statusmsg(None)
if self.status.is_finished:
# If the torrent has already reached it's 'stop_seed_ratio' then do not do anything

View file

@ -54,6 +54,7 @@ class TorrentState:
queue=None,
auto_managed=True,
is_finished=False,
error_statusmsg=None,
stop_ratio=2.00,
stop_at_ratio=False,
remove_at_ratio=False,
@ -654,7 +655,7 @@ class TorrentManager(component.Component):
# Create the state for each Torrent and append to the list
for torrent in self.torrents.values():
paused = False
if torrent.state == "Paused":
if torrent.state in ["Paused", "Error"]:
paused = True
torrent_state = TorrentState(
@ -674,6 +675,7 @@ class TorrentManager(component.Component):
torrent.get_queue_position(),
torrent.options["auto_managed"],
torrent.is_finished,
torrent.error_statusmsg,
torrent.options["stop_ratio"],
torrent.options["stop_at_ratio"],
torrent.options["remove_at_ratio"],
@ -1043,7 +1045,7 @@ class TorrentManager(component.Component):
return
# Set an Error message and pause the torrent
alert_msg = decode_string(alert.message()).split(':', 1)[1].strip()
torrent.set_status_message("Error: Moving storage failed, %s" % alert_msg)
torrent.set_error_statusmsg("Failed to move storage: %s" % alert_msg)
torrent.moving_storage = False
torrent.pause()
torrent.update_state()