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