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/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 if x[1].startswith('/autofs/'):
268 self.session.openWithCallback(self.backuplocation_choosen, ChoiceBox, title = _("Please select medium to use as backup location"), list = parts)
269 elif (currentEntry == "backupfiles"):
270 self.session.openWithCallback(self.backupfiles_choosen,BackupSelection)
271 elif (currentEntry == "advancedrestore"):
272 self.session.open(RestoreMenu, self.skin_path)
273 elif (currentEntry == "ipkg-source"):
274 self.session.open(IPKGMenu, self.skin_path)
275 elif (currentEntry == "advanced-plugin"):
276 self.extended = current[3]
277 self.extended(self.session, None)
279 def backupfiles_choosen(self, ret):
280 self.backupdirs = ' '.join( config.plugins.configurationbackup.backupdirs.value )
282 def backuplocation_choosen(self, option):
283 if option is not None:
284 config.plugins.configurationbackup.backuplocation.value = str(option[1])
285 config.plugins.configurationbackup.backuplocation.save()
286 config.plugins.configurationbackup.save()
288 self.createBackupfolders()
290 def runUpgrade(self, result):
292 self.session.open(UpdatePlugin, self.skin_path)
294 def createBackupfolders(self):
295 print "Creating backup folder if not already there..."
296 self.backuppath = getBackupPath()
298 if (os_path.exists(self.backuppath) == False):
299 makedirs(self.backuppath)
301 self.session.open(MessageBox, _("Sorry, your backup destination is not writeable.\n\nPlease choose another one."), MessageBox.TYPE_INFO, timeout = 10)
303 def backupDone(self,retval = None):
305 self.session.open(MessageBox, _("Backup done."), MessageBox.TYPE_INFO, timeout = 10)
307 self.session.open(MessageBox, _("Backup failed."), MessageBox.TYPE_INFO, timeout = 10)
309 def startRestore(self, ret = False):
312 self.session.open(RestoreScreen, runRestore = True)
314 class SoftwareManagerSetup(Screen, ConfigListScreen):
317 <screen name="SoftwareManagerSetup" position="center,center" size="560,440" title="SoftwareManager setup">
318 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
319 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
320 <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" alphatest="on" />
321 <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" alphatest="on" />
322 <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" />
323 <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" />
324 <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" />
325 <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" />
326 <widget name="config" position="5,50" size="550,350" scrollbarMode="showOnDemand" />
327 <ePixmap pixmap="skin_default/div-h.png" position="0,400" zPosition="1" size="560,2" />
328 <widget source="introduction" render="Label" position="5,410" size="550,30" zPosition="10" font="Regular;21" halign="center" valign="center" backgroundColor="#25062748" transparent="1" />
331 def __init__(self, session, skin_path = None):
332 Screen.__init__(self, session)
333 self.session = session
334 self.skin_path = skin_path
335 if self.skin_path == None:
336 self.skin_path = resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager")
338 self.onChangedEntry = [ ]
339 self.setup_title = _("Software manager setup")
340 self.overwriteConfigfilesEntry = None
343 ConfigListScreen.__init__(self, self.list, session = session, on_change = self.changedEntry)
345 self["actions"] = ActionMap(["SetupActions"],
347 "cancel": self.keyCancel,
351 self["key_red"] = StaticText(_("Cancel"))
352 self["key_green"] = StaticText(_("OK"))
353 self["key_yellow"] = StaticText()
354 self["key_blue"] = StaticText()
355 self["introduction"] = StaticText()
358 self.onLayoutFinish.append(self.layoutFinished)
360 def layoutFinished(self):
361 self.setTitle(self.setup_title)
363 def createSetup(self):
365 self.overwriteConfigfilesEntry = getConfigListEntry(_("Overwrite configuration files ?"), config.plugins.SoftwareManager.overwriteConfigFiles)
366 self.list.append(self.overwriteConfigfilesEntry)
367 self["config"].list = self.list
368 self["config"].l.setSeperation(400)
369 self["config"].l.setList(self.list)
370 if not self.selectionChanged in self["config"].onSelectionChanged:
371 self["config"].onSelectionChanged.append(self.selectionChanged)
372 self.selectionChanged()
374 def selectionChanged(self):
375 if self["config"].getCurrent() == self.overwriteConfigfilesEntry:
376 self["introduction"].setText(_("Overwrite configuration files during software upgrade?"))
378 self["introduction"].setText("")
384 ConfigListScreen.keyLeft(self)
387 ConfigListScreen.keyRight(self)
389 def confirm(self, confirmed):
391 print "not confirmed"
397 self.session.openWithCallback(self.confirm, MessageBox, _("Use this settings?"), MessageBox.TYPE_YESNO, timeout = 20, default = True)
399 def cancelConfirm(self, result):
402 for x in self["config"].list:
407 if self["config"].isChanged():
408 self.session.openWithCallback(self.cancelConfirm, MessageBox, _("Really close without saving settings?"), MessageBox.TYPE_YESNO, timeout = 20, default = True)
413 def changedEntry(self):
414 for x in self.onChangedEntry:
416 self.selectionChanged()
418 def getCurrentEntry(self):
419 return self["config"].getCurrent()[0]
421 def getCurrentValue(self):
422 return str(self["config"].getCurrent()[1].value)
424 def createSummary(self):
425 from Screens.Setup import SetupSummary
429 class SoftwareManagerInfo(Screen):
431 <screen name="SoftwareManagerInfo" position="center,center" size="560,440" title="SoftwareManager information">
432 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
433 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
434 <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" alphatest="on" />
435 <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" alphatest="on" />
436 <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" />
437 <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" />
438 <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" />
439 <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" />
440 <widget source="list" render="Listbox" position="5,50" size="550,340" scrollbarMode="showOnDemand" selectionDisabled="0">
441 <convert type="TemplatedMultiContent">
443 MultiContentEntryText(pos = (5, 0), size = (540, 26), font=0, flags = RT_HALIGN_LEFT | RT_HALIGN_CENTER, text = 0), # index 0 is the name
445 "fonts": [gFont("Regular", 24),gFont("Regular", 22)],
450 <ePixmap pixmap="skin_default/div-h.png" position="0,400" zPosition="1" size="560,2" />
451 <widget source="introduction" render="Label" position="5,410" size="550,30" zPosition="10" font="Regular;21" halign="center" valign="center" backgroundColor="#25062748" transparent="1" />
454 def __init__(self, session, skin_path = None, mode = None):
455 Screen.__init__(self, session)
456 self.session = session
458 self.skin_path = skin_path
459 if self.skin_path == None:
460 self.skin_path = resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager")
462 self["actions"] = ActionMap(["ShortcutActions", "WizardActions"],
469 self["list"] = List(self.list)
471 self["key_red"] = StaticText(_("Close"))
472 self["key_green"] = StaticText()
473 self["key_yellow"] = StaticText()
474 self["key_blue"] = StaticText()
475 self["introduction"] = StaticText()
477 self.onLayoutFinish.append(self.layoutFinished)
479 def layoutFinished(self):
480 self.setTitle(_("Softwaremanager information"))
481 if self.mode is not None:
485 if self.mode == "backupinfo":
487 backupfiles = config.plugins.configurationbackup.backupdirs.value
488 for entry in backupfiles:
490 self.list.append((entry,))
491 self['list'].setList(self.list)
494 class PluginManager(Screen, DreamInfoHandler):
497 <screen name="PluginManager" position="center,center" size="560,440" title="Extensions management" >
498 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
499 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
500 <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" alphatest="on" />
501 <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" alphatest="on" />
502 <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" />
503 <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" />
504 <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" />
505 <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" />
506 <widget source="list" render="Listbox" position="5,50" size="550,360" scrollbarMode="showOnDemand">
507 <convert type="TemplatedMultiContent">
510 MultiContentEntryText(pos = (0, 1), size = (470, 24), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
511 MultiContentEntryText(pos = (0, 25), size = (470, 24), font=1, flags = RT_HALIGN_LEFT, text = 2), # index 2 is the description
512 MultiContentEntryPixmapAlphaTest(pos = (475, 0), size = (48, 48), png = 5), # index 5 is the status pixmap
513 MultiContentEntryPixmapAlphaTest(pos = (0, 49), size = (550, 2), png = 6), # index 6 is the div pixmap
516 MultiContentEntryText(pos = (30, 0), size = (500, 22), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
517 MultiContentEntryText(pos = (30, 22), size = (500, 16), font=2, flags = RT_HALIGN_LEFT, text = 1), # index 1 is the description
518 MultiContentEntryPixmapAlphaTest(pos = (0, 38), size = (550, 2), png = 3), # index 3 is the div pixmap
521 "fonts": [gFont("Regular", 22),gFont("Regular", 20),gFont("Regular", 16)],
526 <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" />
529 def __init__(self, session, plugin_path = None, args = None):
530 Screen.__init__(self, session)
531 self.session = session
532 self.skin_path = plugin_path
533 if self.skin_path == None:
534 self.skin_path = resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager")
536 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions", "InfobarEPGActions", "HelpActions" ],
538 "ok": self.handleCurrent,
541 "green": self.handleCurrent,
542 "yellow": self.handleSelected,
543 "showEventInfo": self.handleSelected,
544 "displayHelp": self.handleHelp,
549 self.selectedFiles = []
550 self.categoryList = []
552 self["list"] = List(self.list)
553 self["key_red"] = StaticText(_("Close"))
554 self["key_green"] = StaticText("")
555 self["key_yellow"] = StaticText("")
556 self["key_blue"] = StaticText("")
557 self["status"] = StaticText("")
560 self.oktext = _("\nAfter pressing OK, please wait!")
561 if not self.selectionChanged in self["list"].onSelectionChanged:
562 self["list"].onSelectionChanged.append(self.selectionChanged)
565 self.currentSelectedTag = None
566 self.currentSelectedIndex = None
567 self.currentSelectedPackage = None
568 self.saved_currentSelectedPackage = None
570 self.onShown.append(self.setWindowTitle)
571 self.onLayoutFinish.append(self.getUpdateInfos)
573 def setWindowTitle(self):
574 self.setTitle(_("Extensions management"))
577 if self.currList == "packages":
578 self.currList = "category"
579 self.currentSelectedTag = None
580 self["list"].style = "category"
581 self['list'].setList(self.categoryList)
582 self["list"].setIndex(self.currentSelectedIndex)
583 self["list"].updateList(self.categoryList)
584 self.selectionChanged()
586 iSoftwareTools.cleanupSoftwareTools()
587 self.prepareInstall()
588 if len(self.cmdList):
589 self.session.openWithCallback(self.runExecute, PluginManagerInfo, self.skin_path, self.cmdList)
593 def handleHelp(self):
594 if self.currList != "status":
595 self.session.open(PluginManagerHelp, self.skin_path)
597 def setState(self,status = None):
599 self.currList = "status"
601 self["key_green"].setText("")
602 self["key_blue"].setText("")
603 self["key_yellow"].setText("")
604 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
605 if status == 'update':
606 statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgrade.png"))
607 self.statuslist.append(( _("Updating software catalog"), '', _("Searching for available updates. Please wait..." ),'', '', statuspng, divpng, None, '' ))
608 elif status == 'sync':
609 statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgrade.png"))
610 self.statuslist.append(( _("Package list update"), '', _("Searching for new installed or removed packages. Please wait..." ),'', '', statuspng, divpng, None, '' ))
611 elif status == 'error':
612 self["key_green"].setText(_("Continue"))
613 statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
614 self.statuslist.append(( _("Error"), '', _("There was an error downloading the packetlist. Please try again." ),'', '', statuspng, divpng, None, '' ))
615 self["list"].style = "default"
616 self['list'].setList(self.statuslist)
619 def getUpdateInfos(self):
620 if (iSoftwareTools.lastDownloadDate is not None and iSoftwareTools.NetworkConnectionAvailable is False):
623 self.setState('update')
624 iSoftwareTools.startSoftwareTools(self.getUpdateInfosCB)
626 def getUpdateInfosCB(self, retval = None):
627 if retval is not None:
629 if iSoftwareTools.available_updates is not 0:
630 self["status"].setText(_("There are at least ") + str(iSoftwareTools.available_updates) + _(" updates available."))
632 self["status"].setText(_("There are no updates available."))
634 elif retval is False:
635 if iSoftwareTools.lastDownloadDate is None:
636 self.setState('error')
637 if iSoftwareTools.NetworkConnectionAvailable:
638 self["status"].setText(_("Updatefeed not available."))
640 self["status"].setText(_("No network connection available."))
642 iSoftwareTools.lastDownloadDate = time()
643 iSoftwareTools.list_updating = True
644 self.setState('update')
645 iSoftwareTools.getUpdates(self.getUpdateInfosCB)
647 def rebuildList(self, retval = None):
648 if self.currentSelectedTag is None:
649 self.buildCategoryList()
651 self.buildPacketList(self.currentSelectedTag)
653 def selectionChanged(self):
654 current = self["list"].getCurrent()
655 self["status"].setText("")
657 if self.currList == "packages":
658 self["key_red"].setText(_("Back"))
659 if current[4] == 'installed':
660 self["key_green"].setText(_("Uninstall"))
661 elif current[4] == 'installable':
662 self["key_green"].setText(_("Install"))
663 if iSoftwareTools.NetworkConnectionAvailable is False:
664 self["key_green"].setText("")
665 elif current[4] == 'remove':
666 self["key_green"].setText(_("Undo uninstall"))
667 elif current[4] == 'install':
668 self["key_green"].setText(_("Undo install"))
669 if iSoftwareTools.NetworkConnectionAvailable is False:
670 self["key_green"].setText("")
671 self["key_yellow"].setText(_("View details"))
672 self["key_blue"].setText("")
673 if len(self.selectedFiles) == 0 and iSoftwareTools.available_updates is not 0:
674 self["status"].setText(_("There are at least ") + str(iSoftwareTools.available_updates) + _(" updates available."))
675 elif len(self.selectedFiles) is not 0:
676 self["status"].setText(str(len(self.selectedFiles)) + _(" packages selected."))
678 self["status"].setText(_("There are currently no outstanding actions."))
679 elif self.currList == "category":
680 self["key_red"].setText(_("Close"))
681 self["key_green"].setText("")
682 self["key_yellow"].setText("")
683 self["key_blue"].setText("")
684 if len(self.selectedFiles) == 0 and iSoftwareTools.available_updates is not 0:
685 self["status"].setText(_("There are at least ") + str(iSoftwareTools.available_updates) + _(" updates available."))
686 self["key_yellow"].setText(_("Update"))
687 elif len(self.selectedFiles) is not 0:
688 self["status"].setText(str(len(self.selectedFiles)) + _(" packages selected."))
689 self["key_yellow"].setText(_("Process"))
691 self["status"].setText(_("There are currently no outstanding actions."))
693 def getSelectionState(self, detailsFile):
694 for entry in self.selectedFiles:
695 if entry[0] == detailsFile:
699 def handleCurrent(self):
700 current = self["list"].getCurrent()
702 if self.currList == "category":
703 self.currentSelectedIndex = self["list"].index
704 selectedTag = current[2]
705 self.buildPacketList(selectedTag)
706 elif self.currList == "packages":
707 if current[7] is not '':
708 idx = self["list"].getIndex()
709 detailsFile = self.list[idx][1]
710 if self.list[idx][7] == True:
711 for entry in self.selectedFiles:
712 if entry[0] == detailsFile:
713 self.selectedFiles.remove(entry)
715 alreadyinList = False
716 for entry in self.selectedFiles:
717 if entry[0] == detailsFile:
719 if not alreadyinList:
720 if (iSoftwareTools.NetworkConnectionAvailable is False and current[4] in ('installable','install')):
723 self.selectedFiles.append((detailsFile,current[4],current[3]))
724 self.currentSelectedPackage = ((detailsFile,current[4],current[3]))
725 if current[4] == 'installed':
726 self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'remove', True)
727 elif current[4] == 'installable':
728 if iSoftwareTools.NetworkConnectionAvailable:
729 self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'install', True)
730 elif current[4] == 'remove':
731 self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'installed', False)
732 elif current[4] == 'install':
733 if iSoftwareTools.NetworkConnectionAvailable:
734 self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'installable',False)
735 self["list"].setList(self.list)
736 self["list"].setIndex(idx)
737 self["list"].updateList(self.list)
738 self.selectionChanged()
739 elif self.currList == "status":
740 iSoftwareTools.lastDownloadDate = time()
741 iSoftwareTools.list_updating = True
742 self.setState('update')
743 iSoftwareTools.getUpdates(self.getUpdateInfosCB)
745 def handleSelected(self):
746 current = self["list"].getCurrent()
748 if self.currList == "packages":
749 if current[7] is not '':
750 detailsfile = iSoftwareTools.directory[0] + "/" + current[1]
751 if (os_path.exists(detailsfile) == True):
752 self.saved_currentSelectedPackage = self.currentSelectedPackage
753 self.session.openWithCallback(self.detailsClosed, PluginDetails, self.skin_path, current)
755 self.session.open(MessageBox, _("Sorry, no Details available!"), MessageBox.TYPE_INFO, timeout = 10)
756 elif self.currList == "category":
757 self.prepareInstall()
758 if len(self.cmdList):
759 self.session.openWithCallback(self.runExecute, PluginManagerInfo, self.skin_path, self.cmdList)
761 def detailsClosed(self, result = None):
762 if result is not None:
763 if result is not False:
764 self.setState('sync')
765 iSoftwareTools.lastDownloadDate = time()
766 for entry in self.selectedFiles:
767 if entry == self.saved_currentSelectedPackage:
768 self.selectedFiles.remove(entry)
769 iSoftwareTools.startIpkgListInstalled(self.rebuildList)
771 def buildEntryComponent(self, name, details, description, packagename, state, selected = False):
772 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
773 installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installed.png"))
774 installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installable.png"))
775 removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
776 installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/install.png"))
777 if state == 'installed':
778 return((name, details, description, packagename, state, installedpng, divpng, selected))
779 elif state == 'installable':
780 return((name, details, description, packagename, state, installablepng, divpng, selected))
781 elif state == 'remove':
782 return((name, details, description, packagename, state, removepng, divpng, selected))
783 elif state == 'install':
784 return((name, details, description, packagename, state, installpng, divpng, selected))
786 def buildPacketList(self, categorytag = None):
787 if categorytag is not None:
788 self.currList = "packages"
789 self.currentSelectedTag = categorytag
791 for package in iSoftwareTools.packagesIndexlist[:]:
792 prerequisites = package[0]["prerequisites"]
793 if prerequisites.has_key("tag"):
794 for foundtag in prerequisites["tag"]:
795 if categorytag == foundtag:
796 attributes = package[0]["attributes"]
797 if attributes.has_key("packagetype"):
798 if attributes["packagetype"] == "internal":
800 self.packetlist.append([attributes["name"], attributes["details"], attributes["shortdescription"], attributes["packagename"]])
802 self.packetlist.append([attributes["name"], attributes["details"], attributes["shortdescription"], attributes["packagename"]])
804 for x in self.packetlist:
807 details = x[1].strip()
808 description = x[2].strip()
809 packagename = x[3].strip()
810 selectState = self.getSelectionState(details)
811 if iSoftwareTools.installed_packetlist.has_key(packagename):
812 if selectState == True:
816 self.list.append(self.buildEntryComponent(name, _(details), _(description), packagename, status, selected = selectState))
818 if selectState == True:
821 status = "installable"
822 self.list.append(self.buildEntryComponent(name, _(details), _(description), packagename, status, selected = selectState))
824 self.list.sort(key=lambda x: x[0])
825 self["list"].style = "default"
826 self['list'].setList(self.list)
827 self["list"].updateList(self.list)
828 self.selectionChanged()
830 def buildCategoryList(self):
831 self.currList = "category"
833 self.categoryList = []
834 for package in iSoftwareTools.packagesIndexlist[:]:
835 prerequisites = package[0]["prerequisites"]
836 if prerequisites.has_key("tag"):
837 for foundtag in prerequisites["tag"]:
838 attributes = package[0]["attributes"]
839 if foundtag not in self.categories:
840 self.categories.append(foundtag)
841 self.categoryList.append(self.buildCategoryComponent(foundtag))
842 self.categoryList.sort(key=lambda x: x[0])
843 self["list"].style = "category"
844 self['list'].setList(self.categoryList)
845 self["list"].updateList(self.categoryList)
846 self.selectionChanged()
848 def buildCategoryComponent(self, tag = None):
849 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
852 return(( _("System"), _("View list of available system extensions" ), tag, divpng ))
854 return(( _("Skins"), _("View list of available skins" ), tag, divpng ))
855 elif tag == 'Recording':
856 return(( _("Recordings"), _("View list of available recording extensions" ), tag, divpng ))
857 elif tag == 'Network':
858 return(( _("Network"), _("View list of available networking extensions" ), tag, divpng ))
860 return(( _("CommonInterface"), _("View list of available CommonInterface extensions" ), tag, divpng ))
861 elif tag == 'Default':
862 return(( _("Default Settings"), _("View list of available default settings" ), tag, divpng ))
864 return(( _("Satellite equipment"), _("View list of available Satellite equipment extensions." ), tag, divpng ))
865 elif tag == 'Software':
866 return(( _("Software"), _("View list of available software extensions" ), tag, divpng ))
867 elif tag == 'Multimedia':
868 return(( _("Multimedia"), _("View list of available multimedia extensions." ), tag, divpng ))
869 elif tag == 'Display':
870 return(( _("Display and Userinterface"), _("View list of available Display and Userinterface extensions." ), tag, divpng ))
872 return(( _("Electronic Program Guide"), _("View list of available EPG extensions." ), tag, divpng ))
873 elif tag == 'Communication':
874 return(( _("Communication"), _("View list of available communication extensions." ), tag, divpng ))
875 else: # dynamically generate non existent tags
876 return(( str(tag), _("View list of available ") + str(tag) + _(" extensions." ), tag, divpng ))
878 def prepareInstall(self):
880 if iSoftwareTools.available_updates > 0:
881 self.cmdList.append((IpkgComponent.CMD_UPGRADE, { "test_only": False }))
882 if self.selectedFiles and len(self.selectedFiles):
883 for plugin in self.selectedFiles:
884 detailsfile = iSoftwareTools.directory[0] + "/" + plugin[0]
885 if (os_path.exists(detailsfile) == True):
886 iSoftwareTools.fillPackageDetails(plugin[0])
887 self.package = iSoftwareTools.packageDetails[0]
888 if self.package[0].has_key("attributes"):
889 self.attributes = self.package[0]["attributes"]
890 if self.attributes.has_key("package"):
891 self.packagefiles = self.attributes["package"]
892 if plugin[1] == 'installed':
893 if self.packagefiles:
894 for package in self.packagefiles[:]:
895 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": package["name"] }))
897 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": plugin[2] }))
899 if self.packagefiles:
900 for package in self.packagefiles[:]:
901 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package["name"] }))
903 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": plugin[2] }))
905 if plugin[1] == 'installed':
906 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": plugin[2] }))
908 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": plugin[2] }))
910 def runExecute(self, result = None):
911 if result is not None:
912 if result[0] is True:
913 self.session.openWithCallback(self.runExecuteFinished, Ipkg, cmdList = self.cmdList)
914 elif result[0] is False:
915 self.cmdList = result[1]
916 self.session.openWithCallback(self.runExecuteFinished, Ipkg, cmdList = self.cmdList)
920 def runExecuteFinished(self):
921 self.session.openWithCallback(self.ExecuteReboot, MessageBox, _("Install or remove finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
923 def ExecuteReboot(self, result):
927 self.reloadPluginlist()
928 self.selectedFiles = []
929 self.detailsClosed(True)
933 def reloadPluginlist(self):
934 plugins.readPluginList(resolveFilename(SCOPE_PLUGINS))
937 class PluginManagerInfo(Screen):
939 <screen name="PluginManagerInfo" position="center,center" size="560,450" title="Plugin manager activity information" >
940 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
941 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
942 <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" />
943 <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" />
944 <widget source="list" render="Listbox" position="5,50" size="550,350" scrollbarMode="showOnDemand" selectionDisabled="1">
945 <convert type="TemplatedMultiContent">
947 MultiContentEntryText(pos = (50, 0), size = (150, 26), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
948 MultiContentEntryText(pos = (50, 27), size = (540, 23), font=1, flags = RT_HALIGN_LEFT, text = 1), # index 1 is the state
949 MultiContentEntryPixmapAlphaTest(pos = (0, 1), size = (48, 48), png = 2), # index 2 is the status pixmap
950 MultiContentEntryPixmapAlphaTest(pos = (0, 48), size = (550, 2), png = 3), # index 3 is the div pixmap
952 "fonts": [gFont("Regular", 24),gFont("Regular", 22)],
957 <ePixmap pixmap="skin_default/div-h.png" position="0,404" zPosition="10" size="560,2" transparent="1" alphatest="on" />
958 <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" />
961 def __init__(self, session, plugin_path, cmdlist = None):
962 Screen.__init__(self, session)
963 self.session = session
964 self.skin_path = plugin_path
965 self.cmdlist = cmdlist
967 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"],
969 "ok": self.process_all,
972 "green": self.process_extensions,
976 self["list"] = List(self.list)
977 self["key_red"] = StaticText(_("Cancel"))
978 self["key_green"] = StaticText(_("Only extensions."))
979 self["status"] = StaticText(_("Following tasks will be done after you press OK!"))
981 self.onShown.append(self.setWindowTitle)
982 self.onLayoutFinish.append(self.rebuildList)
984 def setWindowTitle(self):
985 self.setTitle(_("Plugin manager activity information"))
987 def rebuildList(self):
989 if self.cmdlist is not None:
990 for entry in self.cmdlist:
1002 info = args['package']
1004 info = args['package']
1006 info = _("Dreambox software because updates are available.")
1008 self.list.append(self.buildEntryComponent(action,info))
1009 self['list'].setList(self.list)
1010 self['list'].updateList(self.list)
1012 def buildEntryComponent(self, action,info):
1013 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
1014 upgradepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgrade.png"))
1015 installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/install.png"))
1016 removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
1017 if action == 'install':
1018 return(( _('Installing'), info, installpng, divpng))
1019 elif action == 'remove':
1020 return(( _('Removing'), info, removepng, divpng))
1022 return(( _('Upgrading'), info, upgradepng, divpng))
1027 def process_all(self):
1028 self.close((True,None))
1030 def process_extensions(self):
1032 if self.cmdlist is not None:
1033 for entry in self.cmdlist:
1035 if entry[0] in (0,2):
1036 self.list.append((entry))
1037 self.close((False,self.list))
1040 class PluginManagerHelp(Screen):
1042 <screen name="PluginManagerHelp" position="center,center" size="560,450" title="Plugin manager help" >
1043 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1044 <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" />
1045 <widget source="list" render="Listbox" position="5,50" size="550,350" scrollbarMode="showOnDemand" selectionDisabled="1">
1046 <convert type="TemplatedMultiContent">
1048 MultiContentEntryText(pos = (50, 0), size = (540, 26), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
1049 MultiContentEntryText(pos = (50, 27), size = (540, 23), font=1, flags = RT_HALIGN_LEFT, text = 1), # index 1 is the state
1050 MultiContentEntryPixmapAlphaTest(pos = (0, 1), size = (48, 48), png = 2), # index 2 is the status pixmap
1051 MultiContentEntryPixmapAlphaTest(pos = (0, 48), size = (550, 2), png = 3), # index 3 is the div pixmap
1053 "fonts": [gFont("Regular", 24),gFont("Regular", 22)],
1058 <ePixmap pixmap="skin_default/div-h.png" position="0,404" zPosition="10" size="560,2" transparent="1" alphatest="on" />
1059 <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" />
1062 def __init__(self, session, plugin_path):
1063 Screen.__init__(self, session)
1064 self.session = session
1065 self.skin_path = plugin_path
1067 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"],
1074 self["list"] = List(self.list)
1075 self["key_red"] = StaticText(_("Close"))
1076 self["status"] = StaticText(_("A small overview of the available icon states and actions."))
1078 self.onShown.append(self.setWindowTitle)
1079 self.onLayoutFinish.append(self.rebuildList)
1081 def setWindowTitle(self):
1082 self.setTitle(_("Plugin manager help"))
1084 def rebuildList(self):
1086 self.list.append(self.buildEntryComponent('install'))
1087 self.list.append(self.buildEntryComponent('installable'))
1088 self.list.append(self.buildEntryComponent('installed'))
1089 self.list.append(self.buildEntryComponent('remove'))
1090 self['list'].setList(self.list)
1091 self['list'].updateList(self.list)
1093 def buildEntryComponent(self, state):
1094 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
1095 installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installed.png"))
1096 installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installable.png"))
1097 removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
1098 installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/install.png"))
1100 if state == 'installed':
1101 return(( _('This plugin is installed.'), _('You can remove this plugin.'), installedpng, divpng))
1102 elif state == 'installable':
1103 return(( _('This plugin is not installed.'), _('You can install this plugin.'), installablepng, divpng))
1104 elif state == 'install':
1105 return(( _('This plugin will be installed.'), _('You can cancel the installation.'), installpng, divpng))
1106 elif state == 'remove':
1107 return(( _('This plugin will be removed.'), _('You can cancel the removal.'), removepng, divpng))
1113 class PluginDetails(Screen, DreamInfoHandler):
1115 <screen name="PluginDetails" position="center,center" size="600,440" title="Plugin details" >
1116 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1117 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1118 <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" />
1119 <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" />
1120 <widget source="author" render="Label" position="10,50" size="500,25" zPosition="10" font="Regular;21" transparent="1" />
1121 <widget name="statuspic" position="550,40" size="48,48" alphatest="on"/>
1122 <widget name="divpic" position="0,80" size="600,2" alphatest="on"/>
1123 <widget name="detailtext" position="10,90" size="270,330" zPosition="10" font="Regular;21" transparent="1" halign="left" valign="top"/>
1124 <widget name="screenshot" position="290,90" size="300,330" alphatest="on"/>
1126 def __init__(self, session, plugin_path, packagedata = None):
1127 Screen.__init__(self, session)
1128 self.skin_path = plugin_path
1129 self.language = language.getLanguage()[:2] # getLanguage returns e.g. "fi_FI" for "language_country"
1130 self.attributes = None
1131 DreamInfoHandler.__init__(self, self.statusCallback, blocking = False)
1132 self.directory = resolveFilename(SCOPE_METADIR)
1134 self.pluginname = packagedata[0]
1135 self.details = packagedata[1]
1136 self.pluginstate = packagedata[4]
1137 self.statuspicinstance = packagedata[5]
1138 self.divpicinstance = packagedata[6]
1139 self.fillPackageDetails(self.details)
1143 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"],
1149 "down": self.pageDown,
1150 "left": self.pageUp,
1151 "right": self.pageDown,
1154 self["key_red"] = StaticText(_("Close"))
1155 self["key_green"] = StaticText("")
1156 self["author"] = StaticText()
1157 self["statuspic"] = Pixmap()
1158 self["divpic"] = Pixmap()
1159 self["screenshot"] = Pixmap()
1160 self["detailtext"] = ScrollLabel()
1162 self["statuspic"].hide()
1163 self["screenshot"].hide()
1164 self["divpic"].hide()
1166 self.package = self.packageDetails[0]
1167 if self.package[0].has_key("attributes"):
1168 self.attributes = self.package[0]["attributes"]
1171 self.oktext = _("\nAfter pressing OK, please wait!")
1172 self.picload = ePicLoad()
1173 self.picload.PictureData.get().append(self.paintScreenshotPixmapCB)
1174 self.onShown.append(self.setWindowTitle)
1175 self.onLayoutFinish.append(self.setInfos)
1177 def setWindowTitle(self):
1178 self.setTitle(_("Details for plugin: ") + self.pluginname )
1184 self["detailtext"].pageUp()
1187 self["detailtext"].pageDown()
1189 def statusCallback(self, status, progress):
1193 if self.attributes.has_key("screenshot"):
1194 self.loadThumbnail(self.attributes)
1196 if self.attributes.has_key("name"):
1197 self.pluginname = self.attributes["name"]
1199 self.pluginname = _("unknown")
1201 if self.attributes.has_key("author"):
1202 self.author = self.attributes["author"]
1204 self.author = _("unknown")
1206 if self.attributes.has_key("description"):
1207 self.description = _(self.attributes["description"].replace("\\n", "\n"))
1209 self.description = _("No description available.")
1211 self["author"].setText(_("Author: ") + self.author)
1212 self["detailtext"].setText(_(self.description))
1213 if self.pluginstate in ('installable', 'install'):
1214 if iSoftwareTools.NetworkConnectionAvailable:
1215 self["key_green"].setText(_("Install"))
1217 self["key_green"].setText("")
1219 self["key_green"].setText(_("Remove"))
1221 def loadThumbnail(self, entry):
1223 if entry.has_key("screenshot"):
1224 thumbnailUrl = entry["screenshot"]
1225 if self.language == "de":
1226 if thumbnailUrl[-7:] == "_en.jpg":
1227 thumbnailUrl = thumbnailUrl[:-7] + "_de.jpg"
1229 if thumbnailUrl is not None:
1230 self.thumbnail = "/tmp/" + thumbnailUrl.split('/')[-1]
1231 print "[PluginDetails] downloading screenshot " + thumbnailUrl + " to " + self.thumbnail
1232 if iSoftwareTools.NetworkConnectionAvailable:
1233 client.downloadPage(thumbnailUrl,self.thumbnail).addCallback(self.setThumbnail).addErrback(self.fetchFailed)
1235 self.setThumbnail(noScreenshot = True)
1237 self.setThumbnail(noScreenshot = True)
1239 def setThumbnail(self, noScreenshot = False):
1240 if not noScreenshot:
1241 filename = self.thumbnail
1243 filename = resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/noprev.png")
1245 sc = AVSwitch().getFramebufferScale()
1246 self.picload.setPara((self["screenshot"].instance.size().width(), self["screenshot"].instance.size().height(), sc[0], sc[1], False, 1, "#00000000"))
1247 self.picload.startDecode(filename)
1249 if self.statuspicinstance != None:
1250 self["statuspic"].instance.setPixmap(self.statuspicinstance.__deref__())
1251 self["statuspic"].show()
1252 if self.divpicinstance != None:
1253 self["divpic"].instance.setPixmap(self.divpicinstance.__deref__())
1254 self["divpic"].show()
1256 def paintScreenshotPixmapCB(self, picInfo=None):
1257 ptr = self.picload.getData()
1259 self["screenshot"].instance.setPixmap(ptr.__deref__())
1260 self["screenshot"].show()
1262 self.setThumbnail(noScreenshot = True)
1265 if self.attributes.has_key("package"):
1266 self.packagefiles = self.attributes["package"]
1268 if self.pluginstate in ('installed', 'remove'):
1269 if self.packagefiles:
1270 for package in self.packagefiles[:]:
1271 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": package["name"] }))
1272 if len(self.cmdList):
1273 self.session.openWithCallback(self.runRemove, MessageBox, _("Do you want to remove the package:\n") + self.pluginname + "\n" + self.oktext)
1275 if iSoftwareTools.NetworkConnectionAvailable:
1276 if self.packagefiles:
1277 for package in self.packagefiles[:]:
1278 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package["name"] }))
1279 if len(self.cmdList):
1280 self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to install the package:\n") + self.pluginname + "\n" + self.oktext)
1282 def runUpgrade(self, result):
1284 self.session.openWithCallback(self.runUpgradeFinished, Ipkg, cmdList = self.cmdList)
1286 def runUpgradeFinished(self):
1287 self.session.openWithCallback(self.UpgradeReboot, MessageBox, _("Installation finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
1289 def UpgradeReboot(self, result):
1297 def runRemove(self, result):
1299 self.session.openWithCallback(self.runRemoveFinished, Ipkg, cmdList = self.cmdList)
1301 def runRemoveFinished(self):
1302 self.session.openWithCallback(self.RemoveReboot, MessageBox, _("Remove finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
1304 def RemoveReboot(self, result):
1312 def reloadPluginlist(self):
1313 plugins.readPluginList(resolveFilename(SCOPE_PLUGINS))
1315 def fetchFailed(self,string):
1316 self.setThumbnail(noScreenshot = True)
1317 print "[PluginDetails] fetch failed " + string.getErrorMessage()
1320 class UpdatePlugin(Screen):
1322 <screen name="UpdatePlugin" position="center,center" size="550,300" title="Software update" >
1323 <widget name="activityslider" position="0,0" size="550,5" />
1324 <widget name="slider" position="0,150" size="550,30" />
1325 <widget source="package" render="Label" position="10,30" size="540,20" font="Regular;18" halign="center" valign="center" backgroundColor="#25062748" transparent="1" />
1326 <widget source="status" render="Label" position="10,180" size="540,100" font="Regular;20" halign="center" valign="center" backgroundColor="#25062748" transparent="1" />
1329 def __init__(self, session, args = None):
1330 Screen.__init__(self, session)
1332 self.sliderPackages = { "dreambox-dvb-modules": 1, "enigma2": 2, "tuxbox-image-info": 3 }
1334 self.slider = Slider(0, 4)
1335 self["slider"] = self.slider
1336 self.activityslider = Slider(0, 100)
1337 self["activityslider"] = self.activityslider
1338 self.status = StaticText(_("Upgrading Dreambox... Please wait"))
1339 self["status"] = self.status
1340 self.package = StaticText()
1341 self["package"] = self.package
1342 self.oktext = _("Press OK on your remote control to continue.")
1346 self.processed_packages = []
1349 self.activityTimer = eTimer()
1350 self.activityTimer.callback.append(self.doActivityTimer)
1351 self.activityTimer.start(100, False)
1353 self.ipkg = IpkgComponent()
1354 self.ipkg.addCallback(self.ipkgCallback)
1356 self.updating = True
1357 self.package.setText(_("Package list update"))
1358 self.ipkg.startCmd(IpkgComponent.CMD_UPDATE)
1360 self["actions"] = ActionMap(["WizardActions"],
1366 def doActivityTimer(self):
1368 if self.activity == 100:
1370 self.activityslider.setValue(self.activity)
1372 def ipkgCallback(self, event, param):
1373 if event == IpkgComponent.EVENT_DOWNLOAD:
1374 self.status.setText(_("Downloading"))
1375 elif event == IpkgComponent.EVENT_UPGRADE:
1376 if self.sliderPackages.has_key(param):
1377 self.slider.setValue(self.sliderPackages[param])
1378 self.package.setText(param)
1379 self.status.setText(_("Upgrading"))
1380 if not param in self.processed_packages:
1381 self.processed_packages.append(param)
1383 elif event == IpkgComponent.EVENT_INSTALL:
1384 self.package.setText(param)
1385 self.status.setText(_("Installing"))
1386 if not param in self.processed_packages:
1387 self.processed_packages.append(param)
1389 elif event == IpkgComponent.EVENT_REMOVE:
1390 self.package.setText(param)
1391 self.status.setText(_("Removing"))
1392 if not param in self.processed_packages:
1393 self.processed_packages.append(param)
1395 elif event == IpkgComponent.EVENT_CONFIGURING:
1396 self.package.setText(param)
1397 self.status.setText(_("Configuring"))
1399 elif event == IpkgComponent.EVENT_MODIFIED:
1400 if config.plugins.SoftwareManager.overwriteConfigFiles.value in ("N", "Y"):
1401 self.ipkg.write(True and config.plugins.SoftwareManager.overwriteConfigFiles.value)
1403 self.session.openWithCallback(
1404 self.modificationCallback,
1406 _("A configuration file (%s) was modified since Installation.\nDo you want to keep your version?") % (param)
1408 elif event == IpkgComponent.EVENT_ERROR:
1410 elif event == IpkgComponent.EVENT_DONE:
1412 self.updating = False
1413 self.ipkg.startCmd(IpkgComponent.CMD_UPGRADE, args = {'test_only': False})
1414 elif self.error == 0:
1415 self.slider.setValue(4)
1417 self.activityTimer.stop()
1418 self.activityslider.setValue(0)
1420 self.package.setText(_("Done - Installed or upgraded %d packages") % self.packages)
1421 self.status.setText(self.oktext)
1423 self.activityTimer.stop()
1424 self.activityslider.setValue(0)
1425 error = _("your dreambox might be unusable now. Please consult the manual for further assistance before rebooting your dreambox.")
1426 if self.packages == 0:
1427 error = _("No packages were upgraded yet. So you can check your network and try again.")
1429 error = _("Your dreambox isn't connected to the internet properly. Please check it and try again.")
1430 self.status.setText(_("Error") + " - " + error)
1431 #print event, "-", param
1434 def modificationCallback(self, res):
1435 self.ipkg.write(res and "N" or "Y")
1438 if not self.ipkg.isRunning():
1439 if self.packages != 0 and self.error == 0:
1440 self.session.openWithCallback(self.exitAnswer, MessageBox, _("Upgrade finished.") +" "+_("Do you want to reboot your Dreambox?"))
1444 def exitAnswer(self, result):
1445 if result is not None and result:
1451 class IPKGMenu(Screen):
1453 <screen name="IPKGMenu" position="center,center" size="560,400" title="Select upgrade source to edit." >
1454 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1455 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1456 <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" />
1457 <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" />
1458 <widget name="filelist" position="5,50" size="550,340" scrollbarMode="showOnDemand" />
1461 def __init__(self, session, plugin_path):
1462 Screen.__init__(self, session)
1463 self.skin_path = plugin_path
1465 self["key_red"] = StaticText(_("Close"))
1466 self["key_green"] = StaticText(_("Edit"))
1475 self["actions"] = NumberActionMap(["SetupActions"],
1478 "cancel": self.keyCancel
1481 self["shortcuts"] = ActionMap(["ShortcutActions"],
1483 "red": self.keyCancel,
1484 "green": self.KeyOk,
1487 self["filelist"] = MenuList(self.flist)
1489 self.onLayoutFinish.append(self.layoutFinished)
1491 def layoutFinished(self):
1492 self.setWindowTitle()
1494 def setWindowTitle(self):
1495 self.setTitle(_("Select upgrade source to edit."))
1497 def fill_list(self):
1499 self.path = '/etc/ipkg/'
1500 if (os_path.exists(self.path) == False):
1503 for file in listdir(self.path):
1504 if (file.endswith(".conf")):
1505 if file != 'arch.conf':
1506 self.flist.append((file))
1508 self["filelist"].l.setList(self.flist)
1511 if (self.exe == False) and (self.entry == True):
1512 self.sel = self["filelist"].getCurrent()
1513 self.val = self.path + self.sel
1514 self.session.open(IPKGSource, self.val)
1516 def keyCancel(self):
1523 class IPKGSource(Screen):
1525 <screen name="IPKGSource" position="center,center" size="560,80" title="Edit upgrade source url." >
1526 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1527 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1528 <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" />
1529 <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" />
1530 <widget name="text" position="5,50" size="550,25" font="Regular;20" backgroundColor="background" foregroundColor="#cccccc" />
1533 def __init__(self, session, configfile = None):
1534 Screen.__init__(self, session)
1535 self.session = session
1536 self.configfile = configfile
1540 fp = file(configfile, 'r')
1541 sources = fp.readlines()
1548 desk = getDesktop(0)
1549 x= int(desk.size().width())
1550 y= int(desk.size().height())
1552 self["key_red"] = StaticText(_("Cancel"))
1553 self["key_green"] = StaticText(_("Save"))
1556 self["text"] = Input(text, maxSize=False, type=Input.TEXT)
1558 self["text"] = Input(text, maxSize=False, visible_width = 55, type=Input.TEXT)
1560 self["actions"] = NumberActionMap(["WizardActions", "InputActions", "TextEntryActions", "KeyboardInputActions","ShortcutActions"],
1566 "left": self.keyLeft,
1567 "right": self.keyRight,
1568 "home": self.keyHome,
1570 "deleteForward": self.keyDeleteForward,
1571 "deleteBackward": self.keyDeleteBackward,
1572 "1": self.keyNumberGlobal,
1573 "2": self.keyNumberGlobal,
1574 "3": self.keyNumberGlobal,
1575 "4": self.keyNumberGlobal,
1576 "5": self.keyNumberGlobal,
1577 "6": self.keyNumberGlobal,
1578 "7": self.keyNumberGlobal,
1579 "8": self.keyNumberGlobal,
1580 "9": self.keyNumberGlobal,
1581 "0": self.keyNumberGlobal
1584 self.onLayoutFinish.append(self.layoutFinished)
1586 def layoutFinished(self):
1587 self.setWindowTitle()
1588 self["text"].right()
1590 def setWindowTitle(self):
1591 self.setTitle(_("Edit upgrade source url."))
1594 text = self["text"].getText()
1596 fp = file(self.configfile, 'w')
1606 self["text"].right()
1614 def keyDeleteForward(self):
1615 self["text"].delete()
1617 def keyDeleteBackward(self):
1618 self["text"].deleteBackward()
1620 def keyNumberGlobal(self, number):
1621 self["text"].number(number)
1624 class PacketManager(Screen, NumericalTextInput):
1626 <screen name="PacketManager" position="center,center" size="530,420" title="Packet manager" >
1627 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1628 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1629 <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" />
1630 <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" />
1631 <widget source="list" render="Listbox" position="5,50" size="520,365" scrollbarMode="showOnDemand">
1632 <convert type="TemplatedMultiContent">
1634 MultiContentEntryText(pos = (5, 1), size = (440, 28), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
1635 MultiContentEntryText(pos = (5, 26), size = (440, 20), font=1, flags = RT_HALIGN_LEFT, text = 2), # index 2 is the description
1636 MultiContentEntryPixmapAlphaTest(pos = (445, 2), size = (48, 48), png = 4), # index 4 is the status pixmap
1637 MultiContentEntryPixmapAlphaTest(pos = (5, 50), size = (510, 2), png = 5), # index 4 is the div pixmap
1639 "fonts": [gFont("Regular", 22),gFont("Regular", 14)],
1646 def __init__(self, session, plugin_path, args = None):
1647 Screen.__init__(self, session)
1648 NumericalTextInput.__init__(self)
1649 self.session = session
1650 self.skin_path = plugin_path
1652 self.setUseableChars(u'1234567890abcdefghijklmnopqrstuvwxyz')
1654 self["shortcuts"] = NumberActionMap(["ShortcutActions", "WizardActions", "NumberActions", "InputActions", "InputAsciiActions", "KeyboardInputActions" ],
1659 "green": self.reload,
1660 "gotAsciiCode": self.keyGotAscii,
1661 "1": self.keyNumberGlobal,
1662 "2": self.keyNumberGlobal,
1663 "3": self.keyNumberGlobal,
1664 "4": self.keyNumberGlobal,
1665 "5": self.keyNumberGlobal,
1666 "6": self.keyNumberGlobal,
1667 "7": self.keyNumberGlobal,
1668 "8": self.keyNumberGlobal,
1669 "9": self.keyNumberGlobal,
1670 "0": self.keyNumberGlobal
1674 self.statuslist = []
1675 self["list"] = List(self.list)
1676 self["key_red"] = StaticText(_("Close"))
1677 self["key_green"] = StaticText(_("Reload"))
1679 self.list_updating = True
1680 self.packetlist = []
1681 self.installed_packetlist = {}
1682 self.upgradeable_packages = {}
1683 self.Console = Console()
1686 self.cache_ttl = 86400 #600 is default, 0 disables, Seconds cache is considered valid (24h should be ok for caching ipkgs)
1687 self.cache_file = eEnv.resolve('${libdir}/enigma2/python/Plugins/SystemPlugins/SoftwareManager/packetmanager.cache') #Path to cache directory
1688 self.oktext = _("\nAfter pressing OK, please wait!")
1689 self.unwanted_extensions = ('-dbg', '-dev', '-doc', 'busybox')
1690 self.opkgAvail = fileExists('/usr/bin/opkg')
1692 self.ipkg = IpkgComponent()
1693 self.ipkg.addCallback(self.ipkgCallback)
1694 self.onShown.append(self.setWindowTitle)
1695 self.onLayoutFinish.append(self.rebuildList)
1697 rcinput = eRCInput.getInstance()
1698 rcinput.setKeyboardMode(rcinput.kmAscii)
1700 def keyNumberGlobal(self, val):
1701 key = self.getKey(val)
1703 keyvalue = key.encode("utf-8")
1704 if len(keyvalue) == 1:
1705 self.setNextIdx(keyvalue[0])
1707 def keyGotAscii(self):
1708 keyvalue = unichr(getPrevAsciiCode()).encode("utf-8")
1709 if len(keyvalue) == 1:
1710 self.setNextIdx(keyvalue[0])
1712 def setNextIdx(self,char):
1713 if char in ("0", "1", "a"):
1714 self["list"].setIndex(0)
1716 idx = self.getNextIdx(char)
1717 if idx and idx <= self["list"].count:
1718 self["list"].setIndex(idx)
1720 def getNextIdx(self,char):
1722 for i in self["list"].list:
1729 if self.Console is not None:
1730 if len(self.Console.appContainers):
1731 for name in self.Console.appContainers.keys():
1732 self.Console.kill(name)
1733 rcinput = eRCInput.getInstance()
1734 rcinput.setKeyboardMode(rcinput.kmNone)
1738 if (os_path.exists(self.cache_file) == True):
1739 remove(self.cache_file)
1740 self.list_updating = True
1743 def setWindowTitle(self):
1744 self.setTitle(_("Packet manager"))
1746 def setStatus(self,status = None):
1748 self.statuslist = []
1749 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
1750 if status == 'update':
1751 statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgrade.png"))
1752 self.statuslist.append(( _("Package list update"), '', _("Trying to download a new packetlist. Please wait..." ),'',statuspng, divpng ))
1753 self['list'].setList(self.statuslist)
1754 elif status == 'error':
1755 statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
1756 self.statuslist.append(( _("Error"), '', _("There was an error downloading the packetlist. Please try again." ),'',statuspng, divpng ))
1757 self['list'].setList(self.statuslist)
1759 def rebuildList(self):
1760 self.setStatus('update')
1762 self.vc = valid_cache(self.cache_file, self.cache_ttl)
1763 if self.cache_ttl > 0 and self.vc != 0:
1765 self.buildPacketList()
1768 if self.cache_ttl == 0 or self.inv_cache == 1 or self.vc == 0:
1770 self.ipkg.startCmd(IpkgComponent.CMD_UPDATE)
1772 def go(self, returnValue = None):
1773 cur = self["list"].getCurrent()
1778 if status == 'installed':
1779 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": package }))
1780 if len(self.cmdList):
1781 self.session.openWithCallback(self.runRemove, MessageBox, _("Do you want to remove the package:\n") + package + "\n" + self.oktext)
1782 elif status == 'upgradeable':
1783 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package }))
1784 if len(self.cmdList):
1785 self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to upgrade the package:\n") + package + "\n" + self.oktext)
1786 elif status == "installable":
1787 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package }))
1788 if len(self.cmdList):
1789 self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to install the package:\n") + package + "\n" + self.oktext)
1791 def runRemove(self, result):
1793 self.session.openWithCallback(self.runRemoveFinished, Ipkg, cmdList = self.cmdList)
1795 def runRemoveFinished(self):
1796 self.session.openWithCallback(self.RemoveReboot, MessageBox, _("Remove finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
1798 def RemoveReboot(self, result):
1802 cur = self["list"].getCurrent()
1804 item = self['list'].getIndex()
1805 self.list[item] = self.buildEntryComponent(cur[0], cur[1], cur[2], 'installable')
1806 self.cachelist[item] = [cur[0], cur[1], cur[2], 'installable']
1807 self['list'].setList(self.list)
1808 write_cache(self.cache_file, self.cachelist)
1809 self.reloadPluginlist()
1813 def runUpgrade(self, result):
1815 self.session.openWithCallback(self.runUpgradeFinished, Ipkg, cmdList = self.cmdList)
1817 def runUpgradeFinished(self):
1818 self.session.openWithCallback(self.UpgradeReboot, MessageBox, _("Upgrade finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
1820 def UpgradeReboot(self, result):
1824 cur = self["list"].getCurrent()
1826 item = self['list'].getIndex()
1827 self.list[item] = self.buildEntryComponent(cur[0], cur[1], cur[2], 'installed')
1828 self.cachelist[item] = [cur[0], cur[1], cur[2], 'installed']
1829 self['list'].setList(self.list)
1830 write_cache(self.cache_file, self.cachelist)
1831 self.reloadPluginlist()
1835 def ipkgCallback(self, event, param):
1836 if event == IpkgComponent.EVENT_ERROR:
1837 self.list_updating = False
1838 self.setStatus('error')
1839 elif event == IpkgComponent.EVENT_DONE:
1840 if self.list_updating:
1841 self.list_updating = False
1842 if not self.Console:
1843 self.Console = Console()
1845 self.Console.ePopen(cmd, self.IpkgList_Finished)
1846 #print event, "-", param
1849 def IpkgList_Finished(self, result, retval, extra_args = None):
1851 self.packetlist = []
1853 for x in result.splitlines():
1854 tokens = x.split(' - ')
1855 name = tokens[0].strip()
1856 if not any(name.endswith(x) for x in self.unwanted_extensions):
1858 version = l > 1 and tokens[1].strip() or ""
1859 descr = l > 2 and tokens[2].strip() or ""
1860 if name == last_name:
1863 self.packetlist.append([name, version, descr])
1865 if not self.Console:
1866 self.Console = Console()
1867 cmd = "ipkg list_installed"
1868 self.Console.ePopen(cmd, self.IpkgListInstalled_Finished)
1870 def IpkgListInstalled_Finished(self, result, retval, extra_args = None):
1872 self.installed_packetlist = {}
1873 for x in result.splitlines():
1874 tokens = x.split(' - ')
1875 name = tokens[0].strip()
1876 if not any(name.endswith(x) for x in self.unwanted_extensions):
1878 version = l > 1 and tokens[1].strip() or ""
1879 self.installed_packetlist[name] = version
1881 if not self.Console:
1882 self.Console = Console()
1883 cmd = "opkg list-upgradable"
1884 self.Console.ePopen(cmd, self.OpkgListUpgradeable_Finished)
1886 self.buildPacketList()
1888 def OpkgListUpgradeable_Finished(self, result, retval, extra_args = None):
1890 self.upgradeable_packages = {}
1891 for x in result.splitlines():
1892 tokens = x.split(' - ')
1893 name = tokens[0].strip()
1894 if not any(name.endswith(x) for x in self.unwanted_extensions):
1896 version = l > 2 and tokens[2].strip() or ""
1897 self.upgradeable_packages[name] = version
1898 self.buildPacketList()
1900 def buildEntryComponent(self, name, version, description, state):
1901 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
1902 if state == 'installed':
1903 installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installed.png"))
1904 return((name, version, _(description), state, installedpng, divpng))
1905 elif state == 'upgradeable':
1906 upgradeablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgradeable.png"))
1907 return((name, version, _(description), state, upgradeablepng, divpng))
1909 installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installable.png"))
1910 return((name, version, _(description), state, installablepng, divpng))
1912 def buildPacketList(self):
1915 if self.cache_ttl > 0 and self.vc != 0:
1916 print 'Loading packagelist cache from ',self.cache_file
1918 self.cachelist = load_cache(self.cache_file)
1919 if len(self.cachelist) > 0:
1920 for x in self.cachelist:
1921 self.list.append(self.buildEntryComponent(x[0], x[1], x[2], x[3]))
1922 self['list'].setList(self.list)
1926 if self.cache_ttl == 0 or self.inv_cache == 1 or self.vc == 0:
1927 print 'rebuilding fresh package list'
1928 for x in self.packetlist:
1930 if self.installed_packetlist.has_key(x[0]):
1932 if self.upgradeable_packages.has_key(x[0]):
1933 status = "upgradeable"
1935 status = "installed"
1937 if self.installed_packetlist[x[0]] == x[1]:
1938 status = "installed"
1940 status = "upgradeable"
1942 status = "installable"
1943 self.list.append(self.buildEntryComponent(x[0], x[1], x[2], status))
1944 self.cachelist.append([x[0], x[1], x[2], status])
1945 write_cache(self.cache_file, self.cachelist)
1946 self['list'].setList(self.list)
1948 def reloadPluginlist(self):
1949 plugins.readPluginList(resolveFilename(SCOPE_PLUGINS))
1952 class IpkgInstaller(Screen):
1954 <screen name="IpkgInstaller" position="center,center" size="550,450" title="Install extensions" >
1955 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1956 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1957 <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" />
1958 <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" />
1959 <widget name="list" position="5,50" size="540,360" />
1960 <ePixmap pixmap="skin_default/div-h.png" position="0,410" zPosition="10" size="560,2" transparent="1" alphatest="on" />
1961 <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" />
1964 def __init__(self, session, list):
1965 Screen.__init__(self, session)
1967 self.list = SelectionList()
1968 self["list"] = self.list
1969 for listindex in range(len(list)):
1970 self.list.addSelection(list[listindex], list[listindex], listindex, True)
1972 self["key_red"] = StaticText(_("Close"))
1973 self["key_green"] = StaticText(_("Install"))
1974 self["introduction"] = StaticText(_("Press OK to toggle the selection."))
1976 self["actions"] = ActionMap(["OkCancelActions", "ColorActions"],
1978 "ok": self.list.toggleSelection,
1979 "cancel": self.close,
1981 "green": self.install
1985 list = self.list.getSelectionsList()
1988 cmdList.append((IpkgComponent.CMD_INSTALL, { "package": item[1] }))
1989 self.session.open(Ipkg, cmdList = cmdList)
1992 def filescan_open(list, session, **kwargs):
1993 filelist = [x.path for x in list]
1994 session.open(IpkgInstaller, filelist) # list
1996 def filescan(**kwargs):
1997 from Components.Scanner import Scanner, ScanPath
1999 Scanner(mimetypes = ["application/x-debian-package"],
2002 ScanPath(path = "ipk", with_subdirs = True),
2003 ScanPath(path = "", with_subdirs = False),
2006 description = _("Install extensions."),
2007 openfnc = filescan_open, )
2011 def UpgradeMain(session, **kwargs):
2012 session.open(UpdatePluginMenu)
2014 def startSetup(menuid):
2015 if menuid != "setup":
2017 return [(_("Software management"), UpgradeMain, "software_manager", 50)]
2020 def Plugins(path, **kwargs):
2024 PluginDescriptor(name=_("Software management"), description=_("Manage your receiver's software"), where = PluginDescriptor.WHERE_MENU, fnc=startSetup),
2025 PluginDescriptor(name=_("Ipkg"), where = PluginDescriptor.WHERE_FILESCAN, fnc = filescan)
2027 if config.usage.setup_level.index >= 2: # expert+
2028 list.append(PluginDescriptor(name=_("Software management"), description=_("Manage your receiver's software"), where = PluginDescriptor.WHERE_EXTENSIONSMENU, fnc=UpgradeMain))