1 from Plugins.Plugin import PluginDescriptor
2 from Screens.Console import Console
3 from Screens.ChoiceBox import ChoiceBox
4 from Screens.MessageBox import MessageBox
5 from Screens.Screen import Screen
6 from Screens.Ipkg import Ipkg
7 from Components.ActionMap import ActionMap, NumberActionMap
8 from Components.Input import Input
9 from Components.Ipkg import IpkgComponent
10 from Components.Sources.StaticText import StaticText
11 from Components.ScrollLabel import ScrollLabel
12 from Components.Pixmap import Pixmap
13 from Components.MenuList import MenuList
14 from Components.Sources.List import List
15 from Components.Slider import Slider
16 from Components.Harddisk import harddiskmanager
17 from Components.config import config,getConfigListEntry, ConfigSubsection, ConfigText, ConfigLocations, ConfigYesNo, ConfigSelection
18 from Components.ConfigList import ConfigListScreen
19 from Components.Console import Console
20 from Components.MultiContent import MultiContentEntryText, MultiContentEntryPixmapAlphaTest
21 from Components.SelectionList import SelectionList
22 from Components.PluginComponent import plugins
23 from Components.About import about
24 from Components.DreamInfoHandler import DreamInfoHandler
25 from Components.Language import language
26 from Components.AVSwitch import AVSwitch
27 from Components.Network import iNetwork
28 from Tools.Directories import pathExists, fileExists, resolveFilename, SCOPE_PLUGINS, SCOPE_CURRENT_PLUGIN, SCOPE_CURRENT_SKIN, SCOPE_METADIR
29 from Tools.LoadPixmap import LoadPixmap
30 from Tools.NumericalTextInput import NumericalTextInput
31 from enigma import eTimer, quitMainloop, RT_HALIGN_LEFT, RT_VALIGN_CENTER, eListboxPythonMultiContent, eListbox, gFont, getDesktop, ePicLoad, eRCInput, getPrevAsciiCode, eEnv
32 from cPickle import dump, load
33 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
34 from time import time, gmtime, strftime, localtime
35 from stat import ST_MTIME
36 from datetime import date
37 from twisted.web import client
38 from twisted.internet import reactor
40 from ImageWizard import ImageWizard
41 from BackupRestore import BackupSelection, RestoreMenu, BackupScreen, RestoreScreen, getBackupPath, getBackupFilename
42 from SoftwareTools import iSoftwareTools
44 config.plugins.configurationbackup = ConfigSubsection()
45 config.plugins.configurationbackup.backuplocation = ConfigText(default = '/media/hdd/', visible_width = 50, fixed_size = False)
46 config.plugins.configurationbackup.backupdirs = ConfigLocations(default=[eEnv.resolve('${sysconfdir}/enigma2/'), '/etc/network/interfaces', '/etc/wpa_supplicant.conf', '/etc/wpa_supplicant.ath0.conf', '/etc/wpa_supplicant.wlan0.conf', '/etc/resolv.conf', '/etc/default_gw', '/etc/hostname'])
48 config.plugins.softwaremanager = ConfigSubsection()
49 config.plugins.softwaremanager.overwriteConfigFiles = ConfigSelection(
51 ("Y", _("Yes, always")),
52 ("N", _("No, never")),
53 ("ask", _("Always ask"))
56 def write_cache(cache_file, cache_data):
58 if not os_path.isdir( os_path.dirname(cache_file) ):
60 mkdir( os_path.dirname(cache_file) )
62 print os_path.dirname(cache_file), 'is a file'
63 fd = open(cache_file, 'w')
64 dump(cache_data, fd, -1)
67 def valid_cache(cache_file, cache_ttl):
68 #See if the cache file exists and is still living
70 mtime = stat(cache_file)[ST_MTIME]
74 if (curr_time - mtime) > cache_ttl:
79 def load_cache(cache_file):
87 class UpdatePluginMenu(Screen):
89 <screen name="UpdatePluginMenu" position="center,center" size="610,410" title="Software management" >
90 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
91 <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
92 <ePixmap pixmap="skin_default/border_menu_350.png" position="5,50" zPosition="1" size="350,300" transparent="1" alphatest="on" />
93 <widget source="menu" render="Listbox" position="15,60" size="330,290" scrollbarMode="showOnDemand">
94 <convert type="TemplatedMultiContent">
96 MultiContentEntryText(pos = (2, 2), size = (330, 24), flags = RT_HALIGN_LEFT, text = 1), # index 0 is the MenuText,
98 "fonts": [gFont("Regular", 22)],
103 <widget source="menu" render="Listbox" position="360,50" size="240,300" scrollbarMode="showNever" selectionDisabled="1">
104 <convert type="TemplatedMultiContent">
106 MultiContentEntryText(pos = (2, 2), size = (240, 300), flags = RT_HALIGN_CENTER|RT_VALIGN_CENTER|RT_WRAP, text = 2), # index 2 is the Description,
108 "fonts": [gFont("Regular", 22)],
113 <widget source="status" render="Label" position="5,360" zPosition="10" size="600,50" halign="center" valign="center" font="Regular;22" transparent="1" shadowColor="black" shadowOffset="-1,-1" />
116 def __init__(self, session, args = 0):
117 Screen.__init__(self, session)
118 self.skin_path = plugin_path
121 self.oktext = _("\nPress OK on your remote control to continue.")
122 self.menutext = _("Press MENU on your remote control for additional options.")
123 self.infotext = _("Press INFO on your remote control for additional information.")
125 self.backupdirs = ' '.join( config.plugins.configurationbackup.backupdirs.value )
127 print "building menu entries"
128 self.list.append(("install-extensions", _("Manage extensions"), _("\nManage extensions or plugins for your Dreambox" ) + self.oktext, None))
129 self.list.append(("software-update", _("Software update"), _("\nOnline update of your Dreambox software." ) + self.oktext, None))
130 self.list.append(("software-restore", _("Software restore"), _("\nRestore your Dreambox with a new firmware." ) + self.oktext, None))
131 self.list.append(("system-backup", _("Backup system settings"), _("\nBackup your Dreambox settings." ) + self.oktext + "\n\n" + self.infotext, None))
132 self.list.append(("system-restore",_("Restore system settings"), _("\nRestore your Dreambox settings." ) + self.oktext, None))
133 self.list.append(("ipkg-install", _("Install local extension"), _("\nScan for local extensions and install them." ) + self.oktext, None))
134 for p in plugins.getPlugins(PluginDescriptor.WHERE_SOFTWAREMANAGER):
135 if p.__call__.has_key("SoftwareSupported"):
136 callFnc = p.__call__["SoftwareSupported"](None)
137 if callFnc is not None:
138 if p.__call__.has_key("menuEntryName"):
139 menuEntryName = p.__call__["menuEntryName"](None)
141 menuEntryName = _('Extended Software')
142 if p.__call__.has_key("menuEntryDescription"):
143 menuEntryDescription = p.__call__["menuEntryDescription"](None)
145 menuEntryDescription = _('Extended Software Plugin')
146 self.list.append(('default-plugin', menuEntryName, menuEntryDescription + self.oktext, callFnc))
147 if config.usage.setup_level.index >= 2: # expert+
148 self.list.append(("advanced", _("Advanced Options"), _("\nAdvanced options and settings." ) + self.oktext, None))
150 self.list.append(("advancedrestore", _("Advanced restore"), _("\nRestore your backups by date." ) + self.oktext, None))
151 self.list.append(("backuplocation", _("Choose backup location"), _("\nSelect your backup device.\nCurrent device: " ) + config.plugins.configurationbackup.backuplocation.value + self.oktext, None))
152 self.list.append(("backupfiles", _("Choose backup files"), _("Select files for backup.") + self.oktext + "\n\n" + self.infotext, None))
153 if config.usage.setup_level.index >= 2: # expert+
154 self.list.append(("ipkg-manager", _("Packet management"), _("\nView, install and remove available or installed packages." ) + self.oktext, None))
155 self.list.append(("ipkg-source",_("Choose upgrade source"), _("\nEdit the upgrade source address." ) + self.oktext, None))
156 for p in plugins.getPlugins(PluginDescriptor.WHERE_SOFTWAREMANAGER):
157 if p.__call__.has_key("AdvancedSoftwareSupported"):
158 callFnc = p.__call__["AdvancedSoftwareSupported"](None)
159 if callFnc is not None:
160 if p.__call__.has_key("menuEntryName"):
161 menuEntryName = p.__call__["menuEntryName"](None)
163 menuEntryName = _('Advanced Software')
164 if p.__call__.has_key("menuEntryDescription"):
165 menuEntryDescription = p.__call__["menuEntryDescription"](None)
167 menuEntryDescription = _('Advanced Software Plugin')
168 self.list.append(('advanced-plugin', menuEntryName, menuEntryDescription + self.oktext, callFnc))
170 self["menu"] = List(self.list)
171 self["key_red"] = StaticText(_("Close"))
172 self["status"] = StaticText(self.menutext)
174 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions", "InfobarEPGActions", "MenuActions"],
179 "menu": self.handleMenu,
180 "showEventInfo": self.handleInfo,
182 self.onLayoutFinish.append(self.layoutFinished)
183 self.backuppath = getBackupPath()
184 self.backupfile = getBackupFilename()
185 self.fullbackupfilename = self.backuppath + "/" + self.backupfile
186 self.onShown.append(self.setWindowTitle)
188 def layoutFinished(self):
190 self["menu"].index = idx
192 def setWindowTitle(self):
193 self.setTitle(_("Software management"))
196 iNetwork.stopPingConsole()
197 iSoftwareTools.cleanupSoftwareTools()
199 def getUpdateInfos(self):
201 if iSoftwareTools.NetworkConnectionAvailable == True:
202 if iSoftwareTools.list_updating is False:
203 if iSoftwareTools.available_updates is not 0:
204 self.text = _("There are at least ") + str(iSoftwareTools.available_updates) + _(" updates available.")
206 self.text = "" #_("There are no updates available.")
208 if iSoftwareTools.available_updates is not 0:
209 self.text = _("There are at least ") + str(iSoftwareTools.available_updates) + _(" updates available.")
211 self.text = "" #_("There are no updates available.")
212 self.text += "\n" + _("A search for available updates is currently in progress.")
214 self.text = _("No network connection available.")
215 self["status"].setText(self.text)
217 def handleMenu(self):
218 self.session.open(SoftwareManagerSetup)
220 def handleInfo(self):
221 current = self["menu"].getCurrent()
223 currentEntry = current[0]
224 if currentEntry in ("system-backup","backupfiles"):
225 self.session.open(SoftwareManagerInfo, mode = "backupinfo")
228 current = self["menu"].getCurrent()
230 currentEntry = current[0]
232 if (currentEntry == "software-update"):
233 self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to update your Dreambox?")+"\n"+_("\nAfter pressing OK, please wait!"))
234 elif (currentEntry == "software-restore"):
235 self.session.open(ImageWizard)
236 elif (currentEntry == "install-extensions"):
237 self.session.open(PluginManager, self.skin_path)
238 elif (currentEntry == "system-backup"):
239 self.session.openWithCallback(self.backupDone,BackupScreen, runBackup = True)
240 elif (currentEntry == "system-restore"):
241 if os_path.exists(self.fullbackupfilename):
242 self.session.openWithCallback(self.startRestore, MessageBox, _("Are you sure you want to restore your Enigma2 backup?\nEnigma2 will restart after the restore"))
244 self.session.open(MessageBox, _("Sorry no backups found!"), MessageBox.TYPE_INFO, timeout = 10)
245 elif (currentEntry == "ipkg-install"):
247 from Plugins.Extensions.MediaScanner.plugin import main
250 self.session.open(MessageBox, _("Sorry MediaScanner is not installed!"), MessageBox.TYPE_INFO, timeout = 10)
251 elif (currentEntry == "default-plugin"):
252 self.extended = current[3]
253 self.extended(self.session, None)
254 elif (currentEntry == "advanced"):
255 self.session.open(UpdatePluginMenu, 1)
257 if (currentEntry == "ipkg-manager"):
258 self.session.open(PacketManager, self.skin_path)
259 elif (currentEntry == "backuplocation"):
260 parts = [ (r.description, r.mountpoint, self.session) for r in harddiskmanager.getMountedPartitions(onlyhotplug = False)]
262 if not access(x[1], F_OK|R_OK|W_OK) or x[1] == '/':
265 self.session.openWithCallback(self.backuplocation_choosen, ChoiceBox, title = _("Please select medium to use as backup location"), list = parts)
266 elif (currentEntry == "backupfiles"):
267 self.session.openWithCallback(self.backupfiles_choosen,BackupSelection)
268 elif (currentEntry == "advancedrestore"):
269 self.session.open(RestoreMenu, self.skin_path)
270 elif (currentEntry == "ipkg-source"):
271 self.session.open(IPKGMenu, self.skin_path)
272 elif (currentEntry == "advanced-plugin"):
273 self.extended = current[3]
274 self.extended(self.session, None)
276 def backupfiles_choosen(self, ret):
277 self.backupdirs = ' '.join( config.plugins.configurationbackup.backupdirs.value )
278 config.plugins.configurationbackup.backupdirs.save()
279 config.plugins.configurationbackup.save()
282 def backuplocation_choosen(self, option):
283 oldpath = config.plugins.configurationbackup.backuplocation.getValue()
284 if option is not None:
285 config.plugins.configurationbackup.backuplocation.value = str(option[1])
286 config.plugins.configurationbackup.backuplocation.save()
287 config.plugins.configurationbackup.save()
289 newpath = config.plugins.configurationbackup.backuplocation.getValue()
290 if newpath != oldpath:
291 self.createBackupfolders()
293 def runUpgrade(self, result):
295 self.session.open(UpdatePlugin, self.skin_path)
297 def createBackupfolders(self):
298 print "Creating backup folder if not already there..."
299 self.backuppath = getBackupPath()
301 if (os_path.exists(self.backuppath) == False):
302 makedirs(self.backuppath)
304 self.session.open(MessageBox, _("Sorry, your backup destination is not writeable.\n\nPlease choose another one."), MessageBox.TYPE_INFO, timeout = 10)
306 def backupDone(self,retval = None):
308 self.session.open(MessageBox, _("Backup done."), MessageBox.TYPE_INFO, timeout = 10)
310 self.session.open(MessageBox, _("Backup failed."), MessageBox.TYPE_INFO, timeout = 10)
312 def startRestore(self, ret = False):
315 self.session.open(RestoreScreen, runRestore = True)
317 class SoftwareManagerSetup(Screen, ConfigListScreen):
320 <screen name="SoftwareManagerSetup" position="center,center" size="560,440" title="SoftwareManager setup">
321 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
322 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
323 <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" alphatest="on" />
324 <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" alphatest="on" />
325 <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
326 <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
327 <widget source="key_yellow" render="Label" position="280,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#a08500" transparent="1" />
328 <widget source="key_blue" render="Label" position="420,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#18188b" transparent="1" />
329 <widget name="config" position="5,50" size="550,350" scrollbarMode="showOnDemand" />
330 <ePixmap pixmap="skin_default/div-h.png" position="0,400" zPosition="1" size="560,2" />
331 <widget source="introduction" render="Label" position="5,410" size="550,30" zPosition="10" font="Regular;21" halign="center" valign="center" backgroundColor="#25062748" transparent="1" />
334 def __init__(self, session, skin_path = None):
335 Screen.__init__(self, session)
336 self.session = session
337 self.skin_path = skin_path
338 if self.skin_path == None:
339 self.skin_path = resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager")
341 self.onChangedEntry = [ ]
342 self.setup_title = _("Software manager setup")
343 self.overwriteConfigfilesEntry = None
346 ConfigListScreen.__init__(self, self.list, session = session, on_change = self.changedEntry)
348 self["actions"] = ActionMap(["SetupActions"],
350 "cancel": self.keyCancel,
354 self["key_red"] = StaticText(_("Cancel"))
355 self["key_green"] = StaticText(_("OK"))
356 self["key_yellow"] = StaticText()
357 self["key_blue"] = StaticText()
358 self["introduction"] = StaticText()
361 self.onLayoutFinish.append(self.layoutFinished)
363 def layoutFinished(self):
364 self.setTitle(self.setup_title)
366 def createSetup(self):
368 self.overwriteConfigfilesEntry = getConfigListEntry(_("Overwrite configuration files ?"), config.plugins.softwaremanager.overwriteConfigFiles)
369 self.list.append(self.overwriteConfigfilesEntry)
370 self["config"].list = self.list
371 self["config"].l.setSeperation(400)
372 self["config"].l.setList(self.list)
373 if not self.selectionChanged in self["config"].onSelectionChanged:
374 self["config"].onSelectionChanged.append(self.selectionChanged)
375 self.selectionChanged()
377 def selectionChanged(self):
378 if self["config"].getCurrent() == self.overwriteConfigfilesEntry:
379 self["introduction"].setText(_("Overwrite configuration files during software upgrade?"))
381 self["introduction"].setText("")
387 ConfigListScreen.keyLeft(self)
390 ConfigListScreen.keyRight(self)
392 def confirm(self, confirmed):
394 print "not confirmed"
400 self.session.openWithCallback(self.confirm, MessageBox, _("Use this settings?"), MessageBox.TYPE_YESNO, timeout = 20, default = True)
402 def cancelConfirm(self, result):
405 for x in self["config"].list:
410 if self["config"].isChanged():
411 self.session.openWithCallback(self.cancelConfirm, MessageBox, _("Really close without saving settings?"), MessageBox.TYPE_YESNO, timeout = 20, default = True)
416 def changedEntry(self):
417 for x in self.onChangedEntry:
419 self.selectionChanged()
421 def getCurrentEntry(self):
422 return self["config"].getCurrent()[0]
424 def getCurrentValue(self):
425 return str(self["config"].getCurrent()[1].value)
427 def createSummary(self):
428 from Screens.Setup import SetupSummary
432 class SoftwareManagerInfo(Screen):
434 <screen name="SoftwareManagerInfo" position="center,center" size="560,440" title="SoftwareManager information">
435 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
436 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
437 <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" alphatest="on" />
438 <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" alphatest="on" />
439 <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
440 <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
441 <widget source="key_yellow" render="Label" position="280,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#a08500" transparent="1" />
442 <widget source="key_blue" render="Label" position="420,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#18188b" transparent="1" />
443 <widget source="list" render="Listbox" position="5,50" size="550,340" scrollbarMode="showOnDemand" selectionDisabled="0">
444 <convert type="TemplatedMultiContent">
446 MultiContentEntryText(pos = (5, 0), size = (540, 26), font=0, flags = RT_HALIGN_LEFT | RT_HALIGN_CENTER, text = 0), # index 0 is the name
448 "fonts": [gFont("Regular", 24),gFont("Regular", 22)],
453 <ePixmap pixmap="skin_default/div-h.png" position="0,400" zPosition="1" size="560,2" />
454 <widget source="introduction" render="Label" position="5,410" size="550,30" zPosition="10" font="Regular;21" halign="center" valign="center" backgroundColor="#25062748" transparent="1" />
457 def __init__(self, session, skin_path = None, mode = None):
458 Screen.__init__(self, session)
459 self.session = session
461 self.skin_path = skin_path
462 if self.skin_path == None:
463 self.skin_path = resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager")
465 self["actions"] = ActionMap(["ShortcutActions", "WizardActions"],
472 self["list"] = List(self.list)
474 self["key_red"] = StaticText(_("Close"))
475 self["key_green"] = StaticText()
476 self["key_yellow"] = StaticText()
477 self["key_blue"] = StaticText()
478 self["introduction"] = StaticText()
480 self.onLayoutFinish.append(self.layoutFinished)
482 def layoutFinished(self):
483 self.setTitle(_("Softwaremanager information"))
484 if self.mode is not None:
488 if self.mode == "backupinfo":
490 backupfiles = config.plugins.configurationbackup.backupdirs.value
491 for entry in backupfiles:
493 self.list.append((entry,))
494 self['list'].setList(self.list)
497 class PluginManager(Screen, DreamInfoHandler):
500 <screen name="PluginManager" position="center,center" size="560,440" title="Extensions management" >
501 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
502 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
503 <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" alphatest="on" />
504 <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" alphatest="on" />
505 <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
506 <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
507 <widget source="key_yellow" render="Label" position="280,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#a08500" transparent="1" />
508 <widget source="key_blue" render="Label" position="420,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#18188b" transparent="1" />
509 <widget source="list" render="Listbox" position="5,50" size="550,360" scrollbarMode="showOnDemand">
510 <convert type="TemplatedMultiContent">
513 MultiContentEntryText(pos = (0, 1), size = (470, 24), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
514 MultiContentEntryText(pos = (0, 25), size = (470, 24), font=1, flags = RT_HALIGN_LEFT, text = 2), # index 2 is the description
515 MultiContentEntryPixmapAlphaTest(pos = (475, 0), size = (48, 48), png = 5), # index 5 is the status pixmap
516 MultiContentEntryPixmapAlphaTest(pos = (0, 49), size = (550, 2), png = 6), # index 6 is the div pixmap
519 MultiContentEntryText(pos = (30, 0), size = (500, 22), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
520 MultiContentEntryText(pos = (30, 22), size = (500, 16), font=2, flags = RT_HALIGN_LEFT, text = 1), # index 1 is the description
521 MultiContentEntryPixmapAlphaTest(pos = (0, 38), size = (550, 2), png = 3), # index 3 is the div pixmap
524 "fonts": [gFont("Regular", 22),gFont("Regular", 20),gFont("Regular", 16)],
529 <widget source="status" render="Label" position="5,410" zPosition="10" size="540,30" halign="center" valign="center" font="Regular;22" transparent="1" shadowColor="black" shadowOffset="-1,-1" />
532 def __init__(self, session, plugin_path = None, args = None):
533 Screen.__init__(self, session)
534 self.session = session
535 self.skin_path = plugin_path
536 if self.skin_path == None:
537 self.skin_path = resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager")
539 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions", "InfobarEPGActions", "HelpActions" ],
541 "ok": self.handleCurrent,
544 "green": self.handleCurrent,
545 "yellow": self.handleSelected,
546 "showEventInfo": self.handleSelected,
547 "displayHelp": self.handleHelp,
552 self.selectedFiles = []
553 self.categoryList = []
555 self["list"] = List(self.list)
556 self["key_red"] = StaticText(_("Close"))
557 self["key_green"] = StaticText("")
558 self["key_yellow"] = StaticText("")
559 self["key_blue"] = StaticText("")
560 self["status"] = StaticText("")
563 self.oktext = _("\nAfter pressing OK, please wait!")
564 if not self.selectionChanged in self["list"].onSelectionChanged:
565 self["list"].onSelectionChanged.append(self.selectionChanged)
568 self.currentSelectedTag = None
569 self.currentSelectedIndex = None
570 self.currentSelectedPackage = None
571 self.saved_currentSelectedPackage = None
573 self.onShown.append(self.setWindowTitle)
574 self.onLayoutFinish.append(self.getUpdateInfos)
576 def setWindowTitle(self):
577 self.setTitle(_("Extensions management"))
580 if self.currList == "packages":
581 self.currList = "category"
582 self.currentSelectedTag = None
583 self["list"].style = "category"
584 self['list'].setList(self.categoryList)
585 self["list"].setIndex(self.currentSelectedIndex)
586 self["list"].updateList(self.categoryList)
587 self.selectionChanged()
589 iSoftwareTools.cleanupSoftwareTools()
590 self.prepareInstall()
591 if len(self.cmdList):
592 self.session.openWithCallback(self.runExecute, PluginManagerInfo, self.skin_path, self.cmdList)
596 def handleHelp(self):
597 if self.currList != "status":
598 self.session.open(PluginManagerHelp, self.skin_path)
600 def setState(self,status = None):
602 self.currList = "status"
604 self["key_green"].setText("")
605 self["key_blue"].setText("")
606 self["key_yellow"].setText("")
607 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
608 if status == 'update':
609 statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgrade.png"))
610 self.statuslist.append(( _("Updating software catalog"), '', _("Searching for available updates. Please wait..." ),'', '', statuspng, divpng, None, '' ))
611 elif status == 'sync':
612 statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgrade.png"))
613 self.statuslist.append(( _("Package list update"), '', _("Searching for new installed or removed packages. Please wait..." ),'', '', statuspng, divpng, None, '' ))
614 elif status == 'error':
615 self["key_green"].setText(_("Continue"))
616 statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
617 self.statuslist.append(( _("Error"), '', _("There was an error downloading the packetlist. Please try again." ),'', '', statuspng, divpng, None, '' ))
618 self["list"].style = "default"
619 self['list'].setList(self.statuslist)
622 def getUpdateInfos(self):
623 if (iSoftwareTools.lastDownloadDate is not None and iSoftwareTools.NetworkConnectionAvailable is False):
626 self.setState('update')
627 iSoftwareTools.startSoftwareTools(self.getUpdateInfosCB)
629 def getUpdateInfosCB(self, retval = None):
630 if retval is not None:
632 if iSoftwareTools.available_updates is not 0:
633 self["status"].setText(_("There are at least ") + str(iSoftwareTools.available_updates) + _(" updates available."))
635 self["status"].setText(_("There are no updates available."))
637 elif retval is False:
638 if iSoftwareTools.lastDownloadDate is None:
639 self.setState('error')
640 if iSoftwareTools.NetworkConnectionAvailable:
641 self["status"].setText(_("Updatefeed not available."))
643 self["status"].setText(_("No network connection available."))
645 iSoftwareTools.lastDownloadDate = time()
646 iSoftwareTools.list_updating = True
647 self.setState('update')
648 iSoftwareTools.getUpdates(self.getUpdateInfosCB)
650 def rebuildList(self, retval = None):
651 if self.currentSelectedTag is None:
652 self.buildCategoryList()
654 self.buildPacketList(self.currentSelectedTag)
656 def selectionChanged(self):
657 current = self["list"].getCurrent()
658 self["status"].setText("")
660 if self.currList == "packages":
661 self["key_red"].setText(_("Back"))
662 if current[4] == 'installed':
663 self["key_green"].setText(_("Uninstall"))
664 elif current[4] == 'installable':
665 self["key_green"].setText(_("Install"))
666 if iSoftwareTools.NetworkConnectionAvailable is False:
667 self["key_green"].setText("")
668 elif current[4] == 'remove':
669 self["key_green"].setText(_("Undo uninstall"))
670 elif current[4] == 'install':
671 self["key_green"].setText(_("Undo install"))
672 if iSoftwareTools.NetworkConnectionAvailable is False:
673 self["key_green"].setText("")
674 self["key_yellow"].setText(_("View details"))
675 self["key_blue"].setText("")
676 if len(self.selectedFiles) == 0 and iSoftwareTools.available_updates is not 0:
677 self["status"].setText(_("There are at least ") + str(iSoftwareTools.available_updates) + _(" updates available."))
678 elif len(self.selectedFiles) is not 0:
679 self["status"].setText(str(len(self.selectedFiles)) + _(" packages selected."))
681 self["status"].setText(_("There are currently no outstanding actions."))
682 elif self.currList == "category":
683 self["key_red"].setText(_("Close"))
684 self["key_green"].setText("")
685 self["key_yellow"].setText("")
686 self["key_blue"].setText("")
687 if len(self.selectedFiles) == 0 and iSoftwareTools.available_updates is not 0:
688 self["status"].setText(_("There are at least ") + str(iSoftwareTools.available_updates) + _(" updates available."))
689 self["key_yellow"].setText(_("Update"))
690 elif len(self.selectedFiles) is not 0:
691 self["status"].setText(str(len(self.selectedFiles)) + _(" packages selected."))
692 self["key_yellow"].setText(_("Process"))
694 self["status"].setText(_("There are currently no outstanding actions."))
696 def getSelectionState(self, detailsFile):
697 for entry in self.selectedFiles:
698 if entry[0] == detailsFile:
702 def handleCurrent(self):
703 current = self["list"].getCurrent()
705 if self.currList == "category":
706 self.currentSelectedIndex = self["list"].index
707 selectedTag = current[2]
708 self.buildPacketList(selectedTag)
709 elif self.currList == "packages":
710 if current[7] is not '':
711 idx = self["list"].getIndex()
712 detailsFile = self.list[idx][1]
713 if self.list[idx][7] == True:
714 for entry in self.selectedFiles:
715 if entry[0] == detailsFile:
716 self.selectedFiles.remove(entry)
718 alreadyinList = False
719 for entry in self.selectedFiles:
720 if entry[0] == detailsFile:
722 if not alreadyinList:
723 if (iSoftwareTools.NetworkConnectionAvailable is False and current[4] in ('installable','install')):
726 self.selectedFiles.append((detailsFile,current[4],current[3]))
727 self.currentSelectedPackage = ((detailsFile,current[4],current[3]))
728 if current[4] == 'installed':
729 self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'remove', True)
730 elif current[4] == 'installable':
731 if iSoftwareTools.NetworkConnectionAvailable:
732 self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'install', True)
733 elif current[4] == 'remove':
734 self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'installed', False)
735 elif current[4] == 'install':
736 if iSoftwareTools.NetworkConnectionAvailable:
737 self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'installable',False)
738 self["list"].setList(self.list)
739 self["list"].setIndex(idx)
740 self["list"].updateList(self.list)
741 self.selectionChanged()
742 elif self.currList == "status":
743 iSoftwareTools.lastDownloadDate = time()
744 iSoftwareTools.list_updating = True
745 self.setState('update')
746 iSoftwareTools.getUpdates(self.getUpdateInfosCB)
748 def handleSelected(self):
749 current = self["list"].getCurrent()
751 if self.currList == "packages":
752 if current[7] is not '':
753 detailsfile = iSoftwareTools.directory[0] + "/" + current[1]
754 if (os_path.exists(detailsfile) == True):
755 self.saved_currentSelectedPackage = self.currentSelectedPackage
756 self.session.openWithCallback(self.detailsClosed, PluginDetails, self.skin_path, current)
758 self.session.open(MessageBox, _("Sorry, no Details available!"), MessageBox.TYPE_INFO, timeout = 10)
759 elif self.currList == "category":
760 self.prepareInstall()
761 if len(self.cmdList):
762 self.session.openWithCallback(self.runExecute, PluginManagerInfo, self.skin_path, self.cmdList)
764 def detailsClosed(self, result = None):
765 if result is not None:
766 if result is not False:
767 self.setState('sync')
768 iSoftwareTools.lastDownloadDate = time()
769 for entry in self.selectedFiles:
770 if entry == self.saved_currentSelectedPackage:
771 self.selectedFiles.remove(entry)
772 iSoftwareTools.startIpkgListInstalled(self.rebuildList)
774 def buildEntryComponent(self, name, details, description, packagename, state, selected = False):
775 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
776 installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installed.png"))
777 installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installable.png"))
778 removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
779 installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/install.png"))
780 if state == 'installed':
781 return((name, details, description, packagename, state, installedpng, divpng, selected))
782 elif state == 'installable':
783 return((name, details, description, packagename, state, installablepng, divpng, selected))
784 elif state == 'remove':
785 return((name, details, description, packagename, state, removepng, divpng, selected))
786 elif state == 'install':
787 return((name, details, description, packagename, state, installpng, divpng, selected))
789 def buildPacketList(self, categorytag = None):
790 if categorytag is not None:
791 self.currList = "packages"
792 self.currentSelectedTag = categorytag
794 for package in iSoftwareTools.packagesIndexlist[:]:
795 prerequisites = package[0]["prerequisites"]
796 if prerequisites.has_key("tag"):
797 for foundtag in prerequisites["tag"]:
798 if categorytag == foundtag:
799 attributes = package[0]["attributes"]
800 if attributes.has_key("packagetype"):
801 if attributes["packagetype"] == "internal":
803 self.packetlist.append([attributes["name"], attributes["details"], attributes["shortdescription"], attributes["packagename"]])
805 self.packetlist.append([attributes["name"], attributes["details"], attributes["shortdescription"], attributes["packagename"]])
807 for x in self.packetlist:
810 details = x[1].strip()
811 description = x[2].strip()
812 if description == "":
813 description = "No description available."
814 packagename = x[3].strip()
815 selectState = self.getSelectionState(details)
816 if iSoftwareTools.installed_packetlist.has_key(packagename):
817 if selectState == True:
821 self.list.append(self.buildEntryComponent(name, _(details), _(description), packagename, status, selected = selectState))
823 if selectState == True:
826 status = "installable"
827 self.list.append(self.buildEntryComponent(name, _(details), _(description), packagename, status, selected = selectState))
829 self.list.sort(key=lambda x: x[0])
830 self["list"].style = "default"
831 self['list'].setList(self.list)
832 self["list"].updateList(self.list)
833 self.selectionChanged()
835 def buildCategoryList(self):
836 self.currList = "category"
838 self.categoryList = []
839 for package in iSoftwareTools.packagesIndexlist[:]:
840 prerequisites = package[0]["prerequisites"]
841 if prerequisites.has_key("tag"):
842 for foundtag in prerequisites["tag"]:
843 attributes = package[0]["attributes"]
844 if foundtag not in self.categories:
845 self.categories.append(foundtag)
846 self.categoryList.append(self.buildCategoryComponent(foundtag))
847 self.categoryList.sort(key=lambda x: x[0])
848 self["list"].style = "category"
849 self['list'].setList(self.categoryList)
850 self["list"].updateList(self.categoryList)
851 self.selectionChanged()
853 def buildCategoryComponent(self, tag = None):
854 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
857 return(( _("System"), _("View list of available system extensions" ), tag, divpng ))
859 return(( _("Skins"), _("View list of available skins" ), tag, divpng ))
860 elif tag == 'Recording':
861 return(( _("Recordings"), _("View list of available recording extensions" ), tag, divpng ))
862 elif tag == 'Network':
863 return(( _("Network"), _("View list of available networking extensions" ), tag, divpng ))
865 return(( _("CommonInterface"), _("View list of available CommonInterface extensions" ), tag, divpng ))
866 elif tag == 'Default':
867 return(( _("Default Settings"), _("View list of available default settings" ), tag, divpng ))
869 return(( _("Satellite equipment"), _("View list of available Satellite equipment extensions." ), tag, divpng ))
870 elif tag == 'Software':
871 return(( _("Software"), _("View list of available software extensions" ), tag, divpng ))
872 elif tag == 'Multimedia':
873 return(( _("Multimedia"), _("View list of available multimedia extensions." ), tag, divpng ))
874 elif tag == 'Display':
875 return(( _("Display and Userinterface"), _("View list of available Display and Userinterface extensions." ), tag, divpng ))
877 return(( _("Electronic Program Guide"), _("View list of available EPG extensions." ), tag, divpng ))
878 elif tag == 'Communication':
879 return(( _("Communication"), _("View list of available communication extensions." ), tag, divpng ))
880 else: # dynamically generate non existent tags
881 return(( str(tag), _("View list of available ") + str(tag) + _(" extensions." ), tag, divpng ))
883 def prepareInstall(self):
885 if iSoftwareTools.available_updates > 0:
886 self.cmdList.append((IpkgComponent.CMD_UPGRADE, { "test_only": False }))
887 if self.selectedFiles and len(self.selectedFiles):
888 for plugin in self.selectedFiles:
889 detailsfile = iSoftwareTools.directory[0] + "/" + plugin[0]
890 if (os_path.exists(detailsfile) == True):
891 iSoftwareTools.fillPackageDetails(plugin[0])
892 self.package = iSoftwareTools.packageDetails[0]
893 if self.package[0].has_key("attributes"):
894 self.attributes = self.package[0]["attributes"]
895 if self.attributes.has_key("package"):
896 self.packagefiles = self.attributes["package"]
897 if plugin[1] == 'installed':
898 if self.packagefiles:
899 for package in self.packagefiles[:]:
900 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": package["name"] }))
902 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": plugin[2] }))
904 if self.packagefiles:
905 for package in self.packagefiles[:]:
906 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package["name"] }))
908 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": plugin[2] }))
910 if plugin[1] == 'installed':
911 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": plugin[2] }))
913 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": plugin[2] }))
915 def runExecute(self, result = None):
916 if result is not None:
917 if result[0] is True:
918 self.session.openWithCallback(self.runExecuteFinished, Ipkg, cmdList = self.cmdList)
919 elif result[0] is False:
920 self.cmdList = result[1]
921 self.session.openWithCallback(self.runExecuteFinished, Ipkg, cmdList = self.cmdList)
925 def runExecuteFinished(self):
926 self.reloadPluginlist()
927 restartRequired = plugins.restartRequired
929 self.session.openWithCallback(self.ExecuteReboot, MessageBox, _("Install or remove finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
931 self.selectedFiles = []
932 self.detailsClosed(True)
934 def ExecuteReboot(self, result):
938 self.selectedFiles = []
939 self.detailsClosed(True)
941 def reloadPluginlist(self):
942 plugins.readPluginList(resolveFilename(SCOPE_PLUGINS))
945 class PluginManagerInfo(Screen):
947 <screen name="PluginManagerInfo" position="center,center" size="560,450" title="Plugin manager activity information" >
948 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
949 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
950 <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
951 <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
952 <widget source="list" render="Listbox" position="5,50" size="550,350" scrollbarMode="showOnDemand" selectionDisabled="1">
953 <convert type="TemplatedMultiContent">
955 MultiContentEntryText(pos = (50, 0), size = (150, 26), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
956 MultiContentEntryText(pos = (50, 27), size = (540, 23), font=1, flags = RT_HALIGN_LEFT, text = 1), # index 1 is the state
957 MultiContentEntryPixmapAlphaTest(pos = (0, 1), size = (48, 48), png = 2), # index 2 is the status pixmap
958 MultiContentEntryPixmapAlphaTest(pos = (0, 48), size = (550, 2), png = 3), # index 3 is the div pixmap
960 "fonts": [gFont("Regular", 24),gFont("Regular", 22)],
965 <ePixmap pixmap="skin_default/div-h.png" position="0,404" zPosition="10" size="560,2" transparent="1" alphatest="on" />
966 <widget source="status" render="Label" position="5,408" zPosition="10" size="550,44" halign="center" valign="center" font="Regular;22" transparent="1" shadowColor="black" shadowOffset="-1,-1" />
969 def __init__(self, session, plugin_path, cmdlist = None):
970 Screen.__init__(self, session)
971 self.session = session
972 self.skin_path = plugin_path
973 self.cmdlist = cmdlist
975 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"],
977 "ok": self.process_all,
980 "green": self.process_extensions,
984 self["list"] = List(self.list)
985 self["key_red"] = StaticText(_("Cancel"))
986 self["key_green"] = StaticText(_("Only extensions."))
987 self["status"] = StaticText(_("Following tasks will be done after you press OK!"))
989 self.onShown.append(self.setWindowTitle)
990 self.onLayoutFinish.append(self.rebuildList)
992 def setWindowTitle(self):
993 self.setTitle(_("Plugin manager activity information"))
995 def rebuildList(self):
997 if self.cmdlist is not None:
998 for entry in self.cmdlist:
1010 info = args['package']
1012 info = args['package']
1014 info = _("Dreambox software because updates are available.")
1016 self.list.append(self.buildEntryComponent(action,info))
1017 self['list'].setList(self.list)
1018 self['list'].updateList(self.list)
1020 def buildEntryComponent(self, action,info):
1021 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
1022 upgradepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgrade.png"))
1023 installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/install.png"))
1024 removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
1025 if action == 'install':
1026 return(( _('Installing'), info, installpng, divpng))
1027 elif action == 'remove':
1028 return(( _('Removing'), info, removepng, divpng))
1030 return(( _('Upgrading'), info, upgradepng, divpng))
1035 def process_all(self):
1036 self.close((True,None))
1038 def process_extensions(self):
1040 if self.cmdlist is not None:
1041 for entry in self.cmdlist:
1043 if entry[0] in (0,2):
1044 self.list.append((entry))
1045 self.close((False,self.list))
1048 class PluginManagerHelp(Screen):
1050 <screen name="PluginManagerHelp" position="center,center" size="560,450" title="Plugin manager help" >
1051 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1052 <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
1053 <widget source="list" render="Listbox" position="5,50" size="550,350" scrollbarMode="showOnDemand" selectionDisabled="1">
1054 <convert type="TemplatedMultiContent">
1056 MultiContentEntryText(pos = (50, 0), size = (540, 26), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
1057 MultiContentEntryText(pos = (50, 27), size = (540, 23), font=1, flags = RT_HALIGN_LEFT, text = 1), # index 1 is the state
1058 MultiContentEntryPixmapAlphaTest(pos = (0, 1), size = (48, 48), png = 2), # index 2 is the status pixmap
1059 MultiContentEntryPixmapAlphaTest(pos = (0, 48), size = (550, 2), png = 3), # index 3 is the div pixmap
1061 "fonts": [gFont("Regular", 24),gFont("Regular", 22)],
1066 <ePixmap pixmap="skin_default/div-h.png" position="0,404" zPosition="10" size="560,2" transparent="1" alphatest="on" />
1067 <widget source="status" render="Label" position="5,408" zPosition="10" size="550,44" halign="center" valign="center" font="Regular;22" transparent="1" shadowColor="black" shadowOffset="-1,-1" />
1070 def __init__(self, session, plugin_path):
1071 Screen.__init__(self, session)
1072 self.session = session
1073 self.skin_path = plugin_path
1075 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"],
1082 self["list"] = List(self.list)
1083 self["key_red"] = StaticText(_("Close"))
1084 self["status"] = StaticText(_("A small overview of the available icon states and actions."))
1086 self.onShown.append(self.setWindowTitle)
1087 self.onLayoutFinish.append(self.rebuildList)
1089 def setWindowTitle(self):
1090 self.setTitle(_("Plugin manager help"))
1092 def rebuildList(self):
1094 self.list.append(self.buildEntryComponent('install'))
1095 self.list.append(self.buildEntryComponent('installable'))
1096 self.list.append(self.buildEntryComponent('installed'))
1097 self.list.append(self.buildEntryComponent('remove'))
1098 self['list'].setList(self.list)
1099 self['list'].updateList(self.list)
1101 def buildEntryComponent(self, state):
1102 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
1103 installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installed.png"))
1104 installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installable.png"))
1105 removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
1106 installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/install.png"))
1108 if state == 'installed':
1109 return(( _('This plugin is installed.'), _('You can remove this plugin.'), installedpng, divpng))
1110 elif state == 'installable':
1111 return(( _('This plugin is not installed.'), _('You can install this plugin.'), installablepng, divpng))
1112 elif state == 'install':
1113 return(( _('This plugin will be installed.'), _('You can cancel the installation.'), installpng, divpng))
1114 elif state == 'remove':
1115 return(( _('This plugin will be removed.'), _('You can cancel the removal.'), removepng, divpng))
1121 class PluginDetails(Screen, DreamInfoHandler):
1123 <screen name="PluginDetails" position="center,center" size="600,440" title="Plugin details" >
1124 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1125 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1126 <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
1127 <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
1128 <widget source="author" render="Label" position="10,50" size="500,25" zPosition="10" font="Regular;21" transparent="1" />
1129 <widget name="statuspic" position="550,40" size="48,48" alphatest="on"/>
1130 <widget name="divpic" position="0,80" size="600,2" alphatest="on"/>
1131 <widget name="detailtext" position="10,90" size="270,330" zPosition="10" font="Regular;21" transparent="1" halign="left" valign="top"/>
1132 <widget name="screenshot" position="290,90" size="300,330" alphatest="on"/>
1134 def __init__(self, session, plugin_path, packagedata = None):
1135 Screen.__init__(self, session)
1136 self.skin_path = plugin_path
1137 self.language = language.getLanguage()[:2] # getLanguage returns e.g. "fi_FI" for "language_country"
1138 self.attributes = None
1139 DreamInfoHandler.__init__(self, self.statusCallback, blocking = False)
1140 self.directory = resolveFilename(SCOPE_METADIR)
1142 self.pluginname = packagedata[0]
1143 self.details = packagedata[1]
1144 self.pluginstate = packagedata[4]
1145 self.statuspicinstance = packagedata[5]
1146 self.divpicinstance = packagedata[6]
1147 self.fillPackageDetails(self.details)
1151 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"],
1157 "down": self.pageDown,
1158 "left": self.pageUp,
1159 "right": self.pageDown,
1162 self["key_red"] = StaticText(_("Close"))
1163 self["key_green"] = StaticText("")
1164 self["author"] = StaticText()
1165 self["statuspic"] = Pixmap()
1166 self["divpic"] = Pixmap()
1167 self["screenshot"] = Pixmap()
1168 self["detailtext"] = ScrollLabel()
1170 self["statuspic"].hide()
1171 self["screenshot"].hide()
1172 self["divpic"].hide()
1174 self.package = self.packageDetails[0]
1175 if self.package[0].has_key("attributes"):
1176 self.attributes = self.package[0]["attributes"]
1179 self.oktext = _("\nAfter pressing OK, please wait!")
1180 self.picload = ePicLoad()
1181 self.picload.PictureData.get().append(self.paintScreenshotPixmapCB)
1182 self.onShown.append(self.setWindowTitle)
1183 self.onLayoutFinish.append(self.setInfos)
1185 def setWindowTitle(self):
1186 self.setTitle(_("Details for plugin: ") + self.pluginname )
1192 self["detailtext"].pageUp()
1195 self["detailtext"].pageDown()
1197 def statusCallback(self, status, progress):
1201 if self.attributes.has_key("screenshot"):
1202 self.loadThumbnail(self.attributes)
1204 if self.attributes.has_key("name"):
1205 self.pluginname = self.attributes["name"]
1207 self.pluginname = _("unknown")
1209 if self.attributes.has_key("author"):
1210 self.author = self.attributes["author"]
1212 self.author = _("unknown")
1214 if self.attributes.has_key("description"):
1215 self.description = _(self.attributes["description"].replace("\\n", "\n"))
1217 self.description = _("No description available.")
1219 self["author"].setText(_("Author: ") + self.author)
1220 self["detailtext"].setText(_(self.description))
1221 if self.pluginstate in ('installable', 'install'):
1222 if iSoftwareTools.NetworkConnectionAvailable:
1223 self["key_green"].setText(_("Install"))
1225 self["key_green"].setText("")
1227 self["key_green"].setText(_("Remove"))
1229 def loadThumbnail(self, entry):
1231 if entry.has_key("screenshot"):
1232 thumbnailUrl = entry["screenshot"]
1233 if self.language == "de":
1234 if thumbnailUrl[-7:] == "_en.jpg":
1235 thumbnailUrl = thumbnailUrl[:-7] + "_de.jpg"
1237 if thumbnailUrl is not None:
1238 self.thumbnail = "/tmp/" + thumbnailUrl.split('/')[-1]
1239 print "[PluginDetails] downloading screenshot " + thumbnailUrl + " to " + self.thumbnail
1240 if iSoftwareTools.NetworkConnectionAvailable:
1241 client.downloadPage(thumbnailUrl,self.thumbnail).addCallback(self.setThumbnail).addErrback(self.fetchFailed)
1243 self.setThumbnail(noScreenshot = True)
1245 self.setThumbnail(noScreenshot = True)
1247 def setThumbnail(self, noScreenshot = False):
1248 if not noScreenshot:
1249 filename = self.thumbnail
1251 filename = resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/noprev.png")
1253 sc = AVSwitch().getFramebufferScale()
1254 self.picload.setPara((self["screenshot"].instance.size().width(), self["screenshot"].instance.size().height(), sc[0], sc[1], False, 1, "#00000000"))
1255 self.picload.startDecode(filename)
1257 if self.statuspicinstance != None:
1258 self["statuspic"].instance.setPixmap(self.statuspicinstance.__deref__())
1259 self["statuspic"].show()
1260 if self.divpicinstance != None:
1261 self["divpic"].instance.setPixmap(self.divpicinstance.__deref__())
1262 self["divpic"].show()
1264 def paintScreenshotPixmapCB(self, picInfo=None):
1265 ptr = self.picload.getData()
1267 self["screenshot"].instance.setPixmap(ptr.__deref__())
1268 self["screenshot"].show()
1270 self.setThumbnail(noScreenshot = True)
1273 if self.attributes.has_key("package"):
1274 self.packagefiles = self.attributes["package"]
1276 if self.pluginstate in ('installed', 'remove'):
1277 if self.packagefiles:
1278 for package in self.packagefiles[:]:
1279 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": package["name"] }))
1280 if len(self.cmdList):
1281 self.session.openWithCallback(self.runRemove, MessageBox, _("Do you want to remove the package:\n") + self.pluginname + "\n" + self.oktext)
1283 if iSoftwareTools.NetworkConnectionAvailable:
1284 if self.packagefiles:
1285 for package in self.packagefiles[:]:
1286 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package["name"] }))
1287 if len(self.cmdList):
1288 self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to install the package:\n") + self.pluginname + "\n" + self.oktext)
1290 def runUpgrade(self, result):
1292 self.session.openWithCallback(self.runUpgradeFinished, Ipkg, cmdList = self.cmdList)
1294 def runUpgradeFinished(self):
1295 self.reloadPluginlist()
1296 restartRequired = plugins.restartRequired
1298 self.session.openWithCallback(self.UpgradeReboot, MessageBox, _("Installation finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
1301 def UpgradeReboot(self, result):
1307 def runRemove(self, result):
1309 self.session.openWithCallback(self.runRemoveFinished, Ipkg, cmdList = self.cmdList)
1311 def runRemoveFinished(self):
1314 def reloadPluginlist(self):
1315 plugins.readPluginList(resolveFilename(SCOPE_PLUGINS))
1317 def fetchFailed(self,string):
1318 self.setThumbnail(noScreenshot = True)
1319 print "[PluginDetails] fetch failed " + string.getErrorMessage()
1322 class UpdatePlugin(Screen):
1324 <screen name="UpdatePlugin" position="center,center" size="550,300" title="Software update" >
1325 <widget name="activityslider" position="0,0" size="550,5" />
1326 <widget name="slider" position="0,150" size="550,30" />
1327 <widget source="package" render="Label" position="10,30" size="540,20" font="Regular;18" halign="center" valign="center" backgroundColor="#25062748" transparent="1" />
1328 <widget source="status" render="Label" position="10,180" size="540,100" font="Regular;20" halign="center" valign="center" backgroundColor="#25062748" transparent="1" />
1331 def __init__(self, session, args = None):
1332 Screen.__init__(self, session)
1334 self.sliderPackages = { "dreambox-dvb-modules": 1, "enigma2": 2, "tuxbox-image-info": 3 }
1336 self.slider = Slider(0, 4)
1337 self["slider"] = self.slider
1338 self.activityslider = Slider(0, 100)
1339 self["activityslider"] = self.activityslider
1340 self.status = StaticText(_("Please wait..."))
1341 self["status"] = self.status
1342 self.package = StaticText(_("Verifying your internet connection..."))
1343 self["package"] = self.package
1344 self.oktext = _("Press OK on your remote control to continue.")
1348 self.processed_packages = []
1351 self.activityTimer = eTimer()
1352 self.activityTimer.callback.append(self.doActivityTimer)
1354 self.ipkg = IpkgComponent()
1355 self.ipkg.addCallback(self.ipkgCallback)
1357 self.updating = False
1359 self["actions"] = ActionMap(["WizardActions"],
1365 iNetwork.checkNetworkState(self.checkNetworkCB)
1366 self.onClose.append(self.cleanup)
1369 iNetwork.stopPingConsole()
1371 def checkNetworkCB(self,data):
1372 if data is not None:
1374 self.updating = True
1375 self.activityTimer.start(100, False)
1376 self.package.setText(_("Package list update"))
1377 self.status.setText(_("Upgrading Dreambox... Please wait"))
1378 self.ipkg.startCmd(IpkgComponent.CMD_UPDATE)
1380 self.package.setText(_("Your network is not working. Please try again."))
1381 self.status.setText(self.oktext)
1383 def doActivityTimer(self):
1385 if self.activity == 100:
1387 self.activityslider.setValue(self.activity)
1389 def ipkgCallback(self, event, param):
1390 if event == IpkgComponent.EVENT_DOWNLOAD:
1391 self.status.setText(_("Downloading"))
1392 elif event == IpkgComponent.EVENT_UPGRADE:
1393 if self.sliderPackages.has_key(param):
1394 self.slider.setValue(self.sliderPackages[param])
1395 self.package.setText(param)
1396 self.status.setText(_("Upgrading"))
1397 if not param in self.processed_packages:
1398 self.processed_packages.append(param)
1400 elif event == IpkgComponent.EVENT_INSTALL:
1401 self.package.setText(param)
1402 self.status.setText(_("Installing"))
1403 if not param in self.processed_packages:
1404 self.processed_packages.append(param)
1406 elif event == IpkgComponent.EVENT_REMOVE:
1407 self.package.setText(param)
1408 self.status.setText(_("Removing"))
1409 if not param in self.processed_packages:
1410 self.processed_packages.append(param)
1412 elif event == IpkgComponent.EVENT_CONFIGURING:
1413 self.package.setText(param)
1414 self.status.setText(_("Configuring"))
1416 elif event == IpkgComponent.EVENT_MODIFIED:
1417 if config.plugins.softwaremanager.overwriteConfigFiles.value in ("N", "Y"):
1418 self.ipkg.write(True and config.plugins.softwaremanager.overwriteConfigFiles.value)
1420 self.session.openWithCallback(
1421 self.modificationCallback,
1423 _("A configuration file (%s) was modified since Installation.\nDo you want to keep your version?") % (param)
1425 elif event == IpkgComponent.EVENT_ERROR:
1427 elif event == IpkgComponent.EVENT_DONE:
1429 self.updating = False
1430 self.ipkg.startCmd(IpkgComponent.CMD_UPGRADE, args = {'test_only': False})
1431 elif self.error == 0:
1432 self.slider.setValue(4)
1434 self.activityTimer.stop()
1435 self.activityslider.setValue(0)
1437 self.package.setText(_("Done - Installed or upgraded %d packages") % self.packages)
1438 self.status.setText(self.oktext)
1440 self.activityTimer.stop()
1441 self.activityslider.setValue(0)
1442 error = _("your dreambox might be unusable now. Please consult the manual for further assistance before rebooting your dreambox.")
1443 if self.packages == 0:
1444 error = _("No packages were upgraded yet. So you can check your network and try again.")
1446 error = _("Your dreambox isn't connected to the internet properly. Please check it and try again.")
1447 self.status.setText(_("Error") + " - " + error)
1448 #print event, "-", param
1451 def modificationCallback(self, res):
1452 self.ipkg.write(res and "N" or "Y")
1455 if not self.ipkg.isRunning():
1456 if self.packages != 0 and self.error == 0:
1457 self.session.openWithCallback(self.exitAnswer, MessageBox, _("Upgrade finished.") +" "+_("Do you want to reboot your Dreambox?"))
1461 if not self.updating:
1464 def exitAnswer(self, result):
1465 if result is not None and result:
1471 class IPKGMenu(Screen):
1473 <screen name="IPKGMenu" position="center,center" size="560,400" title="Select upgrade source to edit." >
1474 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1475 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1476 <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
1477 <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
1478 <widget name="filelist" position="5,50" size="550,340" scrollbarMode="showOnDemand" />
1481 def __init__(self, session, plugin_path):
1482 Screen.__init__(self, session)
1483 self.skin_path = plugin_path
1485 self["key_red"] = StaticText(_("Close"))
1486 self["key_green"] = StaticText(_("Edit"))
1495 self["actions"] = NumberActionMap(["SetupActions"],
1498 "cancel": self.keyCancel
1501 self["shortcuts"] = ActionMap(["ShortcutActions"],
1503 "red": self.keyCancel,
1504 "green": self.KeyOk,
1507 self["filelist"] = MenuList(self.flist)
1509 self.onLayoutFinish.append(self.layoutFinished)
1511 def layoutFinished(self):
1512 self.setWindowTitle()
1514 def setWindowTitle(self):
1515 self.setTitle(_("Select upgrade source to edit."))
1517 def fill_list(self):
1519 self.path = '/etc/opkg/'
1520 if (os_path.exists(self.path) == False):
1523 for file in listdir(self.path):
1524 if (file.endswith(".conf")):
1525 if file != 'arch.conf':
1526 self.flist.append((file))
1528 self["filelist"].l.setList(self.flist)
1531 if (self.exe == False) and (self.entry == True):
1532 self.sel = self["filelist"].getCurrent()
1533 self.val = self.path + self.sel
1534 self.session.open(IPKGSource, self.val)
1536 def keyCancel(self):
1543 class IPKGSource(Screen):
1545 <screen name="IPKGSource" position="center,center" size="560,80" title="Edit upgrade source url." >
1546 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1547 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1548 <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
1549 <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
1550 <widget name="text" position="5,50" size="550,25" font="Regular;20" backgroundColor="background" foregroundColor="#cccccc" />
1553 def __init__(self, session, configfile = None):
1554 Screen.__init__(self, session)
1555 self.session = session
1556 self.configfile = configfile
1560 fp = file(configfile, 'r')
1561 sources = fp.readlines()
1568 desk = getDesktop(0)
1569 x= int(desk.size().width())
1570 y= int(desk.size().height())
1572 self["key_red"] = StaticText(_("Cancel"))
1573 self["key_green"] = StaticText(_("Save"))
1576 self["text"] = Input(text, maxSize=False, type=Input.TEXT)
1578 self["text"] = Input(text, maxSize=False, visible_width = 55, type=Input.TEXT)
1580 self["actions"] = NumberActionMap(["WizardActions", "InputActions", "TextEntryActions", "KeyboardInputActions","ShortcutActions"],
1586 "left": self.keyLeft,
1587 "right": self.keyRight,
1588 "home": self.keyHome,
1590 "deleteForward": self.keyDeleteForward,
1591 "deleteBackward": self.keyDeleteBackward,
1592 "1": self.keyNumberGlobal,
1593 "2": self.keyNumberGlobal,
1594 "3": self.keyNumberGlobal,
1595 "4": self.keyNumberGlobal,
1596 "5": self.keyNumberGlobal,
1597 "6": self.keyNumberGlobal,
1598 "7": self.keyNumberGlobal,
1599 "8": self.keyNumberGlobal,
1600 "9": self.keyNumberGlobal,
1601 "0": self.keyNumberGlobal
1604 self.onLayoutFinish.append(self.layoutFinished)
1606 def layoutFinished(self):
1607 self.setWindowTitle()
1608 self["text"].right()
1610 def setWindowTitle(self):
1611 self.setTitle(_("Edit upgrade source url."))
1614 text = self["text"].getText()
1616 fp = file(self.configfile, 'w')
1626 self["text"].right()
1634 def keyDeleteForward(self):
1635 self["text"].delete()
1637 def keyDeleteBackward(self):
1638 self["text"].deleteBackward()
1640 def keyNumberGlobal(self, number):
1641 self["text"].number(number)
1644 class PacketManager(Screen, NumericalTextInput):
1646 <screen name="PacketManager" position="center,center" size="530,420" title="Packet manager" >
1647 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1648 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1649 <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
1650 <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
1651 <widget source="list" render="Listbox" position="5,50" size="520,365" scrollbarMode="showOnDemand">
1652 <convert type="TemplatedMultiContent">
1654 MultiContentEntryText(pos = (5, 1), size = (440, 28), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
1655 MultiContentEntryText(pos = (5, 26), size = (440, 20), font=1, flags = RT_HALIGN_LEFT, text = 2), # index 2 is the description
1656 MultiContentEntryPixmapAlphaTest(pos = (445, 2), size = (48, 48), png = 4), # index 4 is the status pixmap
1657 MultiContentEntryPixmapAlphaTest(pos = (5, 50), size = (510, 2), png = 5), # index 4 is the div pixmap
1659 "fonts": [gFont("Regular", 22),gFont("Regular", 14)],
1666 def __init__(self, session, plugin_path, args = None):
1667 Screen.__init__(self, session)
1668 NumericalTextInput.__init__(self)
1669 self.session = session
1670 self.skin_path = plugin_path
1672 self.setUseableChars(u'1234567890abcdefghijklmnopqrstuvwxyz')
1674 self["shortcuts"] = NumberActionMap(["ShortcutActions", "WizardActions", "NumberActions", "InputActions", "InputAsciiActions", "KeyboardInputActions" ],
1679 "green": self.reload,
1680 "gotAsciiCode": self.keyGotAscii,
1681 "1": self.keyNumberGlobal,
1682 "2": self.keyNumberGlobal,
1683 "3": self.keyNumberGlobal,
1684 "4": self.keyNumberGlobal,
1685 "5": self.keyNumberGlobal,
1686 "6": self.keyNumberGlobal,
1687 "7": self.keyNumberGlobal,
1688 "8": self.keyNumberGlobal,
1689 "9": self.keyNumberGlobal,
1690 "0": self.keyNumberGlobal
1694 self.statuslist = []
1695 self["list"] = List(self.list)
1696 self["key_red"] = StaticText(_("Close"))
1697 self["key_green"] = StaticText(_("Reload"))
1699 self.list_updating = True
1700 self.packetlist = []
1701 self.installed_packetlist = {}
1702 self.upgradeable_packages = {}
1703 self.Console = Console()
1706 self.cache_ttl = 86400 #600 is default, 0 disables, Seconds cache is considered valid (24h should be ok for caching ipkgs)
1707 self.cache_file = eEnv.resolve('${libdir}/enigma2/python/Plugins/SystemPlugins/SoftwareManager/packetmanager.cache') #Path to cache directory
1708 self.oktext = _("\nAfter pressing OK, please wait!")
1709 self.unwanted_extensions = ('-dbg', '-dev', '-doc', 'busybox')
1711 self.ipkg = IpkgComponent()
1712 self.ipkg.addCallback(self.ipkgCallback)
1713 self.onShown.append(self.setWindowTitle)
1714 self.onLayoutFinish.append(self.rebuildList)
1716 rcinput = eRCInput.getInstance()
1717 rcinput.setKeyboardMode(rcinput.kmAscii)
1719 def keyNumberGlobal(self, val):
1720 key = self.getKey(val)
1722 keyvalue = key.encode("utf-8")
1723 if len(keyvalue) == 1:
1724 self.setNextIdx(keyvalue[0])
1726 def keyGotAscii(self):
1727 keyvalue = unichr(getPrevAsciiCode()).encode("utf-8")
1728 if len(keyvalue) == 1:
1729 self.setNextIdx(keyvalue[0])
1731 def setNextIdx(self,char):
1732 if char in ("0", "1", "a"):
1733 self["list"].setIndex(0)
1735 idx = self.getNextIdx(char)
1736 if idx and idx <= self["list"].count:
1737 self["list"].setIndex(idx)
1739 def getNextIdx(self,char):
1741 for i in self["list"].list:
1748 if self.Console is not None:
1749 if len(self.Console.appContainers):
1750 for name in self.Console.appContainers.keys():
1751 self.Console.kill(name)
1752 rcinput = eRCInput.getInstance()
1753 rcinput.setKeyboardMode(rcinput.kmNone)
1757 if (os_path.exists(self.cache_file) == True):
1758 remove(self.cache_file)
1759 self.list_updating = True
1762 def setWindowTitle(self):
1763 self.setTitle(_("Packet manager"))
1765 def setStatus(self,status = None):
1767 self.statuslist = []
1768 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
1769 if status == 'update':
1770 statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgrade.png"))
1771 self.statuslist.append(( _("Package list update"), '', _("Trying to download a new packetlist. Please wait..." ),'',statuspng, divpng ))
1772 self['list'].setList(self.statuslist)
1773 elif status == 'error':
1774 statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
1775 self.statuslist.append(( _("Error"), '', _("There was an error downloading the packetlist. Please try again." ),'',statuspng, divpng ))
1776 self['list'].setList(self.statuslist)
1778 def rebuildList(self):
1779 self.setStatus('update')
1781 self.vc = valid_cache(self.cache_file, self.cache_ttl)
1782 if self.cache_ttl > 0 and self.vc != 0:
1784 self.buildPacketList()
1787 if self.cache_ttl == 0 or self.inv_cache == 1 or self.vc == 0:
1789 self.ipkg.startCmd(IpkgComponent.CMD_UPDATE)
1791 def go(self, returnValue = None):
1792 cur = self["list"].getCurrent()
1797 if status == 'installed':
1798 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": package }))
1799 if len(self.cmdList):
1800 self.session.openWithCallback(self.runRemove, MessageBox, _("Do you want to remove the package:\n") + package + "\n" + self.oktext)
1801 elif status == 'upgradeable':
1802 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package }))
1803 if len(self.cmdList):
1804 self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to upgrade the package:\n") + package + "\n" + self.oktext)
1805 elif status == "installable":
1806 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package }))
1807 if len(self.cmdList):
1808 self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to install the package:\n") + package + "\n" + self.oktext)
1810 def runRemove(self, result):
1812 self.session.openWithCallback(self.runRemoveFinished, Ipkg, cmdList = self.cmdList)
1814 def runRemoveFinished(self):
1815 self.session.openWithCallback(self.RemoveReboot, MessageBox, _("Remove finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
1817 def RemoveReboot(self, result):
1821 cur = self["list"].getCurrent()
1823 item = self['list'].getIndex()
1824 self.list[item] = self.buildEntryComponent(cur[0], cur[1], cur[2], 'installable')
1825 self.cachelist[item] = [cur[0], cur[1], cur[2], 'installable']
1826 self['list'].setList(self.list)
1827 write_cache(self.cache_file, self.cachelist)
1828 self.reloadPluginlist()
1832 def runUpgrade(self, result):
1834 self.session.openWithCallback(self.runUpgradeFinished, Ipkg, cmdList = self.cmdList)
1836 def runUpgradeFinished(self):
1837 self.session.openWithCallback(self.UpgradeReboot, MessageBox, _("Upgrade finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
1839 def UpgradeReboot(self, result):
1843 cur = self["list"].getCurrent()
1845 item = self['list'].getIndex()
1846 self.list[item] = self.buildEntryComponent(cur[0], cur[1], cur[2], 'installed')
1847 self.cachelist[item] = [cur[0], cur[1], cur[2], 'installed']
1848 self['list'].setList(self.list)
1849 write_cache(self.cache_file, self.cachelist)
1850 self.reloadPluginlist()
1854 def ipkgCallback(self, event, param):
1855 if event == IpkgComponent.EVENT_ERROR:
1856 self.list_updating = False
1857 self.setStatus('error')
1858 elif event == IpkgComponent.EVENT_DONE:
1859 if self.list_updating:
1860 self.list_updating = False
1861 if not self.Console:
1862 self.Console = Console()
1864 self.Console.ePopen(cmd, self.IpkgList_Finished)
1865 #print event, "-", param
1868 def IpkgList_Finished(self, result, retval, extra_args = None):
1870 self.packetlist = []
1872 for x in result.splitlines():
1873 tokens = x.split(' - ')
1874 name = tokens[0].strip()
1875 if not any(name.endswith(x) for x in self.unwanted_extensions):
1877 version = l > 1 and tokens[1].strip() or ""
1878 descr = l > 2 and tokens[2].strip() or ""
1879 if name == last_name:
1882 self.packetlist.append([name, version, descr])
1884 if not self.Console:
1885 self.Console = Console()
1886 cmd = "opkg list-installed"
1887 self.Console.ePopen(cmd, self.IpkgListInstalled_Finished)
1889 def IpkgListInstalled_Finished(self, result, retval, extra_args = None):
1891 self.installed_packetlist = {}
1892 for x in result.splitlines():
1893 tokens = x.split(' - ')
1894 name = tokens[0].strip()
1895 if not any(name.endswith(x) for x in self.unwanted_extensions):
1897 version = l > 1 and tokens[1].strip() or ""
1898 self.installed_packetlist[name] = version
1899 if not self.Console:
1900 self.Console = Console()
1901 cmd = "opkg list-upgradable"
1902 self.Console.ePopen(cmd, self.OpkgListUpgradeable_Finished)
1904 def OpkgListUpgradeable_Finished(self, result, retval, extra_args = None):
1906 self.upgradeable_packages = {}
1907 for x in result.splitlines():
1908 tokens = x.split(' - ')
1909 name = tokens[0].strip()
1910 if not any(name.endswith(x) for x in self.unwanted_extensions):
1912 version = l > 2 and tokens[2].strip() or ""
1913 self.upgradeable_packages[name] = version
1914 self.buildPacketList()
1916 def buildEntryComponent(self, name, version, description, state):
1917 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
1918 if description == "":
1919 description = "No description available."
1920 if state == 'installed':
1921 installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installed.png"))
1922 return((name, version, _(description), state, installedpng, divpng))
1923 elif state == 'upgradeable':
1924 upgradeablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgradeable.png"))
1925 return((name, version, _(description), state, upgradeablepng, divpng))
1927 installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installable.png"))
1928 return((name, version, _(description), state, installablepng, divpng))
1930 def buildPacketList(self):
1933 if self.cache_ttl > 0 and self.vc != 0:
1934 print 'Loading packagelist cache from ',self.cache_file
1936 self.cachelist = load_cache(self.cache_file)
1937 if len(self.cachelist) > 0:
1938 for x in self.cachelist:
1939 self.list.append(self.buildEntryComponent(x[0], x[1], x[2], x[3]))
1940 self['list'].setList(self.list)
1944 if self.cache_ttl == 0 or self.inv_cache == 1 or self.vc == 0:
1945 print 'rebuilding fresh package list'
1946 for x in self.packetlist:
1948 if self.installed_packetlist.has_key(x[0]):
1949 if self.upgradeable_packages.has_key(x[0]):
1950 status = "upgradeable"
1952 status = "installed"
1954 status = "installable"
1955 self.list.append(self.buildEntryComponent(x[0], x[1], x[2], status))
1956 self.cachelist.append([x[0], x[1], x[2], status])
1957 write_cache(self.cache_file, self.cachelist)
1958 self['list'].setList(self.list)
1960 def reloadPluginlist(self):
1961 plugins.readPluginList(resolveFilename(SCOPE_PLUGINS))
1964 class IpkgInstaller(Screen):
1966 <screen name="IpkgInstaller" position="center,center" size="550,450" title="Install extensions" >
1967 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1968 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1969 <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
1970 <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
1971 <widget name="list" position="5,50" size="540,360" />
1972 <ePixmap pixmap="skin_default/div-h.png" position="0,410" zPosition="10" size="560,2" transparent="1" alphatest="on" />
1973 <widget source="introduction" render="Label" position="5,420" zPosition="10" size="550,30" halign="center" valign="center" font="Regular;22" transparent="1" shadowColor="black" shadowOffset="-1,-1" />
1976 def __init__(self, session, list):
1977 Screen.__init__(self, session)
1979 self.list = SelectionList()
1980 self["list"] = self.list
1981 for listindex in range(len(list)):
1982 self.list.addSelection(list[listindex], list[listindex], listindex, True)
1984 self["key_red"] = StaticText(_("Close"))
1985 self["key_green"] = StaticText(_("Install"))
1986 self["introduction"] = StaticText(_("Press OK to toggle the selection."))
1988 self["actions"] = ActionMap(["OkCancelActions", "ColorActions"],
1990 "ok": self.list.toggleSelection,
1991 "cancel": self.close,
1993 "green": self.install
1997 list = self.list.getSelectionsList()
2000 cmdList.append((IpkgComponent.CMD_INSTALL, { "package": item[1] }))
2001 self.session.open(Ipkg, cmdList = cmdList)
2004 def filescan_open(list, session, **kwargs):
2005 filelist = [x.path for x in list]
2006 session.open(IpkgInstaller, filelist) # list
2008 def filescan(**kwargs):
2009 from Components.Scanner import Scanner, ScanPath
2011 Scanner(mimetypes = ["application/x-debian-package"],
2014 ScanPath(path = "ipk", with_subdirs = True),
2015 ScanPath(path = "", with_subdirs = False),
2018 description = _("Install extensions."),
2019 openfnc = filescan_open, )
2023 def UpgradeMain(session, **kwargs):
2024 session.open(UpdatePluginMenu)
2026 def startSetup(menuid):
2027 if menuid != "setup":
2029 return [(_("Software management"), UpgradeMain, "software_manager", 50)]
2032 def Plugins(path, **kwargs):
2036 PluginDescriptor(name=_("Software management"), description=_("Manage your receiver's software"), where = PluginDescriptor.WHERE_MENU, needsRestart = False, fnc=startSetup),
2037 PluginDescriptor(name=_("Ipkg"), where = PluginDescriptor.WHERE_FILESCAN, needsRestart = False, fnc = filescan)
2039 if config.usage.setup_level.index >= 2: # expert+
2040 list.append(PluginDescriptor(name=_("Software management"), description=_("Manage your receiver's software"), where = PluginDescriptor.WHERE_EXTENSIONSMENU, needsRestart = False, fnc=UpgradeMain))