* 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)
This commit is contained in:
@@ -1,3 +1,12 @@
|
||||
2009-05-07 Thomas Vander Stichele <thomas at apestaart dot org>
|
||||
|
||||
* 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 <thomas at apestaart dot org>
|
||||
|
||||
* morituri/common/common.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()
|
||||
|
||||
|
||||
@@ -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<code>.+)\s # function code
|
||||
\[(?P<function>.*)\]\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)
|
||||
|
||||
Reference in New Issue
Block a user