use hotplugNotifier to ease use of NFIFlash plugin. change some excess status bar...
[enigma2.git] / lib / python / Plugins / SystemPlugins / NFIFlash / flasher.py
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
14 from os import system
15 from enigma import eConsoleAppContainer
16 import re
17
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")
22                 if box == "dm7025":
23                         self.end = 256
24                 elif box[:5] == "dm800":
25                         self.end = 512
26                 if box == "dm8000":
27                         self.setTool("/usr/lib/enigma2/python/Plugins/SystemPlugins/NFIFlash/dm8000_writenand")
28                 self.args += param
29                 self.weighting = 1
30
31         def processOutput(self, data):
32                 print "[writeNand] " + data
33                 if data == "." or data.endswith(" ."):
34                         self.progress += 1
35                 elif data.find("*** done!") > 0:
36                         print "data.found done"
37                         self.setProgress(self.end)
38                 else:
39                         self.output_line = data
40
41 class NFISummary(Screen):
42         skin = """
43         <screen position="0,0" size="132,64">
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_progresslabel" render="Label" position="66,50" size="60,14" font="Regular;12" transparent="1" halign="right" zPosition="0" />
47                 <widget source="job_progressbar" render="Progress" position="2,50" size="66,14" borderWidth="1" />
48         </screen>"""
49
50         def __init__(self, session, parent):
51                 Screen.__init__(self, session, parent)
52                 self["title"] = StaticText(_("Image flash utility"))
53                 self["content"] = StaticText(_("Please select .NFI flash image file from medium"))
54                 self["job_progressbar"] = Progress()
55                 self["job_progresslabel"] = StaticText("")
56
57         def setText(self, text):
58                 self["content"].setText(text)
59
60 class NFIFlash(Screen):
61         skin = """
62                 <screen name="NFIFlash" position="90,95" size="560,420" title="Image flash utility">
63                         <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" zPosition="0" size="140,40" transparent="1" alphatest="on" />
64                         <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" zPosition="0" size="140,40" transparent="1" alphatest="on" />
65                         <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" zPosition="0" size="140,40" transparent="1" alphatest="on" />
66                         <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />
67                         <widget source="key_yellow" render="Label" position="280,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#a08500" transparent="1" />
68                         <widget source="key_blue" render="Label" position="420,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#18188b" transparent="1" />
69                         <widget source="listlabel" render="Label" position="16,44" size="200,21" valign="center" font="Regular;18" />
70                         <widget name="filelist" position="0,68" size="260,260" scrollbarMode="showOnDemand" />
71                         <widget source="infolabel" render="Label" position="270,44" size="280,284" font="Regular;16" />
72                         <widget source="job_progressbar" render="Progress" position="10,374" size="540,26" borderWidth="1" backgroundColor="#254f7497" />
73                         <widget source="job_progresslabel" render="Label" position="180,378" zPosition="2" font="Regular;18" halign="center" transparent="1" size="200,22" foregroundColor="#000000" />
74                         <widget source="statusbar" render="Label" position="10,404" size="540,16" font="Regular;16" foregroundColor="#cccccc" />
75                 </screen>"""
76
77         def __init__(self, session, cancelable = True, close_on_finish = False):
78                 self.skin = NFIFlash.skin
79                 Screen.__init__(self, session)
80                 
81                 self["job_progressbar"] = Progress()
82                 self["job_progresslabel"] = StaticText("")
83                 
84                 self["finished"] = Boolean()
85
86                 self["infolabel"] = StaticText("")
87                 self["statusbar"] = StaticText(_("Please select .NFI flash image file from medium"))
88                 self["listlabel"] = StaticText(_("select .NFI flash file")+":")
89                 
90                 self["key_green"] = StaticText()
91                 self["key_yellow"] = StaticText()
92                 self["key_blue"] = StaticText()
93
94                 self["actions"] = ActionMap(["OkCancelActions", "ColorActions", "DirectionActions"],
95                 {
96                         "green": self.ok,
97                         "yellow": self.reboot,
98                         "ok": self.ok,
99                         "left": self.left,
100                         "right": self.right,
101                         "up": self.up,
102                         "down": self.down
103                 }, -1)
104
105                 currDir = "/media/usb/"
106                 self.filelist = FileList(currDir, matchingPattern = "^.*\.(nfi|NFI)")
107                 self["filelist"] = self.filelist
108                 self.nfifile = ""
109                 self.md5sum = ""
110                 self.job = None
111                 self.box = HardwareInfo().get_device_name()
112
113         def closeCB(self):
114                 if ( self.job is None or self.job.status is not self.job.IN_PROGRESS ) and not self.no_autostart:
115                         self.close()
116                 #else:
117                         #if self.cancelable:
118                                 #self.cancel()
119
120         def up(self):
121                 self["filelist"].up()
122                 self.check_for_NFO()
123
124         def down(self):
125                 self["filelist"].down()
126                 self.check_for_NFO()
127         
128         def right(self):
129                 self["filelist"].pageDown()
130                 self.check_for_NFO()
131
132         def left(self):
133                 self["filelist"].pageUp()
134                 self.check_for_NFO()
135
136         def check_for_NFO(self):
137                 self.session.summary.setText(self["filelist"].getFilename())
138                 if self["filelist"].getFilename() is None:
139                         return
140                 if self["filelist"].getCurrentDirectory() is not None:
141                         self.nfifile = self["filelist"].getCurrentDirectory()+self["filelist"].getFilename()
142
143                 if self.nfifile.upper().endswith(".NFI"):
144                         self["key_green"].text = _("Flash")
145                         nfofilename = self.nfifile[0:-3]+"nfo"
146                         if fileExists(nfofilename):
147                                 nfocontent = open(nfofilename, "r").read()
148                                 self["infolabel"].text = nfocontent
149                                 pos = nfocontent.find("MD5:")
150                                 if pos > 0:
151                                         self.md5sum = nfocontent[pos+5:pos+5+32] + "  " + self.nfifile
152                                 else:
153                                         self.md5sum = ""
154                         else:
155                                 self["infolabel"].text = _("No details for this image file") + ":\n" + self["filelist"].getFilename()
156                                 self.md5sum = ""
157                 else:
158                         self["infolabel"].text = ""
159                         self["key_green"].text = ""
160
161         def ok(self):
162                 if self.job is None or self.job.status is not self.job.IN_PROGRESS:
163                         if self["filelist"].canDescent(): # isDir
164                                 self["filelist"].descent()
165                                 self.session.summary.setText(self["filelist"].getFilename())
166                                 self.check_for_NFO()
167                         else:
168                                 self.queryFlash()
169         
170         def queryFlash(self):
171                 fd = open(self.nfifile, 'r')
172                 print fd
173                 sign = fd.read(11)
174                 print sign
175                 if sign.find("NFI1" + self.box + "\0") == 0:
176                         if self.md5sum != "":
177                                 self["statusbar"].text = ("Please wait for md5 signature verification...")
178                                 self.session.summary.setText(("Please wait for md5 signature verification..."))
179                                 self.container = eConsoleAppContainer()
180                                 self.container.setCWD(self["filelist"].getCurrentDirectory())
181                                 self.container.appClosed.append(self.md5finished)
182                                 self.container.dataSent.append(self.md5ready)
183                                 self.container.execute("md5sum -cw -")
184                                 self.container.write(self.md5sum)
185                         else:
186                                 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)
187                 else:
188                         self.session.open(MessageBox, (_("This .NFI file does not contain a valid %s image!") % (self.box.upper())), MessageBox.TYPE_ERROR)
189
190         def md5ready(self, retval):
191                 self.container.sendEOF()
192
193         def md5finished(self, retval):
194                 if retval==0:
195                         self.session.openWithCallback(self.queryCB, MessageBox, _("This .NFI file has a valid md5 signature. Continue programming this image to flash memory?"), MessageBox.TYPE_YESNO)
196                 else:
197                         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)
198
199         def queryCB(self, answer):
200                 if answer == True:
201                         self.createJob()
202                 else:
203                         self["statusbar"].text = _("Please select .NFI flash image file from medium")
204
205         def createJob(self):
206                 self.job = Job("Image flashing job")
207                 param = [self.nfifile]
208                 writeNAND(self.job,param,self.box)
209                 #writeNAND2(self.job,param)
210                 #writeNAND3(self.job,param)
211                 self.job.state_changed.append(self.update_job)
212                 self.job.end = 540
213                 self.cwd = self["filelist"].getCurrentDirectory()
214                 self["job_progressbar"].range = self.job.end
215                 self.startJob()
216
217         def startJob(self):
218                 self["key_blue"].text = ""
219                 self["key_yellow"].text = ""
220                 self["key_green"].text = ""
221                 #self["progress0"].show()
222                 #self["progress1"].show()
223
224                 self.job.start(self.jobcb)
225
226         def update_job(self):
227                 j = self.job
228                 #print "[job state_changed]"
229                 if j.status == j.IN_PROGRESS:
230                         self.session.summary["job_progressbar"].value = j.progress
231                         self.session.summary["job_progressbar"].range = j.end
232                         self.session.summary["job_progresslabel"].text = "%.2f%%" % (100*j.progress/float(j.end))
233                         self["job_progressbar"].range = j.end
234                         self["job_progressbar"].value = j.progress
235                         #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)))
236                         self["job_progresslabel"].text = "%.2f%%" % (100*j.progress/float(j.end))
237                         self.session.summary.setText(j.tasks[j.current_task].name)
238                         self["statusbar"].text = (j.tasks[j.current_task].name)
239
240                 elif j.status == j.FINISHED:
241                         self["statusbar"].text = _("Writing NFI image file to flash completed")
242                         self.session.summary.setText(_("NFI image flashing completed. Press Yellow to Reboot!"))
243                         self["key_yellow"].text = _("Reboot")
244
245                 elif j.status == j.FAILED:
246                         self["statusbar"].text = j.tasks[j.current_task].name + " " + _("failed")
247                         self.session.open(MessageBox, (_("Flashing failed") + ":\n" + j.tasks[j.current_task].name + ":\n" + j.tasks[j.current_task].output_line), MessageBox.TYPE_ERROR)
248
249         def jobcb(self, jobref, fasel, blubber):
250                 print "[jobcb] %s %s %s" % (jobref, fasel, blubber)
251                 self["key_green"].text = _("Flash")
252
253         def reboot(self):
254                 if self.job.status == self.job.FINISHED:
255                         self["statusbar"].text = ("rebooting...")
256                         TryQuitMainloop(self.session,2)
257                         
258         def createSummary(self):
259                 return NFISummary