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 = ""
202 self["key_red"].text = _("Exit")
203 if self["feedlist"].isValid():
204 self["key_green"].text = (_("Download"))
205 if self.focus is self.LIST_SOURCE:
206 self["key_yellow"].text = (_("Change dir."))
208 self["key_yellow"].text = (_("Select image"))
209 self["key_blue"].text = (_("Fix USB stick"))
211 def switchList(self,to_where=None):
212 if self.download or not self["feedlist"].isValid():
215 self["job_progressbar"].value = 0
216 self["job_progresslabel"].text = ""
219 if self.focus is self.LIST_SOURCE:
220 to_where = self.LIST_DEST
221 if self.focus is self.LIST_DEST:
222 to_where = self.LIST_SOURCE
224 if to_where is self.LIST_DEST:
225 self.focus = self.LIST_DEST
226 self["statusbar"].text = _("Please select target directory or medium")
227 self["label_top"].text = _("choose destination directory")+":"
228 self["feedlist"].hide()
229 self["destlist"].show()
230 self["label_bottom"].text = _("Selected source image")+":"
231 self["path_bottom"].text = str(self["feedlist"].getNFIname())
232 self["key_yellow"].text = (_("Select image"))
234 elif to_where is self.LIST_SOURCE:
235 self.focus = self.LIST_SOURCE
236 self["statusbar"].text = _("Please choose .NFI image file from feed server to download")
237 self["label_top"].text = _("select image from server")+":"
238 self["feedlist"].show()
239 self["destlist"].hide()
240 self["label_bottom"].text = _("Destination directory")+":"
241 self["path_bottom"].text = str(self["destlist"].getCurrentDirectory())
242 self["key_yellow"].text = (_("Change dir."))
247 if self.focus is self.LIST_SOURCE:
248 self["feedlist"].up()
250 if self.focus is self.LIST_DEST:
251 self["destlist"].up()
256 if self.focus is self.LIST_SOURCE:
257 self["feedlist"].down()
259 if self.focus is self.LIST_DEST:
260 self["destlist"].down()
265 if self.focus is self.LIST_SOURCE:
266 self["feedlist"].pageUp()
268 if self.focus is self.LIST_DEST:
269 self["destlist"].pageUp()
274 if self.focus is self.LIST_SOURCE:
275 self["feedlist"].pageDown()
277 if self.focus is self.LIST_DEST:
278 self["destlist"].pageDown()
283 if self.focus is self.LIST_DEST:
284 if self["destlist"].canDescent():
285 self["destlist"].descent()
287 def feed_download(self):
288 self.downloading(True)
289 self.download = self.feed_download
290 client.getPage(self.feed_base).addCallback(self.feed_finished).addErrback(self.feed_failed)
292 def feed_failed(self, failure_instance):
293 print "[feed_failed] " + str(failure_instance)
294 self["infolabel"].text = _("Could not connect to Dreambox .NFI Image Feed Server:") + "\n" + failure_instance.getErrorMessage() + "\n\n" + _("Please check your network settings!")
295 self.downloading(False)
297 def feed_finished(self, feedhtml):
298 print "[feed_finished] " + str(feedhtml)
299 self.downloading(False)
300 fileresultmask = re.compile("<a href=[\'\"](?P<url>.*?)[\'\"]>(?P<name>.*?.nfi)</a>", re.DOTALL)
301 searchresults = fileresultmask.finditer(feedhtml)
304 for x in searchresults:
306 if url[0:7] != "http://":
307 url = self.feed_base + x.group("url")
308 name = x.group("name")
309 if name.find(self.nfi_filter) > -1:
310 entry = [[name, url],(eListboxPythonMultiContent.TYPE_TEXT, 0, 0,250, 30, 0, RT_HALIGN_LEFT|RT_VALIGN_CENTER, name)]
311 print "adding to feedlist: " + str(entry)
312 fileresultlist.append(entry)
314 print "NOT adding to feedlist: " + name
315 self["feedlist"].l.setList(fileresultlist)
316 self["feedlist"].moveSelection(0)
318 if len(fileresultlist) > 0:
319 self.switchList(self.LIST_SOURCE)
322 self["infolabel"].text = _("Cannot parse feed directory")
324 def nfo_download(self):
325 print "[check_for_NFO]"
326 if self["feedlist"].isValid():
327 print "nfiname: " + self["feedlist"].getNFIname()
328 self["job_progressbar"].value = 0
329 self["job_progresslabel"].text = ""
330 if self["feedlist"].getNFIurl() is None:
331 self["key_green"].text = ""
333 self["key_green"].text = _("Download")
334 nfourl = self["feedlist"].getNFOurl()
335 print "downloading " + nfourl
336 self.download = self.nfo_download
337 self.downloading(True)
338 client.getPage(nfourl).addCallback(self.nfo_finished).addErrback(self.nfo_failed)
339 self["statusbar"].text = _("Downloading image description...")
341 def nfo_failed(self, failure_instance):
342 print "[nfo_failed] " + str(failure_instance)
343 self["infolabel"].text = _("No details for this image file") + "\n" + self["feedlist"].getNFIname()
344 self["statusbar"].text = ""
345 self.nfofilename = ""
347 self.downloading(False)
349 def nfo_finished(self,nfodata=""):
350 print "[nfo_finished] " + str(nfodata)
351 self.downloading(False)
354 self.nfofilename = self["destlist"].getCurrentDirectory() + '/' + self["feedlist"].getNFOname()
355 self["infolabel"].text = self.nfo
357 self.nfofilename = ""
358 self["infolabel"].text = _("No details for this image file")
359 self["statusbar"].text = ""
361 def nfi_download(self):
362 if self["destlist"].getCurrentDirectory() is None:
363 self.switchList(self.LIST_TARGET)
364 if self["feedlist"].isValid():
365 url = self["feedlist"].getNFIurl()
366 localfile = self["destlist"].getCurrentDirectory()+'/'+self["feedlist"].getNFIname()
367 print "[nfi_download] downloading %s to %s" % (url, localfile)
368 self.download = downloadWithProgress(url,localfile)
369 self.download.addProgress(self.nfi_progress)
370 self["job_progressbar"].range = 1000
371 self.download.start().addCallback(self.nfi_finished).addErrback(self.nfi_failed)
372 self.downloading(True)
374 def nfi_progress(self, recvbytes, totalbytes):
375 #print "[update_progress] recvbytes=%d, totalbytes=%d" % (recvbytes, totalbytes)
376 self["job_progressbar"].value = int(1000*recvbytes/float(totalbytes))
377 self["job_progresslabel"].text = "%d of %d kBytes (%.2f%%)" % (recvbytes/1024, totalbytes/1024, 100*recvbytes/float(totalbytes))
379 def nfi_failed(self, failure_instance=None, error_message=""):
380 if error_message == "" and failure_instance is not None:
381 error_message = failure_instance.getErrorMessage()
382 print "[nfi_failed] " + error_message
383 if fileExists(self["destlist"].getCurrentDirectory()+'/'+self["feedlist"].getNFIname()):
384 message = "%s %s\n%s" % (_(".NFI Download failed:"), error_message, _("Remove the incomplete .NFI file?"))
385 self.session.openWithCallback(self.nfi_remove, MessageBox, message, MessageBox.TYPE_YESNO)
387 message = "%s %s" % (_(".NFI Download failed:"),error_message)
388 self.session.open(MessageBox, message, MessageBox.TYPE_ERROR)
389 self.downloading(False)
391 #def nfi_failed(self, failure_instance):
392 #print "[nfi_failed] "
393 #print failure_instance
394 #if isinstance(failure_instance, Plugins.SystemPlugins.NFIFlash.plugin.UserRequestedCancel):
395 #print "is instance of Plugins.SystemPlugins.NFIFlash.plugin.UserRequestedCancel"
397 #print "not an instance of Plugins.SystemPlugins.NFIFlash.plugin.UserRequestedCancel"
399 def nfi_finished(self, string=""):
400 print "[nfi_finished] " + str(string)
402 self.nfofilename = self["destlist"].getCurrentDirectory() + '/' + self["feedlist"].getNFOname()
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, )