[SCM] morituri/master: * morituri/common/task.py: * morituri/program/cdrdao.py: Factor out a PopenTask base class.

js at users.alioth.debian.org js at users.alioth.debian.org
Sun Oct 19 20:09:49 UTC 2014


The following commit has been merged in the master branch:
commit b8fd3f2931546e4eb4e088de9f22dd298d5dff8b
Author: Thomas Vander Stichele <thomas (at) apestaart (dot) org>
Date:   Mon Dec 3 22:58:22 2012 +0000

    	* morituri/common/task.py:
    	* morituri/program/cdrdao.py:
    	  Factor out a PopenTask base class.

diff --git a/ChangeLog b/ChangeLog
index b065bdb..5082140 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2012-12-03  Thomas Vander Stichele  <thomas at apestaart dot org>
 
+	* morituri/common/task.py:
+	* morituri/program/cdrdao.py:
+	  Factor out a PopenTask base class.
+
+2012-12-03  Thomas Vander Stichele  <thomas at apestaart dot org>
+
 	* morituri/common/program.py:
 	  Store rip result after verifying AccurateRip so those results
 	  are stored too.
diff --git a/morituri/common/task.py b/morituri/common/task.py
index f7744e7..55afffe 100644
--- a/morituri/common/task.py
+++ b/morituri/common/task.py
@@ -1,6 +1,11 @@
 # -*- Mode: Python -*-
 # vi:si:et:sw=4:sts=4:ts=4
 
+import os
+import signal
+import subprocess
+
+from morituri.extern import asyncsub
 from morituri.extern.log import log
 from morituri.extern.task import task, gstreamer
 
@@ -13,3 +18,116 @@ class SyncRunner(log.Loggable, task.SyncRunner):
 
 class GstPipelineTask(log.Loggable, gstreamer.GstPipelineTask):
     pass
+
+
+class PopenTask(log.Loggable, task.Task):
+    """
+    I am a task that runs a command using Popen.
+    """
+
+    logCategory = 'PopenTask'
+    bufsize = 1024
+    command = None
+
+    def start(self, runner):
+        task.Task.start(self, runner)
+
+        try:
+            self._popen = asyncsub.Popen(self.command,
+                bufsize=self.bufsize,
+                stdin=subprocess.PIPE, stdout=subprocess.PIPE,
+                stderr=subprocess.PIPE, close_fds=True)
+        except OSError, e:
+            import errno
+            if e.errno == errno.ENOENT:
+                self.commandMissing()
+
+            raise
+
+        self.debug('Started %r with pid %d', self.command,
+            self._popen.pid)
+
+        self.schedule(1.0, self._read, runner)
+
+    def _read(self, runner):
+        try:
+            ret = self._popen.recv()
+
+            if ret:
+                self.log("read from stdout: %s", ret)
+                self.readbytesout(ret)
+
+            ret = self._popen.recv_err()
+
+            if ret:
+                self.log("read from stderr: %s", ret)
+                self.readbyteserr(ret)
+
+            if self._popen.poll() is None and self.runner:
+                # not finished yet
+                self.schedule(1.0, self._read, runner)
+                return
+
+            self._done()
+        except Exception, e:
+            self.debug('exception during _read()')
+            self.debug(log.getExceptionMessage(e))
+            self.setException(e)
+            self.stop()
+
+    def _done(self):
+            assert self._popen.returncode is not None, "No returncode"
+
+            if self._popen.returncode >= 0:
+                self.debug('Return code was %d', self._popen.returncode)
+            else:
+                self.debug('Terminated with signal %d',
+                    -self._popen.returncode)
+
+            self.setProgress(1.0)
+
+            if self._popen.returncode != 0:
+                self.failed()
+            else:
+                self.done()
+
+            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 readbytesout(self, bytes):
+        """
+        Called when bytes have been read from stdout.
+        """
+        pass
+
+    def readbyteserr(self, bytes):
+        """
+        Called when bytes have been read from stderr.
+        """
+        pass
+
+    def done(self):
+        """
+        Called when the command completed successfully.
+        """
+        raise NotImplementedError
+
+    def failed(self):
+        """
+        Called when the command failed.
+        """
+        raise NotImplementedError
+
+
+    def commandMissing(self):
+        """
+        Called when the command is missing.
+        """
+        pass
+
+
diff --git a/morituri/program/cdrdao.py b/morituri/program/cdrdao.py
index 0b1fb7b..eb58a34 100644
--- a/morituri/program/cdrdao.py
+++ b/morituri/program/cdrdao.py
@@ -23,14 +23,12 @@
 
 import re
 import os
-import signal
-import subprocess
 import tempfile
 
 from morituri.common import log, common
 from morituri.image import toc, table
+from morituri.common import task as ctask
 
-from morituri.extern import asyncsub
 from morituri.extern.task import task
 
 
@@ -244,7 +242,7 @@ class OutputParser(object, log.Loggable):
 # FIXME: handle errors
 
 
-class CDRDAOTask(task.Task):
+class CDRDAOTask(ctask.PopenTask):
     """
     I am a task base class that runs CDRDAO.
     """
@@ -258,97 +256,20 @@ class CDRDAOTask(task.Task):
         self.debug('creating CDRDAOTask')
 
     def start(self, runner):
-        task.Task.start(self, runner)
+        self.debug('Starting cdrdao with options %r', self.options)
+        self.command = ['cdrdao', ] + self.options
 
-        bufsize = 1024
-        try:
-            self._popen = asyncsub.Popen(["cdrdao", ] + self.options,
-                bufsize=bufsize,
-                stdin=subprocess.PIPE, stdout=subprocess.PIPE,
-                stderr=subprocess.PIPE, close_fds=True)
-        except OSError, e:
-            import errno
-            if e.errno == errno.ENOENT:
-                raise common.MissingDependencyException('cdrdao')
+        ctask.PopenTask.start(self, runner)
 
-            raise
+    def commandMissing(self):
+        raise common.MissingDependencyException('cdrdao')
 
-        self.debug('Started cdrdao with pid %d and options %r',
-            self._popen.pid, self.options)
-        self.debug('command: cdrdao %s', ' '.join(self.options))
 
-        self.schedule(1.0, self._read, runner)
-
-    def _read(self, runner):
-        try:
-            ret = self._popen.recv()
-
-            if ret:
-                self.log("read from stdout: %s", ret)
-                self.readbytesout(ret)
-
-            ret = self._popen.recv_err()
-
-            if ret:
-                self.log("read from stderr: %s", ret)
-                self.readbyteserr(ret)
-
-            if self._popen.poll() is None and self.runner:
-                # not finished yet
-                self.schedule(1.0, self._read, runner)
-                return
-
-            self._done()
-        except Exception, e:
-            self.debug('exception during _read()')
-            self.debug(log.getExceptionMessage(e))
-            self.setException(e)
-            self.stop()
-
-    def _done(self):
-            assert self._popen.returncode is not None, "No returncode"
-
-            if self._popen.returncode >= 0:
-                self.debug('Return code was %d', self._popen.returncode)
-            else:
-                self.debug('Terminated with signal %d',
-                    -self._popen.returncode)
-
-            self.setProgress(1.0)
-
-            if self._popen.returncode != 0:
-                if self.errors:
-                    raise DeviceOpenException("\n".join(self.errors))
-                else:
-                    raise ProgramFailedException(self._popen.returncode)
-            else:
-                self.done()
-
-            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 readbytesout(self, bytes):
-        """
-        Called when bytes have been read from stdout.
-        """
-        pass
-
-    def readbyteserr(self, bytes):
-        """
-        Called when bytes have been read from stderr.
-        """
-        pass
-
-    def done(self):
-        """
-        Called when cdrdao completed successfully.
-        """
-        raise NotImplementedError
+    def failed(self):
+        if self.errors:
+            raise DeviceOpenException("\n".join(self.errors))
+        else:
+            raise ProgramFailedException(self._popen.returncode)
 
 
 class DiscInfoTask(CDRDAOTask):

-- 
morituri packaging



More information about the pkg-multimedia-commits mailing list