X-Git-Url: http://code.vuplus.com/gitweb/?a=blobdiff_plain;f=lib%2Fpython%2FComponents%2FTask.py;h=075324b01109864754640379fcd60680f03ede44;hb=b5513ae969d3d8e5a0870d21cf6c8499987b1135;hp=0441e00e5b2cacd9d72894a88b69ae308817f870;hpb=bad1a92b98b1dfac4d5269f5ad6e983e309572b5;p=vuplus_dvbapp diff --git a/lib/python/Components/Task.py b/lib/python/Components/Task.py index 0441e00..075324b 100644 --- a/lib/python/Components/Task.py +++ b/lib/python/Components/Task.py @@ -3,7 +3,7 @@ from Tools.CList import CList -class Job: +class Job(object): NOT_STARTED, IN_PROGRESS, FINISHED, FAILED = range(4) def __init__(self, name): self.tasks = [ ] @@ -12,6 +12,9 @@ class Job: self.callback = None self.name = name self.finished = False + self.end = 100 + self.__progress = 0 + self.weightScale = 1 self.state_changed = CList() @@ -24,6 +27,18 @@ class Job: def createDescription(self): return None + def getProgress(self): + if self.current_task == len(self.tasks): + return self.end + t = self.tasks[self.current_task] + jobprogress = t.weighting * t.progress / float(t.end) + sum([task.weighting for task in self.tasks[:self.current_task]]) + return int(jobprogress*self.weightScale) + + progress = property(getProgress) + + def task_progress_changed_CB(self): + self.state_changed() + def addTask(self, task): task.job = self self.tasks.append(task) @@ -34,6 +49,8 @@ class Job: self.status = self.IN_PROGRESS self.state_changed() self.runNext() + sumTaskWeightings = sum([t.weighting for t in self.tasks]) + self.weightScale = (self.end+1) / float(sumTaskWeightings) def runNext(self): if self.current_task == len(self.tasks): @@ -41,7 +58,7 @@ class Job: self.status = self.FINISHED self.state_changed() else: - self.tasks[self.current_task].run(self.taskCallback) + self.tasks[self.current_task].run(self.taskCallback,self.task_progress_changed_CB) self.state_changed() def taskCallback(self, res): @@ -51,10 +68,19 @@ class Job: self.state_changed() self.callback(self, res) else: + self.state_changed(); self.current_task += 1 self.runNext() -class Task: + def abort(self): + if self.current_task < len(self.tasks): + self.tasks[self.current_task].abort() + + def cancel(self): + # some Jobs might have a better idea of how to cancel a job + self.abort() + +class Task(object) : def __init__(self, job, name): self.name = name self.immediate_preconditions = [ ] @@ -64,8 +90,13 @@ class Task: self.initial_input = None self.job = None + self.end = 100 + self.weighting = 100 + self.__progress = 0 self.cmd = None + self.cwd = "/tmp" self.args = [ ] + self.task_progress_changed = None job.addTask(self) def setCommandline(self, cmd, args): @@ -89,7 +120,7 @@ class Task: not_met.append(precondition) return not_met - def run(self, callback): + def run(self, callback, task_progress_changed): failed_preconditions = self.checkPreconditions(True) + self.checkPreconditions(False) if len(failed_preconditions): callback(failed_preconditions) @@ -97,6 +128,7 @@ class Task: 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) @@ -105,6 +137,9 @@ class Task: assert self.cmd is not None assert len(self.args) >= 1 + if self.cwd is not None: + self.container.setCWD(self.cwd) + print "execute:", self.container.execute(self.cmd, self.args), self.cmd, self.args if self.initial_input: self.writeInput(self.initial_input) @@ -122,13 +157,21 @@ class Task: self.returncode = returncode self.finish() - def finish(self): + def abort(self): + self.container.kill() + self.finish(aborted = True) + + def finish(self, aborted = False): self.afterRun() not_met = [ ] - for postcondition in self.postconditions: - if not postcondition.check(self): - not_met.append(postcondition) + if aborted: + not_met.append(AbortedPostcondition()) + else: + for postcondition in self.postconditions: + if not postcondition.check(self): + not_met.append(postcondition) + self.cleanup(not_met) self.callback(not_met) def afterRun(self): @@ -137,6 +180,16 @@ class Task: def writeInput(self, input): self.container.write(input) + def getProgress(self): + return self.__progress + + def setProgress(self, progress): + print "progress now", progress + self.__progress = progress + self.task_progress_changed() + + progress = property(getProgress, setProgress) + class JobManager: def __init__(self): self.active_jobs = [ ] @@ -196,18 +249,34 @@ class JobManager: # if filesystem is not None: # self.args += ["-t", filesystem] # self.args.append(device + "part%d" % partition) -# -#class DiskspacePrecondition: -# def __init__(self, diskspace_required): -# self.diskspace_required = diskspace_required -# -# def check(self, task): -# return getFreeDiskspace(task.workspace) >= self.diskspace_required -# + +class WorkspaceExistsPrecondition: + def check(self, task): + return os.access(task.job.workspace, os.W_OK) + +class DiskspacePrecondition: + def __init__(self, diskspace_required): + self.diskspace_required = diskspace_required + + def check(self, task): + import os + try: + s = os.statvfs(task.job.workspace) + return s.f_bsize * s.f_bavail >= self.diskspace_required + except OSError: + return False + class ToolExistsPrecondition: def check(self, task): import os - return os.access(task.cmd, os.X_OK) + if task.cmd[0]=='/': + realpath = task.cmd + else: + realpath = self.cwd + '/' + self.cmd + return os.access(realpath, os.X_OK) + +class AbortedPostcondition: + pass class ReturncodePostcondition: def check(self, task):