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 self.nfofilename = self["destlist"].getCurrentDirectory() + '/' + self["feedlist"].getNFOname()
404 nfofd = open(self.nfofilename, "w")
406 nfofd.write(self.nfo)
409 print "couldn't save nfo file " + self.nfofilename
411 pos = self.nfo.find("md5sum")
413 self["statusbar"].text = _("Please wait for md5 signature verification...")
414 cmd = "md5sum -cs " + self.nfofilename
416 self.download_container.setCWD(self["destlist"].getCurrentDirectory())
417 self.download_container.appClosed.get().append(self.md5finished)
418 self.download_container.execute(cmd)
420 self["statusbar"].text = "Download completed."
421 self.downloading(False)
423 self["statusbar"].text = "Download completed."
424 self.downloading(False)
426 def md5finished(self, retval):
427 print "[md5finished]: " + str(retval)
428 self.download_container.appClosed.get().remove(self.md5finished)
430 self["statusbar"].text = _(".NFI file passed md5sum signature check. You can safely flash this image!")
431 self.switchList(self.LIST_SOURCE)
432 self.downloading(False)
434 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)
436 def nfi_remove(self, answer):
437 self.downloading(False)
439 nfifilename = self["destlist"].getCurrentDirectory()+'/'+self["feedlist"].getNFIname()
440 if fileExists(self.nfofilename):
441 remove(self.nfofilename)
442 if fileExists(nfifilename):
444 self.switchList(self.LIST_SOURCE)
446 def askCreateUSBstick(self):
448 self.imagefilename = "/tmp/nfiflash_" + self.box + ".img"
449 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.")
450 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)
452 def flasherdownload_query(self, answer):
454 self.downloading(False)
455 self.switchList(self.LIST_SOURCE)
457 #url = self.feed_base + "/nfiflasher_" + self.box + ".tar.bz2"
458 url = "http://www.dreamboxupdate.com/download/opendreambox/dreambox-nfiflasher-%s.tar.bz2" % self.box
459 localfile = "/tmp/nfiflasher_image.tar.bz2"
460 print "[flasherdownload_query] downloading %s to %s" % (url, localfile)
461 self["statusbar"].text = ("Downloading %s..." % url)
462 self.download = downloadWithProgress(url,localfile)
463 self.download.addProgress(self.nfi_progress)
464 self["job_progressbar"].range = 1000
465 self.download.start().addCallback(self.flasherdownload_finished).addErrback(self.flasherdownload_failed)
467 def flasherdownload_failed(self, failure_instance=None, error_message=""):
468 if error_message == "" and failure_instance is not None:
469 error_message = failure_instance.getErrorMessage()
470 print "[flasherdownload_failed] " + error_message
471 message = "%s %s" % (_("Download of USB flasher boot image failed: "),error_message)
472 self.session.open(MessageBox, message, MessageBox.TYPE_ERROR)
473 self.remove_img(True)
475 def flasherdownload_finished(self, string=""):
476 print "[flasherdownload_finished] " + str(string)
477 self.container = eConsoleAppContainer()
478 self.container.appClosed.get().append(self.umount_finished)
479 self.container.dataAvail.get().append(self.tool_avail)
482 from os import listdir
483 for device in listdir("/dev"):
484 if device[:2] == "sd" and device[-1:].isdigit():
485 umountdevs += "/dev/"+device
486 self.cmd = "umount " + umountdevs
487 print "executing " + self.cmd
488 self.container.execute(self.cmd)
490 def tool_avail(self, string):
491 print "[tool_avail]" + string
492 self.taskstring += string
494 def umount_finished(self, retval):
495 self.container.appClosed.get().remove(self.umount_finished)
496 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)
498 def dmesg_clear(self, answer):
499 self.container.appClosed.get().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, retval):
506 self.container.appClosed.get().remove(self.dmesg_cleared)
507 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)
509 def stick_back_in(self, answer):
510 self["statusbar"].text = _("Waiting for USB stick to settle...")
511 self.delayTimer = eTimer()
512 self.delayTimer.callback.append(self.waiting_for_stick)
514 self.delayTimer.start(1000)
516 def waiting_for_stick(self):
518 self["job_progressbar"].range = 6
519 self["job_progressbar"].value = self.delayCount
520 self["job_progresslabel"].text = "-%d s" % (6-self.delayCount)
521 if self.delayCount > 5:
522 self.delayTimer.stop()
523 self.container.appClosed.get().append(self.dmesg_scanned)
526 print "executing " + self.cmd
527 self.container.execute(self.cmd)
529 def dmesg_scanned(self, retval):
530 self.container.appClosed.get().remove(self.dmesg_scanned)
531 dmesg_lines = self.taskstring.splitlines()
532 self.devicetext = None
533 self.stickdevice = None
534 for i, line in enumerate(dmesg_lines):
535 if line.find("usb-storage: waiting for device") != -1 and len(dmesg_lines) > i+3:
536 self.devicetext = dmesg_lines[i+1].lstrip()+"\n"+dmesg_lines[i+3]
537 elif line.find("/dev/scsi/host") != -1:
538 self.stickdevice = line.split(":",1)[0].lstrip()
540 if retval != 0 or self.devicetext is None or self.stickdevice is None:
541 self.session.openWithCallback(self.remove_img, MessageBox, _("No useable USB stick found"), MessageBox.TYPE_ERROR)
543 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)
545 def fdisk_query(self, answer):
547 self["statusbar"].text = _("Partitioning USB stick...")
548 self["job_progressbar"].range = 1000
549 self["job_progressbar"].value = 100
550 self["job_progresslabel"].text = "5.00%"
552 self.container.appClosed.get().append(self.fdisk_finished)
553 self.container.execute("fdisk " + self.stickdevice + "/disc")
554 self.container.write("d\nn\np\n1\n\n\nt\n6\nw\n")
555 self.delayTimer = eTimer()
556 self.delayTimer.callback.append(self.progress_increment)
557 self.delayTimer.start(105, False)
559 self.remove_img(True)
561 def fdisk_finished(self, retval):
562 self.container.appClosed.get().remove(self.fdisk_finished)
563 self.delayTimer.stop()
565 if fileExists(self.imagefilename):
567 self["job_progressbar"].value = 700
569 self["statusbar"].text = _("Decompressing USB stick flasher boot image...")
571 self.container.appClosed.get().append(self.tar_finished)
572 self.container.setCWD("/tmp")
573 self.cmd = "tar -xjvf nfiflasher_image.tar.bz2"
574 self.container.execute(self.cmd)
575 print "executing " + self.cmd
576 self.delayTimer = eTimer()
577 self.delayTimer.callback.append(self.progress_increment)
578 self.delayTimer.start(105, False)
580 print "fdisk failed: " + str(retval)
581 self.session.openWithCallback(self.remove_img, MessageBox, ("fdisk " + _("failed") + ":\n" + str(self.taskstring)), MessageBox.TYPE_ERROR)
583 def progress_increment(self):
584 newval = int(self["job_progressbar"].value) + 1
586 self["job_progressbar"].value = newval
587 self["job_progresslabel"].text = "%.2f%%" % (newval/10.0)
589 def tar_finished(self, retval):
590 self.delayTimer.stop()
591 if len(self.container.appClosed.get()) > 0:
592 self.container.appClosed.get().remove(self.tar_finished)
594 self.imagefilename = "/tmp/nfiflash_" + self.box + ".img"
595 self["statusbar"].text = _("Copying USB flasher boot image to stick...")
597 self.container.appClosed.get().append(self.dd_finished)
598 self.cmd = "dd if=%s of=%s" % (self.imagefilename,self.stickdevice+"/part1")
599 self.container.execute(self.cmd)
600 print "executing " + self.cmd
601 self.delayTimer = eTimer()
602 self.delayTimer.callback.append(self.progress_increment)
603 self.delayTimer.start(105, False)
605 self.session.openWithCallback(self.remove_img, MessageBox, (self.cmd + " " + _("failed") + ":\n" + str(self.taskstring)), MessageBox.TYPE_ERROR)
607 def dd_finished(self, retval):
608 self.delayTimer.stop()
609 self.container.appClosed.get().remove(self.dd_finished)
610 self.downloading(False)
612 self["job_progressbar"].value = 950
613 self["job_progresslabel"].text = "95.00%"
614 self["statusbar"].text = _("Remounting stick partition...")
616 self.container.appClosed.get().append(self.mount_finished)
617 self.cmd = "mount %s /mnt/usb -o rw,sync" % (self.stickdevice+"/part1")
618 self.container.execute(self.cmd)
619 print "executing " + self.cmd
621 self.session.openWithCallback(self.remove_img, MessageBox, (self.cmd + " " + _("failed") + ":\n" + str(self.taskstring)), MessageBox.TYPE_ERROR)
623 def mount_finished(self, retval):
624 self.container.dataAvail.get().remove(self.tool_avail)
625 self.container.appClosed.get().remove(self.mount_finished)
627 self["job_progressbar"].value = 1000
628 self["job_progresslabel"].text = "100.00%"
629 self["statusbar"].text = _(".NFI Flasher bootable USB stick successfully created.")
630 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)
631 self["destlist"].changeDir("/mnt/usb")
633 self.session.openWithCallback(self.remove_img, MessageBox, (self.cmd + " " + _("failed") + ":\n" + str(self.taskstring)), MessageBox.TYPE_ERROR)
635 def remove_img(self, answer):
636 if fileExists("/tmp/nfiflasher_image.tar.bz2"):
637 remove("/tmp/nfiflasher_image.tar.bz2")
638 if fileExists(self.imagefilename):
639 remove(self.imagefilename)
640 self.downloading(False)
641 self.switchList(self.LIST_SOURCE)
646 #self.nfi_failed(None, "Cancelled by user request")
647 self.downloading(False)
651 def main(session, **kwargs):
652 session.open(NFIDownload,"/home/root")
654 def filescan_open(list, session, **kwargs):
655 dev = "/dev/" + (list[0].path).rsplit('/',1)[0][7:]
656 print "mounting device " + dev + " to /mnt/usb..."
657 system("mount "+dev+" /mnt/usb/ -o rw,sync")
658 session.open(NFIDownload,"/mnt/usb/")
660 def filescan(**kwargs):
661 from Components.Scanner import Scanner, ScanPath
663 Scanner(mimetypes = ["application/x-dream-image"],
666 ScanPath(path = "", with_subdirs = False),
669 description = (_("Download .NFI-Files for USB-Flasher")+"..."),
670 openfnc = filescan_open, )