ba96c07182814456b5cd36a8e0de0d3add979f78
[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 Screens.Console import Console
6 from Components.ActionMap import ActionMap
7 from Components.Sources.StaticText import StaticText
8 from Components.Sources.Progress import Progress
9 from Components.Sources.Boolean import Boolean
10 from Components.Label import Label
11 from Components.FileList import FileList
12 from Components.Task import Task, Job, job_manager, Condition
13 from Screens.TaskView import JobView
14 from Tools.Directories import fileExists
15 from Tools.HardwareInfo import HardwareInfo
16 from os import system
17 from enigma import eConsoleAppContainer, quitMainloop
18 from Components.About import about
19
20 class md5Postcondition(Condition):
21         def check(self, task):
22                 print "md5Postcondition::check", task.returncode
23                 return task.returncode == 0
24
25         def getErrorMessage(self, task):
26                 if task.returncode == 1:
27                         return _("The md5sum validation failed, the file may be corrupted!")
28                 return "md5 error"
29
30 class md5verify(Task):
31         def __init__(self, job, path, md5):
32                 Task.__init__(self, job, "md5sum")
33                 self.postconditions.append(md5Postcondition())
34                 self.weighting = 5
35                 self.cwd = path
36                 self.setTool("md5sum")
37                 self.args += ["-c", "-s"]
38                 self.initial_input = md5
39         
40         def writeInput(self, input):
41                 self.container.dataSent.append(self.md5ready)
42                 print "[writeInput]", input
43                 Task.writeInput(self, input)
44
45         def md5ready(self, retval):
46                 self.container.sendEOF()
47
48         def processOutput(self, data):
49                 print "[md5sum]",
50
51 class writeNAND(Task):
52         def __init__(self, job, param, box):
53                 Task.__init__(self,job, ("Writing image file to NAND Flash"))
54                 self.setTool("/usr/lib/enigma2/python/Plugins/SystemPlugins/NFIFlash/writenfi-mipsel-2.6.18-r1")
55                 if box == "dm7025":
56                         self.end = 256
57                 elif box[:5] == "dm800":
58                         self.end = 512
59                 self.args += param
60                 self.weighting = 95
61
62         def processOutput(self, data):
63                 print "[writeNand] " + data
64                 if data == "." or data.endswith(" ."):
65                         self.progress += 1
66                 elif data.find("*** done!") > 0:
67                         print "data.found done"
68                         self.setProgress(self.end)
69                 else:
70                         self.output_line = data
71
72 class NFIFlash(Screen):
73         skin = """
74         <screen name="NFIFlash" position="center,center" size="610,410" title="Image flash utility" >
75                 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
76                 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
77                 <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" alphatest="on" />
78                 <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" alphatest="on" />
79                 <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#9f1313" transparent="1" />
80                 <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" />
81                 <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" />
82                 <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" />
83                 <ePixmap pixmap="skin_default/border_menu_350.png" position="5,50" zPosition="1" size="350,300" transparent="1" alphatest="on" />
84                 <widget name="filelist" position="15,60" size="330,284" scrollbarMode="showOnDemand" />
85                 <widget source="infolabel" render="Label" position="360,50" size="240,300" font="Regular;13" />
86                 <widget source="status" render="Label" position="5,360" zPosition="10" size="600,50" halign="center" valign="center" font="Regular;22" transparent="1" shadowColor="black" shadowOffset="-1,-1" />
87         </screen>"""
88
89         def __init__(self, session, destdir=None):
90                 Screen.__init__(self, session)
91                 
92                 self.box = HardwareInfo().get_device_name()
93                 self.usbmountpoint = "/mnt/usb/"
94
95                 self["key_red"] = StaticText()
96                 self["key_green"] = StaticText()
97                 self["key_yellow"] = StaticText()
98                 self["key_blue"] = StaticText()
99                 self.filelist = FileList(self.usbmountpoint, matchingPattern = "^.*\.(nfi|NFI)", showDirectories = False, showMountpoints = False)
100                 self["filelist"] = self.filelist
101                 self["infolabel"] = StaticText()
102
103                 self["status"] = StaticText(_("Please select an NFI file and press green key to flash!") + '\n' + _("currently installed image: %s") % (about.getImageVersionString()))
104                 self.job = None
105
106                 self["shortcuts"] = ActionMap(["OkCancelActions", "ColorActions", "ShortcutActions", "DirectionActions"],
107                 {
108                         "ok": self.keyOk,
109                         "green": self.keyOk,
110                         "up": self.keyUp,
111                         "upRepeated": self.keyUp,
112                         "downRepeated": self.keyDown,
113                         "down": self.keyDown,
114                         "left": self.keyLeft,
115                         "yellow": self.reboot,
116                         "right": self.keyRight
117                 }, -1)
118                 self.md5sum = ""
119                 self.onShown.append(self.autostart)
120
121         def autostart(self):
122                 self.onShown.remove(self.autostart)
123                 self.check_for_NFO()
124                 print "[[layoutFinished]]", len(self["filelist"].getFileList())
125                 if len(self["filelist"].getFileList()) == 1:
126                         print "==1"
127                         self.keyOk()
128
129         def keyUp(self):
130                 self["filelist"].up()
131                 self.check_for_NFO()
132
133         def keyDown(self):
134                 self["filelist"].down()
135                 self.check_for_NFO()
136         
137         def keyRight(self):
138                 self["filelist"].pageDown()
139                 self.check_for_NFO()
140
141         def keyLeft(self):
142                 self["filelist"].pageUp()
143                 self.check_for_NFO()
144
145         def keyOk(self):
146                 if self.job is None or self.job.status is not self.job.IN_PROGRESS:
147                         if self["filelist"].canDescent(): # isDir
148                                 self["filelist"].descent()
149                                 self.check_for_NFO()
150                         elif self["filelist"].getFilename():
151                                 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)
152
153         def check_for_NFO(self, nfifile=None):
154                 print "check_for_NFO", self["filelist"].getFilename(), self["filelist"].getCurrentDirectory()
155                 self["infolabel"].text = ""
156                 self["key_green"].text = ""
157
158                 if nfifile is None:
159                         if self["filelist"].getFilename() is None:
160                                 return
161                         if self["filelist"].getCurrentDirectory() is not None:
162                                 self.nfifile = self["filelist"].getCurrentDirectory()+self["filelist"].getFilename()
163                 else:
164                         self.nfifile = nfifile
165
166                 if self.nfifile.upper().endswith(".NFI"):
167                         self["key_green"].text = _("Flash")
168                         nfofilename = self.nfifile[0:-3]+"nfo"
169                         print nfofilename, fileExists(nfofilename)
170                         if fileExists(nfofilename):
171                                 nfocontent = open(nfofilename, "r").read()
172                                 print "nfocontent:", nfocontent
173                                 self["infolabel"].text = nfocontent
174                                 pos = nfocontent.find("MD5:")
175                                 if pos > 0:
176                                         self.md5sum = nfocontent[pos+5:pos+5+32] + "  " + self.nfifile
177                                 else:
178                                         self.md5sum = ""
179                         else:
180                                 self["infolabel"].text = _("No details for this image file") + (self["filelist"].getFilename() or "")
181                                 self.md5sum = ""
182
183         def queryCB(self, answer):
184                 if answer == True:
185                         self.createJob()
186
187         def createJob(self):
188                 self.job = Job("Image flashing job")
189                 self.job.afterEvent = "close"
190                 cwd = self["filelist"].getCurrentDirectory()
191                 md5verify(self.job, cwd, self.md5sum)
192                 writeNAND(self.job, [self.nfifile], self.box)
193                 self["key_blue"].text = ""
194                 self["key_yellow"].text = ""
195                 self["key_green"].text = ""
196                 job_manager.AddJob(self.job)
197                 self.session.openWithCallback(self.flashed, JobView, self.job, cancelable = False, backgroundable = False, afterEventChangeable = False)
198
199         def flashed(self, bg):
200                 print "[flashed]"
201                 if self.job.status == self.job.FINISHED:
202                         self["status"].text = _("NFI image flashing completed. Press Yellow to Reboot!")
203                         filename = self.usbmountpoint+'enigma2settingsbackup.tar.gz'
204                         if fileExists(filename):
205                                 import os.path, time
206                                 date = time.ctime(os.path.getmtime(filename))
207                                 self.session.openWithCallback(self.askRestoreCB, MessageBox, _("The wizard found a configuration backup. Do you want to restore your old settings from %s?") % date, MessageBox.TYPE_YESNO)
208                         else:
209                                 self.unlockRebootButton()
210                 else:
211                         self["status"].text = _("Flashing failed")
212
213         def askRestoreCB(self, ret):
214                 if ret:
215                         from Plugins.SystemPlugins.SoftwareManager.BackupRestore import getBackupFilename
216                         restorecmd = ["tar -xzvf " + self.usbmountpoint + getBackupFilename() + " -C /"]
217                         self.session.openWithCallback(self.unlockRebootButton, Console, title = _("Restore is running..."), cmdlist = restorecmd, closeOnSuccess = True)
218                 else:
219                         self.unlockRebootButton()
220
221         def unlockRebootButton(self, retval = None):
222                 if self.job.status == self.job.FINISHED:
223                         self["key_yellow"].text = _("Reboot")
224
225         def reboot(self, ret=None):
226                 if self.job.status == self.job.FINISHED:
227                         self["status"].text = ("rebooting...")
228                         from os import system
229                         system("/usr/lib/enigma2/python/Plugins/SystemPlugins/NFIFlash/kill_e2_reboot.sh")