from Tools.CList import CList
-class Job:
+class Job(object):
NOT_STARTED, IN_PROGRESS, FINISHED, FAILED = range(4)
def __init__(self, name):
self.tasks = [ ]
+ self.workspace = "/tmp"
self.current_task = 0
self.callback = None
self.name = name
self.finished = False
+ self.end = 100
+ self.__progress = 0
+ self.weightScale = 1
self.state_changed = CList()
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)
def start(self, callback):
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):
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):
self.state_changed()
self.callback(self, res)
else:
+ self.state_changed();
self.current_task += 1
self.runNext()
-class Task:
- def __init__(self, name):
+ 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.workspace = "/tmp"
self.immediate_preconditions = [ ]
self.global_preconditions = [ ]
self.postconditions = [ ]
self.returncode = None
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):
self.cmd = cmd
not_met.append(precondition)
return not_met
- def run(self, callback):
- failed_preconditions = self.checkPreconditions(True)
+ def run(self, callback, task_progress_changed):
+ failed_preconditions = self.checkPreconditions(True) + self.checkPreconditions(False)
if len(failed_preconditions):
- errback(failed_preconditions)
+ callback(failed_preconditions)
return
+ 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)
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)
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):
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 = [ ]
# 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 ToolExistsPrecondition:
-# def check(self, task):
-# import os
-# return os.access(task.cmd, os.X_OK)
-#
-#class ReturncodePostcondition:
-# def check(self, task):
-# return task.returncode == 0
-#
+
+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
+ 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):
+ return task.returncode == 0
+
#class HDDInitJob(Job):
# def __init__(self, device):
# Job.__init__(self, _("Initialize Harddisk"))