1 from Plugins.Plugin import PluginDescriptor
2 from Screens.Console import Console
3 from Screens.ChoiceBox import ChoiceBox
4 from Screens.MessageBox import MessageBox
5 from Screens.Screen import Screen
6 from Screens.Ipkg import Ipkg
7 from Components.ActionMap import ActionMap, NumberActionMap
8 from Components.Input import Input
9 from Components.Ipkg import IpkgComponent
10 from Components.Sources.StaticText import StaticText
11 from Components.ScrollLabel import ScrollLabel
12 from Components.Pixmap import Pixmap
13 from Components.MenuList import MenuList
14 from Components.Sources.List import List
15 from Components.Slider import Slider
16 from Components.Harddisk import harddiskmanager
17 from Components.config import config,getConfigListEntry, ConfigSubsection, ConfigText, ConfigLocations, ConfigYesNo, ConfigSelection
18 from Components.ConfigList import ConfigListScreen
19 from Components.Console import Console
20 from Components.MultiContent import MultiContentEntryText, MultiContentEntryPixmapAlphaTest
21 from Components.SelectionList import SelectionList
22 from Components.PluginComponent import plugins
23 from Components.About import about
24 from Components.DreamInfoHandler import DreamInfoHandler
25 from Components.Language import language
26 from Components.AVSwitch import AVSwitch
27 from Components.Network import iNetwork
28 from Tools.Directories import pathExists, fileExists, resolveFilename, SCOPE_PLUGINS, SCOPE_CURRENT_PLUGIN, SCOPE_CURRENT_SKIN, SCOPE_METADIR
29 from Tools.LoadPixmap import LoadPixmap
30 from Tools.NumericalTextInput import NumericalTextInput
31 from enigma import eTimer, quitMainloop, RT_HALIGN_LEFT, RT_VALIGN_CENTER, eListboxPythonMultiContent, eListbox, gFont, getDesktop, ePicLoad, eRCInput, getPrevAsciiCode, eEnv
32 from cPickle import dump, load
33 from os import path as os_path, system as os_system, unlink, stat, mkdir, popen, makedirs, listdir, access, rename, remove, W_OK, R_OK, F_OK
34 from time import time, gmtime, strftime, localtime
35 from stat import ST_MTIME
36 from datetime import date
37 from twisted.web import client
38 from twisted.internet import reactor
40 from ImageWizard import ImageWizard
41 from BackupRestore import BackupSelection, RestoreMenu, BackupScreen, RestoreScreen, getBackupPath, getBackupFilename
42 from SoftwareTools import iSoftwareTools
44 config.plugins.configurationbackup = ConfigSubsection()
45 config.plugins.configurationbackup.backuplocation = ConfigText(default = '/media/hdd/', visible_width = 50, fixed_size = False)
46 config.plugins.configurationbackup.backupdirs = ConfigLocations(default=[eEnv.resolve('${sysconfdir}/enigma2/'), '/etc/network/interfaces', '/etc/wpa_supplicant.conf', '/etc/wpa_supplicant.ath0.conf', '/etc/wpa_supplicant.wlan0.conf', '/etc/resolv.conf', '/etc/default_gw', '/etc/hostname'])
48 config.plugins.softwaremanager = ConfigSubsection()
49 config.plugins.softwaremanager.overwriteConfigFiles = ConfigSelection(
51 ("Y", _("Yes, always")),
52 ("N", _("No, never")),
53 ("ask", _("Always ask"))
56 def write_cache(cache_file, cache_data):
58 if not os_path.isdir( os_path.dirname(cache_file) ):
60 mkdir( os_path.dirname(cache_file) )
62 print os_path.dirname(cache_file), 'is a file'
63 fd = open(cache_file, 'w')
64 dump(cache_data, fd, -1)
67 def valid_cache(cache_file, cache_ttl):
68 #See if the cache file exists and is still living
70 mtime = stat(cache_file)[ST_MTIME]
74 if (curr_time - mtime) > cache_ttl:
79 def load_cache(cache_file):
87 class UpdatePluginMenu(Screen):
89 <screen name="UpdatePluginMenu" position="center,center" size="610,410" title="Software management" >
90 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
91 <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
92 <ePixmap pixmap="skin_default/border_menu_350.png" position="5,50" zPosition="1" size="350,300" transparent="1" alphatest="on" />
93 <widget source="menu" render="Listbox" position="15,60" size="330,290" scrollbarMode="showOnDemand">
94 <convert type="TemplatedMultiContent">
96 MultiContentEntryText(pos = (2, 2), size = (330, 24), flags = RT_HALIGN_LEFT, text = 1), # index 0 is the MenuText,
98 "fonts": [gFont("Regular", 22)],
103 <widget source="menu" render="Listbox" position="360,50" size="240,300" scrollbarMode="showNever" selectionDisabled="1">
104 <convert type="TemplatedMultiContent">
106 MultiContentEntryText(pos = (2, 2), size = (240, 300), flags = RT_HALIGN_CENTER|RT_VALIGN_CENTER|RT_WRAP, text = 2), # index 2 is the Description,
108 "fonts": [gFont("Regular", 22)],
113 <widget source="status" render="Label" position="5,360" zPosition="10" size="600,50" halign="center" valign="center" font="Regular;22" transparent="1" shadowColor="black" shadowOffset="-1,-1" />
116 def __init__(self, session, args = 0):
117 Screen.__init__(self, session)
118 self.skin_path = plugin_path
121 self.oktext = _("\nPress OK on your remote control to continue.")
122 self.menutext = _("Press MENU on your remote control for additional options.")
123 self.infotext = _("Press INFO on your remote control for additional information.")
125 self.backupdirs = ' '.join( config.plugins.configurationbackup.backupdirs.value )
127 print "building menu entries"
128 self.list.append(("install-extensions", _("Manage extensions"), _("\nManage extensions or plugins for your Dreambox" ) + self.oktext, None))
129 self.list.append(("software-update", _("Software update"), _("\nOnline update of your Dreambox software." ) + self.oktext, None))
130 self.list.append(("software-restore", _("Software restore"), _("\nRestore your Dreambox with a new firmware." ) + self.oktext, None))
131 self.list.append(("system-backup", _("Backup system settings"), _("\nBackup your Dreambox settings." ) + self.oktext + "\n\n" + self.infotext, None))
132 self.list.append(("system-restore",_("Restore system settings"), _("\nRestore your Dreambox settings." ) + self.oktext, None))
133 self.list.append(("ipkg-install", _("Install local extension"), _("\nScan for local extensions and install them." ) + self.oktext, None))
134 for p in plugins.getPlugins(PluginDescriptor.WHERE_SOFTWAREMANAGER):
135 if p.__call__.has_key("SoftwareSupported"):
136 callFnc = p.__call__["SoftwareSupported"](None)
137 if callFnc is not None:
138 if p.__call__.has_key("menuEntryName"):
139 menuEntryName = p.__call__["menuEntryName"](None)
141 menuEntryName = _('Extended Software')
142 if p.__call__.has_key("menuEntryDescription"):
143 menuEntryDescription = p.__call__["menuEntryDescription"](None)
145 menuEntryDescription = _('Extended Software Plugin')
146 self.list.append(('default-plugin', menuEntryName, menuEntryDescription + self.oktext, callFnc))
147 if config.usage.setup_level.index >= 2: # expert+
148 self.list.append(("advanced", _("Advanced Options"), _("\nAdvanced options and settings." ) + self.oktext, None))
150 self.list.append(("advancedrestore", _("Advanced restore"), _("\nRestore your backups by date." ) + self.oktext, None))
151 self.list.append(("backuplocation", _("Choose backup location"), _("\nSelect your backup device.\nCurrent device: " ) + config.plugins.configurationbackup.backuplocation.value + self.oktext, None))
152 self.list.append(("backupfiles", _("Choose backup files"), _("Select files for backup.") + self.oktext + "\n\n" + self.infotext, None))
153 if config.usage.setup_level.index >= 2: # expert+
154 self.list.append(("ipkg-manager", _("Packet management"), _("\nView, install and remove available or installed packages." ) + self.oktext, None))
155 self.list.append(("ipkg-source",_("Choose upgrade source"), _("\nEdit the upgrade source address." ) + self.oktext, None))
156 for p in plugins.getPlugins(PluginDescriptor.WHERE_SOFTWAREMANAGER):
157 if p.__call__.has_key("AdvancedSoftwareSupported"):
158 callFnc = p.__call__["AdvancedSoftwareSupported"](None)
159 if callFnc is not None:
160 if p.__call__.has_key("menuEntryName"):
161 menuEntryName = p.__call__["menuEntryName"](None)
163 menuEntryName = _('Advanced Software')
164 if p.__call__.has_key("menuEntryDescription"):
165 menuEntryDescription = p.__call__["menuEntryDescription"](None)
167 menuEntryDescription = _('Advanced Software Plugin')
168 self.list.append(('advanced-plugin', menuEntryName, menuEntryDescription + self.oktext, callFnc))
170 self["menu"] = List(self.list)
171 self["key_red"] = StaticText(_("Close"))
172 self["status"] = StaticText(self.menutext)
174 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions", "InfobarEPGActions", "MenuActions"],
179 "menu": self.handleMenu,
180 "showEventInfo": self.handleInfo,
182 self.onLayoutFinish.append(self.layoutFinished)
183 self.backuppath = getBackupPath()
184 self.backupfile = getBackupFilename()
185 self.fullbackupfilename = self.backuppath + "/" + self.backupfile
186 self.onShown.append(self.setWindowTitle)
188 def layoutFinished(self):
190 self["menu"].index = idx
192 def setWindowTitle(self):
193 self.setTitle(_("Software management"))
196 iNetwork.stopPingConsole()
197 iSoftwareTools.cleanupSoftwareTools()
199 def getUpdateInfos(self):
201 if iSoftwareTools.NetworkConnectionAvailable == True:
202 if iSoftwareTools.list_updating is False:
203 if iSoftwareTools.available_updates is not 0:
204 self.text = _("There are at least ") + str(iSoftwareTools.available_updates) + _(" updates available.")
206 self.text = "" #_("There are no updates available.")
208 if iSoftwareTools.available_updates is not 0:
209 self.text = _("There are at least ") + str(iSoftwareTools.available_updates) + _(" updates available.")
211 self.text = "" #_("There are no updates available.")
212 self.text += "\n" + _("A search for available updates is currently in progress.")
214 self.text = _("No network connection available.")
215 self["status"].setText(self.text)
217 def handleMenu(self):
218 self.session.open(SoftwareManagerSetup)
220 def handleInfo(self):
221 current = self["menu"].getCurrent()
223 currentEntry = current[0]
224 if currentEntry in ("system-backup","backupfiles"):
225 self.session.open(SoftwareManagerInfo, mode = "backupinfo")
228 current = self["menu"].getCurrent()
230 currentEntry = current[0]
232 if (currentEntry == "software-update"):
233 self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to update your Dreambox?")+"\n"+_("\nAfter pressing OK, please wait!"))
234 elif (currentEntry == "software-restore"):
235 self.session.open(ImageWizard)
236 elif (currentEntry == "install-extensions"):
237 self.session.open(PluginManager, self.skin_path)
238 elif (currentEntry == "system-backup"):
239 self.session.openWithCallback(self.backupDone,BackupScreen, runBackup = True)
240 elif (currentEntry == "system-restore"):
241 if os_path.exists(self.fullbackupfilename):
242 self.session.openWithCallback(self.startRestore, MessageBox, _("Are you sure you want to restore your Enigma2 backup?\nEnigma2 will restart after the restore"))
244 self.session.open(MessageBox, _("Sorry no backups found!"), MessageBox.TYPE_INFO, timeout = 10)
245 elif (currentEntry == "ipkg-install"):
247 from Plugins.Extensions.MediaScanner.plugin import main
250 self.session.open(MessageBox, _("Sorry MediaScanner is not installed!"), MessageBox.TYPE_INFO, timeout = 10)
251 elif (currentEntry == "default-plugin"):
252 self.extended = current[3]
253 self.extended(self.session, None)
254 elif (currentEntry == "advanced"):
255 self.session.open(UpdatePluginMenu, 1)
257 if (currentEntry == "ipkg-manager"):
258 self.session.open(PacketManager, self.skin_path)
259 elif (currentEntry == "backuplocation"):
260 parts = [ (r.description, r.mountpoint, self.session) for r in harddiskmanager.getMountedPartitions(onlyhotplug = False)]
262 if not access(x[1], F_OK|R_OK|W_OK) or x[1] == '/':
265 self.session.openWithCallback(self.backuplocation_choosen, ChoiceBox, title = _("Please select medium to use as backup location"), list = parts)
266 elif (currentEntry == "backupfiles"):
267 self.session.openWithCallback(self.backupfiles_choosen,BackupSelection)
268 elif (currentEntry == "advancedrestore"):
269 self.session.open(RestoreMenu, self.skin_path)
270 elif (currentEntry == "ipkg-source"):
271 self.session.open(IPKGMenu, self.skin_path)
272 elif (currentEntry == "advanced-plugin"):
273 self.extended = current[3]
274 self.extended(self.session, None)
276 def backupfiles_choosen(self, ret):
277 self.backupdirs = ' '.join( config.plugins.configurationbackup.backupdirs.value )
278 config.plugins.configurationbackup.backupdirs.save()
279 config.plugins.configurationbackup.save()
282 def backuplocation_choosen(self, option):
283 oldpath = config.plugins.configurationbackup.backuplocation.getValue()
284 if option is not None:
285 config.plugins.configurationbackup.backuplocation.value = str(option[1])
286 config.plugins.configurationbackup.backuplocation.save()
287 config.plugins.configurationbackup.save()
289 newpath = config.plugins.configurationbackup.backuplocation.getValue()
290 if newpath != oldpath:
291 self.createBackupfolders()
293 def runUpgrade(self, result):
295 self.session.open(UpdatePlugin, self.skin_path)
297 def createBackupfolders(self):
298 print "Creating backup folder if not already there..."
299 self.backuppath = getBackupPath()
301 if (os_path.exists(self.backuppath) == False):
302 makedirs(self.backuppath)
304 self.session.open(MessageBox, _("Sorry, your backup destination is not writeable.\n\nPlease choose another one."), MessageBox.TYPE_INFO, timeout = 10)
306 def backupDone(self,retval = None):
308 self.session.open(MessageBox, _("Backup done."), MessageBox.TYPE_INFO, timeout = 10)
310 self.session.open(MessageBox, _("Backup failed."), MessageBox.TYPE_INFO, timeout = 10)
312 def startRestore(self, ret = False):
315 self.session.open(RestoreScreen, runRestore = True)
317 class SoftwareManagerSetup(Screen, ConfigListScreen):
320 <screen name="SoftwareManagerSetup" position="center,center" size="560,440" title="SoftwareManager setup">
321 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
322 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
323 <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" alphatest="on" />
324 <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" alphatest="on" />
325 <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
326 <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
327 <widget source="key_yellow" render="Label" position="280,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#a08500" transparent="1" />
328 <widget source="key_blue" render="Label" position="420,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#18188b" transparent="1" />
329 <widget name="config" position="5,50" size="550,350" scrollbarMode="showOnDemand" />
330 <ePixmap pixmap="skin_default/div-h.png" position="0,400" zPosition="1" size="560,2" />
331 <widget source="introduction" render="Label" position="5,410" size="550,30" zPosition="10" font="Regular;21" halign="center" valign="center" backgroundColor="#25062748" transparent="1" />
334 def __init__(self, session, skin_path = None):
335 Screen.__init__(self, session)
336 self.session = session
337 self.skin_path = skin_path
338 if self.skin_path == None:
339 self.skin_path = resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager")
341 self.onChangedEntry = [ ]
342 self.setup_title = _("Software manager setup")
343 self.overwriteConfigfilesEntry = None
346 ConfigListScreen.__init__(self, self.list, session = session, on_change = self.changedEntry)
348 self["actions"] = ActionMap(["SetupActions"],
350 "cancel": self.keyCancel,
354 self["key_red"] = StaticText(_("Cancel"))
355 self["key_green"] = StaticText(_("OK"))
356 self["key_yellow"] = StaticText()
357 self["key_blue"] = StaticText()
358 self["introduction"] = StaticText()
361 self.onLayoutFinish.append(self.layoutFinished)
363 def layoutFinished(self):
364 self.setTitle(self.setup_title)
366 def createSetup(self):
368 self.overwriteConfigfilesEntry = getConfigListEntry(_("Overwrite configuration files ?"), config.plugins.softwaremanager.overwriteConfigFiles)
369 self.list.append(self.overwriteConfigfilesEntry)
370 self["config"].list = self.list
371 self["config"].l.setSeperation(400)
372 self["config"].l.setList(self.list)
373 if not self.selectionChanged in self["config"].onSelectionChanged:
374 self["config"].onSelectionChanged.append(self.selectionChanged)
375 self.selectionChanged()
377 def selectionChanged(self):
378 if self["config"].getCurrent() == self.overwriteConfigfilesEntry:
379 self["introduction"].setText(_("Overwrite configuration files during software upgrade?"))
381 self["introduction"].setText("")
387 ConfigListScreen.keyLeft(self)
390 ConfigListScreen.keyRight(self)
392 def confirm(self, confirmed):
394 print "not confirmed"
400 self.session.openWithCallback(self.confirm, MessageBox, _("Use this settings?"), MessageBox.TYPE_YESNO, timeout = 20, default = True)
402 def cancelConfirm(self, result):
405 for x in self["config"].list:
410 if self["config"].isChanged():
411 self.session.openWithCallback(self.cancelConfirm, MessageBox, _("Really close without saving settings?"), MessageBox.TYPE_YESNO, timeout = 20, default = True)
416 def changedEntry(self):
417 for x in self.onChangedEntry:
419 self.selectionChanged()
421 def getCurrentEntry(self):
422 return self["config"].getCurrent()[0]
424 def getCurrentValue(self):
425 return str(self["config"].getCurrent()[1].value)
427 def createSummary(self):
428 from Screens.Setup import SetupSummary
432 class SoftwareManagerInfo(Screen):
434 <screen name="SoftwareManagerInfo" position="center,center" size="560,440" title="SoftwareManager information">
435 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
436 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
437 <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" alphatest="on" />
438 <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" alphatest="on" />
439 <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
440 <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
441 <widget source="key_yellow" render="Label" position="280,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#a08500" transparent="1" />
442 <widget source="key_blue" render="Label" position="420,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#18188b" transparent="1" />
443 <widget source="list" render="Listbox" position="5,50" size="550,340" scrollbarMode="showOnDemand" selectionDisabled="0">
444 <convert type="TemplatedMultiContent">
446 MultiContentEntryText(pos = (5, 0), size = (540, 26), font=0, flags = RT_HALIGN_LEFT | RT_HALIGN_CENTER, text = 0), # index 0 is the name
448 "fonts": [gFont("Regular", 24),gFont("Regular", 22)],
453 <ePixmap pixmap="skin_default/div-h.png" position="0,400" zPosition="1" size="560,2" />
454 <widget source="introduction" render="Label" position="5,410" size="550,30" zPosition="10" font="Regular;21" halign="center" valign="center" backgroundColor="#25062748" transparent="1" />
457 def __init__(self, session, skin_path = None, mode = None):
458 Screen.__init__(self, session)
459 self.session = session
461 self.skin_path = skin_path
462 if self.skin_path == None:
463 self.skin_path = resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager")
465 self["actions"] = ActionMap(["ShortcutActions", "WizardActions"],
472 self["list"] = List(self.list)
474 self["key_red"] = StaticText(_("Close"))
475 self["key_green"] = StaticText()
476 self["key_yellow"] = StaticText()
477 self["key_blue"] = StaticText()
478 self["introduction"] = StaticText()
480 self.onLayoutFinish.append(self.layoutFinished)
482 def layoutFinished(self):
483 self.setTitle(_("Softwaremanager information"))
484 if self.mode is not None:
488 if self.mode == "backupinfo":
490 backupfiles = config.plugins.configurationbackup.backupdirs.value
491 for entry in backupfiles:
492 self.list.append((entry,))
493 self['list'].setList(self.list)
496 class PluginManager(Screen, DreamInfoHandler):
499 <screen name="PluginManager" position="center,center" size="560,440" title="Extensions management" >
500 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
501 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
502 <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" alphatest="on" />
503 <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" alphatest="on" />
504 <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" />
505 <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" />
506 <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" />
507 <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" />
508 <widget source="list" render="Listbox" position="5,50" size="550,360" scrollbarMode="showOnDemand">
509 <convert type="TemplatedMultiContent">
512 MultiContentEntryText(pos = (0, 1), size = (470, 24), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
513 MultiContentEntryText(pos = (0, 25), size = (470, 24), font=1, flags = RT_HALIGN_LEFT, text = 2), # index 2 is the description
514 MultiContentEntryPixmapAlphaTest(pos = (475, 0), size = (48, 48), png = 5), # index 5 is the status pixmap
515 MultiContentEntryPixmapAlphaTest(pos = (0, 49), size = (550, 2), png = 6), # index 6 is the div pixmap
518 MultiContentEntryText(pos = (30, 0), size = (500, 22), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
519 MultiContentEntryText(pos = (30, 22), size = (500, 16), font=2, flags = RT_HALIGN_LEFT, text = 1), # index 1 is the description
520 MultiContentEntryPixmapAlphaTest(pos = (0, 38), size = (550, 2), png = 3), # index 3 is the div pixmap
523 "fonts": [gFont("Regular", 22),gFont("Regular", 20),gFont("Regular", 16)],
528 <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" />
531 def __init__(self, session, plugin_path = None, args = None):
532 Screen.__init__(self, session)
533 self.session = session
534 self.skin_path = plugin_path
535 if self.skin_path == None:
536 self.skin_path = resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager")
538 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions", "InfobarEPGActions", "HelpActions" ],
540 "ok": self.handleCurrent,
543 "green": self.handleCurrent,
544 "yellow": self.handleSelected,
545 "showEventInfo": self.handleSelected,
546 "displayHelp": self.handleHelp,
551 self.selectedFiles = []
552 self.categoryList = []
554 self["list"] = List(self.list)
555 self["key_red"] = StaticText(_("Close"))
556 self["key_green"] = StaticText("")
557 self["key_yellow"] = StaticText("")
558 self["key_blue"] = StaticText("")
559 self["status"] = StaticText("")
562 self.oktext = _("\nAfter pressing OK, please wait!")
563 if not self.selectionChanged in self["list"].onSelectionChanged:
564 self["list"].onSelectionChanged.append(self.selectionChanged)
567 self.currentSelectedTag = None
568 self.currentSelectedIndex = None
569 self.currentSelectedPackage = None
570 self.saved_currentSelectedPackage = None
571 self.restartRequired = False
573 self.onShown.append(self.setWindowTitle)
574 self.onLayoutFinish.append(self.getUpdateInfos)
576 def setWindowTitle(self):
577 self.setTitle(_("Extensions management"))
580 if self.currList == "packages":
581 self.currList = "category"
582 self.currentSelectedTag = None
583 self["list"].style = "category"
584 self['list'].setList(self.categoryList)
585 self["list"].setIndex(self.currentSelectedIndex)
586 self["list"].updateList(self.categoryList)
587 self.selectionChanged()
589 iSoftwareTools.cleanupSoftwareTools()
590 self.prepareInstall()
591 if len(self.cmdList):
592 self.session.openWithCallback(self.runExecute, PluginManagerInfo, self.skin_path, self.cmdList)
596 def handleHelp(self):
597 if self.currList != "status":
598 self.session.open(PluginManagerHelp, self.skin_path)
600 def setState(self,status = None):
602 self.currList = "status"
604 self["key_green"].setText("")
605 self["key_blue"].setText("")
606 self["key_yellow"].setText("")
607 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
608 if status == 'update':
609 statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgrade.png"))
610 self.statuslist.append(( _("Updating software catalog"), '', _("Searching for available updates. Please wait..." ),'', '', statuspng, divpng, None, '' ))
611 elif status == 'sync':
612 statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgrade.png"))
613 self.statuslist.append(( _("Package list update"), '', _("Searching for new installed or removed packages. Please wait..." ),'', '', statuspng, divpng, None, '' ))
614 elif status == 'error':
615 self["key_green"].setText(_("Continue"))
616 statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
617 self.statuslist.append(( _("Error"), '', _("There was an error downloading the packetlist. Please try again." ),'', '', statuspng, divpng, None, '' ))
618 self["list"].style = "default"
619 self['list'].setList(self.statuslist)
622 def getUpdateInfos(self):
623 if (iSoftwareTools.lastDownloadDate is not None and iSoftwareTools.NetworkConnectionAvailable is False):
626 self.setState('update')
627 iSoftwareTools.startSoftwareTools(self.getUpdateInfosCB)
629 def getUpdateInfosCB(self, retval = None):
630 if retval is not None:
632 if iSoftwareTools.available_updates is not 0:
633 self["status"].setText(_("There are at least ") + str(iSoftwareTools.available_updates) + _(" updates available."))
635 self["status"].setText(_("There are no updates available."))
637 elif retval is False:
638 if iSoftwareTools.lastDownloadDate is None:
639 self.setState('error')
640 if iSoftwareTools.NetworkConnectionAvailable:
641 self["status"].setText(_("Updatefeed not available."))
643 self["status"].setText(_("No network connection available."))
645 iSoftwareTools.lastDownloadDate = time()
646 iSoftwareTools.list_updating = True
647 self.setState('update')
648 iSoftwareTools.getUpdates(self.getUpdateInfosCB)
650 def rebuildList(self, retval = None):
651 if self.currentSelectedTag is None:
652 self.buildCategoryList()
654 self.buildPacketList(self.currentSelectedTag)
656 def selectionChanged(self):
657 current = self["list"].getCurrent()
658 self["status"].setText("")
660 if self.currList == "packages":
661 self["key_red"].setText(_("Back"))
662 if current[4] == 'installed':
663 self["key_green"].setText(_("Uninstall"))
664 elif current[4] == 'installable':
665 self["key_green"].setText(_("Install"))
666 if iSoftwareTools.NetworkConnectionAvailable is False:
667 self["key_green"].setText("")
668 elif current[4] == 'remove':
669 self["key_green"].setText(_("Undo uninstall"))
670 elif current[4] == 'install':
671 self["key_green"].setText(_("Undo install"))
672 if iSoftwareTools.NetworkConnectionAvailable is False:
673 self["key_green"].setText("")
674 self["key_yellow"].setText(_("View details"))
675 self["key_blue"].setText("")
676 if len(self.selectedFiles) == 0 and iSoftwareTools.available_updates is not 0:
677 self["status"].setText(_("There are at least ") + str(iSoftwareTools.available_updates) + _(" updates available."))
678 elif len(self.selectedFiles) is not 0:
679 self["status"].setText(str(len(self.selectedFiles)) + _(" packages selected."))
681 self["status"].setText(_("There are currently no outstanding actions."))
682 elif self.currList == "category":
683 self["key_red"].setText(_("Close"))
684 self["key_green"].setText("")
685 self["key_yellow"].setText("")
686 self["key_blue"].setText("")
687 if len(self.selectedFiles) == 0 and iSoftwareTools.available_updates is not 0:
688 self["status"].setText(_("There are at least ") + str(iSoftwareTools.available_updates) + _(" updates available."))
689 self["key_yellow"].setText(_("Update"))
690 elif len(self.selectedFiles) is not 0:
691 self["status"].setText(str(len(self.selectedFiles)) + _(" packages selected."))
692 self["key_yellow"].setText(_("Process"))
694 self["status"].setText(_("There are currently no outstanding actions."))
696 def getSelectionState(self, detailsFile):
697 for entry in self.selectedFiles:
698 if entry[0] == detailsFile:
702 def handleCurrent(self):
703 current = self["list"].getCurrent()
705 if self.currList == "category":
706 self.currentSelectedIndex = self["list"].index
707 selectedTag = current[2]
708 self.buildPacketList(selectedTag)
709 elif self.currList == "packages":
710 if current[7] is not '':
711 idx = self["list"].getIndex()
712 detailsFile = self.list[idx][1]
713 if self.list[idx][7] == True:
714 for entry in self.selectedFiles:
715 if entry[0] == detailsFile:
716 self.selectedFiles.remove(entry)
718 alreadyinList = False
719 for entry in self.selectedFiles:
720 if entry[0] == detailsFile:
722 if not alreadyinList:
723 if (iSoftwareTools.NetworkConnectionAvailable is False and current[4] in ('installable','install')):
726 self.selectedFiles.append((detailsFile,current[4],current[3]))
727 self.currentSelectedPackage = ((detailsFile,current[4],current[3]))
728 if current[4] == 'installed':
729 self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'remove', True)
730 elif current[4] == 'installable':
731 if iSoftwareTools.NetworkConnectionAvailable:
732 self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'install', True)
733 elif current[4] == 'remove':
734 self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'installed', False)
735 elif current[4] == 'install':
736 if iSoftwareTools.NetworkConnectionAvailable:
737 self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'installable',False)
738 self["list"].setList(self.list)
739 self["list"].setIndex(idx)
740 self["list"].updateList(self.list)
741 self.selectionChanged()
742 elif self.currList == "status":
743 iSoftwareTools.lastDownloadDate = time()
744 iSoftwareTools.list_updating = True
745 self.setState('update')
746 iSoftwareTools.getUpdates(self.getUpdateInfosCB)
748 def handleSelected(self):
749 current = self["list"].getCurrent()
751 if self.currList == "packages":
752 if current[7] is not '':
753 detailsfile = iSoftwareTools.directory[0] + "/" + current[1]
754 if (os_path.exists(detailsfile) == True):
755 self.saved_currentSelectedPackage = self.currentSelectedPackage
756 self.session.openWithCallback(self.detailsClosed, PluginDetails, self.skin_path, current)
758 self.session.open(MessageBox, _("Sorry, no Details available!"), MessageBox.TYPE_INFO, timeout = 10)
759 elif self.currList == "category":
760 self.prepareInstall()
761 if len(self.cmdList):
762 self.session.openWithCallback(self.runExecute, PluginManagerInfo, self.skin_path, self.cmdList)
764 def detailsClosed(self, result = None):
765 if result is not None:
766 if result is not False:
767 self.setState('sync')
768 iSoftwareTools.lastDownloadDate = time()
769 for entry in self.selectedFiles:
770 if entry == self.saved_currentSelectedPackage:
771 self.selectedFiles.remove(entry)
772 iSoftwareTools.startIpkgListInstalled(self.rebuildList)
774 def buildEntryComponent(self, name, details, description, packagename, state, selected = False):
775 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
776 installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installed.png"))
777 installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installable.png"))
778 removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
779 installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/install.png"))
780 if state == 'installed':
781 return((name, details, description, packagename, state, installedpng, divpng, selected))
782 elif state == 'installable':
783 return((name, details, description, packagename, state, installablepng, divpng, selected))
784 elif state == 'remove':
785 return((name, details, description, packagename, state, removepng, divpng, selected))
786 elif state == 'install':
787 return((name, details, description, packagename, state, installpng, divpng, selected))
789 def buildPacketList(self, categorytag = None):
790 if categorytag is not None:
791 self.currList = "packages"
792 self.currentSelectedTag = categorytag
794 for package in iSoftwareTools.packagesIndexlist[:]:
795 prerequisites = package[0]["prerequisites"]
796 if prerequisites.has_key("tag"):
797 for foundtag in prerequisites["tag"]:
798 if categorytag == foundtag:
799 attributes = package[0]["attributes"]
800 if attributes.has_key("packagetype"):
801 if attributes["packagetype"] == "internal":
803 self.packetlist.append([attributes["name"], attributes["details"], attributes["shortdescription"], attributes["packagename"]])
805 self.packetlist.append([attributes["name"], attributes["details"], attributes["shortdescription"], attributes["packagename"]])
807 for x in self.packetlist:
810 details = x[1].strip()
811 description = x[2].strip()
812 if description == "":
813 description = "No description available."
814 packagename = x[3].strip()
815 selectState = self.getSelectionState(details)
816 if iSoftwareTools.installed_packetlist.has_key(packagename):
817 if selectState == True:
821 self.list.append(self.buildEntryComponent(name, _(details), _(description), packagename, status, selected = selectState))
823 if selectState == True:
826 status = "installable"
827 self.list.append(self.buildEntryComponent(name, _(details), _(description), packagename, status, selected = selectState))
829 self.list.sort(key=lambda x: x[0])
830 self["list"].style = "default"
831 self['list'].setList(self.list)
832 self["list"].updateList(self.list)
833 self.selectionChanged()
835 def buildCategoryList(self):
836 self.currList = "category"
838 self.categoryList = []
839 for package in iSoftwareTools.packagesIndexlist[:]:
840 prerequisites = package[0]["prerequisites"]
841 if prerequisites.has_key("tag"):
842 for foundtag in prerequisites["tag"]:
843 attributes = package[0]["attributes"]
844 if foundtag not in self.categories:
845 self.categories.append(foundtag)
846 self.categoryList.append(self.buildCategoryComponent(foundtag))
847 self.categoryList.sort(key=lambda x: x[0])
848 self["list"].style = "category"
849 self['list'].setList(self.categoryList)
850 self["list"].updateList(self.categoryList)
851 self.selectionChanged()
853 def buildCategoryComponent(self, tag = None):
854 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
857 return(( _("System"), _("View list of available system extensions" ), tag, divpng ))
859 return(( _("Skins"), _("View list of available skins" ), tag, divpng ))
860 elif tag == 'Recording':
861 return(( _("Recordings"), _("View list of available recording extensions" ), tag, divpng ))
862 elif tag == 'Network':
863 return(( _("Network"), _("View list of available networking extensions" ), tag, divpng ))
865 return(( _("CommonInterface"), _("View list of available CommonInterface extensions" ), tag, divpng ))
866 elif tag == 'Default':
867 return(( _("Default Settings"), _("View list of available default settings" ), tag, divpng ))
869 return(( _("Satellite equipment"), _("View list of available Satellite equipment extensions." ), tag, divpng ))
870 elif tag == 'Software':
871 return(( _("Software"), _("View list of available software extensions" ), tag, divpng ))
872 elif tag == 'Multimedia':
873 return(( _("Multimedia"), _("View list of available multimedia extensions." ), tag, divpng ))
874 elif tag == 'Display':
875 return(( _("Display and Userinterface"), _("View list of available Display and Userinterface extensions." ), tag, divpng ))
877 return(( _("Electronic Program Guide"), _("View list of available EPG extensions." ), tag, divpng ))
878 elif tag == 'Communication':
879 return(( _("Communication"), _("View list of available communication extensions." ), tag, divpng ))
880 else: # dynamically generate non existent tags
881 return(( str(tag), _("View list of available ") + str(tag) + _(" extensions." ), tag, divpng ))
883 def prepareInstall(self):
885 if iSoftwareTools.available_updates > 0:
886 self.cmdList.append((IpkgComponent.CMD_UPGRADE, { "test_only": False }))
887 if self.selectedFiles and len(self.selectedFiles):
888 for plugin in self.selectedFiles:
889 detailsfile = iSoftwareTools.directory[0] + "/" + plugin[0]
890 if (os_path.exists(detailsfile) == True):
891 iSoftwareTools.fillPackageDetails(plugin[0])
892 self.package = iSoftwareTools.packageDetails[0]
893 if self.package[0].has_key("attributes"):
894 self.attributes = self.package[0]["attributes"]
895 if self.attributes.has_key("needsRestart"):
896 self.restartRequired = True
897 if self.attributes.has_key("package"):
898 self.packagefiles = self.attributes["package"]
899 if plugin[1] == 'installed':
900 if self.packagefiles:
901 for package in self.packagefiles[:]:
902 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": package["name"] }))
904 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": plugin[2] }))
906 if self.packagefiles:
907 for package in self.packagefiles[:]:
908 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package["name"] }))
910 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": plugin[2] }))
912 if plugin[1] == 'installed':
913 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": plugin[2] }))
915 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": plugin[2] }))
917 def runExecute(self, result = None):
918 if result is not None:
919 if result[0] is True:
920 self.session.openWithCallback(self.runExecuteFinished, Ipkg, cmdList = self.cmdList)
921 elif result[0] is False:
922 self.cmdList = result[1]
923 self.session.openWithCallback(self.runExecuteFinished, Ipkg, cmdList = self.cmdList)
927 def runExecuteFinished(self):
928 self.reloadPluginlist()
929 if plugins.restartRequired or self.restartRequired:
930 self.session.openWithCallback(self.ExecuteReboot, MessageBox, _("Install or remove finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
932 self.selectedFiles = []
933 self.restartRequired = False
934 self.detailsClosed(True)
936 def ExecuteReboot(self, result):
940 self.selectedFiles = []
941 self.restartRequired = False
942 self.detailsClosed(True)
944 def reloadPluginlist(self):
945 plugins.readPluginList(resolveFilename(SCOPE_PLUGINS))
948 class PluginManagerInfo(Screen):
950 <screen name="PluginManagerInfo" position="center,center" size="560,450" title="Plugin manager activity information" >
951 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
952 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
953 <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" />
954 <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" />
955 <widget source="list" render="Listbox" position="5,50" size="550,350" scrollbarMode="showOnDemand" selectionDisabled="1">
956 <convert type="TemplatedMultiContent">
958 MultiContentEntryText(pos = (50, 0), size = (150, 26), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
959 MultiContentEntryText(pos = (50, 27), size = (540, 23), font=1, flags = RT_HALIGN_LEFT, text = 1), # index 1 is the state
960 MultiContentEntryPixmapAlphaTest(pos = (0, 1), size = (48, 48), png = 2), # index 2 is the status pixmap
961 MultiContentEntryPixmapAlphaTest(pos = (0, 48), size = (550, 2), png = 3), # index 3 is the div pixmap
963 "fonts": [gFont("Regular", 24),gFont("Regular", 22)],
968 <ePixmap pixmap="skin_default/div-h.png" position="0,404" zPosition="10" size="560,2" transparent="1" alphatest="on" />
969 <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" />
972 def __init__(self, session, plugin_path, cmdlist = None):
973 Screen.__init__(self, session)
974 self.session = session
975 self.skin_path = plugin_path
976 self.cmdlist = cmdlist
978 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"],
980 "ok": self.process_all,
983 "green": self.process_extensions,
987 self["list"] = List(self.list)
988 self["key_red"] = StaticText(_("Cancel"))
989 self["key_green"] = StaticText(_("Only extensions."))
990 self["status"] = StaticText(_("Following tasks will be done after you press OK!"))
992 self.onShown.append(self.setWindowTitle)
993 self.onLayoutFinish.append(self.rebuildList)
995 def setWindowTitle(self):
996 self.setTitle(_("Plugin manager activity information"))
998 def rebuildList(self):
1000 if self.cmdlist is not None:
1001 for entry in self.cmdlist:
1013 info = args['package']
1015 info = args['package']
1017 info = _("Dreambox software because updates are available.")
1019 self.list.append(self.buildEntryComponent(action,info))
1020 self['list'].setList(self.list)
1021 self['list'].updateList(self.list)
1023 def buildEntryComponent(self, action,info):
1024 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
1025 upgradepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgrade.png"))
1026 installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/install.png"))
1027 removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
1028 if action == 'install':
1029 return(( _('Installing'), info, installpng, divpng))
1030 elif action == 'remove':
1031 return(( _('Removing'), info, removepng, divpng))
1033 return(( _('Upgrading'), info, upgradepng, divpng))
1038 def process_all(self):
1039 self.close((True,None))
1041 def process_extensions(self):
1043 if self.cmdlist is not None:
1044 for entry in self.cmdlist:
1046 if entry[0] in (0,2):
1047 self.list.append((entry))
1048 self.close((False,self.list))
1051 class PluginManagerHelp(Screen):
1053 <screen name="PluginManagerHelp" position="center,center" size="560,450" title="Plugin manager help" >
1054 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1055 <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" />
1056 <widget source="list" render="Listbox" position="5,50" size="550,350" scrollbarMode="showOnDemand" selectionDisabled="1">
1057 <convert type="TemplatedMultiContent">
1059 MultiContentEntryText(pos = (50, 0), size = (540, 26), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
1060 MultiContentEntryText(pos = (50, 27), size = (540, 23), font=1, flags = RT_HALIGN_LEFT, text = 1), # index 1 is the state
1061 MultiContentEntryPixmapAlphaTest(pos = (0, 1), size = (48, 48), png = 2), # index 2 is the status pixmap
1062 MultiContentEntryPixmapAlphaTest(pos = (0, 48), size = (550, 2), png = 3), # index 3 is the div pixmap
1064 "fonts": [gFont("Regular", 24),gFont("Regular", 22)],
1069 <ePixmap pixmap="skin_default/div-h.png" position="0,404" zPosition="10" size="560,2" transparent="1" alphatest="on" />
1070 <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" />
1073 def __init__(self, session, plugin_path):
1074 Screen.__init__(self, session)
1075 self.session = session
1076 self.skin_path = plugin_path
1078 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"],
1085 self["list"] = List(self.list)
1086 self["key_red"] = StaticText(_("Close"))
1087 self["status"] = StaticText(_("A small overview of the available icon states and actions."))
1089 self.onShown.append(self.setWindowTitle)
1090 self.onLayoutFinish.append(self.rebuildList)
1092 def setWindowTitle(self):
1093 self.setTitle(_("Plugin manager help"))
1095 def rebuildList(self):
1097 self.list.append(self.buildEntryComponent('install'))
1098 self.list.append(self.buildEntryComponent('installable'))
1099 self.list.append(self.buildEntryComponent('installed'))
1100 self.list.append(self.buildEntryComponent('remove'))
1101 self['list'].setList(self.list)
1102 self['list'].updateList(self.list)
1104 def buildEntryComponent(self, state):
1105 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
1106 installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installed.png"))
1107 installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installable.png"))
1108 removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
1109 installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/install.png"))
1111 if state == 'installed':
1112 return(( _('This plugin is installed.'), _('You can remove this plugin.'), installedpng, divpng))
1113 elif state == 'installable':
1114 return(( _('This plugin is not installed.'), _('You can install this plugin.'), installablepng, divpng))
1115 elif state == 'install':
1116 return(( _('This plugin will be installed.'), _('You can cancel the installation.'), installpng, divpng))
1117 elif state == 'remove':
1118 return(( _('This plugin will be removed.'), _('You can cancel the removal.'), removepng, divpng))
1124 class PluginDetails(Screen, DreamInfoHandler):
1126 <screen name="PluginDetails" position="center,center" size="600,440" title="Plugin details" >
1127 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1128 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1129 <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" />
1130 <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" />
1131 <widget source="author" render="Label" position="10,50" size="500,25" zPosition="10" font="Regular;21" transparent="1" />
1132 <widget name="statuspic" position="550,40" size="48,48" alphatest="on"/>
1133 <widget name="divpic" position="0,80" size="600,2" alphatest="on"/>
1134 <widget name="detailtext" position="10,90" size="270,330" zPosition="10" font="Regular;21" transparent="1" halign="left" valign="top"/>
1135 <widget name="screenshot" position="290,90" size="300,330" alphatest="on"/>
1137 def __init__(self, session, plugin_path, packagedata = None):
1138 Screen.__init__(self, session)
1139 self.skin_path = plugin_path
1140 self.language = language.getLanguage()[:2] # getLanguage returns e.g. "fi_FI" for "language_country"
1141 self.attributes = None
1142 DreamInfoHandler.__init__(self, self.statusCallback, blocking = False)
1143 self.directory = resolveFilename(SCOPE_METADIR)
1145 self.pluginname = packagedata[0]
1146 self.details = packagedata[1]
1147 self.pluginstate = packagedata[4]
1148 self.statuspicinstance = packagedata[5]
1149 self.divpicinstance = packagedata[6]
1150 self.fillPackageDetails(self.details)
1154 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"],
1160 "down": self.pageDown,
1161 "left": self.pageUp,
1162 "right": self.pageDown,
1165 self["key_red"] = StaticText(_("Close"))
1166 self["key_green"] = StaticText("")
1167 self["author"] = StaticText()
1168 self["statuspic"] = Pixmap()
1169 self["divpic"] = Pixmap()
1170 self["screenshot"] = Pixmap()
1171 self["detailtext"] = ScrollLabel()
1173 self["statuspic"].hide()
1174 self["screenshot"].hide()
1175 self["divpic"].hide()
1177 self.package = self.packageDetails[0]
1178 if self.package[0].has_key("attributes"):
1179 self.attributes = self.package[0]["attributes"]
1180 self.restartRequired = False
1182 self.oktext = _("\nAfter pressing OK, please wait!")
1183 self.picload = ePicLoad()
1184 self.picload.PictureData.get().append(self.paintScreenshotPixmapCB)
1185 self.onShown.append(self.setWindowTitle)
1186 self.onLayoutFinish.append(self.setInfos)
1188 def setWindowTitle(self):
1189 self.setTitle(_("Details for plugin: ") + self.pluginname )
1195 self["detailtext"].pageUp()
1198 self["detailtext"].pageDown()
1200 def statusCallback(self, status, progress):
1204 if self.attributes.has_key("screenshot"):
1205 self.loadThumbnail(self.attributes)
1207 if self.attributes.has_key("name"):
1208 self.pluginname = self.attributes["name"]
1210 self.pluginname = _("unknown")
1212 if self.attributes.has_key("author"):
1213 self.author = self.attributes["author"]
1215 self.author = _("unknown")
1217 if self.attributes.has_key("description"):
1218 self.description = _(self.attributes["description"].replace("\\n", "\n"))
1220 self.description = _("No description available.")
1222 self["author"].setText(_("Author: ") + self.author)
1223 self["detailtext"].setText(_(self.description))
1224 if self.pluginstate in ('installable', 'install'):
1225 if iSoftwareTools.NetworkConnectionAvailable:
1226 self["key_green"].setText(_("Install"))
1228 self["key_green"].setText("")
1230 self["key_green"].setText(_("Remove"))
1232 def loadThumbnail(self, entry):
1234 if entry.has_key("screenshot"):
1235 thumbnailUrl = entry["screenshot"]
1236 if self.language == "de":
1237 if thumbnailUrl[-7:] == "_en.jpg":
1238 thumbnailUrl = thumbnailUrl[:-7] + "_de.jpg"
1240 if thumbnailUrl is not None:
1241 self.thumbnail = "/tmp/" + thumbnailUrl.split('/')[-1]
1242 print "[PluginDetails] downloading screenshot " + thumbnailUrl + " to " + self.thumbnail
1243 if iSoftwareTools.NetworkConnectionAvailable:
1244 client.downloadPage(thumbnailUrl,self.thumbnail).addCallback(self.setThumbnail).addErrback(self.fetchFailed)
1246 self.setThumbnail(noScreenshot = True)
1248 self.setThumbnail(noScreenshot = True)
1250 def setThumbnail(self, noScreenshot = False):
1251 if not noScreenshot:
1252 filename = self.thumbnail
1254 filename = resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/noprev.png")
1256 sc = AVSwitch().getFramebufferScale()
1257 self.picload.setPara((self["screenshot"].instance.size().width(), self["screenshot"].instance.size().height(), sc[0], sc[1], False, 1, "#00000000"))
1258 self.picload.startDecode(filename)
1260 if self.statuspicinstance != None:
1261 self["statuspic"].instance.setPixmap(self.statuspicinstance.__deref__())
1262 self["statuspic"].show()
1263 if self.divpicinstance != None:
1264 self["divpic"].instance.setPixmap(self.divpicinstance.__deref__())
1265 self["divpic"].show()
1267 def paintScreenshotPixmapCB(self, picInfo=None):
1268 ptr = self.picload.getData()
1270 self["screenshot"].instance.setPixmap(ptr.__deref__())
1271 self["screenshot"].show()
1273 self.setThumbnail(noScreenshot = True)
1276 if self.attributes.has_key("package"):
1277 self.packagefiles = self.attributes["package"]
1278 if self.attributes.has_key("needsRestart"):
1279 self.restartRequired = True
1281 if self.pluginstate in ('installed', 'remove'):
1282 if self.packagefiles:
1283 for package in self.packagefiles[:]:
1284 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": package["name"] }))
1285 if len(self.cmdList):
1286 self.session.openWithCallback(self.runRemove, MessageBox, _("Do you want to remove the package:\n") + self.pluginname + "\n" + self.oktext)
1288 if iSoftwareTools.NetworkConnectionAvailable:
1289 if self.packagefiles:
1290 for package in self.packagefiles[:]:
1291 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package["name"] }))
1292 if len(self.cmdList):
1293 self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to install the package:\n") + self.pluginname + "\n" + self.oktext)
1295 def runUpgrade(self, result):
1297 self.session.openWithCallback(self.runUpgradeFinished, Ipkg, cmdList = self.cmdList)
1299 def runUpgradeFinished(self):
1300 self.reloadPluginlist()
1301 if plugins.restartRequired or self.restartRequired:
1302 self.session.openWithCallback(self.UpgradeReboot, MessageBox, _("Installation finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
1305 def UpgradeReboot(self, result):
1311 def runRemove(self, result):
1313 self.session.openWithCallback(self.runRemoveFinished, Ipkg, cmdList = self.cmdList)
1315 def runRemoveFinished(self):
1318 def reloadPluginlist(self):
1319 plugins.readPluginList(resolveFilename(SCOPE_PLUGINS))
1321 def fetchFailed(self,string):
1322 self.setThumbnail(noScreenshot = True)
1323 print "[PluginDetails] fetch failed " + string.getErrorMessage()
1326 class UpdatePlugin(Screen):
1328 <screen name="UpdatePlugin" position="center,center" size="550,300" title="Software update" >
1329 <widget name="activityslider" position="0,0" size="550,5" />
1330 <widget name="slider" position="0,150" size="550,30" />
1331 <widget source="package" render="Label" position="10,30" size="540,20" font="Regular;18" halign="center" valign="center" backgroundColor="#25062748" transparent="1" />
1332 <widget source="status" render="Label" position="10,180" size="540,100" font="Regular;20" halign="center" valign="center" backgroundColor="#25062748" transparent="1" />
1335 def __init__(self, session, args = None):
1336 Screen.__init__(self, session)
1338 self.sliderPackages = { "dreambox-dvb-modules": 1, "enigma2": 2, "tuxbox-image-info": 3 }
1340 self.slider = Slider(0, 4)
1341 self["slider"] = self.slider
1342 self.activityslider = Slider(0, 100)
1343 self["activityslider"] = self.activityslider
1344 self.status = StaticText(_("Please wait..."))
1345 self["status"] = self.status
1346 self.package = StaticText(_("Verifying your internet connection..."))
1347 self["package"] = self.package
1348 self.oktext = _("Press OK on your remote control to continue.")
1352 self.processed_packages = []
1355 self.activityTimer = eTimer()
1356 self.activityTimer.callback.append(self.doActivityTimer)
1358 self.ipkg = IpkgComponent()
1359 self.ipkg.addCallback(self.ipkgCallback)
1361 self.updating = False
1363 self["actions"] = ActionMap(["WizardActions"],
1369 iNetwork.checkNetworkState(self.checkNetworkCB)
1370 self.onClose.append(self.cleanup)
1373 iNetwork.stopPingConsole()
1375 def checkNetworkCB(self,data):
1376 if data is not None:
1378 self.updating = True
1379 self.activityTimer.start(100, False)
1380 self.package.setText(_("Package list update"))
1381 self.status.setText(_("Upgrading Dreambox... Please wait"))
1382 self.ipkg.startCmd(IpkgComponent.CMD_UPDATE)
1384 self.package.setText(_("Your network is not working. Please try again."))
1385 self.status.setText(self.oktext)
1387 def doActivityTimer(self):
1389 if self.activity == 100:
1391 self.activityslider.setValue(self.activity)
1393 def ipkgCallback(self, event, param):
1394 if event == IpkgComponent.EVENT_DOWNLOAD:
1395 self.status.setText(_("Downloading"))
1396 elif event == IpkgComponent.EVENT_UPGRADE:
1397 if self.sliderPackages.has_key(param):
1398 self.slider.setValue(self.sliderPackages[param])
1399 self.package.setText(param)
1400 self.status.setText(_("Upgrading"))
1401 if not param in self.processed_packages:
1402 self.processed_packages.append(param)
1404 elif event == IpkgComponent.EVENT_INSTALL:
1405 self.package.setText(param)
1406 self.status.setText(_("Installing"))
1407 if not param in self.processed_packages:
1408 self.processed_packages.append(param)
1410 elif event == IpkgComponent.EVENT_REMOVE:
1411 self.package.setText(param)
1412 self.status.setText(_("Removing"))
1413 if not param in self.processed_packages:
1414 self.processed_packages.append(param)
1416 elif event == IpkgComponent.EVENT_CONFIGURING:
1417 self.package.setText(param)
1418 self.status.setText(_("Configuring"))
1420 elif event == IpkgComponent.EVENT_MODIFIED:
1421 if config.plugins.softwaremanager.overwriteConfigFiles.value in ("N", "Y"):
1422 self.ipkg.write(True and config.plugins.softwaremanager.overwriteConfigFiles.value)
1424 self.session.openWithCallback(
1425 self.modificationCallback,
1427 _("A configuration file (%s) was modified since Installation.\nDo you want to keep your version?") % (param)
1429 elif event == IpkgComponent.EVENT_ERROR:
1431 elif event == IpkgComponent.EVENT_DONE:
1433 self.updating = False
1434 self.ipkg.startCmd(IpkgComponent.CMD_UPGRADE, args = {'test_only': False})
1435 elif self.error == 0:
1436 self.slider.setValue(4)
1438 self.activityTimer.stop()
1439 self.activityslider.setValue(0)
1441 self.package.setText(_("Done - Installed or upgraded %d packages") % self.packages)
1442 self.status.setText(self.oktext)
1444 self.activityTimer.stop()
1445 self.activityslider.setValue(0)
1446 error = _("your dreambox might be unusable now. Please consult the manual for further assistance before rebooting your dreambox.")
1447 if self.packages == 0:
1448 error = _("No packages were upgraded yet. So you can check your network and try again.")
1450 error = _("Your dreambox isn't connected to the internet properly. Please check it and try again.")
1451 self.status.setText(_("Error") + " - " + error)
1452 #print event, "-", param
1455 def modificationCallback(self, res):
1456 self.ipkg.write(res and "N" or "Y")
1459 if not self.ipkg.isRunning():
1460 if self.packages != 0 and self.error == 0:
1461 self.session.openWithCallback(self.exitAnswer, MessageBox, _("Upgrade finished.") +" "+_("Do you want to reboot your Dreambox?"))
1465 if not self.updating:
1468 def exitAnswer(self, result):
1469 if result is not None and result:
1475 class IPKGMenu(Screen):
1477 <screen name="IPKGMenu" position="center,center" size="560,400" title="Select upgrade source to edit." >
1478 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1479 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1480 <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" />
1481 <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" />
1482 <widget name="filelist" position="5,50" size="550,340" scrollbarMode="showOnDemand" />
1485 def __init__(self, session, plugin_path):
1486 Screen.__init__(self, session)
1487 self.skin_path = plugin_path
1489 self["key_red"] = StaticText(_("Close"))
1490 self["key_green"] = StaticText(_("Edit"))
1499 self["actions"] = NumberActionMap(["SetupActions"],
1502 "cancel": self.keyCancel
1505 self["shortcuts"] = ActionMap(["ShortcutActions"],
1507 "red": self.keyCancel,
1508 "green": self.KeyOk,
1511 self["filelist"] = MenuList(self.flist)
1513 self.onLayoutFinish.append(self.layoutFinished)
1515 def layoutFinished(self):
1516 self.setWindowTitle()
1518 def setWindowTitle(self):
1519 self.setTitle(_("Select upgrade source to edit."))
1521 def fill_list(self):
1523 self.path = '/etc/opkg/'
1524 if (os_path.exists(self.path) == False):
1527 for file in listdir(self.path):
1528 if (file.endswith(".conf")):
1529 if file != 'arch.conf':
1530 self.flist.append((file))
1532 self["filelist"].l.setList(self.flist)
1535 if (self.exe == False) and (self.entry == True):
1536 self.sel = self["filelist"].getCurrent()
1537 self.val = self.path + self.sel
1538 self.session.open(IPKGSource, self.val)
1540 def keyCancel(self):
1547 class IPKGSource(Screen):
1549 <screen name="IPKGSource" position="center,center" size="560,80" title="Edit upgrade source url." >
1550 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1551 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1552 <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" />
1553 <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" />
1554 <widget name="text" position="5,50" size="550,25" font="Regular;20" backgroundColor="background" foregroundColor="#cccccc" />
1557 def __init__(self, session, configfile = None):
1558 Screen.__init__(self, session)
1559 self.session = session
1560 self.configfile = configfile
1564 fp = file(configfile, 'r')
1565 sources = fp.readlines()
1572 desk = getDesktop(0)
1573 x= int(desk.size().width())
1574 y= int(desk.size().height())
1576 self["key_red"] = StaticText(_("Cancel"))
1577 self["key_green"] = StaticText(_("Save"))
1580 self["text"] = Input(text, maxSize=False, type=Input.TEXT)
1582 self["text"] = Input(text, maxSize=False, visible_width = 55, type=Input.TEXT)
1584 self["actions"] = NumberActionMap(["WizardActions", "InputActions", "TextEntryActions", "KeyboardInputActions","ShortcutActions"],
1590 "left": self.keyLeft,
1591 "right": self.keyRight,
1592 "home": self.keyHome,
1594 "deleteForward": self.keyDeleteForward,
1595 "deleteBackward": self.keyDeleteBackward,
1596 "1": self.keyNumberGlobal,
1597 "2": self.keyNumberGlobal,
1598 "3": self.keyNumberGlobal,
1599 "4": self.keyNumberGlobal,
1600 "5": self.keyNumberGlobal,
1601 "6": self.keyNumberGlobal,
1602 "7": self.keyNumberGlobal,
1603 "8": self.keyNumberGlobal,
1604 "9": self.keyNumberGlobal,
1605 "0": self.keyNumberGlobal
1608 self.onLayoutFinish.append(self.layoutFinished)
1610 def layoutFinished(self):
1611 self.setWindowTitle()
1612 self["text"].right()
1614 def setWindowTitle(self):
1615 self.setTitle(_("Edit upgrade source url."))
1618 text = self["text"].getText()
1620 fp = file(self.configfile, 'w')
1630 self["text"].right()
1638 def keyDeleteForward(self):
1639 self["text"].delete()
1641 def keyDeleteBackward(self):
1642 self["text"].deleteBackward()
1644 def keyNumberGlobal(self, number):
1645 self["text"].number(number)
1648 class PacketManager(Screen, NumericalTextInput):
1650 <screen name="PacketManager" position="center,center" size="530,420" title="Packet manager" >
1651 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1652 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1653 <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" />
1654 <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" />
1655 <widget source="list" render="Listbox" position="5,50" size="520,365" scrollbarMode="showOnDemand">
1656 <convert type="TemplatedMultiContent">
1658 MultiContentEntryText(pos = (5, 1), size = (440, 28), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
1659 MultiContentEntryText(pos = (5, 26), size = (440, 20), font=1, flags = RT_HALIGN_LEFT, text = 2), # index 2 is the description
1660 MultiContentEntryPixmapAlphaTest(pos = (445, 2), size = (48, 48), png = 4), # index 4 is the status pixmap
1661 MultiContentEntryPixmapAlphaTest(pos = (5, 50), size = (510, 2), png = 5), # index 4 is the div pixmap
1663 "fonts": [gFont("Regular", 22),gFont("Regular", 14)],
1670 def __init__(self, session, plugin_path, args = None):
1671 Screen.__init__(self, session)
1672 NumericalTextInput.__init__(self)
1673 self.session = session
1674 self.skin_path = plugin_path
1676 self.setUseableChars(u'1234567890abcdefghijklmnopqrstuvwxyz')
1678 self["shortcuts"] = NumberActionMap(["ShortcutActions", "WizardActions", "NumberActions", "InputActions", "InputAsciiActions", "KeyboardInputActions" ],
1683 "green": self.reload,
1684 "gotAsciiCode": self.keyGotAscii,
1685 "1": self.keyNumberGlobal,
1686 "2": self.keyNumberGlobal,
1687 "3": self.keyNumberGlobal,
1688 "4": self.keyNumberGlobal,
1689 "5": self.keyNumberGlobal,
1690 "6": self.keyNumberGlobal,
1691 "7": self.keyNumberGlobal,
1692 "8": self.keyNumberGlobal,
1693 "9": self.keyNumberGlobal,
1694 "0": self.keyNumberGlobal
1698 self.statuslist = []
1699 self["list"] = List(self.list)
1700 self["key_red"] = StaticText(_("Close"))
1701 self["key_green"] = StaticText(_("Reload"))
1703 self.list_updating = True
1704 self.packetlist = []
1705 self.installed_packetlist = {}
1706 self.upgradeable_packages = {}
1707 self.Console = Console()
1710 self.cache_ttl = 86400 #600 is default, 0 disables, Seconds cache is considered valid (24h should be ok for caching ipkgs)
1711 self.cache_file = eEnv.resolve('${libdir}/enigma2/python/Plugins/SystemPlugins/SoftwareManager/packetmanager.cache') #Path to cache directory
1712 self.oktext = _("\nAfter pressing OK, please wait!")
1713 self.unwanted_extensions = ('-dbg', '-dev', '-doc', 'busybox')
1715 self.ipkg = IpkgComponent()
1716 self.ipkg.addCallback(self.ipkgCallback)
1717 self.onShown.append(self.setWindowTitle)
1718 self.onLayoutFinish.append(self.rebuildList)
1720 rcinput = eRCInput.getInstance()
1721 rcinput.setKeyboardMode(rcinput.kmAscii)
1723 def keyNumberGlobal(self, val):
1724 key = self.getKey(val)
1726 keyvalue = key.encode("utf-8")
1727 if len(keyvalue) == 1:
1728 self.setNextIdx(keyvalue[0])
1730 def keyGotAscii(self):
1731 keyvalue = unichr(getPrevAsciiCode()).encode("utf-8")
1732 if len(keyvalue) == 1:
1733 self.setNextIdx(keyvalue[0])
1735 def setNextIdx(self,char):
1736 if char in ("0", "1", "a"):
1737 self["list"].setIndex(0)
1739 idx = self.getNextIdx(char)
1740 if idx and idx <= self["list"].count:
1741 self["list"].setIndex(idx)
1743 def getNextIdx(self,char):
1745 for i in self["list"].list:
1752 if self.Console is not None:
1753 if len(self.Console.appContainers):
1754 for name in self.Console.appContainers.keys():
1755 self.Console.kill(name)
1756 rcinput = eRCInput.getInstance()
1757 rcinput.setKeyboardMode(rcinput.kmNone)
1761 if (os_path.exists(self.cache_file) == True):
1762 remove(self.cache_file)
1763 self.list_updating = True
1766 def setWindowTitle(self):
1767 self.setTitle(_("Packet manager"))
1769 def setStatus(self,status = None):
1771 self.statuslist = []
1772 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
1773 if status == 'update':
1774 statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgrade.png"))
1775 self.statuslist.append(( _("Package list update"), '', _("Trying to download a new packetlist. Please wait..." ),'',statuspng, divpng ))
1776 self['list'].setList(self.statuslist)
1777 elif status == 'error':
1778 statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
1779 self.statuslist.append(( _("Error"), '', _("There was an error downloading the packetlist. Please try again." ),'',statuspng, divpng ))
1780 self['list'].setList(self.statuslist)
1782 def rebuildList(self):
1783 self.setStatus('update')
1785 self.vc = valid_cache(self.cache_file, self.cache_ttl)
1786 if self.cache_ttl > 0 and self.vc != 0:
1788 self.buildPacketList()
1791 if self.cache_ttl == 0 or self.inv_cache == 1 or self.vc == 0:
1793 self.ipkg.startCmd(IpkgComponent.CMD_UPDATE)
1795 def go(self, returnValue = None):
1796 cur = self["list"].getCurrent()
1801 if status == 'installed':
1802 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": package }))
1803 if len(self.cmdList):
1804 self.session.openWithCallback(self.runRemove, MessageBox, _("Do you want to remove the package:\n") + package + "\n" + self.oktext)
1805 elif status == 'upgradeable':
1806 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package }))
1807 if len(self.cmdList):
1808 self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to upgrade the package:\n") + package + "\n" + self.oktext)
1809 elif status == "installable":
1810 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package }))
1811 if len(self.cmdList):
1812 self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to install the package:\n") + package + "\n" + self.oktext)
1814 def runRemove(self, result):
1816 self.session.openWithCallback(self.runRemoveFinished, Ipkg, cmdList = self.cmdList)
1818 def runRemoveFinished(self):
1819 self.session.openWithCallback(self.RemoveReboot, MessageBox, _("Remove finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
1821 def RemoveReboot(self, result):
1825 cur = self["list"].getCurrent()
1827 item = self['list'].getIndex()
1828 self.list[item] = self.buildEntryComponent(cur[0], cur[1], cur[2], 'installable')
1829 self.cachelist[item] = [cur[0], cur[1], cur[2], 'installable']
1830 self['list'].setList(self.list)
1831 write_cache(self.cache_file, self.cachelist)
1832 self.reloadPluginlist()
1836 def runUpgrade(self, result):
1838 self.session.openWithCallback(self.runUpgradeFinished, Ipkg, cmdList = self.cmdList)
1840 def runUpgradeFinished(self):
1841 self.session.openWithCallback(self.UpgradeReboot, MessageBox, _("Upgrade finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
1843 def UpgradeReboot(self, result):
1847 cur = self["list"].getCurrent()
1849 item = self['list'].getIndex()
1850 self.list[item] = self.buildEntryComponent(cur[0], cur[1], cur[2], 'installed')
1851 self.cachelist[item] = [cur[0], cur[1], cur[2], 'installed']
1852 self['list'].setList(self.list)
1853 write_cache(self.cache_file, self.cachelist)
1854 self.reloadPluginlist()
1858 def ipkgCallback(self, event, param):
1859 if event == IpkgComponent.EVENT_ERROR:
1860 self.list_updating = False
1861 self.setStatus('error')
1862 elif event == IpkgComponent.EVENT_DONE:
1863 if self.list_updating:
1864 self.list_updating = False
1865 if not self.Console:
1866 self.Console = Console()
1868 self.Console.ePopen(cmd, self.IpkgList_Finished)
1869 #print event, "-", param
1872 def IpkgList_Finished(self, result, retval, extra_args = None):
1874 self.packetlist = []
1876 for x in result.splitlines():
1877 tokens = x.split(' - ')
1878 name = tokens[0].strip()
1879 if not any(name.endswith(x) for x in self.unwanted_extensions):
1881 version = l > 1 and tokens[1].strip() or ""
1882 descr = l > 2 and tokens[2].strip() or ""
1883 if name == last_name:
1886 self.packetlist.append([name, version, descr])
1888 if not self.Console:
1889 self.Console = Console()
1890 cmd = "opkg list-installed"
1891 self.Console.ePopen(cmd, self.IpkgListInstalled_Finished)
1893 def IpkgListInstalled_Finished(self, result, retval, extra_args = None):
1895 self.installed_packetlist = {}
1896 for x in result.splitlines():
1897 tokens = x.split(' - ')
1898 name = tokens[0].strip()
1899 if not any(name.endswith(x) for x in self.unwanted_extensions):
1901 version = l > 1 and tokens[1].strip() or ""
1902 self.installed_packetlist[name] = version
1903 if not self.Console:
1904 self.Console = Console()
1905 cmd = "opkg list-upgradable"
1906 self.Console.ePopen(cmd, self.OpkgListUpgradeable_Finished)
1908 def OpkgListUpgradeable_Finished(self, result, retval, extra_args = None):
1910 self.upgradeable_packages = {}
1911 for x in result.splitlines():
1912 tokens = x.split(' - ')
1913 name = tokens[0].strip()
1914 if not any(name.endswith(x) for x in self.unwanted_extensions):
1916 version = l > 2 and tokens[2].strip() or ""
1917 self.upgradeable_packages[name] = version
1918 self.buildPacketList()
1920 def buildEntryComponent(self, name, version, description, state):
1921 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
1922 if description == "":
1923 description = "No description available."
1924 if state == 'installed':
1925 installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installed.png"))
1926 return((name, version, _(description), state, installedpng, divpng))
1927 elif state == 'upgradeable':
1928 upgradeablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgradeable.png"))
1929 return((name, version, _(description), state, upgradeablepng, divpng))
1931 installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installable.png"))
1932 return((name, version, _(description), state, installablepng, divpng))
1934 def buildPacketList(self):
1937 if self.cache_ttl > 0 and self.vc != 0:
1938 print 'Loading packagelist cache from ',self.cache_file
1940 self.cachelist = load_cache(self.cache_file)
1941 if len(self.cachelist) > 0:
1942 for x in self.cachelist:
1943 self.list.append(self.buildEntryComponent(x[0], x[1], x[2], x[3]))
1944 self['list'].setList(self.list)
1948 if self.cache_ttl == 0 or self.inv_cache == 1 or self.vc == 0:
1949 print 'rebuilding fresh package list'
1950 for x in self.packetlist:
1952 if self.installed_packetlist.has_key(x[0]):
1953 if self.upgradeable_packages.has_key(x[0]):
1954 status = "upgradeable"
1956 status = "installed"
1958 status = "installable"
1959 self.list.append(self.buildEntryComponent(x[0], x[1], x[2], status))
1960 self.cachelist.append([x[0], x[1], x[2], status])
1961 write_cache(self.cache_file, self.cachelist)
1962 self['list'].setList(self.list)
1964 def reloadPluginlist(self):
1965 plugins.readPluginList(resolveFilename(SCOPE_PLUGINS))
1968 class IpkgInstaller(Screen):
1970 <screen name="IpkgInstaller" position="center,center" size="550,450" title="Install extensions" >
1971 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1972 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1973 <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" />
1974 <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" />
1975 <widget name="list" position="5,50" size="540,360" />
1976 <ePixmap pixmap="skin_default/div-h.png" position="0,410" zPosition="10" size="560,2" transparent="1" alphatest="on" />
1977 <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" />
1980 def __init__(self, session, list):
1981 Screen.__init__(self, session)
1983 self.list = SelectionList()
1984 self["list"] = self.list
1985 for listindex in range(len(list)):
1986 self.list.addSelection(list[listindex], list[listindex], listindex, True)
1988 self["key_red"] = StaticText(_("Close"))
1989 self["key_green"] = StaticText(_("Install"))
1990 self["introduction"] = StaticText(_("Press OK to toggle the selection."))
1992 self["actions"] = ActionMap(["OkCancelActions", "ColorActions"],
1994 "ok": self.list.toggleSelection,
1995 "cancel": self.close,
1997 "green": self.install
2001 list = self.list.getSelectionsList()
2004 cmdList.append((IpkgComponent.CMD_INSTALL, { "package": item[1] }))
2005 self.session.open(Ipkg, cmdList = cmdList)
2008 def filescan_open(list, session, **kwargs):
2009 filelist = [x.path for x in list]
2010 session.open(IpkgInstaller, filelist) # list
2012 def filescan(**kwargs):
2013 from Components.Scanner import Scanner, ScanPath
2015 Scanner(mimetypes = ["application/x-debian-package"],
2018 ScanPath(path = "ipk", with_subdirs = True),
2019 ScanPath(path = "", with_subdirs = False),
2022 description = _("Install extensions."),
2023 openfnc = filescan_open, )
2027 def UpgradeMain(session, **kwargs):
2028 session.open(UpdatePluginMenu)
2030 def startSetup(menuid):
2031 if menuid != "setup":
2033 return [(_("Software management"), UpgradeMain, "software_manager", 50)]
2036 def Plugins(path, **kwargs):
2040 PluginDescriptor(name=_("Software management"), description=_("Manage your receiver's software"), where = PluginDescriptor.WHERE_MENU, needsRestart = False, fnc=startSetup),
2041 PluginDescriptor(name=_("Ipkg"), where = PluginDescriptor.WHERE_FILESCAN, needsRestart = False, fnc = filescan)
2043 if config.usage.setup_level.index >= 2: # expert+
2044 list.append(PluginDescriptor(name=_("Software management"), description=_("Manage your receiver's software"), where = PluginDescriptor.WHERE_EXTENSIONSMENU, needsRestart = False, fnc=UpgradeMain))