from Plugins.Plugin import PluginDescriptor
from Screens.Console import Console
from Screens.ChoiceBox import ChoiceBox
from Screens.MessageBox import MessageBox
from Screens.Screen import Screen
from Screens.Ipkg import Ipkg
from Components.ActionMap import ActionMap, NumberActionMap
from Components.Input import Input
from Components.Ipkg import IpkgComponent
from Components.Sources.StaticText import StaticText
from Components.ScrollLabel import ScrollLabel
from Components.Pixmap import Pixmap
from Components.MenuList import MenuList
from Components.Sources.List import List
from Components.Slider import Slider
from Components.Harddisk import harddiskmanager
from Components.config import config,getConfigListEntry, ConfigSubsection, ConfigText, ConfigLocations
from Components.Console import Console
from Components.MultiContent import MultiContentEntryText, MultiContentEntryPixmapAlphaTest
from Components.SelectionList import SelectionList
from Components.PluginComponent import plugins
from Components.About import about
from Components.DreamInfoHandler import DreamInfoHandler
from Components.Language import language
from Components.AVSwitch import AVSwitch
from Tools.Directories import pathExists, fileExists, resolveFilename, SCOPE_PLUGINS, SCOPE_SKIN_IMAGE, SCOPE_METADIR
from Tools.LoadPixmap import LoadPixmap
from enigma import eTimer, quitMainloop, RT_HALIGN_LEFT, RT_VALIGN_CENTER, eListboxPythonMultiContent, eListbox, gFont, getDesktop, ePicLoad
from cPickle import dump, load
from os import path as os_path, system as os_system, unlink, stat, mkdir, popen, makedirs, listdir, access, rename, remove, W_OK, R_OK, F_OK
from time import time, gmtime, strftime, localtime
from stat import ST_MTIME
from datetime import date
from twisted.web import client
from twisted.internet import reactor
from ImageWizard import ImageWizard
from BackupRestore import BackupSelection, RestoreMenu, BackupScreen, RestoreScreen, getBackupPath, getBackupFilename
config.plugins.configurationbackup = ConfigSubsection()
config.plugins.configurationbackup.backuplocation = ConfigText(default = '/media/hdd/', visible_width = 50, fixed_size = False)
config.plugins.configurationbackup.backupdirs = ConfigLocations(default=['/etc/enigma2/', '/etc/network/interfaces', '/etc/wpa_supplicant.conf', '/etc/resolv.conf', '/etc/default_gw', '/etc/hostname'])
def write_cache(cache_file, cache_data):
#Does a cPickle dump
if not os_path.isdir( os_path.dirname(cache_file) ):
try:
mkdir( os_path.dirname(cache_file) )
except OSError:
print os_path.dirname(cache_file), 'is a file'
fd = open(cache_file, 'w')
dump(cache_data, fd, -1)
fd.close()
def valid_cache(cache_file, cache_ttl):
#See if the cache file exists and is still living
try:
mtime = stat(cache_file)[ST_MTIME]
except:
return 0
curr_time = time()
if (curr_time - mtime) > cache_ttl:
return 0
else:
return 1
def load_cache(cache_file):
#Does a cPickle load
fd = open(cache_file)
cache_data = load(fd)
fd.close()
return cache_data
class UpdatePluginMenu(Screen):
skin = """
{"template": [
MultiContentEntryText(pos = (2, 2), size = (290, 22), flags = RT_HALIGN_LEFT, text = 1), # index 0 is the MenuText,
],
"fonts": [gFont("Regular", 20)],
"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)],
"itemHeight": 300
}
"""
def __init__(self, session, args = 0):
Screen.__init__(self, session)
self.skin_path = plugin_path
self.menu = args
self.list = []
self.oktext = _("\nPress OK on your remote control to continue.")
self.backupdirs = ' '.join( config.plugins.configurationbackup.backupdirs.value )
if self.menu == 0:
self.list.append(("software-update", _("Software update"), _("\nOnline update of your Dreambox software." ) + self.oktext) )
#self.list.append(("install-plugins", _("Install extensions"), _("\nInstall new Extensions or Plugins to your dreambox" ) + self.oktext) )
self.list.append(("software-restore", _("Software restore"), _("\nRestore your Dreambox with a new firmware." ) + self.oktext))
self.list.append(("system-backup", _("Backup system settings"), _("\nBackup your Dreambox settings." ) + self.oktext))
self.list.append(("system-restore",_("Restore system settings"), _("\nRestore your Dreambox settings." ) + self.oktext))
self.list.append(("ipkg-install", _("Install local extension"), _("\nScan for local packages and install them." ) + self.oktext))
if config.usage.setup_level.index >= 2: # expert+
self.list.append(("advanced", _("Advanced Options"), _("\nAdvanced options and settings." ) + self.oktext))
elif self.menu == 1:
self.list.append(("advancedrestore", _("Advanced restore"), _("\nRestore your backups by date." ) + self.oktext))
self.list.append(("backuplocation", _("Choose backup location"), _("\nSelect your backup device.\nCurrent device: " ) + config.plugins.configurationbackup.backuplocation.value + self.oktext ))
self.list.append(("backupfiles", _("Choose backup files"), _("Select files for backup. Currently selected:\n" ) + self.backupdirs + self.oktext))
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))
self.list.append(("ipkg-source",_("Choose upgrade source"), _("\nEdit the upgrade source address." ) + self.oktext))
self["menu"] = List(self.list)
self["key_red"] = StaticText(_("Close"))
self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"],
{
"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)
def layoutFinished(self):
idx = 0
self["menu"].index = idx
def setWindowTitle(self):
self.setTitle(_("Software manager"))
def go(self):
current = self["menu"].getCurrent()
if current:
current = current[0]
if self.menu == 0:
if (current == "software-update"):
self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to update your Dreambox?")+"\n"+_("\nAfter pressing OK, please wait!"))
elif (current == "software-restore"):
self.session.open(ImageWizard)
elif (current == "install-plugins"):
self.session.open(PluginManager, self.skin_path)
elif (current == "system-backup"):
self.session.openWithCallback(self.backupDone,BackupScreen, runBackup = True)
elif (current == "system-restore"):
if os_path.exists(self.fullbackupfilename):
self.session.openWithCallback(self.startRestore, MessageBox, _("Are you sure you want to restore your Enigma2 backup?\nEnigma2 will restart after the restore"))
else:
self.session.open(MessageBox, _("Sorry no backups found!"), MessageBox.TYPE_INFO, timeout = 10)
elif (current == "ipkg-install"):
try:
from Plugins.Extensions.MediaScanner.plugin import main
main(self.session)
except:
self.session.open(MessageBox, _("Sorry MediaScanner is not installed!"), MessageBox.TYPE_INFO, timeout = 10)
elif (current == "advanced"):
self.session.open(UpdatePluginMenu, 1)
elif self.menu == 1:
if (current == "ipkg-manager"):
self.session.open(PacketManager, self.skin_path)
elif (current == "backuplocation"):
parts = [ (r.description, r.mountpoint, self.session) for r in harddiskmanager.getMountedPartitions(onlyhotplug = False)]
for x in parts:
if not access(x[1], F_OK|R_OK|W_OK) or x[1] == '/':
parts.remove(x)
for x in parts:
if x[1].startswith('/autofs/'):
parts.remove(x)
if len(parts):
self.session.openWithCallback(self.backuplocation_choosen, ChoiceBox, title = _("Please select medium to use as backup location"), list = parts)
elif (current == "backupfiles"):
self.session.openWithCallback(self.backupfiles_choosen,BackupSelection)
elif (current == "advancedrestore"):
self.session.open(RestoreMenu, self.skin_path)
elif (current == "ipkg-source"):
self.session.open(IPKGMenu, self.skin_path)
def backupfiles_choosen(self, ret):
self.backupdirs = ' '.join( config.plugins.configurationbackup.backupdirs.value )
def backuplocation_choosen(self, option):
if option is not None:
config.plugins.configurationbackup.backuplocation.value = str(option[1])
config.plugins.configurationbackup.backuplocation.save()
config.plugins.configurationbackup.save()
config.save()
self.createBackupfolders()
def runUpgrade(self, result):
if result:
self.session.open(UpdatePlugin, self.skin_path)
def createBackupfolders(self):
print "Creating backup folder if not already there..."
self.backuppath = getBackupPath()
try:
if (os_path.exists(self.backuppath) == False):
makedirs(self.backuppath)
except OSError:
self.session.open(MessageBox, _("Sorry, your backup destination is not writeable.\n\nPlease choose another one."), MessageBox.TYPE_INFO, timeout = 10)
def backupDone(self,retval = None):
if retval is True:
self.session.open(MessageBox, _("Backup done."), MessageBox.TYPE_INFO, timeout = 10)
else:
self.session.open(MessageBox, _("Backup failed."), MessageBox.TYPE_INFO, timeout = 10)
def startRestore(self, ret = False):
if (ret == True):
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 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)],
"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"],
{
"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["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 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 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 setStatus(self,status = None):
if status:
self.statuslist = []
divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/div-h.png"))
if status == 'update':
statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_PLUGINS, "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_PLUGINS, "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)
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:
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 runUpgrade(self, result):
if result:
self.session.openWithCallback(self.runUpgradeFinished, Ipkg, cmdList = self.cmdList)
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_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 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 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 buildEntryComponent(self, name, version, description, state):
divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/div-h.png"))
if state == 'installed':
installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_PLUGINS, "SystemPlugins/SoftwareManager/installed.png"))
return((name, version, description, state, installedpng, divpng))
elif state == 'upgradeable':
upgradeablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_PLUGINS, "SystemPlugins/SoftwareManager/upgradeable.png"))
return((name, version, description, state, upgradeablepng, divpng))
else:
installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_PLUGINS, "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 PluginManager(Screen, DreamInfoHandler):
lastDownloadDate = None
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
}
"""
def __init__(self, session, plugin_path, args = 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["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions", "InfobarEPGActions", "HelpActions" ],
{
"ok": self.handleCurrent,
"back": self.exit,
"red": self.exit,
"green": self.handleCurrent,
"yellow": self.handleSelected,
"showEventInfo": self.handleSelected,
"displayHelp": self.handleHelp,
}, -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.onShown.append(self.setWindowTitle)
self.onLayoutFinish.append(self.rebuildList)
def setWindowTitle(self):
self.setTitle(_("Plugin 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:
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 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_SKIN_IMAGE, "skin_default/div-h.png"))
if status == 'update':
statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_PLUGINS, "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_PLUGINS, "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_PLUGINS, "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)
else:
print "last update time < 1h"
self.startIpkgList()
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 startIpkgList(self):
if self.list_updating:
if not self.Console:
self.Console = Console()
cmd = "ipkg list"
self.Console.ePopen(cmd, self.IpkgList_Finished)
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 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)
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 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
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()
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)
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 buildEntryComponent(self, name, details, description, packagename, state, selected = False):
divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/div-h.png"))
if state == 'installed':
installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_PLUGINS, "SystemPlugins/SoftwareManager/installed.png"))
return((name, details, description, packagename, state, installedpng, divpng, selected))
elif state == 'installable':
installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_PLUGINS, "SystemPlugins/SoftwareManager/installable.png"))
return((name, details, description, packagename, state, installablepng, divpng, selected))
elif state == 'remove':
removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_PLUGINS, "SystemPlugins/SoftwareManager/remove.png"))
return((name, details, description, packagename, state, removepng, divpng, selected))
elif state == 'install':
installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_PLUGINS, "SystemPlugins/SoftwareManager/install.png"))
return((name, details, description, packagename, state, installpng, divpng, selected))
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 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_SKIN_IMAGE, "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 ))
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] }))
def runExecute(self, result):
if result:
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.detailsClosed(True)
if result:
quitMainloop(3)
def reloadPluginlist(self):
plugins.readPluginList(resolveFilename(SCOPE_PLUGINS))
class PluginManagerInfo(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):
Screen.__init__(self, session)
self.session = session
self.skin_path = plugin_path
self.cmdlist = cmdlist
self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"],
{
"ok": self.process,
"back": self.exit,
"red": self.exit,
"green": self.process,
}, -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.onShown.append(self.setWindowTitle)
self.onLayoutFinish.append(self.rebuildList)
def setWindowTitle(self):
self.setTitle(_("Plugin manager activity information"))
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.")
self.list.append(self.buildEntryComponent(action,info))
self['list'].setList(self.list)
self['list'].updateList(self.list)
def buildEntryComponent(self, action,info):
divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/div-h.png"))
upgradepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_PLUGINS, "SystemPlugins/SoftwareManager/upgrade.png"))
installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_PLUGINS, "SystemPlugins/SoftwareManager/install.png"))
removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_PLUGINS, "SystemPlugins/SoftwareManager/remove.png"))
if action == 'install':
return(( _('Installing'), info, installpng, divpng))
elif action == 'remove':
return(( _('Removing'), info, removepng, divpng))
else:
return(( _('Upgrading'), info, upgradepng, divpng))
def exit(self):
self.close(False)
def process(self):
self.close(True)
class PluginManagerHelp(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
],
"fonts": [gFont("Regular", 22),gFont("Regular", 18)],
"itemHeight": 52
}
"""
def __init__(self, session, plugin_path):
Screen.__init__(self, session)
self.session = session
self.skin_path = plugin_path
self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"],
{
"back": self.exit,
"red": self.exit,
}, -1)
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."))
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_SKIN_IMAGE, "skin_default/div-h.png"))
installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_PLUGINS, "SystemPlugins/SoftwareManager/installed.png"))
installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_PLUGINS, "SystemPlugins/SoftwareManager/installable.png"))
removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_PLUGINS, "SystemPlugins/SoftwareManager/remove.png"))
installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_PLUGINS, "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.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 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_PLUGINS, "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)
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 modificationCallback(self, res):
self.ipkg.write(res and "N" or "Y")
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 exitAnswer(self, result):
if result is not None and result:
quitMainloop(2)
self.close()
class IpkgInstaller(Screen):
skin = """
"""
def __init__(self, session, list):
Screen.__init__(self, session)
self.list = SelectionList()
self["list"] = self.list
for listindex in range(len(list)):
self.list.addSelection(list[listindex], list[listindex], listindex, True)
self["key_red"] = StaticText(_("Close"))
self["key_green"] = StaticText(_("Install"))
self["introduction"] = StaticText(_("Press OK to toggle the selection."))
self["actions"] = ActionMap(["OkCancelActions", "ColorActions"],
{
"ok": self.list.toggleSelection,
"cancel": self.close,
"red": self.close,
"green": self.install
}, -1)
def install(self):
list = self.list.getSelectionsList()
cmdList = []
for item in list:
cmdList.append((IpkgComponent.CMD_INSTALL, { "package": item[1] }))
self.session.open(Ipkg, cmdList = cmdList)
def filescan_open(list, session, **kwargs):
filelist = [x.path for x in list]
session.open(IpkgInstaller, filelist) # list
def filescan(**kwargs):
from Components.Scanner import Scanner, ScanPath
return \
Scanner(mimetypes = ["application/x-debian-package"],
paths_to_scan =
[
ScanPath(path = "ipk", with_subdirs = True),
ScanPath(path = "", with_subdirs = False),
],
name = "Ipkg",
description = _("Install extensions."),
openfnc = filescan_open, )
def UpgradeMain(session, **kwargs):
session.open(UpdatePluginMenu)
def startSetup(menuid):
if menuid != "setup":
return [ ]
return [(_("Software manager"), UpgradeMain, "software_manager", 50)]
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(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))
return list