1 from Components.MenuList import MenuList
2 from Screens.Screen import Screen
3 from Screens.MessageBox import MessageBox
4 from Screens.ChoiceBox import ChoiceBox
5 from Components.ActionMap import ActionMap
6 from Components.Sources.StaticText import StaticText
7 from Components.Sources.Progress import Progress
8 from Components.Label import Label
9 from Components.FileList import FileList
10 from Components.MultiContent import MultiContentEntryText
11 from Tools.Directories import fileExists
12 from Tools.HardwareInfo import HardwareInfo
13 from enigma import eConsoleAppContainer, eListbox, gFont, eListboxPythonMultiContent, \
14 RT_HALIGN_LEFT, RT_HALIGN_CENTER, RT_VALIGN_CENTER, RT_WRAP, eRect, eTimer
15 from os import system, remove
18 from twisted.web import client
19 from twisted.internet import reactor, defer
20 from twisted.python import failure
22 class UserRequestedCancel(Exception):
25 class HTTPProgressDownloader(client.HTTPDownloader):
26 def __init__(self, url, outfile, headers=None):
27 client.HTTPDownloader.__init__(self, url, outfile, headers=headers, agent="Dreambox .NFI Download Plugin")
29 self.progress_callback = None
30 self.deferred = defer.Deferred()
32 def noPage(self, reason):
33 if self.status == "304":
34 print reason.getErrorMessage()
35 client.HTTPDownloader.page(self, "")
37 client.HTTPDownloader.noPage(self, reason)
39 def gotHeaders(self, headers):
40 if self.status == "200":
41 if headers.has_key("content-length"):
42 self.totalbytes = int(headers["content-length"][0])
45 self.currentbytes = 0.0
46 return client.HTTPDownloader.gotHeaders(self, headers)
48 def pagePart(self, packet):
49 if self.status == "200":
50 self.currentbytes += len(packet)
51 if self.totalbytes and self.progress_callback:
52 self.progress_callback(self.currentbytes, self.totalbytes)
53 return client.HTTPDownloader.pagePart(self, packet)
56 return client.HTTPDownloader.pageEnd(self)
58 class downloadWithProgress:
59 def __init__(self, url, outputfile, contextFactory=None, *args, **kwargs):
60 scheme, host, port, path = client._parse(url)
61 self.factory = HTTPProgressDownloader(url, outputfile, *args, **kwargs)
62 self.connection = reactor.connectTCP(host, port, self.factory)
65 return self.factory.deferred
69 self.connection.disconnect()
70 #self.factory.deferred.errback(failure.Failure(UserRequestedCancel))
72 def addProgress(self, progress_callback):
74 self.factory.progress_callback = progress_callback
76 class Feedlist(MenuList):
77 def __init__(self, list=[], enableWrapAround = False):
78 MenuList.__init__(self, list, enableWrapAround, eListboxPythonMultiContent)
79 self.l.setFont(0, gFont("Regular", 16))
80 self.l.setItemHeight(22)
84 self.l.setList(self.list)
87 l = self.l.getCurrentSelection()
91 l = self.l.getCurrentSelection()
95 l = self.l.getCurrentSelection()
96 return l and l[0][0][:-3]+"nfo"
99 l = self.l.getCurrentSelection()
100 return l and l[0][1][:-3]+"nfo"
103 l = self.l.getCurrentSelection()
109 def moveSelection(self,idx=0):
110 if self.instance is not None:
111 self.instance.moveSelectionTo(idx)
113 class NFIDownload(Screen):
117 <screen name="NFIDownload" position="90,95" size="560,420" title="Image download utility">
118 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" zPosition="0" size="140,40" transparent="1" alphatest="on" />
119 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" zPosition="0" size="140,40" transparent="1" alphatest="on" />
120 <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" zPosition="0" size="140,40" transparent="1" alphatest="on" />
121 <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" zPosition="0" size="140,40" transparent="1" alphatest="on" />
122 <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" />
123 <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" />
124 <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" />
125 <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" />
127 <widget source="label_top" render="Label" position="10,44" size="240,20" font="Regular;16" />
128 <widget name="feedlist" position="10,66" size="250,222" scrollbarMode="showOnDemand" />
129 <widget name="destlist" position="0,66" size="260,222" scrollbarMode="showOnDemand" />
131 <widget source="label_bottom" render="Label" position="10,312" size="240,18" font="Regular;16"/>
132 <widget source="path_bottom" render="Label" position="10,330" size="250,42" font="Regular;18" />
134 <widget source="infolabel" render="Label" position="270,44" size="280,284" font="Regular;16" />
135 <widget source="job_progressbar" render="Progress" position="10,374" size="540,26" borderWidth="1" backgroundColor="#254f7497" />
136 <widget source="job_progresslabel" render="Label" position="130,378" zPosition="2" font="Regular;18" halign="center" transparent="1" size="300,22" foregroundColor="#000000" />
137 <widget source="statusbar" render="Label" position="10,404" size="540,16" font="Regular;16" foregroundColor="#cccccc" />
140 def __init__(self, session, destdir="/tmp/"):
141 self.skin = NFIDownload.skin
142 Screen.__init__(self, session)
144 self["job_progressbar"] = Progress()
145 self["job_progresslabel"] = StaticText()
147 self["infolabel"] = StaticText()
148 self["statusbar"] = StaticText()
149 self["label_top"] = StaticText()
150 self["label_bottom"] = StaticText()
151 self["path_bottom"] = StaticText()
153 self["key_green"] = StaticText()
154 self["key_yellow"] = StaticText()
155 self["key_blue"] = StaticText()
157 self["key_red"] = StaticText()
159 self["feedlist"] = Feedlist([0,(eListboxPythonMultiContent.TYPE_TEXT, 0, 0,250, 30, 0, RT_HALIGN_LEFT|RT_VALIGN_CENTER, "feed not available")])
160 self["destlist"] = FileList(destdir, showDirectories = True, showFiles = False)
161 self["destlist"].hide()
163 self.download_container = eConsoleAppContainer()
169 self.box = HardwareInfo().get_device_name()
170 self.feed_base = "http://www.dreamboxupdate.com/opendreambox/1.5/%s/images/" % self.box
171 self.nfi_filter = "" # "release" # only show NFIs containing this string, or all if ""
173 self["actions"] = ActionMap(["OkCancelActions", "ColorActions", "DirectionActions", "EPGSelectActions"],
175 "cancel": self.closeCB,
177 "green": self.nfi_download,
178 "yellow": self.switchList,
179 "blue": self.askCreateUSBstick,
180 "prevBouquet": self.switchList,
181 "nextBouquet": self.switchList,
186 "upRepeated": self.up,
187 "downRepeated": self.down,
193 def downloading(self, state=True):
195 self["key_red"].text = _("Cancel")
196 self["key_green"].text = ""
197 self["key_yellow"].text = ""
198 self["key_blue"].text = ""
201 self["key_red"].text = _("Exit")
202 if self["feedlist"].isValid():
203 self["key_green"].text = (_("Download"))
204 if self.focus is self.LIST_SOURCE:
205 self["key_yellow"].text = (_("Change dir."))
207 self["key_yellow"].text = (_("Select image"))
208 self["key_blue"].text = (_("Fix USB stick"))
210 def switchList(self,to_where=None):
211 if self.download or not self["feedlist"].isValid():
214 self["job_progressbar"].value = 0
215 self["job_progresslabel"].text = ""
218 if self.focus is self.LIST_SOURCE:
219 to_where = self.LIST_DEST
220 if self.focus is self.LIST_DEST:
221 to_where = self.LIST_SOURCE
223 if to_where is self.LIST_DEST:
224 self.focus = self.LIST_DEST
225 self["statusbar"].text = _("Please select target directory or medium")
226 self["label_top"].text = _("choose destination directory")+":"
227 self["feedlist"].hide()
228 self["destlist"].show()
229 self["label_bottom"].text = _("Selected source image")+":"
230 self["path_bottom"].text = str(self["feedlist"].getNFIname())
231 self["key_yellow"].text = (_("Select image"))
233 elif to_where is self.LIST_SOURCE:
234 self.focus = self.LIST_SOURCE
235 self["statusbar"].text = _("Please choose .NFI image file from feed server to download")
236 self["label_top"].text = _("select image from server")+":"
237 self["feedlist"].show()
238 self["destlist"].hide()
239 self["label_bottom"].text = _("Destination directory")+":"
240 self["path_bottom"].text = str(self["destlist"].getCurrentDirectory())
241 self["key_yellow"].text = (_("Change dir."))
246 if self.focus is self.LIST_SOURCE:
247 self["feedlist"].up()
249 if self.focus is self.LIST_DEST:
250 self["destlist"].up()
255 if self.focus is self.LIST_SOURCE:
256 self["feedlist"].down()
258 if self.focus is self.LIST_DEST:
259 self["destlist"].down()
264 if self.focus is self.LIST_SOURCE:
265 self["feedlist"].pageUp()
267 if self.focus is self.LIST_DEST:
268 self["destlist"].pageUp()
273 if self.focus is self.LIST_SOURCE:
274 self["feedlist"].pageDown()
276 if self.focus is self.LIST_DEST:
277 self["destlist"].pageDown()
282 if self.focus is self.LIST_DEST:
283 if self["destlist"].canDescent():
284 self["destlist"].descent()
286 def feed_download(self):
287 self.downloading(True)
288 self.download = self.feed_download
289 client.getPage(self.feed_base).addCallback(self.feed_finished).addErrback(self.feed_failed)
291 def feed_failed(self, failure_instance):
292 print "[feed_failed] " + str(failure_instance)
293 self["infolabel"].text = _("Could not connect to Dreambox .NFI Image Feed Server:") + "\n" + failure_instance.getErrorMessage() + "\n\n" + _("Please check your network settings!")
294 self.downloading(False)
296 def feed_finished(self, feedhtml):
297 print "[feed_finished] " + str(feedhtml)
298 self.downloading(False)
299 fileresultmask = re.compile("<a href=[\'\"](?P<url>.*?)[\'\"]>(?P<name>.*?.nfi)</a>", re.DOTALL)
300 searchresults = fileresultmask.finditer(feedhtml)
303 for x in searchresults:
305 if url[0:7] != "http://":
306 url = self.feed_base + x.group("url")
307 name = x.group("name")
308 if name.find(self.nfi_filter) > -1:
309 entry = [[name, url],(eListboxPythonMultiContent.TYPE_TEXT, 0, 0,250, 30, 0, RT_HALIGN_LEFT|RT_VALIGN_CENTER, name)]
310 print "adding to feedlist: " + str(entry)
311 fileresultlist.append(entry)
313 print "NOT adding to feedlist: " + name
314 self["feedlist"].l.setList(fileresultlist)
315 self["feedlist"].moveSelection(0)
317 if len(fileresultlist) > 0:
318 self.switchList(self.LIST_SOURCE)
321 self["infolabel"].text = _("Cannot parse feed directory")
323 def nfo_download(self):
324 print "[check_for_NFO]"
325 if self["feedlist"].isValid():
326 print "nfiname: " + self["feedlist"].getNFIname()
327 self["job_progressbar"].value = 0
328 self["job_progresslabel"].text = ""
329 if self["feedlist"].getNFIurl() is None:
330 self["key_green"].text = ""
332 self["key_green"].text = _("Download")
333 nfourl = self["feedlist"].getNFOurl()
334 print "downloading " + nfourl
335 self.download = self.nfo_download
336 self.downloading(True)
337 client.getPage(nfourl).addCallback(self.nfo_finished).addErrback(self.nfo_failed)
338 self["statusbar"].text = _("Downloading image description...")
340 def nfo_failed(self, failure_instance):
341 print "[nfo_failed] " + str(failure_instance)
342 self["infolabel"].text = _("No details for this image file") + "\n" + self["feedlist"].getNFIname()
343 self["statusbar"].text = ""
344 self.nfofilename = ""
346 self.downloading(False)
348 def nfo_finished(self,nfodata=""):
349 print "[nfo_finished] " + str(nfodata)
350 self.downloading(False)
353 self.nfofilename = self["destlist"].getCurrentDirectory() + '/' + self["feedlist"].getNFOname()
354 self["infolabel"].text = self.nfo
356 self.nfofilename = ""
357 self["infolabel"].text = _("No details for this image file")
358 self["statusbar"].text = ""
360 def nfi_download(self):
361 if self["destlist"].getCurrentDirectory() is None:
362 self.switchList(self.LIST_TARGET)
363 if self["feedlist"].isValid():
364 url = self["feedlist"].getNFIurl()
365 self.nfilocal = self["destlist"].getCurrentDirectory()+'/'+self["feedlist"].getNFIname()
366 print "[nfi_download] downloading %s to %s" % (url, self.nfilocal)
367 self.download = downloadWithProgress(url,self.nfilocal)
368 self.download.addProgress(self.nfi_progress)
369 self["job_progressbar"].range = 1000
370 self.download.start().addCallback(self.nfi_finished).addErrback(self.nfi_failed)
371 self.downloading(True)
373 def nfi_progress(self, recvbytes, totalbytes):
374 #print "[update_progress] recvbytes=%d, totalbytes=%d" % (recvbytes, totalbytes)
375 self["job_progressbar"].value = int(1000*recvbytes/float(totalbytes))
376 self["job_progresslabel"].text = "%d of %d kBytes (%.2f%%)" % (recvbytes/1024, totalbytes/1024, 100*recvbytes/float(totalbytes))
378 def nfi_failed(self, failure_instance=None, error_message=""):
379 if error_message == "" and failure_instance is not None:
380 error_message = failure_instance.getErrorMessage()
381 print "[nfi_failed] " + error_message
382 if fileExists(self["destlist"].getCurrentDirectory()+'/'+self["feedlist"].getNFIname()):
383 message = "%s %s\n%s" % (_(".NFI Download failed:"), error_message, _("Remove the incomplete .NFI file?"))
384 self.session.openWithCallback(self.nfi_remove, MessageBox, message, MessageBox.TYPE_YESNO)
386 message = "%s %s" % (_(".NFI Download failed:"),error_message)
387 self.session.open(MessageBox, message, MessageBox.TYPE_ERROR)
388 self.downloading(False)
390 def nfi_finished(self, string=""):
391 print "[nfi_finished] " + str(string)
393 self.nfofilename = self["destlist"].getCurrentDirectory() + '/' + self["feedlist"].getNFOname()
394 nfofd = open(self.nfofilename, "w")
396 nfofd.write(self.nfo)
399 print "couldn't save nfo file " + self.nfofilename
401 pos = self.nfo.find("MD5:")
402 if pos > 0 and len(self.nfo) >= pos+5+32:
403 self["statusbar"].text = _("Please wait for md5 signature verification...")
405 md5 = self.nfo[pos+5:pos+5+32] + " " + self.nfilocal
407 self.download_container.setCWD(self["destlist"].getCurrentDirectory())
408 self.download_container.appClosed.append(self.md5finished)
409 self.download_container.execute(cmd)
410 self.download_container.write(md5)
411 self.download_container.dataSent.append(self.md5ready)
413 self["statusbar"].text = "Download completed."
414 self.downloading(False)
416 self["statusbar"].text = "Download completed."
417 self.downloading(False)
419 def md5ready(self, retval):
420 self.download_container.sendEOF()
422 def md5finished(self, retval):
423 print "[md5finished]: " + str(retval)
424 self.download_container.appClosed.remove(self.md5finished)
426 self["statusbar"].text = _(".NFI file passed md5sum signature check. You can safely flash this image!")
427 self.switchList(self.LIST_SOURCE)
428 self.downloading(False)
430 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)
432 def nfi_remove(self, answer):
433 self.downloading(False)
435 nfifilename = self["destlist"].getCurrentDirectory()+'/'+self["feedlist"].getNFIname()
436 if fileExists(self.nfofilename):
437 remove(self.nfofilename)
438 if fileExists(nfifilename):
440 self.switchList(self.LIST_SOURCE)
442 def askCreateUSBstick(self):
444 self.imagefilename = "/tmp/nfiflash_" + self.box + ".img"
445 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.")
446 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)
448 def flasherdownload_query(self, answer):
450 self.downloading(False)
451 self.switchList(self.LIST_SOURCE)
453 #url = self.feed_base + "/nfiflasher_" + self.box + ".tar.bz2"
454 url = "http://www.dreamboxupdate.com/download/opendreambox/dreambox-nfiflasher-%s.tar.bz2" % self.box
455 localfile = "/tmp/nfiflasher_image.tar.bz2"
456 print "[flasherdownload_query] downloading %s to %s" % (url, localfile)
457 self["statusbar"].text = ("Downloading %s..." % url)
458 self.download = downloadWithProgress(url,localfile)
459 self.download.addProgress(self.nfi_progress)
460 self["job_progressbar"].range = 1000
461 self.download.start().addCallback(self.flasherdownload_finished).addErrback(self.flasherdownload_failed)
463 def flasherdownload_failed(self, failure_instance=None, error_message=""):
464 if error_message == "" and failure_instance is not None:
465 error_message = failure_instance.getErrorMessage()
466 print "[flasherdownload_failed] " + error_message
467 message = "%s %s" % (_("Download of USB flasher boot image failed: "),error_message)
468 self.session.open(MessageBox, message, MessageBox.TYPE_ERROR)
469 self.remove_img(True)
471 def flasherdownload_finished(self, string=""):
472 print "[flasherdownload_finished] " + str(string)
473 self.container = eConsoleAppContainer()
474 self.container.appClosed.append(self.umount_finished)
475 self.container.dataAvail.append(self.tool_avail)
478 from os import listdir
479 for device in listdir("/dev"):
480 if device[:2] == "sd" and device[-1:].isdigit():
481 umountdevs += "/dev/"+device
482 self.cmd = "umount " + umountdevs
483 print "executing " + self.cmd
484 self.container.execute(self.cmd)
486 def tool_avail(self, string):
487 print "[tool_avail]" + string
488 self.taskstring += string
490 def umount_finished(self, retval):
491 self.container.appClosed.remove(self.umount_finished)
492 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)
494 def dmesg_clear(self, answer):
495 self.container.appClosed.append(self.dmesg_cleared)
497 self.cmd = "dmesg -c"
498 print "executing " + self.cmd
499 self.container.execute(self.cmd)
501 def dmesg_cleared(self, retval):
502 self.container.appClosed.remove(self.dmesg_cleared)
503 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)
505 def stick_back_in(self, answer):
506 self["statusbar"].text = _("Waiting for USB stick to settle...")
507 self.delayTimer = eTimer()
508 self.delayTimer.callback.append(self.waiting_for_stick)
510 self.delayTimer.start(1000)
512 def waiting_for_stick(self):
514 self["job_progressbar"].range = 6
515 self["job_progressbar"].value = self.delayCount
516 self["job_progresslabel"].text = "-%d s" % (6-self.delayCount)
517 if self.delayCount > 5:
518 self.delayTimer.stop()
519 self.container.appClosed.append(self.dmesg_scanned)
522 print "executing " + self.cmd
523 self.container.execute(self.cmd)
525 def dmesg_scanned(self, retval):
526 self.container.appClosed.remove(self.dmesg_scanned)
527 dmesg_lines = self.taskstring.splitlines()
528 self.devicetext = None
529 self.stickdevice = None
530 for i, line in enumerate(dmesg_lines):
531 if line.find("usb-storage: waiting for device") != -1 and len(dmesg_lines) > i+3:
532 self.devicetext = dmesg_lines[i+1].lstrip()+"\n"+dmesg_lines[i+3]
533 elif line.find("/dev/scsi/host") != -1:
534 self.stickdevice = line.split(":",1)[0].lstrip()
536 if retval != 0 or self.devicetext is None or self.stickdevice is None:
537 self.session.openWithCallback(self.remove_img, MessageBox, _("No useable USB stick found"), MessageBox.TYPE_ERROR)
539 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)
541 def fdisk_query(self, answer):
543 self["statusbar"].text = _("Partitioning USB stick...")
544 self["job_progressbar"].range = 1000
545 self["job_progressbar"].value = 100
546 self["job_progresslabel"].text = "5.00%"
548 self.container.appClosed.append(self.fdisk_finished)
549 self.container.execute("fdisk " + self.stickdevice + "/disc")
550 self.container.write("d\nn\np\n1\n\n\nt\n6\nw\n")
551 self.delayTimer = eTimer()
552 self.delayTimer.callback.append(self.progress_increment)
553 self.delayTimer.start(105, False)
555 self.remove_img(True)
557 def fdisk_finished(self, retval):
558 self.container.appClosed.remove(self.fdisk_finished)
559 self.delayTimer.stop()
561 if fileExists(self.imagefilename):
563 self["job_progressbar"].value = 700
565 self["statusbar"].text = _("Decompressing USB stick flasher boot image...")
567 self.container.appClosed.append(self.tar_finished)
568 self.container.setCWD("/tmp")
569 self.cmd = "tar -xjvf nfiflasher_image.tar.bz2"
570 self.container.execute(self.cmd)
571 print "executing " + self.cmd
572 self.delayTimer = eTimer()
573 self.delayTimer.callback.append(self.progress_increment)
574 self.delayTimer.start(105, False)
576 print "fdisk failed: " + str(retval)
577 self.session.openWithCallback(self.remove_img, MessageBox, ("fdisk " + _("failed") + ":\n" + str(self.taskstring)), MessageBox.TYPE_ERROR)
579 def progress_increment(self):
580 newval = int(self["job_progressbar"].value) + 1
582 self["job_progressbar"].value = newval
583 self["job_progresslabel"].text = "%.2f%%" % (newval/10.0)
585 def tar_finished(self, retval):
586 self.delayTimer.stop()
587 if len(self.container.appClosed) > 0:
588 self.container.appClosed.remove(self.tar_finished)
590 self.imagefilename = "/tmp/nfiflash_" + self.box + ".img"
591 self["statusbar"].text = _("Copying USB flasher boot image to stick...")
593 self.container.appClosed.append(self.dd_finished)
594 self.cmd = "dd if=%s of=%s" % (self.imagefilename,self.stickdevice+"/part1")
595 self.container.execute(self.cmd)
596 print "executing " + self.cmd
597 self.delayTimer = eTimer()
598 self.delayTimer.callback.append(self.progress_increment)
599 self.delayTimer.start(105, False)
601 self.session.openWithCallback(self.remove_img, MessageBox, (self.cmd + " " + _("failed") + ":\n" + str(self.taskstring)), MessageBox.TYPE_ERROR)
603 def dd_finished(self, retval):
604 self.delayTimer.stop()
605 self.container.appClosed.remove(self.dd_finished)
606 self.downloading(False)
608 self["job_progressbar"].value = 950
609 self["job_progresslabel"].text = "95.00%"
610 self["statusbar"].text = _("Remounting stick partition...")
612 self.container.appClosed.append(self.mount_finished)
613 self.cmd = "mount %s /mnt/usb -o rw,sync" % (self.stickdevice+"/part1")
614 self.container.execute(self.cmd)
615 print "executing " + self.cmd
617 self.session.openWithCallback(self.remove_img, MessageBox, (self.cmd + " " + _("failed") + ":\n" + str(self.taskstring)), MessageBox.TYPE_ERROR)
619 def mount_finished(self, retval):
620 self.container.dataAvail.remove(self.tool_avail)
621 self.container.appClosed.remove(self.mount_finished)
623 self["job_progressbar"].value = 1000
624 self["job_progresslabel"].text = "100.00%"
625 self["statusbar"].text = _(".NFI Flasher bootable USB stick successfully created.")
626 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)
627 self["destlist"].changeDir("/mnt/usb")
629 self.session.openWithCallback(self.remove_img, MessageBox, (self.cmd + " " + _("failed") + ":\n" + str(self.taskstring)), MessageBox.TYPE_ERROR)
631 def remove_img(self, answer):
632 if fileExists("/tmp/nfiflasher_image.tar.bz2"):
633 remove("/tmp/nfiflasher_image.tar.bz2")
634 if fileExists(self.imagefilename):
635 remove(self.imagefilename)
636 self.downloading(False)
637 self.switchList(self.LIST_SOURCE)
642 #self.nfi_failed(None, "Cancelled by user request")
643 self.downloading(False)
647 def main(session, **kwargs):
648 session.open(NFIDownload,"/home/root")
650 def filescan_open(list, session, **kwargs):
651 dev = "/dev/" + (list[0].path).rsplit('/',1)[0][7:]
652 print "mounting device " + dev + " to /mnt/usb..."
653 system("mount "+dev+" /mnt/usb/ -o rw,sync")
654 session.open(NFIDownload,"/mnt/usb/")
656 def filescan(**kwargs):
657 from Components.Scanner import Scanner, ScanPath
659 Scanner(mimetypes = ["application/x-dream-image"],
662 ScanPath(path = "", with_subdirs = False),
665 description = (_("Download .NFI-Files for USB-Flasher")+"..."),
666 openfnc = filescan_open, )