1 # -*- coding: utf-8 -*-
2 from Components.MenuList import MenuList
3 from Screens.Screen import Screen
4 from Screens.MessageBox import MessageBox
5 from Screens.ChoiceBox import ChoiceBox
6 from Components.ActionMap import ActionMap
7 from Components.Sources.StaticText import StaticText
8 from Components.Sources.Progress import Progress
9 from Components.Label import Label
10 from Components.FileList import FileList
11 from Components.MultiContent import MultiContentEntryText
12 from Tools.Directories import fileExists
13 from Tools.HardwareInfo import HardwareInfo
14 from enigma import eConsoleAppContainer, eListbox, gFont, eListboxPythonMultiContent, \
15 RT_HALIGN_LEFT, RT_HALIGN_CENTER, RT_VALIGN_CENTER, RT_WRAP, eRect, eTimer
16 from os import system, remove
19 from twisted.web import client
20 from twisted.internet import reactor, defer
21 from twisted.python import failure
22 from Plugins.SystemPlugins.Hotplug.plugin import hotplugNotifier
24 class UserRequestedCancel(Exception):
27 class HTTPProgressDownloader(client.HTTPDownloader):
28 def __init__(self, url, outfile, headers=None):
29 client.HTTPDownloader.__init__(self, url, outfile, headers=headers, agent="Dreambox .NFI Download Plugin")
31 self.progress_callback = None
32 self.deferred = defer.Deferred()
34 def noPage(self, reason):
35 if self.status == "304":
36 print reason.getErrorMessage()
37 client.HTTPDownloader.page(self, "")
39 client.HTTPDownloader.noPage(self, reason)
41 def gotHeaders(self, headers):
42 if self.status == "200":
43 if headers.has_key("content-length"):
44 self.totalbytes = int(headers["content-length"][0])
47 self.currentbytes = 0.0
48 return client.HTTPDownloader.gotHeaders(self, headers)
50 def pagePart(self, packet):
51 if self.status == "200":
52 self.currentbytes += len(packet)
53 if self.totalbytes and self.progress_callback:
54 self.progress_callback(self.currentbytes, self.totalbytes)
55 return client.HTTPDownloader.pagePart(self, packet)
58 return client.HTTPDownloader.pageEnd(self)
60 class downloadWithProgress:
61 def __init__(self, url, outputfile, contextFactory=None, *args, **kwargs):
62 scheme, host, port, path = client._parse(url)
63 self.factory = HTTPProgressDownloader(url, outputfile, *args, **kwargs)
64 self.connection = reactor.connectTCP(host, port, self.factory)
67 return self.factory.deferred
71 self.connection.disconnect()
72 #self.factory.deferred.errback(failure.Failure(UserRequestedCancel))
74 def addProgress(self, progress_callback):
76 self.factory.progress_callback = progress_callback
78 class Feedlist(MenuList):
79 def __init__(self, list=[], enableWrapAround = False):
80 MenuList.__init__(self, list, enableWrapAround, eListboxPythonMultiContent)
81 self.l.setFont(0, gFont("Regular", 16))
82 self.l.setItemHeight(22)
86 self.l.setList(self.list)
89 l = self.l.getCurrentSelection()
93 l = self.l.getCurrentSelection()
97 l = self.l.getCurrentSelection()
98 return l and l[0][0][:-3]+"nfo"
101 l = self.l.getCurrentSelection()
102 return l and l[0][1][:-3]+"nfo"
105 l = self.l.getCurrentSelection()
111 def moveSelection(self,idx=0):
112 if self.instance is not None:
113 self.instance.moveSelectionTo(idx)
115 class NFIDownload(Screen):
119 <screen name="NFIDownload" position="90,95" size="560,420" title="Image download utility">
120 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" zPosition="0" size="140,40" transparent="1" alphatest="on" />
121 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" zPosition="0" size="140,40" transparent="1" alphatest="on" />
122 <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" zPosition="0" size="140,40" transparent="1" alphatest="on" />
123 <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" zPosition="0" size="140,40" transparent="1" alphatest="on" />
124 <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" />
125 <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" />
126 <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" />
127 <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" />
129 <widget source="label_top" render="Label" position="10,44" size="240,20" font="Regular;16" />
130 <widget name="feedlist" position="10,66" size="250,222" scrollbarMode="showOnDemand" />
131 <widget name="destlist" position="0,66" size="260,222" scrollbarMode="showOnDemand" />
133 <widget source="label_bottom" render="Label" position="10,312" size="240,18" font="Regular;16"/>
134 <widget source="path_bottom" render="Label" position="10,330" size="250,42" font="Regular;18" />
136 <widget source="infolabel" render="Label" position="270,44" size="280,284" font="Regular;16" />
137 <widget source="job_progressbar" render="Progress" position="10,374" size="540,26" borderWidth="1" backgroundColor="#254f7497" />
138 <widget source="job_progresslabel" render="Label" position="130,378" zPosition="2" font="Regular;18" halign="center" transparent="1" size="300,22" foregroundColor="#000000" />
139 <widget source="statusbar" render="Label" position="10,404" size="540,16" font="Regular;16" foregroundColor="#cccccc" />
142 def __init__(self, session, destdir="/tmp/"):
143 self.skin = NFIDownload.skin
144 Screen.__init__(self, session)
146 self["job_progressbar"] = Progress()
147 self["job_progresslabel"] = StaticText()
149 self["infolabel"] = StaticText()
150 self["statusbar"] = StaticText()
151 self["label_top"] = StaticText()
152 self["label_bottom"] = StaticText()
153 self["path_bottom"] = StaticText()
155 self["key_green"] = StaticText()
156 self["key_yellow"] = StaticText()
157 self["key_blue"] = StaticText()
159 self["key_red"] = StaticText()
161 self["feedlist"] = Feedlist([0,(eListboxPythonMultiContent.TYPE_TEXT, 0, 0,250, 30, 0, RT_HALIGN_LEFT|RT_VALIGN_CENTER, "feed not available")])
162 self["destlist"] = FileList(destdir, showDirectories = True, showFiles = False)
163 self["destlist"].hide()
165 self.download_container = eConsoleAppContainer()
171 self.box = HardwareInfo().get_device_name()
172 self.feed_base = "http://www.dreamboxupdate.com/opendreambox/1.5/%s/images/" % self.box
173 self.nfi_filter = "" # "release" # only show NFIs containing this string, or all if ""
174 self.wizard_mode = False
176 self["actions"] = ActionMap(["OkCancelActions", "ColorActions", "DirectionActions", "EPGSelectActions"],
178 "cancel": self.closeCB,
180 "green": self.nfi_download,
181 "yellow": self.switchList,
182 "blue": self.askCreateUSBstick,
183 "prevBouquet": self.switchList,
184 "nextBouquet": self.switchList,
189 "upRepeated": self.up,
190 "downRepeated": self.down,
196 def downloading(self, state=True):
198 self["key_red"].text = _("Cancel")
199 self["key_green"].text = ""
200 self["key_yellow"].text = ""
201 self["key_blue"].text = ""
204 self["key_red"].text = _("Exit")
205 if self["feedlist"].isValid():
206 self["key_green"].text = (_("Download"))
207 if self.focus is self.LIST_SOURCE:
208 self["key_yellow"].text = (_("Change dir."))
210 self["key_yellow"].text = (_("Select image"))
211 self["key_blue"].text = (_("USB stick wizard"))
213 def switchList(self,to_where=None):
214 if self.download or not self["feedlist"].isValid():
217 self["job_progressbar"].value = 0
218 self["job_progresslabel"].text = ""
221 if self.focus is self.LIST_SOURCE:
222 to_where = self.LIST_DEST
223 if self.focus is self.LIST_DEST:
224 to_where = self.LIST_SOURCE
226 if to_where is self.LIST_DEST:
227 self.focus = self.LIST_DEST
228 self["statusbar"].text = _("Please select target directory or medium")
229 self["label_top"].text = _("choose destination directory")+":"
230 self["feedlist"].hide()
231 self["destlist"].show()
232 self["label_bottom"].text = _("Selected source image")+":"
233 self["path_bottom"].text = str(self["feedlist"].getNFIname())
234 self["key_yellow"].text = (_("Select image"))
236 elif to_where is self.LIST_SOURCE:
237 self.focus = self.LIST_SOURCE
238 self["statusbar"].text = _("Please choose .NFI image file from feed server to download")
239 self["label_top"].text = _("select image from server")+":"
240 self["feedlist"].show()
241 self["destlist"].hide()
242 self["label_bottom"].text = _("Destination directory")+":"
243 self["path_bottom"].text = str(self["destlist"].getCurrentDirectory())
244 self["key_yellow"].text = (_("Change dir."))
249 if self.focus is self.LIST_SOURCE:
250 self["feedlist"].up()
252 if self.focus is self.LIST_DEST:
253 self["destlist"].up()
258 if self.focus is self.LIST_SOURCE:
259 self["feedlist"].down()
261 if self.focus is self.LIST_DEST:
262 self["destlist"].down()
267 if self.focus is self.LIST_SOURCE:
268 self["feedlist"].pageUp()
270 if self.focus is self.LIST_DEST:
271 self["destlist"].pageUp()
276 if self.focus is self.LIST_SOURCE:
277 self["feedlist"].pageDown()
279 if self.focus is self.LIST_DEST:
280 self["destlist"].pageDown()
285 if self.focus is self.LIST_DEST:
286 if self["destlist"].canDescent():
287 self["destlist"].descent()
289 def feed_download(self):
290 self.downloading(True)
291 self.download = self.feed_download
292 client.getPage(self.feed_base).addCallback(self.feed_finished).addErrback(self.feed_failed)
294 def feed_failed(self, failure_instance):
295 print "[feed_failed] " + str(failure_instance)
296 self["infolabel"].text = _("Could not connect to Dreambox .NFI Image Feed Server:") + "\n" + failure_instance.getErrorMessage() + "\n\n" + _("Please check your network settings!")
297 self.downloading(False)
299 def feed_finished(self, feedhtml):
300 print "[feed_finished] " + str(feedhtml)
301 self.downloading(False)
302 fileresultmask = re.compile("<a href=[\'\"](?P<url>.*?)[\'\"]>(?P<name>.*?.nfi)</a>", re.DOTALL)
303 searchresults = fileresultmask.finditer(feedhtml)
306 for x in searchresults:
308 if url[0:7] != "http://":
309 url = self.feed_base + x.group("url")
310 name = x.group("name")
311 if name.find(self.nfi_filter) > -1:
312 entry = [[name, url],(eListboxPythonMultiContent.TYPE_TEXT, 0, 0,250, 30, 0, RT_HALIGN_LEFT|RT_VALIGN_CENTER, name)]
313 print "adding to feedlist: " + str(entry)
314 fileresultlist.append(entry)
316 print "NOT adding to feedlist: " + name
317 self["feedlist"].l.setList(fileresultlist)
318 self["feedlist"].moveSelection(0)
320 if len(fileresultlist) > 0:
321 self.switchList(self.LIST_SOURCE)
324 self["infolabel"].text = _("Cannot parse feed directory")
326 def nfo_download(self):
327 print "[check_for_NFO]"
328 if self["feedlist"].isValid():
329 print "nfiname: " + self["feedlist"].getNFIname()
330 self["job_progressbar"].value = 0
331 self["job_progresslabel"].text = ""
332 if self["feedlist"].getNFIurl() is None:
333 self["key_green"].text = ""
335 self["key_green"].text = _("Download")
336 nfourl = self["feedlist"].getNFOurl()
337 print "downloading " + nfourl
338 self.download = self.nfo_download
339 self.downloading(True)
340 client.getPage(nfourl).addCallback(self.nfo_finished).addErrback(self.nfo_failed)
341 self["statusbar"].text = ("Downloading image description...")
343 def nfo_failed(self, failure_instance):
344 print "[nfo_failed] " + str(failure_instance)
345 self["infolabel"].text = _("No details for this image file") + "\n" + self["feedlist"].getNFIname()
346 self["statusbar"].text = ""
347 self.nfofilename = ""
349 self.downloading(False)
351 def nfo_finished(self,nfodata=""):
352 print "[nfo_finished] " + str(nfodata)
353 self.downloading(False)
356 self.nfofilename = self["destlist"].getCurrentDirectory() + '/' + self["feedlist"].getNFOname()
357 self["infolabel"].text = self.nfo
359 self.nfofilename = ""
360 self["infolabel"].text = _("No details for this image file")
361 self["statusbar"].text = ""
363 def nfi_download(self):
364 if self["destlist"].getCurrentDirectory() is None:
365 self.switchList(self.LIST_TARGET)
366 if self["feedlist"].isValid():
367 url = self["feedlist"].getNFIurl()
368 self.nfilocal = self["destlist"].getCurrentDirectory()+'/'+self["feedlist"].getNFIname()
369 print "[nfi_download] downloading %s to %s" % (url, self.nfilocal)
370 self.download = downloadWithProgress(url,self.nfilocal)
371 self.download.addProgress(self.nfi_progress)
372 self["job_progressbar"].range = 1000
373 self.download.start().addCallback(self.nfi_finished).addErrback(self.nfi_failed)
374 self.downloading(True)
376 def nfi_progress(self, recvbytes, totalbytes):
377 #print "[update_progress] recvbytes=%d, totalbytes=%d" % (recvbytes, totalbytes)
378 self["job_progressbar"].value = int(1000*recvbytes/float(totalbytes))
379 self["job_progresslabel"].text = "%d of %d kBytes (%.2f%%)" % (recvbytes/1024, totalbytes/1024, 100*recvbytes/float(totalbytes))
381 def nfi_failed(self, failure_instance=None, error_message=""):
382 if error_message == "" and failure_instance is not None:
383 error_message = failure_instance.getErrorMessage()
384 print "[nfi_failed] " + error_message
385 if fileExists(self["destlist"].getCurrentDirectory()+'/'+self["feedlist"].getNFIname()):
386 message = "%s %s\n%s" % (_(".NFI Download failed:"), error_message, _("Remove the incomplete .NFI file?"))
387 self.session.openWithCallback(self.nfi_remove, MessageBox, message, MessageBox.TYPE_YESNO)
389 message = "%s %s" % (_(".NFI Download failed:"),error_message)
390 self.session.open(MessageBox, message, MessageBox.TYPE_ERROR)
391 self.downloading(False)
393 def nfi_finished(self, string=""):
394 print "[nfi_finished] " + str(string)
396 self.nfofilename = self["destlist"].getCurrentDirectory() + '/' + self["feedlist"].getNFOname()
397 nfofd = open(self.nfofilename, "w")
399 nfofd.write(self.nfo)
402 print "couldn't save nfo file " + self.nfofilename
404 pos = self.nfo.find("MD5:")
405 if pos > 0 and len(self.nfo) >= pos+5+32:
406 self["statusbar"].text = ("Please wait for md5 signature verification...")
408 md5 = self.nfo[pos+5:pos+5+32] + " " + self.nfilocal
410 self.download_container.setCWD(self["destlist"].getCurrentDirectory())
411 self.download_container.appClosed.append(self.md5finished)
412 self.download_container.execute(cmd)
413 self.download_container.write(md5)
414 self.download_container.dataSent.append(self.md5ready)
416 self["statusbar"].text = "Download completed."
417 self.downloading(False)
419 self["statusbar"].text = "Download completed."
420 self.downloading(False)
424 def md5ready(self, retval):
425 self.download_container.sendEOF()
427 def md5finished(self, retval):
428 print "[md5finished]: " + str(retval)
429 self.download_container.appClosed.remove(self.md5finished)
431 self.downloading(False)
435 self["statusbar"].text = _(".NFI file passed md5sum signature check. You can safely flash this image!")
436 self.switchList(self.LIST_SOURCE)
438 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)
440 def nfi_remove(self, answer):
441 self.downloading(False)
443 nfifilename = self["destlist"].getCurrentDirectory()+'/'+self["feedlist"].getNFIname()
444 if fileExists(self.nfofilename):
445 remove(self.nfofilename)
446 if fileExists(nfifilename):
448 self.switchList(self.LIST_SOURCE)
450 def askCreateUSBstick(self):
452 self.imagefilename = "/tmp/nfiflash_" + self.box + ".img"
453 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.")
454 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)
456 def flasherdownload_query(self, answer):
458 self.downloading(False)
459 self.switchList(self.LIST_SOURCE)
461 #url = self.feed_base + "/nfiflasher_" + self.box + ".tar.bz2"
462 url = "http://www.dreamboxupdate.com/download/opendreambox/dreambox-nfiflasher-%s.tar.bz2" % self.box
463 localfile = "/tmp/nfiflasher_image.tar.bz2"
464 print "[flasherdownload_query] downloading %s to %s" % (url, localfile)
465 self["statusbar"].text = ("Downloading %s..." % url)
466 self.download = downloadWithProgress(url,localfile)
467 self.download.addProgress(self.nfi_progress)
468 self["job_progressbar"].range = 1000
469 self.download.start().addCallback(self.flasherdownload_finished).addErrback(self.flasherdownload_failed)
471 def flasherdownload_failed(self, failure_instance=None, error_message=""):
472 if error_message == "" and failure_instance is not None:
473 error_message = failure_instance.getErrorMessage()
474 print "[flasherdownload_failed] " + error_message
475 message = "%s %s" % (_("Download of USB flasher boot image failed: "),error_message)
476 self.session.open(MessageBox, message, MessageBox.TYPE_ERROR)
477 self.remove_img(True)
479 def flasherdownload_finished(self, string=""):
480 print "[flasherdownload_finished] " + str(string)
481 self.container = eConsoleAppContainer()
482 self.container.appClosed.append(self.umount_finished)
483 self.container.dataAvail.append(self.tool_avail)
486 from os import listdir
487 for device in listdir("/dev"):
488 if device[:2] == "sd" and device[-1:].isdigit():
489 umountdevs += "/dev/"+device
490 self.cmd = "umount " + umountdevs
491 print "executing " + self.cmd
492 self.container.execute(self.cmd)
494 def tool_avail(self, string):
495 print "[tool_avail]" + string
496 self.taskstring += string
498 def umount_finished(self, retval):
499 self.container.appClosed.remove(self.umount_finished)
500 self.container.appClosed.append(self.dmesg_cleared)
502 self.cmd = "dmesg -c"
503 print "executing " + self.cmd
504 self.container.execute(self.cmd)
506 def dmesg_cleared(self, answer):
507 self.container.appClosed.remove(self.dmesg_cleared)
508 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)
509 hotplugNotifier.append(self.hotplugCB)
511 def hotplugCB(self, dev, action):
512 print "[hotplugCB]", dev, action
513 if dev.startswith("sd") and action == "add":
515 hotplugNotifier.remove(self.hotplugCB)
516 self.container.appClosed.append(self.dmesg_scanned)
519 print "executing " + self.cmd
520 self.container.execute(self.cmd)
522 def dmesg_scanned(self, retval):
523 self.container.appClosed.remove(self.dmesg_scanned)
524 dmesg_lines = self.taskstring.splitlines()
525 self.devicetext = None
526 self.stickdevice = None
527 for i, line in enumerate(dmesg_lines):
528 if line.find("usb-storage: waiting for device") != -1 and len(dmesg_lines) > i+3:
529 self.devicetext = dmesg_lines[i+1].lstrip()+"\n"+dmesg_lines[i+3]
530 elif line.find("/dev/scsi/host") != -1:
531 self.stickdevice = line.split(":",1)[0].lstrip()
533 if retval != 0 or self.devicetext is None or self.stickdevice is None:
534 self.session.openWithCallback(self.remove_img, MessageBox, _("No useable USB stick found"), MessageBox.TYPE_ERROR)
536 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)
538 def fdisk_query(self, answer):
539 if answer == True and self.stickdevice:
540 self["statusbar"].text = ("Partitioning USB stick...")
541 self["job_progressbar"].range = 1000
542 self["job_progressbar"].value = 100
543 self["job_progresslabel"].text = "5.00%"
545 self.container.appClosed.append(self.fdisk_finished)
546 self.container.execute("fdisk " + self.stickdevice + "/disc")
547 self.container.write("d\nn\np\n1\n\n\nt\n6\nw\n")
548 self.delayTimer = eTimer()
549 self.delayTimer.callback.append(self.progress_increment)
550 self.delayTimer.start(105, False)
552 self.remove_img(True)
554 def fdisk_finished(self, retval):
555 self.container.appClosed.remove(self.fdisk_finished)
556 self.delayTimer.stop()
558 if fileExists(self.imagefilename):
560 self["job_progressbar"].value = 700
562 self["statusbar"].text = ("Decompressing USB stick flasher boot image...")
564 self.container.appClosed.append(self.tar_finished)
565 self.container.setCWD("/tmp")
566 self.cmd = "tar -xjvf nfiflasher_image.tar.bz2"
567 self.container.execute(self.cmd)
568 print "executing " + self.cmd
569 self.delayTimer = eTimer()
570 self.delayTimer.callback.append(self.progress_increment)
571 self.delayTimer.start(105, False)
573 print "fdisk failed: " + str(retval)
574 self.session.openWithCallback(self.remove_img, MessageBox, ("fdisk " + _("failed") + ":\n" + str(self.taskstring)), MessageBox.TYPE_ERROR)
576 def progress_increment(self):
577 newval = int(self["job_progressbar"].value) + 1
579 self["job_progressbar"].value = newval
580 self["job_progresslabel"].text = "%.2f%%" % (newval/10.0)
582 def tar_finished(self, retval):
583 self.delayTimer.stop()
584 if len(self.container.appClosed) > 0:
585 self.container.appClosed.remove(self.tar_finished)
587 self.imagefilename = "/tmp/nfiflash_" + self.box + ".img"
588 self["statusbar"].text = ("Copying USB flasher boot image to stick...")
590 self.container.appClosed.append(self.dd_finished)
591 self.cmd = "dd if=%s of=%s" % (self.imagefilename,self.stickdevice+"/part1")
592 self.container.execute(self.cmd)
593 print "executing " + self.cmd
594 self.delayTimer = eTimer()
595 self.delayTimer.callback.append(self.progress_increment)
596 self.delayTimer.start(105, False)
598 self.session.openWithCallback(self.remove_img, MessageBox, (self.cmd + " " + _("failed") + ":\n" + str(self.taskstring)), MessageBox.TYPE_ERROR)
600 def dd_finished(self, retval):
601 self.delayTimer.stop()
602 self.container.appClosed.remove(self.dd_finished)
603 self.downloading(False)
605 self["job_progressbar"].value = 950
606 self["job_progresslabel"].text = "95.00%"
607 self["statusbar"].text = ("Remounting stick partition...")
609 self.container.appClosed.append(self.mount_finished)
610 self.cmd = "mount %s /mnt/usb -o rw,sync" % (self.stickdevice+"/part1")
611 self.container.execute(self.cmd)
612 print "executing " + self.cmd
614 self.session.openWithCallback(self.remove_img, MessageBox, (self.cmd + " " + _("failed") + ":\n" + str(self.taskstring)), MessageBox.TYPE_ERROR)
616 def mount_finished(self, retval):
617 self.container.dataAvail.remove(self.tool_avail)
618 self.container.appClosed.remove(self.mount_finished)
620 self["job_progressbar"].value = 1000
621 self["job_progresslabel"].text = "100.00%"
622 self["statusbar"].text = (".NFI Flasher bootable USB stick successfully created.")
623 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)
624 self["destlist"].changeDir("/mnt/usb")
626 self.session.openWithCallback(self.flasherFinishedCB, MessageBox, (self.cmd + " " + _("failed") + ":\n" + str(self.taskstring)), MessageBox.TYPE_ERROR)
627 self.remove_img(True)
629 def remove_img(self, answer):
630 if fileExists("/tmp/nfiflasher_image.tar.bz2"):
631 remove("/tmp/nfiflasher_image.tar.bz2")
632 if fileExists(self.imagefilename):
633 remove(self.imagefilename)
634 self.downloading(False)
635 self.switchList(self.LIST_SOURCE)
637 def flasherFinishedCB(self, answer):
639 self.wizard_mode = True
640 self["feedlist"].moveSelection(0)
641 self["path_bottom"].text = str(self["destlist"].getCurrentDirectory())
645 def configBackup(self):
646 self.session.openWithCallback(self.runBackup, MessageBox, _("The wizard can backup your current settings. Do you want to do a backup now?"))
648 def runBackup(self, result=None):
649 from Tools.Directories import createDir, isMount, pathExists
650 from time import localtime
651 from datetime import date
652 from Screens.Console import Console
654 if isMount("/mnt/usb/"):
655 if (pathExists("/mnt/usb/backup") == False):
656 createDir("/mnt/usb/backup", True)
658 dt = date(d.tm_year, d.tm_mon, d.tm_mday)
659 self.backup_file = "backup/" + str(dt) + "_settings_backup.tar.gz"
660 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)
662 self.backup_file = None
663 self.backup_finished(skipped=True)
665 def backup_finished(self, skipped=False):
667 wizardfd = open("/mnt/usb/wizard.nfo", "w")
669 wizardfd.write("image: "+self["feedlist"].getNFIname()+'\n')
670 wizardfd.write("configuration: "+self.backup_file+'\n')
672 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)
677 #self.nfi_failed(None, "Cancelled by user request")
678 self.downloading(False)
682 def main(session, **kwargs):
683 session.open(NFIDownload,"/home/root")
685 def filescan_open(list, session, **kwargs):
686 dev = "/dev/" + (list[0].path).rsplit('/',1)[0][7:]
687 print "mounting device " + dev + " to /mnt/usb..."
688 system("mount "+dev+" /mnt/usb/ -o rw,sync")
689 session.open(NFIDownload,"/mnt/usb/")
691 def filescan(**kwargs):
692 from Components.Scanner import Scanner, ScanPath
694 Scanner(mimetypes = ["application/x-dream-image"],
697 ScanPath(path = "", with_subdirs = False),
700 description = (_("Download .NFI-Files for USB-Flasher")+"..."),
701 openfnc = filescan_open, )