From c06814e1397c1415547a9d4e8316e119ceb8e482 Mon Sep 17 00:00:00 2001 From: Thomas Vander Stichele Date: Thu, 7 May 2009 09:19:41 +0000 Subject: [PATCH] * morituri/common/task.py: Add an exception ivar for tasks to set an exception on while running. Make SyncRunner raise it during done() * morituri/program/cdparanoia.py: Set an exception if the ripped file doesn't match the expected size (for example when disc is full) --- ChangeLog | 9 +++++++ morituri/common/task.py | 17 +++++++++--- morituri/program/cdparanoia.py | 47 +++++++++++++++++++++++++--------- 3 files changed, 58 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index 81ebce5..3fd9804 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2009-05-07 Thomas Vander Stichele + + * morituri/common/task.py: + Add an exception ivar for tasks to set an exception on while + running. Make SyncRunner raise it during done() + * morituri/program/cdparanoia.py: + Set an exception if the ripped file doesn't match the expected size + (for example when disc is full) + 2009-05-07 Thomas Vander Stichele * morituri/common/common.py: diff --git a/morituri/common/task.py b/morituri/common/task.py index 87e8332..385eac5 100644 --- a/morituri/common/task.py +++ b/morituri/common/task.py @@ -32,6 +32,8 @@ class Task(object, log.Loggable): I can be listened to for starting, stopping, and progress updates. @ivar description: what am I doing + @ivar exception: set if an exception happened during the task + execution. """ description = 'I am doing something.' @@ -39,6 +41,7 @@ class Task(object, log.Loggable): increment = 0.01 running = False runner = None + exception = None _listeners = None @@ -93,9 +96,9 @@ class Task(object, log.Loggable): self._listeners.append(listener) def _notifyListeners(self, methodName, *args, **kwargs): - if self._listeners: - for l in self._listeners: - getattr(l, methodName)(self, *args, **kwargs) + if self._listeners: + for l in self._listeners: + getattr(l, methodName)(self, *args, **kwargs) # this is a Dummy task that can be used if this works at all class DummyTask(Task): @@ -157,6 +160,11 @@ class BaseMultiTask(Task): pass def stopped(self, task): + if task.exception: + self.exception = task.exception + self.stop() + return + if not self.__tasks: self.stop() return @@ -282,6 +290,8 @@ class SyncRunner(TaskRunner): # otherwise the task might complete before we are in it gobject.timeout_add(0L, self._task.start, self) self._loop.run() + if self._task.exception: + raise self._task.exception def schedule(self, delta, callable, *args, **kwargs): def c(): @@ -320,6 +330,7 @@ class SyncRunner(TaskRunner): self._report() def stopped(self, task): + print 'stopped' self.progressed(task, 1.0) self._loop.quit() diff --git a/morituri/program/cdparanoia.py b/morituri/program/cdparanoia.py index c4f3a8f..a8541ed 100644 --- a/morituri/program/cdparanoia.py +++ b/morituri/program/cdparanoia.py @@ -30,6 +30,22 @@ import tempfile from morituri.common import task, log, common, checksum from morituri.extern import asyncsub +class FileSizeError(Exception): + """ + The given path does not have the expected size. + """ + def __init__(self, path): + self.args = (path, ) + self.path = path + +class ReturnCodeError(Exception): + """ + The program had a non-zero return code. + """ + def __init__(self, returncode): + self.args = (returncode, ) + self.returncode = returncode + _PROGRESS_RE = re.compile(r""" ^\#\#: (?P.+)\s # function code \[(?P.*)\]\s@\s # function name @@ -181,17 +197,20 @@ class ReadTrackTask(task.Task): expected = offsetLength * checksum.BYTES_PER_FRAME + 44 if size != expected: # FIXME: handle errors better - print 'ERROR: file size %d did not match expected size %d' % ( + self.warning('file size %d did not match expected size %d', size, expected) if (size - expected) % checksum.BYTES_PER_FRAME == 0: print 'ERROR: %d frames difference' % ( (size - expected) / checksum.BYTES_PER_FRAME) - if self._popen.returncode != 0: + self.exception = FileSizeError(self.path) + + if not self.exception and self._popen.returncode != 0: if self._errors: print "\n".join(self._errors) else: - print 'ERROR: exit code %r' % self._popen.returncode + self.warning('exit code %r', self._popen.returncode) + self.exception = ReturnCodeError(self._popen.returncode) self.stop() return @@ -240,14 +259,18 @@ class ReadVerifyTrackTask(task.MultiSeparateTask): self.checksum = None def stop(self): - c1 = self.tasks[1].checksum - c2 = self.tasks[3].checksum - if c1 == c2: - self.info('Checksums match, %08x' % c1) - self.checksum = checksum - shutil.move(self._tmppath, self.path) - else: - print 'ERROR: read and verify failed' - self.checksum = None + if not self.exception: + c1 = self.tasks[1].checksum + c2 = self.tasks[3].checksum + if c1 == c2: + self.info('Checksums match, %08x' % c1) + try: + shutil.move(self._tmppath, self.path) + self.checksum = checksum + except Exception, e: + self._exception = e + else: + print 'ERROR: read and verify failed' + self.checksum = None task.MultiSeparateTask.stop(self)