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 Tools.Downloader import downloadWithProgress
20 from twisted.web import client
21 from twisted.internet import reactor, defer
22 from twisted.python import failure
23 from Plugins.SystemPlugins.Hotplug.plugin import hotplugNotifier
25 class UserRequestedCancel(Exception):
28 class Feedlist(MenuList):
29 def __init__(self, list=[], enableWrapAround = False):
30 MenuList.__init__(self, list, enableWrapAround, eListboxPythonMultiContent)
31 self.l.setFont(0, gFont("Regular", 16))
32 self.l.setItemHeight(22)
36 self.l.setList(self.list)
39 l = self.l.getCurrentSelection()
43 l = self.l.getCurrentSelection()
47 l = self.l.getCurrentSelection()
48 return l and l[0][0][:-3]+"nfo"
51 l = self.l.getCurrentSelection()
52 return l and l[0][1][:-3]+"nfo"
55 l = self.l.getCurrentSelection()
61 def moveSelection(self,idx=0):
62 if self.instance is not None:
63 self.instance.moveSelectionTo(idx)
65 class NFIDownload(Screen):
69 <screen name="NFIDownload" position="90,95" size="560,420" title="Image download utility">
70 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" zPosition="0" size="140,40" transparent="1" alphatest="on" />
71 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" zPosition="0" size="140,40" transparent="1" alphatest="on" />
72 <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" zPosition="0" size="140,40" transparent="1" alphatest="on" />
73 <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" zPosition="0" size="140,40" transparent="1" alphatest="on" />
74 <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" />
75 <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" />
76 <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" />
77 <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" />
79 <widget source="label_top" render="Label" position="10,44" size="240,20" font="Regular;16" />
80 <widget name="feedlist" position="10,66" size="250,222" scrollbarMode="showOnDemand" />
81 <widget name="destlist" position="0,66" size="260,222" scrollbarMode="showOnDemand" />
83 <widget source="label_bottom" render="Label" position="10,312" size="240,18" font="Regular;16"/>
84 <widget source="path_bottom" render="Label" position="10,330" size="250,42" font="Regular;18" />
86 <widget source="infolabel" render="Label" position="270,44" size="280,284" font="Regular;16" />
87 <widget source="job_progressbar" render="Progress" position="10,374" size="540,26" borderWidth="1" backgroundColor="#254f7497" />
88 <widget source="job_progresslabel" render="Label" position="130,378" zPosition="2" font="Regular;18" halign="center" transparent="1" size="300,22" foregroundColor="#000000" />
89 <widget source="statusbar" render="Label" position="10,404" size="540,16" font="Regular;16" foregroundColor="#cccccc" />
92 def __init__(self, session, destdir="/tmp/"):
93 self.skin = NFIDownload.skin
94 Screen.__init__(self, session)
96 self["job_progressbar"] = Progress()
97 self["job_progresslabel"] = StaticText()
99 self["infolabel"] = StaticText()
100 self["statusbar"] = StaticText()
101 self["label_top"] = StaticText()
102 self["label_bottom"] = StaticText()
103 self["path_bottom"] = StaticText()
105 self["key_green"] = StaticText()
106 self["key_yellow"] = StaticText()
107 self["key_blue"] = StaticText()
109 self["key_red"] = StaticText()
111 self["feedlist"] = Feedlist([0,(eListboxPythonMultiContent.TYPE_TEXT, 0, 0,250, 30, 0, RT_HALIGN_LEFT|RT_VALIGN_CENTER, "feed not available")])
112 self["destlist"] = FileList(destdir, showDirectories = True, showFiles = False)
113 self["destlist"].hide()
115 self.download_container = eConsoleAppContainer()
121 self.box = HardwareInfo().get_device_name()
122 self.feed_base = "http://www.dreamboxupdate.com/opendreambox/1.5/%s/images/" % self.box
123 self.nfi_filter = "" # "release" # only show NFIs containing this string, or all if ""
124 self.wizard_mode = False
126 self["actions"] = ActionMap(["OkCancelActions", "ColorActions", "DirectionActions", "EPGSelectActions"],
128 "cancel": self.closeCB,
130 "green": self.nfi_download,
131 "yellow": self.switchList,
132 "blue": self.askCreateUSBstick,
133 "prevBouquet": self.switchList,
134 "nextBouquet": self.switchList,
139 "upRepeated": self.up,
140 "downRepeated": self.down,
146 def downloading(self, state=True):
148 self["key_red"].text = _("Cancel")
149 self["key_green"].text = ""
150 self["key_yellow"].text = ""
151 self["key_blue"].text = ""
154 self["key_red"].text = _("Exit")
155 if self["feedlist"].isValid():
156 self["key_green"].text = (_("Download"))
157 if self.focus is self.LIST_SOURCE:
158 self["key_yellow"].text = (_("Change dir."))
160 self["key_yellow"].text = (_("Select image"))
161 self["key_blue"].text = (_("USB stick wizard"))
163 def switchList(self,to_where=None):
164 if self.download or not self["feedlist"].isValid():
167 self["job_progressbar"].value = 0
168 self["job_progresslabel"].text = ""
171 if self.focus is self.LIST_SOURCE:
172 to_where = self.LIST_DEST
173 if self.focus is self.LIST_DEST:
174 to_where = self.LIST_SOURCE
176 if to_where is self.LIST_DEST:
177 self.focus = self.LIST_DEST
178 self["statusbar"].text = _("Please select target directory or medium")
179 self["label_top"].text = _("choose destination directory")+":"
180 self["feedlist"].hide()
181 self["destlist"].show()
182 self["label_bottom"].text = _("Selected source image")+":"
183 self["path_bottom"].text = str(self["feedlist"].getNFIname())
184 self["key_yellow"].text = (_("Select image"))
186 elif to_where is self.LIST_SOURCE:
187 self.focus = self.LIST_SOURCE
188 self["statusbar"].text = _("Please choose .NFI image file from feed server to download")
189 self["label_top"].text = _("select image from server")+":"
190 self["feedlist"].show()
191 self["destlist"].hide()
192 self["label_bottom"].text = _("Destination directory")+":"
193 self["path_bottom"].text = str(self["destlist"].getCurrentDirectory())
194 self["key_yellow"].text = (_("Change dir."))
199 if self.focus is self.LIST_SOURCE:
200 self["feedlist"].up()
202 if self.focus is self.LIST_DEST:
203 self["destlist"].up()
208 if self.focus is self.LIST_SOURCE:
209 self["feedlist"].down()
211 if self.focus is self.LIST_DEST:
212 self["destlist"].down()
217 if self.focus is self.LIST_SOURCE:
218 self["feedlist"].pageUp()
220 if self.focus is self.LIST_DEST:
221 self["destlist"].pageUp()
226 if self.focus is self.LIST_SOURCE:
227 self["feedlist"].pageDown()
229 if self.focus is self.LIST_DEST:
230 self["destlist"].pageDown()
235 if self.focus is self.LIST_DEST:
236 if self["destlist"].canDescent():
237 self["destlist"].descent()
239 def feed_download(self):
240 self.downloading(True)
241 self.download = self.feed_download
242 client.getPage(self.feed_base).addCallback(self.feed_finished).addErrback(self.feed_failed)
244 def feed_failed(self, failure_instance):
245 print "[feed_failed] " + str(failure_instance)
246 self["infolabel"].text = _("Could not connect to Dreambox .NFI Image Feed Server:") + "\n" + failure_instance.getErrorMessage() + "\n\n" + _("Please check your network settings!")
247 self.downloading(False)
249 def feed_finished(self, feedhtml):
250 print "[feed_finished] " + str(feedhtml)
251 self.downloading(False)
252 fileresultmask = re.compile("<a href=[\'\"](?P<url>.*?)[\'\"]>(?P<name>.*?.nfi)</a>", re.DOTALL)
253 searchresults = fileresultmask.finditer(feedhtml)
256 for x in searchresults:
258 if url[0:7] != "http://":
259 url = self.feed_base + x.group("url")
260 name = x.group("name")
261 if name.find(self.nfi_filter) > -1:
262 entry = [[name, url],(eListboxPythonMultiContent.TYPE_TEXT, 0, 0,250, 30, 0, RT_HALIGN_LEFT|RT_VALIGN_CENTER, name)]
263 print "adding to feedlist: " + str(entry)
264 fileresultlist.append(entry)
266 print "NOT adding to feedlist: " + name
267 self["feedlist"].l.setList(fileresultlist)
268 self["feedlist"].moveSelection(0)
270 if len(fileresultlist) > 0:
271 self.switchList(self.LIST_SOURCE)
274 self["infolabel"].text = _("Cannot parse feed directory")
276 def nfo_download(self):
277 print "[check_for_NFO]"
278 if self["feedlist"].isValid():
279 print "nfiname: " + self["feedlist"].getNFIname()
280 self["job_progressbar"].value = 0
281 self["job_progresslabel"].text = ""
282 if self["feedlist"].getNFIurl() is None:
283 self["key_green"].text = ""
285 self["key_green"].text = _("Download")
286 nfourl = self["feedlist"].getNFOurl()
287 print "downloading " + nfourl
288 self.download = self.nfo_download
289 self.downloading(True)
290 client.getPage(nfourl).addCallback(self.nfo_finished).addErrback(self.nfo_failed)
291 self["statusbar"].text = ("Downloading image description...")
293 def nfo_failed(self, failure_instance):
294 print "[nfo_failed] " + str(failure_instance)
295 self["infolabel"].text = _("No details for this image file") + "\n" + self["feedlist"].getNFIname()
296 self["statusbar"].text = ""
297 self.nfofilename = ""
299 self.downloading(False)
301 def nfo_finished(self,nfodata=""):
302 print "[nfo_finished] " + str(nfodata)
303 self.downloading(False)
306 self.nfofilename = self["destlist"].getCurrentDirectory() + '/' + self["feedlist"].getNFOname()
307 self["infolabel"].text = self.nfo
309 self.nfofilename = ""
310 self["infolabel"].text = _("No details for this image file")
311 self["statusbar"].text = ""
313 def nfi_download(self):
314 if self["destlist"].getCurrentDirectory() is None:
315 self.switchList(self.LIST_TARGET)
316 if self["feedlist"].isValid():
317 url = self["feedlist"].getNFIurl()
318 self.nfilocal = self["destlist"].getCurrentDirectory()+'/'+self["feedlist"].getNFIname()
319 print "[nfi_download] downloading %s to %s" % (url, self.nfilocal)
320 self.download = downloadWithProgress(url,self.nfilocal)
321 self.download.addProgress(self.nfi_progress)
322 self["job_progressbar"].range = 1000
323 self.download.start().addCallback(self.nfi_finished).addErrback(self.nfi_failed)
324 self.downloading(True)
326 def nfi_progress(self, recvbytes, totalbytes):
327 #print "[update_progress] recvbytes=%d, totalbytes=%d" % (recvbytes, totalbytes)
328 self["job_progressbar"].value = int(1000*recvbytes/float(totalbytes))
329 self["job_progresslabel"].text = "%d of %d kBytes (%.2f%%)" % (recvbytes/1024, totalbytes/1024, 100*recvbytes/float(totalbytes))
331 def nfi_failed(self, failure_instance=None, error_message=""):
332 if error_message == "" and failure_instance is not None:
333 error_message = failure_instance.getErrorMessage()
334 print "[nfi_failed] " + error_message
335 if fileExists(self["destlist"].getCurrentDirectory()+'/'+self["feedlist"].getNFIname()):
336 message = "%s %s\n%s" % (_(".NFI Download failed:"), error_message, _("Remove the incomplete .NFI file?"))
337 self.session.openWithCallback(self.nfi_remove, MessageBox, message, MessageBox.TYPE_YESNO)
339 message = "%s %s" % (_(".NFI Download failed:"),error_message)
340 self.session.open(MessageBox, message, MessageBox.TYPE_ERROR)
341 self.downloading(False)
343 def nfi_finished(self, string=""):
344 print "[nfi_finished] " + str(string)
346 self.nfofilename = self["destlist"].getCurrentDirectory() + '/' + self["feedlist"].getNFOname()
347 nfofd = open(self.nfofilename, "w")
349 nfofd.write(self.nfo)
352 print "couldn't save nfo file " + self.nfofilename
354 pos = self.nfo.find("MD5:")
355 if pos > 0 and len(self.nfo) >= pos+5+32:
356 self["statusbar"].text = ("Please wait for md5 signature verification...")
358 md5 = self.nfo[pos+5:pos+5+32] + " " + self.nfilocal
360 self.download_container.setCWD(self["destlist"].getCurrentDirectory())
361 self.download_container.appClosed.append(self.md5finished)
362 self.download_container.execute(cmd)
363 self.download_container.write(md5)
364 self.download_container.dataSent.append(self.md5ready)
366 self["statusbar"].text = "Download completed."
367 self.downloading(False)
369 self["statusbar"].text = "Download completed."
370 self.downloading(False)
374 def md5ready(self, retval):
375 self.download_container.sendEOF()
377 def md5finished(self, retval):
378 print "[md5finished]: " + str(retval)
379 self.download_container.appClosed.remove(self.md5finished)
381 self.downloading(False)
385 self["statusbar"].text = _(".NFI file passed md5sum signature check. You can safely flash this image!")
386 self.switchList(self.LIST_SOURCE)
388 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)
390 def nfi_remove(self, answer):
391 self.downloading(False)
393 nfifilename = self["destlist"].getCurrentDirectory()+'/'+self["feedlist"].getNFIname()
394 if fileExists(self.nfofilename):
395 remove(self.nfofilename)
396 if fileExists(nfifilename):
398 self.switchList(self.LIST_SOURCE)
400 def askCreateUSBstick(self):
402 self.imagefilename = "/tmp/nfiflash_" + self.box + ".img"
403 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.")
404 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)
406 def flasherdownload_query(self, answer):
408 self.downloading(False)
409 self.switchList(self.LIST_SOURCE)
411 #url = self.feed_base + "/nfiflasher_" + self.box + ".tar.bz2"
412 url = "http://www.dreamboxupdate.com/download/opendreambox/dreambox-nfiflasher-%s.tar.bz2" % self.box
413 localfile = "/tmp/nfiflasher_image.tar.bz2"
414 print "[flasherdownload_query] downloading %s to %s" % (url, localfile)
415 self["statusbar"].text = ("Downloading %s..." % url)
416 self.download = downloadWithProgress(url,localfile)
417 self.download.addProgress(self.nfi_progress)
418 self["job_progressbar"].range = 1000
419 self.download.start().addCallback(self.flasherdownload_finished).addErrback(self.flasherdownload_failed)
421 def flasherdownload_failed(self, failure_instance=None, error_message=""):
422 if error_message == "" and failure_instance is not None:
423 error_message = failure_instance.getErrorMessage()
424 print "[flasherdownload_failed] " + error_message
425 message = "%s %s" % (_("Download of USB flasher boot image failed: "),error_message)
426 self.session.open(MessageBox, message, MessageBox.TYPE_ERROR)
427 self.remove_img(True)
429 def flasherdownload_finished(self, string=""):
430 print "[flasherdownload_finished] " + str(string)
431 self.container = eConsoleAppContainer()
432 self.container.appClosed.append(self.umount_finished)
433 self.container.dataAvail.append(self.tool_avail)
436 from os import listdir
437 for device in listdir("/dev"):
438 if device[:2] == "sd" and device[-1:].isdigit():
439 umountdevs += "/dev/"+device
440 self.cmd = "umount " + umountdevs
441 print "executing " + self.cmd
442 self.container.execute(self.cmd)
444 def tool_avail(self, string):
445 print "[tool_avail]" + string
446 self.taskstring += string
448 def umount_finished(self, retval):
449 self.container.appClosed.remove(self.umount_finished)
450 self.container.appClosed.append(self.dmesg_cleared)
452 self.cmd = "dmesg -c"
453 print "executing " + self.cmd
454 self.container.execute(self.cmd)
456 def dmesg_cleared(self, answer):
457 self.container.appClosed.remove(self.dmesg_cleared)
458 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)
459 hotplugNotifier.append(self.hotplugCB)
461 def hotplugCB(self, dev, action):
462 print "[hotplugCB]", dev, action
463 if dev.startswith("sd") and action == "add":
465 hotplugNotifier.remove(self.hotplugCB)
466 self.container.appClosed.append(self.dmesg_scanned)
469 print "executing " + self.cmd
470 self.container.execute(self.cmd)
472 def dmesg_scanned(self, retval):
473 self.container.appClosed.remove(self.dmesg_scanned)
474 dmesg_lines = self.taskstring.splitlines()
475 self.devicetext = None
476 self.stickdevice = None
477 for i, line in enumerate(dmesg_lines):
478 if line.find("usb-storage: waiting for device") != -1 and len(dmesg_lines) > i+3:
479 self.devicetext = dmesg_lines[i+1].lstrip()+"\n"+dmesg_lines[i+3]
480 elif line.find("/dev/scsi/host") != -1:
481 self.stickdevice = line.split(":",1)[0].lstrip()
483 if retval != 0 or self.devicetext is None or self.stickdevice is None:
484 self.session.openWithCallback(self.remove_img, MessageBox, _("No useable USB stick found"), MessageBox.TYPE_ERROR)
486 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)
488 def fdisk_query(self, answer):
489 if answer == True and self.stickdevice:
490 self["statusbar"].text = ("Partitioning USB stick...")
491 self["job_progressbar"].range = 1000
492 self["job_progressbar"].value = 100
493 self["job_progresslabel"].text = "5.00%"
495 self.container.appClosed.append(self.fdisk_finished)
496 self.container.execute("fdisk " + self.stickdevice + "/disc")
497 self.container.write("d\n4\nd\n3\nd\n2\nd\nn\np\n1\n\n\nt\n6\nw\n")
498 self.delayTimer = eTimer()
499 self.delayTimer.callback.append(self.progress_increment)
500 self.delayTimer.start(105, False)
502 self.remove_img(True)
504 def fdisk_finished(self, retval):
505 self.container.appClosed.remove(self.fdisk_finished)
506 self.delayTimer.stop()
508 if fileExists(self.imagefilename):
510 self["job_progressbar"].value = 700
512 self["statusbar"].text = ("Decompressing USB stick flasher boot image...")
514 self.container.appClosed.append(self.tar_finished)
515 self.container.setCWD("/tmp")
516 self.cmd = "tar -xjvf nfiflasher_image.tar.bz2"
517 self.container.execute(self.cmd)
518 print "executing " + self.cmd
519 self.delayTimer = eTimer()
520 self.delayTimer.callback.append(self.progress_increment)
521 self.delayTimer.start(105, False)
523 print "fdisk failed: " + str(retval)
524 self.session.openWithCallback(self.remove_img, MessageBox, ("fdisk " + _("failed") + ":\n" + str(self.taskstring)), MessageBox.TYPE_ERROR)
526 def progress_increment(self):
527 newval = int(self["job_progressbar"].value) + 1
529 self["job_progressbar"].value = newval
530 self["job_progresslabel"].text = "%.2f%%" % (newval/10.0)
532 def tar_finished(self, retval):
533 self.delayTimer.stop()
534 if len(self.container.appClosed) > 0:
535 self.container.appClosed.remove(self.tar_finished)
537 self.imagefilename = "/tmp/nfiflash_" + self.box + ".img"
538 self["statusbar"].text = ("Copying USB flasher boot image to stick...")
540 self.container.appClosed.append(self.dd_finished)
541 self.cmd = "dd if=%s of=%s" % (self.imagefilename,self.stickdevice+"/part1")
542 self.container.execute(self.cmd)
543 print "executing " + self.cmd
544 self.delayTimer = eTimer()
545 self.delayTimer.callback.append(self.progress_increment)
546 self.delayTimer.start(105, False)
548 self.session.openWithCallback(self.remove_img, MessageBox, (self.cmd + " " + _("failed") + ":\n" + str(self.taskstring)), MessageBox.TYPE_ERROR)
550 def dd_finished(self, retval):
551 self.delayTimer.stop()
552 self.container.appClosed.remove(self.dd_finished)
553 self.downloading(False)
555 self["job_progressbar"].value = 950
556 self["job_progresslabel"].text = "95.00%"
557 self["statusbar"].text = ("Remounting stick partition...")
559 self.container.appClosed.append(self.mount_finished)
560 self.cmd = "mount %s /mnt/usb -o rw,sync" % (self.stickdevice+"/part1")
561 self.container.execute(self.cmd)
562 print "executing " + self.cmd
564 self.session.openWithCallback(self.remove_img, MessageBox, (self.cmd + " " + _("failed") + ":\n" + str(self.taskstring)), MessageBox.TYPE_ERROR)
566 def mount_finished(self, retval):
567 self.container.dataAvail.remove(self.tool_avail)
568 self.container.appClosed.remove(self.mount_finished)
570 self["job_progressbar"].value = 1000
571 self["job_progresslabel"].text = "100.00%"
572 self["statusbar"].text = (".NFI Flasher bootable USB stick successfully created.")
573 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)
574 self["destlist"].changeDir("/mnt/usb")
576 self.session.openWithCallback(self.flasherFinishedCB, MessageBox, (self.cmd + " " + _("failed") + ":\n" + str(self.taskstring)), MessageBox.TYPE_ERROR)
577 self.remove_img(True)
579 def remove_img(self, answer):
580 if fileExists("/tmp/nfiflasher_image.tar.bz2"):
581 remove("/tmp/nfiflasher_image.tar.bz2")
582 if fileExists(self.imagefilename):
583 remove(self.imagefilename)
584 self.downloading(False)
585 self.switchList(self.LIST_SOURCE)
587 def flasherFinishedCB(self, answer):
589 self.wizard_mode = True
590 self["feedlist"].moveSelection(0)
591 self["path_bottom"].text = str(self["destlist"].getCurrentDirectory())
595 def configBackup(self):
596 self.session.openWithCallback(self.runBackup, MessageBox, _("The wizard can backup your current settings. Do you want to do a backup now?"))
598 def runBackup(self, result=None):
599 from Tools.Directories import createDir, isMount, pathExists
600 from time import localtime
601 from datetime import date
602 from Screens.Console import Console
604 if isMount("/mnt/usb/"):
605 if (pathExists("/mnt/usb/backup") == False):
606 createDir("/mnt/usb/backup", True)
608 dt = date(d.tm_year, d.tm_mon, d.tm_mday)
609 self.backup_file = "backup/" + str(dt) + "_settings_backup.tar.gz"
610 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)
612 self.backup_file = None
613 self.backup_finished(skipped=True)
615 def backup_finished(self, skipped=False):
617 wizardfd = open("/mnt/usb/wizard.nfo", "w")
619 wizardfd.write("image: "+self["feedlist"].getNFIname()+'\n')
620 wizardfd.write("configuration: "+self.backup_file+'\n')
622 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)
627 #self.nfi_failed(None, "Cancelled by user request")
628 self.downloading(False)
632 def main(session, **kwargs):
633 session.open(NFIDownload,"/home/root")
635 def filescan_open(list, session, **kwargs):
636 dev = "/dev/" + (list[0].path).rsplit('/',1)[0][7:]
637 print "mounting device " + dev + " to /mnt/usb..."
638 system("mount "+dev+" /mnt/usb/ -o rw,sync")
639 session.open(NFIDownload,"/mnt/usb/")
641 def filescan(**kwargs):
642 from Components.Scanner import Scanner, ScanPath
644 Scanner(mimetypes = ["application/x-dream-image"],
647 ScanPath(path = "", with_subdirs = False),
650 description = (_("Download .NFI-Files for USB-Flasher")+"..."),
651 openfnc = filescan_open, )