1 from Screens.Screen import Screen
2 from Screens.MessageBox import MessageBox
3 from Screens.ChoiceBox import ChoiceBox
4 from Screens.Standby import TryQuitMainloop
5 from Components.ActionMap import ActionMap
6 from Components.Sources.StaticText import StaticText
7 from Components.Sources.Progress import Progress
8 from Components.Sources.Boolean import Boolean
9 from Components.Label import Label
10 from Components.FileList import FileList
11 from Components.Task import Task, Job, JobManager
12 from Tools.Directories import fileExists
13 from Tools.HardwareInfo import HardwareInfo
15 from enigma import eConsoleAppContainer
18 class writeNAND(Task):
19 def __init__(self,job,param,box):
20 Task.__init__(self,job, ("Writing image file to NAND Flash"))
21 self.setTool("/usr/lib/enigma2/python/Plugins/SystemPlugins/NFIFlash/mywritenand")
24 elif box[:5] == "dm800":
27 self.setTool("/usr/lib/enigma2/python/Plugins/SystemPlugins/NFIFlash/dm8000_writenand")
31 def processOutput(self, data):
32 print "[writeNand] " + data
33 if data == "." or data.endswith(" ."):
35 elif data.find("*** done!") > 0:
36 print "data.found done"
37 self.setProgress(self.end)
39 self.output_line = data
41 class NFISummary(Screen):
43 """<screen name="NFISummary" position="0,0" size="132,64" id="1">
44 <widget source="title" render="Label" position="2,0" size="120,14" valign="center" font="Regular;12" />
45 <widget source="content" render="Label" position="2,14" size="120,34" font="Regular;12" transparent="1" zPosition="1" />
46 <widget source="job_progressbar" render="Progress" position="2,50" size="66,14" borderWidth="1" />
47 <widget source="job_progresslabel" render="Label" position="66,50" size="60,14" font="Regular;12" transparent="1" halign="right" zPosition="0" />
49 """<screen name="NFISummary" position="0,0" size="96,64" id="2">
50 <widget source="title" render="Label" position="0,0" size="96,14" valign="center" font="Regular;10" />
51 <widget source="content" render="Label" position="0,14" size="96,34" font="Regular;10" transparent="1" zPosition="1" />
52 <widget source="job_progressbar" render="Progress" position="0,50" size="50,14" borderWidth="1" />
53 <widget source="job_progresslabel" render="Label" position="50,50" size="46,14" font="Regular;10" transparent="1" halign="right" zPosition="0" />
56 def __init__(self, session, parent):
57 Screen.__init__(self, session, parent)
58 self["title"] = StaticText(_("Image flash utility"))
59 self["content"] = StaticText(_("Please select .NFI flash image file from medium"))
60 self["job_progressbar"] = Progress()
61 self["job_progresslabel"] = StaticText("")
63 def setText(self, text):
64 self["content"].setText(text)
66 class NFIFlash(Screen):
68 <screen name="NFIFlash" position="90,95" size="560,420" title="Image flash utility">
69 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" zPosition="0" size="140,40" transparent="1" alphatest="on" />
70 <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" zPosition="0" size="140,40" transparent="1" alphatest="on" />
71 <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" zPosition="0" size="140,40" transparent="1" alphatest="on" />
72 <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;19" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />
73 <widget source="key_yellow" render="Label" position="280,0" zPosition="1" size="140,40" font="Regular;19" valign="center" halign="center" backgroundColor="#a08500" transparent="1" />
74 <widget source="key_blue" render="Label" position="420,0" zPosition="1" size="140,40" font="Regular;19" valign="center" halign="center" backgroundColor="#18188b" transparent="1" />
75 <widget source="listlabel" render="Label" position="10,44" size="250,20" font="Regular;16" />
76 <widget name="filelist" position="0,68" size="260,260" scrollbarMode="showOnDemand" />
77 <widget source="infolabel" render="Label" position="270,44" size="280,284" font="Regular;16" />
78 <widget source="job_progressbar" render="Progress" position="10,374" size="540,26" borderWidth="1" backgroundColor="#254f7497" />
79 <widget source="job_progresslabel" render="Label" position="180,378" zPosition="2" font="Regular;18" halign="center" transparent="1" size="200,22" foregroundColor="#000000" />
80 <widget source="statusbar" render="Label" position="10,404" size="540,16" font="Regular;16" foregroundColor="#cccccc" />
83 def __init__(self, session, cancelable = True, close_on_finish = False):
84 self.skin = NFIFlash.skin
85 Screen.__init__(self, session)
87 self["job_progressbar"] = Progress()
88 self["job_progresslabel"] = StaticText("")
90 self["finished"] = Boolean()
92 self["infolabel"] = StaticText("")
93 self["statusbar"] = StaticText(_("Please select .NFI flash image file from medium"))
94 self["listlabel"] = StaticText(_("select .NFI flash file")+":")
96 self["key_green"] = StaticText()
97 self["key_yellow"] = StaticText()
98 self["key_blue"] = StaticText()
100 self["actions"] = ActionMap(["OkCancelActions", "ColorActions", "DirectionActions"],
103 "yellow": self.reboot,
104 "blue": self.runWizard,
112 currDir = "/media/usb/"
113 self.filelist = FileList(currDir, matchingPattern = "^.*\.(nfi|NFI)")
114 self["filelist"] = self.filelist
118 self.box = HardwareInfo().get_device_name()
119 self.configuration_restorable = None
120 self.wizard_mode = False
121 from enigma import eTimer
122 self.delayTimer = eTimer()
123 self.delayTimer.callback.append(self.runWizard)
124 self.delayTimer.start(50,1)
126 def check_for_wizard(self):
127 if self["filelist"].getCurrentDirectory() is not None and fileExists(self["filelist"].getCurrentDirectory()+"wizard.nfo"):
128 self["key_blue"].text = _("USB stick wizard")
131 self["key_blue"].text = ""
135 if not self.check_for_wizard():
136 self.wizard_mode = False
138 wizardcontent = open(self["filelist"].getCurrentDirectory()+"/wizard.nfo", "r").readlines()
140 for line in wizardcontent:
142 if line.startswith("image: "):
143 nfifile = self["filelist"].getCurrentDirectory()+line[7:]
144 if line.startswith("configuration: "):
145 backupfile = self["filelist"].getCurrentDirectory()+line[15:]
146 if fileExists(backupfile):
147 print "wizard configuration:", backupfile
148 self.configuration_restorable = backupfile
150 self.configuration_restorable = None
151 if nfifile and fileExists(nfifile):
152 self.wizard_mode = True
153 print "wizard image:", nfifile
154 self.check_for_NFO(nfifile)
158 if ( self.job is None or self.job.status is not self.job.IN_PROGRESS ) and not self.no_autostart:
165 self["filelist"].up()
169 self["filelist"].down()
173 self["filelist"].pageDown()
177 self["filelist"].pageUp()
180 def check_for_NFO(self, nfifile=None):
181 self.session.summary.setText(self["filelist"].getFilename())
183 self.session.summary.setText(self["filelist"].getFilename())
184 if self["filelist"].getFilename() is None:
186 if self["filelist"].getCurrentDirectory() is not None:
187 self.nfifile = self["filelist"].getCurrentDirectory()+self["filelist"].getFilename()
189 self.nfifile = nfifile
191 if self.nfifile.upper().endswith(".NFI"):
192 self["key_green"].text = _("Flash")
193 nfofilename = self.nfifile[0:-3]+"nfo"
194 if fileExists(nfofilename):
195 nfocontent = open(nfofilename, "r").read()
196 self["infolabel"].text = nfocontent
197 pos = nfocontent.find("MD5:")
199 self.md5sum = nfocontent[pos+5:pos+5+32] + " " + self.nfifile
203 self["infolabel"].text = _("No details for this image file") + (self["filelist"].getFilename() or "")
206 self["infolabel"].text = ""
207 self["key_green"].text = ""
210 if self.job is None or self.job.status is not self.job.IN_PROGRESS:
211 if self["filelist"].canDescent(): # isDir
212 self["filelist"].descent()
213 self.session.summary.setText(self["filelist"].getFilename())
215 self.check_for_wizard()
219 def queryFlash(self):
220 fd = open(self.nfifile, 'r')
224 if sign.find("NFI1" + self.box + "\0") == 0:
225 if self.md5sum != "":
226 self["statusbar"].text = ("Please wait for md5 signature verification...")
227 self.session.summary.setText(("Please wait for md5 signature verification..."))
228 self.container = eConsoleAppContainer()
229 self.container.setCWD(self["filelist"].getCurrentDirectory())
230 self.container.appClosed.append(self.md5finished)
231 self.container.dataSent.append(self.md5ready)
232 self.container.execute("md5sum -cw -")
233 self.container.write(self.md5sum)
235 self.session.openWithCallback(self.queryCB, MessageBox, _("This .NFI file does not have a md5sum signature and is not guaranteed to work. Do you really want to burn this image to flash memory?"), MessageBox.TYPE_YESNO)
237 self.session.open(MessageBox, (_("This .NFI file does not contain a valid %s image!") % (self.box.upper())), MessageBox.TYPE_ERROR)
239 def md5ready(self, retval):
240 self.container.sendEOF()
242 def md5finished(self, retval):
245 self.session.openWithCallback(self.queryCB, MessageBox, _("Shall the USB stick wizard proceed and program the image file %s into flash memory?" % self.nfifile.rsplit('/',1)[-1]), MessageBox.TYPE_YESNO)
247 self.session.openWithCallback(self.queryCB, MessageBox, _("This .NFI file has a valid md5 signature. Continue programming this image to flash memory?"), MessageBox.TYPE_YESNO)
249 self.session.openWithCallback(self.queryCB, MessageBox, _("The md5sum validation failed, the file may be corrupted! Are you sure that you want to burn this image to flash memory? You are doing this at your own risk!"), MessageBox.TYPE_YESNO)
251 def queryCB(self, answer):
255 self["statusbar"].text = _("Please select .NFI flash image file from medium")
256 self.wizard_mode = False
259 self.job = Job("Image flashing job")
260 param = [self.nfifile]
261 writeNAND(self.job,param,self.box)
262 #writeNAND2(self.job,param)
263 #writeNAND3(self.job,param)
264 self.job.state_changed.append(self.update_job)
266 self.cwd = self["filelist"].getCurrentDirectory()
267 self["job_progressbar"].range = self.job.end
271 self["key_blue"].text = ""
272 self["key_yellow"].text = ""
273 self["key_green"].text = ""
274 #self["progress0"].show()
275 #self["progress1"].show()
277 self.job.start(self.jobcb)
279 def update_job(self):
281 #print "[job state_changed]"
282 if j.status == j.IN_PROGRESS:
283 self.session.summary["job_progressbar"].value = j.progress
284 self.session.summary["job_progressbar"].range = j.end
285 self.session.summary["job_progresslabel"].text = "%.2f%%" % (100*j.progress/float(j.end))
286 self["job_progressbar"].range = j.end
287 self["job_progressbar"].value = j.progress
288 #print "[update_job] j.progress=%f, j.getProgress()=%f, j.end=%d, text=%f" % (j.progress, j.getProgress(), j.end, (100*j.progress/float(j.end)))
289 self["job_progresslabel"].text = "%.2f%%" % (100*j.progress/float(j.end))
290 self.session.summary.setText(j.tasks[j.current_task].name)
291 self["statusbar"].text = (j.tasks[j.current_task].name)
293 elif j.status == j.FINISHED:
294 self["statusbar"].text = _("Writing NFI image file to flash completed")
295 self.session.summary.setText(_("NFI image flashing completed. Press Yellow to Reboot!"))
297 self.restoreConfiguration()
298 self["key_yellow"].text = _("Reboot")
300 elif j.status == j.FAILED:
301 self["statusbar"].text = j.tasks[j.current_task].name + " " + _("failed")
302 self.session.open(MessageBox, (_("Flashing failed") + ":\n" + j.tasks[j.current_task].name + ":\n" + j.tasks[j.current_task].output_line), MessageBox.TYPE_ERROR)
304 def jobcb(self, jobref, fasel, blubber):
305 print "[jobcb] %s %s %s" % (jobref, fasel, blubber)
306 self["key_green"].text = _("Flash")
308 def reboot(self, ret=None):
309 if self.job.status == self.job.FINISHED:
310 self["statusbar"].text = ("rebooting...")
311 TryQuitMainloop(self.session,2)
313 def restoreConfiguration(self):
314 if self.configuration_restorable:
315 from Screens.Console import Console
316 cmdlist = [ "mount /dev/mtdblock/3 /mnt/realroot -t jffs2", "tar -xzvf " + self.configuration_restorable + " -C /mnt/realroot/" ]
317 self.session.open(Console, title = "Restore running", cmdlist = cmdlist, finishedCallback = self.restore_finished, closeOnSuccess = True)
319 def restore_finished(self):
320 self.session.openWithCallback(self.reboot, MessageBox, _("USB stick wizard finished. Your dreambox will now restart with your new image!"), MessageBox.TYPE_INFO)
322 def createSummary(self):