def confirmation(self): self.message = _("Do you want to flash image\n%s") % self.imagename if MultiBoot.canMultiBoot(): self.getImageList = MultiBoot.getSlotImageList( self.getImagelistCallback) else: self.checkMedia(True)
def flashimage(self): self["header"].setText(_("Flashing Image")) self["summary_header"].setText(self["header"].getText()) def findimagefiles(path): for path, subdirs, files in os.walk(path): if not subdirs and files: return checkimagefiles(files) and path imagefiles = findimagefiles(self.unzippedimage) if imagefiles: self.ROOTFSSUBDIR = "none" bootSlots = MultiBoot.getBootSlots() if bootSlots: self.MTDKERNEL = bootSlots[self.multibootslot]["kernel"].split( '/')[2] if bootSlots[self.multibootslot].get("ubi"): self.MTDROOTFS = bootSlots[self.multibootslot]["device"] else: self.MTDROOTFS = bootSlots[ self.multibootslot]["device"].split('/')[2] if MultiBoot.hasRootSubdir(): self.ROOTFSSUBDIR = bootSlots[ self.multibootslot]["rootsubdir"] else: self.MTDKERNEL = getMachineMtdKernel() self.MTDROOTFS = getMachineMtdRoot() if getMachineBuild( ) in ("dm820", "dm7080"): # temp solution ofgwrite autodetection not ready CMD = "/usr/bin/ofgwrite -rmmcblk0p1 '%s'" % imagefiles elif self.MTDKERNEL == self.MTDROOTFS: # receiver with kernel and rootfs on one partition CMD = "/usr/bin/ofgwrite -r '%s'" % imagefiles else: CMD = "/usr/bin/ofgwrite -r -k '%s'" % imagefiles #normal non multiboot receiver if MultiBoot.canMultiBoot(): if (self.ROOTFSSUBDIR ) is None: # receiver with SD card multiboot CMD = "/usr/bin/ofgwrite -r%s -k%s -m0 '%s'" % ( self.MTDROOTFS, self.MTDKERNEL, imagefiles) else: CMD = "/usr/bin/ofgwrite -r -k -m%s '%s'" % ( self.multibootslot, imagefiles) self.containerofgwrite = Console() self.containerofgwrite.ePopen(CMD, self.FlashimageDone) fbClass.getInstance().lock() else: self.session.openWithCallback( self.abort, MessageBox, _("Image to install is invalid\n%s") % self.imagename, type=MessageBox.TYPE_ERROR, simple=True)
def flashImage(self): def findImageFiles(path): for path, subDirs, files in walk(path): if not subDirs and files: return checkImageFiles(files) and path self["header"].setText(_("Flashing Image")) self["summary_header"].setText(self["header"].getText()) imageFiles = findImageFiles(self.unzippedImage) if imageFiles: rootSubDir = "none" bootSlots = MultiBoot.getBootSlots() if bootSlots: mtdKernel = bootSlots[self.slotCode]["kernel"].split(sep)[2] mtdRootFS = bootSlots[self.slotCode]["device"] if bootSlots[ self.slotCode].get("ubi") else bootSlots[ self.slotCode]["device"].split(sep)[2] if MultiBoot.hasRootSubdir(): rootSubDir = bootSlots[self.slotCode]["rootsubdir"] else: mtdKernel = BoxInfo.getItem("mtdkernel") mtdRootFS = BoxInfo.getItem("mtdrootfs") if MultiBoot.canMultiBoot( ): # Receiver with SD card MultiBoot if (rootSubDir) is None. cmdArgs = ["-r%s" % mtdRootFS, "-k%s" % mtdKernel, "-m0"] if (rootSubDir) is None else [ "-r", "-k", "-m%s" % self.slotCode ] elif BoxInfo.getItem("model") in ( "dm820", "dm7080" ): # Temp solution ofgwrite auto detection not ready. cmdArgs = ["-rmmcblk0p1"] elif mtdKernel == mtdRootFS: # Receiver with kernel and rootfs on one partition. cmdArgs = ["-r"] else: # Normal non MultiBoot receiver. cmdArgs = ["-r", "-k"] self.containerOFGWrite = Console() self.containerOFGWrite.ePopen([OFGWRITE, OFGWRITE] + cmdArgs + ['%s' % imageFiles], callback=self.flashImageDone) fbClass.getInstance().lock() else: self.session.openWithCallback( self.keyCancel, MessageBox, _("Error: Image '%s' to install is invalid!") % self.imageName, type=MessageBox.TYPE_ERROR, windowTitle=self.getTitle())
def getImageListCallback(self, imageDictionary): self.getImageList = None currentSlotCode = MultiBoot.getCurrentSlotCode() print("[FlashManager] Current image slot is '%s'." % currentSlotCode) choices = [] default = 0 for index, slotCode in enumerate(sorted(imageDictionary.keys())): print("[FlashManager] Image Slot '%s': %s." % (slotCode, str(imageDictionary[slotCode]))) if slotCode == currentSlotCode: choices.append( (_("Slot '%s': %s - Current") % (slotCode, imageDictionary[slotCode]["imagename"]), (slotCode, True))) default = index else: choices.append( (_("Slot '%s': %s") % (slotCode, imageDictionary[slotCode]["imagename"]), (slotCode, True))) choices.append((_("No, don't flash this image"), False)) self.session.openWithCallback( self.checkMedia, MessageBox, _("Do you want to flash the image '%s'?") % self.imageName, list=choices, default=default, windowTitle=self.getTitle())
def keyOK(self): fbClass.getInstance().unlock() if self["header"].text == _("Flashing image successful"): if MultiBoot.canMultiBoot(): self.session.openWithCallback(self.keyCancel, MultiBootManager) else: self.close() else: return 0
def getSlotImageListCallback(self, slotImages): imageList = [] if slotImages: slotCode, bootCode = MultiBoot.getCurrentSlotAndBootCodes() slotImageList = sorted(slotImages.keys()) currentMsg = " - %s" % _("Current") slotMsg = _("Slot '%s': %s%s") imageLists = {} for slot in slotImageList: for boot in slotImages[slot]["bootCodes"]: if imageLists.get(boot) is None: imageLists[boot] = [] current = currentMsg if boot == bootCode and slot == slotCode else "" imageLists[boot].append( ChoiceEntryComponent( "none" if boot else "", (slotMsg % (slot, slotImages[slot]["imagename"], current), (slot, boot, slotImages[slot]["status"], slotImages[slot]["ubi"], current != "")))) for bootCode in sorted(imageLists.keys()): if bootCode == "": continue imageList.append( ChoiceEntryComponent( "", (MultiBoot.getBootCodeDescription(bootCode), None))) imageList.extend(imageLists[bootCode]) if "" in imageLists: imageList.extend(imageLists[""]) if self.initialize: self.initialize = False for index, item in enumerate(imageList): if item[0][1] and item[0][1][4]: break else: index = self["slotlist"].getSelectedIndex() else: imageList.append( ChoiceEntryComponent("", (_("No slot images found"), "Void"))) index = 0 self["slotlist"].setList(imageList) self["slotlist"].moveToIndex(index) self.selectionChanged()
def selectionChanged(self): slotCode = MultiBoot.getCurrentSlotCode() currentSelected = self["slotlist"].l.getCurrentSelection()[0] slot = currentSelected[1][0] status = currentSelected[1][2] ubi = currentSelected[1][3] current = currentSelected[1][4] if slot == slotCode or status in ("android", "androidlinuxse", "recovery"): self["key_green"].setText(_("Reboot")) self["key_yellow"].setText("") self["key_blue"].setText("") self["restartActions"].setEnabled(True) self["deleteActions"].setEnabled(False) self["restoreActions"].setEnabled(False) elif status == "unknown": self["key_green"].setText("") self["key_yellow"].setText("") self["key_blue"].setText("") self["restartActions"].setEnabled(False) self["deleteActions"].setEnabled(False) self["restoreActions"].setEnabled(False) elif status == "empty": self["key_green"].setText("") self["key_yellow"].setText("") self["key_blue"].setText(_("Restore")) self["restartActions"].setEnabled(False) self["deleteActions"].setEnabled(False) self["restoreActions"].setEnabled(True) elif ubi: self["key_green"].setText(_("Reboot")) self["key_yellow"].setText(_("Wipe")) self["key_blue"].setText("") self["restartActions"].setEnabled(True) self["deleteActions"].setEnabled(True) self["restoreActions"].setEnabled(False) else: self["key_green"].setText(_("Reboot")) self["key_yellow"].setText(_("Delete")) self["key_blue"].setText("") self["restartActions"].setEnabled(True) self["deleteActions"].setEnabled(True) self["restoreActions"].setEnabled(False)
def getImagelistCallback(self, imagedict): self.getImageList = None choices = [] for item in imagedict.copy(): if not item.isdecimal(): imagedict.pop(item) currentimageslot = int(MultiBoot.getCurrentSlotCode()) print("[FlashOnline] Current image slot %s." % currentimageslot) for slotCode in imagedict.keys(): print("[FlashOnline] Image Slot %s: %s" % (slotCode, str(imagedict))) choices.append( ((_("slot%s - %s (current image)") if slotCode == currentimageslot else _("slot%s - %s")) % (slotCode, imagedict[slotCode]['imagename']), (slotCode, True))) choices.append((_("No, do not flash an image"), False)) self.session.openWithCallback(self.checkMedia, MessageBox, self.message, list=choices, default=currentimageslot, simple=True)
def deleteImageAnswer(self, answer): if answer: currentSelected = self["slotlist"].l.getCurrentSelection()[0] MultiBoot.emptySlot(currentSelected[1][0], self.deleteImageCallback)
def checkMedia(self, choice): if choice: def findMedia(paths): def availableSpace(path): if not "/mmc" in path and isdir(path) and access( path, W_OK): try: fs = statvfs(path) return (fs.f_bavail * fs.f_frsize) / (1 << 20) except OSError as err: print( "[FlashManager] checkMedia Error %d: Unable to get status for '%s'! (%s)" % (err.errno, path, err.strerror)) return 0 def checkIfDevice(path, diskStats): deviceID = stat(path).st_dev return (major(deviceID), minor(deviceID)) in diskStats diskStats = [(int(x[0]), int(x[1])) for x in [ x.split()[0:3] for x in open("/proc/diskstats").readlines() ] if x[2].startswith("sd")] for path in paths: if isdir(path) and checkIfDevice( path, diskStats) and availableSpace(path) > 500: return (path, True) devices = [] mounts = [] for path in ["/media/%s" % x for x in listdir("/media")] + ([ "/media/net/%s" % x for x in listdir("/media/net") ] if isdir("/media/net") else []): if checkIfDevice(path, diskStats): devices.append((path, availableSpace(path))) else: mounts.append((path, availableSpace(path))) devices.sort(key=lambda x: x[1], reverse=True) mounts.sort(key=lambda x: x[1], reverse=True) return ((devices[0][1] > 500 and (devices[0][0], True)) if devices else mounts and mounts[0][1] > 500 and (mounts[0][0], False)) or (None, None) if "backup" not in str(choice): if MultiBoot.canMultiBoot(): self.slotCode = choice[0] if BoxInfo.getItem("distro") in self.imageName: self.session.openWithCallback( self.backupQuestionCallback, MessageBox, _("Do you want to backup settings?"), default=True, timeout=10, windowTitle=self.getTitle()) else: self.backupQuestionCallback(None) return destination, isDevice = findMedia(["/media/hdd", "/media/usb"]) if destination: destination = pathjoin(destination, "images") self.zippedImage = "://" in self.source and pathjoin( destination, self.imageName) or self.source self.unzippedImage = pathjoin( destination, "%s.unzipped" % self.imageName[:-4]) try: if isfile(destination): unlink(destination) if not isdir(destination): mkdir(destination) if isDevice or "no_backup" == choice: self.startBackupSettings(choice) else: self.session.openWithCallback( self.startBackupSettings, MessageBox, _("Warning: There is only a network drive to store the backup. This means the auto restore will not work after the flash. Alternatively, mount the network drive after the flash and perform a manufacturer reset to auto restore." ), windowTitle=self.getTitle()) except OSError as err: self.session.openWithCallback( self.keyCancel, MessageBox, _("Error: Unable to create the required directories on the target device (e.g. USB stick or hard disk)! Please verify device and try again." ), type=MessageBox.TYPE_ERROR, windowTitle=self.getTitle()) else: self.session.openWithCallback( self.keyCancel, MessageBox, _("Error: Could not find a suitable device! Please remove some downloaded images or attach another device (e.g. USB stick) with sufficient free space and try again." ), type=MessageBox.TYPE_ERROR, windowTitle=self.getTitle()) else: self.keyCancel()
def confirmation(self): if MultiBoot.canMultiBoot(): self.getImageList = MultiBoot.getSlotImageList( self.getImageListCallback) else: self.checkMedia(True)
def reboot(self): currentSelected = self["slotlist"].l.getCurrentSelection()[0] MultiBoot.activateSlot(currentSelected[1][0], currentSelected[1][1], self.rebootCallback)
def restoreImage(self): currentSelected = self["slotlist"].l.getCurrentSelection()[0] MultiBoot.restoreSlot(currentSelected[1][0], self.restoreImageCallback)
def getImagesList(self): MultiBoot.getSlotImageList(self.getSlotImageListCallback)
"vuultimo4k", "et13000", "sf5008", "vuuno4kse", "vuduo4k", "vuduo4kse") or model in ("spycat4k", "spycat4kcombo", "gbquad4k") SystemInfo["HAVEEDIDDECODE"] = fileCheck( "/proc/stb/hdmi/raw_edid") and fileCheck("/usr/bin/edid-decode") SystemInfo["HaveRCA"] = getHaveRCA() == "True" SystemInfo["HaveDVI"] = getHaveDVI() == "True" SystemInfo["HaveAVJACK"] = getHaveAVJACK() == "True" SystemInfo["HAVESCART"] = getHaveSCART() == "True" SystemInfo["HAVESCARTYUV"] = getHaveSCARTYUV() == "True" SystemInfo["HAVEYUV"] = getHaveYUV() == "True" SystemInfo["HAVEHDMI"] = getHaveHDMI() == "True" SystemInfo["HasMMC"] = fileHas( "/proc/cmdline", "root=/dev/mmcblk") or "mmcblk" in getMachineMtdRoot() SystemInfo["CanProc"] = SystemInfo["HasMMC"] and getBrandOEM() != "vuplus" SystemInfo["HasHiSi"] = pathExists("/proc/hisi") SystemInfo["canMultiBoot"] = MultiBoot.getBootSlots() SystemInfo["RecoveryMode"] = fileCheck( "/proc/stb/fp/boot_mode") or MultiBoot.hasRecovery() SystemInfo["HasMMC"] = fileHas( "/proc/cmdline", "root=/dev/mmcblk") or MultiBoot.canMultiBoot() and fileHas( "/proc/cmdline", "root=/dev/sda") SystemInfo["HasSDmmc"] = MultiBoot.canMultiBoot( ) and "sd" in MultiBoot.getBootSlots()["2"] and "mmcblk" in getMachineMtdRoot( ) SystemInfo["HasSDswap"] = getMachineBuild() in ( "h9", "i55plus") and pathExists("/dev/mmcblk0p1") SystemInfo["HasFullHDSkinSupport"] = model not in ("et4000", "et5000", "sh1", "hd500c", "hd1100", "xp1000", "lc") SystemInfo["CanProc"] = SystemInfo["HasMMC"] and getBrandOEM() != "vuplus"
# ] # BoxInfo.setItem("InformationDistributionWelcome", welcome) BoxInfo.setItem("12V_Output", Misc_Options.getInstance().detected_12V_output()) #FIXME : Do we need this? BoxInfo.setItem("3DMode", fileCheck("/proc/stb/fb/3dmode") or fileCheck("/proc/stb/fb/primary/3d")) BoxInfo.setItem("3DZNorm", fileCheck("/proc/stb/fb/znorm") or fileCheck("/proc/stb/fb/primary/zoffset")) BoxInfo.setItem("7segment", DISPLAYTYPE in ("7segment",)) BoxInfo.setItem("AmlogicFamily", SOC_FAMILY.startswith(("aml", "meson")) or exists("/proc/device-tree/amlogic-dt-id") or exists("/usr/bin/amlhalt") or exists("/sys/module/amports")) BoxInfo.setItem("ArchIsARM64", ARCHITECTURE == "aarch64" or "64" in ARCHITECTURE) BoxInfo.setItem("ArchIsARM", ARCHITECTURE.startswith(("arm", "cortex"))) BoxInfo.setItem("Blindscan", isPluginInstalled("Blindscan")) BoxInfo.setItem("BoxName", GetBoxName()) canImageBackup = not MODEL.startswith('az') and not BRAND.startswith('cube') and not BRAND.startswith('wetek') and not MODEL.startswith('alien') BoxInfo.setItem("canImageBackup", canImageBackup) BoxInfo.setItem("CanMeasureFrontendInputPower", eDVBResourceManager.getInstance().canMeasureFrontendInputPower()) BoxInfo.setItem("canMultiBoot", MultiBoot.getBootSlots()) BoxInfo.setItem("CanNotDoSimultaneousTranscodeAndPIP", MODEL in ("vusolo4k", "gbquad4k", "gbue4k")) BoxInfo.setItem("canRecovery", MODEL in ("hd51", "vs1500", "h7", "8100s") and ("disk.img", "mmcblk0p1") or MODEL in ("xc7439", "osmio4k", "osmio4kplus", "osmini4k") and ("emmc.img", "mmcblk1p1") or MODEL in ("gbmv200", "cc1", "sf8008", "sf8008m", "sf8008opt", "sx988", "ustym4kpro", "ustym4kottpremium", "beyonwizv2", "viper4k", "og2ott4k") and ("usb_update.bin", "none")) BoxInfo.setItem("CanUse3DModeChoices", fileExists("/proc/stb/fb/3dmode_choices") and True or False) BoxInfo.setItem("CIHelper", fileExists("/usr/bin/cihelper")) BoxInfo.setItem("DeepstandbySupport", MODEL != 'dm800') BoxInfo.setItem("DefaultDisplayBrightness", MODEL in ("dm900", "dm920") and 8 or 5) BoxInfo.setItem("FBLCDDisplay", fileCheck("/proc/stb/fb/sd_detach")) BoxInfo.setItem("Fan", fileCheck("/proc/stb/fp/fan")) BoxInfo.setItem("FanPWM", BoxInfo.getItem("Fan") and fileCheck("/proc/stb/fp/fan_pwm")) BoxInfo.setItem("ForceLNBPowerChanged", fileCheck("/proc/stb/frontend/fbc/force_lnbon")) BoxInfo.setItem("ForceToneBurstChanged", fileCheck("/proc/stb/frontend/fbc/force_toneburst")) BoxInfo.setItem("FrontpanelDisplay", fileExists("/dev/dbox/oled0") or fileExists("/dev/dbox/lcd0")) BoxInfo.setItem("GBWOL", fileExists("/usr/bin/gigablue_wol")) BoxInfo.setItem("grautec", fileExists("/tmp/usbtft")) BoxInfo.setItem("GraphicLCD", MODEL in ("vuultimo", "xpeedlx3", "et10000", "mutant2400", "quadbox2400", "sezammarvel", "atemionemesis", "mbultra", "beyonwizt4", "osmio4kplus"))
def checkMedia(self, retval): if retval: if not 'backup' in str(retval): if MultiBoot.canMultiBoot(): self.multibootslot = retval[0] self.session.openWithCallback(self.backupQuestionCB, MessageBox, _('Backup Settings') + '?', default=True, timeout=10) return def findmedia(paths): def avail(path): if not '/mmc' in path and os.path.isdir( path) and os.access(path, os.W_OK): try: statvfs = os.statvfs(path) return (statvfs.f_bavail * statvfs.f_frsize) / (1 << 20) except: pass def checkIfDevice(path, diskstats): st_dev = os.stat(path).st_dev return (os.major(st_dev), os.minor(st_dev)) in diskstats diskstats = [(int(x[0]), int(x[1])) for x in [ x.split()[0:3] for x in open('/proc/diskstats').readlines() ] if x[2].startswith("sd")] for path in paths: if os.path.isdir(path) and checkIfDevice( path, diskstats) and avail(path) > 500: return (path, True) mounts = [] devices = [] for path in ['/media/%s' % x for x in os.listdir('/media')] + ([ '/media/net/%s' % x for x in os.listdir('/media/net') ] if os.path.isdir('/media/net') else []): if checkIfDevice(path, diskstats): devices.append((path, avail(path))) else: mounts.append((path, avail(path))) devices.sort(key=lambda x: x[1], reverse=True) mounts.sort(key=lambda x: x[1], reverse=True) return ((devices[0][1] > 500 and (devices[0][0], True)) if devices else mounts and mounts[0][1] > 500 and (mounts[0][0], False)) or (None, None) self.destination, isDevice = findmedia( ["/media/hdd", "/media/usb"]) if self.destination: destination = os.path.join(self.destination, 'images') self.zippedimage = "://" in self.source and os.path.join( destination, self.imagename) or self.source self.unzippedimage = os.path.join( destination, '%s.unzipped' % self.imagename[:-4]) try: if os.path.isfile(destination): os.remove(destination) if not os.path.isdir(destination): os.mkdir(destination) if isDevice or 'no_backup' == retval: self.startBackupsettings(retval) else: self.session.openWithCallback( self.startBackupsettings, MessageBox, _("Can only find a network drive to store the backup this means after the flash the autorestore will not work. Alternatively you can mount the network drive after the flash and perform a manufacturer reset to autorestore" ), simple=True) except: self.session.openWithCallback( self.abort, MessageBox, _("Unable to create the required directories on the media (e.g. USB stick or Harddisk) - Please verify media and try again!" ), type=MessageBox.TYPE_ERROR, simple=True) else: self.session.openWithCallback( self.abort, MessageBox, _("Could not find suitable media - Please remove some downloaded images or insert a media (e.g. USB stick) with sufficient free space and try again!" ), type=MessageBox.TYPE_ERROR, simple=True) else: self.abort()