* morituri/common/task.py:
Log on runners too. * morituri/program/cdrdao.py: Abort if output has ERROR by killing and setting an exception.
This commit is contained in:
@@ -1,3 +1,10 @@
|
||||
2009-05-07 Thomas Vander Stichele <thomas at apestaart dot org>
|
||||
|
||||
* morituri/common/task.py:
|
||||
Log on runners too.
|
||||
* morituri/program/cdrdao.py:
|
||||
Abort if output has ERROR by killing and setting an exception.
|
||||
|
||||
2009-05-07 Thomas Vander Stichele <thomas at apestaart dot org>
|
||||
|
||||
* examples/readdisc.py:
|
||||
|
||||
@@ -216,11 +216,12 @@ class MultiCombinedTask(BaseMultiTask):
|
||||
self.setProgress(float(self._stopped) / len(self.tasks))
|
||||
BaseMultiTask.stopped(self, task)
|
||||
|
||||
class TaskRunner(object):
|
||||
class TaskRunner(object, log.Loggable):
|
||||
"""
|
||||
I am a base class for task runners.
|
||||
Task runners should be reusable.
|
||||
"""
|
||||
logCategory = 'TaskRunner'
|
||||
|
||||
def run(self, task):
|
||||
"""
|
||||
@@ -279,6 +280,7 @@ class SyncRunner(TaskRunner):
|
||||
self._longest = 0 # longest string shown; for clearing
|
||||
|
||||
def run(self, task, verbose=None, skip=False):
|
||||
self.debug('run task %r', task)
|
||||
self._task = task
|
||||
self._verboseRun = self._verbose
|
||||
if verbose is not None:
|
||||
@@ -291,7 +293,9 @@ class SyncRunner(TaskRunner):
|
||||
# otherwise the task might complete before we are in it
|
||||
gobject.timeout_add(0L, self._task.start, self)
|
||||
self._loop.run()
|
||||
self.debug('done running task %r', task)
|
||||
if self._task.exception:
|
||||
self.debug('raising exception')
|
||||
raise self._task.exception
|
||||
|
||||
def schedule(self, delta, callable, *args, **kwargs):
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
import re
|
||||
import os
|
||||
import signal
|
||||
import subprocess
|
||||
import tempfile
|
||||
|
||||
@@ -30,6 +31,14 @@ from morituri.common import task, log
|
||||
from morituri.image import toc, table
|
||||
from morituri.extern import asyncsub
|
||||
|
||||
class ProgramError(Exception):
|
||||
"""
|
||||
The program had a fatal error.
|
||||
"""
|
||||
def __init__(self, message):
|
||||
self.args = (message, )
|
||||
self.message = message
|
||||
|
||||
states = ['START', 'TRACK', 'LEADOUT', 'DONE']
|
||||
|
||||
_ANALYZING_RE = re.compile(r'^Analyzing track (?P<track>\d+).*')
|
||||
@@ -118,7 +127,9 @@ class OutputParser(object, log.Loggable):
|
||||
for line in lines:
|
||||
self.log('Parsing %s', line)
|
||||
if line.startswith('ERROR:'):
|
||||
self._errors.append(line)
|
||||
self._task.exception = ProgramError(line)
|
||||
self._task.abort()
|
||||
return
|
||||
|
||||
self._parse(lines)
|
||||
self._lines.extend(lines)
|
||||
@@ -191,6 +202,7 @@ class CDRDAOTask(task.Task):
|
||||
bufsize=bufsize,
|
||||
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE, close_fds=True)
|
||||
self.debug('Started cdrdao with pid %d', self._popen.pid)
|
||||
|
||||
self.runner.schedule(1.0, self._read, runner)
|
||||
|
||||
@@ -221,6 +233,11 @@ class CDRDAOTask(task.Task):
|
||||
self.stop()
|
||||
return
|
||||
|
||||
def abort(self):
|
||||
self.debug('Aborting, sending SIGTERM to %d', self._popen.pid)
|
||||
os.kill(self._popen.pid, signal.SIGTERM)
|
||||
self.stop()
|
||||
|
||||
def readbytes(self, bytes):
|
||||
"""
|
||||
Called when bytes have been read from stderr.
|
||||
|
||||
Reference in New Issue
Block a user