From 80e4cd758b53ebc828076b5a11a2ffb5053cc3b2 Mon Sep 17 00:00:00 2001 From: ghost Date: Tue, 1 Dec 2009 10:32:01 +0100 Subject: Components/Lcd.py: use 1 instead of 0 for Oled standby default value (with new drivers the oled is completely disabled on lowest step) --- lib/python/Components/Lcd.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'lib/python') diff --git a/lib/python/Components/Lcd.py b/lib/python/Components/Lcd.py index 0e501237..7d27c097 100644 --- a/lib/python/Components/Lcd.py +++ b/lib/python/Components/Lcd.py @@ -42,9 +42,18 @@ def InitLcd(): def setLCDinverted(configElement): ilcd.setInverted(configElement.value); + standby_default = 0 + ilcd = LCD() - config.lcd.standby = ConfigSlider(default=0, limits=(0, 10)) + if not ilcd.isOled(): + config.lcd.contrast = ConfigSlider(default=5, limits=(0, 20)) + config.lcd.contrast.addNotifier(setLCDcontrast); + else: + config.lcd.contrast = ConfigNothing() + standby_default = 1 + + config.lcd.standby = ConfigSlider(default=standby_default, limits=(0, 10)) config.lcd.standby.addNotifier(setLCDbright); config.lcd.standby.apply = lambda : setLCDbright(config.lcd.standby) @@ -53,12 +62,6 @@ def InitLcd(): config.lcd.bright.apply = lambda : setLCDbright(config.lcd.bright) config.lcd.bright.callNotifiersOnSaveAndCancel = True - if not ilcd.isOled(): - config.lcd.contrast = ConfigSlider(default=5, limits=(0, 20)) - config.lcd.contrast.addNotifier(setLCDcontrast); - else: - config.lcd.contrast = ConfigNothing() - config.lcd.invert = ConfigYesNo(default=False) config.lcd.invert.addNotifier(setLCDinverted); else: -- cgit v1.2.3 From 2c3384af08412169cad78b45eae107effafce328 Mon Sep 17 00:00:00 2001 From: ghost Date: Thu, 3 Dec 2009 15:23:41 +0100 Subject: Plugins/Plugin.py, InfoBarGenerics.py: add WHERE_AUDIOMENU for plugins .. requested by Tode for the AudioSync Plugin fixes bug #305 --- lib/python/Plugins/Plugin.py | 2 ++ lib/python/Screens/InfoBarGenerics.py | 47 ++++++++++++++++++++++++++++------- 2 files changed, 40 insertions(+), 9 deletions(-) (limited to 'lib/python') diff --git a/lib/python/Plugins/Plugin.py b/lib/python/Plugins/Plugin.py index d7fc6898..dc68ebf3 100755 --- a/lib/python/Plugins/Plugin.py +++ b/lib/python/Plugins/Plugin.py @@ -52,6 +52,8 @@ class PluginDescriptor: # reason (True: Networkconfig read finished, False: Networkconfig reload initiated ) WHERE_NETWORKCONFIG_READ = 12 + WHERE_AUDIOMENU = 13 + def __init__(self, name = "Plugin", where = [ ], description = "", icon = None, fnc = None, wakeupfnc = None, internal = False): self.name = name self.internal = internal diff --git a/lib/python/Screens/InfoBarGenerics.py b/lib/python/Screens/InfoBarGenerics.py index 2cbfeb73..4f10cbcf 100644 --- a/lib/python/Screens/InfoBarGenerics.py +++ b/lib/python/Screens/InfoBarGenerics.py @@ -1669,17 +1669,46 @@ class InfoBarAudioSelection: else: break + availableKeys = [] + usedKeys = [] + if SystemInfo["CanDownmixAC3"]: - tlist = [(_("AC3 downmix") + " - " +(_("Off"), _("On"))[config.av.downmix_ac3.value and 1 or 0], "CALLFUNC", self.changeAC3Downmix), - ((_("Left"), _("Stereo"), _("Right"))[self.audioChannel.getCurrentChannel()], "mode"), - ("--", "")] + tlist - keys = [ "red", "green", "", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0"] + [""]*n - selection += 3 - else: - tlist = [((_("Left"), _("Stereo"), _("Right"))[self.audioChannel.getCurrentChannel()], "mode"), ("--", "")] + tlist - keys = [ "red", "", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0"] + [""]*n + flist = [(_("AC3 downmix") + " - " +(_("Off"), _("On"))[config.av.downmix_ac3.value and 1 or 0], "CALLFUNC", self.changeAC3Downmix), + ((_("Left"), _("Stereo"), _("Right"))[self.audioChannel.getCurrentChannel()], "mode")] + usedKeys.extend(["red", "green"]) + availableKeys.extend(["yellow", "blue"]) selection += 2 - self.session.openWithCallback(self.audioSelected, ChoiceBox, title=_("Select audio track"), list = tlist, selection = selection, keys = keys, skin_name = "AudioTrackSelection") + else: + flist = [((_("Left"), _("Stereo"), _("Right"))[self.audioChannel.getCurrentChannel()], "mode")] + usedKeys.extend(["red"]) + availableKeys.extend(["green", "yellow", "blue"]) + selection += 1 + + if hasattr(self, "runPlugin"): + class PluginCaller: + def __init__(self, fnc, *args): + self.fnc = fnc + self.args = args + def __call__(self, *args, **kwargs): + self.fnc(*self.args) + + Plugins = [ (p.name, PluginCaller(self.runPlugin, p)) for p in plugins.getPlugins(where = PluginDescriptor.WHERE_AUDIOMENU) ] + + for p in Plugins: + selection += 1 + flist.append((p[0], "CALLFUNC", p[1])) + if availableKeys: + usedKeys.append(availableKeys[0]) + del availableKeys[0] + else: + usedKeys.append("") + + flist.append(("--", "")) + usedKeys.append("") + selection += 1 + + keys = usedKeys + [ "1", "2", "3", "4", "5", "6", "7", "8", "9", "0" ] + [""] * n + self.session.openWithCallback(self.audioSelected, ChoiceBox, title=_("Select audio track"), list = flist + tlist, selection = selection, keys = keys, skin_name = "AudioTrackSelection") else: del self.audioTracks -- cgit v1.2.3 From d6a27dd3d6f51434d5dce98477be2722b91450e3 Mon Sep 17 00:00:00 2001 From: ghost Date: Thu, 3 Dec 2009 16:37:52 +0100 Subject: Components/SystemInfo.py: add new SystemInfo entry "DeepstandbySupport" --- lib/python/Components/SystemInfo.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib/python') diff --git a/lib/python/Components/SystemInfo.py b/lib/python/Components/SystemInfo.py index d2b405a2..f9c4065f 100644 --- a/lib/python/Components/SystemInfo.py +++ b/lib/python/Components/SystemInfo.py @@ -1,5 +1,6 @@ from enigma import eDVBResourceManager from Tools.Directories import fileExists +from Tools.HardwareInfo import HardwareInfo SystemInfo = { } @@ -27,3 +28,4 @@ def countFrontpanelLEDs(): SystemInfo["NumFrontpanelLEDs"] = countFrontpanelLEDs() SystemInfo["FrontpanelDisplay"] = fileExists("/dev/dbox/oled0") or fileExists("/dev/dbox/lcd0") SystemInfo["FrontpanelDisplayGrayscale"] = fileExists("/dev/dbox/oled0") +SystemInfo["DeepstandbySupport"] = HardwareInfo().get_device_name() != "dm800" -- cgit v1.2.3 From cb00266f327ae7da1685cdeaeefddf441bf88316 Mon Sep 17 00:00:00 2001 From: ghost Date: Thu, 3 Dec 2009 16:40:44 +0100 Subject: Menu.py: add possibility to use the exclamation mark as NOT indicator in menu/setup.xml for requires entries (thx to Moritz Venn) --- lib/python/Screens/Menu.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'lib/python') diff --git a/lib/python/Screens/Menu.py b/lib/python/Screens/Menu.py index 5f2032f1..bb0709e5 100644 --- a/lib/python/Screens/Menu.py +++ b/lib/python/Screens/Menu.py @@ -97,8 +97,12 @@ class Menu(Screen): def addMenu(self, destList, node): requires = node.get("requires") - if requires and not SystemInfo.get(requires, False): - return + if requires: + if requires[0] == '!': + if SystemInfo.get(requires[1:], False): + return + elif not SystemInfo.get(requires, False): + return MenuTitle = _(node.get("text", "??").encode("UTF-8")) entryID = node.get("entryID", "undefined") weight = node.get("weight", 50) @@ -120,8 +124,12 @@ class Menu(Screen): def addItem(self, destList, node): requires = node.get("requires") - if requires and not SystemInfo.get(requires, False): - return + if requires: + if requires[0] == '!': + if SystemInfo.get(requires[1:], False): + return + elif not SystemInfo.get(requires, False): + return item_text = node.get("text", "").encode("UTF-8") entryID = node.get("entryID", "undefined") weight = node.get("weight", 50) -- cgit v1.2.3 From 29aad534cf1c20a723fe8d736babad1be1e6e9fa Mon Sep 17 00:00:00 2001 From: ghost Date: Thu, 3 Dec 2009 16:42:12 +0100 Subject: use new DeepstandbySupport SystemInfo entry at some places... this fixes bug #307 --- data/menu.xml | 3 ++- lib/python/Screens/SleepTimerEdit.py | 7 ++++++- lib/python/Screens/TaskView.py | 7 ++++++- lib/python/Screens/TimerEntry.py | 7 ++++++- 4 files changed, 20 insertions(+), 4 deletions(-) (limited to 'lib/python') diff --git a/data/menu.xml b/data/menu.xml index c7fb8897..a96912a6 100644 --- a/data/menu.xml +++ b/data/menu.xml @@ -104,6 +104,7 @@ self.session.openWithCallback(msgClosed, FactoryReset) 2 3 - 1 + 1 + 1 diff --git a/lib/python/Screens/SleepTimerEdit.py b/lib/python/Screens/SleepTimerEdit.py index ff061d88..e5e7af4e 100644 --- a/lib/python/Screens/SleepTimerEdit.py +++ b/lib/python/Screens/SleepTimerEdit.py @@ -5,6 +5,7 @@ from Components.Input import Input from Components.Label import Label from Components.Pixmap import Pixmap from Components.config import config, ConfigInteger +from Components.SystemInfo import SystemInfo from enigma import eEPGCache from SleepTimer import SleepTimer from time import time @@ -77,7 +78,11 @@ class SleepTimerEdit(Screen): self["red_text"].setText(_("Action:") + " " + _("Disable timer")) if config.SleepTimer.action.value == "shutdown": - self["green_text"].setText(_("Sleep timer action:") + " " + _("Deep Standby")) + if SystemInfo["DeepstandbySupport"]: + shutdownString = _("Deep Standby") + else: + shutdownString = _("Shutdown") + self["green_text"].setText(_("Sleep timer action:") + " " + shutdownString) elif config.SleepTimer.action.value == "standby": self["green_text"].setText(_("Sleep timer action:") + " " + _("Standby")) diff --git a/lib/python/Screens/TaskView.py b/lib/python/Screens/TaskView.py index 1453c05f..eb926ca3 100644 --- a/lib/python/Screens/TaskView.py +++ b/lib/python/Screens/TaskView.py @@ -1,6 +1,7 @@ from Screen import Screen from Components.ConfigList import ConfigListScreen from Components.config import config, ConfigSubsection, ConfigSelection, getConfigListEntry +from Components.SystemInfo import SystemInfo from InfoBarGenerics import InfoBarNotifications import Screens.Standby from Tools import Notifications @@ -44,7 +45,11 @@ class JobView(InfoBarNotifications, Screen, ConfigListScreen): self.afterevents = [ "nothing", "standby", "deepstandby", "close" ] self.settings = ConfigSubsection() - self.settings.afterEvent = ConfigSelection(choices = [("nothing", _("do nothing")), ("close", _("Close")), ("standby", _("go to standby")), ("deepstandby", _("go to deep standby"))], default = self.afterevents[afterEvent]) + if SystemInfo["DeepstandbySupport"]: + shutdownString = _("go to deep standby") + else: + shutdownString = _("shut down") + self.settings.afterEvent = ConfigSelection(choices = [("nothing", _("do nothing")), ("close", _("Close")), ("standby", _("go to standby")), ("deepstandby", shutdownString)], default = self.afterevents[afterEvent]) self.setupList() self.state_changed() diff --git a/lib/python/Screens/TimerEntry.py b/lib/python/Screens/TimerEntry.py index edd19685..c6b0db8f 100644 --- a/lib/python/Screens/TimerEntry.py +++ b/lib/python/Screens/TimerEntry.py @@ -8,6 +8,7 @@ from Components.MenuList import MenuList from Components.Button import Button from Components.Label import Label from Components.Pixmap import Pixmap +from Components.SystemInfo import SystemInfo from Screens.MovieSelection import getPreferredTagEditor from Screens.LocationBox import MovieLocationBox from Screens.ChoiceBox import ChoiceBox @@ -93,7 +94,11 @@ class TimerEntry(Screen, ConfigListScreen): day[weekday] = 1 self.timerentry_justplay = ConfigSelection(choices = [("zap", _("zap")), ("record", _("record"))], default = {0: "record", 1: "zap"}[justplay]) - self.timerentry_afterevent = ConfigSelection(choices = [("nothing", _("do nothing")), ("standby", _("go to standby")), ("deepstandby", _("go to deep standby")), ("auto", _("auto"))], default = afterevent) + if SystemInfo["DeepstandbySupport"]: + shutdownString = _("go to deep standby") + else: + shutdownString = _("shut down") + self.timerentry_afterevent = ConfigSelection(choices = [("nothing", _("do nothing")), ("standby", _("go to standby")), ("deepstandby", shutdownString), ("auto", _("auto"))], default = afterevent) self.timerentry_type = ConfigSelection(choices = [("once",_("once")), ("repeated", _("repeated"))], default = type) self.timerentry_name = ConfigText(default = self.timer.name, visible_width = 50, fixed_size = False) self.timerentry_description = ConfigText(default = self.timer.description, visible_width = 50, fixed_size = False) -- cgit v1.2.3 From bbe28d433549d0559ac2f91ca2903d5bc6b60bf4 Mon Sep 17 00:00:00 2001 From: ghost Date: Wed, 9 Dec 2009 15:47:56 +0100 Subject: fix skip backward from live to timeshift --- lib/python/Screens/InfoBarGenerics.py | 3 --- lib/service/servicedvb.cpp | 3 ++- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'lib/python') diff --git a/lib/python/Screens/InfoBarGenerics.py b/lib/python/Screens/InfoBarGenerics.py index 39a8b59d..527b9772 100644 --- a/lib/python/Screens/InfoBarGenerics.py +++ b/lib/python/Screens/InfoBarGenerics.py @@ -1205,10 +1205,7 @@ class InfoBarTimeshift: self.setSeekState(self.SEEK_STATE_PAUSE) if back: - self.doSeek(-5) # seek some gops before end self.ts_rewind_timer.start(200, 1) - else: - self.doSeek(-1) # seek 1 gop before end def rewindService(self): self.setSeekState(self.makeStateBackward(int(config.seek.enter_backward.value))) diff --git a/lib/service/servicedvb.cpp b/lib/service/servicedvb.cpp index b71271a9..9a995e7b 100644 --- a/lib/service/servicedvb.cpp +++ b/lib/service/servicedvb.cpp @@ -2285,12 +2285,13 @@ void eDVBServicePlay::switchToTimeshift() r.path = m_timeshift_file; m_cue = new eCueSheet(); + m_cue->seekTo(0, -1000); m_service_handler_timeshift.tune(r, 1, m_cue, 0, m_dvb_service); /* use the decoder demux for everything */ eDebug("eDVBServicePlay::switchToTimeshift, in pause mode now."); pause(); updateDecoder(); /* mainly to switch off PCR, and to set pause */ - + m_event((iPlayableService*)this, evSeekableStatusChanged); } -- cgit v1.2.3 From 807d980857651dacdba0abfc9a5e87fb473303cc Mon Sep 17 00:00:00 2001 From: ghost Date: Sun, 13 Dec 2009 12:35:54 +0100 Subject: CutListEditor: always restart service on cutlist editor close --- lib/python/Plugins/Extensions/CutListEditor/plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/python') diff --git a/lib/python/Plugins/Extensions/CutListEditor/plugin.py b/lib/python/Plugins/Extensions/CutListEditor/plugin.py index 75663462..ee75ec09 100644 --- a/lib/python/Plugins/Extensions/CutListEditor/plugin.py +++ b/lib/python/Plugins/Extensions/CutListEditor/plugin.py @@ -189,7 +189,7 @@ class CutListEditor(Screen, InfoBarBase, InfoBarSeek, InfoBarCueSheetSupport, He self.onClose.append(self.__onClose) def __onClose(self): - self.session.nav.playService(self.old_service) + self.session.nav.playService(self.old_service, forceRestart=True) def showTutorial(self): if not self.tutorial_seen: -- cgit v1.2.3 From d2188eb11a8c7663e34b1ab3d343a9981e60da62 Mon Sep 17 00:00:00 2001 From: ghost Date: Mon, 14 Dec 2009 10:27:38 +0100 Subject: Bugfix by Anders Holst: A bug was detected in the recent recordpath patch. It could cause a crash when using the green or yellow button to select a tag in the movielist. --- lib/python/Screens/MovieSelection.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/python') diff --git a/lib/python/Screens/MovieSelection.py b/lib/python/Screens/MovieSelection.py index 15f6b465..0468f8a0 100644 --- a/lib/python/Screens/MovieSelection.py +++ b/lib/python/Screens/MovieSelection.py @@ -398,7 +398,7 @@ class MovieSelection(Screen, HelpableScreen, SelectionEventInfo): def showTagsN(self, tagele): if not self.tags: self.showTagWarning() - elif not tagele or tagele.value in self.selected_tags or not tagele.value in self.tags: + elif not tagele or (self.selected_tags and tagele.value in self.selected_tags) or not tagele.value in self.tags: self.showTagsMenu(tagele) else: self.selected_tags_ele = tagele -- cgit v1.2.3 From 5808051426cab03a0dc117c73b941b0afb05a87d Mon Sep 17 00:00:00 2001 From: acid-burn Date: Wed, 23 Dec 2009 07:17:35 +0100 Subject: WirelessLan/plugin.py: fix merge conflict --- lib/python/Plugins/SystemPlugins/WirelessLan/plugin.py | 5 ----- 1 file changed, 5 deletions(-) (limited to 'lib/python') diff --git a/lib/python/Plugins/SystemPlugins/WirelessLan/plugin.py b/lib/python/Plugins/SystemPlugins/WirelessLan/plugin.py index c71037c5..c8568b98 100755 --- a/lib/python/Plugins/SystemPlugins/WirelessLan/plugin.py +++ b/lib/python/Plugins/SystemPlugins/WirelessLan/plugin.py @@ -262,11 +262,6 @@ class WlanScan(Screen): self.updateAPList() def buildEntryComponent(self, essid, bssid, encrypted, iface, maxrate, signal): -<<<<<<< HEAD:lib/python/Plugins/SystemPlugins/WirelessLan/plugin.py - print "buildEntryComponent",essid - print "buildEntryComponent",bssid -======= ->>>>>>> bug_203_fix_wrong_networkstate:lib/python/Plugins/SystemPlugins/WirelessLan/plugin.py divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/div-h.png")) encryption = encrypted and _("Yes") or _("No") if bssid == 'hidden...': -- cgit v1.2.3 From d87634a81b24586b49adeab2f62a40e15f8e863a Mon Sep 17 00:00:00 2001 From: Stefan Pluecken Date: Tue, 10 Nov 2009 16:35:00 +0100 Subject: fixes bug #281 add "yes to all" and "no to all" to "Delete no more configured satellite" dialog if orbpos isn't needed anymore in current sat config --- lib/python/Screens/Satconfig.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'lib/python') diff --git a/lib/python/Screens/Satconfig.py b/lib/python/Screens/Satconfig.py index 8b5089a3..e24e4636 100644 --- a/lib/python/Screens/Satconfig.py +++ b/lib/python/Screens/Satconfig.py @@ -8,6 +8,7 @@ from Components.NimManager import nimmanager from Components.config import getConfigListEntry, config, ConfigNothing, ConfigSelection, updateConfigElement from Components.Sources.List import List from Screens.MessageBox import MessageBox +from Screens.ChoiceBox import ChoiceBox from time import mktime, localtime from datetime import datetime @@ -342,10 +343,10 @@ class NimSetup(Screen, ConfigListScreen): new_configured_sats = nimmanager.getConfiguredSats() self.unconfed_sats = old_configured_sats - new_configured_sats self.satpos_to_remove = None - self.deleteConfirmed(False) + self.deleteConfirmed((None, "no")) def deleteConfirmed(self, confirmed): - if confirmed: + if confirmed[1] == "yes" or confirmed[1] == "yestoall": eDVBDB.getInstance().removeServices(-1, -1, -1, self.satpos_to_remove) if self.satpos_to_remove is not None: @@ -365,11 +366,15 @@ class NimSetup(Screen, ConfigListScreen): else: h = _("E") sat_name = ("%d.%d" + h) % (orbpos / 10, orbpos % 10) - self.session.openWithCallback(self.deleteConfirmed, MessageBox, _("Delete no more configured satellite\n%s?") %(sat_name)) + + if confirmed[1] == "yes" or confirmed[1] == "no": + self.session.openWithCallback(self.deleteConfirmed, ChoiceBox, _("Delete no more configured satellite\n%s?") %(sat_name), [(_("Yes"), "yes"), (_("No"), "no"), (_("Yes to all"), "yestoall"), (_("No to all"), "notoall")]) + if confirmed[1] == "yestoall" or confirmed[1] == "notoall": + self.deleteConfirmed(confirmed) break if not self.satpos_to_remove: self.close() - + def __init__(self, session, slotid): Screen.__init__(self, session) self.list = [ ] -- cgit v1.2.3 From ab069c3dbe84a06e5cfa4c1f5c196690d53fa9a2 Mon Sep 17 00:00:00 2001 From: Stefan Pluecken Date: Sat, 7 Nov 2009 12:21:25 +0100 Subject: fixes bug #280 don't allow scanning on a nim configured as advanced with no LNB assigned to any sat --- lib/python/Screens/ScanSetup.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib/python') diff --git a/lib/python/Screens/ScanSetup.py b/lib/python/Screens/ScanSetup.py index bea08724..fa787a70 100644 --- a/lib/python/Screens/ScanSetup.py +++ b/lib/python/Screens/ScanSetup.py @@ -524,6 +524,8 @@ class ScanSetup(ConfigListScreen, Screen, CableTransponderSearchSupport): for n in nimmanager.nim_slots: if n.config_mode == "nothing": continue + if n.config_mode == "advanced" and len(nimmanager.getSatListForNim(n.slot)) < 1: + continue if n.config_mode in ("loopthrough", "satposdepends"): root_id = nimmanager.sec.getRoot(n.slot_id, int(n.config.connectedTo.value)) if n.type == nimmanager.nim_slots[root_id].type: # check if connected from a DVB-S to DVB-S2 Nim or vice versa -- cgit v1.2.3 From 6494baea016edbaab77c1d07521cf73205857085 Mon Sep 17 00:00:00 2001 From: Stefan Pluecken Date: Mon, 16 Nov 2009 19:03:34 +0100 Subject: fixes bug #291 don't crash if auto scart switching is enabled and the scart voltage is high on enigma2 startup not the best solution since the whole scart switching stuff is broken by design, but this fix prevents the crash --- lib/python/Screens/MessageBox.py | 4 +++- lib/python/Screens/Scart.py | 19 ++++++++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) (limited to 'lib/python') diff --git a/lib/python/Screens/MessageBox.py b/lib/python/Screens/MessageBox.py index 86bf07d3..f3538b7b 100644 --- a/lib/python/Screens/MessageBox.py +++ b/lib/python/Screens/MessageBox.py @@ -12,9 +12,11 @@ class MessageBox(Screen): TYPE_WARNING = 2 TYPE_ERROR = 3 - def __init__(self, session, text, type = TYPE_YESNO, timeout = -1, close_on_any_key = False, default = True, enable_input = True): + def __init__(self, session, text, type = TYPE_YESNO, timeout = -1, close_on_any_key = False, default = True, enable_input = True, msgBoxID = None): self.type = type Screen.__init__(self, session) + + self.msgBoxID = msgBoxID self["text"] = Label(text) self["Text"] = StaticText(text) diff --git a/lib/python/Screens/Scart.py b/lib/python/Screens/Scart.py index dc511448..00e78593 100644 --- a/lib/python/Screens/Scart.py +++ b/lib/python/Screens/Scart.py @@ -1,10 +1,13 @@ from Screen import Screen from MessageBox import MessageBox from Components.AVSwitch import AVSwitch +from Tools import Notifications class Scart(Screen): def __init__(self, session, start_visible=True): Screen.__init__(self, session) + self.msgBox = None + self.notificationVisible = None self.avswitch = AVSwitch() @@ -22,7 +25,11 @@ class Scart(Screen): if not self.msgVisible: self.msgVisible = True self.avswitch.setInput("SCART") - self.msgBox = self.session.openWithCallback(self.MsgBoxClosed, MessageBox, _("If you see this, something is wrong with\nyour scart connection. Press OK to return."), MessageBox.TYPE_ERROR) + if not self.session.in_exec: + self.notificationVisible = True + Notifications.AddNotificationWithCallback(self.MsgBoxClosed, MessageBox, _("If you see this, something is wrong with\nyour scart connection. Press OK to return."), MessageBox.TYPE_ERROR, msgBoxID = "scart_msgbox") + else: + self.msgBox = self.session.openWithCallback(self.MsgBoxClosed, MessageBox, _("If you see this, something is wrong with\nyour scart connection. Press OK to return."), MessageBox.TYPE_ERROR) def MsgBoxClosed(self, *val): self.msgBox = None @@ -35,3 +42,13 @@ class Scart(Screen): return self.avswitch.setInput("ENCODER") self.msgVisible = False + if self.notificationVisible: + self.avswitch.setInput("ENCODER") + self.notificationVisible = False + for notification in Notifications.current_notifications: + try: + if notification[1].msgBoxID == "scart_msgbox": + notification[1].close() + except: + print "other notification is open. try another one." + \ No newline at end of file -- cgit v1.2.3 From ee9a89efd6533997e3dc9a4e8adcb360333d01d9 Mon Sep 17 00:00:00 2001 From: thedoc Date: Wed, 23 Dec 2009 11:42:22 +0100 Subject: fixes bug #322 change default visibility of blinking dish icon to true --- lib/python/Components/UsageConfig.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/python') diff --git a/lib/python/Components/UsageConfig.py b/lib/python/Components/UsageConfig.py index 680b5944..60827107 100644 --- a/lib/python/Components/UsageConfig.py +++ b/lib/python/Components/UsageConfig.py @@ -7,7 +7,7 @@ import os def InitUsageConfig(): config.usage = ConfigSubsection(); - config.usage.showdish = ConfigYesNo(default = False) + config.usage.showdish = ConfigYesNo(default = True) config.usage.multibouquet = ConfigYesNo(default = False) config.usage.quickzap_bouquet_change = ConfigYesNo(default = False) config.usage.e1like_radio_mode = ConfigYesNo(default = False) -- cgit v1.2.3 From 0d6eafb15604b8044bfaad3cc844b561f14cfbe1 Mon Sep 17 00:00:00 2001 From: thedoc Date: Wed, 23 Dec 2009 21:57:24 +0100 Subject: fixes bug #273 add a quick shortcut to switch to "nothing connected" in the sat config screen for remote debugging purposes (undocumented) --- data/keymap.xml | 4 ++++ lib/python/Screens/Satconfig.py | 11 +++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) (limited to 'lib/python') diff --git a/data/keymap.xml b/data/keymap.xml index 25538f87..9461d509 100755 --- a/data/keymap.xml +++ b/data/keymap.xml @@ -98,6 +98,10 @@ + + + + diff --git a/lib/python/Screens/Satconfig.py b/lib/python/Screens/Satconfig.py index e24e4636..93fdcd35 100644 --- a/lib/python/Screens/Satconfig.py +++ b/lib/python/Screens/Satconfig.py @@ -5,7 +5,8 @@ from Components.ActionMap import ActionMap from Components.ConfigList import ConfigListScreen from Components.MenuList import MenuList from Components.NimManager import nimmanager -from Components.config import getConfigListEntry, config, ConfigNothing, ConfigSelection, updateConfigElement +from Components.config import getConfigListEntry, config, ConfigNothing, ConfigSelection, updateConfigElement,\ + ConfigSatlist from Components.Sources.List import List from Screens.MessageBox import MessageBox from Screens.ChoiceBox import ChoiceBox @@ -381,10 +382,11 @@ class NimSetup(Screen, ConfigListScreen): ConfigListScreen.__init__(self, self.list) - self["actions"] = ActionMap(["SetupActions"], + self["actions"] = ActionMap(["SetupActions", "SatlistShortcutAction"], { "ok": self.keySave, "cancel": self.keyCancel, + "nothingconnected": self.nothingConnectedShortcut }, -2) self.slotid = slotid @@ -421,6 +423,11 @@ class NimSetup(Screen, ConfigListScreen): # we need to call saveAll to reset the connectedTo choices self.saveAll() self.close() + + def nothingConnectedShortcut(self): + if type(self["config"].getCurrent()[1]) is ConfigSatlist: + self["config"].getCurrent()[1].setValue("3601") + self["config"].invalidateCurrent() class NimSelection(Screen): def __init__(self, session): -- cgit v1.2.3 From 4fa93c4c98d18601102d8aa2d5606c4e2a824442 Mon Sep 17 00:00:00 2001 From: acid-burn Date: Mon, 28 Dec 2009 20:58:06 +0100 Subject: Screens/PluginBrowser.py: - remove possibility to install/remove plugins from Plugins Menu. This is now possible over new extension management inside the Software management. this is for bug #112 --- lib/python/Screens/PluginBrowser.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'lib/python') diff --git a/lib/python/Screens/PluginBrowser.py b/lib/python/Screens/PluginBrowser.py index 61bb7d0a..acb9dafb 100755 --- a/lib/python/Screens/PluginBrowser.py +++ b/lib/python/Screens/PluginBrowser.py @@ -22,18 +22,16 @@ class PluginBrowser(Screen): def __init__(self, session): Screen.__init__(self, session) - self["red"] = Label(_("Remove Plugins")) - self["green"] = Label(_("Download Plugins")) + self["red"] = Label() + self["green"] = Label() self.list = [] self["list"] = PluginList(self.list) - self["actions"] = ActionMap(["WizardActions", "ColorActions"], + self["actions"] = ActionMap(["WizardActions"], { "ok": self.save, "back": self.close, - "red": self.delete, - "green": self.download }) self.onFirstExecBegin.append(self.checkWarnings) self.onShown.append(self.updateList) @@ -47,7 +45,6 @@ class PluginBrowser(Screen): self.session.open(MessageBox, text = text, type = MessageBox.TYPE_WARNING) def save(self): - #self.close() self.run() def run(self): -- cgit v1.2.3 From a3772ffd9c498db0eaadfae4d02e1816325ca58e Mon Sep 17 00:00:00 2001 From: acid-burn Date: Mon, 28 Dec 2009 21:01:06 +0100 Subject: SystemPlugins/SoftwareManager: - add SoftwareTools.py to factor out some code. This is for bug #112 --- .../SystemPlugins/SoftwareManager/SoftwareTools.py | 226 +++++++++++++++++++++ 1 file changed, 226 insertions(+) create mode 100755 lib/python/Plugins/SystemPlugins/SoftwareManager/SoftwareTools.py (limited to 'lib/python') diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/SoftwareTools.py b/lib/python/Plugins/SystemPlugins/SoftwareManager/SoftwareTools.py new file mode 100755 index 00000000..4e7591ef --- /dev/null +++ b/lib/python/Plugins/SystemPlugins/SoftwareManager/SoftwareTools.py @@ -0,0 +1,226 @@ +from enigma import eConsoleAppContainer +from Components.Console import Console +from Components.About import about +from Components.DreamInfoHandler import DreamInfoHandler +from Components.Language import language +from Components.Sources.List import List +from Components.Ipkg import IpkgComponent +from Components.Network import iNetwork +from Tools.Directories import pathExists, fileExists, resolveFilename, SCOPE_METADIR + +from time import time + +class SoftwareTools(DreamInfoHandler): + 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" + DreamInfoHandler.__init__(self, self.statusCallback, blocking = False, neededTag = 'ALL_TAGS', neededFlag = self.ImageVersion, language = self.language) + 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') + self.ipkg = IpkgComponent() + self.ipkg.addCallback(self.ipkgCallback) + + 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: + SoftwareTools.NetworkConnectionAvailable = True + self.getUpdates() + else: + SoftwareTools.NetworkConnectionAvailable = False + self.getUpdates() + + def getUpdates(self, callback = None): + if SoftwareTools.NetworkConnectionAvailable == True: + SoftwareTools.lastDownloadDate = time() + if SoftwareTools.list_updating is False and callback is None: + SoftwareTools.list_updating = True + self.ipkg.startCmd(IpkgComponent.CMD_UPDATE) + elif SoftwareTools.list_updating is False and callback is not None: + SoftwareTools.list_updating = True + self.NotifierCallback = callback + self.ipkg.startCmd(IpkgComponent.CMD_UPDATE) + elif SoftwareTools.list_updating is True and callback is not None: + #update info collecting already in progress + self.NotifierCallback = callback + else: + SoftwareTools.list_updating = False + if callback is not None: + callback(False) + elif self.NotifierCallback is not None: + self.NotifierCallback(False) + + def ipkgCallback(self, event, param): + if event == IpkgComponent.EVENT_ERROR: + SoftwareTools.list_updating = False + elif event == IpkgComponent.EVENT_DONE: + if SoftwareTools.list_updating: + self.startIpkgListAvailable() + pass + + def startIpkgListAvailable(self, callback = None): + if callback is not None: + SoftwareTools.list_updating = True + if SoftwareTools.list_updating: + if not self.UpdateConsole: + self.UpdateConsole = Console() + cmd = "ipkg list" + self.UpdateConsole.ePopen(cmd, self.IpkgListAvailableCB, callback) + + def IpkgListAvailableCB(self, result, retval, extra_args = None): + (callback) = extra_args + if len(result): + if SoftwareTools.list_updating: + SoftwareTools.available_packetlist = [] + for x in result.splitlines(): + split = x.split(' - ') + name = split[0].strip() + if not any(name.endswith(x) for x in self.unwanted_extensions): + SoftwareTools.available_packetlist.append([name, split[1].strip(), split[2].strip()]) + if callback is None: + self.startInstallMetaPackage() + else: + if self.UpdateConsole: + if len(self.UpdateConsole.appContainers) == 0: + callback(True) + else: + SoftwareTools.list_updating = False + if self.UpdateConsole: + if len(self.UpdateConsole.appContainers) == 0: + if callback is not None: + callback(False) + + def startInstallMetaPackage(self, callback = None): + if callback is not None: + SoftwareTools.list_updating = True + if SoftwareTools.list_updating: + if not self.UpdateConsole: + self.UpdateConsole = Console() + cmd = "ipkg install enigma2-meta enigma2-plugins-meta enigma2-skins-meta" + self.UpdateConsole.ePopen(cmd, self.InstallMetaPackageCB, callback) + + def InstallMetaPackageCB(self, result, retval, extra_args = None): + (callback) = extra_args + if len(result): + self.fillPackagesIndexList() + if callback is None: + self.startIpkgListInstalled() + else: + if self.UpdateConsole: + if len(self.UpdateConsole.appContainers) == 0: + callback(True) + else: + SoftwareTools.list_updating = False + if self.UpdateConsole: + if len(self.UpdateConsole.appContainers) == 0: + if callback is not None: + callback(False) + + def startIpkgListInstalled(self, callback = None): + if callback is not None: + SoftwareTools.list_updating = True + if SoftwareTools.list_updating: + if not self.UpdateConsole: + self.UpdateConsole = Console() + cmd = "ipkg list_installed" + self.UpdateConsole.ePopen(cmd, self.IpkgListInstalledCB, callback) + + def IpkgListInstalledCB(self, result, retval, extra_args = None): + (callback) = extra_args + if len(result): + SoftwareTools.installed_packetlist = {} + for x in result.splitlines(): + split = x.split(' - ') + name = split[0].strip() + if not any(name.endswith(x) for x in self.unwanted_extensions): + SoftwareTools.installed_packetlist[name] = split[1].strip() + if callback is None: + self.countUpdates() + else: + if self.UpdateConsole: + if len(self.UpdateConsole.appContainers) == 0: + callback(True) + else: + SoftwareTools.list_updating = False + if self.UpdateConsole: + if len(self.UpdateConsole.appContainers) == 0: + if callback is not None: + callback(False) + + def countUpdates(self, callback = None): + SoftwareTools.available_updates = 0 + SoftwareTools.available_updatelist = [] + for package in self.packagesIndexlist[:]: + attributes = package[0]["attributes"] + packagename = attributes["packagename"] + for x in SoftwareTools.available_packetlist: + if x[0] == packagename: + if SoftwareTools.installed_packetlist.has_key(packagename): + if SoftwareTools.installed_packetlist[packagename] != x[1]: + SoftwareTools.available_updates +=1 + SoftwareTools.available_updatelist.append([packagename]) + + SoftwareTools.list_updating = False + if self.UpdateConsole: + if len(self.UpdateConsole.appContainers) == 0: + if callback is not None: + callback(True) + callback = None + elif self.NotifierCallback is not None: + self.NotifierCallback(True) + self.NotifierCallback = None + + def startIpkgUpdate(self, callback = None): + if not self.Console: + self.Console = Console() + cmd = "ipkg update" + self.Console.ePopen(cmd, self.IpkgUpdateCB, callback) + + def IpkgUpdateCB(self, result, retval, extra_args = None): + (callback) = extra_args + if len(result): + if self.Console: + if len(self.Console.appContainers) == 0: + if callback is not None: + callback(True) + callback = None + + def cleanupSoftwareTools(self): + if self.NotifierCallback is not None: + self.NotifierCallback = None + self.ipkg.stop() + if self.Console is not None: + if len(self.Console.appContainers): + for name in self.Console.appContainers.keys(): + self.Console.kill(name) + if self.UpdateConsole is not None: + if len(self.UpdateConsole.appContainers): + for name in self.UpdateConsole.appContainers.keys(): + self.UpdateConsole.kill(name) + +iSoftwareTools = SoftwareTools() \ No newline at end of file -- cgit v1.2.3 From 018534fa7bf9be0885b2ffc753d8d6fc5b56143c Mon Sep 17 00:00:00 2001 From: acid-burn Date: Mon, 28 Dec 2009 21:02:41 +0100 Subject: SoftwareManager/plugin.py: - enable extensions management inside Software manager. - disable no more needed packet manager. - some cleanups and fixes. This fixes bug #112. --- .../SystemPlugins/SoftwareManager/plugin.py | 2400 ++++++++++---------- 1 file changed, 1189 insertions(+), 1211 deletions(-) (limited to 'lib/python') diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/plugin.py b/lib/python/Plugins/SystemPlugins/SoftwareManager/plugin.py index c70201b3..6162d8a5 100755 --- a/lib/python/Plugins/SystemPlugins/SoftwareManager/plugin.py +++ b/lib/python/Plugins/SystemPlugins/SoftwareManager/plugin.py @@ -23,6 +23,7 @@ from Components.About import about from Components.DreamInfoHandler import DreamInfoHandler from Components.Language import language from Components.AVSwitch import AVSwitch +from Components.Network import iNetwork from Tools.Directories import pathExists, fileExists, resolveFilename, SCOPE_PLUGINS, SCOPE_CURRENT_PLUGIN, SCOPE_CURRENT_SKIN, SCOPE_METADIR from Tools.LoadPixmap import LoadPixmap from enigma import eTimer, quitMainloop, RT_HALIGN_LEFT, RT_VALIGN_CENTER, eListboxPythonMultiContent, eListbox, gFont, getDesktop, ePicLoad @@ -36,6 +37,7 @@ from twisted.internet import reactor from ImageWizard import ImageWizard from BackupRestore import BackupSelection, RestoreMenu, BackupScreen, RestoreScreen, getBackupPath, getBackupFilename +from SoftwareTools import iSoftwareTools config.plugins.configurationbackup = ConfigSubsection() config.plugins.configurationbackup.backuplocation = ConfigText(default = '/media/hdd/', visible_width = 50, fixed_size = False) @@ -74,30 +76,31 @@ def load_cache(cache_file): class UpdatePluginMenu(Screen): skin = """ - + - - + + {"template": [ - MultiContentEntryText(pos = (2, 2), size = (290, 22), flags = RT_HALIGN_LEFT, text = 1), # index 0 is the MenuText, + MultiContentEntryText(pos = (2, 2), size = (330, 24), flags = RT_HALIGN_LEFT, text = 1), # index 0 is the MenuText, ], - "fonts": [gFont("Regular", 20)], + "fonts": [gFont("Regular", 22)], "itemHeight": 25 } - + {"template": [ MultiContentEntryText(pos = (2, 2), size = (240, 300), flags = RT_HALIGN_CENTER|RT_VALIGN_CENTER|RT_WRAP, text = 2), # index 2 is the Description, ], - "fonts": [gFont("Regular", 20)], + "fonts": [gFont("Regular", 22)], "itemHeight": 300 } + """ def __init__(self, session, args = 0): @@ -106,14 +109,15 @@ class UpdatePluginMenu(Screen): self.menu = args self.list = [] self.oktext = _("\nPress OK on your remote control to continue.") + self.text = "" self.backupdirs = ' '.join( config.plugins.configurationbackup.backupdirs.value ) if self.menu == 0: + self.list.append(("install-extensions", _("Manage extensions"), _("\nManage extensions or plugins for your Dreambox" ) + self.oktext, None)) self.list.append(("software-update", _("Software update"), _("\nOnline update of your Dreambox software." ) + self.oktext, None)) - #self.list.append(("install-plugins", _("Install extensions"), _("\nInstall new Extensions or Plugins to your dreambox" ) + self.oktext, None)) self.list.append(("software-restore", _("Software restore"), _("\nRestore your Dreambox with a new firmware." ) + self.oktext, None)) self.list.append(("system-backup", _("Backup system settings"), _("\nBackup your Dreambox settings." ) + self.oktext, None)) self.list.append(("system-restore",_("Restore system settings"), _("\nRestore your Dreambox settings." ) + self.oktext, None)) - self.list.append(("ipkg-install", _("Install local extension"), _("\nScan for local packages and install them." ) + self.oktext, None)) + self.list.append(("ipkg-install", _("Install local extension"), _("\nScan for local extensions and install them." ) + self.oktext, None)) for p in plugins.getPlugins(PluginDescriptor.WHERE_SOFTWAREMANAGER): if p.__call__.has_key("SoftwareSupported"): callFnc = p.__call__["SoftwareSupported"](None) @@ -133,8 +137,8 @@ class UpdatePluginMenu(Screen): self.list.append(("advancedrestore", _("Advanced restore"), _("\nRestore your backups by date." ) + self.oktext, None)) self.list.append(("backuplocation", _("Choose backup location"), _("\nSelect your backup device.\nCurrent device: " ) + config.plugins.configurationbackup.backuplocation.value + self.oktext, None)) self.list.append(("backupfiles", _("Choose backup files"), _("Select files for backup. Currently selected:\n" ) + self.backupdirs + self.oktext, None)) - if config.usage.setup_level.index >= 2: # expert+ - self.list.append(("ipkg-manager", _("Packet management"), _("\nView, install and remove available or installed packages." ) + self.oktext, None)) + #if config.usage.setup_level.index >= 2: # expert+ + # self.list.append(("ipkg-manager", _("Packet management"), _("\nView, install and remove available or installed packages." ) + self.oktext, None)) self.list.append(("ipkg-source",_("Choose upgrade source"), _("\nEdit the upgrade source address." ) + self.oktext, None)) for p in plugins.getPlugins(PluginDescriptor.WHERE_SOFTWAREMANAGER): if p.__call__.has_key("AdvancedSoftwareSupported"): @@ -152,28 +156,54 @@ class UpdatePluginMenu(Screen): self["menu"] = List(self.list) self["key_red"] = StaticText(_("Close")) + self["status"] = StaticText("") - self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"], + self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions", "InfobarEPGActions"], { "ok": self.go, "back": self.close, "red": self.close, }, -1) - self.onLayoutFinish.append(self.layoutFinished) self.backuppath = getBackupPath() self.backupfile = getBackupFilename() self.fullbackupfilename = self.backuppath + "/" + self.backupfile self.onShown.append(self.setWindowTitle) + #self.onClose.append(self.cleanup) def layoutFinished(self): idx = 0 self["menu"].index = idx + #self.getUpdateInfos() def setWindowTitle(self): - self.setTitle(_("Software manager")) + self.setTitle(_("Software management")) + + def cleanup(self): + iNetwork.stopPingConsole() + iSoftwareTools.cleanupSoftwareTools() + + def getUpdateInfos(self): + self.text = "" + if iSoftwareTools.NetworkConnectionAvailable == True: + if iSoftwareTools.list_updating is False: + if iSoftwareTools.available_updates is not 0: + self.text = _("There are at least ") + str(iSoftwareTools.available_updates) + _(" updates available.") + else: + self.text = "" #_("There are no updates available.") + else: + if iSoftwareTools.available_updates is not 0: + self.text = _("There are at least ") + str(iSoftwareTools.available_updates) + _(" updates available.") + else: + self.text = "" #_("There are no updates available.") + self.text += "\n" + _("A search for available updates is currently in progress.") + else: + self.text = _("No network connection available.") + self["status"].setText(self.text) + def go(self): + #iNetwork.stopPingConsole() current = self["menu"].getCurrent() if current: currentEntry = current[0] @@ -182,7 +212,7 @@ class UpdatePluginMenu(Screen): self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to update your Dreambox?")+"\n"+_("\nAfter pressing OK, please wait!")) elif (currentEntry == "software-restore"): self.session.open(ImageWizard) - elif (currentEntry == "install-plugins"): + elif (currentEntry == "install-extensions"): self.session.open(PluginManager, self.skin_path) elif (currentEntry == "system-backup"): self.session.openWithCallback(self.backupDone,BackupScreen, runBackup = True) @@ -260,1262 +290,1214 @@ class UpdatePluginMenu(Screen): self.exe = True self.session.open(RestoreScreen, runRestore = True) -class IPKGMenu(Screen): - skin = """ - - - - - - - """ - - def __init__(self, session, plugin_path): - Screen.__init__(self, session) - self.skin_path = plugin_path - - self["key_red"] = StaticText(_("Close")) - self["key_green"] = StaticText(_("Edit")) - - self.sel = [] - self.val = [] - self.entry = False - self.exe = False - - self.path = "" - - self["actions"] = NumberActionMap(["SetupActions"], - { - "ok": self.KeyOk, - "cancel": self.keyCancel - }, -1) - - self["shortcuts"] = ActionMap(["ShortcutActions"], - { - "red": self.keyCancel, - "green": self.KeyOk, - }) - self.flist = [] - self["filelist"] = MenuList(self.flist) - self.fill_list() - self.onLayoutFinish.append(self.layoutFinished) - - def layoutFinished(self): - self.setWindowTitle() - - def setWindowTitle(self): - self.setTitle(_("Select upgrade source to edit.")) - - def fill_list(self): - self.flist = [] - self.path = '/etc/ipkg/' - if (os_path.exists(self.path) == False): - self.entry = False - return - for file in listdir(self.path): - if (file.endswith(".conf")): - if file != 'arch.conf': - self.flist.append((file)) - self.entry = True - self["filelist"].l.setList(self.flist) - - def KeyOk(self): - if (self.exe == False) and (self.entry == True): - self.sel = self["filelist"].getCurrent() - self.val = self.path + self.sel - self.session.open(IPKGSource, self.val) - - def keyCancel(self): - self.close() - - def Exit(self): - self.close() - - -class IPKGSource(Screen): - skin = """ - - - - - - - """ - - def __init__(self, session, configfile = None): - Screen.__init__(self, session) - self.session = session - self.configfile = configfile - text = "" - if self.configfile: - try: - fp = file(configfile, 'r') - sources = fp.readlines() - if sources: - text = sources[0] - fp.close() - except IOError: - pass - - desk = getDesktop(0) - x= int(desk.size().width()) - y= int(desk.size().height()) - - self["key_red"] = StaticText(_("Cancel")) - self["key_green"] = StaticText(_("Save")) - - if (y>=720): - self["text"] = Input(text, maxSize=False, type=Input.TEXT) - else: - self["text"] = Input(text, maxSize=False, visible_width = 55, type=Input.TEXT) - - self["actions"] = NumberActionMap(["WizardActions", "InputActions", "TextEntryActions", "KeyboardInputActions","ShortcutActions"], - { - "ok": self.go, - "back": self.close, - "red": self.close, - "green": self.go, - "left": self.keyLeft, - "right": self.keyRight, - "home": self.keyHome, - "end": self.keyEnd, - "deleteForward": self.keyDeleteForward, - "deleteBackward": self.keyDeleteBackward, - "1": self.keyNumberGlobal, - "2": self.keyNumberGlobal, - "3": self.keyNumberGlobal, - "4": self.keyNumberGlobal, - "5": self.keyNumberGlobal, - "6": self.keyNumberGlobal, - "7": self.keyNumberGlobal, - "8": self.keyNumberGlobal, - "9": self.keyNumberGlobal, - "0": self.keyNumberGlobal - }, -1) - - self.onLayoutFinish.append(self.layoutFinished) - - def layoutFinished(self): - self.setWindowTitle() - self["text"].right() - - def setWindowTitle(self): - self.setTitle(_("Edit upgrade source url.")) - - def go(self): - text = self["text"].getText() - if text: - fp = file(self.configfile, 'w') - fp.write(text) - fp.write("\n") - fp.close() - self.close() - - def keyLeft(self): - self["text"].left() - - def keyRight(self): - self["text"].right() - - def keyHome(self): - self["text"].home() - - def keyEnd(self): - self["text"].end() - - def keyDeleteForward(self): - self["text"].delete() - - def keyDeleteBackward(self): - self["text"].deleteBackward() - - def keyNumberGlobal(self, number): - self["text"].number(number) +class PluginManager(Screen, DreamInfoHandler): -class PacketManager(Screen): skin = """ - + + + - + + + - {"template": [ - MultiContentEntryText(pos = (5, 1), size = (440, 28), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name - MultiContentEntryText(pos = (5, 26), size = (440, 20), font=1, flags = RT_HALIGN_LEFT, text = 2), # index 2 is the description - MultiContentEntryPixmapAlphaTest(pos = (445, 2), size = (48, 48), png = 4), # index 4 is the status pixmap - MultiContentEntryPixmapAlphaTest(pos = (5, 50), size = (510, 2), png = 5), # index 4 is the div pixmap - ], - "fonts": [gFont("Regular", 22),gFont("Regular", 14)], + {"templates": + {"default": (51,[ + MultiContentEntryText(pos = (30, 1), size = (470, 24), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name + MultiContentEntryText(pos = (30, 25), size = (470, 24), font=1, flags = RT_HALIGN_LEFT, text = 2), # index 2 is the description + MultiContentEntryPixmapAlphaTest(pos = (475, 0), size = (48, 48), png = 5), # index 5 is the status pixmap + MultiContentEntryPixmapAlphaTest(pos = (0, 49), size = (550, 2), png = 6), # index 6 is the div pixmap + ]), + "category": (40,[ + MultiContentEntryText(pos = (30, 0), size = (500, 22), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name + MultiContentEntryText(pos = (30, 22), size = (500, 16), font=2, flags = RT_HALIGN_LEFT, text = 1), # index 1 is the description + MultiContentEntryPixmapAlphaTest(pos = (0, 38), size = (550, 2), png = 3), # index 3 is the div pixmap + ]) + }, + "fonts": [gFont("Regular", 22),gFont("Regular", 20),gFont("Regular", 16)], "itemHeight": 52 - } + } + """ - + def __init__(self, session, plugin_path, args = None): Screen.__init__(self, session) self.session = session self.skin_path = plugin_path - self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"], + self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions", "InfobarEPGActions", "HelpActions" ], { - "ok": self.go, + "ok": self.handleCurrent, "back": self.exit, "red": self.exit, - "green": self.reload, + "green": self.handleCurrent, + "yellow": self.handleSelected, + "showEventInfo": self.handleSelected, + "displayHelp": self.handleHelp, }, -1) - + self.list = [] self.statuslist = [] + self.selectedFiles = [] + self.categoryList = [] + self.packetlist = [] self["list"] = List(self.list) self["key_red"] = StaticText(_("Close")) - self["key_green"] = StaticText(_("Reload")) + self["key_green"] = StaticText("") + self["key_yellow"] = StaticText("") + self["key_blue"] = StaticText("") + self["status"] = StaticText("") - self.list_updating = True - self.packetlist = [] - self.installed_packetlist = {} - self.Console = Console() self.cmdList = [] - self.cachelist = [] - self.cache_ttl = 86400 #600 is default, 0 disables, Seconds cache is considered valid (24h should be ok for caching ipkgs) - self.cache_file = '/usr/lib/enigma2/python/Plugins/SystemPlugins/SoftwareManager/packetmanager.cache' #Path to cache directory self.oktext = _("\nAfter pressing OK, please wait!") - self.unwanted_extensions = ('-dbg', '-dev', '-doc', 'busybox') + if not self.selectionChanged in self["list"].onSelectionChanged: + self["list"].onSelectionChanged.append(self.selectionChanged) - self.ipkg = IpkgComponent() - self.ipkg.addCallback(self.ipkgCallback) + self.currList = "" + self.currentSelectedTag = None + self.currentSelectedIndex = None + self.currentSelectedPackage = None + self.saved_currentSelectedPackage = None + self.onShown.append(self.setWindowTitle) - self.onLayoutFinish.append(self.rebuildList) + self.onLayoutFinish.append(self.getUpdateInfos) - def exit(self): - self.ipkg.stop() - if self.Console is not None: - if len(self.Console.appContainers): - for name in self.Console.appContainers.keys(): - self.Console.kill(name) - self.close() + def setWindowTitle(self): + self.setTitle(_("Extensions management")) - def reload(self): - if (os_path.exists(self.cache_file) == True): - remove(self.cache_file) - self.list_updating = True - self.rebuildList() - - def setWindowTitle(self): - self.setTitle(_("Packet manager")) + def exit(self): + if self.currList == "packages": + self.currList = "category" + self.currentSelectedTag = None + self["list"].style = "category" + self['list'].setList(self.categoryList) + self["list"].setIndex(self.currentSelectedIndex) + self["list"].updateList(self.categoryList) + self.selectionChanged() + else: + iSoftwareTools.cleanupSoftwareTools() + self.prepareInstall() + if len(self.cmdList): + self.session.openWithCallback(self.runExecute, PluginManagerInfo, self.skin_path, self.cmdList) + else: + self.close() - def setStatus(self,status = None): + def handleHelp(self): + if self.currList != "status": + self.session.open(PluginManagerHelp, self.skin_path) + + def setState(self,status = None): if status: + self.currList = "status" self.statuslist = [] + self["key_green"].setText("") + self["key_blue"].setText("") + self["key_yellow"].setText("") 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 packetlist. Please wait..." ),'',statuspng, divpng )) - self['list'].setList(self.statuslist) + self.statuslist.append(( _("Updating software catalog"), '', _("Searching for available updates. Please wait..." ),'', '', statuspng, divpng, None, '' )) + self["list"].style = "default" + self['list'].setList(self.statuslist) + elif status == 'sync': + statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgrade.png")) + self.statuslist.append(( _("Package list update"), '', _("Searching for new installed or removed packages. Please wait..." ),'', '', statuspng, divpng, None, '' )) + self["list"].style = "default" + self['list'].setList(self.statuslist) 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 packetlist. Please try again." ),'',statuspng, divpng )) - self['list'].setList(self.statuslist) - - def rebuildList(self): - self.setStatus('update') - self.inv_cache = 0 - self.vc = valid_cache(self.cache_file, self.cache_ttl) - if self.cache_ttl > 0 and self.vc != 0: - try: - self.buildPacketList() - except: - self.inv_cache = 1 - if self.cache_ttl == 0 or self.inv_cache == 1 or self.vc == 0: - self.run = 0 - self.ipkg.startCmd(IpkgComponent.CMD_UPDATE) - - def go(self, returnValue = None): - cur = self["list"].getCurrent() - if cur: - status = cur[3] - package = cur[0] - self.cmdList = [] - if status == 'installed': - self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": package })) - if len(self.cmdList): - self.session.openWithCallback(self.runRemove, MessageBox, _("Do you want to remove the package:\n") + package + "\n" + self.oktext) - elif status == 'upgradeable': - self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package })) - if len(self.cmdList): - self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to upgrade the package:\n") + package + "\n" + self.oktext) - elif status == "installable": - self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package })) - if len(self.cmdList): - self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to install the package:\n") + package + "\n" + self.oktext) + self.statuslist.append(( _("Error"), '', _("There was an error downloading the packetlist. Please try again." ),'', '', statuspng, divpng, None, '' )) + self["list"].style = "default" + self['list'].setList(self.statuslist) - def runRemove(self, result): - if result: - self.session.openWithCallback(self.runRemoveFinished, Ipkg, cmdList = self.cmdList) + def getUpdateInfos(self): + self.setState('update') + iSoftwareTools.getUpdates(self.getUpdateInfosCB) - def runRemoveFinished(self): - self.session.openWithCallback(self.RemoveReboot, MessageBox, _("Remove finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO) + def getUpdateInfosCB(self, retval = None): + if retval is not None: + if retval is True: + if iSoftwareTools.available_updates is not 0: + self["status"].setText(_("There are at least ") + str(iSoftwareTools.available_updates) + _(" updates available.")) + else: + self["status"].setText(_("There are no updates available.")) + elif retval is False: + self["status"].setText(_("No network connection available.")) + self.rebuildList() - def RemoveReboot(self, result): - if result is None: - return - if result is False: - cur = self["list"].getCurrent() - if cur: - item = self['list'].getIndex() - self.list[item] = self.buildEntryComponent(cur[0], cur[1], cur[2], 'installable') - self.cachelist[item] = [cur[0], cur[1], cur[2], 'installable'] - self['list'].setList(self.list) - write_cache(self.cache_file, self.cachelist) - self.reloadPluginlist() - if result: - quitMainloop(3) + def rebuildList(self, retval = None): + if self.currentSelectedTag is None: + self.buildCategoryList() + else: + self.buildPacketList(self.currentSelectedTag) - def runUpgrade(self, result): - if result: - self.session.openWithCallback(self.runUpgradeFinished, Ipkg, cmdList = self.cmdList) + def selectionChanged(self): + current = self["list"].getCurrent() + self["status"].setText("") + if current: + if self.currList == "packages": + self["key_red"].setText(_("Back")) + if current[4] == 'installed': + self["key_green"].setText(_("Uninstall")) + elif current[4] == 'installable': + self["key_green"].setText(_("Install")) + elif current[4] == 'remove': + self["key_green"].setText(_("Undo uninstall")) + elif current[4] == 'install': + self["key_green"].setText(_("Undo install")) + self["key_yellow"].setText(_("View details")) + self["key_blue"].setText("") + if len(self.selectedFiles) == 0 and iSoftwareTools.available_updates is not 0: + self["status"].setText(_("There are at least ") + str(iSoftwareTools.available_updates) + _(" updates available.")) + elif len(self.selectedFiles) is not 0: + self["status"].setText(str(len(self.selectedFiles)) + _(" packages selected.")) + else: + self["status"].setText(_("There are currently no outstanding actions.")) + elif self.currList == "category": + self["key_red"].setText(_("Close")) + self["key_green"].setText("") + self["key_yellow"].setText("") + self["key_blue"].setText("") + if len(self.selectedFiles) == 0 and iSoftwareTools.available_updates is not 0: + self["status"].setText(_("There are at least ") + str(iSoftwareTools.available_updates) + _(" updates available.")) + self["key_yellow"].setText(_("Update")) + elif len(self.selectedFiles) is not 0: + self["status"].setText(str(len(self.selectedFiles)) + _(" packages selected.")) + self["key_yellow"].setText(_("Process")) + else: + self["status"].setText(_("There are currently no outstanding actions.")) - def runUpgradeFinished(self): - self.session.openWithCallback(self.UpgradeReboot, MessageBox, _("Upgrade finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO) - - def UpgradeReboot(self, result): - if result is None: - return - if result is False: - cur = self["list"].getCurrent() - if cur: - item = self['list'].getIndex() - self.list[item] = self.buildEntryComponent(cur[0], cur[1], cur[2], 'installed') - self.cachelist[item] = [cur[0], cur[1], cur[2], 'installed'] - self['list'].setList(self.list) - write_cache(self.cache_file, self.cachelist) - self.reloadPluginlist() - if result: - quitMainloop(3) + def getSelectionState(self, detailsFile): + for entry in self.selectedFiles: + if entry[0] == detailsFile: + return True + return False - def ipkgCallback(self, event, param): - if event == IpkgComponent.EVENT_ERROR: - self.list_updating = False - self.setStatus('error') - elif event == IpkgComponent.EVENT_DONE: - if self.list_updating: - self.list_updating = False - if not self.Console: - self.Console = Console() - cmd = "ipkg list" - self.Console.ePopen(cmd, self.IpkgList_Finished) - #print event, "-", param - pass + def handleCurrent(self): + current = self["list"].getCurrent() + if current: + if self.currList == "category": + self.currentSelectedIndex = self["list"].index + selectedTag = current[2] + self.buildPacketList(selectedTag) + elif self.currList == "packages": + if current[7] is not '': + idx = self["list"].getIndex() + detailsFile = self.list[idx][1] + if self.list[idx][7] == True: + for entry in self.selectedFiles: + if entry[0] == detailsFile: + self.selectedFiles.remove(entry) + else: + alreadyinList = False + for entry in self.selectedFiles: + if entry[0] == detailsFile: + alreadyinList = True + if not alreadyinList: + self.selectedFiles.append((detailsFile,current[4],current[3])) + self.currentSelectedPackage = ((detailsFile,current[4],current[3])) + if current[4] == 'installed': + self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'remove', True) + elif current[4] == 'installable': + self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'install', True) + elif current[4] == 'remove': + self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'installed', False) + elif current[4] == 'install': + self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'installable',False) + self["list"].setList(self.list) + self["list"].setIndex(idx) + self["list"].updateList(self.list) + self.selectionChanged() - def IpkgList_Finished(self, result, retval, extra_args = None): - if len(result): - self.packetlist = [] - for x in result.splitlines(): - split = x.split(' - ') #self.blacklisted_packages - if not any(split[0].strip().endswith(x) for x in self.unwanted_extensions): - self.packetlist.append([split[0].strip(), split[1].strip(),split[2].strip()]) - if not self.Console: - self.Console = Console() - cmd = "ipkg list_installed" - self.Console.ePopen(cmd, self.IpkgListInstalled_Finished) + def handleSelected(self): + current = self["list"].getCurrent() + if current: + if self.currList == "packages": + if current[7] is not '': + detailsfile = iSoftwareTools.directory[0] + "/" + current[1] + if (os_path.exists(detailsfile) == True): + self.saved_currentSelectedPackage = self.currentSelectedPackage + self.session.openWithCallback(self.detailsClosed, PluginDetails, self.skin_path, current) + else: + self.session.open(MessageBox, _("Sorry, no Details available!"), MessageBox.TYPE_INFO, timeout = 10) + elif self.currList == "category": + self.prepareInstall() + if len(self.cmdList): + self.session.openWithCallback(self.runExecute, PluginManagerInfo, self.skin_path, self.cmdList) - def IpkgListInstalled_Finished(self, result, retval, extra_args = None): - if len(result): - self.installed_packetlist = {} - for x in result.splitlines(): - split = x.split(' - ') - if not any(split[0].strip().endswith(x) for x in self.unwanted_extensions): - self.installed_packetlist[split[0].strip()] = split[1].strip() - self.buildPacketList() + def detailsClosed(self, result = None): + if result is not None: + if result is not False: + self.setState('sync') + iSoftwareTools.lastDownloadDate = time() + for entry in self.selectedFiles: + if entry == self.saved_currentSelectedPackage: + self.selectedFiles.remove(entry) + iSoftwareTools.startIpkgListInstalled(self.rebuildList) - def buildEntryComponent(self, name, version, description, state): + def buildEntryComponent(self, name, details, description, packagename, state, selected = False): divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png")) + installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installed.png")) + installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installable.png")) + removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png")) + installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/install.png")) 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)) + return((name, details, description, packagename, state, installedpng, divpng, selected)) + elif state == 'installable': + return((name, details, description, packagename, state, installablepng, divpng, selected)) + elif state == 'remove': + return((name, details, description, packagename, state, removepng, divpng, selected)) + elif state == 'install': + return((name, details, description, packagename, state, installpng, divpng, selected)) - def buildPacketList(self): - self.list = [] - self.cachelist = [] - - if self.cache_ttl > 0 and self.vc != 0: - print 'Loading packagelist cache from ',self.cache_file - try: - self.cachelist = load_cache(self.cache_file) - if len(self.cachelist) > 0: - for x in self.cachelist: - self.list.append(self.buildEntryComponent(x[0], x[1], x[2], x[3])) - self['list'].setList(self.list) - except: - self.inv_cache = 1 - - if self.cache_ttl == 0 or self.inv_cache == 1 or self.vc == 0: - print 'rebuilding fresh package list' + def buildPacketList(self, categorytag = None): + if categorytag is not None: + self.currList = "packages" + self.currentSelectedTag = categorytag + self.packetlist = [] + for package in iSoftwareTools.packagesIndexlist[:]: + prerequisites = package[0]["prerequisites"] + if prerequisites.has_key("tag"): + for foundtag in prerequisites["tag"]: + if categorytag == foundtag: + attributes = package[0]["attributes"] + print "ATTRIBUTES",attributes + if attributes.has_key("packagetype"): + print "PACKAGETYPE",attributes["packagetype"] + if attributes["packagetype"] == "internal": + continue + self.packetlist.append([attributes["name"], attributes["details"], attributes["shortdescription"], attributes["packagename"]]) + else: + self.packetlist.append([attributes["name"], attributes["details"], attributes["shortdescription"], attributes["packagename"]]) + self.list = [] for x in self.packetlist: status = "" - if self.installed_packetlist.has_key(x[0].strip()): - if self.installed_packetlist[x[0].strip()] == x[1].strip(): - status = "installed" - self.list.append(self.buildEntryComponent(x[0].strip(), x[1].strip(), x[2].strip(), status)) + name = x[0].strip() + details = x[1].strip() + description = x[2].strip() + packagename = x[3].strip() + selectState = self.getSelectionState(details) + if iSoftwareTools.installed_packetlist.has_key(packagename): + if selectState == True: + status = "remove" else: - status = "upgradeable" - self.list.append(self.buildEntryComponent(x[0].strip(), x[1].strip(), x[2].strip(), status)) + status = "installed" + self.list.append(self.buildEntryComponent(name, details, description, packagename, status, selected = selectState)) else: - status = "installable" - self.list.append(self.buildEntryComponent(x[0].strip(), x[1].strip(), x[2].strip(), status)) - if not any(x[0].strip().endswith(x) for x in self.unwanted_extensions): - self.cachelist.append([x[0].strip(), x[1].strip(), x[2].strip(), status]) - write_cache(self.cache_file, self.cachelist) + if selectState == True: + status = "install" + else: + status = "installable" + self.list.append(self.buildEntryComponent(name, details, description, packagename, status, selected = selectState)) + if len(self.list): + self.list.sort(key=lambda x: x[0]) + self["list"].style = "default" self['list'].setList(self.list) + self["list"].updateList(self.list) + self.selectionChanged() - def reloadPluginlist(self): - plugins.readPluginList(resolveFilename(SCOPE_PLUGINS)) + def buildCategoryList(self): + self.currList = "category" + self.categories = [] + self.categoryList = [] + for package in iSoftwareTools.packagesIndexlist[:]: + prerequisites = package[0]["prerequisites"] + if prerequisites.has_key("tag"): + for foundtag in prerequisites["tag"]: + attributes = package[0]["attributes"] + if foundtag not in self.categories: + self.categories.append(foundtag) + self.categoryList.append(self.buildCategoryComponent(foundtag)) + self.categoryList.sort(key=lambda x: x[0]) + self["list"].style = "category" + self['list'].setList(self.categoryList) + self["list"].updateList(self.categoryList) + self.selectionChanged() + def buildCategoryComponent(self, tag = None): + divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png")) + if tag is not None: + if tag == 'System': + return(( _("System"), _("View list of available system extensions" ), tag, divpng )) + elif tag == 'Skin': + return(( _("Skins"), _("View list of available skins" ), tag, divpng )) + elif tag == 'Recording': + return(( _("Recordings"), _("View list of available recording extensions" ), tag, divpng )) + elif tag == 'Network': + return(( _("Network"), _("View list of available networking extensions" ), tag, divpng )) + elif tag == 'CI': + return(( _("CommonInterface"), _("View list of available CommonInterface extensions" ), tag, divpng )) + elif tag == 'Default': + return(( _("Default Settings"), _("View list of available default settings" ), tag, divpng )) + elif tag == 'SAT': + return(( _("Satteliteequipment"), _("View list of available Satteliteequipment extensions." ), tag, divpng )) + elif tag == 'Software': + return(( _("Software"), _("View list of available software extensions" ), tag, divpng )) + elif tag == 'Multimedia': + return(( _("Multimedia"), _("View list of available multimedia extensions." ), tag, divpng )) + elif tag == 'Display': + return(( _("Display and Userinterface"), _("View list of available Display and Userinterface extensions." ), tag, divpng )) + elif tag == 'EPG': + return(( _("Electronic Program Guide"), _("View list of available EPG extensions." ), tag, divpng )) + elif tag == 'Communication': + return(( _("Communication"), _("View list of available communication extensions." ), tag, divpng )) + else: # dynamically generate non existent tags + return(( str(tag), _("View list of available ") + str(tag) + _(" extensions." ), tag, divpng )) -class PluginManager(Screen, DreamInfoHandler): + def prepareInstall(self): + self.cmdList = [] + if iSoftwareTools.available_updates > 0: + self.cmdList.append((IpkgComponent.CMD_UPGRADE, { "test_only": False })) + if self.selectedFiles and len(self.selectedFiles): + for plugin in self.selectedFiles: + detailsfile = iSoftwareTools.directory[0] + "/" + plugin[0] + if (os_path.exists(detailsfile) == True): + iSoftwareTools.fillPackageDetails(plugin[0]) + self.package = iSoftwareTools.packageDetails[0] + if self.package[0].has_key("attributes"): + self.attributes = self.package[0]["attributes"] + if self.attributes.has_key("package"): + self.packagefiles = self.attributes["package"] + if plugin[1] == 'installed': + if self.packagefiles: + for package in self.packagefiles[:]: + self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": package["name"] })) + else: + self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": plugin[2] })) + else: + if self.packagefiles: + for package in self.packagefiles[:]: + self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package["name"] })) + else: + self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": plugin[2] })) + else: + if plugin[1] == 'installed': + self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": plugin[2] })) + else: + self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": plugin[2] })) + + def runExecute(self, result = None): + if result is not None: + if result[0] is True: + self.session.openWithCallback(self.runExecuteFinished, Ipkg, cmdList = self.cmdList) + elif result[0] is False: + self.cmdList = result[1] + self.session.openWithCallback(self.runExecuteFinished, Ipkg, cmdList = self.cmdList) + else: + self.close() + + def runExecuteFinished(self): + self.session.openWithCallback(self.ExecuteReboot, MessageBox, _("Install or remove finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO) + + def ExecuteReboot(self, result): + if result is None: + return + if result is False: + self.reloadPluginlist() + self.selectedFiles = None + self.detailsClosed(True) + if result: + quitMainloop(3) + + def reloadPluginlist(self): + plugins.readPluginList(resolveFilename(SCOPE_PLUGINS)) - lastDownloadDate = None +class PluginManagerInfo(Screen): skin = """ - + - - - - - + - {"templates": - {"default": (51,[ - MultiContentEntryText(pos = (30, 1), size = (470, 24), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name - MultiContentEntryText(pos = (30, 25), size = (470, 20), font=1, flags = RT_HALIGN_LEFT, text = 2), # index 2 is the description - MultiContentEntryPixmapAlphaTest(pos = (475, 0), size = (48, 48), png = 5), # index 5 is the status pixmap - MultiContentEntryPixmapAlphaTest(pos = (0, 49), size = (550, 2), png = 6), # index 6 is the div pixmap - ]), - "category": (40,[ - MultiContentEntryText(pos = (30, 0), size = (500, 22), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name - MultiContentEntryText(pos = (30, 22), size = (500, 16), font=1, flags = RT_HALIGN_LEFT, text = 1), # index 1 is the description - MultiContentEntryPixmapAlphaTest(pos = (0, 38), size = (550, 2), png = 3), # index 3 is the div pixmap - ]) - }, - "fonts": [gFont("Regular", 22),gFont("Regular", 16)], - "itemHeight": 52 - } + {"template": [ + MultiContentEntryText(pos = (50, 0), size = (150, 26), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name + MultiContentEntryText(pos = (50, 27), size = (540, 23), font=1, flags = RT_HALIGN_LEFT, text = 1), # index 1 is the state + MultiContentEntryPixmapAlphaTest(pos = (0, 1), size = (48, 48), png = 2), # index 2 is the status pixmap + MultiContentEntryPixmapAlphaTest(pos = (0, 48), size = (550, 2), png = 3), # index 3 is the div pixmap + ], + "fonts": [gFont("Regular", 24),gFont("Regular", 22)], + "itemHeight": 50 + } - + + """ - def __init__(self, session, plugin_path, args = None): + def __init__(self, session, plugin_path, cmdlist = None): Screen.__init__(self, session) self.session = session self.skin_path = plugin_path - 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" - - DreamInfoHandler.__init__(self, self.statusCallback, blocking = False, neededTag = 'ALL_TAGS', neededFlag = self.ImageVersion, language = self.language) - self.directory = resolveFilename(SCOPE_METADIR) + self.cmdlist = cmdlist - self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions", "InfobarEPGActions", "HelpActions" ], + self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"], { - "ok": self.handleCurrent, + "ok": self.process_all, "back": self.exit, "red": self.exit, - "green": self.handleCurrent, - "yellow": self.handleSelected, - "showEventInfo": self.handleSelected, - "displayHelp": self.handleHelp, + "green": self.process_extensions, }, -1) self.list = [] - self.statuslist = [] - self.selectedFiles = [] - self.categoryList = [] self["list"] = List(self.list) - self["key_red"] = StaticText(_("Close")) - self["key_green"] = StaticText("") - self["key_yellow"] = StaticText("") - self["key_blue"] = StaticText("") - self["status"] = StaticText("") - - self.list_updating = True - self.packetlist = [] - self.installed_packetlist = {} - self.available_packetlist = [] - self.available_updates = 0 - self.Console = Console() - self.cmdList = [] - self.oktext = _("\nAfter pressing OK, please wait!") - self.unwanted_extensions = ('-dbg', '-dev', '-doc') - - self.ipkg = IpkgComponent() - self.ipkg.addCallback(self.ipkgCallback) - if not self.selectionChanged in self["list"].onSelectionChanged: - self["list"].onSelectionChanged.append(self.selectionChanged) - - self.currList = "" - self.currentSelectedTag = None - self.currentSelectedIndex = None + self["key_red"] = StaticText(_("Cancel")) + self["key_green"] = StaticText(_("Only extensions.")) + self["status"] = StaticText(_("Following tasks will be done after you press OK!")) self.onShown.append(self.setWindowTitle) self.onLayoutFinish.append(self.rebuildList) def setWindowTitle(self): - self.setTitle(_("Plugin manager")) + self.setTitle(_("Plugin manager activity information")) - def exit(self): - if self.currList == "packages": - self.currList = "category" - self.currentSelectedTag = None - self["list"].style = "category" - self['list'].setList(self.categoryList) - self["list"].setIndex(self.currentSelectedIndex) - self["list"].updateList(self.categoryList) - self.selectionChanged() - else: - self.ipkg.stop() - if self.Console is not None: - if len(self.Console.appContainers): - for name in self.Console.appContainers.keys(): - self.Console.kill(name) - self.prepareInstall() - if len(self.cmdList): - self.session.openWithCallback(self.runExecute, PluginManagerInfo, self.skin_path, self.cmdList) - else: - self.close() + def rebuildList(self): + self.list = [] + if self.cmdlist is not None: + for entry in self.cmdlist: + action = "" + info = "" + cmd = entry[0] + if cmd == 0: + action = 'install' + elif cmd == 2: + action = 'remove' + else: + action = 'upgrade' + args = entry[1] + if cmd == 0: + info = args['package'] + elif cmd == 2: + info = args['package'] + else: + info = _("Dreambox software because updates are available.") - def handleHelp(self): - if self.currList != "status": - self.session.open(PluginManagerHelp, self.skin_path) + self.list.append(self.buildEntryComponent(action,info)) + self['list'].setList(self.list) + self['list'].updateList(self.list) - def setState(self,status = None): - if status: - self.currList = "status" - self.statuslist = [] - self["key_green"].setText("") - self["key_blue"].setText("") - self["key_yellow"].setText("") - 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 packetlist. Please wait..." ),'', '', statuspng, divpng, None, '' )) - self["list"].style = "default" - self['list'].setList(self.statuslist) - elif status == 'sync': - statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgrade.png")) - self.statuslist.append(( _("Package list update"), '', _("Searching for new installed or removed packages. Please wait..." ),'', '', statuspng, divpng, None, '' )) - self["list"].style = "default" - self['list'].setList(self.statuslist) - 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 packetlist. Please try again." ),'', '', statuspng, divpng, None, '' )) - self["list"].style = "default" - self['list'].setList(self.statuslist) - - def statusCallback(self, status, progress): - pass - - def selectionChanged(self): - current = self["list"].getCurrent() - self["status"].setText("") - if current: - if self.currList == "packages": - self["key_red"].setText(_("Back")) - if current[4] == 'installed': - self["key_green"].setText(_("Remove")) - elif current[4] == 'installable': - self["key_green"].setText(_("Install")) - elif current[4] == 'remove': - self["key_green"].setText(_("Undo\nRemove")) - elif current[4] == 'install': - self["key_green"].setText(_("Undo\nInstall")) - self["key_yellow"].setText(_("View details")) - self["key_blue"].setText("") - if len(self.selectedFiles) == 0 and self.available_updates is not 0: - self["status"].setText(_("There are at least ") + str(self.available_updates) + _(" updates available.")) - elif len(self.selectedFiles) is not 0: - self["status"].setText(str(len(self.selectedFiles)) + _(" packages selected.")) - else: - self["status"].setText(_("There is nothing to be done.")) - elif self.currList == "category": - self["key_red"].setText(_("Close")) - self["key_green"].setText("") - self["key_yellow"].setText("") - self["key_blue"].setText("") - if len(self.selectedFiles) == 0 and self.available_updates is not 0: - self["status"].setText(_("There are at least ") + str(self.available_updates) + _(" updates available.")) - self["key_yellow"].setText(_("Update")) - elif len(self.selectedFiles) is not 0: - self["status"].setText(str(len(self.selectedFiles)) + _(" packages selected.")) - self["key_yellow"].setText(_("Process")) - else: - self["status"].setText(_("There is nothing to be done.")) - - def getSelectionState(self, detailsFile): - for entry in self.selectedFiles: - if entry[0] == detailsFile: - return True - return False - - def rebuildList(self): - self.setState('update') - if not PluginManager.lastDownloadDate or (time() - PluginManager.lastDownloadDate) > 3600: - # Only update from internet once per hour - PluginManager.lastDownloadDate = time() - print "last update time > 1h" - self.ipkg.startCmd(IpkgComponent.CMD_UPDATE) + def buildEntryComponent(self, action,info): + divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png")) + upgradepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgrade.png")) + installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/install.png")) + removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png")) + if action == 'install': + return(( _('Installing'), info, installpng, divpng)) + elif action == 'remove': + return(( _('Removing'), info, removepng, divpng)) else: - print "last update time < 1h" - self.startIpkgList() + return(( _('Upgrading'), info, upgradepng, divpng)) - def ipkgCallback(self, event, param): - if event == IpkgComponent.EVENT_ERROR: - self.list_updating = False - self.setState('error') - elif event == IpkgComponent.EVENT_DONE: - self.startIpkgList() - pass + def exit(self): + self.close() - def startIpkgList(self): - if self.list_updating: - if not self.Console: - self.Console = Console() - cmd = "ipkg list" - self.Console.ePopen(cmd, self.IpkgList_Finished) + def process_all(self): + self.close((True,None)) - def IpkgList_Finished(self, result, retval, extra_args = None): - if len(result): - self.available_packetlist = [] - for x in result.splitlines(): - split = x.split(' - ') - if not any(split[0].strip().endswith(x) for x in self.unwanted_extensions): - self.available_packetlist.append([split[0].strip(), split[1].strip(), split[2].strip()]) - self.startInstallMetaPackage() + def process_extensions(self): + self.list = [] + if self.cmdlist is not None: + for entry in self.cmdlist: + cmd = entry[0] + if entry[0] in (0,2): + self.list.append((entry)) + self.close((False,self.list)) - def startInstallMetaPackage(self): - if self.list_updating: - self.list_updating = False - if not self.Console: - self.Console = Console() - cmd = "ipkg install enigma2-meta" #dummy,will change probably" - self.Console.ePopen(cmd, self.InstallMetaPackage_Finished) - def InstallMetaPackage_Finished(self, result, retval, extra_args = None): - if len(result): - self.fillPackagesIndexList() - if not self.Console: - self.Console = Console() - self.setState('sync') - cmd = "ipkg list_installed" - self.Console.ePopen(cmd, self.IpkgListInstalled_Finished) +class PluginManagerHelp(Screen): + skin = """ + + + + + + {"template": [ + MultiContentEntryText(pos = (50, 0), size = (150, 26), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name + MultiContentEntryText(pos = (50, 27), size = (540, 23), font=1, flags = RT_HALIGN_LEFT, text = 1), # index 1 is the state + MultiContentEntryPixmapAlphaTest(pos = (0, 1), size = (48, 48), png = 2), # index 2 is the status pixmap + MultiContentEntryPixmapAlphaTest(pos = (0, 48), size = (550, 2), png = 3), # index 3 is the div pixmap + ], + "fonts": [gFont("Regular", 24),gFont("Regular", 22)], + "itemHeight": 50 + } + + + + + """ - def IpkgListInstalled_Finished(self, result, retval, extra_args = None): - if len(result): - self.installed_packetlist = {} - for x in result.splitlines(): - split = x.split(' - ') - if not any(split[0].strip().endswith(x) for x in self.unwanted_extensions): - self.installed_packetlist[split[0].strip()] = split[1].strip() - self.countUpdates() - if self.currentSelectedTag is None: - self.buildCategoryList() - else: - self.buildPacketList(self.currentSelectedTag) + def __init__(self, session, plugin_path): + Screen.__init__(self, session) + self.session = session + self.skin_path = plugin_path - def countUpdates(self): - self.available_updates = 0 - for package in self.packagesIndexlist[:]: - attributes = package[0]["attributes"] - packagename = attributes["packagename"] - for x in self.available_packetlist: - if x[0].strip() == packagename: - if self.installed_packetlist.has_key(packagename): - if self.installed_packetlist[packagename] != x[1].strip(): - self.available_updates +=1 + self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"], + { + "back": self.exit, + "red": self.exit, + }, -1) - def handleCurrent(self): - current = self["list"].getCurrent() - if current: - if self.currList == "category": - self.currentSelectedIndex = self["list"].index - selectedTag = current[2] - self.buildPacketList(selectedTag) - elif self.currList == "packages": - if current[7] is not '': - idx = self["list"].getIndex() - detailsFile = self.list[idx][1] - if self.list[idx][7] == True: - for entry in self.selectedFiles: - if entry[0] == detailsFile: - self.selectedFiles.remove(entry) - else: - alreadyinList = False - for entry in self.selectedFiles: - if entry[0] == detailsFile: - alreadyinList = True - if not alreadyinList: - self.selectedFiles.append((detailsFile,current[4],current[3])) - if current[4] == 'installed': - self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'remove', True) - elif current[4] == 'installable': - self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'install', True) - elif current[4] == 'remove': - self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'installed', False) - elif current[4] == 'install': - self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'installable',False) - self["list"].setList(self.list) - self["list"].setIndex(idx) - self["list"].updateList(self.list) - self.selectionChanged() + self.list = [] + self["list"] = List(self.list) + self["key_red"] = StaticText(_("Close")) + self["status"] = StaticText(_("A small overview of the available icon states and actions.")) - def handleSelected(self): - current = self["list"].getCurrent() - if current: - if self.currList == "packages": - if current[7] is not '': - detailsfile = self.directory[0] + "/" + current[1] - if (os_path.exists(detailsfile) == True): - self.session.openWithCallback(self.detailsClosed, PluginDetails, self.skin_path, current) - else: - self.session.open(MessageBox, _("Sorry, no Details available!"), MessageBox.TYPE_INFO, timeout = 10) - elif self.currList == "category": - self.prepareInstall() - if len(self.cmdList): - self.session.openWithCallback(self.runExecute, PluginManagerInfo, self.skin_path, self.cmdList) + self.onShown.append(self.setWindowTitle) + self.onLayoutFinish.append(self.rebuildList) - def detailsClosed(self, result): - if result: - if not self.Console: - self.Console = Console() - self.setState('sync') - PluginManager.lastDownloadDate = time() - self.selectedFiles = [] - cmd = "ipkg update" - self.Console.ePopen(cmd, self.InstallMetaPackage_Finished) + def setWindowTitle(self): + self.setTitle(_("Plugin manager help")) - def buildEntryComponent(self, name, details, description, packagename, state, selected = False): + def rebuildList(self): + self.list = [] + self.list.append(self.buildEntryComponent('install')) + self.list.append(self.buildEntryComponent('installable')) + self.list.append(self.buildEntryComponent('installed')) + self.list.append(self.buildEntryComponent('remove')) + self['list'].setList(self.list) + self['list'].updateList(self.list) + + def buildEntryComponent(self, state): divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png")) + installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installed.png")) + installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installable.png")) + removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png")) + installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/install.png")) + if state == 'installed': - installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installed.png")) - return((name, details, description, packagename, state, installedpng, divpng, selected)) + return(( _('This plugin is installed.'), _('You can remove this plugin.'), installedpng, divpng)) elif state == 'installable': - installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installable.png")) - return((name, details, description, packagename, state, installablepng, divpng, selected)) - elif state == 'remove': - removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png")) - return((name, details, description, packagename, state, removepng, divpng, selected)) + return(( _('This plugin is not installed.'), _('You can install this plugin.'), installablepng, divpng)) elif state == 'install': - installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/install.png")) - return((name, details, description, packagename, state, installpng, divpng, selected)) + return(( _('This plugin will be installed.'), _('You can cancel the installation.'), installpng, divpng)) + elif state == 'remove': + return(( _('This plugin will be removed.'), _('You can cancel the removal.'), removepng, divpng)) - def buildPacketList(self, categorytag = None): - if categorytag is not None: - self.currList = "packages" - self.currentSelectedTag = categorytag - self.packetlist = [] - for package in self.packagesIndexlist[:]: - prerequisites = package[0]["prerequisites"] - if prerequisites.has_key("tag"): - for foundtag in prerequisites["tag"]: - if categorytag == foundtag: - attributes = package[0]["attributes"] - if attributes.has_key("packagetype"): - if attributes["packagetype"] == "internal": - continue - self.packetlist.append([attributes["name"], attributes["details"], attributes["shortdescription"], attributes["packagename"]]) - else: - self.packetlist.append([attributes["name"], attributes["details"], attributes["shortdescription"], attributes["packagename"]]) - self.list = [] - for x in self.packetlist: - status = "" - selectState = self.getSelectionState(x[1].strip()) - if self.installed_packetlist.has_key(x[3].strip()): - if selectState == True: - status = "remove" - else: - status = "installed" - self.list.append(self.buildEntryComponent(x[0].strip(), x[1].strip(), x[2].strip(), x[3].strip(), status, selected = selectState)) - else: - if selectState == True: - status = "install" - else: - status = "installable" - self.list.append(self.buildEntryComponent(x[0].strip(), x[1].strip(), x[2].strip(), x[3].strip(), status, selected = selectState)) - if len(self.list): - self.list.sort(key=lambda x: x[0]) - self["list"].style = "default" - self['list'].setList(self.list) - self["list"].updateList(self.list) - self.selectionChanged() + def exit(self): + self.close() - def buildCategoryList(self): - self.currList = "category" - self.categories = [] - self.categoryList = [] - for package in self.packagesIndexlist[:]: - prerequisites = package[0]["prerequisites"] - if prerequisites.has_key("tag"): - for foundtag in prerequisites["tag"]: - attributes = package[0]["attributes"] - if foundtag not in self.categories: - self.categories.append(foundtag) - self.categoryList.append(self.buildCategoryComponent(foundtag)) - self.categoryList.sort(key=lambda x: x[0]) - self["list"].style = "category" - self['list'].setList(self.categoryList) - self["list"].updateList(self.categoryList) - self.selectionChanged() - def buildCategoryComponent(self, tag = None): - divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png")) - if tag is not None: - if tag == 'System': - return(( _("System"), _("View list of available system extensions" ), tag, divpng )) - elif tag == 'Skin': - return(( _("Skins"), _("View list of available skins" ), tag, divpng )) - elif tag == 'Recording': - return(( _("Recordings"), _("View list of available recording extensions" ), tag, divpng )) - elif tag == 'Network': - return(( _("Network"), _("View list of available networking extensions" ), tag, divpng )) - elif tag == 'CI': - return(( _("CommonInterface"), _("View list of available CommonInterface extensions" ), tag, divpng )) - elif tag == 'Default': - return(( _("Default Settings"), _("View list of available default settings" ), tag, divpng )) - elif tag == 'SAT': - return(( _("Satteliteequipment"), _("View list of available Satteliteequipment extensions." ), tag, divpng )) - elif tag == 'Software': - return(( _("Software"), _("View list of available software extensions" ), tag, divpng )) - elif tag == 'Multimedia': - return(( _("Multimedia"), _("View list of available multimedia extensions." ), tag, divpng )) - elif tag == 'Display': - return(( _("Display and Userinterface"), _("View list of available Display and Userinterface extensions." ), tag, divpng )) - elif tag == 'EPG': - return(( _("Electronic Program Guide"), _("View list of available EPG extensions." ), tag, divpng )) - elif tag == 'Communication': - return(( _("Communication"), _("View list of available communication extensions." ), tag, divpng )) - else: # dynamically generate non existent tags - return(( str(tag), _("View list of available ") + str(tag) + _(" extensions." ), tag, divpng )) +class PluginDetails(Screen, DreamInfoHandler): + skin = """ + + + + + + + + + + + """ + def __init__(self, session, plugin_path, packagedata = None): + Screen.__init__(self, session) + self.skin_path = plugin_path + self.language = language.getLanguage()[:2] # getLanguage returns e.g. "fi_FI" for "language_country" + self.attributes = None + self.translatedAttributes = None + DreamInfoHandler.__init__(self, self.statusCallback, blocking = False, language = self.language) + self.directory = resolveFilename(SCOPE_METADIR) + if packagedata: + self.pluginname = packagedata[0] + self.details = packagedata[1] + self.pluginstate = packagedata[4] + self.statuspicinstance = packagedata[5] + self.divpicinstance = packagedata[6] + self.fillPackageDetails(self.details) + + self.thumbnail = "" + + self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"], + { + "back": self.exit, + "red": self.exit, + "green": self.go, + "up": self.pageUp, + "down": self.pageDown, + "left": self.pageUp, + "right": self.pageDown, + }, -1) + + self["key_red"] = StaticText(_("Close")) + self["key_green"] = StaticText("") + self["author"] = StaticText() + self["statuspic"] = Pixmap() + self["divpic"] = Pixmap() + self["screenshot"] = Pixmap() + self["detailtext"] = ScrollLabel() + + self["statuspic"].hide() + self["screenshot"].hide() + self["divpic"].hide() + + self.package = self.packageDetails[0] + if self.package[0].has_key("attributes"): + self.attributes = self.package[0]["attributes"] + if self.package[0].has_key("translation"): + self.translatedAttributes = self.package[0]["translation"] - def prepareInstall(self): self.cmdList = [] - if self.available_updates > 0: - self.cmdList.append((IpkgComponent.CMD_UPGRADE, { "test_only": False })) - if self.selectedFiles and len(self.selectedFiles): - for plugin in self.selectedFiles: - detailsfile = self.directory[0] + "/" + plugin[0] - if (os_path.exists(detailsfile) == True): - self.fillPackageDetails(plugin[0]) - self.package = self.packageDetails[0] - if self.package[0].has_key("attributes"): - self.attributes = self.package[0]["attributes"] - if self.attributes.has_key("package"): - self.packagefiles = self.attributes["package"] - if plugin[1] == 'installed': - if self.packagefiles: - for package in self.packagefiles[:]: - self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": package["name"] })) - else: - self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": plugin[2] })) - else: - if self.packagefiles: - for package in self.packagefiles[:]: - self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package["name"] })) - else: - self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": plugin[2] })) - else: - if plugin[1] == 'installed': - self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": plugin[2] })) - else: - self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": plugin[2] })) + self.oktext = _("\nAfter pressing OK, please wait!") + self.picload = ePicLoad() + self.picload.PictureData.get().append(self.paintScreenshotPixmapCB) + self.onShown.append(self.setWindowTitle) + self.onLayoutFinish.append(self.setInfos) + + def setWindowTitle(self): + self.setTitle(_("Details for extension: " + self.pluginname)) + + def exit(self): + self.close(False) + + def pageUp(self): + self["detailtext"].pageUp() + + def pageDown(self): + self["detailtext"].pageDown() + + def statusCallback(self, status, progress): + pass + + def setInfos(self): + if self.translatedAttributes.has_key("name"): + self.pluginname = self.translatedAttributes["name"] + elif self.attributes.has_key("name"): + self.pluginname = self.attributes["name"] + else: + self.pluginname = _("unknown") + + if self.translatedAttributes.has_key("author"): + self.author = self.translatedAttributes["author"] + elif self.attributes.has_key("author"): + self.author = self.attributes["author"] + else: + self.author = _("unknown") + + if self.translatedAttributes.has_key("description"): + self.description = self.translatedAttributes["description"] + elif self.attributes.has_key("description"): + self.description = self.attributes["description"] + else: + self.description = _("No description available.") + + if self.translatedAttributes.has_key("screenshot"): + self.loadThumbnail(self.translatedAttributes) + else: + self.loadThumbnail(self.attributes) + + self["author"].setText(_("Author: ") + self.author) + self["detailtext"].setText(self.description.strip()) + if self.pluginstate in ('installable', 'install'): + self["key_green"].setText(_("Install")) + else: + self["key_green"].setText(_("Remove")) + + def loadThumbnail(self, entry): + thumbnailUrl = None + if entry.has_key("screenshot"): + thumbnailUrl = entry["screenshot"] + if thumbnailUrl is not None: + self.thumbnail = "/tmp/" + thumbnailUrl.split('/')[-1] + print "[PluginDetails] downloading screenshot " + thumbnailUrl + " to " + self.thumbnail + client.downloadPage(thumbnailUrl,self.thumbnail).addCallback(self.setThumbnail).addErrback(self.fetchFailed) + else: + self.setThumbnail(noScreenshot = True) + + def setThumbnail(self, noScreenshot = False): + if not noScreenshot: + filename = self.thumbnail + else: + filename = resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/noprev.png") + + sc = AVSwitch().getFramebufferScale() + self.picload.setPara((self["screenshot"].instance.size().width(), self["screenshot"].instance.size().height(), sc[0], sc[1], False, 1, "#00000000")) + self.picload.startDecode(filename) + + if self.statuspicinstance != None: + self["statuspic"].instance.setPixmap(self.statuspicinstance.__deref__()) + self["statuspic"].show() + if self.divpicinstance != None: + self["divpic"].instance.setPixmap(self.divpicinstance.__deref__()) + self["divpic"].show() + + def paintScreenshotPixmapCB(self, picInfo=None): + ptr = self.picload.getData() + if ptr != None: + self["screenshot"].instance.setPixmap(ptr.__deref__()) + self["screenshot"].show() + else: + self.setThumbnail(noScreenshot = True) + + def go(self): + if self.attributes.has_key("package"): + self.packagefiles = self.attributes["package"] + self.cmdList = [] + if self.pluginstate in ('installed', 'remove'): + if self.packagefiles: + for package in self.packagefiles[:]: + self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": package["name"] })) + if len(self.cmdList): + self.session.openWithCallback(self.runRemove, MessageBox, _("Do you want to remove the package:\n") + self.pluginname + "\n" + self.oktext) + else: + if self.packagefiles: + for package in self.packagefiles[:]: + self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package["name"] })) + if len(self.cmdList): + self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to install the package:\n") + self.pluginname + "\n" + self.oktext) + + def runUpgrade(self, result): + if result: + self.session.openWithCallback(self.runUpgradeFinished, Ipkg, cmdList = self.cmdList) + + def runUpgradeFinished(self): + self.session.openWithCallback(self.UpgradeReboot, MessageBox, _("Installation finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO) + + def UpgradeReboot(self, result): + if result is None: + return + if result is False: + self.close(True) + if result: + quitMainloop(3) + + def runRemove(self, result): + if result: + self.session.openWithCallback(self.runRemoveFinished, Ipkg, cmdList = self.cmdList) + + def runRemoveFinished(self): + self.session.openWithCallback(self.RemoveReboot, MessageBox, _("Remove finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO) + + def RemoveReboot(self, result): + if result is None: + return + if result is False: + self.close(True) + if result: + quitMainloop(3) + + def reloadPluginlist(self): + plugins.readPluginList(resolveFilename(SCOPE_PLUGINS)) + + def fetchFailed(self,string): + self.setThumbnail(noScreenshot = True) + print "[PluginDetails] fetch failed " + string.getErrorMessage() + + +class UpdatePlugin(Screen): + skin = """ + + + + + + """ + + def __init__(self, session, args = None): + Screen.__init__(self, session) + + self.sliderPackages = { "dreambox-dvb-modules": 1, "enigma2": 2, "tuxbox-image-info": 3 } + + self.slider = Slider(0, 4) + self["slider"] = self.slider + self.activityslider = Slider(0, 100) + self["activityslider"] = self.activityslider + self.status = StaticText(_("Upgrading Dreambox... Please wait")) + self["status"] = self.status + self.package = StaticText() + self["package"] = self.package + + self.packages = 0 + self.error = 0 + + self.activity = 0 + self.activityTimer = eTimer() + self.activityTimer.callback.append(self.doActivityTimer) + self.activityTimer.start(100, False) + + self.ipkg = IpkgComponent() + self.ipkg.addCallback(self.ipkgCallback) + + self.updating = True + self.package.setText(_("Package list update")) + self.ipkg.startCmd(IpkgComponent.CMD_UPDATE) + + self["actions"] = ActionMap(["WizardActions"], + { + "ok": self.exit, + "back": self.exit + }, -1) + + def doActivityTimer(self): + self.activity += 1 + if self.activity == 100: + self.activity = 0 + self.activityslider.setValue(self.activity) + + def ipkgCallback(self, event, param): + if event == IpkgComponent.EVENT_DOWNLOAD: + self.status.setText(_("Downloading")) + elif event == IpkgComponent.EVENT_UPGRADE: + if self.sliderPackages.has_key(param): + self.slider.setValue(self.sliderPackages[param]) + self.package.setText(param) + self.status.setText(_("Upgrading")) + self.packages += 1 + elif event == IpkgComponent.EVENT_INSTALL: + self.package.setText(param) + self.status.setText(_("Installing")) + self.packages += 1 + elif event == IpkgComponent.EVENT_CONFIGURING: + self.package.setText(param) + self.status.setText(_("Configuring")) + elif event == IpkgComponent.EVENT_MODIFIED: + self.session.openWithCallback( + self.modificationCallback, + MessageBox, + _("A configuration file (%s) was modified since Installation.\nDo you want to keep your version?") % (param) + ) + elif event == IpkgComponent.EVENT_ERROR: + self.error += 1 + elif event == IpkgComponent.EVENT_DONE: + if self.updating: + self.updating = False + self.ipkg.startCmd(IpkgComponent.CMD_UPGRADE, args = {'test_only': False}) + elif self.error == 0: + self.slider.setValue(4) + + self.activityTimer.stop() + self.activityslider.setValue(0) + + self.package.setText("") + self.status.setText(_("Done - Installed or upgraded %d packages") % self.packages) + else: + self.activityTimer.stop() + self.activityslider.setValue(0) + error = _("your dreambox might be unusable now. Please consult the manual for further assistance before rebooting your dreambox.") + if self.packages == 0: + error = _("No packages were upgraded yet. So you can check your network and try again.") + if self.updating: + error = _("Your dreambox isn't connected to the internet properly. Please check it and try again.") + self.status.setText(_("Error") + " - " + error) + #print event, "-", param + pass - def runExecute(self, result): - if result: - self.session.openWithCallback(self.runExecuteFinished, Ipkg, cmdList = self.cmdList) - else: - self.close() + def modificationCallback(self, res): + self.ipkg.write(res and "N" or "Y") - def runExecuteFinished(self): - self.session.openWithCallback(self.ExecuteReboot, MessageBox, _("Install or remove finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO) + def exit(self): + if not self.ipkg.isRunning(): + if self.packages != 0 and self.error == 0: + self.session.openWithCallback(self.exitAnswer, MessageBox, _("Upgrade finished.") +" "+_("Do you want to reboot your Dreambox?")) + else: + self.close() - def ExecuteReboot(self, result): - if result is None: - return - if result is False: - self.reloadPluginlist() - self.detailsClosed(True) - if result: - quitMainloop(3) + def exitAnswer(self, result): + if result is not None and result: + quitMainloop(2) + self.close() - def reloadPluginlist(self): - plugins.readPluginList(resolveFilename(SCOPE_PLUGINS)) -class PluginManagerInfo(Screen): +class IPKGMenu(Screen): skin = """ - + - - - {"template": [ - MultiContentEntryText(pos = (50, 1), size = (150, 24), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name - MultiContentEntryText(pos = (50, 25), size = (540, 24), font=1, flags = RT_HALIGN_LEFT, text = 1), # index 1 is the state - MultiContentEntryPixmapAlphaTest(pos = (0, 1), size = (48, 48), png = 2), # index 2 is the status pixmap - MultiContentEntryPixmapAlphaTest(pos = (0, 49), size = (550, 2), png = 3), # index 3 is the div pixmap - ], - "fonts": [gFont("Regular", 22),gFont("Regular", 18)], - "itemHeight": 52 - } - - - - + """ - def __init__(self, session, plugin_path, cmdlist = None): + def __init__(self, session, plugin_path): Screen.__init__(self, session) - self.session = session self.skin_path = plugin_path - self.cmdlist = cmdlist + + self["key_red"] = StaticText(_("Close")) + self["key_green"] = StaticText(_("Edit")) - self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"], + self.sel = [] + self.val = [] + self.entry = False + self.exe = False + + self.path = "" + + self["actions"] = NumberActionMap(["SetupActions"], { - "ok": self.process, - "back": self.exit, - "red": self.exit, - "green": self.process, + "ok": self.KeyOk, + "cancel": self.keyCancel }, -1) - self.list = [] - self["list"] = List(self.list) - self["key_red"] = StaticText(_("Cancel")) - self["key_green"] = StaticText(_("Continue")) - self["status"] = StaticText(_("Following tasks will be done after you press continue!")) + self["shortcuts"] = ActionMap(["ShortcutActions"], + { + "red": self.keyCancel, + "green": self.KeyOk, + }) + self.flist = [] + self["filelist"] = MenuList(self.flist) + self.fill_list() + self.onLayoutFinish.append(self.layoutFinished) - self.onShown.append(self.setWindowTitle) - self.onLayoutFinish.append(self.rebuildList) + def layoutFinished(self): + self.setWindowTitle() def setWindowTitle(self): - self.setTitle(_("Plugin manager activity information")) + self.setTitle(_("Select upgrade source to edit.")) - def rebuildList(self): - self.list = [] - if self.cmdlist is not None: - for entry in self.cmdlist: - action = "" - info = "" - cmd = entry[0] - if cmd == 0: - action = 'install' - elif cmd == 2: - action = 'remove' - else: - action = 'upgrade' - args = entry[1] - if cmd == 0: - info = args['package'] - elif cmd == 2: - info = args['package'] - else: - info = _("Dreambox software because updates are available.") + def fill_list(self): + self.flist = [] + self.path = '/etc/ipkg/' + if (os_path.exists(self.path) == False): + self.entry = False + return + for file in listdir(self.path): + if (file.endswith(".conf")): + if file != 'arch.conf': + self.flist.append((file)) + self.entry = True + self["filelist"].l.setList(self.flist) - self.list.append(self.buildEntryComponent(action,info)) - self['list'].setList(self.list) - self['list'].updateList(self.list) + def KeyOk(self): + if (self.exe == False) and (self.entry == True): + self.sel = self["filelist"].getCurrent() + self.val = self.path + self.sel + self.session.open(IPKGSource, self.val) - def buildEntryComponent(self, action,info): - divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png")) - upgradepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgrade.png")) - installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/install.png")) - removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png")) - if action == 'install': - return(( _('Installing'), info, installpng, divpng)) - elif action == 'remove': - return(( _('Removing'), info, removepng, divpng)) + def keyCancel(self): + self.close() + + def Exit(self): + self.close() + + +class IPKGSource(Screen): + skin = """ + + + + + + + """ + + def __init__(self, session, configfile = None): + Screen.__init__(self, session) + self.session = session + self.configfile = configfile + text = "" + if self.configfile: + try: + fp = file(configfile, 'r') + sources = fp.readlines() + if sources: + text = sources[0] + fp.close() + except IOError: + pass + + desk = getDesktop(0) + x= int(desk.size().width()) + y= int(desk.size().height()) + + self["key_red"] = StaticText(_("Cancel")) + self["key_green"] = StaticText(_("Save")) + + if (y>=720): + self["text"] = Input(text, maxSize=False, type=Input.TEXT) else: - return(( _('Upgrading'), info, upgradepng, divpng)) + self["text"] = Input(text, maxSize=False, visible_width = 55, type=Input.TEXT) - def exit(self): - self.close(False) + self["actions"] = NumberActionMap(["WizardActions", "InputActions", "TextEntryActions", "KeyboardInputActions","ShortcutActions"], + { + "ok": self.go, + "back": self.close, + "red": self.close, + "green": self.go, + "left": self.keyLeft, + "right": self.keyRight, + "home": self.keyHome, + "end": self.keyEnd, + "deleteForward": self.keyDeleteForward, + "deleteBackward": self.keyDeleteBackward, + "1": self.keyNumberGlobal, + "2": self.keyNumberGlobal, + "3": self.keyNumberGlobal, + "4": self.keyNumberGlobal, + "5": self.keyNumberGlobal, + "6": self.keyNumberGlobal, + "7": self.keyNumberGlobal, + "8": self.keyNumberGlobal, + "9": self.keyNumberGlobal, + "0": self.keyNumberGlobal + }, -1) - def process(self): - self.close(True) + self.onLayoutFinish.append(self.layoutFinished) + + def layoutFinished(self): + self.setWindowTitle() + self["text"].right() + def setWindowTitle(self): + self.setTitle(_("Edit upgrade source url.")) -class PluginManagerHelp(Screen): + def go(self): + text = self["text"].getText() + if text: + fp = file(self.configfile, 'w') + fp.write(text) + fp.write("\n") + fp.close() + self.close() + + def keyLeft(self): + self["text"].left() + + def keyRight(self): + self["text"].right() + + def keyHome(self): + self["text"].home() + + def keyEnd(self): + self["text"].end() + + def keyDeleteForward(self): + self["text"].delete() + + def keyDeleteBackward(self): + self["text"].deleteBackward() + + def keyNumberGlobal(self, number): + self["text"].number(number) + + +class PacketManager(Screen): skin = """ - + + - + + {"template": [ - MultiContentEntryText(pos = (50, 1), size = (540, 24), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name - MultiContentEntryText(pos = (50, 25), size = (540, 24), font=1, flags = RT_HALIGN_LEFT, text = 1), # index 1 is the state - MultiContentEntryPixmapAlphaTest(pos = (0, 1), size = (48, 48), png = 2), # index 2 is the status pixmap - MultiContentEntryPixmapAlphaTest(pos = (0, 49), size = (550, 2), png = 3), # index 3 is the div pixmap + MultiContentEntryText(pos = (5, 1), size = (440, 28), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name + MultiContentEntryText(pos = (5, 26), size = (440, 20), font=1, flags = RT_HALIGN_LEFT, text = 2), # index 2 is the description + MultiContentEntryPixmapAlphaTest(pos = (445, 2), size = (48, 48), png = 4), # index 4 is the status pixmap + MultiContentEntryPixmapAlphaTest(pos = (5, 50), size = (510, 2), png = 5), # index 4 is the div pixmap ], - "fonts": [gFont("Regular", 22),gFont("Regular", 18)], + "fonts": [gFont("Regular", 22),gFont("Regular", 14)], "itemHeight": 52 } - - """ - - def __init__(self, session, plugin_path): + + def __init__(self, session, plugin_path, args = None): Screen.__init__(self, session) self.session = session self.skin_path = plugin_path - self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"], + self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"], { + "ok": self.go, "back": self.exit, "red": self.exit, + "green": self.reload, }, -1) - + self.list = [] + self.statuslist = [] self["list"] = List(self.list) self["key_red"] = StaticText(_("Close")) - self["status"] = StaticText(_("A small overview of the available icon states and actions.")) + self["key_green"] = StaticText(_("Reload")) + + self.list_updating = True + self.packetlist = [] + self.installed_packetlist = {} + self.Console = Console() + self.cmdList = [] + self.cachelist = [] + self.cache_ttl = 86400 #600 is default, 0 disables, Seconds cache is considered valid (24h should be ok for caching ipkgs) + self.cache_file = '/usr/lib/enigma2/python/Plugins/SystemPlugins/SoftwareManager/packetmanager.cache' #Path to cache directory + self.oktext = _("\nAfter pressing OK, please wait!") + self.unwanted_extensions = ('-dbg', '-dev', '-doc', 'busybox') + self.ipkg = IpkgComponent() + self.ipkg.addCallback(self.ipkgCallback) self.onShown.append(self.setWindowTitle) self.onLayoutFinish.append(self.rebuildList) - def setWindowTitle(self): - self.setTitle(_("Plugin manager help")) - - def rebuildList(self): - self.list = [] - self.list.append(self.buildEntryComponent('install')) - self.list.append(self.buildEntryComponent('installable')) - self.list.append(self.buildEntryComponent('installed')) - self.list.append(self.buildEntryComponent('remove')) - self['list'].setList(self.list) - self['list'].updateList(self.list) - - def buildEntryComponent(self, state): - divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png")) - installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installed.png")) - installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installable.png")) - removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png")) - installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/install.png")) - - if state == 'installed': - return(( _('This plugin is installed.'), _('You can remove this plugin.'), installedpng, divpng)) - elif state == 'installable': - return(( _('This plugin is not installed.'), _('You can install this plugin.'), installablepng, divpng)) - elif state == 'install': - return(( _('This plugin will be installed.'), _('You can cancel the installation.'), installpng, divpng)) - elif state == 'remove': - return(( _('This plugin will be removed.'), _('You can cancel the removal.'), removepng, divpng)) - def exit(self): + self.ipkg.stop() + if self.Console is not None: + if len(self.Console.appContainers): + for name in self.Console.appContainers.keys(): + self.Console.kill(name) self.close() - -class PluginDetails(Screen, DreamInfoHandler): - skin = """ - - - - - - - - - - - """ - def __init__(self, session, plugin_path, packagedata = None): - Screen.__init__(self, session) - self.skin_path = plugin_path - self.language = language.getLanguage()[:2] # getLanguage returns e.g. "fi_FI" for "language_country" - self.attributes = None - self.translatedAttributes = None - DreamInfoHandler.__init__(self, self.statusCallback, blocking = False, language = self.language) - self.directory = resolveFilename(SCOPE_METADIR) - if packagedata: - self.pluginname = packagedata[0] - self.details = packagedata[1] - self.pluginstate = packagedata[4] - self.statuspicinstance = packagedata[5] - self.divpicinstance = packagedata[6] - self.fillPackageDetails(self.details) - - self.thumbnail = "" - - self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"], - { - "back": self.exit, - "red": self.exit, - "green": self.go, - "up": self.pageUp, - "down": self.pageDown, - "left": self.pageUp, - "right": self.pageDown, - }, -1) - - self["key_red"] = StaticText(_("Close")) - self["key_green"] = StaticText("") - self["author"] = StaticText() - self["statuspic"] = Pixmap() - self["divpic"] = Pixmap() - self["screenshot"] = Pixmap() - self["detailtext"] = ScrollLabel() - - self["statuspic"].hide() - self["screenshot"].hide() - self["divpic"].hide() - - self.package = self.packageDetails[0] - if self.package[0].has_key("attributes"): - self.attributes = self.package[0]["attributes"] - if self.package[0].has_key("translation"): - self.translatedAttributes = self.package[0]["translation"] - - self.cmdList = [] - self.oktext = _("\nAfter pressing OK, please wait!") - self.picload = ePicLoad() - self.picload.PictureData.get().append(self.paintScreenshotPixmapCB) - self.onShown.append(self.setWindowTitle) - self.onLayoutFinish.append(self.setInfos) - + def reload(self): + if (os_path.exists(self.cache_file) == True): + remove(self.cache_file) + self.list_updating = True + self.rebuildList() + def setWindowTitle(self): - self.setTitle(_("Package details for: " + self.pluginname)) - - def exit(self): - self.close(False) - - def pageUp(self): - self["detailtext"].pageUp() - - def pageDown(self): - self["detailtext"].pageDown() - - def statusCallback(self, status, progress): - pass - - def setInfos(self): - if self.translatedAttributes.has_key("name"): - self.pluginname = self.translatedAttributes["name"] - elif self.attributes.has_key("name"): - self.pluginname = self.attributes["name"] - else: - self.pluginname = _("unknown") - - if self.translatedAttributes.has_key("author"): - self.author = self.translatedAttributes["author"] - elif self.attributes.has_key("author"): - self.author = self.attributes["author"] - else: - self.author = _("unknown") - - if self.translatedAttributes.has_key("description"): - self.description = self.translatedAttributes["description"] - elif self.attributes.has_key("description"): - self.description = self.attributes["description"] - else: - self.description = _("No description available.") - - if self.translatedAttributes.has_key("screenshot"): - self.loadThumbnail(self.translatedAttributes) - else: - self.loadThumbnail(self.attributes) - - self["author"].setText(_("Author: ") + self.author) - self["detailtext"].setText(self.description.strip()) - if self.pluginstate == 'installable': - self["key_green"].setText(_("Install")) - else: - self["key_green"].setText(_("Remove")) - - def loadThumbnail(self, entry): - thumbnailUrl = None - if entry.has_key("screenshot"): - thumbnailUrl = entry["screenshot"] - if thumbnailUrl is not None: - self.thumbnail = "/tmp/" + thumbnailUrl.split('/')[-1] - print "[PluginDetails] downloading screenshot " + thumbnailUrl + " to " + self.thumbnail - client.downloadPage(thumbnailUrl,self.thumbnail).addCallback(self.setThumbnail).addErrback(self.fetchFailed) - else: - self.setThumbnail(noScreenshot = True) - - def setThumbnail(self, noScreenshot = False): - if not noScreenshot: - filename = self.thumbnail - else: - filename = resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/noprev.png") - - sc = AVSwitch().getFramebufferScale() - self.picload.setPara((self["screenshot"].instance.size().width(), self["screenshot"].instance.size().height(), sc[0], sc[1], False, 1, "#00000000")) - self.picload.startDecode(filename) - - if self.statuspicinstance != None: - self["statuspic"].instance.setPixmap(self.statuspicinstance.__deref__()) - self["statuspic"].show() - if self.divpicinstance != None: - self["divpic"].instance.setPixmap(self.divpicinstance.__deref__()) - self["divpic"].show() - - def paintScreenshotPixmapCB(self, picInfo=None): - ptr = self.picload.getData() - if ptr != None: - self["screenshot"].instance.setPixmap(ptr.__deref__()) - self["screenshot"].show() - else: - self.setThumbnail(noScreenshot = True) - - def go(self): - if self.attributes.has_key("package"): - self.packagefiles = self.attributes["package"] - self.cmdList = [] - if self.pluginstate == 'installed': - if self.packagefiles: - for package in self.packagefiles[:]: - self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": package["name"] })) - if len(self.cmdList): - self.session.openWithCallback(self.runRemove, MessageBox, _("Do you want to remove the package:\n") + self.pluginname + "\n" + self.oktext) - else: - if self.packagefiles: - for package in self.packagefiles[:]: - self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package["name"] })) - if len(self.cmdList): - self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to install the package:\n") + self.pluginname + "\n" + self.oktext) + self.setTitle(_("Packet manager")) - def runUpgrade(self, result): - if result: - self.session.openWithCallback(self.runUpgradeFinished, Ipkg, cmdList = self.cmdList) + 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 packetlist. Please wait..." ),'',statuspng, divpng )) + self['list'].setList(self.statuslist) + 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 packetlist. Please try again." ),'',statuspng, divpng )) + self['list'].setList(self.statuslist) - def runUpgradeFinished(self): - self.session.openWithCallback(self.UpgradeReboot, MessageBox, _("Installation finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO) + def rebuildList(self): + self.setStatus('update') + self.inv_cache = 0 + self.vc = valid_cache(self.cache_file, self.cache_ttl) + if self.cache_ttl > 0 and self.vc != 0: + try: + self.buildPacketList() + except: + self.inv_cache = 1 + if self.cache_ttl == 0 or self.inv_cache == 1 or self.vc == 0: + self.run = 0 + self.ipkg.startCmd(IpkgComponent.CMD_UPDATE) - def UpgradeReboot(self, result): - if result is None: - return - if result is False: - self.close(True) - if result: - quitMainloop(3) + def go(self, returnValue = None): + cur = self["list"].getCurrent() + if cur: + status = cur[3] + package = cur[0] + self.cmdList = [] + if status == 'installed': + self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": package })) + if len(self.cmdList): + self.session.openWithCallback(self.runRemove, MessageBox, _("Do you want to remove the package:\n") + package + "\n" + self.oktext) + elif status == 'upgradeable': + self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package })) + if len(self.cmdList): + self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to upgrade the package:\n") + package + "\n" + self.oktext) + elif status == "installable": + self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package })) + if len(self.cmdList): + self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to install the package:\n") + package + "\n" + self.oktext) def runRemove(self, result): if result: @@ -1528,131 +1510,122 @@ class PluginDetails(Screen, DreamInfoHandler): if result is None: return if result is False: - self.close(True) + cur = self["list"].getCurrent() + if cur: + item = self['list'].getIndex() + self.list[item] = self.buildEntryComponent(cur[0], cur[1], cur[2], 'installable') + self.cachelist[item] = [cur[0], cur[1], cur[2], 'installable'] + self['list'].setList(self.list) + write_cache(self.cache_file, self.cachelist) + self.reloadPluginlist() if result: quitMainloop(3) - def reloadPluginlist(self): - plugins.readPluginList(resolveFilename(SCOPE_PLUGINS)) - - def fetchFailed(self,string): - self.setThumbnail(noScreenshot = True) - print "[PluginDetails] fetch failed " + string.getErrorMessage() - - -class UpdatePlugin(Screen): - skin = """ - - - - - - """ - - def __init__(self, session, args = None): - Screen.__init__(self, session) - - self.sliderPackages = { "dreambox-dvb-modules": 1, "enigma2": 2, "tuxbox-image-info": 3 } - - self.slider = Slider(0, 4) - self["slider"] = self.slider - self.activityslider = Slider(0, 100) - self["activityslider"] = self.activityslider - self.status = StaticText(_("Upgrading Dreambox... Please wait")) - self["status"] = self.status - self.package = StaticText() - self["package"] = self.package - - self.packages = 0 - self.error = 0 - - self.activity = 0 - self.activityTimer = eTimer() - self.activityTimer.callback.append(self.doActivityTimer) - self.activityTimer.start(100, False) - - self.ipkg = IpkgComponent() - self.ipkg.addCallback(self.ipkgCallback) - - self.updating = True - self.package.setText(_("Package list update")) - self.ipkg.startCmd(IpkgComponent.CMD_UPDATE) - - self["actions"] = ActionMap(["WizardActions"], - { - "ok": self.exit, - "back": self.exit - }, -1) + def runUpgrade(self, result): + if result: + self.session.openWithCallback(self.runUpgradeFinished, Ipkg, cmdList = self.cmdList) - def doActivityTimer(self): - self.activity += 1 - if self.activity == 100: - self.activity = 0 - self.activityslider.setValue(self.activity) + def runUpgradeFinished(self): + self.session.openWithCallback(self.UpgradeReboot, MessageBox, _("Upgrade finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO) + + def UpgradeReboot(self, result): + if result is None: + return + if result is False: + cur = self["list"].getCurrent() + if cur: + item = self['list'].getIndex() + self.list[item] = self.buildEntryComponent(cur[0], cur[1], cur[2], 'installed') + self.cachelist[item] = [cur[0], cur[1], cur[2], 'installed'] + self['list'].setList(self.list) + write_cache(self.cache_file, self.cachelist) + self.reloadPluginlist() + if result: + quitMainloop(3) def ipkgCallback(self, event, param): - if event == IpkgComponent.EVENT_DOWNLOAD: - self.status.setText(_("Downloading")) - elif event == IpkgComponent.EVENT_UPGRADE: - if self.sliderPackages.has_key(param): - self.slider.setValue(self.sliderPackages[param]) - self.package.setText(param) - self.status.setText(_("Upgrading")) - self.packages += 1 - elif event == IpkgComponent.EVENT_INSTALL: - self.package.setText(param) - self.status.setText(_("Installing")) - self.packages += 1 - elif event == IpkgComponent.EVENT_CONFIGURING: - self.package.setText(param) - self.status.setText(_("Configuring")) - elif event == IpkgComponent.EVENT_MODIFIED: - self.session.openWithCallback( - self.modificationCallback, - MessageBox, - _("A configuration file (%s) was modified since Installation.\nDo you want to keep your version?") % (param) - ) - elif event == IpkgComponent.EVENT_ERROR: - self.error += 1 + if event == IpkgComponent.EVENT_ERROR: + self.list_updating = False + self.setStatus('error') elif event == IpkgComponent.EVENT_DONE: - if self.updating: - self.updating = False - self.ipkg.startCmd(IpkgComponent.CMD_UPGRADE, args = {'test_only': False}) - elif self.error == 0: - self.slider.setValue(4) - - self.activityTimer.stop() - self.activityslider.setValue(0) - - self.package.setText("") - self.status.setText(_("Done - Installed or upgraded %d packages") % self.packages) - else: - self.activityTimer.stop() - self.activityslider.setValue(0) - error = _("your dreambox might be unusable now. Please consult the manual for further assistance before rebooting your dreambox.") - if self.packages == 0: - error = _("No packages were upgraded yet. So you can check your network and try again.") - if self.updating: - error = _("Your dreambox isn't connected to the internet properly. Please check it and try again.") - self.status.setText(_("Error") + " - " + error) + if self.list_updating: + self.list_updating = False + if not self.Console: + self.Console = Console() + cmd = "ipkg list" + self.Console.ePopen(cmd, self.IpkgList_Finished) #print event, "-", param pass - def modificationCallback(self, res): - self.ipkg.write(res and "N" or "Y") + def IpkgList_Finished(self, result, retval, extra_args = None): + if len(result): + self.packetlist = [] + for x in result.splitlines(): + split = x.split(' - ') #self.blacklisted_packages + if not any(split[0].strip().endswith(x) for x in self.unwanted_extensions): + self.packetlist.append([split[0].strip(), split[1].strip(),split[2].strip()]) + if not self.Console: + self.Console = Console() + cmd = "ipkg list_installed" + self.Console.ePopen(cmd, self.IpkgListInstalled_Finished) - def exit(self): - if not self.ipkg.isRunning(): - if self.packages != 0 and self.error == 0: - self.session.openWithCallback(self.exitAnswer, MessageBox, _("Upgrade finished.") +" "+_("Do you want to reboot your Dreambox?")) - else: - self.close() + def IpkgListInstalled_Finished(self, result, retval, extra_args = None): + if len(result): + self.installed_packetlist = {} + for x in result.splitlines(): + split = x.split(' - ') + if not any(split[0].strip().endswith(x) for x in self.unwanted_extensions): + self.installed_packetlist[split[0].strip()] = split[1].strip() + self.buildPacketList() - def exitAnswer(self, result): - if result is not None and result: - quitMainloop(2) - self.close() + def buildEntryComponent(self, name, version, description, state): + divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png")) + 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 = [] + self.cachelist = [] + + if self.cache_ttl > 0 and self.vc != 0: + print 'Loading packagelist cache from ',self.cache_file + try: + self.cachelist = load_cache(self.cache_file) + if len(self.cachelist) > 0: + for x in self.cachelist: + self.list.append(self.buildEntryComponent(x[0], x[1], x[2], x[3])) + self['list'].setList(self.list) + except: + self.inv_cache = 1 + + if self.cache_ttl == 0 or self.inv_cache == 1 or self.vc == 0: + print 'rebuilding fresh package list' + for x in self.packetlist: + status = "" + if self.installed_packetlist.has_key(x[0].strip()): + if self.installed_packetlist[x[0].strip()] == x[1].strip(): + status = "installed" + self.list.append(self.buildEntryComponent(x[0].strip(), x[1].strip(), x[2].strip(), status)) + else: + status = "upgradeable" + self.list.append(self.buildEntryComponent(x[0].strip(), x[1].strip(), x[2].strip(), status)) + else: + status = "installable" + self.list.append(self.buildEntryComponent(x[0].strip(), x[1].strip(), x[2].strip(), status)) + if not any(x[0].strip().endswith(x) for x in self.unwanted_extensions): + self.cachelist.append([x[0].strip(), x[1].strip(), x[2].strip(), status]) + write_cache(self.cache_file, self.cachelist) + self['list'].setList(self.list) + def reloadPluginlist(self): + plugins.readPluginList(resolveFilename(SCOPE_PLUGINS)) class IpkgInstaller(Screen): skin = """ @@ -1719,15 +1692,20 @@ def UpgradeMain(session, **kwargs): def startSetup(menuid): if menuid != "setup": return [ ] - return [(_("Software manager"), UpgradeMain, "software_manager", 50)] + return [(_("Software management"), UpgradeMain, "software_manager", 50)] + +def autostart(reason, **kwargs): + if reason is True: + iSoftwareTools.startSoftwareTools() def Plugins(path, **kwargs): global plugin_path plugin_path = path list = [ - PluginDescriptor(name=_("Software manager"), description=_("Manage your receiver's software"), where = PluginDescriptor.WHERE_MENU, fnc=startSetup), + PluginDescriptor(where = [PluginDescriptor.WHERE_NETWORKCONFIG_READ], fnc = autostart), + PluginDescriptor(name=_("Software management"), description=_("Manage your receiver's software"), where = PluginDescriptor.WHERE_MENU, fnc=startSetup), PluginDescriptor(name=_("Ipkg"), where = PluginDescriptor.WHERE_FILESCAN, fnc = filescan) ] if config.usage.setup_level.index >= 2: # expert+ - list.append(PluginDescriptor(name=_("Software manager"), description=_("Manage your receiver's software"), where = PluginDescriptor.WHERE_EXTENSIONSMENU, fnc=UpgradeMain)) + list.append(PluginDescriptor(name=_("Software management"), description=_("Manage your receiver's software"), where = PluginDescriptor.WHERE_EXTENSIONSMENU, fnc=UpgradeMain)) return list -- cgit v1.2.3