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
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;20" 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;20" 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;20" 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;20" 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 ""
174 self["actions"] = ActionMap(["OkCancelActions", "ColorActions", "DirectionActions", "EPGSelectActions"],
176 "cancel": self.closeCB,
178 "green": self.nfi_download,
179 "yellow": self.switchList,
180 "blue": self.askCreateUSBstick,
181 "prevBouquet": self.switchList,
182 "nextBouquet": self.switchList,
187 "upRepeated": self.up,
188 "downRepeated": self.down,
194 def downloading(self, state=True):
196 self["key_red"].text = _("Cancel")
197 self["key_green"].text = ""
198 self["key_yellow"].text = ""
199 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 = (_("Fix USB stick"))
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 localfile = self["destlist"].getCurrentDirectory()+'/'+self["feedlist"].getNFIname()
368 print "[nfi_download] downloading %s to %s" % (url, localfile)
369 self.download = downloadWithProgress(url,localfile)
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_failed(self, failure_instance):
393 #print "[nfi_failed] "
394 #print failure_instance
395 #if isinstance(failure_instance, Plugins.SystemPlugins.NFIFlash.plugin.UserRequestedCancel):
396 #print "is instance of Plugins.SystemPlugins.NFIFlash.plugin.UserRequestedCancel"
398 #print "not an instance of Plugins.SystemPlugins.NFIFlash.plugin.UserRequestedCancel"
400 def nfi_finished(self, string=""):
401 print "[nfi_finished] " + str(string)
403 nfofd = open(self.nfofilename, "w")
405 nfofd.write(self.nfo)
408 print "couldn't save nfo file " + self.nfofilename
410 pos = self.nfo.find("md5sum")
412 self["statusbar"].text = _("Please wait for md5 signature verification...")
413 cmd = "md5sum -cs " + self.nfofilename
415 self.download_container.setCWD(self["destlist"].getCurrentDirectory())
416 self.download_container.appClosed.get().append(self.md5finished)
417 self.download_container.execute(cmd)
419 self["statusbar"].text = "Download completed."
420 self.downloading(False)
422 self["statusbar"].text = "Download completed."
423 self.downloading(False)
425 def md5finished(self, retval):
426 print "[md5finished]: " + str(retval)
427 self.download_container.appClosed.get().remove(self.md5finished)
429 self["statusbar"].text = _(".NFI file passed md5sum signature check. You can safely flash this image!")
430 self.switchList(self.LIST_SOURCE)
431 self.downloading(False)
433 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)
435 def nfi_remove(self, answer):
436 self.downloading(False)
438 nfifilename = self["destlist"].getCurrentDirectory()+'/'+self["feedlist"].getNFIname()
439 if fileExists(self.nfofilename):
440 remove(self.nfofilename)
441 if fileExists(nfifilename):
443 self.switchList(self.LIST_SOURCE)
445 def askCreateUSBstick(self):
447 self.imagefilename = "/tmp/nfiflash_" + self.box + ".img"
448 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.")
449 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)
451 def flasherdownload_query(self, answer):
453 self.downloading(False)
454 self.switchList(self.LIST_SOURCE)
456 #url = self.feed_base + "/nfiflasher_" + self.box + ".tar.bz2"
457 url = "http://www.dreamboxupdate.com/download/opendreambox/dreambox-nfiflasher-%s.tar.bz2" % self.box
458 localfile = "/tmp/nfiflasher_image.tar.bz2"
459 print "[flasherdownload_query] downloading %s to %s" % (url, localfile)
460 self["statusbar"].text = ("Downloading %s..." % url)
461 self.download = downloadWithProgress(url,localfile)
462 self.download.addProgress(self.nfi_progress)
463 self["job_progressbar"].range = 1000
464 self.download.start().addCallback(self.flasherdownload_finished).addErrback(self.flasherdownload_failed)
466 def flasherdownload_failed(self, failure_instance=None, error_message=""):
467 if error_message == "" and failure_instance is not None:
468 error_message = failure_instance.getErrorMessage()
469 print "[flasherdownload_failed] " + error_message
470 message = "%s %s" % (_("Download of USB flasher boot image failed: "),error_message)
471 self.session.open(MessageBox, message, MessageBox.TYPE_ERROR)
472 self.remove_img(True)
474 def flasherdownload_finished(self, string=""):
475 print "[flasherdownload_finished] " + str(string)
476 self.container = eConsoleAppContainer()
477 self.container.appClosed.get().append(self.umount_finished)
478 self.container.dataAvail.get().append(self.tool_avail)
481 from os import listdir
482 for device in listdir("/dev"):
483 if device[:2] == "sd" and device[-1:].isdigit():
484 umountdevs += "/dev/"+device
485 self.cmd = "umount " + umountdevs
486 print "executing " + self.cmd
487 self.container.execute(self.cmd)
489 def tool_avail(self, string):
490 print "[tool_avail]" + string
491 self.taskstring += string
493 def umount_finished(self, retval):
494 self.container.appClosed.get().remove(self.umount_finished)
495 self.session.openWithCallback(self.dmesg_clear, MessageBox, _("To make sure you intend to do this, please remove the target USB stick now and stick it back in upon prompt. Press OK when you have taken the stick out."), MessageBox.TYPE_INFO)
497 def dmesg_clear(self, answer):
498 self.container.appClosed.get().append(self.dmesg_cleared)
500 self.cmd = "dmesg -c"
501 print "executing " + self.cmd
502 self.container.execute(self.cmd)
504 def dmesg_cleared(self, retval):
505 self.container.appClosed.get().remove(self.dmesg_cleared)
506 self.session.openWithCallback(self.stick_back_in, MessageBox, (_("Now please insert the USB stick (minimum size is 64 MB) that you want to format and use as .NFI image flasher. Press OK after you've put the stick back in.")), MessageBox.TYPE_INFO)
508 def stick_back_in(self, answer):
509 self["statusbar"].text = _("Waiting for USB stick to settle...")
510 self.delayTimer = eTimer()
511 self.delayTimer.callback.append(self.waiting_for_stick)
513 self.delayTimer.start(1000)
515 def waiting_for_stick(self):
517 self["job_progressbar"].range = 6
518 self["job_progressbar"].value = self.delayCount
519 self["job_progresslabel"].text = "-%d s" % (6-self.delayCount)
520 if self.delayCount > 5:
521 self.delayTimer.stop()
522 self.container.appClosed.get().append(self.dmesg_scanned)
525 print "executing " + self.cmd
526 self.container.execute(self.cmd)
528 def dmesg_scanned(self, retval):
529 self.container.appClosed.get().remove(self.dmesg_scanned)
530 dmesg_lines = self.taskstring.splitlines()
531 self.devicetext = None
532 self.stickdevice = None
533 for i, line in enumerate(dmesg_lines):
534 if line.find("usb-storage: waiting for device") != -1 and len(dmesg_lines) > i+3:
535 self.devicetext = dmesg_lines[i+1].lstrip()+"\n"+dmesg_lines[i+3]
536 elif line.find("/dev/scsi/host") != -1:
537 self.stickdevice = line.split(":",1)[0].lstrip()
539 if retval != 0 or self.devicetext is None or self.stickdevice is None:
540 self.session.openWithCallback(self.remove_img, MessageBox, _("No useable USB stick found"), MessageBox.TYPE_ERROR)
542 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)
544 def fdisk_query(self, answer):
546 self["statusbar"].text = _("Partitioning USB stick...")
547 self["job_progressbar"].range = 1000
548 self["job_progressbar"].value = 100
549 self["job_progresslabel"].text = "5.00%"
551 self.container.appClosed.get().append(self.fdisk_finished)
552 self.container.execute("fdisk " + self.stickdevice + "/disc")
553 self.container.write("d\nn\np\n1\n\n\nt\n6\nw\n")
554 self.delayTimer = eTimer()
555 self.delayTimer.callback.append(self.progress_increment)
556 self.delayTimer.start(105, False)
558 self.remove_img(True)
560 def fdisk_finished(self, retval):
561 self.container.appClosed.get().remove(self.fdisk_finished)
562 self.delayTimer.stop()
564 if fileExists(self.imagefilename):
566 self["job_progressbar"].value = 700
568 self["statusbar"].text = _("Decompressing USB stick flasher boot image...")
570 self.container.appClosed.get().append(self.tar_finished)
571 self.container.setCWD("/tmp")
572 self.cmd = "tar -xjvf nfiflasher_image.tar.bz2"
573 self.container.execute(self.cmd)
574 print "executing " + self.cmd
575 self.delayTimer = eTimer()
576 self.delayTimer.callback.append(self.progress_increment)
577 self.delayTimer.start(105, False)
579 print "fdisk failed: " + str(retval)
580 self.session.openWithCallback(self.remove_img, MessageBox, ("fdisk " + _("failed") + ":\n" + str(self.taskstring)), MessageBox.TYPE_ERROR)
582 def progress_increment(self):
583 newval = int(self["job_progressbar"].value) + 1
585 self["job_progressbar"].value = newval
586 self["job_progresslabel"].text = "%.2f%%" % (newval/10.0)
588 def tar_finished(self, retval):
589 self.delayTimer.stop()
590 if len(self.container.appClosed.get()) > 0:
591 self.container.appClosed.get().remove(self.tar_finished)
593 self.imagefilename = "/tmp/nfiflash_" + self.box + ".img"
594 self["statusbar"].text = _("Copying USB flasher boot image to stick...")
596 self.container.appClosed.get().append(self.dd_finished)
597 self.cmd = "dd if=%s of=%s" % (self.imagefilename,self.stickdevice+"/part1")
598 self.container.execute(self.cmd)
599 print "executing " + self.cmd
600 self.delayTimer = eTimer()
601 self.delayTimer.callback.append(self.progress_increment)
602 self.delayTimer.start(105, False)
604 self.session.openWithCallback(self.remove_img, MessageBox, (self.cmd + " " + _("failed") + ":\n" + str(self.taskstring)), MessageBox.TYPE_ERROR)
606 def dd_finished(self, retval):
607 self.delayTimer.stop()
608 self.container.appClosed.get().remove(self.dd_finished)
609 self.downloading(False)
611 self["job_progressbar"].value = 950
612 self["job_progresslabel"].text = "95.00%"
613 self["statusbar"].text = _("Remounting stick partition...")
615 self.container.appClosed.get().append(self.mount_finished)
616 self.cmd = "mount %s /mnt/usb -o rw,sync" % (self.stickdevice+"/part1")
617 self.container.execute(self.cmd)
618 print "executing " + self.cmd
620 self.session.openWithCallback(self.remove_img, MessageBox, (self.cmd + " " + _("failed") + ":\n" + str(self.taskstring)), MessageBox.TYPE_ERROR)
622 def mount_finished(self, retval):
623 self.container.dataAvail.get().remove(self.tool_avail)
624 self.container.appClosed.get().remove(self.mount_finished)
626 self["job_progressbar"].value = 1000
627 self["job_progresslabel"].text = "100.00%"
628 self["statusbar"].text = _(".NFI Flasher bootable USB stick successfully created.")
629 self.session.openWithCallback(self.remove_img, MessageBox, _("The .NFI Image flasher USB stick is now ready to use. Please download an .NFI image file from the feed server and save it on the stick. Then reboot and hold the 'Down' key on the front panel to boot the .NFI flasher from the stick!"), MessageBox.TYPE_INFO)
630 self["destlist"].changeDir("/mnt/usb")
632 self.session.openWithCallback(self.remove_img, MessageBox, (self.cmd + " " + _("failed") + ":\n" + str(self.taskstring)), MessageBox.TYPE_ERROR)
634 def remove_img(self, answer):
635 if fileExists("/tmp/nfiflasher_image.tar.bz2"):
636 remove("/tmp/nfiflasher_image.tar.bz2")
637 if fileExists(self.imagefilename):
638 remove(self.imagefilename)
639 self.downloading(False)
640 self.switchList(self.LIST_SOURCE)
645 #self.nfi_failed(None, "Cancelled by user request")
646 self.downloading(False)
650 def main(session, **kwargs):
651 session.open(NFIDownload,"/home/root")
653 def filescan_open(list, session, **kwargs):
654 dev = "/dev/" + (list[0].path).rsplit('/',1)[0][7:]
655 print "mounting device " + dev + " to /mnt/usb..."
656 system("mount "+dev+" /mnt/usb/ -o rw,sync")
657 session.open(NFIDownload,"/mnt/usb/")
659 def filescan(**kwargs):
660 from Components.Scanner import Scanner, ScanPath
662 Scanner(mimetypes = ["application/x-dream-image"],
665 ScanPath(path = "", with_subdirs = False),
668 description = (_("Download .NFI-Files for USB-Flasher")+"..."),
669 openfnc = filescan_open, )