1 from Components.MenuList import MenuList
2 from Screens.Screen import Screen
3 from Screens.MessageBox import MessageBox
4 from Screens.ChoiceBox import ChoiceBox
5 from Components.ActionMap import ActionMap
6 from Components.Sources.StaticText import StaticText
7 from Components.Sources.Progress import Progress
8 from Components.Label import Label
9 from Components.FileList import FileList
10 from Components.MultiContent import MultiContentEntryText
11 from Tools.Directories import fileExists
12 from Tools.HardwareInfo import HardwareInfo
13 from enigma import eConsoleAppContainer, eListbox, gFont, eListboxPythonMultiContent, \
14 RT_HALIGN_LEFT, RT_HALIGN_CENTER, RT_VALIGN_CENTER, RT_WRAP, eRect, eTimer
15 from os import system, remove
18 from twisted.web import client
19 from twisted.internet import reactor, defer
20 from twisted.python import failure
21 from Plugins.SystemPlugins.Hotplug.plugin import hotplugNotifier
23 class UserRequestedCancel(Exception):
26 class HTTPProgressDownloader(client.HTTPDownloader):
27 def __init__(self, url, outfile, headers=None):
28 client.HTTPDownloader.__init__(self, url, outfile, headers=headers, agent="Dreambox .NFI Download Plugin")
30 self.progress_callback = None
31 self.deferred = defer.Deferred()
33 def noPage(self, reason):
34 if self.status == "304":
35 print reason.getErrorMessage()
36 client.HTTPDownloader.page(self, "")
38 client.HTTPDownloader.noPage(self, reason)
40 def gotHeaders(self, headers):
41 if self.status == "200":
42 if headers.has_key("content-length"):
43 self.totalbytes = int(headers["content-length"][0])
46 self.currentbytes = 0.0
47 return client.HTTPDownloader.gotHeaders(self, headers)
49 def pagePart(self, packet):
50 if self.status == "200":
51 self.currentbytes += len(packet)
52 if self.totalbytes and self.progress_callback:
53 self.progress_callback(self.currentbytes, self.totalbytes)
54 return client.HTTPDownloader.pagePart(self, packet)
57 return client.HTTPDownloader.pageEnd(self)
59 class downloadWithProgress:
60 def __init__(self, url, outputfile, contextFactory=None, *args, **kwargs):
61 scheme, host, port, path = client._parse(url)
62 self.factory = HTTPProgressDownloader(url, outputfile, *args, **kwargs)
63 self.connection = reactor.connectTCP(host, port, self.factory)
66 return self.factory.deferred
70 self.connection.disconnect()
71 #self.factory.deferred.errback(failure.Failure(UserRequestedCancel))
73 def addProgress(self, progress_callback):
75 self.factory.progress_callback = progress_callback
77 class Feedlist(MenuList):
78 def __init__(self, list=[], enableWrapAround = False):
79 MenuList.__init__(self, list, enableWrapAround, eListboxPythonMultiContent)
80 self.l.setFont(0, gFont("Regular", 16))
81 self.l.setItemHeight(22)
85 self.l.setList(self.list)
88 l = self.l.getCurrentSelection()
92 l = self.l.getCurrentSelection()
96 l = self.l.getCurrentSelection()
97 return l and l[0][0][:-3]+"nfo"
100 l = self.l.getCurrentSelection()
101 return l and l[0][1][:-3]+"nfo"
104 l = self.l.getCurrentSelection()
110 def moveSelection(self,idx=0):
111 if self.instance is not None:
112 self.instance.moveSelectionTo(idx)
114 class NFIDownload(Screen):
118 <screen name="NFIDownload" position="90,95" size="560,420" title="Image download utility">
119 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" zPosition="0" size="140,40" transparent="1" alphatest="on" />
120 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" zPosition="0" size="140,40" transparent="1" alphatest="on" />
121 <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" zPosition="0" size="140,40" transparent="1" alphatest="on" />
122 <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" zPosition="0" size="140,40" transparent="1" alphatest="on" />
123 <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;19" valign="center" halign="center" backgroundColor="#9f1313" transparent="1" />
124 <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" />
125 <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" />
126 <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" />
128 <widget source="label_top" render="Label" position="10,44" size="240,20" font="Regular;16" />
129 <widget name="feedlist" position="10,66" size="250,222" scrollbarMode="showOnDemand" />
130 <widget name="destlist" position="0,66" size="260,222" scrollbarMode="showOnDemand" />
132 <widget source="label_bottom" render="Label" position="10,312" size="240,18" font="Regular;16"/>
133 <widget source="path_bottom" render="Label" position="10,330" size="250,42" font="Regular;18" />
135 <widget source="infolabel" render="Label" position="270,44" size="280,284" font="Regular;16" />
136 <widget source="job_progressbar" render="Progress" position="10,374" size="540,26" borderWidth="1" backgroundColor="#254f7497" />
137 <widget source="job_progresslabel" render="Label" position="130,378" zPosition="2" font="Regular;18" halign="center" transparent="1" size="300,22" foregroundColor="#000000" />
138 <widget source="statusbar" render="Label" position="10,404" size="540,16" font="Regular;16" foregroundColor="#cccccc" />
141 def __init__(self, session, destdir="/tmp/"):
142 self.skin = NFIDownload.skin
143 Screen.__init__(self, session)
145 self["job_progressbar"] = Progress()
146 self["job_progresslabel"] = StaticText()
148 self["infolabel"] = StaticText()
149 self["statusbar"] = StaticText()
150 self["label_top"] = StaticText()
151 self["label_bottom"] = StaticText()
152 self["path_bottom"] = StaticText()
154 self["key_green"] = StaticText()
155 self["key_yellow"] = StaticText()
156 self["key_blue"] = StaticText()
158 self["key_red"] = StaticText()
160 self["feedlist"] = Feedlist([0,(eListboxPythonMultiContent.TYPE_TEXT, 0, 0,250, 30, 0, RT_HALIGN_LEFT|RT_VALIGN_CENTER, "feed not available")])
161 self["destlist"] = FileList(destdir, showDirectories = True, showFiles = False)
162 self["destlist"].hide()
164 self.download_container = eConsoleAppContainer()
170 self.box = HardwareInfo().get_device_name()
171 self.feed_base = "http://www.dreamboxupdate.com/opendreambox/1.5/%s/images/" % self.box
172 self.nfi_filter = "" # "release" # only show NFIs containing this string, or all if ""
173 self.wizard_mode = False
175 self["actions"] = ActionMap(["OkCancelActions", "ColorActions", "DirectionActions", "EPGSelectActions"],
177 "cancel": self.closeCB,
179 "green": self.nfi_download,
180 "yellow": self.switchList,
181 "blue": self.askCreateUSBstick,
182 "prevBouquet": self.switchList,
183 "nextBouquet": self.switchList,
188 "upRepeated": self.up,
189 "downRepeated": self.down,
195 def downloading(self, state=True):
197 self["key_red"].text = _("Cancel")
198 self["key_green"].text = ""
199 self["key_yellow"].text = ""
200 self["key_blue"].text = ""
203 self["key_red"].text = _("Exit")
204 if self["feedlist"].isValid():
205 self["key_green"].text = (_("Download"))
206 if self.focus is self.LIST_SOURCE:
207 self["key_yellow"].text = (_("Change dir."))
209 self["key_yellow"].text = (_("Select image"))
210 self["key_blue"].text = (_("USB stick wizard"))
212 def switchList(self,to_where=None):
213 if self.download or not self["feedlist"].isValid():
216 self["job_progressbar"].value = 0
217 self["job_progresslabel"].text = ""
220 if self.focus is self.LIST_SOURCE:
221 to_where = self.LIST_DEST
222 if self.focus is self.LIST_DEST:
223 to_where = self.LIST_SOURCE
225 if to_where is self.LIST_DEST:
226 self.focus = self.LIST_DEST
227 self["statusbar"].text = _("Please select target directory or medium")
228 self["label_top"].text = _("choose destination directory")+":"
229 self["feedlist"].hide()
230 self["destlist"].show()
231 self["label_bottom"].text = _("Selected source image")+":"
232 self["path_bottom"].text = str(self["feedlist"].getNFIname())
233 self["key_yellow"].text = (_("Select image"))
235 elif to_where is self.LIST_SOURCE:
236 self.focus = self.LIST_SOURCE
237 self["statusbar"].text = _("Please choose .NFI image file from feed server to download")
238 self["label_top"].text = _("select image from server")+":"
239 self["feedlist"].show()
240 self["destlist"].hide()
241 self["label_bottom"].text = _("Destination directory")+":"
242 self["path_bottom"].text = str(self["destlist"].getCurrentDirectory())
243 self["key_yellow"].text = (_("Change dir."))
248 if self.focus is self.LIST_SOURCE:
249 self["feedlist"].up()
251 if self.focus is self.LIST_DEST:
252 self["destlist"].up()
257 if self.focus is self.LIST_SOURCE:
258 self["feedlist"].down()
260 if self.focus is self.LIST_DEST:
261 self["destlist"].down()
266 if self.focus is self.LIST_SOURCE:
267 self["feedlist"].pageUp()
269 if self.focus is self.LIST_DEST:
270 self["destlist"].pageUp()
275 if self.focus is self.LIST_SOURCE:
276 self["feedlist"].pageDown()
278 if self.focus is self.LIST_DEST:
279 self["destlist"].pageDown()
284 if self.focus is self.LIST_DEST:
285 if self["destlist"].canDescent():
286 self["destlist"].descent()
288 def feed_download(self):
289 self.downloading(True)
290 self.download = self.feed_download
291 client.getPage(self.feed_base).addCallback(self.feed_finished).addErrback(self.feed_failed)
293 def feed_failed(self, failure_instance):
294 print "[feed_failed] " + str(failure_instance)
295 self["infolabel"].text = _("Could not connect to Dreambox .NFI Image Feed Server:") + "\n" + failure_instance.getErrorMessage() + "\n\n" + _("Please check your network settings!")
296 self.downloading(False)
298 def feed_finished(self, feedhtml):
299 print "[feed_finished] " + str(feedhtml)
300 self.downloading(False)
301 fileresultmask = re.compile("<a href=[\'\"](?P<url>.*?)[\'\"]>(?P<name>.*?.nfi)</a>", re.DOTALL)
302 searchresults = fileresultmask.finditer(feedhtml)
305 for x in searchresults:
307 if url[0:7] != "http://":
308 url = self.feed_base + x.group("url")
309 name = x.group("name")
310 if name.find(self.nfi_filter) > -1:
311 entry = [[name, url],(eListboxPythonMultiContent.TYPE_TEXT, 0, 0,250, 30, 0, RT_HALIGN_LEFT|RT_VALIGN_CENTER, name)]
312 print "adding to feedlist: " + str(entry)
313 fileresultlist.append(entry)
315 print "NOT adding to feedlist: " + name
316 self["feedlist"].l.setList(fileresultlist)
317 self["feedlist"].moveSelection(0)
319 if len(fileresultlist) > 0:
320 self.switchList(self.LIST_SOURCE)
323 self["infolabel"].text = _("Cannot parse feed directory")
325 def nfo_download(self):
326 print "[check_for_NFO]"
327 if self["feedlist"].isValid():
328 print "nfiname: " + self["feedlist"].getNFIname()
329 self["job_progressbar"].value = 0
330 self["job_progresslabel"].text = ""
331 if self["feedlist"].getNFIurl() is None:
332 self["key_green"].text = ""
334 self["key_green"].text = _("Download")
335 nfourl = self["feedlist"].getNFOurl()
336 print "downloading " + nfourl
337 self.download = self.nfo_download
338 self.downloading(True)
339 client.getPage(nfourl).addCallback(self.nfo_finished).addErrback(self.nfo_failed)
340 self["statusbar"].text = ("Downloading image description...")
342 def nfo_failed(self, failure_instance):
343 print "[nfo_failed] " + str(failure_instance)
344 self["infolabel"].text = _("No details for this image file") + "\n" + self["feedlist"].getNFIname()
345 self["statusbar"].text = ""
346 self.nfofilename = ""
348 self.downloading(False)
350 def nfo_finished(self,nfodata=""):
351 print "[nfo_finished] " + str(nfodata)
352 self.downloading(False)
355 self.nfofilename = self["destlist"].getCurrentDirectory() + '/' + self["feedlist"].getNFOname()
356 self["infolabel"].text = self.nfo
358 self.nfofilename = ""
359 self["infolabel"].text = _("No details for this image file")
360 self["statusbar"].text = ""
362 def nfi_download(self):
363 if self["destlist"].getCurrentDirectory() is None:
364 self.switchList(self.LIST_TARGET)
365 if self["feedlist"].isValid():
366 url = self["feedlist"].getNFIurl()
367 self.nfilocal = self["destlist"].getCurrentDirectory()+'/'+self["feedlist"].getNFIname()
368 print "[nfi_download] downloading %s to %s" % (url, self.nfilocal)
369 self.download = downloadWithProgress(url,self.nfilocal)
370 self.download.addProgress(self.nfi_progress)
371 self["job_progressbar"].range = 1000
372 self.download.start().addCallback(self.nfi_finished).addErrback(self.nfi_failed)
373 self.downloading(True)
375 def nfi_progress(self, recvbytes, totalbytes):
376 #print "[update_progress] recvbytes=%d, totalbytes=%d" % (recvbytes, totalbytes)
377 self["job_progressbar"].value = int(1000*recvbytes/float(totalbytes))
378 self["job_progresslabel"].text = "%d of %d kBytes (%.2f%%)" % (recvbytes/1024, totalbytes/1024, 100*recvbytes/float(totalbytes))
380 def nfi_failed(self, failure_instance=None, error_message=""):
381 if error_message == "" and failure_instance is not None:
382 error_message = failure_instance.getErrorMessage()
383 print "[nfi_failed] " + error_message
384 if fileExists(self["destlist"].getCurrentDirectory()+'/'+self["feedlist"].getNFIname()):
385 message = "%s %s\n%s" % (_(".NFI Download failed:"), error_message, _("Remove the incomplete .NFI file?"))
386 self.session.openWithCallback(self.nfi_remove, MessageBox, message, MessageBox.TYPE_YESNO)
388 message = "%s %s" % (_(".NFI Download failed:"),error_message)
389 self.session.open(MessageBox, message, MessageBox.TYPE_ERROR)
390 self.downloading(False)
392 def nfi_finished(self, string=""):
393 print "[nfi_finished] " + str(string)
395 self.nfofilename = self["destlist"].getCurrentDirectory() + '/' + self["feedlist"].getNFOname()
396 nfofd = open(self.nfofilename, "w")
398 nfofd.write(self.nfo)
401 print "couldn't save nfo file " + self.nfofilename
403 pos = self.nfo.find("MD5:")
404 if pos > 0 and len(self.nfo) >= pos+5+32:
405 self["statusbar"].text = ("Please wait for md5 signature verification...")
407 md5 = self.nfo[pos+5:pos+5+32] + " " + self.nfilocal
409 self.download_container.setCWD(self["destlist"].getCurrentDirectory())
410 self.download_container.appClosed.append(self.md5finished)
411 self.download_container.execute(cmd)
412 self.download_container.write(md5)
413 self.download_container.dataSent.append(self.md5ready)
415 self["statusbar"].text = "Download completed."
416 self.downloading(False)
418 self["statusbar"].text = "Download completed."
419 self.downloading(False)
423 def md5ready(self, retval):
424 self.download_container.sendEOF()
426 def md5finished(self, retval):
427 print "[md5finished]: " + str(retval)
428 self.download_container.appClosed.remove(self.md5finished)
430 self.downloading(False)
434 self["statusbar"].text = _(".NFI file passed md5sum signature check. You can safely flash this image!")
435 self.switchList(self.LIST_SOURCE)
437 self.session.openWithCallback(self.nfi_remove, MessageBox, (_("The md5sum validation failed, the file may be downloaded incompletely or be corrupted!") + "\n" + _("Remove the broken .NFI file?")), MessageBox.TYPE_YESNO)
439 def nfi_remove(self, answer):
440 self.downloading(False)
442 nfifilename = self["destlist"].getCurrentDirectory()+'/'+self["feedlist"].getNFIname()
443 if fileExists(self.nfofilename):
444 remove(self.nfofilename)
445 if fileExists(nfifilename):
447 self.switchList(self.LIST_SOURCE)
449 def askCreateUSBstick(self):
451 self.imagefilename = "/tmp/nfiflash_" + self.box + ".img"
452 message = _("You have chosen to create a new .NFI flasher bootable USB stick. This will repartition the USB stick and therefore all data on it will be erased.")
453 self.session.openWithCallback(self.flasherdownload_query, MessageBox, (message + '\n' + _("First we need to download the latest boot environment for the USB flasher.")), MessageBox.TYPE_YESNO)
455 def flasherdownload_query(self, answer):
457 self.downloading(False)
458 self.switchList(self.LIST_SOURCE)
460 #url = self.feed_base + "/nfiflasher_" + self.box + ".tar.bz2"
461 url = "http://www.dreamboxupdate.com/download/opendreambox/dreambox-nfiflasher-%s.tar.bz2" % self.box
462 localfile = "/tmp/nfiflasher_image.tar.bz2"
463 print "[flasherdownload_query] downloading %s to %s" % (url, localfile)
464 self["statusbar"].text = ("Downloading %s..." % url)
465 self.download = downloadWithProgress(url,localfile)
466 self.download.addProgress(self.nfi_progress)
467 self["job_progressbar"].range = 1000
468 self.download.start().addCallback(self.flasherdownload_finished).addErrback(self.flasherdownload_failed)
470 def flasherdownload_failed(self, failure_instance=None, error_message=""):
471 if error_message == "" and failure_instance is not None:
472 error_message = failure_instance.getErrorMessage()
473 print "[flasherdownload_failed] " + error_message
474 message = "%s %s" % (_("Download of USB flasher boot image failed: "),error_message)
475 self.session.open(MessageBox, message, MessageBox.TYPE_ERROR)
476 self.remove_img(True)
478 def flasherdownload_finished(self, string=""):
479 print "[flasherdownload_finished] " + str(string)
480 self.container = eConsoleAppContainer()
481 self.container.appClosed.append(self.umount_finished)
482 self.container.dataAvail.append(self.tool_avail)
485 from os import listdir
486 for device in listdir("/dev"):
487 if device[:2] == "sd" and device[-1:].isdigit():
488 umountdevs += "/dev/"+device
489 self.cmd = "umount " + umountdevs
490 print "executing " + self.cmd
491 self.container.execute(self.cmd)
493 def tool_avail(self, string):
494 print "[tool_avail]" + string
495 self.taskstring += string
497 def umount_finished(self, retval):
498 self.container.appClosed.remove(self.umount_finished)
499 self.container.appClosed.append(self.dmesg_cleared)
501 self.cmd = "dmesg -c"
502 print "executing " + self.cmd
503 self.container.execute(self.cmd)
505 def dmesg_cleared(self, answer):
506 self.container.appClosed.remove(self.dmesg_cleared)
507 self.msgbox = self.session.open(MessageBox, _("Please disconnect all USB devices from your Dreambox and (re-)attach the target USB stick (minimum size is 64 MB) now!"), MessageBox.TYPE_INFO)
508 hotplugNotifier.append(self.hotplugCB)
510 def hotplugCB(self, dev, action):
511 print "[hotplugCB]", dev, action
512 if dev.startswith("sd") and action == "add":
514 hotplugNotifier.remove(self.hotplugCB)
515 self.container.appClosed.append(self.dmesg_scanned)
518 print "executing " + self.cmd
519 self.container.execute(self.cmd)
521 def dmesg_scanned(self, retval):
522 self.container.appClosed.remove(self.dmesg_scanned)
523 dmesg_lines = self.taskstring.splitlines()
524 self.devicetext = None
525 self.stickdevice = None
526 for i, line in enumerate(dmesg_lines):
527 if line.find("usb-storage: waiting for device") != -1 and len(dmesg_lines) > i+3:
528 self.devicetext = dmesg_lines[i+1].lstrip()+"\n"+dmesg_lines[i+3]
529 elif line.find("/dev/scsi/host") != -1:
530 self.stickdevice = line.split(":",1)[0].lstrip()
532 if retval != 0 or self.devicetext is None or self.stickdevice is None:
533 self.session.openWithCallback(self.remove_img, MessageBox, _("No useable USB stick found"), MessageBox.TYPE_ERROR)
535 self.session.openWithCallback(self.fdisk_query, MessageBox, (_("The following device was found:\n\n%s\n\nDo you want to write the USB flasher to this stick?") % self.devicetext), MessageBox.TYPE_YESNO)
537 def fdisk_query(self, answer):
538 if answer == True and self.stickdevice:
539 self["statusbar"].text = ("Partitioning USB stick...")
540 self["job_progressbar"].range = 1000
541 self["job_progressbar"].value = 100
542 self["job_progresslabel"].text = "5.00%"
544 self.container.appClosed.append(self.fdisk_finished)
545 self.container.execute("fdisk " + self.stickdevice + "/disc")
546 self.container.write("d\nn\np\n1\n\n\nt\n6\nw\n")
547 self.delayTimer = eTimer()
548 self.delayTimer.callback.append(self.progress_increment)
549 self.delayTimer.start(105, False)
551 self.remove_img(True)
553 def fdisk_finished(self, retval):
554 self.container.appClosed.remove(self.fdisk_finished)
555 self.delayTimer.stop()
557 if fileExists(self.imagefilename):
559 self["job_progressbar"].value = 700
561 self["statusbar"].text = ("Decompressing USB stick flasher boot image...")
563 self.container.appClosed.append(self.tar_finished)
564 self.container.setCWD("/tmp")
565 self.cmd = "tar -xjvf nfiflasher_image.tar.bz2"
566 self.container.execute(self.cmd)
567 print "executing " + self.cmd
568 self.delayTimer = eTimer()
569 self.delayTimer.callback.append(self.progress_increment)
570 self.delayTimer.start(105, False)
572 print "fdisk failed: " + str(retval)
573 self.session.openWithCallback(self.remove_img, MessageBox, ("fdisk " + _("failed") + ":\n" + str(self.taskstring)), MessageBox.TYPE_ERROR)
575 def progress_increment(self):
576 newval = int(self["job_progressbar"].value) + 1
578 self["job_progressbar"].value = newval
579 self["job_progresslabel"].text = "%.2f%%" % (newval/10.0)
581 def tar_finished(self, retval):
582 self.delayTimer.stop()
583 if len(self.container.appClosed) > 0:
584 self.container.appClosed.remove(self.tar_finished)
586 self.imagefilename = "/tmp/nfiflash_" + self.box + ".img"
587 self["statusbar"].text = ("Copying USB flasher boot image to stick...")
589 self.container.appClosed.append(self.dd_finished)
590 self.cmd = "dd if=%s of=%s" % (self.imagefilename,self.stickdevice+"/part1")
591 self.container.execute(self.cmd)
592 print "executing " + self.cmd
593 self.delayTimer = eTimer()
594 self.delayTimer.callback.append(self.progress_increment)
595 self.delayTimer.start(105, False)
597 self.session.openWithCallback(self.remove_img, MessageBox, (self.cmd + " " + _("failed") + ":\n" + str(self.taskstring)), MessageBox.TYPE_ERROR)
599 def dd_finished(self, retval):
600 self.delayTimer.stop()
601 self.container.appClosed.remove(self.dd_finished)
602 self.downloading(False)
604 self["job_progressbar"].value = 950
605 self["job_progresslabel"].text = "95.00%"
606 self["statusbar"].text = ("Remounting stick partition...")
608 self.container.appClosed.append(self.mount_finished)
609 self.cmd = "mount %s /mnt/usb -o rw,sync" % (self.stickdevice+"/part1")
610 self.container.execute(self.cmd)
611 print "executing " + self.cmd
613 self.session.openWithCallback(self.remove_img, MessageBox, (self.cmd + " " + _("failed") + ":\n" + str(self.taskstring)), MessageBox.TYPE_ERROR)
615 def mount_finished(self, retval):
616 self.container.dataAvail.remove(self.tool_avail)
617 self.container.appClosed.remove(self.mount_finished)
619 self["job_progressbar"].value = 1000
620 self["job_progresslabel"].text = "100.00%"
621 self["statusbar"].text = (".NFI Flasher bootable USB stick successfully created.")
622 self.session.openWithCallback(self.flasherFinishedCB, MessageBox, _("The USB stick is now bootable. Do you want to download the latest image from the feed server and save it on the stick?"), type = MessageBox.TYPE_YESNO)
623 self["destlist"].changeDir("/mnt/usb")
625 self.session.openWithCallback(self.flasherFinishedCB, MessageBox, (self.cmd + " " + _("failed") + ":\n" + str(self.taskstring)), MessageBox.TYPE_ERROR)
626 self.remove_img(True)
628 def remove_img(self, answer):
629 if fileExists("/tmp/nfiflasher_image.tar.bz2"):
630 remove("/tmp/nfiflasher_image.tar.bz2")
631 if fileExists(self.imagefilename):
632 remove(self.imagefilename)
633 self.downloading(False)
634 self.switchList(self.LIST_SOURCE)
636 def flasherFinishedCB(self, answer):
638 self.wizard_mode = True
639 self["feedlist"].moveSelection(0)
640 self["path_bottom"].text = str(self["destlist"].getCurrentDirectory())
644 def configBackup(self):
645 self.session.openWithCallback(self.runBackup, MessageBox, _("The wizard can backup your current settings. Do you want to do a backup now?"))
647 def runBackup(self, result=None):
648 from Tools.Directories import createDir, isMount, pathExists
649 from time import localtime
650 from datetime import date
651 from Screens.Console import Console
653 if isMount("/mnt/usb/"):
654 if (pathExists("/mnt/usb/backup") == False):
655 createDir("/mnt/usb/backup", True)
657 dt = date(d.tm_year, d.tm_mon, d.tm_mday)
658 self.backup_file = "backup/" + str(dt) + "_settings_backup.tar.gz"
659 self.session.open(Console, title = "Backup running", cmdlist = ["tar -czvf " + "/mnt/usb/" + self.backup_file + " /etc/enigma2/ /etc/network/interfaces /etc/wpa_supplicant.conf"], finishedCallback = self.backup_finished, closeOnSuccess = True)
661 def backup_finished(self):
662 wizardfd = open("/mnt/usb/wizard.nfo", "w")
664 wizardfd.write("image: "+self["feedlist"].getNFIname()+'\n')
665 wizardfd.write("configuration: "+self.backup_file+'\n')
667 self.session.open(MessageBox, _("To update your Dreambox firmware, please follow these steps:\n1) Turn off your box with the rear power switch and plug in the bootable USB stick.\n2) Turn mains back on and hold the DOWN button on the front panel pressed for 10 seconds.\n3) Wait for bootup and follow instructions of the wizard."), type = MessageBox.TYPE_INFO)
672 #self.nfi_failed(None, "Cancelled by user request")
673 self.downloading(False)
677 def main(session, **kwargs):
678 session.open(NFIDownload,"/home/root")
680 def filescan_open(list, session, **kwargs):
681 dev = "/dev/" + (list[0].path).rsplit('/',1)[0][7:]
682 print "mounting device " + dev + " to /mnt/usb..."
683 system("mount "+dev+" /mnt/usb/ -o rw,sync")
684 session.open(NFIDownload,"/mnt/usb/")
686 def filescan(**kwargs):
687 from Components.Scanner import Scanner, ScanPath
689 Scanner(mimetypes = ["application/x-dream-image"],
692 ScanPath(path = "", with_subdirs = False),
695 description = (_("Download .NFI-Files for USB-Flasher")+"..."),
696 openfnc = filescan_open, )