コード例 #1
0
class RunSoftwareUpdate(Screen, HelpableScreen):
    skin = """
	<screen name="RunSoftwareUpdate" position="center,center" size="720,435" resolution="1280,720">
		<widget name="update" position="10,10" size="700,400" font="Regular;20" halign="center" transparent="1" valign="center" />
		<widget name="activity" position="10,420" size="700,5" />
	</screen>"""

    def __init__(self, session, *args):
        Screen.__init__(self, session)
        HelpableScreen.__init__(self)
        self.setTitle(_("Software Update"))
        self.onTimerTick = []
        self["update"] = ScrollLabel(
            _("Software update starting, please wait.\n\n"))
        self["activity"] = Slider(0, 100)
        self["actions"] = HelpableActionMap(
            self,
            ["OkCancelActions", "NavigationActions"],
            {
                "cancel":
                (self.keyCancel, _("Stop the update, if running, then exit")),
                "ok":
                (self.keyCancel, _("Stop the update, if running, then exit")),
                "top": (self.top, _("Move to first line / screen")),
                "pageUp": (self.pageUp, _("Move up a page / screen")),
                "up": (self.pageUp, _("Move up a page / screen")),
                # "first": (self.top, _("Move to first line / screen")),
                "left": (self.pageUp, _("Move up a page / screen")),
                "right": (self.pageDown, _("Move down a page / screen")),
                # "last": (self.bottom, _("Move to last line / screen")),
                "down": (self.pageDown, _("Move down a page / screen")),
                "pageDown": (self.pageDown, _("Move down a page / screen")),
                "bottom": (self.bottom, _("Move to last line / screen"))
            },
            prio=0,
            description=_("Software Update Actions"))
        self.activity = 0
        self.timer = eTimer()
        self.timer.callback.append(self.timeout)
        self.packageTotal = 0
        self.downloadCount = 0
        self.updateCount = 0
        self.installCount = 0
        self.removeCount = 0
        self.deselectCount = 0
        self.upgradeCount = 0
        self.configureCount = 0
        self.errorCount = 0
        self.updateFlag = True
        self.opkg = OpkgComponent()
        self.opkg.addCallback(self.opkgCallback)
        self.onLayoutFinish.append(self.layoutFinished)

    def layoutFinished(self):
        self.opkg.startCmd(OpkgComponent.CMD_UPDATE)
        self.timer.start(25, True)

    def timeout(self):
        if self.activity < 0:
            self.timer.stop()
            self["activity"].hide()
        else:
            self.activity += 1
            if self.activity == 100:
                self.activity = 0
            self["activity"].setValue(self.activity)
            self.timer.start(100, True)
        for callback in self.onTimerTick:
            callback()

    def opkgCallback(self, event, parameter):
        if event == OpkgComponent.EVENT_DOWNLOAD:
            self.downloadCount += 1
            if parameter.find(
                    "_"
            ) == -1:  # Only display the downloading of the feed packages.
                self["update"].appendText("%s: '%s'.\n" %
                                          (_("Downloading"), parameter))
        elif event == OpkgComponent.EVENT_UPDATED:
            self.updateCount += 1
            self["update"].appendText("%s: %s\n" % (_("Updated"), parameter))
        elif event == OpkgComponent.EVENT_UPVERSION:
            self.upgradeCount += 1
            self["update"].appendText("%s %s/%s: '%s'.\n" %
                                      (_("Updating"), self.upgradeCount,
                                       self.packageTotal, parameter))
        elif event == OpkgComponent.EVENT_INSTALL:
            self.installCount += 1
            self["update"].appendText("%s: '%s'.\n" %
                                      (_("Installing"), parameter))
        elif event == OpkgComponent.EVENT_REMOVE:
            self.removeCount += 1
            self["update"].appendText("%s: '%s'.\n" %
                                      (_("Removing"), parameter))
        elif event == OpkgComponent.EVENT_CONFIGURING:
            self.configureCount += 1
            self["update"].appendText("%s: '%s'.\n" %
                                      (_("Configuring"), parameter))
        elif event == OpkgComponent.EVENT_MODIFIED:
            if config.plugins.softwaremanager.overwriteConfigFiles.value in (
                    "N", "Y"):
                self.opkg.write(
                    True and
                    config.plugins.softwaremanager.overwriteConfigFiles.value)
            else:
                self.session.openWithCallback(
                    self.modificationCallback, MessageBox,
                    _("Configuration file '%s' has been modified since it was installed, would you like to keep the modified version?"
                      ) % parameter)
        elif event == OpkgComponent.EVENT_ERROR:
            self.errorCount += 1
        elif event == OpkgComponent.EVENT_DONE:
            if self.updateFlag:
                self.updateFlag = False
                self.opkg.startCmd(OpkgComponent.CMD_UPGRADE_LIST)
            elif self.opkg.currentCommand == OpkgComponent.CMD_UPGRADE_LIST:
                self.packageTotal = len(self.opkg.getFetchedList())
                if self.packageTotal:
                    self.opkg.startCmd(OpkgComponent.CMD_UPGRADE,
                                       args={"testMode": False})
                else:
                    self.activity = -1
                    self["update"].appendText(
                        "%s\n\n%s" %
                        (_("No updates available."),
                         _("Press OK on your remote control to continue.")))
            else:
                if self.errorCount == 0:
                    self["update"].appendText("\n%s\n\n" %
                                              _("Update completed."))
                    self["update"].appendText(
                        "%s\n" %
                        ngettext("%d package was identified for upgrade.",
                                 "%d packages were identified for upgrade.",
                                 self.packageTotal) % self.packageTotal)
                    self["update"].appendText("%s\n" % ngettext(
                        "%d package was downloaded.",
                        "%d packages were downloaded.", self.downloadCount) %
                                              self.downloadCount)
                    self["update"].appendText(
                        "%s\n" %
                        ngettext("%d feed catalog package was updated.",
                                 "%d feed catalog packages were updated.",
                                 self.updateCount) % self.updateCount)
                    self["update"].appendText("%s\n" % ngettext(
                        "%d package was installed.",
                        "%d packages were installed.", self.installCount) %
                                              self.installCount)
                    self["update"].appendText("%s\n" % ngettext(
                        "%d package was removed.", "%d packages were removed.",
                        self.removeCount) % self.removeCount)
                    self["update"].appendText("%s\n" % ngettext(
                        "%d package was upgraded.",
                        "%d packages were upgraded.", self.upgradeCount) %
                                              self.upgradeCount)
                    self["update"].appendText("%s\n" % ngettext(
                        "%d package was configured.",
                        "%d packages were configured.", self.configureCount) %
                                              self.configureCount)
                    if self.deselectCount:
                        self["update"].appendText(
                            "%s\n" % ngettext("%d package was deselected.",
                                              "%d packages were deselected.",
                                              self.deselectCount) %
                            self.deselectCount)
                        self["update"].appendText("\n%s\n" % _(
                            "Deselected packages usually occur because those packaged are incompatible with existing packages.  While this is mostly harmless it is possible that your %s %s may experience issues."
                        ) % (displayBrand, displayModel))
                else:
                    error = _(
                        "Your receiver might be unusable now.  Please consult the manual for further assistance before rebooting your %s %s."
                    ) % (displayBrand, displayModel)
                    if self.upgradeCount == 0:
                        error = _(
                            "No updates were available.  Please try again later."
                        )
                    self["update"].appendText("%s: %s\n" % (_("Error"), error))
                self.activity = -1
                self["update"].appendText(
                    "\n%s" % _("Press OK on your remote control to continue."))

    def modificationCallback(self, answer):
        self.opkg.write("N" if answer else "Y")

    def keyCancel(self):
        if self.opkg.isRunning():
            self.opkg.stop()
        self.opkg.removeCallback(self.opkgCallback)
        if self.upgradeCount != 0 and self.errorCount == 0:
            self.restoreMetrixHD()
        else:
            self.close()

    def keyCancelCallback(self, answer):
        if answer:
            self.session.open(TryQuitMainloop, retvalue=QUIT_REBOOT)
        self.close()

    def top(self):
        self["update"].moveTop()

    def pageUp(self):
        self["update"].pageUp()

    def pageDown(self):
        self["update"].pageDown()

    def bottom(self):
        self["update"].moveBottom()

    def createSummary(self):
        return RunSoftwareUpdateSummary

    def restoreMetrixHD(
        self
    ):  # TODO: call this only after metrix update / move this to Metrix Plugin
        try:
            if config.skin.primary_skin.value == "MetrixHD/skin.MySkin.xml":
                if not exists("/usr/share/enigma2/MetrixHD/skin.MySkin.xml"):
                    from Plugins.SystemPlugins.SoftwareManager.BackupRestore import RestoreMyMetrixHD
                    self.session.openWithCallback(self.restoreMetrixHDCallback,
                                                  RestoreMyMetrixHD)
                    return
                elif config.plugins.MyMetrixLiteOther.EHDenabled.value != '0':
                    from Plugins.Extensions.MyMetrixLite.ActivateSkinSettings import ActivateSkinSettings
                    ActivateSkinSettings().RefreshIcons()
        except:
            pass
        self.restoreMetrixHDCallback()

    def restoreMetrixHDCallback(self, ret=None):
        self.session.openWithCallback(
            self.keyCancelCallback, MessageBox,
            _("Upgrade finished.") + " " +
            _("Do you want to reboot your %s %s?") %
            (displayBrand, displayModel))
コード例 #2
0
class SoftwareUpdate(Screen, HelpableScreen, ProtectedScreen):
    FEED_UNKNOWN = 0
    FEED_DISABLED = 1
    FEED_UNSTABLE = 2
    FEED_STABLE = 3

    skin = [
        """
	<screen name="SoftwareUpdate" title="Software Update" position="center,center" size="%d,%d" >
		<widget name="traffic_off" position="%d,%d" size="%d,%d" alphatest="blend" pixmap="icons/traffic_off.png" scale="1" />
		<widget name="traffic_red" position="%d,%d" size="%d,%d" alphatest="blend" pixmap="icons/traffic_red.png" scale="1" />
		<widget name="traffic_yellow" position="%d,%d" size="%d,%d" alphatest="blend" pixmap="icons/traffic_yellow.png" scale="1" />
		<widget name="traffic_green" position="%d,%d" size="%d,%d" alphatest="blend" pixmap="icons/traffic_green.png" scale="1" />
		<widget name="feedstatus_off" position="%d,%d" size="%d,%d" font="Regular;%d" transparent="1" valign="center" />
		<widget name="feedstatus_red" position="%d,%d" size="%d,%d" font="Regular;%d" transparent="1" valign="center" />
		<widget name="feedstatus_yellow" position="%d,%d" size="%d,%d" font="Regular;%d" transparent="1" valign="center" />
		<widget name="feedstatus_green" position="%d,%d" size="%d,%d" font="Regular;%d" transparent="1" valign="center" />
		<widget name="package_text" position="%d,%d" size="%d,%d" font="Regular;%d" transparent="1" valign="center" />
		<widget name="package_count" position="%d,%d" size="%d,%d" font="Regular;%d" halign="right" transparent="1" valign="center" />
		<widget name="feedmessage" position="%d,%d" size="%d,%d" font="Regular;%d" transparent="1" />
		<widget name="activity" position="%d,%d" size="%d,%d" />
		<widget source="list" render="Listbox" position="%d,%d" size="%d,%d" scrollbarMode="showOnDemand">
			<convert type="TemplatedMultiContent">
				{
				"template":
					[
					MultiContentEntryText(pos = (%d, %d), size = (%d, %d), font=0, flags = RT_HALIGN_LEFT | RT_VALIGN_CENTER, text = 0),  # Index 0 is the name.
					MultiContentEntryText(pos = (%d, %d), size = (%d, %d), font=1, flags = RT_HALIGN_LEFT | RT_VALIGN_CENTER, text = 2),  # Index 2 is the description.
					MultiContentEntryPixmapAlphaBlend(pos = (%d, %d), size = (%d, %d), flags = BT_SCALE, png = 4),  # Index 4 is the status pixmap.
					MultiContentEntryPixmapAlphaBlend(pos = (%d, %d), size = (%d, %d), png = 5),  # Index 5 is the div pixmap
					],
				"fonts": [gFont("Regular", %d), gFont("Regular", %d)],
				"itemHeight": %d
				}
			</convert>
		</widget>
		<widget source="key_red" render="Label" position="%d,e-%d" size="%d,%d" backgroundColor="key_red" font="Regular;%d" foregroundColor="key_text" halign="center" valign="center">
			<convert type="ConditionalShowHide" />
		</widget>
		<widget source="key_green" render="Label" position="%d,e-%d" size="%d,%d" backgroundColor="key_green" font="Regular;%d" foregroundColor="key_text" halign="center" valign="center">
			<convert type="ConditionalShowHide" />
		</widget>
		<widget source="key_yellow" render="Label" position="%d,e-%d" size="%d,%d" backgroundColor="key_yellow" font="Regular;%d" foregroundColor="key_text" halign="center" valign="center">
			<convert type="ConditionalShowHide" />
		</widget>
	</screen>""",
        650,
        580,  # SoftwareUpdate
        10,
        10,
        36,
        97,  # traffic_off
        10,
        10,
        36,
        97,  # traffic_red
        10,
        10,
        36,
        97,  # traffic_yellow
        10,
        10,
        36,
        97,  # traffic_green
        60,
        46,
        200,
        30,
        20,  # feedstatus_off
        60,
        14,
        200,
        30,
        20,  # feedstatus_red
        60,
        46,
        200,
        30,
        20,  # feedstatus_yellow
        60,
        78,
        200,
        30,
        20,  # feedstatus_green
        330,
        10,
        250,
        30,
        25,  # package_text
        590,
        10,
        50,
        30,
        25,  # package_count
        330,
        50,
        310,
        50,
        20,  # feedmessage
        330,
        102,
        310,
        5,  # activity
        10,
        120,
        630,
        400,  # list
        10,
        0,
        535,
        30,  # Index 0 - name
        20,
        30,
        515,
        20,  # Index 2 - description
        560,
        0,
        48,
        48,  # Index 4 - status pixmap
        5,
        48,
        630,
        2,  # Index 5 - div pixmap
        22,
        15,  # fonts
        50,  # itemHeight
        10,
        50,
        180,
        40,
        20,  # key_red
        200,
        50,
        180,
        40,
        20,  # key_green
        390,
        50,
        180,
        40,
        20  # key_yellow
    ]

    def __init__(self, session, *args):
        Screen.__init__(self, session)
        HelpableScreen.__init__(self)
        ProtectedScreen.__init__(self)
        Screen.setTitle(self, _("Software Update"))
        self.onCheckTrafficLight = []
        self.updateList = []
        self["list"] = List(self.updateList, enableWrapAround=True)
        self["key_red"] = StaticText(_("Cancel"))
        self["key_green"] = StaticText("")
        self["key_yellow"] = StaticText("")
        self["traffic_off"] = Pixmap()
        self["traffic_red"] = Pixmap()
        self["traffic_red"].hide()
        self["traffic_yellow"] = Pixmap()
        self["traffic_yellow"].hide()
        self["traffic_green"] = Pixmap()
        self["traffic_green"].hide()
        self["feedstatus_off"] = Label(_("Status unavailable!"))
        self["feedstatus_off"].hide()
        self["feedstatus_red"] = Label("< %s" % _("Feed disabled!"))
        self["feedstatus_red"].hide()
        self["feedstatus_yellow"] = Label("< %s" % _("Feed unstable!"))
        self["feedstatus_yellow"].hide()
        self["feedstatus_green"] = Label("< %s" % _("Feed stable."))
        self["feedstatus_green"].hide()
        self["feedmessage"] = Label()
        self["package_text"] = Label(_("Updates available:"))
        self["package_count"] = Label("?")
        self["activity"] = Slider(0, 100)
        cancelMsg = _("Cancel / Close the software update screen")
        updateMsg = _("Proceed with the update")
        self["actions"] = HelpableActionMap(
            self,
            ["OkCancelActions", "ColorActions", "NavigationActions"],
            {
                "cancel": (self.keyCancel, cancelMsg),
                "red": (self.keyCancel, cancelMsg),
                "top": (self.top, _("Move to first line / screen")),
                "pageUp": (self.pageUp, _("Move up a page / screen")),
                "up": (self.up, _("Move up a line")),
                # "first": (self.top, _("Move to first line / screen")),
                "left": (self.pageUp, _("Move up a page / screen")),
                "right": (self.pageDown, _("Move down a page / screen")),
                # "last": (self.bottom, _("Move to last line / screen")),
                "down": (self.down, _("Move down a line")),
                "pageDown": (self.pageDown, _("Move down a page / screen")),
                "bottom": (self.bottom, _("Move to last line / screen"))
            },
            prio=0,
            description=_("Software Update Actions"))
        self["updateActions"] = HelpableActionMap(
            self, ["OkCancelActions", "ColorActions"], {
                "ok": (self.keyUpdate, updateMsg),
                "green": (self.keyUpdate, updateMsg)
            },
            prio=0,
            description=_("Software Update Actions"))
        self["updateActions"].setEnabled(False)
        self["refreshActions"] = HelpableActionMap(
            self, ["ColorActions"], {
                "yellow":
                (self.keyRefresh, _("Refresh the update-able package list"))
            },
            prio=0,
            description=_("Software Update Actions"))
        self["refreshActions"].setEnabled(False)
        self.activity = 0
        self.feedState = self.FEED_UNKNOWN
        self.updateFlag = True
        self.packageCount = 0
        self.timer = eTimer()
        self.timer.callback.append(self.timeout)
        self.timer.callback.append(self.checkTrafficLight)
        self.opkg = OpkgComponent()
        self.opkg.addCallback(self.opkgCallback)
        self.onLayoutFinish.append(self.layoutFinished)

    def isProtected(self):
        return config.ParentalControl.setuppinactive.value and \
         (not config.ParentalControl.config_sections.main_menu.value and not config.ParentalControl.config_sections.configuration.value or hasattr(self.session, "infobar") and self.session.infobar is None) and \
         config.ParentalControl.config_sections.software_update.value

    def layoutFinished(self):
        self["list"].master.master.instance.allowNativeKeys(False)
        self.setStatus("update")
        self.opkg.startCmd(OpkgComponent.CMD_UPDATE)
        self.timer.start(25, True)

    def timeout(self):
        if self.activity < 0:
            self.timer.stop()
            self["activity"].hide()
        else:
            self.activity += 1
            if self.activity == 100:
                self.activity = 0
            self["activity"].setValue(self.activity)
            self.timer.start(100, True)

    def checkTrafficLight(self):
        self.timer.callback.remove(self.checkTrafficLight)
        try:
            #			status = dict(load(urlopen("%s/%s.php" % (BoxInfo.getItem("feedsurl"), BoxInfo.getItem("model")), timeout=5)))
            #			message = status.get("message")
            #			status = status.get("status")
            status = ""
            message = ""
            with urlopen("http://ampel.mynonpublic.com/Ampel/index.php") as fd:
                tmpStatus = fd.read()
                if b"rot.png" in tmpStatus:
                    status = "YELLOW" if exists("/etc/.beta") else "RED"
                elif b"gelb.png" in tmpStatus:
                    status = "YELLOW"
                elif b"gruen.png" in tmpStatus:
                    status = "GREEN"
            self["traffic_off"].hide()
            if status == "RED":
                self["traffic_red"].show()
                self["feedstatus_red"].show()
                self.feedState = self.FEED_DISABLED
            elif status == "YELLOW":
                self["traffic_yellow"].show()
                self["feedstatus_yellow"].show()
                self.feedState = self.FEED_UNSTABLE
            elif status == "GREEN":
                self["traffic_green"].show()
                self["feedstatus_green"].show()
                self.feedState = self.FEED_STABLE
            if message:
                self["feedmessage"].setText(_(message))
        except Exception as err:
            print(
                "[SoftwareUpdate] Error: Unable to get server status!  (%s)" %
                str(err))
            self["feedstatus_off"].show()
        for callback in self.onCheckTrafficLight:
            callback()

    def opkgCallback(self, event, parameter):
        if event == OpkgComponent.EVENT_ERROR:
            self.setStatus("error")
            self.activity = -1
        elif event == OpkgComponent.EVENT_DONE:
            if self.updateFlag:
                self.updateFlag = False
                self.opkg.startCmd(OpkgComponent.CMD_UPGRADE_LIST)
            else:
                self.updateList = []
                fetchedList = self.opkg.getFetchedList()
                count = len(fetchedList)
                if count > 0:
                    upgradeablePng = LoadPixmap(cached=True,
                                                path=resolveFilename(
                                                    SCOPE_GUISKIN,
                                                    "icons/upgradeable.png"))
                    divPng = LoadPixmap(cached=True,
                                        path=resolveFilename(
                                            SCOPE_GUISKIN, "div-h.png"))
                    for fetched in fetchedList:
                        oldVer = fetched[1] if fetched[1] else _(
                            "Current version unknown")
                        newVer = fetched[2] if fetched[2] else _(
                            "Updated version unknown")
                        self.updateList.append(
                            (fetched[0], fetched[1],
                             "%s  ->  %s" % (oldVer, newVer), "upgradeable",
                             upgradeablePng, divPng))
                    if self.updateList:
                        self.updateList.sort(
                            key=lambda x: x[0])  # Sort by package name.
                        self["list"].setList(self.updateList)
                    else:
                        self.setStatus("noupdate")
                elif count == 0:
                    self.setStatus("noupdate")
                else:
                    self.setStatus("error")
                self.packageCount = len(self.updateList)
                print("[SoftwareUpdate] %d packages available for update." %
                      self.packageCount)
                self["package_count"].setText(str(self.packageCount))
                for callback in self.onCheckTrafficLight:
                    callback()
                if self.packageCount:
                    if self.feedState == self.FEED_DISABLED:
                        self["key_red"].setText(_("Close"))
                        self["key_green"].setText("")
                        self["updateActions"].setEnabled(False)
                    else:
                        self["key_red"].setText(_("Cancel"))
                        self["key_green"].setText(_("Update"))
                        self["updateActions"].setEnabled(True)
                else:
                    self["key_red"].setText(_("Close"))
                self["key_yellow"].setText(_("Refresh"))
                self["refreshActions"].setEnabled(True)
                self.activity = -1

    def setStatus(self, status):
        if status == "update":
            imagePath = resolveFilename(SCOPE_GUISKIN, "icons/upgrade.png")
            name = _("Package list update")
            description = _("Downloading latest update list.  Please wait...")
        elif status == "error":
            imagePath = resolveFilename(SCOPE_GUISKIN, "icons/remove.png")
            name = _("Download error")
            description = _(
                "There was an error downloading the update list.  Please try again."
            )
        elif status == "noupdate":
            imagePath = resolveFilename(SCOPE_GUISKIN, "icons/installed.png")
            name = _("Nothing to upgrade")
            description = _("There are no updates available.")
        statusPng = LoadPixmap(cached=True, path=imagePath)
        divPng = LoadPixmap(cached=True,
                            path=resolveFilename(SCOPE_GUISKIN, "div-h.png"))
        self["list"].setList([(name, "", description, "", statusPng, divPng)])

    def keyCancel(self):
        if self.opkg.isRunning():
            self.opkg.stop()
        self.opkg.removeCallback(self.opkgCallback)
        self.close()

    def keyUpdate(self):
        self.opkg.removeCallback(self.opkgCallback)
        updateLimit = BoxInfo.getItem("UpdateLimit", 200)
        if self.packageCount <= updateLimit:
            self.keyUpdateCallback(2)
        else:
            print(
                "[SoftwareUpdate] Warning: There are %d packages available, more than the %d maximum recommended, for an update!"
                % (self.packageCount, updateLimit))
            message = [
                _("Warning: There are %d update packages!") %
                self.packageCount,
                _("There is a risk that your %s %s will not boot or may malfunction after such a large on-line update."
                  ) % (displayBrand, displayModel),
                _("You should flash a new image!"),
                _("What would you like to do?")
            ]
            message = "\n\n".join(message)
            optionList = [(_("Cancel the update"), 0),
                          (_("Perform an on-line flash instead"), 1),
                          (_("Continue with the on-line update"), 2)]
            self.session.openWithCallback(self.keyUpdateCallback,
                                          MessageBox,
                                          message,
                                          list=optionList,
                                          default=0)

    def keyUpdateCallback(self, answer):
        if answer == 1:
            from Screens.FlashManager import FlashManager  # This must be here to ensure the plugin is initialized.
            self.session.open(FlashManager)
        elif answer == 2:
            self.session.open(RunSoftwareUpdate)
        self.close()

    def keyRefresh(self):
        self.timer.callback.append(self.checkTrafficLight)
        self["key_red"].setText(_("Cancel"))
        self["key_green"].setText("")
        self["key_yellow"].setText("")
        self["updateActions"].setEnabled(False)
        self["refreshActions"].setEnabled(False)
        self["package_count"].setText("?")
        self["traffic_off"].show()
        self["traffic_red"].hide()
        self["traffic_yellow"].hide()
        self["traffic_green"].hide()
        self["feedstatus_off"].hide()
        self["feedstatus_red"].hide()
        self["feedstatus_yellow"].hide()
        self["feedstatus_green"].hide()
        self["feedmessage"].setText("")
        self.activity = 0
        self["activity"].setValue(self.activity)
        self["activity"].show()
        self.setStatus("update")
        self.opkg.startCmd(OpkgComponent.CMD_UPDATE)
        self.timer.start(25, True)

    def top(self):
        self["list"].top()

    def pageUp(self):
        self["list"].pageUp()

    def up(self):
        self["list"].up()

    def down(self):
        self["list"].down()

    def pageDown(self):
        self["list"].pageDown()

    def bottom(self):
        self["list"].bottom()

    def createSummary(self):
        return SoftwareUpdateSummary
コード例 #3
0
class ShowSoftcamPackages(Screen):
	skin = """
	<screen name="ShowSoftcamPackages" position="center,center" size="630,500" resolution="1280,720">
		<widget source="list" render="Listbox" position="10,10" size="620,420" enableWrapAround="1" scrollbarMode="showOnDemand">
			<convert type="TemplatedMultiContent">
				{
				"template":
					[
						MultiContentEntryText(pos = (5, 1), size = (540, 28), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
						MultiContentEntryText(pos = (5, 26), size = (540, 20), font=1, flags = RT_HALIGN_LEFT, text = 2), # index 2 is the description
						MultiContentEntryPixmapAlphaBlend(pos = (545, 2), size = (48, 48), png = 4), # index 3 is the status pixmap
						MultiContentEntryPixmapAlphaBlend(pos = (5, 50), size = (510, 2), png = 5), # index 4 is the div pixmap
					],
				"fonts": [gFont("Regular", 22),gFont("Regular", 14)],
				"itemHeight": 52
				}
			</convert>
		</widget>
		<widget source="key_red" render="Label" position="10,e-50" size="140,40" backgroundColor="key_red" font="Regular;20" foregroundColor="key_text" halign="center" valign="center">
			<convert type="ConditionalShowHide" />
		</widget>
		<widget source="key_green" render="Label" position="160,e-50" size="140,40" backgroundColor="key_green" font="Regular;20" foregroundColor="key_text" halign="center" valign="center">
			<convert type="ConditionalShowHide" />
		</widget>
		<widget source="key_yellow" render="Label" position="310,e-50" size="140,40" backgroundColor="key_yellow" font="Regular;20" foregroundColor="key_text" halign="center" valign="center">
			<convert type="ConditionalShowHide" />
		</widget>
	</screen>"""

	def __init__(self, session, args=None):
		Screen.__init__(self, session)
		self.setTitle(_("Install Softcams"))

		self["actions"] = HelpableActionMap(self, ["OkCancelActions", "NavigationActions", "ColorActions"], {
			"cancel": (self.keyCancel, _("Stop the update, if running, then exit")),
			"ok": (self.keyOk, _("Install/Remove plugin")),
			"green": (self.keyOk, _("Install/Remove plugin")),
			"top": (self.top, _("Move to first line / screen")),
			"pageUp": (self.pageUp, _("Move up a page / screen")),
			"up": (self.pageUp, _("Move up a page / screen")),
			# "first": (self.top, _("Move to first line")),
			"left": (self.pageUp, _("Move up a page / screen")),
			"right": (self.pageDown, _("Move down a page / screen")),
			# "last": (self.bottom, _("Move to last line")),
			"down": (self.pageDown, _("Move down a page / screen")),
			"pageDown": (self.pageDown, _("Move down a page / screen")),
			"bottom": (self.bottom, _("Move to last line / screen")),
			"yellow": (self.keyRefresh, _("Refresh the update-able package list"))
		}, prio=0, description=_("Software Update Actions"))

		self["list"] = List([])
		self["list"].onSelectionChanged.append(self.selectionChanged)
		self["key_red"] = StaticText(_("Close"))
		self["key_yellow"] = StaticText(_("Reload"))
		self["key_green"] = StaticText(_("Install"))
		self.installpackage = None
		self.opkg = OpkgComponent()
		self.opkg.addCallback(self.opkgCallback)
		self.onLayoutFinish.append(self.layoutFinished)

	def opkgCallback(self, event, parameter):
		if event == OpkgComponent.EVENT_DONE:
			if self.opkg.currentCommand == OpkgComponent.CMD_UPDATE:
				self.rebuildList()
			elif self.opkg.currentCommand == OpkgComponent.CMD_LIST:
				self.Flist = self.opkg.getFetchedList()
				self.opkg.startCmd(OpkgComponent.CMD_LIST_INSTALLED, args={"package": "enigma2-plugin-softcams-*"})
			elif self.opkg.currentCommand == OpkgComponent.CMD_LIST_INSTALLED:
				self.Elist = self.opkg.getFetchedList()
				if len(self.Flist) > 0:
					self.buildPacketList()
				else:
					self.setStatus('error')
			elif self.opkg.currentCommand == OpkgComponent.CMD_INSTALL:
				self.session.open(MessageBox, _("Install Finished."), MessageBox.TYPE_INFO, timeout=5)
				self.rebuildList()
			elif self.opkg.currentCommand == OpkgComponent.CMD_REMOVE:
				self.session.open(MessageBox, _("Remove Finished."), MessageBox.TYPE_INFO, timeout=5)
				self.rebuildList()
		elif event == OpkgComponent.EVENT_ERROR:
			if self.opkg.currentCommand == OpkgComponent.CMD_INSTALL:
				self.session.open(MessageBox, _("Install Failed !!"), MessageBox.TYPE_ERROR, timeout=10)
			elif self.opkg.currentCommand == OpkgComponent.CMD_REMOVE:
				self.session.open(MessageBox, _("Remove Failed !!"), MessageBox.TYPE_ERROR, timeout=10)
			else:
				self.setStatus("error")

	def layoutFinished(self):
		self.rebuildList()


	def selectionChanged(self):
		cur = self["list"].getCurrent()
		if cur and len(cur) > 3:
			self["key_green"].text = _("Install") if cur[3] == "installable" else _("Remove")

	def keyOk(self, returnValue=None):
		cur = self["list"].getCurrent()
		if cur:
			self.installpackage = cur[0]
			if cur[3] == "installable":
				self.session.openWithCallback(self.runInstall, MessageBox, "%s%s - %s\n%s" % (_("Do you want to install the package:\n"), cur[0], cur[1], _("\nPress OK on your remote control to continue.")))
			else:
				self.session.openWithCallback(self.runUnInstall, MessageBox, "%s%s - %s\n%s" % (_("Do you want to remove the package:\n"), cur[0], cur[1], _("\nPress OK on your remote control to continue.")))

	def runInstall(self, result):
		if result and self.installpackage:
			self.opkg.startCmd(OpkgComponent.CMD_INSTALL, {"package": self.installpackage})

	def runUnInstall(self, result):
		if result and self.installpackage:
			self.opkg.startCmd(OpkgComponent.CMD_REMOVE, {"package": self.installpackage})

	def keyCancel(self):
		if self.opkg.isRunning():
			self.opkg.stop()
		self.opkg.removeCallback(self.opkgCallback)
		self.close()

	def setStatus(self, status=None):
		if status:
			image = "upgrade"
			if status == "update":
				name = _("Package list update")
				description = _("Downloading latest update list.  Please wait...")
			elif status == "list":
				name = _("Package list")
				description = _("Getting Softcam list. Please wait...")
			elif status == "error":
				image = "remove"
				name = _("Download error")
				description = _("There was an error downloading the update list.  Please try again.")
			imagePath = resolveFilename(SCOPE_GUISKIN, "icons/%s.png" % image)
			divPng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_GUISKIN, "div-h.png"))
			statusPng = LoadPixmap(cached=True, path=imagePath)
			self['list'].setList([(name, "", description, "", statusPng, divPng)])

	def keyRefresh(self):
		self.setStatus("update")
		self.opkg.startCmd(OpkgComponent.CMD_UPDATE)

	def rebuildList(self):
		self.Flist = []
		self.Elist = []
		self.setStatus("list")
		self.opkg.startCmd(OpkgComponent.CMD_LIST, args={"package": "enigma2-plugin-softcams-*"})

	def buildPacketList(self):
		plist = []
		excludeList = [x[0] for x in self.Elist]
		divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_GUISKIN, "div-h.png"))
		installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_GUISKIN, "icons/installed.png"))
		installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_GUISKIN, "icons/installable.png"))

		if len(self.Flist) > 0:
			for x in self.Flist:
				if len(x) > 1:
					state = "installable" if x[0] not in excludeList else "installed"
					image = installablepng if x[0] not in excludeList else installedpng
					name = x[0]
					version = x[1]
					description = ""
					if len(x) > 2:
						description = x[2]
					plist.append((name, version, _(description), state, image, divpng))
			self['list'].setList(plist)
		else:
			self.setStatus('error')

	def top(self):
		self["list"].top()

	def pageUp(self):
		self["list"].pageUp()

	def up(self):
		self["list"].up()

	def down(self):
		self["list"].down()

	def pageDown(self):
		self["list"].pageDown()

	def bottom(self):
		self["list"].bottom()
コード例 #4
0
class UpdatePlugin(Screen, ProtectedScreen):
	skin = """
		<screen name="UpdatePlugin" position="center,center" size="550,300">
			<widget name="activityslider" position="0,0" size="550,5"  />
			<widget name="slider" position="0,150" size="550,30"  />
			<widget source="package" render="Label" position="10,30" size="540,20" font="Regular;18" halign="center" valign="center" backgroundColor="#25062748" transparent="1" />
			<widget source="status" render="Label" position="10,180" size="540,100" font="Regular;20" halign="center" valign="center" backgroundColor="#25062748" transparent="1" />
		</screen>"""

	def __init__(self, session, *args):
		Screen.__init__(self, session)
		ProtectedScreen.__init__(self)

		self.sliderPackages = { "enigma2": 1, "openvision": 2 }

		self.setTitle(_("Software update"))
		self.slider = Slider(0, 4)
		self["slider"] = self.slider
		self.activityslider = Slider(0, 100)
		self["activityslider"] = self.activityslider
		self.status = StaticText(_("Please wait..."))
		self["status"] = self.status
		self.package = StaticText(_("Package list update"))
		self["package"] = self.package
		self.oktext = _("Press OK on your remote control to continue.")

		self.packages = 0
		self.error = 0
		self.processed_packages = []
		self.total_packages = None

		self.channellist_only = 0
		self.channellist_name = ''
		self.updating = False
		self.opkg = OpkgComponent()
		self.opkg.addCallback(self.opkgCallback)
		self.onClose.append(self.__close)

		self["actions"] = ActionMap(["WizardActions"],
		{
			"ok": self.exit,
			"back": self.exit
		}, -1)

		self.activity = 0
		self.activityTimer = eTimer()
		self.activityTimer.callback.append(self.checkTraficLight)
		self.activityTimer.callback.append(self.doActivityTimer)
		self.activityTimer.start(100, True)

	def isProtected(self):
		return config.ParentalControl.setuppinactive.value and\
			(not config.ParentalControl.config_sections.main_menu.value and not config.ParentalControl.config_sections.configuration.value  or hasattr(self.session, 'infobar') and self.session.infobar is None) and\
			config.ParentalControl.config_sections.software_update.value

	def checkTraficLight(self):
		self.activityTimer.callback.remove(self.checkTraficLight)
		self.activityTimer.start(100, False)
		status = None
		message = None
		abort = False
		picon = MessageBox.TYPE_ERROR
		url = "https://openvision.tech/trafficlight"

		# try to fetch the trafficlight json from the website
		try:
			status = dict(json.load(urlopen(url, timeout=5)))
			print("[SoftwareUpdate] status is: ", status)
		except:
			pass

		# process the status fetched
		if status is not None:

			try:
				# get image version and machine name
				machine = getBoxType()
				version = open("/etc/issue").readlines()[-2].split()[1]

				# do we have an entry for this version
				if version in status and machine in status[version]['machines']:
					if 'abort' in status[version]:
						abort = status[version]['abort']
					if 'from' in status[version]:
						starttime = datetime.datetime.strptime(status[version]['from'], '%Y%m%d%H%M%S')
					else:
						starttime = datetime.datetime.now()
					if 'to' in status[version]:
						endtime = datetime.datetime.strptime(status[version]['to'], '%Y%m%d%H%M%S')
					else:
						endtime = datetime.datetime.now()
					if (starttime <= datetime.datetime.now() and endtime >= datetime.datetime.now()):
						message = str(status[version]['message'])

				# check if we have per-language messages
				if type(message) is dict:
					lang = language.getLanguage()
					if lang in message:
						message = message[lang]
					elif 'en_EN' in message:
						message = message['en_EN']
					else:
						message =  _("The current image might not be stable.\nFor more information see %s.") % ("openvision.tech")

			except Exception as e:
				print("[SoftwareUpdate] status error: ", str(e))
				message =  _("The current image might not be stable.\nFor more information see %s.") % ("openvision.tech")

		# or display a generic warning if fetching failed
		else:
			message = _("The status of the current image could not be checked because %s can not be reached.") % ("openvision.tech")

		# show the user the message first
		if message is not None:
			if abort:
				self.session.openWithCallback(self.close, MessageBox, message, type=MessageBox.TYPE_ERROR, picon = picon)
			else:
				message += "\n\n" + _("Do you want to update your receiver?")
				self.session.openWithCallback(self.startActualUpdate, MessageBox, message, picon = picon)

		# no message, continue with the update
		else:
			self.startActualUpdate(True)

	def getLatestImageTimestamp(self):
		def gettime(url):
			try:
				return time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(calendar.timegm(urlopen("%s/Packages.gz" % url).info().getdate('Last-Modified'))-time.altzone))
			except:
				return ""
		return sorted([gettime(open("/etc/opkg/%s" % file, "r").readlines()[0].split()[2]) for file in os.listdir("/etc/opkg") if not file.startswith("3rd-party") and file not in ("arch.conf", "opkg.conf", "picons-feed.conf")], reverse=True)[0]

	def startActualUpdate(self,answer):
		if answer:
			self.updating = True
			self.opkg.startCmd(OpkgComponent.CMD_UPDATE)
		else:
			self.close()

	def doActivityTimer(self):
		self.activity += 1
		if self.activity == 100:
			self.activity = 0
		self.activityslider.setValue(self.activity)

	def showUpdateCompletedMessage(self):
		self.setEndMessage(ngettext("Update completed, %d package was installed.", "Update completed, %d packages were installed.", self.packages) % self.packages)

	def opkgCallback(self, event, param):
		if event == OpkgComponent.EVENT_DOWNLOAD:
			self.status.setText(_("Downloading"))
		elif event == OpkgComponent.EVENT_UPGRADE:
			if param in self.sliderPackages:
				self.slider.setValue(self.sliderPackages[param])
			self.package.setText(param)
			self.status.setText(_("Updating") + ": %s/%s" % (self.packages, self.total_packages))
			if not param in self.processed_packages:
				self.processed_packages.append(param)
				self.packages += 1
		elif event == OpkgComponent.EVENT_INSTALL:
			self.package.setText(param)
			self.status.setText(_("Installing"))
			if not param in self.processed_packages:
				self.processed_packages.append(param)
				self.packages += 1
		elif event == OpkgComponent.EVENT_REMOVE:
			self.package.setText(param)
			self.status.setText(_("Removing"))
			if not param in self.processed_packages:
				self.processed_packages.append(param)
				self.packages += 1
		elif event == OpkgComponent.EVENT_CONFIGURING:
			self.package.setText(param)
			self.status.setText(_("Configuring"))
		elif event == OpkgComponent.EVENT_MODIFIED:
			if config.plugins.softwaremanager.overwriteConfigFiles.value in ("N", "Y"):
				self.opkg.write(True and config.plugins.softwaremanager.overwriteConfigFiles.value)
			else:
				self.session.openWithCallback(
					self.modificationCallback,
					MessageBox,
					_("A configuration file (%s) has been modified since it was installed.\nDo you want to keep your modifications?") % (param)
				)
		elif event == OpkgComponent.EVENT_ERROR:
			self.error += 1
		elif event == OpkgComponent.EVENT_DONE:
			if self.updating:
				self.updating = False
				self.opkg.startCmd(OpkgComponent.CMD_UPGRADE_LIST)
			elif self.opkg.currentCommand == OpkgComponent.CMD_UPGRADE_LIST:
				self.total_packages = len(self.opkg.getFetchedList())
				if self.total_packages:
					latestImageTimestamp = self.getLatestImageTimestamp()
					if latestImageTimestamp:
						message = _("Do you want to update your receiver to %s?") % latestImageTimestamp + "\n"
					else:
						message = _("Do you want to update your receiver?") + "\n"
					message += "(" + (ngettext("%s updated package available", "%s updated packages available", self.total_packages) % self.total_packages) + ")"
					if self.total_packages > 150:
						choices = [(_("Update and reboot"), "cold")]
						message += " " + _("Reflash recommended!")
					else:
						choices = [(_("Update and reboot (recommended)"), "cold"),
						(_("Update and ask to reboot"), "hot")]
					choices.append((_("Update channel list only"), "channels"))
					choices.append((_("Show packages to be updated"), "showlist"))
				else:
					message = _("No updates available")
					choices = []
				if fileExists("/home/root/opkgupgrade.log"):
					choices.append((_("Show latest update log"), "log"))
				choices.append((_("Show latest commits"), "commits"))
				choices.append((_("Cancel"), ""))
				self.session.openWithCallback(self.startActualUpgrade, ChoiceBox, title=message, list=choices, windowTitle=self.title)
			elif self.channellist_only > 0:
				if self.channellist_only == 1:
					self.setEndMessage(_("Could not find installed channel list."))
				elif self.channellist_only == 2:
					self.slider.setValue(2)
					self.opkg.startCmd(OpkgComponent.CMD_REMOVE, {'package': self.channellist_name})
					self.channellist_only += 1
				elif self.channellist_only == 3:
					self.slider.setValue(3)
					self.opkg.startCmd(OpkgComponent.CMD_INSTALL, {'package': self.channellist_name})
					self.channellist_only += 1
				elif self.channellist_only == 4:
					self.showUpdateCompletedMessage()
					eDVBDB.getInstance().reloadBouquets()
					eDVBDB.getInstance().reloadServicelist()
			elif self.error == 0:
				self.showUpdateCompletedMessage()
			else:
				self.activityTimer.stop()
				self.activityslider.setValue(0)
				error = _("Your receiver might be unusable now. Please consult the manual for further assistance before rebooting your receiver.")
				if self.packages == 0:
					error = _("No updates available. Please try again later.")
				if self.updating:
					error = _("Update failed. Your receiver does not have a working internet connection.")
				self.status.setText(_("Error") +  " - " + error)
		elif event == OpkgComponent.EVENT_LISTITEM:
			if 'enigma2-plugin-settings-' in param[0] and self.channellist_only > 0:
				self.channellist_name = param[0]
				self.channellist_only = 2
		#print(event, "-", param)
		pass

	def setEndMessage(self, txt):
		self.slider.setValue(4)
		self.activityTimer.stop()
		self.activityslider.setValue(0)
		self.package.setText(txt)
		self.status.setText(self.oktext)

	def startActualUpgrade(self, answer):
		if not answer or not answer[1]:
			self.close()
			return
		if answer[1] == "cold":
			self.session.open(TryQuitMainloop,retvalue=42)
			self.close()
		elif answer[1] == "channels":
			self.channellist_only = 1
			self.slider.setValue(1)
			self.opkg.startCmd(OpkgComponent.CMD_LIST, args = {'installed_only': True})
		elif answer[1] == "commits":
			self.session.openWithCallback(boundFunction(self.opkgCallback, OpkgComponent.EVENT_DONE, None), CommitInfo)
		elif answer[1] == "showlist":
			text = "\n".join([x[0] for x in sorted(self.opkg.getFetchedList(), key=lambda d: d[0])])
			self.session.openWithCallback(boundFunction(self.opkgCallback, OpkgComponent.EVENT_DONE, None), TextBox, text, _("Packages to update"), True)
		elif answer[1] == "log":
			text = open("/home/root/opkgupgrade.log", "r").read()
			self.session.openWithCallback(boundFunction(self.opkgCallback, OpkgComponent.EVENT_DONE, None), TextBox, text, _("Latest update log"), True)
		else:
			self.opkg.startCmd(OpkgComponent.CMD_UPGRADE, args = {'test_only': False})

	def modificationCallback(self, res):
		self.opkg.write(res and "N" or "Y")

	def exit(self):
		if not self.opkg.isRunning():
			if self.packages != 0 and self.error == 0 and self.channellist_only == 0:
				self.session.openWithCallback(self.exitAnswer, MessageBox, _("Update completed. Do you want to reboot your receiver?"))
			else:
				self.close()
		else:
			if not self.updating:
				self.close()

	def exitAnswer(self, result):
		if result is not None and result:
			self.session.open(TryQuitMainloop, retvalue=2)
		self.close()

	def __close(self):
		self.opkg.removeCallback(self.opkgCallback)
コード例 #5
0
class UpdatePlugin(Screen, ProtectedScreen):
    skin = """
		<screen name="UpdatePlugin" position="center,center" size="550,300">
			<widget name="activityslider" position="0,0" size="550,5"  />
			<widget name="slider" position="0,150" size="550,30"  />
			<widget source="package" render="Label" position="10,30" size="540,20" font="Regular;18" halign="center" valign="center" backgroundColor="#25062748" transparent="1" />
			<widget source="status" render="Label" position="10,180" size="540,100" font="Regular;20" halign="center" valign="center" backgroundColor="#25062748" transparent="1" />
		</screen>"""

    def __init__(self, session, *args):
        Screen.__init__(self, session)
        ProtectedScreen.__init__(self)

        self.sliderPackages = {"gigablue-": 1, "enigma2": 2, "teamblue-": 3}

        self.setTitle(_("Software update"))
        self.slider = Slider(0, 4)
        self["slider"] = self.slider
        self.activityslider = Slider(0, 100)
        self["activityslider"] = self.activityslider
        self.status = StaticText(_("Please wait..."))
        self["status"] = self.status
        self.package = StaticText(_("Package list update"))
        self["package"] = self.package
        self.oktext = _("Press OK on your remote control to continue.")

        self.packages = 0
        self.error = 0
        self.processed_packages = []
        self.total_packages = None

        self.channellist_only = 0
        self.channellist_name = ''
        self.updating = False
        self.opkg = OpkgComponent()
        self.opkg.addCallback(self.opkgCallback)
        self.onClose.append(self.__close)

        self["actions"] = ActionMap(["WizardActions"], {
            "ok": self.exit,
            "back": self.exit
        }, -1)

        self.activity = 0
        self.activityTimer = eTimer()
        self.activityTimer.callback.append(self.checkTraficLight)
        self.activityTimer.callback.append(self.doActivityTimer)
        self.activityTimer.start(100, True)

    def isProtected(self):
        return config.ParentalControl.setuppinactive.value and\
         (not config.ParentalControl.config_sections.main_menu.value and not config.ParentalControl.config_sections.configuration.value  or hasattr(self.session, 'infobar') and self.session.infobar is None) and\
         config.ParentalControl.config_sections.software_update.value

    def checkTraficLight(self):
        self.activityTimer.callback.remove(self.checkTraficLight)
        self.activityTimer.start(100, False)
        message = ""
        picon = None
        default = True
        url = "http://images.teamblue.tech/status/%s-%s/" % (getImageVersion(),
                                                             getImageType())
        # print "[SoftwareUpdate] url status: ", url
        try:
            # TODO: Use Twisted's URL fetcher, urlopen is evil. And it can
            # run in parallel to the package update.
            try:
                status = urlopen(url, timeout=5).read().split('!', 1)
                print status
            except:
                # bypass the certificate check
                from ssl import _create_unverified_context
                status = urlopen(
                    url, timeout=5,
                    context=_create_unverified_context()).read().split('!', 1)
                print status
            # prefer getMachineBuild
            if getMachineBuild() in status[0].split(','):
                message = len(status) > 1 and status[1] or _(
                    "The current software might not be stable.\nFor more information see %s."
                ) % ("http://images.teamblue.tech")
                picon = MessageBox.TYPE_ERROR
                default = False
            # only use getBoxType if no getMachineBuild
            elif getBoxType() in status[0].split(','):
                message = len(status) > 1 and status[1] or _(
                    "The current software might not be stable.\nFor more information see %s."
                ) % ("http://images.teamblue.tech")
                picon = MessageBox.TYPE_ERROR
                default = False
        except:
            message = _(
                "The status of the current software could not be checked because %s can not be reached."
            ) % ("http://images.teamblue.tech")
            picon = MessageBox.TYPE_ERROR
            default = False
        if default:
            self.showDisclaimer()
        else:
            message += "\n" + _("Do you want to update your receiver?")
            self.session.openWithCallback(self.startActualUpdate,
                                          MessageBox,
                                          message,
                                          default=default,
                                          picon=picon)

    def showDisclaimer(self, justShow=False):
        if config.usage.show_update_disclaimer.value or justShow:
            message = _(
                "With this disclaimer the teamBlue team is informing you that we are working with nightly builds and it might be that after the upgrades your set top box \
is not anymore working as expected. Therefore it is recommended to create backups. If something went wrong you can easily and quickly restore. \
If you discover 'bugs' please keep them reported on www.teamblue.tech.\n\nDo you understand this?"
            )
            list = not justShow and [
                (_("no"), False), (_("yes"), True),
                (_("yes") + " " + _("and never show this message again"),
                 "never")
            ] or []
            self.session.openWithCallback(boundFunction(
                self.disclaimerCallback, justShow),
                                          MessageBox,
                                          message,
                                          list=list,
                                          title=_("Disclaimer"))
        else:
            self.startActualUpdate(True)

    def disclaimerCallback(self, justShow, answer):
        if answer == "never":
            config.usage.show_update_disclaimer.value = False
            config.usage.show_update_disclaimer.save()
        if justShow and answer:
            self.ipkgCallback(IpkgComponent.EVENT_DONE, None)
        else:
            self.startActualUpdate(answer)

    def getLatestImageTimestamp(self):
        url = "http://images.teamblue.tech/status/%s-%s/buildtimestamp-%s" % (
            getImageVersion(), getImageType(), getBoxType())
        # print "[SoftwareUpdate] url buildtimestamp: ", url
        try:
            # TODO: Use Twisted's URL fetcher, urlopen is evil. And it can
            # run in parallel to the package update.
            from time import strftime
            from datetime import datetime
            try:
                latestImageTimestamp = datetime.fromtimestamp(
                    int(urlopen(url, timeout=5).read())).strftime(
                        _("%Y-%m-%d %H:%M"))
            except:
                # bypass the certificate check
                from ssl import _create_unverified_context
                latestImageTimestamp = datetime.fromtimestamp(
                    int(
                        urlopen(url,
                                timeout=5,
                                context=_create_unverified_context()).read())
                ).strftime(_("%Y-%m-%d %H:%M"))
        except:
            latestImageTimestamp = ""
        print "[SoftwareUpdate] latestImageTimestamp:", latestImageTimestamp
        return latestImageTimestamp

    def startActualUpdate(self, answer):
        if answer:
            self.updating = True
            self.opkg.startCmd(OpkgComponent.CMD_UPDATE)
        else:
            self.close()

    def doActivityTimer(self):
        self.activity += 1
        if self.activity == 100:
            self.activity = 0
        self.activityslider.setValue(self.activity)

    def showUpdateCompletedMessage(self):
        self.setEndMessage(
            ngettext("Update completed, %d package was installed.",
                     "Update completed, %d packages were installed.",
                     self.packages) % self.packages)

    def opkgCallback(self, event, param):
        if event == OpkgComponent.EVENT_DOWNLOAD:
            self.status.setText(_("Downloading"))
        elif event == OpkgComponent.EVENT_UPGRADE:
            if param in self.sliderPackages:
                self.slider.setValue(self.sliderPackages[param])
            self.package.setText(param)
            self.status.setText(
                _("Updating") + ": %s/%s" %
                (self.packages, self.total_packages))
            if not param in self.processed_packages:
                self.processed_packages.append(param)
                self.packages += 1
        elif event == OpkgComponent.EVENT_INSTALL:
            self.package.setText(param)
            self.status.setText(_("Installing"))
            if not param in self.processed_packages:
                self.processed_packages.append(param)
                self.packages += 1
        elif event == OpkgComponent.EVENT_REMOVE:
            self.package.setText(param)
            self.status.setText(_("Removing"))
            if not param in self.processed_packages:
                self.processed_packages.append(param)
                self.packages += 1
        elif event == OpkgComponent.EVENT_CONFIGURING:
            self.package.setText(param)
            self.status.setText(_("Configuring"))
        elif event == OpkgComponent.EVENT_MODIFIED:
            if config.plugins.softwaremanager.overwriteConfigFiles.value in (
                    "N", "Y"):
                self.opkg.write(
                    True and
                    config.plugins.softwaremanager.overwriteConfigFiles.value)
            else:
                self.session.openWithCallback(
                    self.modificationCallback, MessageBox,
                    _("A configuration file (%s) has been modified since it was installed.\nDo you want to keep your modifications?"
                      ) % (param))
        elif event == OpkgComponent.EVENT_ERROR:
            self.error += 1
        elif event == OpkgComponent.EVENT_DONE:
            if self.updating:
                self.updating = False
                self.opkg.startCmd(OpkgComponent.CMD_UPGRADE_LIST)
            elif self.opkg.currentCommand == OpkgComponent.CMD_UPGRADE_LIST:
                self.total_packages = len(self.opkg.getFetchedList())
                if self.total_packages:
                    latestImageTimestamp = self.getLatestImageTimestamp()
                    if latestImageTimestamp:
                        message = _(
                            "Latest available teamBlue %s build is from: %s"
                        ) % (getImageVersion(),
                             self.getLatestImageTimestamp()) + "\n"
                        message += _(
                            "Do you want to update your receiver?") + "\n"
                    else:
                        message = _(
                            "Do you want to update your receiver?") + "\n"
                    message += "(" + (ngettext(
                        "%s updated package available",
                        "%s updated packages available", self.total_packages) %
                                      self.total_packages) + ")"
                    if self.total_packages > 150:
                        message += " " + _("Reflash recommended!")
                    choices = [
                        (_("Update and reboot (recommended)"), "cold"),
                        (_("Update and ask to reboot"), "hot"),
                        #(_("Update channel list only"), "channels"),
                        (_("Show packages to be updated"), "showlist")
                    ]
                else:
                    message = _("No updates available")
                    choices = []
                if fileExists("/home/root/opkgupgrade.log"):
                    choices.append((_("Show latest update log"), "log"))
                choices.append((_("Show latest commits"), "commits"))
                if not config.usage.show_update_disclaimer.value:
                    choices.append((_("Show disclaimer"), "disclaimer"))
                choices.append((_("Cancel"), ""))
                self.session.openWithCallback(self.startActualUpgrade,
                                              ChoiceBox,
                                              title=message,
                                              list=choices,
                                              windowTitle=self.title)
            elif self.channellist_only > 0:
                if self.channellist_only == 1:
                    self.setEndMessage(
                        _("Could not find installed channel list."))
                elif self.channellist_only == 2:
                    self.slider.setValue(2)
                    self.opkg.startCmd(OpkgComponent.CMD_REMOVE,
                                       {'package': self.channellist_name})
                    self.channellist_only += 1
                elif self.channellist_only == 3:
                    self.slider.setValue(3)
                    self.opkg.startCmd(OpkgComponent.CMD_INSTALL,
                                       {'package': self.channellist_name})
                    self.channellist_only += 1
                elif self.channellist_only == 4:
                    self.showUpdateCompletedMessage()
                    eDVBDB.getInstance().reloadBouquets()
                    eDVBDB.getInstance().reloadServicelist()
            elif self.error == 0:
                self.showUpdateCompletedMessage()
            else:
                self.activityTimer.stop()
                self.activityslider.setValue(0)
                error = _(
                    "Your receiver might be unusable now. Please consult the manual for further assistance before rebooting your receiver."
                )
                if self.packages == 0:
                    error = _("No updates available. Please try again later.")
                if self.updating:
                    error = _(
                        "Update failed. Your receiver does not have a working internet connection."
                    )
                self.status.setText(_("Error") + " - " + error)
        elif event == OpkgComponent.EVENT_LISTITEM:
            if 'enigma2-plugin-settings-' in param[
                    0] and self.channellist_only > 0:
                self.channellist_name = param[0]
                self.channellist_only = 2
        #print event, "-", param
        pass

    def setEndMessage(self, txt):
        self.slider.setValue(4)
        self.activityTimer.stop()
        self.activityslider.setValue(0)
        self.package.setText(txt)
        self.status.setText(self.oktext)

    def startActualUpgrade(self, answer):
        if not answer or not answer[1]:
            self.close()
            return
        if answer[1] == "cold":
            self.session.open(TryQuitMainloop, retvalue=42)
            self.close()
        elif answer[1] == "channels":
            self.channellist_only = 1
            self.slider.setValue(1)
            self.opkg.startCmd(OpkgComponent.CMD_LIST,
                               args={'installed_only': True})
        elif answer[1] == "commits":
            self.session.openWithCallback(
                boundFunction(self.opkgCallback, OpkgComponent.EVENT_DONE,
                              None), CommitInfo)
        elif answer[1] == "disclaimer":
            self.showDisclaimer(justShow=True)
        elif answer[1] == "showlist":
            text = "\n".join([
                x[0]
                for x in sorted(self.opkg.getFetchedList(), key=lambda d: d[0])
            ])
            self.session.openWithCallback(
                boundFunction(self.opkgCallback,
                              OpkgComponent.EVENT_DONE, None), TextBox, text,
                _("Packages to update"), True)
        elif answer[1] == "log":
            text = open("/home/root/opkgupgrade.log", "r").read()
            self.session.openWithCallback(
                boundFunction(self.opkgCallback,
                              OpkgComponent.EVENT_DONE, None), TextBox, text,
                _("Latest update log"), True)
        else:
            self.opkg.startCmd(OpkgComponent.CMD_UPGRADE,
                               args={'test_only': False})

    def modificationCallback(self, res):
        self.opkg.write(res and "N" or "Y")

    def exit(self):
        if not self.opkg.isRunning():
            if self.packages != 0 and self.error == 0 and self.channellist_only == 0:
                self.session.openWithCallback(
                    self.exitAnswer, MessageBox,
                    _("Update completed. Do you want to reboot your receiver?")
                )
            else:
                self.close()
        else:
            if not self.updating:
                self.close()

    def exitAnswer(self, result):
        if result is not None and result:
            self.session.open(TryQuitMainloop, retvalue=2)
        self.close()

    def __close(self):
        self.opkg.removeCallback(self.opkgCallback)