Beispiel #1
0
class InstallWizardOpkgUpdater(Screen):
	skin = """
	<screen position="c-300,c-25" size="600,50" title=" ">
		<widget source="statusbar" render="Label" position="10,5" zPosition="10" size="e-10,30" halign="center" valign="center" font="Regular;22" transparent="1" shadowColor="black" shadowOffset="-1,-1" />
	</screen>"""

	def __init__(self, session, index, info, cmd, pkg=None):
		self.skin = InstallWizardOpkgUpdater.skin
		Screen.__init__(self, session)

		self["statusbar"] = StaticText(info)

		self.pkg = pkg
		self.index = index
		self.state = 0

		self.opkg = OpkgComponent()
		self.opkg.addCallback(self.opkgCallback)

		self.opkg.startCmd(cmd, pkg)

	def opkgCallback(self, event, param):
		if event == OpkgComponent.EVENT_DONE:
			if self.index == InstallWizard.STATE_UPDATE:
				config.misc.installwizard.opkgloaded.value = True
			self.close()
Beispiel #2
0
class InstallWizardOpkgUpdater(Screen):
    skin = """
	<screen position="c-300,c-25" size="600,50" title=" ">
		<widget source="statusbar" render="Label" position="10,5" zPosition="10" size="e-10,30" halign="center" valign="center" font="Regular;22" transparent="1" shadowColor="black" shadowOffset="-1,-1" />
	</screen>"""

    def __init__(self, session, index, info, cmd, pkg=None):
        self.skin = InstallWizardOpkgUpdater.skin
        Screen.__init__(self, session)

        self["statusbar"] = StaticText(info)

        self.pkg = pkg
        self.index = index
        self.state = 0

        self.opkg = OpkgComponent()
        self.opkg.addCallback(self.opkgCallback)

        if self.index == InstallWizard.STATE_CHOICE_CHANNELLIST:
            self.opkg.startCmd(cmd, {'package': 'enigma2-plugin-settings-*'})
        else:
            self.opkg.startCmd(cmd, pkg)

    def opkgCallback(self, event, param):
        if event == OpkgComponent.EVENT_DONE:
            if self.index == InstallWizard.STATE_UPDATE:
                config.misc.installwizard.opkgloaded.value = True
            elif self.index == InstallWizard.STATE_CHOICE_CHANNELLIST:
                if self.state == 0:
                    self.opkg.startCmd(OpkgComponent.CMD_INSTALL, self.pkg)
                    self.state = 1
                    return
                else:
                    config.misc.installwizard.channellistdownloaded.value = True
                    eDVBDB.getInstance().reloadBouquets()
                    eDVBDB.getInstance().reloadServicelist()
            self.close()
Beispiel #3
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))
Beispiel #4
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
class PackageInfoHandler:
    STATUS_WORKING = 0
    STATUS_DONE = 1
    STATUS_ERROR = 2
    STATUS_INIT = 4

    def __init__(self,
                 statusCallback,
                 blocking=False,
                 neededTag=None,
                 neededFlag=None):
        self.directory = "/"

        self.neededTag = neededTag
        self.neededFlag = neededFlag

        # caution: blocking should only be used, if further execution in enigma2 depends on the outcome of
        # the installer!
        self.blocking = blocking

        self.currentlyInstallingMetaIndex = None

        self.console = eConsoleAppContainer()
        self.console.appClosed.append(self.installNext)
        self.reloadFavourites = False

        self.statusCallback = statusCallback
        self.setStatus(self.STATUS_INIT)

        self.packageslist = []
        self.packagesIndexlist = []
        self.packageDetails = []

    def readInfo(self, directory, file):
        handler = InfoHandler(self.prerequisiteMet, directory)
        try:
            xml.sax.parse(file, handler)
            for entry in handler.list:
                self.packageslist.append((entry, file))
        except InfoHandlerParseError:
            pass

    def readIndex(self, directory, file):
        handler = InfoHandler(self.prerequisiteMet, directory)
        try:
            xml.sax.parse(file, handler)
            for entry in handler.list:
                self.packagesIndexlist.append((entry, file))
        except InfoHandlerParseError:
            pass

    def readDetails(self, directory, file):
        self.packageDetails = []
        handler = InfoHandler(self.prerequisiteMet, directory)
        try:
            xml.sax.parse(file, handler)
            for entry in handler.list:
                self.packageDetails.append((entry, file))
        except InfoHandlerParseError:
            pass

    def fillPackagesList(self, prerequisites=True):
        self.packageslist = []
        packages = []
        if not isinstance(self.directory, list):
            self.directory = [self.directory]

        for directory in self.directory:
            packages += crawlDirectory(directory, ".*\.info$")

        for package in packages:
            self.readInfo(package[0] + "/", package[0] + "/" + package[1])

        if prerequisites:
            for package in self.packageslist[:]:
                if not self.prerequisiteMet(package[0]["prerequisites"]):
                    self.packageslist.remove(package)
        return self.packageslist

    def fillPackagesIndexList(self, prerequisites=True):
        self.packagesIndexlist = []
        indexfileList = []

        if not isinstance(self.directory, list):
            self.directory = [self.directory]

        for indexfile in os.listdir(self.directory[0]):
            if indexfile.startswith("index-"):
                if indexfile.endswith(".xml"):
                    if indexfile[-7:-6] == "_":
                        continue
                    indexfileList.append(indexfile)
        if len(indexfileList):
            for file in indexfileList:
                neededFile = self.directory[0] + "/" + file
                if os.path.isfile(neededFile):
                    self.readIndex(self.directory[0] + "/", neededFile)

        if prerequisites:
            for package in self.packagesIndexlist[:]:
                if not self.prerequisiteMet(package[0]["prerequisites"]):
                    self.packagesIndexlist.remove(package)
        return self.packagesIndexlist

    def fillPackageDetails(self, details=None):
        self.packageDetails = []
        detailsfile = details
        if not isinstance(self.directory, list):
            self.directory = [self.directory]
        self.readDetails(self.directory[0] + "/",
                         self.directory[0] + "/" + detailsfile)
        return self.packageDetails

    def prerequisiteMet(self, prerequisites):
        met = True
        if self.neededTag is None:
            if "tag" in prerequisites:
                return False
        elif self.neededTag == 'ALL_TAGS':
            return True
        else:
            if "tag" in prerequisites:
                if not self.neededTag in prerequisites["tag"]:
                    return False
            else:
                return False

        if self.neededFlag is None:
            if "flag" in prerequisites:
                return False
        else:
            if "flag" in prerequisites:
                if not self.neededFlag in prerequisites["flag"]:
                    return False
            else:
                return True

        if "satellite" in prerequisites:
            for sat in prerequisites["satellite"]:
                if int(sat) not in nimmanager.getConfiguredSats():
                    return False
        if "bcastsystem" in prerequisites:
            has_system = False
            for bcastsystem in prerequisites["bcastsystem"]:
                if nimmanager.hasNimType(bcastsystem):
                    has_system = True
            if not has_system:
                return False
        if "hardware" in prerequisites:
            hardware_found = False
            for hardware in prerequisites["hardware"]:
                if hardware == getBoxType():
                    hardware_found = True
            if not hardware_found:
                return False
        return True

    def installPackages(self, indexes):
        if len(indexes) == 0:
            self.setStatus(self.STATUS_DONE)
            return
        self.installIndexes = indexes
        self.currentlyInstallingMetaIndex = 0
        self.installPackage(
            self.installIndexes[self.currentlyInstallingMetaIndex])

    def installPackage(self, index):
        if len(self.packageslist) <= index:
            return

        attributes = self.packageslist[index][0]["attributes"]
        self.installingAttributes = attributes
        self.attributeNames = [
            "skin", "config", "favourites", "package", "services"
        ]
        self.currentAttributeIndex = 0
        self.currentIndex = -1
        self.installNext()

    def setStatus(self, status):
        self.status = status
        self.statusCallback(self.status, None)

    def installNext(self, *args, **kwargs):
        if self.reloadFavourites:
            self.reloadFavourites = False
            db = eDVBDB.getInstance().reloadBouquets()

        self.currentIndex += 1
        attributes = self.installingAttributes

        if self.currentAttributeIndex >= len(self.attributeNames):
            if self.currentlyInstallingMetaIndex is None or self.currentlyInstallingMetaIndex >= len(
                    self.installIndexes) - 1:
                self.setStatus(self.STATUS_DONE)
                return
            else:
                self.currentlyInstallingMetaIndex += 1
                self.currentAttributeIndex = 0
                self.installPackage(
                    self.installIndexes[self.currentlyInstallingMetaIndex])
                return

        self.setStatus(self.STATUS_WORKING)

        currentAttribute = self.attributeNames[self.currentAttributeIndex]

        if currentAttribute in attributes:
            if self.currentIndex >= len(attributes[currentAttribute]):
                self.currentIndex = -1
                self.currentAttributeIndex += 1
                self.installNext()
                return
        else:
            self.currentIndex = -1
            self.currentAttributeIndex += 1
            self.installNext()
            return

        if currentAttribute == "skin":
            skin = attributes["skin"][self.currentIndex]
            self.installSkin(skin["directory"], skin["name"])
        elif currentAttribute == "config":
            if self.currentIndex == 0:
                from Components.config import configfile
                configfile.save()
            config = attributes["config"][self.currentIndex]
            self.mergeConfig(config["directory"], config["name"])
        elif currentAttribute == "favourites":
            favourite = attributes["favourites"][self.currentIndex]
            self.installFavourites(favourite["directory"], favourite["name"])
        elif currentAttribute == "package":
            package = attributes["package"][self.currentIndex]
            self.installIPK(package["directory"], package["name"])
        elif currentAttribute == "services":
            service = attributes["services"][self.currentIndex]
            self.mergeServices(service["directory"], service["name"])

    def readfile(self, filename):
        if not os.path.isfile(filename):
            return []
        fd = open(filename)
        lines = fd.readlines()
        fd.close()
        return lines

    def mergeConfig(self, directory, name, merge=True):
        if os.path.isfile(directory + name):
            config.loadFromFile(directory + name, base_file=False)
            configfile.save()
        self.installNext()

    def installIPK(self, directory, name):
        if self.blocking:
            Console().ePopen("opkg install %s%s" % (directory, name))
            self.installNext()
        else:
            self.opkg = OpkgComponent()
            self.opkg.addCallback(self.opkgCallback)
            self.opkg.startCmd(OpkgComponent.CMD_INSTALL,
                               {'package': directory + name})

    def opkgCallback(self, event, param):
        if event == OpkgComponent.EVENT_DONE:
            self.installNext()
        elif event == OpkgComponent.EVENT_ERROR:
            self.installNext()

    def installSkin(self, directory, name):
        if self.blocking:
            copytree(directory, resolveFilename(SCOPE_SKIN))
            self.installNext()
        else:
            if self.console.execute("cp -a %s %s" %
                                    (directory, resolveFilename(SCOPE_SKIN))):
                self.installNext()

    def mergeServices(self, directory, name, merge=False):
        if os.path.isfile(directory + name):
            db = eDVBDB.getInstance()
            db.reloadServicelist()
            db.loadServicelist(directory + name)
            db.saveServicelist()
        self.installNext()

    def installFavourites(self, directory, name):
        self.reloadFavourites = True

        if self.blocking:
            copyfile(directory + name, resolveFilename(SCOPE_CONFIG))
            self.installNext()
        else:
            if self.console.execute(
                    "cp %s %s" %
                ((directory + name), resolveFilename(SCOPE_CONFIG))):
                self.installNext()
Beispiel #6
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 = { "dreambox-dvb-modules": 1, "enigma2": 2, "tuxbox-image-info": 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)
		status = None
		message = None
		abort = False
		picon = MessageBox.TYPE_ERROR
		url = "https://openpli.org/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 = HardwareInfo().get_machine_name()
				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.") % ("openpli.org")

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

		# or display a generic warning if fetching failed
		else:
Beispiel #7
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)
class SoftwareTools(PackageInfoHandler):
    lastDownloadDate = None
    NetworkConnectionAvailable = None
    list_updating = False
    available_updates = 0
    available_updatelist = []
    available_packetlist = []
    installed_packetlist = {}

    def __init__(self):
        aboutInfo = about.getImageVersionString()
        if aboutInfo.startswith("dev-"):
            self.ImageVersion = 'Experimental'
        else:
            self.ImageVersion = 'Stable'
        self.language = language.getLanguage(
        )[:2]  # getLanguage returns e.g. "fi_FI" for "language_country"
        PackageInfoHandler.__init__(self,
                                    self.statusCallback,
                                    neededTag='ALL_TAGS',
                                    neededFlag=self.ImageVersion)
        self.directory = resolveFilename(SCOPE_METADIR)
        self.list = List([])
        self.NotifierCallback = None
        self.Console = Console()
        self.UpdateConsole = Console()
        self.cmdList = []
        self.unwanted_extensions = ('-dbg', '-dev', '-doc', '-staticdev',
                                    '-src')
        self.opkg = OpkgComponent()
        self.opkg.addCallback(self.opkgCallback)

    def statusCallback(self, status, progress):
        pass

    def startSoftwareTools(self, callback=None):
        if callback is not None:
            self.NotifierCallback = callback
        iNetwork.checkNetworkState(self.checkNetworkCB)

    def checkNetworkCB(self, data):
        if data is not None:
            if data <= 2:
                self.NetworkConnectionAvailable = True
                self.getUpdates()
            else:
                self.NetworkConnectionAvailable = False
                self.getUpdates()

    def getUpdates(self, callback=None):
        if self.lastDownloadDate is None:
            if self.NetworkConnectionAvailable == True:
                self.lastDownloadDate = time()
                if self.list_updating is False and callback is None:
                    self.list_updating = True
                    self.opkg.startCmd(OpkgComponent.CMD_UPDATE)
                elif self.list_updating is False and callback is not None:
                    self.list_updating = True
                    self.NotifierCallback = callback
                    self.opkg.startCmd(OpkgComponent.CMD_UPDATE)
                elif self.list_updating is True and callback is not None:
                    self.NotifierCallback = callback
            else:
                self.list_updating = False
                if callback is not None:
                    callback(False)
                elif self.NotifierCallback is not None:
                    self.NotifierCallback(False)
        else:
            if self.NetworkConnectionAvailable == True:
                self.lastDownloadDate = time()
                if self.list_updating is False and callback is None:
                    self.list_updating = True
                    self.opkg.startCmd(OpkgComponent.CMD_UPDATE)
                elif self.list_updating is False and callback is not None:
                    self.list_updating = True
                    self.NotifierCallback = callback
                    self.opkg.startCmd(OpkgComponent.CMD_UPDATE)
                elif self.list_updating is True and callback is not None:
                    self.NotifierCallback = callback
            else:
                if self.list_updating and callback is not None:
                    self.NotifierCallback = callback
                    self.startOpkgListAvailable()
                else:
                    self.list_updating = False
                    if callback is not None:
                        callback(False)
                    elif self.NotifierCallback is not None:
                        self.NotifierCallback(False)

    def opkgCallback(self, event, param):
        if event == OpkgComponent.EVENT_ERROR:
            self.list_updating = False
            if self.NotifierCallback is not None:
                self.NotifierCallback(False)
        elif event == OpkgComponent.EVENT_DONE:
            if self.list_updating:
                self.startOpkgListAvailable()
        pass

    def startOpkgListAvailable(self, callback=None):
        if callback is not None:
            self.list_updating = True
        if self.list_updating:
            if not self.UpdateConsole:
                self.UpdateConsole = Console()
            cmd = self.opkg.opkg + " list"
            self.UpdateConsole.ePopen(cmd, self.OpkgListAvailableCB, callback)

    def OpkgListAvailableCB(self, result, retval, extra_args=None):
        (callback) = extra_args
        if result:
            if self.list_updating:
                self.available_packetlist = []
                for x in result.splitlines():
                    tokens = x.split(' - ')
                    name = tokens[0].strip()
                    if not any(
                            name.endswith(x)
                            for x in self.unwanted_extensions):
                        l = len(tokens)
                        version = l > 1 and tokens[1].strip() or ""
                        descr = l > 2 and tokens[2].strip() or ""
                        self.available_packetlist.append(
                            [name, version, descr])
                if callback is None:
                    self.startInstallMetaPackage()
                else:
                    if self.UpdateConsole:
                        if not self.UpdateConsole.appContainers:
                            callback(True)
        else:
            self.list_updating = False
            if self.UpdateConsole:
                if not self.UpdateConsole.appContainers:
                    if callback is not None:
                        callback(False)

    def startInstallMetaPackage(self, callback=None):
        if callback is not None:
            self.list_updating = True
        if self.list_updating:
            if self.NetworkConnectionAvailable == True:
                if not self.UpdateConsole:
                    self.UpdateConsole = Console()
                cmd = self.opkg.opkg + " install enigma2-meta enigma2-plugins-meta enigma2-skins-meta"
                self.UpdateConsole.ePopen(cmd, self.InstallMetaPackageCB,
                                          callback)
            else:
                self.InstallMetaPackageCB(True)

    def InstallMetaPackageCB(self, result, retval=None, extra_args=None):
        (callback) = extra_args
        if result:
            self.fillPackagesIndexList()
            if callback is None:
                self.startOpkgListInstalled()
            else:
                if self.UpdateConsole:
                    if not self.UpdateConsole.appContainers:
                        callback(True)
        else:
            self.list_updating = False
            if self.UpdateConsole:
                if not self.UpdateConsole.appContainers:
                    if callback is not None:
                        callback(False)

    def startOpkgListInstalled(self, callback=None):
        if callback is not None:
            self.list_updating = True
        if self.list_updating:
            if not self.UpdateConsole:
                self.UpdateConsole = Console()
            cmd = self.opkg.opkg + " list_installed"
            self.UpdateConsole.ePopen(cmd, self.OpkgListInstalledCB, callback)

    def OpkgListInstalledCB(self, result, retval, extra_args=None):
        (callback) = extra_args
        if result:
            self.installed_packetlist = {}
            for x in result.splitlines():
                tokens = x.split(' - ')
                name = tokens[0].strip()
                if not any(name.endswith(x) for x in self.unwanted_extensions):
                    l = len(tokens)
                    version = l > 1 and tokens[1].strip() or ""
                    self.installed_packetlist[name] = version
            for package in self.packagesIndexlist[:]:
                if not self.verifyPrerequisites(package[0]["prerequisites"]):
                    self.packagesIndexlist.remove(package)
            for package in self.packagesIndexlist[:]:
                attributes = package[0]["attributes"]
                if "packagetype" in attributes:
                    if attributes["packagetype"] == "internal":
                        self.packagesIndexlist.remove(package)
            if callback is None:
                self.countUpdates()
            else:
                if self.UpdateConsole:
                    if not self.UpdateConsole.appContainers:
                        callback(True)
        else:
            self.list_updating = False
            if self.UpdateConsole:
                if not self.UpdateConsole.appContainers:
                    if callback is not None:
                        callback(False)

    def countUpdates(self, callback=None):
        self.available_updates = 0
        self.available_updatelist = []
        for package in self.packagesIndexlist[:]:
            attributes = package[0]["attributes"]
            packagename = attributes["packagename"]
            for x in self.available_packetlist:
                if x[0] == packagename:
                    if packagename in self.installed_packetlist:
                        if self.installed_packetlist[packagename] != x[1]:
                            self.available_updates += 1
                            self.available_updatelist.append([packagename])

        self.list_updating = False
        if self.UpdateConsole:
            if not self.UpdateConsole.appContainers:
                if callback is not None:
                    callback(True)
                    callback = None
                elif self.NotifierCallback is not None:
                    self.NotifierCallback(True)
                    self.NotifierCallback = None

    def startOpkgUpdate(self, callback=None):
        if not self.Console:
            self.Console = Console()
        cmd = self.opkg.opkg + " update"
        self.Console.ePopen(cmd, self.OpkgUpdateCB, callback)

    def OpkgUpdateCB(self, result, retval, extra_args=None):
        (callback) = extra_args
        if result:
            if self.Console:
                if not self.Console.appContainers:
                    if callback is not None:
                        callback(True)
                        callback = None

    def cleanupSoftwareTools(self):
        self.list_updating = False
        if self.NotifierCallback is not None:
            self.NotifierCallback = None
        self.opkg.stop()
        if self.Console is not None:
            self.Console.killAll()
        if self.UpdateConsole is not None:
            self.UpdateConsole.killAll()

    def verifyPrerequisites(self, prerequisites):
        if "hardware" in prerequisites:
            hardware_found = False
            for hardware in prerequisites["hardware"]:
                if hardware == getBoxType():
                    hardware_found = True
            if not hardware_found:
                return False
        return True
Beispiel #9
0
class Opkg(Screen):
    def __init__(self, session, cmdList=[]):
        Screen.__init__(self, session)

        self.cmdList = cmdList

        self.sliderPackages = {}

        self.slider = Slider(0, len(cmdList))
        self["slider"] = self.slider
        self.activityslider = Slider(0, 100)
        self["activityslider"] = self.activityslider
        self.status = Label(_("Preparing... Please wait"))
        self["status"] = self.status
        self.package = Label()
        self["package"] = self.package

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

        self.activity = 0
        self.activityTimer = eTimer()
        self.activityTimer.callback.append(self.doActivityTimer)
        #self.activityTimer.start(100, False)

        self.opkg = OpkgComponent()
        self.opkg.addCallback(self.opkgCallback)

        self.runningCmd = None
        self.runNextCmd()

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

    def runNextCmd(self):
        if self.runningCmd is None:
            self.runningCmd = 0
        else:
            self.runningCmd += 1
        print(len(self.cmdList), self.runningCmd)
        if len(self.cmdList) - 1 < self.runningCmd:
            self.activityslider.setValue(0)
            self.slider.setValue(len(self.cmdList))

            self.package.setText("")
            self.status.setText(
                ngettext(
                    "Done - Installed, updated or removed %d package (%s)",
                    "Done - Installed, updated or removed %d packages (%s)",
                    self.packages) %
                (self.packages,
                 ngettext("with %d error", "with %d errors", self.error) %
                 self.error))
            return False
        else:
            cmd = self.cmdList[self.runningCmd]
            self.slider.setValue(self.runningCmd)
            self.opkg.startCmd(cmd[0], args=cmd[1])
            self.startActivityTimer()

    def doActivityTimer(self):
        if not self.opkg.isRunning():
            self.stopActivityTimer()
        else:
            self.activity += 1
            if self.activity == 100:
                self.activity = 0
            self.activityslider.setValue(self.activity)

    def startActivityTimer(self):
        self.activityTimer.start(100, False)

    def stopActivityTimer(self):
        self.activityTimer.stop()

    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"))
            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_ERROR:
            self.error += 1
        elif event == OpkgComponent.EVENT_DONE:
            self.runNextCmd()
        elif event == OpkgComponent.EVENT_MODIFIED:
            self.session.openWithCallback(
                self.modificationCallback, MessageBox,
                _("A configuration file (%s) has been modified since it was installed. Would you like to keep the modified version?"
                  ) % (param))

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

    def exit(self):
        if not self.opkg.isRunning():
            self.close()
Beispiel #10
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()
Beispiel #11
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)
class SoftwarePanel(Screen):
    def __init__(self, session, *args):
        Screen.__init__(self, session)
        Screen.setTitle(self, _("Openeight Software Panel"))
        skin = """
		<screen name="SoftwarePanel" position="center,center" size="650,605" title="Software Panel">
			<widget name="a_off" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/ExtrasPanel/pics/aoff.png" position="10,10" zPosition="1" size="36,97" alphatest="on" />
			<widget name="a_red" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/ExtrasPanel/pics/ared.png" position="10,10" zPosition="1" size="36,97" alphatest="on" />
			<widget name="a_yellow" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/ExtrasPanel/pics/ayellow.png" position="10,10" zPosition="1" size="36,97" alphatest="on" />
			<widget name="a_green" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/ExtrasPanel/pics/agreen.png" position="10,10" zPosition="1" size="36,97" alphatest="on" />
			<widget name="feedstatusRED" position="60,14" size="200,30" zPosition="1" font="Regular;25" halign="left" transparent="1" />
			<widget name="feedstatusYELLOW" position="60,46" size="200,30" zPosition="1" font="Regular;25" halign="left" transparent="1" />
			<widget name="feedstatusGREEN" position="60,78" size="200,30" zPosition="1" font="Regular;25" halign="left" transparent="1" />
			<widget name="packagetext" position="276,50" size="247,30" zPosition="1" font="Regular;25" halign="right" transparent="1" />
			<widget name="packagenr" position="529,50" size="69,30" zPosition="1" font="Regular;25" halign="left" transparent="1" />
			<widget source="list" render="Listbox" position="10,120" size="630,365" 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
							MultiContentEntryPixmapAlphaTest(pos = (545, 2), size = (48, 48), png = 4), # index 4 is the status pixmap
							MultiContentEntryPixmapAlphaTest(pos = (5, 50), size = (610, 2), png = 5), # index 4 is the div pixmap
						],
					"fonts": [gFont("Regular", 22),gFont("Regular", 14)],
					"itemHeight": 52
					}
				</convert>
			</widget>
			<ePixmap pixmap="skin_default/buttons/red.png" position="30,560" size="138,40" alphatest="blend" />
                        <widget name="key_green_pic" pixmap="skin_default/buttons/green.png" position="180,560" size="138,40" alphatest="blend" />
                        <ePixmap pixmap="skin_default/buttons/yellow.png" position="333,560" size="138,40" alphatest="blend" />
                        <ePixmap pixmap="skin_default/buttons/blue.png" position="481,560" size="138,40" alphatest="blend" />
                        <widget name="key_red" position="38,570" size="124,26" zPosition="1" font="Regular;17" halign="center" transparent="1" />
                        <widget name="key_green" position="188,570" size="124,26" zPosition="1" font="Regular;17" halign="center" transparent="1" />
                        <widget name="key_yellow" position="340,570" size="124,26" zPosition="1" font="Regular;17" halign="center" transparent="1" />
                        <widget name="key_blue" position="491,570" size="124,26" zPosition="1" font="Regular;17" halign="center" transparent="1" />
		</screen> """
        self.skin = skin
        self.list = []
        self.statuslist = []
        self["list"] = List(self.list)
        self['a_off'] = Pixmap()
        self['a_red'] = Pixmap()
        self['a_yellow'] = Pixmap()
        self['a_green'] = Pixmap()
        self['key_green_pic'] = Pixmap()
        self['key_red_pic'] = Pixmap()
        self['key_red'] = Label(_("Cancel"))
        self['key_green'] = Label(_("Update"))
        self['key_yellow'] = Label(_(""))
        self['packagetext'] = Label(_("Updates Available:"))
        self['packagenr'] = Label("0")
        self['feedstatusRED'] = Label("<  " + _("feed status"))
        self['feedstatusYELLOW'] = Label("<  " + _("feed status"))
        self['feedstatusGREEN'] = Label("<  " + _("feed status"))
        self['key_green'].hide()
        self['key_green_pic'].hide()
        self.update = False
        self.packages = 0
        self.trafficLight = 0
        self.opkg = OpkgComponent()
        self.opkg.addCallback(self.opkgCallback)
        self["actions"] = ActionMap([
            "OkCancelActions", "DirectionActions", "ColorActions",
            "SetupActions"
        ], {
            "cancel": self.Exit,
            "green": self.Green,
            "yellow": self.showCommitLog
        }, -2)

        self.onLayoutFinish.append(self.layoutFinished)

    def Exit(self):
        self.opkg.stop()
        self.close()

    def Green(self):
        if self.packages > 0 and self.trafficLight > 0:
            if self.trafficLight == 1:  # yellow
                message = _(
                    "The current image might not be stable.\nFor more information see %s."
                ) % ("http://octagon-forum.eu")
                picon = MessageBox.TYPE_WARNING
            elif self.trafficLight == 2:  # red
                message = _(
                    "The current image is not stable.\nFor more information see %s."
                ) % ("http://octagon-forum.eu")
                picon = MessageBox.TYPE_ERROR
                self.session.open(MessageBox,
                                  message,
                                  type=MessageBox.TYPE_ERROR,
                                  picon=picon,
                                  timeout=15,
                                  close_on_any_key=True)
                return
            elif self.trafficLight == 3:  # unknown
                message = _(
                    "The status of the current image could not be checked because %s can not be reached."
                ) % ("http://octagon-forum.eu")
                picon = MessageBox.TYPE_ERROR
            message += "\n" + _("Do you want to update your receiver?")
            self.session.openWithCallback(self.startActualUpdate,
                                          MessageBox,
                                          message,
                                          default=False,
                                          picon=picon)
        elif self.packages > 0:
            self.startActualUpdate(True)

    def showCommitLog(self):
        self.session.open(CommitInfo)

    def startActualUpdate(self, answer):
        if answer:
            from Plugins.SystemPlugins.SoftwareManager.plugin import UpdatePlugin
            self.session.open(UpdatePlugin)
            self.close()

    def layoutFinished(self):
        self.checkTrafficLight()
        self.rebuildList()

    def UpdatePackageNr(self):
        self.packages = len(self.list)
        print self.packages
        print "packagenr" + str(self.packages)
        self["packagenr"].setText(str(self.packages))
        if self.packages == 0:
            self['key_green'].hide()
            self['key_green_pic'].hide()
        else:
            self['key_green'].show()
            self['key_green_pic'].show()

    def checkTrafficLight(self):
        print "checkTrafficLight"
        from urllib import urlopen
        import socket
        self['a_red'].hide()
        self['a_yellow'].hide()
        self['a_green'].hide()
        self['feedstatusRED'].hide()
        self['feedstatusYELLOW'].hide()
        self['feedstatusGREEN'].hide()
        currentTimeoutDefault = socket.getdefaulttimeout()
        socket.setdefaulttimeout(3)
        try:
            urlOpeneight = "http://feed.openeight.de/status"
            d = urlopen(urlOpeneight)
            self.trafficLight = int(d.read())
            if self.trafficLight == 2:
                self['a_off'].hide()
                self['a_red'].show()
                self['feedstatusRED'].show()
            elif self.trafficLight == 1:
                self['a_off'].hide()
                self['a_yellow'].show()
                self['feedstatusYELLOW'].show()
            elif self.trafficLight == 0:
                self['a_off'].hide()
                self['a_green'].show()
                self['feedstatusGREEN'].show()
        except:
            self.trafficLight = 3
            self['a_off'].show()
        socket.setdefaulttimeout(currentTimeoutDefault)

    def setStatus(self, status=None):
        if status:
            self.statuslist = []
            divpng = LoadPixmap(cached=True,
                                path=resolveFilename(SCOPE_CURRENT_SKIN,
                                                     "skin_default/div-h.png"))
            if status == 'update':
                statuspng = LoadPixmap(
                    cached=True,
                    path=resolveFilename(
                        SCOPE_CURRENT_PLUGIN,
                        "SystemPlugins/SoftwareManager/upgrade.png"))
                self.statuslist.append(
                    (_("Package list update"), '',
                     _("Trying to download a new updatelist. Please wait..."),
                     '', statuspng, divpng))
            elif status == 'error':
                statuspng = LoadPixmap(
                    cached=True,
                    path=resolveFilename(
                        SCOPE_CURRENT_PLUGIN,
                        "SystemPlugins/SoftwareManager/remove.png"))
                self.statuslist.append((
                    _("Error"), '',
                    _("There was an error downloading the updatelist. Please try again."
                      ), '', statuspng, divpng))
            elif status == 'noupdate':
                statuspng = LoadPixmap(
                    cached=True,
                    path=resolveFilename(
                        SCOPE_CURRENT_PLUGIN,
                        "SystemPlugins/SoftwareManager/installed.png"))
                self.statuslist.append((_("Nothing to upgrade"), '',
                                        _("There are no updates available."),
                                        '', statuspng, divpng))

            self['list'].setList(self.statuslist)

    def rebuildList(self):
        self.setStatus('update')
        self.opkg.startCmd(OpkgComponent.CMD_UPDATE)

    def opkgCallback(self, event, param):
        if event == OpkgComponent.EVENT_ERROR:
            self.setStatus('error')
        elif event == OpkgComponent.EVENT_DONE:
            if self.update == False:
                self.update = True
                self.opkg.startCmd(OpkgComponent.CMD_UPGRADE_LIST)
            else:
                self.buildPacketList()
        pass

    def buildEntryComponent(self, name, version, description, state):
        divpng = LoadPixmap(cached=True,
                            path=resolveFilename(SCOPE_CURRENT_SKIN,
                                                 "skin_default/div-h.png"))
        if not description:
            description = "No description available."
        if state == 'installed':
            installedpng = LoadPixmap(
                cached=True,
                path=resolveFilename(
                    SCOPE_CURRENT_PLUGIN,
                    "SystemPlugins/SoftwareManager/installed.png"))
            return ((name, version, _(description), state, installedpng,
                     divpng))
        elif state == 'upgradeable':
            upgradeablepng = LoadPixmap(
                cached=True,
                path=resolveFilename(
                    SCOPE_CURRENT_PLUGIN,
                    "SystemPlugins/SoftwareManager/upgradeable.png"))
            return ((name, version, _(description), state, upgradeablepng,
                     divpng))
        else:
            installablepng = LoadPixmap(
                cached=True,
                path=resolveFilename(
                    SCOPE_CURRENT_PLUGIN,
                    "SystemPlugins/SoftwareManager/installable.png"))
            return ((name, version, _(description), state, installablepng,
                     divpng))

    def buildPacketList(self):
        self.list = []
        fetchedList = self.opkg.getFetchedList()

        if len(fetchedList) > 0:
            for x in fetchedList:
                try:
                    self.list.append(
                        self.buildEntryComponent(x[0], x[1], x[2],
                                                 "upgradeable"))
                except:
                    print "[SOFTWAREPANEL] " + x[
                        0] + " no valid architecture, ignoring !!"

            self['list'].setList(self.list)

        elif len(fetchedList) == 0:
            self.setStatus('noupdate')
        else:
            self.setStatus('error')

        self.UpdatePackageNr()