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
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=['/etc/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 statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
613 self.statuslist.append(( _("Error"), '', _("There was an error downloading the packetlist. Please try again." ),'', '', statuspng, divpng, None, '' ))
614 self["list"].style = "default"
615 self['list'].setList(self.statuslist)
618 def getUpdateInfos(self):
619 self.setState('update')
620 iSoftwareTools.startSoftwareTools(self.getUpdateInfosCB)
622 def getUpdateInfosCB(self, retval = None):
623 if retval is not None:
625 if iSoftwareTools.available_updates is not 0:
626 self["status"].setText(_("There are at least ") + str(iSoftwareTools.available_updates) + _(" updates available."))
628 self["status"].setText(_("There are no updates available."))
630 elif retval is False:
631 self.setState('error')
632 if iSoftwareTools.NetworkConnectionAvailable:
633 self["status"].setText(_("Updatefeed not available."))
635 self["status"].setText(_("No network connection available."))
637 def rebuildList(self, retval = None):
638 if self.currentSelectedTag is None:
639 self.buildCategoryList()
641 self.buildPacketList(self.currentSelectedTag)
643 def selectionChanged(self):
644 current = self["list"].getCurrent()
645 self["status"].setText("")
647 if self.currList == "packages":
648 self["key_red"].setText(_("Back"))
649 if current[4] == 'installed':
650 self["key_green"].setText(_("Uninstall"))
651 elif current[4] == 'installable':
652 self["key_green"].setText(_("Install"))
653 elif current[4] == 'remove':
654 self["key_green"].setText(_("Undo uninstall"))
655 elif current[4] == 'install':
656 self["key_green"].setText(_("Undo install"))
657 self["key_yellow"].setText(_("View details"))
658 self["key_blue"].setText("")
659 if len(self.selectedFiles) == 0 and iSoftwareTools.available_updates is not 0:
660 self["status"].setText(_("There are at least ") + str(iSoftwareTools.available_updates) + _(" updates available."))
661 elif len(self.selectedFiles) is not 0:
662 self["status"].setText(str(len(self.selectedFiles)) + _(" packages selected."))
664 self["status"].setText(_("There are currently no outstanding actions."))
665 elif self.currList == "category":
666 self["key_red"].setText(_("Close"))
667 self["key_green"].setText("")
668 self["key_yellow"].setText("")
669 self["key_blue"].setText("")
670 if len(self.selectedFiles) == 0 and iSoftwareTools.available_updates is not 0:
671 self["status"].setText(_("There are at least ") + str(iSoftwareTools.available_updates) + _(" updates available."))
672 self["key_yellow"].setText(_("Update"))
673 elif len(self.selectedFiles) is not 0:
674 self["status"].setText(str(len(self.selectedFiles)) + _(" packages selected."))
675 self["key_yellow"].setText(_("Process"))
677 self["status"].setText(_("There are currently no outstanding actions."))
679 def getSelectionState(self, detailsFile):
680 for entry in self.selectedFiles:
681 if entry[0] == detailsFile:
685 def handleCurrent(self):
686 current = self["list"].getCurrent()
688 if self.currList == "category":
689 self.currentSelectedIndex = self["list"].index
690 selectedTag = current[2]
691 self.buildPacketList(selectedTag)
692 elif self.currList == "packages":
693 if current[7] is not '':
694 idx = self["list"].getIndex()
695 detailsFile = self.list[idx][1]
696 if self.list[idx][7] == True:
697 for entry in self.selectedFiles:
698 if entry[0] == detailsFile:
699 self.selectedFiles.remove(entry)
701 alreadyinList = False
702 for entry in self.selectedFiles:
703 if entry[0] == detailsFile:
705 if not alreadyinList:
706 self.selectedFiles.append((detailsFile,current[4],current[3]))
707 self.currentSelectedPackage = ((detailsFile,current[4],current[3]))
708 if current[4] == 'installed':
709 self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'remove', True)
710 elif current[4] == 'installable':
711 self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'install', True)
712 elif current[4] == 'remove':
713 self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'installed', False)
714 elif current[4] == 'install':
715 self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'installable',False)
716 self["list"].setList(self.list)
717 self["list"].setIndex(idx)
718 self["list"].updateList(self.list)
719 self.selectionChanged()
721 def handleSelected(self):
722 current = self["list"].getCurrent()
724 if self.currList == "packages":
725 if current[7] is not '':
726 detailsfile = iSoftwareTools.directory[0] + "/" + current[1]
727 if (os_path.exists(detailsfile) == True):
728 self.saved_currentSelectedPackage = self.currentSelectedPackage
729 self.session.openWithCallback(self.detailsClosed, PluginDetails, self.skin_path, current)
731 self.session.open(MessageBox, _("Sorry, no Details available!"), MessageBox.TYPE_INFO, timeout = 10)
732 elif self.currList == "category":
733 self.prepareInstall()
734 if len(self.cmdList):
735 self.session.openWithCallback(self.runExecute, PluginManagerInfo, self.skin_path, self.cmdList)
737 def detailsClosed(self, result = None):
738 if result is not None:
739 if result is not False:
740 self.setState('sync')
741 iSoftwareTools.lastDownloadDate = time()
742 for entry in self.selectedFiles:
743 if entry == self.saved_currentSelectedPackage:
744 self.selectedFiles.remove(entry)
745 iSoftwareTools.startIpkgListInstalled(self.rebuildList)
747 def buildEntryComponent(self, name, details, description, packagename, state, selected = False):
748 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
749 installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installed.png"))
750 installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installable.png"))
751 removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
752 installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/install.png"))
753 if state == 'installed':
754 return((name, details, description, packagename, state, installedpng, divpng, selected))
755 elif state == 'installable':
756 return((name, details, description, packagename, state, installablepng, divpng, selected))
757 elif state == 'remove':
758 return((name, details, description, packagename, state, removepng, divpng, selected))
759 elif state == 'install':
760 return((name, details, description, packagename, state, installpng, divpng, selected))
762 def buildPacketList(self, categorytag = None):
763 if categorytag is not None:
764 self.currList = "packages"
765 self.currentSelectedTag = categorytag
767 for package in iSoftwareTools.packagesIndexlist[:]:
768 prerequisites = package[0]["prerequisites"]
769 if prerequisites.has_key("tag"):
770 for foundtag in prerequisites["tag"]:
771 if categorytag == foundtag:
772 attributes = package[0]["attributes"]
773 if attributes.has_key("packagetype"):
774 if attributes["packagetype"] == "internal":
776 self.packetlist.append([attributes["name"], attributes["details"], attributes["shortdescription"], attributes["packagename"]])
778 self.packetlist.append([attributes["name"], attributes["details"], attributes["shortdescription"], attributes["packagename"]])
780 for x in self.packetlist:
783 details = x[1].strip()
784 description = x[2].strip()
785 packagename = x[3].strip()
786 selectState = self.getSelectionState(details)
787 if iSoftwareTools.installed_packetlist.has_key(packagename):
788 if selectState == True:
792 self.list.append(self.buildEntryComponent(name, _(details), _(description), packagename, status, selected = selectState))
794 if selectState == True:
797 status = "installable"
798 self.list.append(self.buildEntryComponent(name, _(details), _(description), packagename, status, selected = selectState))
800 self.list.sort(key=lambda x: x[0])
801 self["list"].style = "default"
802 self['list'].setList(self.list)
803 self["list"].updateList(self.list)
804 self.selectionChanged()
806 def buildCategoryList(self):
807 self.currList = "category"
809 self.categoryList = []
810 for package in iSoftwareTools.packagesIndexlist[:]:
811 prerequisites = package[0]["prerequisites"]
812 if prerequisites.has_key("tag"):
813 for foundtag in prerequisites["tag"]:
814 attributes = package[0]["attributes"]
815 if foundtag not in self.categories:
816 self.categories.append(foundtag)
817 self.categoryList.append(self.buildCategoryComponent(foundtag))
818 self.categoryList.sort(key=lambda x: x[0])
819 self["list"].style = "category"
820 self['list'].setList(self.categoryList)
821 self["list"].updateList(self.categoryList)
822 self.selectionChanged()
824 def buildCategoryComponent(self, tag = None):
825 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
828 return(( _("System"), _("View list of available system extensions" ), tag, divpng ))
830 return(( _("Skins"), _("View list of available skins" ), tag, divpng ))
831 elif tag == 'Recording':
832 return(( _("Recordings"), _("View list of available recording extensions" ), tag, divpng ))
833 elif tag == 'Network':
834 return(( _("Network"), _("View list of available networking extensions" ), tag, divpng ))
836 return(( _("CommonInterface"), _("View list of available CommonInterface extensions" ), tag, divpng ))
837 elif tag == 'Default':
838 return(( _("Default Settings"), _("View list of available default settings" ), tag, divpng ))
840 return(( _("Satellite equipment"), _("View list of available Satellite equipment extensions." ), tag, divpng ))
841 elif tag == 'Software':
842 return(( _("Software"), _("View list of available software extensions" ), tag, divpng ))
843 elif tag == 'Multimedia':
844 return(( _("Multimedia"), _("View list of available multimedia extensions." ), tag, divpng ))
845 elif tag == 'Display':
846 return(( _("Display and Userinterface"), _("View list of available Display and Userinterface extensions." ), tag, divpng ))
848 return(( _("Electronic Program Guide"), _("View list of available EPG extensions." ), tag, divpng ))
849 elif tag == 'Communication':
850 return(( _("Communication"), _("View list of available communication extensions." ), tag, divpng ))
851 else: # dynamically generate non existent tags
852 return(( str(tag), _("View list of available ") + str(tag) + _(" extensions." ), tag, divpng ))
854 def prepareInstall(self):
856 if iSoftwareTools.available_updates > 0:
857 self.cmdList.append((IpkgComponent.CMD_UPGRADE, { "test_only": False }))
858 if self.selectedFiles and len(self.selectedFiles):
859 for plugin in self.selectedFiles:
860 detailsfile = iSoftwareTools.directory[0] + "/" + plugin[0]
861 if (os_path.exists(detailsfile) == True):
862 iSoftwareTools.fillPackageDetails(plugin[0])
863 self.package = iSoftwareTools.packageDetails[0]
864 if self.package[0].has_key("attributes"):
865 self.attributes = self.package[0]["attributes"]
866 if self.attributes.has_key("package"):
867 self.packagefiles = self.attributes["package"]
868 if plugin[1] == 'installed':
869 if self.packagefiles:
870 for package in self.packagefiles[:]:
871 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": package["name"] }))
873 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": plugin[2] }))
875 if self.packagefiles:
876 for package in self.packagefiles[:]:
877 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package["name"] }))
879 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": plugin[2] }))
881 if plugin[1] == 'installed':
882 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": plugin[2] }))
884 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": plugin[2] }))
886 def runExecute(self, result = None):
887 if result is not None:
888 if result[0] is True:
889 self.session.openWithCallback(self.runExecuteFinished, Ipkg, cmdList = self.cmdList)
890 elif result[0] is False:
891 self.cmdList = result[1]
892 self.session.openWithCallback(self.runExecuteFinished, Ipkg, cmdList = self.cmdList)
896 def runExecuteFinished(self):
897 self.session.openWithCallback(self.ExecuteReboot, MessageBox, _("Install or remove finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
899 def ExecuteReboot(self, result):
903 self.reloadPluginlist()
904 self.selectedFiles = []
905 self.detailsClosed(True)
909 def reloadPluginlist(self):
910 plugins.readPluginList(resolveFilename(SCOPE_PLUGINS))
913 class PluginManagerInfo(Screen):
915 <screen name="PluginManagerInfo" position="center,center" size="560,450" title="Plugin manager activity information" >
916 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
917 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
918 <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" />
919 <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" />
920 <widget source="list" render="Listbox" position="5,50" size="550,350" scrollbarMode="showOnDemand" selectionDisabled="1">
921 <convert type="TemplatedMultiContent">
923 MultiContentEntryText(pos = (50, 0), size = (150, 26), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
924 MultiContentEntryText(pos = (50, 27), size = (540, 23), font=1, flags = RT_HALIGN_LEFT, text = 1), # index 1 is the state
925 MultiContentEntryPixmapAlphaTest(pos = (0, 1), size = (48, 48), png = 2), # index 2 is the status pixmap
926 MultiContentEntryPixmapAlphaTest(pos = (0, 48), size = (550, 2), png = 3), # index 3 is the div pixmap
928 "fonts": [gFont("Regular", 24),gFont("Regular", 22)],
933 <ePixmap pixmap="skin_default/div-h.png" position="0,404" zPosition="10" size="560,2" transparent="1" alphatest="on" />
934 <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" />
937 def __init__(self, session, plugin_path, cmdlist = None):
938 Screen.__init__(self, session)
939 self.session = session
940 self.skin_path = plugin_path
941 self.cmdlist = cmdlist
943 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"],
945 "ok": self.process_all,
948 "green": self.process_extensions,
952 self["list"] = List(self.list)
953 self["key_red"] = StaticText(_("Cancel"))
954 self["key_green"] = StaticText(_("Only extensions."))
955 self["status"] = StaticText(_("Following tasks will be done after you press OK!"))
957 self.onShown.append(self.setWindowTitle)
958 self.onLayoutFinish.append(self.rebuildList)
960 def setWindowTitle(self):
961 self.setTitle(_("Plugin manager activity information"))
963 def rebuildList(self):
965 if self.cmdlist is not None:
966 for entry in self.cmdlist:
978 info = args['package']
980 info = args['package']
982 info = _("Dreambox software because updates are available.")
984 self.list.append(self.buildEntryComponent(action,info))
985 self['list'].setList(self.list)
986 self['list'].updateList(self.list)
988 def buildEntryComponent(self, action,info):
989 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
990 upgradepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgrade.png"))
991 installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/install.png"))
992 removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
993 if action == 'install':
994 return(( _('Installing'), info, installpng, divpng))
995 elif action == 'remove':
996 return(( _('Removing'), info, removepng, divpng))
998 return(( _('Upgrading'), info, upgradepng, divpng))
1003 def process_all(self):
1004 self.close((True,None))
1006 def process_extensions(self):
1008 if self.cmdlist is not None:
1009 for entry in self.cmdlist:
1011 if entry[0] in (0,2):
1012 self.list.append((entry))
1013 self.close((False,self.list))
1016 class PluginManagerHelp(Screen):
1018 <screen name="PluginManagerHelp" position="center,center" size="560,450" title="Plugin manager help" >
1019 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1020 <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" />
1021 <widget source="list" render="Listbox" position="5,50" size="550,350" scrollbarMode="showOnDemand" selectionDisabled="1">
1022 <convert type="TemplatedMultiContent">
1024 MultiContentEntryText(pos = (50, 0), size = (540, 26), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
1025 MultiContentEntryText(pos = (50, 27), size = (540, 23), font=1, flags = RT_HALIGN_LEFT, text = 1), # index 1 is the state
1026 MultiContentEntryPixmapAlphaTest(pos = (0, 1), size = (48, 48), png = 2), # index 2 is the status pixmap
1027 MultiContentEntryPixmapAlphaTest(pos = (0, 48), size = (550, 2), png = 3), # index 3 is the div pixmap
1029 "fonts": [gFont("Regular", 24),gFont("Regular", 22)],
1034 <ePixmap pixmap="skin_default/div-h.png" position="0,404" zPosition="10" size="560,2" transparent="1" alphatest="on" />
1035 <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" />
1038 def __init__(self, session, plugin_path):
1039 Screen.__init__(self, session)
1040 self.session = session
1041 self.skin_path = plugin_path
1043 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"],
1050 self["list"] = List(self.list)
1051 self["key_red"] = StaticText(_("Close"))
1052 self["status"] = StaticText(_("A small overview of the available icon states and actions."))
1054 self.onShown.append(self.setWindowTitle)
1055 self.onLayoutFinish.append(self.rebuildList)
1057 def setWindowTitle(self):
1058 self.setTitle(_("Plugin manager help"))
1060 def rebuildList(self):
1062 self.list.append(self.buildEntryComponent('install'))
1063 self.list.append(self.buildEntryComponent('installable'))
1064 self.list.append(self.buildEntryComponent('installed'))
1065 self.list.append(self.buildEntryComponent('remove'))
1066 self['list'].setList(self.list)
1067 self['list'].updateList(self.list)
1069 def buildEntryComponent(self, state):
1070 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
1071 installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installed.png"))
1072 installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installable.png"))
1073 removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
1074 installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/install.png"))
1076 if state == 'installed':
1077 return(( _('This plugin is installed.'), _('You can remove this plugin.'), installedpng, divpng))
1078 elif state == 'installable':
1079 return(( _('This plugin is not installed.'), _('You can install this plugin.'), installablepng, divpng))
1080 elif state == 'install':
1081 return(( _('This plugin will be installed.'), _('You can cancel the installation.'), installpng, divpng))
1082 elif state == 'remove':
1083 return(( _('This plugin will be removed.'), _('You can cancel the removal.'), removepng, divpng))
1089 class PluginDetails(Screen, DreamInfoHandler):
1091 <screen name="PluginDetails" position="center,center" size="600,440" title="Plugin details" >
1092 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1093 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1094 <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" />
1095 <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" />
1096 <widget source="author" render="Label" position="10,50" size="500,25" zPosition="10" font="Regular;21" transparent="1" />
1097 <widget name="statuspic" position="550,40" size="48,48" alphatest="on"/>
1098 <widget name="divpic" position="0,80" size="600,2" alphatest="on"/>
1099 <widget name="detailtext" position="10,90" size="270,330" zPosition="10" font="Regular;21" transparent="1" halign="left" valign="top"/>
1100 <widget name="screenshot" position="290,90" size="300,330" alphatest="on"/>
1102 def __init__(self, session, plugin_path, packagedata = None):
1103 Screen.__init__(self, session)
1104 self.skin_path = plugin_path
1105 self.language = language.getLanguage()[:2] # getLanguage returns e.g. "fi_FI" for "language_country"
1106 self.attributes = None
1107 DreamInfoHandler.__init__(self, self.statusCallback, blocking = False)
1108 self.directory = resolveFilename(SCOPE_METADIR)
1110 self.pluginname = packagedata[0]
1111 self.details = packagedata[1]
1112 self.pluginstate = packagedata[4]
1113 self.statuspicinstance = packagedata[5]
1114 self.divpicinstance = packagedata[6]
1115 self.fillPackageDetails(self.details)
1119 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"],
1125 "down": self.pageDown,
1126 "left": self.pageUp,
1127 "right": self.pageDown,
1130 self["key_red"] = StaticText(_("Close"))
1131 self["key_green"] = StaticText("")
1132 self["author"] = StaticText()
1133 self["statuspic"] = Pixmap()
1134 self["divpic"] = Pixmap()
1135 self["screenshot"] = Pixmap()
1136 self["detailtext"] = ScrollLabel()
1138 self["statuspic"].hide()
1139 self["screenshot"].hide()
1140 self["divpic"].hide()
1142 self.package = self.packageDetails[0]
1143 if self.package[0].has_key("attributes"):
1144 self.attributes = self.package[0]["attributes"]
1147 self.oktext = _("\nAfter pressing OK, please wait!")
1148 self.picload = ePicLoad()
1149 self.picload.PictureData.get().append(self.paintScreenshotPixmapCB)
1150 self.onShown.append(self.setWindowTitle)
1151 self.onLayoutFinish.append(self.setInfos)
1153 def setWindowTitle(self):
1154 self.setTitle(_("Details for plugin: ") + self.pluginname )
1160 self["detailtext"].pageUp()
1163 self["detailtext"].pageDown()
1165 def statusCallback(self, status, progress):
1169 if self.attributes.has_key("screenshot"):
1170 self.loadThumbnail(self.attributes)
1172 if self.attributes.has_key("name"):
1173 self.pluginname = self.attributes["name"]
1175 self.pluginname = _("unknown")
1177 if self.attributes.has_key("author"):
1178 self.author = self.attributes["author"]
1180 self.author = _("unknown")
1182 if self.attributes.has_key("description"):
1183 self.description = _(self.attributes["description"].replace("\\n", "\n"))
1185 self.description = _("No description available.")
1187 self["author"].setText(_("Author: ") + self.author)
1188 self["detailtext"].setText(_(self.description))
1189 if self.pluginstate in ('installable', 'install'):
1190 self["key_green"].setText(_("Install"))
1192 self["key_green"].setText(_("Remove"))
1194 def loadThumbnail(self, entry):
1196 if entry.has_key("screenshot"):
1197 thumbnailUrl = entry["screenshot"]
1198 if self.language == "de":
1199 if thumbnailUrl[-7:] == "_en.jpg":
1200 thumbnailUrl = thumbnailUrl[:-7] + "_de.jpg"
1202 if thumbnailUrl is not None:
1203 self.thumbnail = "/tmp/" + thumbnailUrl.split('/')[-1]
1204 print "[PluginDetails] downloading screenshot " + thumbnailUrl + " to " + self.thumbnail
1205 client.downloadPage(thumbnailUrl,self.thumbnail).addCallback(self.setThumbnail).addErrback(self.fetchFailed)
1207 self.setThumbnail(noScreenshot = True)
1209 def setThumbnail(self, noScreenshot = False):
1210 if not noScreenshot:
1211 filename = self.thumbnail
1213 filename = resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/noprev.png")
1215 sc = AVSwitch().getFramebufferScale()
1216 self.picload.setPara((self["screenshot"].instance.size().width(), self["screenshot"].instance.size().height(), sc[0], sc[1], False, 1, "#00000000"))
1217 self.picload.startDecode(filename)
1219 if self.statuspicinstance != None:
1220 self["statuspic"].instance.setPixmap(self.statuspicinstance.__deref__())
1221 self["statuspic"].show()
1222 if self.divpicinstance != None:
1223 self["divpic"].instance.setPixmap(self.divpicinstance.__deref__())
1224 self["divpic"].show()
1226 def paintScreenshotPixmapCB(self, picInfo=None):
1227 ptr = self.picload.getData()
1229 self["screenshot"].instance.setPixmap(ptr.__deref__())
1230 self["screenshot"].show()
1232 self.setThumbnail(noScreenshot = True)
1235 if self.attributes.has_key("package"):
1236 self.packagefiles = self.attributes["package"]
1238 if self.pluginstate in ('installed', 'remove'):
1239 if self.packagefiles:
1240 for package in self.packagefiles[:]:
1241 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": package["name"] }))
1242 if len(self.cmdList):
1243 self.session.openWithCallback(self.runRemove, MessageBox, _("Do you want to remove the package:\n") + self.pluginname + "\n" + self.oktext)
1245 if self.packagefiles:
1246 for package in self.packagefiles[:]:
1247 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package["name"] }))
1248 if len(self.cmdList):
1249 self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to install the package:\n") + self.pluginname + "\n" + self.oktext)
1251 def runUpgrade(self, result):
1253 self.session.openWithCallback(self.runUpgradeFinished, Ipkg, cmdList = self.cmdList)
1255 def runUpgradeFinished(self):
1256 self.session.openWithCallback(self.UpgradeReboot, MessageBox, _("Installation finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
1258 def UpgradeReboot(self, result):
1266 def runRemove(self, result):
1268 self.session.openWithCallback(self.runRemoveFinished, Ipkg, cmdList = self.cmdList)
1270 def runRemoveFinished(self):
1271 self.session.openWithCallback(self.RemoveReboot, MessageBox, _("Remove finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
1273 def RemoveReboot(self, result):
1281 def reloadPluginlist(self):
1282 plugins.readPluginList(resolveFilename(SCOPE_PLUGINS))
1284 def fetchFailed(self,string):
1285 self.setThumbnail(noScreenshot = True)
1286 print "[PluginDetails] fetch failed " + string.getErrorMessage()
1289 class UpdatePlugin(Screen):
1291 <screen name="UpdatePlugin" position="center,center" size="550,300" title="Software update" >
1292 <widget name="activityslider" position="0,0" size="550,5" />
1293 <widget name="slider" position="0,150" size="550,30" />
1294 <widget source="package" render="Label" position="10,30" size="540,20" font="Regular;18" halign="center" valign="center" backgroundColor="#25062748" transparent="1" />
1295 <widget source="status" render="Label" position="10,60" size="540,45" font="Regular;20" halign="center" valign="center" backgroundColor="#25062748" transparent="1" />
1298 def __init__(self, session, args = None):
1299 Screen.__init__(self, session)
1301 self.sliderPackages = { "dreambox-dvb-modules": 1, "enigma2": 2, "tuxbox-image-info": 3 }
1303 self.slider = Slider(0, 4)
1304 self["slider"] = self.slider
1305 self.activityslider = Slider(0, 100)
1306 self["activityslider"] = self.activityslider
1307 self.status = StaticText(_("Upgrading Dreambox... Please wait"))
1308 self["status"] = self.status
1309 self.package = StaticText()
1310 self["package"] = self.package
1311 self.oktext = _("Press OK on your remote control to continue.")
1315 self.processed_packages = []
1318 self.activityTimer = eTimer()
1319 self.activityTimer.callback.append(self.doActivityTimer)
1320 self.activityTimer.start(100, False)
1322 self.ipkg = IpkgComponent()
1323 self.ipkg.addCallback(self.ipkgCallback)
1325 self.updating = True
1326 self.package.setText(_("Package list update"))
1327 self.ipkg.startCmd(IpkgComponent.CMD_UPDATE)
1329 self["actions"] = ActionMap(["WizardActions"],
1335 def doActivityTimer(self):
1337 if self.activity == 100:
1339 self.activityslider.setValue(self.activity)
1341 def ipkgCallback(self, event, param):
1342 if event == IpkgComponent.EVENT_DOWNLOAD:
1343 self.status.setText(_("Downloading"))
1344 elif event == IpkgComponent.EVENT_UPGRADE:
1345 if self.sliderPackages.has_key(param):
1346 self.slider.setValue(self.sliderPackages[param])
1347 self.package.setText(param)
1348 self.status.setText(_("Upgrading"))
1349 if not param in self.processed_packages:
1350 self.processed_packages.append(param)
1352 elif event == IpkgComponent.EVENT_INSTALL:
1353 self.package.setText(param)
1354 self.status.setText(_("Installing"))
1355 if not param in self.processed_packages:
1356 self.processed_packages.append(param)
1358 elif event == IpkgComponent.EVENT_REMOVE:
1359 self.package.setText(param)
1360 self.status.setText(_("Removing"))
1361 if not param in self.processed_packages:
1362 self.processed_packages.append(param)
1364 elif event == IpkgComponent.EVENT_CONFIGURING:
1365 self.package.setText(param)
1366 self.status.setText(_("Configuring"))
1368 elif event == IpkgComponent.EVENT_MODIFIED:
1369 if config.plugins.SoftwareManager.overwriteConfigFiles.value in ("N", "Y"):
1370 self.ipkg.write(True and config.plugins.SoftwareManager.overwriteConfigFiles.value)
1372 self.session.openWithCallback(
1373 self.modificationCallback,
1375 _("A configuration file (%s) was modified since Installation.\nDo you want to keep your version?") % (param)
1377 elif event == IpkgComponent.EVENT_ERROR:
1379 elif event == IpkgComponent.EVENT_DONE:
1381 self.updating = False
1382 self.ipkg.startCmd(IpkgComponent.CMD_UPGRADE, args = {'test_only': False})
1383 elif self.error == 0:
1384 self.slider.setValue(4)
1386 self.activityTimer.stop()
1387 self.activityslider.setValue(0)
1389 self.package.setText("")
1390 self.status.setText(_("Done - Installed or upgraded %d packages") % self.packages + "\n\n" + self.oktext)
1392 self.activityTimer.stop()
1393 self.activityslider.setValue(0)
1394 error = _("your dreambox might be unusable now. Please consult the manual for further assistance before rebooting your dreambox.")
1395 if self.packages == 0:
1396 error = _("No packages were upgraded yet. So you can check your network and try again.")
1398 error = _("Your dreambox isn't connected to the internet properly. Please check it and try again.")
1399 self.status.setText(_("Error") + " - " + error)
1400 #print event, "-", param
1403 def modificationCallback(self, res):
1404 self.ipkg.write(res and "N" or "Y")
1407 if not self.ipkg.isRunning():
1408 if self.packages != 0 and self.error == 0:
1409 self.session.openWithCallback(self.exitAnswer, MessageBox, _("Upgrade finished.") +" "+_("Do you want to reboot your Dreambox?"))
1413 def exitAnswer(self, result):
1414 if result is not None and result:
1420 class IPKGMenu(Screen):
1422 <screen name="IPKGMenu" position="center,center" size="560,400" title="Select upgrade source to edit." >
1423 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1424 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1425 <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" />
1426 <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" />
1427 <widget name="filelist" position="5,50" size="550,340" scrollbarMode="showOnDemand" />
1430 def __init__(self, session, plugin_path):
1431 Screen.__init__(self, session)
1432 self.skin_path = plugin_path
1434 self["key_red"] = StaticText(_("Close"))
1435 self["key_green"] = StaticText(_("Edit"))
1444 self["actions"] = NumberActionMap(["SetupActions"],
1447 "cancel": self.keyCancel
1450 self["shortcuts"] = ActionMap(["ShortcutActions"],
1452 "red": self.keyCancel,
1453 "green": self.KeyOk,
1456 self["filelist"] = MenuList(self.flist)
1458 self.onLayoutFinish.append(self.layoutFinished)
1460 def layoutFinished(self):
1461 self.setWindowTitle()
1463 def setWindowTitle(self):
1464 self.setTitle(_("Select upgrade source to edit."))
1466 def fill_list(self):
1468 self.path = '/etc/ipkg/'
1469 if (os_path.exists(self.path) == False):
1472 for file in listdir(self.path):
1473 if (file.endswith(".conf")):
1474 if file != 'arch.conf':
1475 self.flist.append((file))
1477 self["filelist"].l.setList(self.flist)
1480 if (self.exe == False) and (self.entry == True):
1481 self.sel = self["filelist"].getCurrent()
1482 self.val = self.path + self.sel
1483 self.session.open(IPKGSource, self.val)
1485 def keyCancel(self):
1492 class IPKGSource(Screen):
1494 <screen name="IPKGSource" position="center,center" size="560,80" title="Edit upgrade source url." >
1495 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1496 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1497 <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" />
1498 <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" />
1499 <widget name="text" position="5,50" size="550,25" font="Regular;20" backgroundColor="background" foregroundColor="#cccccc" />
1502 def __init__(self, session, configfile = None):
1503 Screen.__init__(self, session)
1504 self.session = session
1505 self.configfile = configfile
1509 fp = file(configfile, 'r')
1510 sources = fp.readlines()
1517 desk = getDesktop(0)
1518 x= int(desk.size().width())
1519 y= int(desk.size().height())
1521 self["key_red"] = StaticText(_("Cancel"))
1522 self["key_green"] = StaticText(_("Save"))
1525 self["text"] = Input(text, maxSize=False, type=Input.TEXT)
1527 self["text"] = Input(text, maxSize=False, visible_width = 55, type=Input.TEXT)
1529 self["actions"] = NumberActionMap(["WizardActions", "InputActions", "TextEntryActions", "KeyboardInputActions","ShortcutActions"],
1535 "left": self.keyLeft,
1536 "right": self.keyRight,
1537 "home": self.keyHome,
1539 "deleteForward": self.keyDeleteForward,
1540 "deleteBackward": self.keyDeleteBackward,
1541 "1": self.keyNumberGlobal,
1542 "2": self.keyNumberGlobal,
1543 "3": self.keyNumberGlobal,
1544 "4": self.keyNumberGlobal,
1545 "5": self.keyNumberGlobal,
1546 "6": self.keyNumberGlobal,
1547 "7": self.keyNumberGlobal,
1548 "8": self.keyNumberGlobal,
1549 "9": self.keyNumberGlobal,
1550 "0": self.keyNumberGlobal
1553 self.onLayoutFinish.append(self.layoutFinished)
1555 def layoutFinished(self):
1556 self.setWindowTitle()
1557 self["text"].right()
1559 def setWindowTitle(self):
1560 self.setTitle(_("Edit upgrade source url."))
1563 text = self["text"].getText()
1565 fp = file(self.configfile, 'w')
1575 self["text"].right()
1583 def keyDeleteForward(self):
1584 self["text"].delete()
1586 def keyDeleteBackward(self):
1587 self["text"].deleteBackward()
1589 def keyNumberGlobal(self, number):
1590 self["text"].number(number)
1593 class PacketManager(Screen, NumericalTextInput):
1595 <screen name="PacketManager" position="center,center" size="530,420" title="Packet manager" >
1596 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1597 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1598 <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" />
1599 <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" />
1600 <widget source="list" render="Listbox" position="5,50" size="520,365" scrollbarMode="showOnDemand">
1601 <convert type="TemplatedMultiContent">
1603 MultiContentEntryText(pos = (5, 1), size = (440, 28), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
1604 MultiContentEntryText(pos = (5, 26), size = (440, 20), font=1, flags = RT_HALIGN_LEFT, text = 2), # index 2 is the description
1605 MultiContentEntryPixmapAlphaTest(pos = (445, 2), size = (48, 48), png = 4), # index 4 is the status pixmap
1606 MultiContentEntryPixmapAlphaTest(pos = (5, 50), size = (510, 2), png = 5), # index 4 is the div pixmap
1608 "fonts": [gFont("Regular", 22),gFont("Regular", 14)],
1615 def __init__(self, session, plugin_path, args = None):
1616 Screen.__init__(self, session)
1617 NumericalTextInput.__init__(self)
1618 self.session = session
1619 self.skin_path = plugin_path
1621 self.setUseableChars(u'1234567890abcdefghijklmnopqrstuvwxyz')
1623 self["shortcuts"] = NumberActionMap(["ShortcutActions", "WizardActions", "NumberActions", "InputActions", "InputAsciiActions", "KeyboardInputActions" ],
1628 "green": self.reload,
1629 "gotAsciiCode": self.keyGotAscii,
1630 "1": self.keyNumberGlobal,
1631 "2": self.keyNumberGlobal,
1632 "3": self.keyNumberGlobal,
1633 "4": self.keyNumberGlobal,
1634 "5": self.keyNumberGlobal,
1635 "6": self.keyNumberGlobal,
1636 "7": self.keyNumberGlobal,
1637 "8": self.keyNumberGlobal,
1638 "9": self.keyNumberGlobal,
1639 "0": self.keyNumberGlobal
1643 self.statuslist = []
1644 self["list"] = List(self.list)
1645 self["key_red"] = StaticText(_("Close"))
1646 self["key_green"] = StaticText(_("Reload"))
1648 self.list_updating = True
1649 self.packetlist = []
1650 self.installed_packetlist = {}
1651 self.Console = Console()
1654 self.cache_ttl = 86400 #600 is default, 0 disables, Seconds cache is considered valid (24h should be ok for caching ipkgs)
1655 self.cache_file = '/usr/lib/enigma2/python/Plugins/SystemPlugins/SoftwareManager/packetmanager.cache' #Path to cache directory
1656 self.oktext = _("\nAfter pressing OK, please wait!")
1657 self.unwanted_extensions = ('-dbg', '-dev', '-doc', 'busybox')
1659 self.ipkg = IpkgComponent()
1660 self.ipkg.addCallback(self.ipkgCallback)
1661 self.onShown.append(self.setWindowTitle)
1662 self.onLayoutFinish.append(self.rebuildList)
1664 rcinput = eRCInput.getInstance()
1665 rcinput.setKeyboardMode(rcinput.kmAscii)
1667 def keyNumberGlobal(self, val):
1668 key = self.getKey(val)
1670 keyvalue = key.encode("utf-8")
1671 if len(keyvalue) == 1:
1672 self.setNextIdx(keyvalue[0])
1674 def keyGotAscii(self):
1675 keyvalue = unichr(getPrevAsciiCode()).encode("utf-8")
1676 if len(keyvalue) == 1:
1677 self.setNextIdx(keyvalue[0])
1679 def setNextIdx(self,char):
1680 if char in ("0", "1", "a"):
1681 self["list"].setIndex(0)
1683 idx = self.getNextIdx(char)
1684 if idx and idx <= self["list"].count:
1685 self["list"].setIndex(idx)
1687 def getNextIdx(self,char):
1689 for i in self["list"].list:
1696 if self.Console is not None:
1697 if len(self.Console.appContainers):
1698 for name in self.Console.appContainers.keys():
1699 self.Console.kill(name)
1700 rcinput = eRCInput.getInstance()
1701 rcinput.setKeyboardMode(rcinput.kmNone)
1705 if (os_path.exists(self.cache_file) == True):
1706 remove(self.cache_file)
1707 self.list_updating = True
1710 def setWindowTitle(self):
1711 self.setTitle(_("Packet manager"))
1713 def setStatus(self,status = None):
1715 self.statuslist = []
1716 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
1717 if status == 'update':
1718 statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgrade.png"))
1719 self.statuslist.append(( _("Package list update"), '', _("Trying to download a new packetlist. Please wait..." ),'',statuspng, divpng ))
1720 self['list'].setList(self.statuslist)
1721 elif status == 'error':
1722 statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
1723 self.statuslist.append(( _("Error"), '', _("There was an error downloading the packetlist. Please try again." ),'',statuspng, divpng ))
1724 self['list'].setList(self.statuslist)
1726 def rebuildList(self):
1727 self.setStatus('update')
1729 self.vc = valid_cache(self.cache_file, self.cache_ttl)
1730 if self.cache_ttl > 0 and self.vc != 0:
1732 self.buildPacketList()
1735 if self.cache_ttl == 0 or self.inv_cache == 1 or self.vc == 0:
1737 self.ipkg.startCmd(IpkgComponent.CMD_UPDATE)
1739 def go(self, returnValue = None):
1740 cur = self["list"].getCurrent()
1745 if status == 'installed':
1746 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": package }))
1747 if len(self.cmdList):
1748 self.session.openWithCallback(self.runRemove, MessageBox, _("Do you want to remove the package:\n") + package + "\n" + self.oktext)
1749 elif status == 'upgradeable':
1750 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package }))
1751 if len(self.cmdList):
1752 self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to upgrade the package:\n") + package + "\n" + self.oktext)
1753 elif status == "installable":
1754 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package }))
1755 if len(self.cmdList):
1756 self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to install the package:\n") + package + "\n" + self.oktext)
1758 def runRemove(self, result):
1760 self.session.openWithCallback(self.runRemoveFinished, Ipkg, cmdList = self.cmdList)
1762 def runRemoveFinished(self):
1763 self.session.openWithCallback(self.RemoveReboot, MessageBox, _("Remove finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
1765 def RemoveReboot(self, result):
1769 cur = self["list"].getCurrent()
1771 item = self['list'].getIndex()
1772 self.list[item] = self.buildEntryComponent(cur[0], cur[1], cur[2], 'installable')
1773 self.cachelist[item] = [cur[0], cur[1], cur[2], 'installable']
1774 self['list'].setList(self.list)
1775 write_cache(self.cache_file, self.cachelist)
1776 self.reloadPluginlist()
1780 def runUpgrade(self, result):
1782 self.session.openWithCallback(self.runUpgradeFinished, Ipkg, cmdList = self.cmdList)
1784 def runUpgradeFinished(self):
1785 self.session.openWithCallback(self.UpgradeReboot, MessageBox, _("Upgrade finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
1787 def UpgradeReboot(self, result):
1791 cur = self["list"].getCurrent()
1793 item = self['list'].getIndex()
1794 self.list[item] = self.buildEntryComponent(cur[0], cur[1], cur[2], 'installed')
1795 self.cachelist[item] = [cur[0], cur[1], cur[2], 'installed']
1796 self['list'].setList(self.list)
1797 write_cache(self.cache_file, self.cachelist)
1798 self.reloadPluginlist()
1802 def ipkgCallback(self, event, param):
1803 if event == IpkgComponent.EVENT_ERROR:
1804 self.list_updating = False
1805 self.setStatus('error')
1806 elif event == IpkgComponent.EVENT_DONE:
1807 if self.list_updating:
1808 self.list_updating = False
1809 if not self.Console:
1810 self.Console = Console()
1812 self.Console.ePopen(cmd, self.IpkgList_Finished)
1813 #print event, "-", param
1816 def IpkgList_Finished(self, result, retval, extra_args = None):
1818 self.packetlist = []
1819 for x in result.splitlines():
1820 tokens = x.split(' - ') #self.blacklisted_packages
1821 name = tokens[0].strip()
1822 if not any(name.endswith(x) for x in self.unwanted_extensions):
1824 version = l > 1 and tokens[1].strip() or ""
1825 descr = l > 2 and tokens[2].strip() or ""
1826 self.packetlist.append([name, version, descr])
1827 if not self.Console:
1828 self.Console = Console()
1829 cmd = "ipkg list_installed"
1830 self.Console.ePopen(cmd, self.IpkgListInstalled_Finished)
1832 def IpkgListInstalled_Finished(self, result, retval, extra_args = None):
1834 self.installed_packetlist = {}
1835 for x in result.splitlines():
1836 tokens = x.split(' - ') #self.blacklisted_packages
1837 name = tokens[0].strip()
1838 if not any(name.endswith(x) for x in self.unwanted_extensions):
1840 version = l > 1 and tokens[1].strip() or ""
1841 self.installed_packetlist[name] = version
1842 self.buildPacketList()
1844 def buildEntryComponent(self, name, version, description, state):
1845 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
1846 if state == 'installed':
1847 installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installed.png"))
1848 return((name, version, description, state, installedpng, divpng))
1849 elif state == 'upgradeable':
1850 upgradeablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgradeable.png"))
1851 return((name, version, description, state, upgradeablepng, divpng))
1853 installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installable.png"))
1854 return((name, version, description, state, installablepng, divpng))
1856 def buildPacketList(self):
1860 if self.cache_ttl > 0 and self.vc != 0:
1861 print 'Loading packagelist cache from ',self.cache_file
1863 self.cachelist = load_cache(self.cache_file)
1864 if len(self.cachelist) > 0:
1865 for x in self.cachelist:
1866 self.list.append(self.buildEntryComponent(x[0], x[1], x[2], x[3]))
1867 self['list'].setList(self.list)
1871 if self.cache_ttl == 0 or self.inv_cache == 1 or self.vc == 0:
1872 print 'rebuilding fresh package list'
1873 for x in self.packetlist:
1875 if self.installed_packetlist.has_key(x[0].strip()):
1876 if self.installed_packetlist[x[0].strip()] == x[1].strip():
1877 status = "installed"
1878 self.list.append(self.buildEntryComponent(x[0].strip(), x[1].strip(), x[2].strip(), status))
1880 status = "upgradeable"
1881 self.list.append(self.buildEntryComponent(x[0].strip(), x[1].strip(), x[2].strip(), status))
1883 status = "installable"
1884 self.list.append(self.buildEntryComponent(x[0].strip(), x[1].strip(), x[2].strip(), status))
1885 if not any(x[0].strip().endswith(x) for x in self.unwanted_extensions):
1886 self.cachelist.append([x[0].strip(), x[1].strip(), x[2].strip(), status])
1887 write_cache(self.cache_file, self.cachelist)
1888 self['list'].setList(self.list)
1890 def reloadPluginlist(self):
1891 plugins.readPluginList(resolveFilename(SCOPE_PLUGINS))
1893 class IpkgInstaller(Screen):
1895 <screen name="IpkgInstaller" position="center,center" size="550,450" title="Install extensions" >
1896 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1897 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1898 <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" />
1899 <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" />
1900 <widget name="list" position="5,50" size="540,360" />
1901 <ePixmap pixmap="skin_default/div-h.png" position="0,410" zPosition="10" size="560,2" transparent="1" alphatest="on" />
1902 <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" />
1905 def __init__(self, session, list):
1906 Screen.__init__(self, session)
1908 self.list = SelectionList()
1909 self["list"] = self.list
1910 for listindex in range(len(list)):
1911 self.list.addSelection(list[listindex], list[listindex], listindex, True)
1913 self["key_red"] = StaticText(_("Close"))
1914 self["key_green"] = StaticText(_("Install"))
1915 self["introduction"] = StaticText(_("Press OK to toggle the selection."))
1917 self["actions"] = ActionMap(["OkCancelActions", "ColorActions"],
1919 "ok": self.list.toggleSelection,
1920 "cancel": self.close,
1922 "green": self.install
1926 list = self.list.getSelectionsList()
1929 cmdList.append((IpkgComponent.CMD_INSTALL, { "package": item[1] }))
1930 self.session.open(Ipkg, cmdList = cmdList)
1933 def filescan_open(list, session, **kwargs):
1934 filelist = [x.path for x in list]
1935 session.open(IpkgInstaller, filelist) # list
1937 def filescan(**kwargs):
1938 from Components.Scanner import Scanner, ScanPath
1940 Scanner(mimetypes = ["application/x-debian-package"],
1943 ScanPath(path = "ipk", with_subdirs = True),
1944 ScanPath(path = "", with_subdirs = False),
1947 description = _("Install extensions."),
1948 openfnc = filescan_open, )
1952 def UpgradeMain(session, **kwargs):
1953 session.open(UpdatePluginMenu)
1955 def startSetup(menuid):
1956 if menuid != "setup":
1958 return [(_("Software management"), UpgradeMain, "software_manager", 50)]
1961 def Plugins(path, **kwargs):
1965 PluginDescriptor(name=_("Software management"), description=_("Manage your receiver's software"), where = PluginDescriptor.WHERE_MENU, fnc=startSetup),
1966 PluginDescriptor(name=_("Ipkg"), where = PluginDescriptor.WHERE_FILESCAN, fnc = filescan)
1968 if config.usage.setup_level.index >= 2: # expert+
1969 list.append(PluginDescriptor(name=_("Software management"), description=_("Manage your receiver's software"), where = PluginDescriptor.WHERE_EXTENSIONSMENU, fnc=UpgradeMain))