Expect formatting in background too soon.
Needs more testing and much better error handling.
from SystemInfo import SystemInfo
import time
from Components.Console import Console
+import Task
def readFile(filename):
file = open(filename)
numPart += 1
return numPart
+ def _unmount(self):
+ self.unmount()
+
def unmount(self):
cmd = "umount"
for parts in getProcMounts():
if path.realpath(parts[0]).startswith(self.dev_path):
cmd = ' ' . join([cmd, parts[1]])
+ break
+ else:
+ # not mounted, return OK
+ return 0
+ print "[Harddisk]", cmd
res = system(cmd)
return (res >> 8)
def mkfs(self):
cmd = "mkfs.ext3 "
size = self.diskSize()
- if size > 2 * 1024:
- cmd += "-T largefile -N %d " % (size * 32)
- elif size > 16 * 1024:
+ if size > 16 * 1024:
cmd += "-T largefile -O sparse_super "
+ elif size > 2 * 1024:
+ cmd += "-T largefile -N %d " % (size * 32)
cmd += "-m0 -O dir_index " + self.partitionPath("1")
res = system(cmd)
return (res >> 8)
def killPartition(self, n):
part = self.partitionPath(n)
+ try:
+ h = open(part, 'wb')
+ zero = 512 * '\0'
+ for i in range(3):
+ h.write(zero)
+ h.close()
+ except Exception, e:
+ print "[Harddisk] Failed to write to", part, "error:", e
- if access(part, 0):
- cmd = 'dd bs=512 count=3 if=/dev/zero of=' + part
- res = system(cmd)
- else:
- res = 0
+ errorList = [ _("Everything is fine"), _("Creating partition failed"), _("Mkfs failed"), _("Mount failed"), _("Create movie folder failed"), _("Fsck failed"), _("Please Reboot"), _("Filesystem contains uncorrectable errors"), _("Unmount failed")]
- return (res >> 8)
+ def createInitializeJob(self):
+ job = Task.Job(_("Initializing storage device..."))
- errorList = [ _("Everything is fine"), _("Creating partition failed"), _("Mkfs failed"), _("Mount failed"), _("Create movie folder failed"), _("Fsck failed"), _("Please Reboot"), _("Filesystem contains uncorrectable errors"), _("Unmount failed")]
+ task = Task.PythonTask(job, _("Unmount"))
+ task.work = self.unmount
+
+ task = Task.PythonTask(job, _("Kill partition"))
+ task.work = lambda: self.killPartition("1")
+
+ task = Task.Task(job, _("Create Partition"))
+ task.setTool('sfdisk')
+ task.args.append('-f')
+ task.args.append(self.disk_path)
+ task.initial_input = "0,\n;\n;\n;\ny\n"
+
+ task = Task.Task(job, _("Create Filesystem"))
+ task.setTool("mkfs.ext3")
+ size = self.diskSize()
+ if size > 16 * 1024:
+ task.args += ["-T", "largefile", "-O", "sparse_super"]
+ elif size > 2 * 1024:
+ task.args += ["-T", "largefile", "-N", str(size * 32)]
+ task.args += ["-m0", "-O", "dir_index", self.partitionPath("1")]
+
+ task = Task.PythonTask(job, _("Mount"))
+ task.work = self.mount
+
+ return job
def initialize(self):
self.unmount()
return -3
return 0
+
+ def createCheckJob(self):
+ job = Task.Job(_("Check storage device..."))
+
+ task = Task.PythonTask(job, _("Unmount"))
+ task.work = self.unmount
+
+ task = Task.Task(job, "fsck")
+ task.setTool('fsck.ext3')
+ task.args.append('-f')
+ task.args.append('-p')
+ task.args.append(self.partitionPath("1"))
+
+ task = Task.PythonTask(job, _("Mount"))
+ task.work = self.mount
+
+ return job
def getDeviceDir(self):
return self.dev_path
def cancel(self):
# some Jobs might have a better idea of how to cancel a job
self.abort()
+
+ def __str__(self):
+ return "Components.Task.Job name=%s #tasks=%s" % (self.name, len(self.tasks))
class Task(object):
def __init__(self, job, name):
not_met.append(precondition)
return not_met
- def run(self, callback):
- failed_preconditions = self.checkPreconditions(True) + self.checkPreconditions(False)
- if len(failed_preconditions):
- callback(self, failed_preconditions)
- return
- self.prepare()
-
- self.callback = callback
+ def _run(self):
from enigma import eConsoleAppContainer
self.container = eConsoleAppContainer()
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)
-
if not self.cmd and self.cmdline:
print "execute:", self.container.execute(self.cmdline), self.cmdline
else:
if self.initial_input:
self.writeInput(self.initial_input)
+ def run(self, callback):
+ failed_preconditions = self.checkPreconditions(True) + self.checkPreconditions(False)
+ if failed_preconditions:
+ callback(self, failed_preconditions)
+ return
+ self.prepare()
+ self.callback = callback
+ self._run()
+
def prepare(self):
pass
self.output_line = self.output_line[i+1:]
def processOutputLine(self, line):
+ print "[Task %s]" % self.name, line
pass
def processFinished(self, returncode):
progress = property(getProgress, setProgress)
+ def __str__(self):
+ return "Components.Task.Task name=%s" % (self.name)
+
+class PythonTask(Task):
+ def _run(self):
+ from twisted.internet import threads, task
+ self.aborted = False
+ self.pos = 0
+ threads.deferToThread(self.work).addBoth(self.onComplete)
+ self.timer = task.LoopingCall(self.onTimer)
+ self.timer.start(5, False)
+ def work(self):
+ raise NotImplemented, "work"
+ def abort(self):
+ self.aborted = True
+ if self.callback is None:
+ self.finish(aborted = True)
+ def onTimer(self):
+ self.setProgress(self.pos)
+ def onComplete(self, result):
+ self.postconditions.append(FailedPostcondition(result))
+ self.timer.stop()
+ del self.timer
+ self.finish()
+
+
# The jobmanager will execute multiple jobs, each after another.
# later, it will also support suspending jobs (and continuing them after reboot etc)
# It also supports a notification when some error occured, and possibly a retry.
def check(self, task):
return task.returncode == 0
+class FailedPostcondition(Condition):
+ def __init__(self, exception):
+ self.exception = exception
+ def getErrorMessage(self, task):
+ return str(self.exception)
+ def check(self, task):
+ return (self.exception is None) or (self.exception == 0)
+
#class HDDInitJob(Job):
# def __init__(self, device):
# Job.__init__(self, _("Initialize Harddisk"))
def check(self, task):
return self.exception is None
-
-class CopyFileTask(Components.Task.Task):
+class CopyFileTask(Components.Task.PythonTask):
def openFiles(self, fileList):
self.callback = None
+ self.fileList = fileList
self.handles = [(open(fn[0], 'rb'), open(fn[1], 'wb')) for fn in fileList]
self.end = 0
for src,dst in fileList:
if not self.end:
self.end = 1
print "[CopyFileTask] size:", self.end
- def run(self, callback):
- print "[CopyFileTask] run"
- self.callback = callback
- self.aborted = False
- self.pos = 0
- threads.deferToThread(self.copyHandles).addBoth(self.onComplete)
- self.timer = task.LoopingCall(self.onTimer)
- self.timer.start(5, False)
- def copyHandles(self):
- print "copyHandles: ", len(self.handles)
+ def work(self):
+ print "[CopyFileTask] handles ", len(self.handles)
try:
for src, dst in self.handles:
while 1:
if self.aborted:
+ print "[CopyFileTask] aborting"
raise Exception, "Aborted"
d = src.read(65536)
if not d:
+ src.close()
+ dst.close()
# EOF
break
dst.write(d)
self.pos += len(d)
- finally:
+ except:
# In any event, close all handles
for src, dst in self.handles:
src.close()
dst.close()
- def abort(self):
- print "[CopyFileTask] abort!"
- self.aborted = True
- if self.callback is None:
- self.finish(aborted = True)
- def onTimer(self):
- self.setProgress(self.pos)
- def onComplete(self, result):
- #callback from reactor, result=None or Failure.
- print "[CopyFileTask] onComplete", result
- self.postconditions.append(FailedPostcondition(result))
- self.timer.stop()
- del self.timer
- if result is None:
- print "[CopyFileTask] done, okay"
- else:
- for s,d in fileList:
+ for s,d in self.fileList:
# Remove incomplete data.
try:
os.unlink(d)
except:
pass
- self.finish()
+ raise
def copyFiles(fileList, name):
from Components.Label import Label
from Components.Pixmap import Pixmap
from Screens.MessageBox import MessageBox
+import Components.Task
from enigma import eTimer
class HarddiskWait(Screen):
def doCheck(self):
self.timer.stop()
- result = self.hdd.check()
- self.close(result)
+ Components.Task.job_manager.AddJob(self.hdd.createCheckJob())
+ self.close(None)
def __init__(self, session, hdd, type):
Screen.__init__(self, session)
def hddReady(self, result):
print "Result: " + str(result)
- if (result != 0):
+ if result is None:
+ # todo: Notify about background task?
+ self.close()
+ elif (result != 0):
if self.type == self.HARDDISK_INITIALIZE:
message = _("Unable to initialize device.\nError: ")
else: