X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/14d000b6d44919aaa81f5811ab77d1a294c8d129..614a88f1e3ce676367241d11eca6b19c6ecbb1f5:/lib/python/Components/Task.py diff --git a/lib/python/Components/Task.py b/lib/python/Components/Task.py index e7fdd8f7..a1e04bce 100644 --- a/lib/python/Components/Task.py +++ b/lib/python/Components/Task.py @@ -37,11 +37,15 @@ class Job(object): progress = property(getProgress) + def getStatustext(self): + return { self.NOT_STARTED: _("Waiting"), self.IN_PROGRESS: _("In Progress"), self.FINISHED: _("Finished"), self.FAILED: _("Failed") }[self.status] + def task_progress_changed_CB(self): self.state_changed() def addTask(self, task): task.job = self + task.task_progress_changed = self.task_progress_changed_CB self.tasks.append(task) def start(self, callback): @@ -53,7 +57,7 @@ class Job(object): self.status = self.IN_PROGRESS self.state_changed() self.runNext() - sumTaskWeightings = sum([t.weighting for t in self.tasks]) + sumTaskWeightings = sum([t.weighting for t in self.tasks]) or 1 self.weightScale = self.end / float(sumTaskWeightings) def runNext(self): @@ -67,7 +71,7 @@ class Job(object): else: print "still waiting for %d resident task(s) %s to finish" % (len(self.resident_tasks), str(self.resident_tasks)) else: - self.tasks[self.current_task].run(self.taskCallback, self.task_progress_changed_CB) + self.tasks[self.current_task].run(self.taskCallback) self.state_changed() def taskCallback(self, task, res, stay_resident = False): @@ -123,9 +127,11 @@ class Task(object): self.cmd = None self.cwd = "/tmp" self.args = [ ] + self.cmdline = None self.task_progress_changed = None self.output_line = "" job.addTask(self) + self.container = None def setCommandline(self, cmd, args): self.cmd = cmd @@ -137,6 +143,9 @@ class Task(object): self.global_preconditions.append(ToolExistsPrecondition()) self.postconditions.append(ReturncodePostcondition()) + def setCmdline(self, cmdline): + self.cmdline = cmdline + def checkPreconditions(self, immediate = False): not_met = [ ] if immediate: @@ -148,7 +157,7 @@ class Task(object): not_met.append(precondition) return not_met - def run(self, callback, task_progress_changed): + def run(self, callback): failed_preconditions = self.checkPreconditions(True) + self.checkPreconditions(False) if len(failed_preconditions): callback(self, failed_preconditions) @@ -156,19 +165,21 @@ class Task(object): self.prepare() self.callback = callback - self.task_progress_changed = task_progress_changed from enigma import eConsoleAppContainer self.container = eConsoleAppContainer() - self.container.appClosed.get().append(self.processFinished) - self.container.dataAvail.get().append(self.processOutput) - - assert self.cmd is not None - assert len(self.args) >= 1 + self.container.appClosed.append(self.processFinished) + self.container.stdoutAvail.append(self.processStdout) + self.container.stderrAvail.append(self.processStderr) if self.cwd is not None: self.container.setCWD(self.cwd) - print "execute:", self.container.execute(self.cmd, self.args), self.cmd, " ".join(self.args) + if not self.cmd and self.cmdline: + print "execute:", self.container.execute(self.cmdline), self.cmdline + else: + assert self.cmd is not None + assert len(self.args) >= 1 + print "execute:", self.container.execute(self.cmd, *self.args), ' '.join(self.args) if self.initial_input: self.writeInput(self.initial_input) @@ -177,6 +188,12 @@ class Task(object): def cleanup(self, failed): pass + + def processStdout(self, data): + self.processOutput(data) + + def processStderr(self, data): + self.processOutput(data) def processOutput(self, data): self.output_line += data @@ -195,7 +212,8 @@ class Task(object): self.finish() def abort(self): - self.container.kill() + if self.container: + self.container.kill() self.finish(aborted = True) def finish(self, aborted = False): @@ -225,7 +243,8 @@ class Task(object): if progress < 0: progress = 0 self.__progress = progress - self.task_progress_changed() + if self.task_progress_changed: + self.task_progress_changed() progress = property(getProgress, setProgress) @@ -237,6 +256,7 @@ class JobManager: self.active_jobs = [ ] self.failed_jobs = [ ] self.job_classes = [ ] + self.in_background = False self.active_job = None def AddJob(self, job): @@ -251,10 +271,18 @@ class JobManager: def jobDone(self, job, task, problems): print "job", job, "completed with", problems, "in", task + from Tools import Notifications + if self.in_background: + from Screens.TaskView import JobView + self.in_background = False + Notifications.AddNotification(JobView, self.active_job) if problems: - from Tools import Notifications from Screens.MessageBox import MessageBox - Notifications.AddNotificationWithCallback(self.errorCB, MessageBox, _("Error: %s\nRetry?") % (problems[0].getErrorMessage(task))) + if problems[0].RECOVERABLE: + Notifications.AddNotificationWithCallback(self.errorCB, MessageBox, _("Error: %s\nRetry?") % (problems[0].getErrorMessage(task))) + else: + Notifications.AddNotification(MessageBox, _("Error") + (': %s') % (problems[0].getErrorMessage(task)), type = MessageBox.TYPE_ERROR ) + self.errorCB(False) return #self.failed_jobs.append(self.active_job) @@ -271,6 +299,12 @@ class JobManager: self.active_job = None self.kick() + def getPendingJobs(self): + list = [ ] + if self.active_job: + list.append(self.active_job) + list += self.active_jobs + return list # some examples: #class PartitionExistsPostcondition: # def __init__(self, device): @@ -310,7 +344,7 @@ class Condition: RECOVERABLE = False def getErrorMessage(self, task): - return _("An error has occured. (%s)") % (self.__class__.__name__) + return _("An unknown error occured!") + " (%s @ task %s)" % (self.__class__.__name__, task.__class__.__name__) class WorkspaceExistsPrecondition(Condition): def check(self, task): @@ -336,18 +370,27 @@ class DiskspacePrecondition(Condition): class ToolExistsPrecondition(Condition): def check(self, task): import os + if task.cmd[0]=='/': - realpath = task.cmd + self.realpath = task.cmd + print "[Task.py][ToolExistsPrecondition] WARNING: usage of absolute paths for tasks should be avoided!" + return os.access(self.realpath, os.X_OK) else: - realpath = task.cwd + '/' + task.cmd - self.realpath = realpath - return os.access(realpath, os.X_OK) + self.realpath = task.cmd + path = os.environ.get('PATH', '').split(os.pathsep) + path.append(task.cwd + '/') + absolutes = filter(lambda file: os.access(file, os.X_OK), map(lambda directory, file = task.cmd: os.path.join(directory, file), path)) + if len(absolutes) > 0: + self.realpath = task.cmd[0] + return True + return False def getErrorMessage(self, task): return _("A required tool (%s) was not found.") % (self.realpath) class AbortedPostcondition(Condition): - pass + def getErrorMessage(self, task): + return "Cancelled upon user request" class ReturncodePostcondition(Condition): def check(self, task):