X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/dfc3142e629d32e1f5efa380e777f711dc0fe92c..cd176a16cb54350617ea202de983e8d643978971:/lib/python/Screens/PluginBrowser.py diff --git a/lib/python/Screens/PluginBrowser.py b/lib/python/Screens/PluginBrowser.py old mode 100644 new mode 100755 index 429163ee..69bf80f7 --- a/lib/python/Screens/PluginBrowser.py +++ b/lib/python/Screens/PluginBrowser.py @@ -1,77 +1,132 @@ from Screen import Screen - +from Components.Language import language from enigma import eConsoleAppContainer -from Components.MenuList import MenuList from Components.ActionMap import ActionMap from Components.PluginComponent import plugins from Components.PluginList import * -from Components.config import config from Components.Label import Label from Screens.MessageBox import MessageBox from Screens.Console import Console from Plugins.Plugin import PluginDescriptor -from Tools.Directories import resolveFilename, SCOPE_PLUGINS +from Tools.Directories import resolveFilename, fileExists, SCOPE_PLUGINS, SCOPE_SKIN_IMAGE +from Tools.LoadPixmap import LoadPixmap + +from time import time + +def languageChanged(): + plugins.clearPluginList() + plugins.readPluginList(resolveFilename(SCOPE_PLUGINS)) class PluginBrowser(Screen): def __init__(self, session): Screen.__init__(self, session) - self["red"] = Label(_("Delete")) - self["green"] = Label(_("Download Plugins")) + self["red"] = Label() + self["green"] = Label() self.list = [] self["list"] = PluginList(self.list) - self.updateList() - self["actions"] = ActionMap(["WizardActions", "ColorActions"], + self["actions"] = ActionMap(["WizardActions"], { "ok": self.save, "back": self.close, + }) + self["PluginDownloadActions"] = ActionMap(["ColorActions"], + { "red": self.delete, "green": self.download }) - + self["SoftwareActions"] = ActionMap(["ColorActions"], + { + "red": self.openExtensionmanager + }) + self["PluginDownloadActions"].setEnabled(False) + self["SoftwareActions"].setEnabled(False) + self.onFirstExecBegin.append(self.checkWarnings) + self.onShown.append(self.updateList) + + def checkWarnings(self): + if len(plugins.warnings): + text = _("Some plugins are not available:\n") + for (pluginname, error) in plugins.warnings: + text += _("%s (%s)\n") % (pluginname, error) + plugins.resetWarnings() + self.session.open(MessageBox, text = text, type = MessageBox.TYPE_WARNING) + def save(self): - #self.close() self.run() def run(self): plugin = self["list"].l.getCurrentSelection()[0] - plugin(session=self.session) def updateList(self): - self.list = [ ] self.pluginlist = plugins.getPlugins(PluginDescriptor.WHERE_PLUGINMENU) - for plugin in self.pluginlist: - self.list.append(PluginEntryComponent(plugin)) - + self.list = [PluginEntryComponent(plugin) for plugin in self.pluginlist] self["list"].l.setList(self.list) - + if fileExists(resolveFilename(SCOPE_PLUGINS, "SystemPlugins/SoftwareManager/plugin.py")): + self["red"].setText(_("Manage extensions")) + self["green"].setText("") + self["SoftwareActions"].setEnabled(True) + self["PluginDownloadActions"].setEnabled(False) + else: + self["red"].setText(_("Remove Plugins")) + self["green"].setText(_("Download Plugins")) + self["SoftwareActions"].setEnabled(False) + self["PluginDownloadActions"].setEnabled(True) + def delete(self): - pass + self.session.openWithCallback(self.PluginDownloadBrowserClosed, PluginDownloadBrowser, PluginDownloadBrowser.REMOVE) def download(self): - self.session.openWithCallback(self.updateList, PluginDownloadBrowser) + self.session.openWithCallback(self.PluginDownloadBrowserClosed, PluginDownloadBrowser, PluginDownloadBrowser.DOWNLOAD) + + def PluginDownloadBrowserClosed(self): + self.updateList() + self.checkWarnings() + + def openExtensionmanager(self): + if fileExists(resolveFilename(SCOPE_PLUGINS, "SystemPlugins/SoftwareManager/plugin.py")): + try: + from Plugins.SystemPlugins.SoftwareManager.plugin import PluginManager + except ImportError: + self.session.open(MessageBox, _("The Softwaremanagement extension is not installed!\nPlease install it."), type = MessageBox.TYPE_INFO,timeout = 10 ) + else: + self.session.openWithCallback(self.PluginDownloadBrowserClosed, PluginManager) class PluginDownloadBrowser(Screen): - def __init__(self, session): + DOWNLOAD = 0 + REMOVE = 1 + lastDownloadDate = None + + def __init__(self, session, type): Screen.__init__(self, session) + self.type = type + self.container = eConsoleAppContainer() - self.container.appClosed.get().append(self.runFinished) - self.container.dataAvail.get().append(self.dataAvail) + self.container.appClosed.append(self.runFinished) + self.container.dataAvail.append(self.dataAvail) self.onLayoutFinish.append(self.startRun) + self.onShown.append(self.setWindowTitle) self.list = [] self["list"] = PluginList(self.list) self.pluginlist = [] + self.expanded = [] + self.installedplugins = [] - self["text"] = Label(_("Downloading plugin information. Please wait...")) + if self.type == self.DOWNLOAD: + self["text"] = Label(_("Downloading plugin information. Please wait...")) + elif self.type == self.REMOVE: + self["text"] = Label(_("Getting plugin information. Please wait...")) self.run = 0 - + + self.remainingdata = "" + self["actions"] = ActionMap(["WizardActions"], { "ok": self.go, @@ -79,43 +134,126 @@ class PluginDownloadBrowser(Screen): }) def go(self): - print "plugin: installing:", self.pluginlist[self["list"].l.getCurrentSelectionIndex()] - self.session.openWithCallback(self.runInstall, MessageBox, _("Do you really want to download\nthe plugin \"" + self.pluginlist[self["list"].l.getCurrentSelectionIndex()][3] + "\"?")) - + sel = self["list"].l.getCurrentSelection() + + if sel is None: + return + + sel = sel[0] + if isinstance(sel, str): # category + if sel in self.expanded: + self.expanded.remove(sel) + else: + self.expanded.append(sel) + self.updateList() + else: + if self.type == self.DOWNLOAD: + self.session.openWithCallback(self.runInstall, MessageBox, _("Do you really want to download\nthe plugin \"%s\"?") % sel.name) + elif self.type == self.REMOVE: + self.session.openWithCallback(self.runInstall, MessageBox, _("Do you really want to REMOVE\nthe plugin \"%s\"?") % sel.name) + def runInstall(self, val): if val: - self.session.openWithCallback(self.installFinished, Console, ["ipkg install " + self.pluginlist[self["list"].l.getCurrentSelectionIndex()][0]]) + if self.type == self.DOWNLOAD: + self.session.openWithCallback(self.installFinished, Console, cmdlist = ["ipkg install " + "enigma2-plugin-" + self["list"].l.getCurrentSelection()[0].name]) + elif self.type == self.REMOVE: + self.session.openWithCallback(self.installFinished, Console, cmdlist = ["ipkg remove " + "enigma2-plugin-" + self["list"].l.getCurrentSelection()[0].name]) + + def setWindowTitle(self): + if self.type == self.DOWNLOAD: + self.setTitle(_("Downloadable new plugins")) + elif self.type == self.REMOVE: + self.setTitle(_("Remove plugins")) + + def startIpkgListInstalled(self): + self.container.execute("ipkg list_installed enigma2-plugin-*") + + def startIpkgListAvailable(self): + self.container.execute("ipkg list enigma2-plugin-*") def startRun(self): self["list"].instance.hide() - self.container.execute("ipkg update") - + if self.type == self.DOWNLOAD: + if not PluginDownloadBrowser.lastDownloadDate or (time() - PluginDownloadBrowser.lastDownloadDate) > 3600: + # Only update from internet once per hour + self.container.execute("ipkg update") + PluginDownloadBrowser.lastDownloadDate = time() + else: + self.startIpkgListAvailable() + elif self.type == self.REMOVE: + self.run = 1 + self.startIpkgListInstalled() + def installFinished(self): plugins.readPluginList(resolveFilename(SCOPE_PLUGINS)) - + self.container.appClosed.remove(self.runFinished) + self.container.dataAvail.remove(self.dataAvail) + self.close() + def runFinished(self, retval): + self.remainingdata = "" if self.run == 0: self.run = 1 - self.container.execute("ipkg list enigma2-plugin-*") + if self.type == self.DOWNLOAD: + self.startIpkgListInstalled() + elif self.run == 1 and self.type == self.DOWNLOAD: + self.run = 2 + self.startIpkgListAvailable() else: if len(self.pluginlist) > 0: self.updateList() self["list"].instance.show() else: - self["text"].setText("No plugins found") + self["text"].setText("No new plugins found") def dataAvail(self, str): - for x in str.split('\n'): - plugin = x.split(" - ") + #prepend any remaining data from the previous call + str = self.remainingdata + str + #split in lines + lines = str.split('\n') + #'str' should end with '\n', so when splitting, the last line should be empty. If this is not the case, we received an incomplete line + if len(lines[-1]): + #remember this data for next time + self.remainingdata = lines[-1] + lines = lines[0:-1] + else: + self.remainingdata = "" + + for x in lines: + plugin = x.split(" - ", 2) if len(plugin) == 3: - plugin.append(plugin[0][15:]) + if self.run == 1 and self.type == self.DOWNLOAD: + if plugin[0] not in self.installedplugins: + self.installedplugins.append(plugin[0]) + else: + if plugin[0] not in self.installedplugins: + plugin.append(plugin[0][15:]) - self.pluginlist.append(plugin) + self.pluginlist.append(plugin) def updateList(self): - for x in self.pluginlist: - plugin = PluginDescriptor(name = x[3], description = x[2]) - self.list.append(PluginEntryComponent(plugin)) + list = [] + expandableIcon = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/expandable-plugins.png")) + expandedIcon = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/expanded-plugins.png")) + verticallineIcon = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/verticalline-plugins.png")) - self["list"].l.setList(self.list) + self.plugins = {} + for x in self.pluginlist: + split = x[3].split('-', 1) + if len(split) < 2: + continue + if not self.plugins.has_key(split[0]): + self.plugins[split[0]] = [] + + self.plugins[split[0]].append((PluginDescriptor(name = x[3], description = x[2], icon = verticallineIcon), split[1])) + + for x in self.plugins.keys(): + if x in self.expanded: + list.append(PluginCategoryComponent(x, expandedIcon)) + list.extend([PluginDownloadComponent(plugin[0], plugin[1]) for plugin in self.plugins[x]]) + else: + list.append(PluginCategoryComponent(x, expandableIcon)) + self.list = list + self["list"].l.setList(list) +language.addCallback(languageChanged) \ No newline at end of file