From a9ec95e56d2318abb27746747b54861c206d3540 Mon Sep 17 00:00:00 2001 From: Thomas Vander Stichele Date: Mon, 20 Apr 2009 22:20:07 +0000 Subject: [PATCH] * morituri/common/task.py: Add a 'described' method so listeners can get proper notification of description changes, and update their description in between progress changes. Add a MultiCombinedTask that reports on progress over all tasks combined. * examples/trm.py: Add a playlist option to the example. Still needs to store results to pickles, preferably after each completed task. * morituri/common/checksum.py: Add audioconvert to make sure we can trm ogg files. --- ChangeLog | 14 +++++++ examples/trm.py | 27 ++++++++---- morituri/common/checksum.py | 3 +- morituri/common/task.py | 83 ++++++++++++++++++++++++++++++------- 4 files changed, 104 insertions(+), 23 deletions(-) diff --git a/ChangeLog b/ChangeLog index 70601f3..df232b9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2009-04-21 Thomas Vander Stichele + + * morituri/common/task.py: + Add a 'described' method so listeners can get proper notification + of description changes, and update their description in between + progress changes. + Add a MultiCombinedTask that reports on progress over all tasks + combined. + * examples/trm.py: + Add a playlist option to the example. Still needs to store results + to pickles, preferably after each completed task. + * morituri/common/checksum.py: + Add audioconvert to make sure we can trm ogg files. + 2009-04-20 Thomas Vander Stichele * morituri/common/task.py: diff --git a/examples/trm.py b/examples/trm.py index 34b4caf..3b34c2e 100644 --- a/examples/trm.py +++ b/examples/trm.py @@ -54,16 +54,26 @@ def main(argv): action="store", dest="runner", help="runner ('cli' or 'gtk', defaults to %s)" % default, default=default) + parser.add_option('-p', '--playlist', + action="store", dest="playlist", + help="playlist to analyze files from") + options, args = parser.parse_args(argv[1:]) - try: - path = sys.argv[1] - except IndexError: - sys.stderr.write('Please give a file to trm!\n') - return + paths = [] + if len(args) > 0: + paths.extend(args[0:]) + if options.playlist: + paths.extend(open(options.playlist).readlines()) + + mtask = task.MultiCombinedTask() + for path in paths: + path = path.rstrip() + trmtask = checksum.TRMTask(path) + mtask.addTask(trmtask) + mtask.description = 'Fingerprinting files' - trmtask = checksum.TRMTask(path) if options.runner == 'cli': runner = task.SyncRunner() @@ -72,9 +82,10 @@ def main(argv): runner = task.GtkProgressRunner() function = gtkmain - function(runner, trmtask) + function(runner, mtask) print - print trmtask.trm + for trmtask in mtask: + print trmtask.trm main(sys.argv) diff --git a/morituri/common/checksum.py b/morituri/common/checksum.py index e7104cb..abb3f9d 100644 --- a/morituri/common/checksum.py +++ b/morituri/common/checksum.py @@ -280,7 +280,7 @@ class TRMTask(task.Task): task.Task.start(self, runner) self._pipeline = gst.parse_launch(''' filesrc location="%s" ! - decodebin ! audio/x-raw-int ! + decodebin ! audioconvert ! audio/x-raw-int ! trm name=trm ! appsink name=sink sync=False emit-signals=True''' % self._path) self._bus = self._pipeline.get_bus() @@ -293,6 +293,7 @@ class TRMTask(task.Task): gst.debug('pausing') self._pipeline.set_state(gst.STATE_PAUSED) + gst.debug('paused') self._pipeline.get_state() gst.debug('paused') diff --git a/morituri/common/task.py b/morituri/common/task.py index 14855cb..5d909ac 100644 --- a/morituri/common/task.py +++ b/morituri/common/task.py @@ -49,7 +49,7 @@ class Task(object): Subclasses should chain up to me at the beginning. """ - self.progress = 0.0 + self.setProgress(self.progress) self.running = True self.runner = runner self._notifyListeners('started') @@ -81,6 +81,11 @@ class Task(object): self._notifyListeners('progressed', value) self.debug('notifying progress', value) + def setDescription(self, description): + if description != self.description: + self._notifyListeners('described', description) + self.description = description + def addListener(self, listener): """ Add a listener for task status changes. @@ -111,15 +116,17 @@ class DummyTask(Task): self.runner.schedule(1.0, self._wind) -class MultiTask(Task): +class BaseMultiTask(Task): """ I perform multiple tasks. - I track progress of each individual task, going back to 0 for each task. """ description = 'Doing various tasks' tasks = None + def __init__(self): + self.tasks = [] + def addTask(self, task): if self.tasks is None: self.tasks = [] @@ -133,16 +140,15 @@ class MultiTask(Task): self.__tasks = self.tasks[:] self._generic = self.description - self._next() + self.next() - def _next(self): + def next(self): # start next task - self.progress = 0.0 # reset progress for each task task = self.__tasks[0] del self.__tasks[0] self._task += 1 - self.description = "%s (%d of %d) ..." % ( - self._generic, self._task, len(self.tasks)) + self.setDescription("%s (%d of %d) ..." % ( + self._generic, self._task, len(self.tasks))) task.addListener(self) task.start(self.runner) @@ -151,7 +157,7 @@ class MultiTask(Task): pass def progressed(self, task, value): - self.setProgress(value) + pass def stopped(self, task): if not self.__tasks: @@ -159,9 +165,44 @@ class MultiTask(Task): return # pick another - self._next() + self.next() +class MultiTask(BaseMultiTask): + """ + I perform multiple tasks. + I track progress of each individual task, going back to 0 for each task. + """ + + def start(self, runner): + BaseMultiTask.start(self, runner) + + def next(self): + # start next task + self.progress = 0.0 # reset progress for each task + BaseMultiTask.next(self) + + ### listener methods + def progressed(self, task, value): + self.setProgress(value) + +class MultiCombinedTask(BaseMultiTask): + """ + I perform multiple tasks. + I track progress as a combined progress on all tasks on task granularity. + """ + + _stopped = 0 + + ### listener methods + def progressed(self, task, value): + self.setProgress(float(self._stopped + value) / len(self.tasks)) + + def stopped(self, task): + self._stopped += 1 + self.setProgress(float(self._stopped) / len(self.tasks)) + BaseMultiTask.stopped(self, task) + class TaskRunner: """ I am a base class for task runners. @@ -197,6 +238,14 @@ class TaskRunner: @param value: progress, from 0.0 to 1.0 """ + def described(self, task, description): + """ + Implement me to be informed about description changes. + + @type description: str + @param description: description + """ + def started(self, task): """ Implement me to be informed about the task starting. @@ -234,9 +283,7 @@ class SyncRunner(TaskRunner): if not self._verbose: return - sys.stdout.write('%s %3d %%\r' % ( - self._task.description, value * 100.0)) - sys.stdout.flush() + self._report() if value >= 1.0: if self._skip: @@ -248,9 +295,16 @@ class SyncRunner(TaskRunner): self._task.description, 100.0) sys.stdout.write("%s\r" % (' ' * len(text), )) + def described(self, task, description): + self._report() + def stopped(self, task): self._loop.quit() + def _report(self): + sys.stdout.write('%s %3d %%\r' % ( + self._task.description, self._task.progress * 100.0)) + sys.stdout.flush() class GtkProgressRunner(gtk.VBox, TaskRunner): """ @@ -294,9 +348,10 @@ class GtkProgressRunner(gtk.VBox, TaskRunner): # self._task.removeListener(self) def progressed(self, task, value): - self._label.set_text(task.description) self._progress.set_fraction(value) + def described(self, task, description): + self._label.set_text(description) if __name__ == '__main__': task = DummyTask()