1 from Plugins.Plugin import PluginDescriptor
2 from Screens.Console import Console
3 from Screens.ChoiceBox import ChoiceBox
4 from Screens.MessageBox import MessageBox
5 from Screens.Screen import Screen
6 from Screens.Ipkg import Ipkg
7 from Components.ActionMap import ActionMap, NumberActionMap
8 from Components.Input import Input
9 from Components.Ipkg import IpkgComponent
10 from Components.Sources.StaticText import StaticText
11 from Components.ScrollLabel import ScrollLabel
12 from Components.Pixmap import Pixmap
13 from Components.MenuList import MenuList
14 from Components.Sources.List import List
15 from Components.Slider import Slider
16 from Components.Harddisk import harddiskmanager
17 from Components.config import config,getConfigListEntry, ConfigSubsection, ConfigText, ConfigLocations, ConfigYesNo, ConfigSelection
18 from Components.ConfigList import ConfigListScreen
19 from Components.Console import Console
20 from Components.MultiContent import MultiContentEntryText, MultiContentEntryPixmapAlphaTest
21 from Components.SelectionList import SelectionList
22 from Components.PluginComponent import plugins
23 from Components.About import about
24 from Components.DreamInfoHandler import DreamInfoHandler
25 from Components.Language import language
26 from Components.AVSwitch import AVSwitch
27 from Components.Network import iNetwork
28 from Tools.Directories import pathExists, fileExists, resolveFilename, SCOPE_PLUGINS, SCOPE_CURRENT_PLUGIN, SCOPE_CURRENT_SKIN, SCOPE_METADIR
29 from Tools.LoadPixmap import LoadPixmap
30 from Tools.NumericalTextInput import NumericalTextInput
31 from enigma import eTimer, quitMainloop, RT_HALIGN_LEFT, RT_VALIGN_CENTER, eListboxPythonMultiContent, eListbox, gFont, getDesktop, ePicLoad, eRCInput, getPrevAsciiCode, eEnv
32 from cPickle import dump, load
33 from os import path as os_path, system as os_system, unlink, stat, mkdir, popen, makedirs, listdir, access, rename, remove, W_OK, R_OK, F_OK
34 from time import time, gmtime, strftime, localtime
35 from stat import ST_MTIME
36 from datetime import date
37 from twisted.web import client
38 from twisted.internet import reactor
40 from ImageWizard import ImageWizard
41 from BackupRestore import BackupSelection, RestoreMenu, BackupScreen, RestoreScreen, getBackupPath, getBackupFilename
42 from SoftwareTools import iSoftwareTools
44 config.plugins.configurationbackup = ConfigSubsection()
45 config.plugins.configurationbackup.backuplocation = ConfigText(default = '/media/hdd/', visible_width = 50, fixed_size = False)
46 config.plugins.configurationbackup.backupdirs = ConfigLocations(default=[eEnv.resolve('${sysconfdir}/enigma2/'), '/etc/network/interfaces', '/etc/wpa_supplicant.conf', '/etc/resolv.conf', '/etc/default_gw', '/etc/hostname'])
48 config.plugins.SoftwareManager = ConfigSubsection()
49 config.plugins.SoftwareManager.overwriteConfigFiles = ConfigSelection(
51 ("Y", _("Yes, always")),
52 ("N", _("No, never")),
53 ("ask", _("Always ask"))
56 def write_cache(cache_file, cache_data):
58 if not os_path.isdir( os_path.dirname(cache_file) ):
60 mkdir( os_path.dirname(cache_file) )
62 print os_path.dirname(cache_file), 'is a file'
63 fd = open(cache_file, 'w')
64 dump(cache_data, fd, -1)
67 def valid_cache(cache_file, cache_ttl):
68 #See if the cache file exists and is still living
70 mtime = stat(cache_file)[ST_MTIME]
74 if (curr_time - mtime) > cache_ttl:
79 def load_cache(cache_file):
87 class UpdatePluginMenu(Screen):
89 <screen name="UpdatePluginMenu" position="center,center" size="610,410" title="Software management" >
90 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
91 <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
92 <ePixmap pixmap="skin_default/border_menu_350.png" position="5,50" zPosition="1" size="350,300" transparent="1" alphatest="on" />
93 <widget source="menu" render="Listbox" position="15,60" size="330,290" scrollbarMode="showOnDemand">
94 <convert type="TemplatedMultiContent">
96 MultiContentEntryText(pos = (2, 2), size = (330, 24), flags = RT_HALIGN_LEFT, text = 1), # index 0 is the MenuText,
98 "fonts": [gFont("Regular", 22)],
103 <widget source="menu" render="Listbox" position="360,50" size="240,300" scrollbarMode="showNever" selectionDisabled="1">
104 <convert type="TemplatedMultiContent">
106 MultiContentEntryText(pos = (2, 2), size = (240, 300), flags = RT_HALIGN_CENTER|RT_VALIGN_CENTER|RT_WRAP, text = 2), # index 2 is the Description,
108 "fonts": [gFont("Regular", 22)],
113 <widget source="status" render="Label" position="5,360" zPosition="10" size="600,50" halign="center" valign="center" font="Regular;22" transparent="1" shadowColor="black" shadowOffset="-1,-1" />
116 def __init__(self, session, args = 0):
117 Screen.__init__(self, session)
118 self.skin_path = plugin_path
121 self.oktext = _("\nPress OK on your remote control to continue.")
122 self.menutext = _("Press MENU on your remote control for additional options.")
123 self.infotext = _("Press INFO on your remote control for additional information.")
125 self.backupdirs = ' '.join( config.plugins.configurationbackup.backupdirs.value )
127 print "building menu entries"
128 self.list.append(("install-extensions", _("Manage extensions"), _("\nManage extensions or plugins for your Dreambox" ) + self.oktext, None))
129 self.list.append(("software-update", _("Software update"), _("\nOnline update of your Dreambox software." ) + self.oktext, None))
130 self.list.append(("software-restore", _("Software restore"), _("\nRestore your Dreambox with a new firmware." ) + self.oktext, None))
131 self.list.append(("system-backup", _("Backup system settings"), _("\nBackup your Dreambox settings." ) + self.oktext + "\n\n" + self.infotext, None))
132 self.list.append(("system-restore",_("Restore system settings"), _("\nRestore your Dreambox settings." ) + self.oktext, None))
133 self.list.append(("ipkg-install", _("Install local extension"), _("\nScan for local extensions and install them." ) + self.oktext, None))
134 for p in plugins.getPlugins(PluginDescriptor.WHERE_SOFTWAREMANAGER):
135 if p.__call__.has_key("SoftwareSupported"):
136 callFnc = p.__call__["SoftwareSupported"](None)
137 if callFnc is not None:
138 if p.__call__.has_key("menuEntryName"):
139 menuEntryName = p.__call__["menuEntryName"](None)
141 menuEntryName = _('Extended Software')
142 if p.__call__.has_key("menuEntryDescription"):
143 menuEntryDescription = p.__call__["menuEntryDescription"](None)
145 menuEntryDescription = _('Extended Software Plugin')
146 self.list.append(('default-plugin', menuEntryName, menuEntryDescription + self.oktext, callFnc))
147 if config.usage.setup_level.index >= 2: # expert+
148 self.list.append(("advanced", _("Advanced Options"), _("\nAdvanced options and settings." ) + self.oktext, None))
150 self.list.append(("advancedrestore", _("Advanced restore"), _("\nRestore your backups by date." ) + self.oktext, None))
151 self.list.append(("backuplocation", _("Choose backup location"), _("\nSelect your backup device.\nCurrent device: " ) + config.plugins.configurationbackup.backuplocation.value + self.oktext, None))
152 self.list.append(("backupfiles", _("Choose backup files"), _("Select files for backup.") + self.oktext + "\n\n" + self.infotext, None))
153 if config.usage.setup_level.index >= 2: # expert+
154 self.list.append(("ipkg-manager", _("Packet management"), _("\nView, install and remove available or installed packages." ) + self.oktext, None))
155 self.list.append(("ipkg-source",_("Choose upgrade source"), _("\nEdit the upgrade source address." ) + self.oktext, None))
156 for p in plugins.getPlugins(PluginDescriptor.WHERE_SOFTWAREMANAGER):
157 if p.__call__.has_key("AdvancedSoftwareSupported"):
158 callFnc = p.__call__["AdvancedSoftwareSupported"](None)
159 if callFnc is not None:
160 if p.__call__.has_key("menuEntryName"):
161 menuEntryName = p.__call__["menuEntryName"](None)
163 menuEntryName = _('Advanced Software')
164 if p.__call__.has_key("menuEntryDescription"):
165 menuEntryDescription = p.__call__["menuEntryDescription"](None)
167 menuEntryDescription = _('Advanced Software Plugin')
168 self.list.append(('advanced-plugin', menuEntryName, menuEntryDescription + self.oktext, callFnc))
170 self["menu"] = List(self.list)
171 self["key_red"] = StaticText(_("Close"))
172 self["status"] = StaticText(self.menutext)
174 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions", "InfobarEPGActions", "MenuActions"],
179 "menu": self.handleMenu,
180 "showEventInfo": self.handleInfo,
182 self.onLayoutFinish.append(self.layoutFinished)
183 self.backuppath = getBackupPath()
184 self.backupfile = getBackupFilename()
185 self.fullbackupfilename = self.backuppath + "/" + self.backupfile
186 self.onShown.append(self.setWindowTitle)
188 def layoutFinished(self):
190 self["menu"].index = idx
192 def setWindowTitle(self):
193 self.setTitle(_("Software management"))
196 iNetwork.stopPingConsole()
197 iSoftwareTools.cleanupSoftwareTools()
199 def getUpdateInfos(self):
201 if iSoftwareTools.NetworkConnectionAvailable == True:
202 if iSoftwareTools.list_updating is False:
203 if iSoftwareTools.available_updates is not 0:
204 self.text = _("There are at least ") + str(iSoftwareTools.available_updates) + _(" updates available.")
206 self.text = "" #_("There are no updates available.")
208 if iSoftwareTools.available_updates is not 0:
209 self.text = _("There are at least ") + str(iSoftwareTools.available_updates) + _(" updates available.")
211 self.text = "" #_("There are no updates available.")
212 self.text += "\n" + _("A search for available updates is currently in progress.")
214 self.text = _("No network connection available.")
215 self["status"].setText(self.text)
217 def handleMenu(self):
218 self.session.open(SoftwareManagerSetup)
220 def handleInfo(self):
221 current = self["menu"].getCurrent()
223 currentEntry = current[0]
224 if currentEntry in ("system-backup","backupfiles"):
225 self.session.open(SoftwareManagerInfo, mode = "backupinfo")
228 current = self["menu"].getCurrent()
230 currentEntry = current[0]
232 if (currentEntry == "software-update"):
233 self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to update your Dreambox?")+"\n"+_("\nAfter pressing OK, please wait!"))
234 elif (currentEntry == "software-restore"):
235 self.session.open(ImageWizard)
236 elif (currentEntry == "install-extensions"):
237 self.session.open(PluginManager, self.skin_path)
238 elif (currentEntry == "system-backup"):
239 self.session.openWithCallback(self.backupDone,BackupScreen, runBackup = True)
240 elif (currentEntry == "system-restore"):
241 if os_path.exists(self.fullbackupfilename):
242 self.session.openWithCallback(self.startRestore, MessageBox, _("Are you sure you want to restore your Enigma2 backup?\nEnigma2 will restart after the restore"))
244 self.session.open(MessageBox, _("Sorry no backups found!"), MessageBox.TYPE_INFO, timeout = 10)
245 elif (currentEntry == "ipkg-install"):
247 from Plugins.Extensions.MediaScanner.plugin import main
250 self.session.open(MessageBox, _("Sorry MediaScanner is not installed!"), MessageBox.TYPE_INFO, timeout = 10)
251 elif (currentEntry == "default-plugin"):
252 self.extended = current[3]
253 self.extended(self.session, None)
254 elif (currentEntry == "advanced"):
255 self.session.open(UpdatePluginMenu, 1)
257 if (currentEntry == "ipkg-manager"):
258 self.session.open(PacketManager, self.skin_path)
259 elif (currentEntry == "backuplocation"):
260 parts = [ (r.description, r.mountpoint, self.session) for r in harddiskmanager.getMountedPartitions(onlyhotplug = False)]
262 if not access(x[1], F_OK|R_OK|W_OK) or x[1] == '/':
265 self.session.openWithCallback(self.backuplocation_choosen, ChoiceBox, title = _("Please select medium to use as backup location"), list = parts)
266 elif (currentEntry == "backupfiles"):
267 self.session.openWithCallback(self.backupfiles_choosen,BackupSelection)
268 elif (currentEntry == "advancedrestore"):
269 self.session.open(RestoreMenu, self.skin_path)
270 elif (currentEntry == "ipkg-source"):
271 self.session.open(IPKGMenu, self.skin_path)
272 elif (currentEntry == "advanced-plugin"):
273 self.extended = current[3]
274 self.extended(self.session, None)
276 def backupfiles_choosen(self, ret):
277 self.backupdirs = ' '.join( config.plugins.configurationbackup.backupdirs.value )
278 config.plugins.configurationbackup.backupdirs.save()
279 config.plugins.configurationbackup.save()
282 def backuplocation_choosen(self, option):
283 oldpath = config.plugins.configurationbackup.backuplocation.getValue()
284 if option is not None:
285 config.plugins.configurationbackup.backuplocation.value = str(option[1])
286 config.plugins.configurationbackup.backuplocation.save()
287 config.plugins.configurationbackup.save()
289 newpath = config.plugins.configurationbackup.backuplocation.getValue()
290 if newpath != oldpath:
291 self.createBackupfolders()
293 def runUpgrade(self, result):
295 self.session.open(UpdatePlugin, self.skin_path)
297 def createBackupfolders(self):
298 print "Creating backup folder if not already there..."
299 self.backuppath = getBackupPath()
301 if (os_path.exists(self.backuppath) == False):
302 makedirs(self.backuppath)
304 self.session.open(MessageBox, _("Sorry, your backup destination is not writeable.\n\nPlease choose another one."), MessageBox.TYPE_INFO, timeout = 10)
306 def backupDone(self,retval = None):
308 self.session.open(MessageBox, _("Backup done."), MessageBox.TYPE_INFO, timeout = 10)
310 self.session.open(MessageBox, _("Backup failed."), MessageBox.TYPE_INFO, timeout = 10)
312 def startRestore(self, ret = False):
315 self.session.open(RestoreScreen, runRestore = True)
317 class SoftwareManagerSetup(Screen, ConfigListScreen):
320 <screen name="SoftwareManagerSetup" position="center,center" size="560,440" title="SoftwareManager setup">
321 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
322 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
323 <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" alphatest="on" />
324 <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" alphatest="on" />
325 <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
326 <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
327 <widget source="key_yellow" render="Label" position="280,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#a08500" transparent="1" />
328 <widget source="key_blue" render="Label" position="420,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#18188b" transparent="1" />
329 <widget name="config" position="5,50" size="550,350" scrollbarMode="showOnDemand" />
330 <ePixmap pixmap="skin_default/div-h.png" position="0,400" zPosition="1" size="560,2" />
331 <widget source="introduction" render="Label" position="5,410" size="550,30" zPosition="10" font="Regular;21" halign="center" valign="center" backgroundColor="#25062748" transparent="1" />
334 def __init__(self, session, skin_path = None):
335 Screen.__init__(self, session)
336 self.session = session
337 self.skin_path = skin_path
338 if self.skin_path == None:
339 self.skin_path = resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager")
341 self.onChangedEntry = [ ]
342 self.setup_title = _("Software manager setup")
343 self.overwriteConfigfilesEntry = None
346 ConfigListScreen.__init__(self, self.list, session = session, on_change = self.changedEntry)
348 self["actions"] = ActionMap(["SetupActions"],
350 "cancel": self.keyCancel,
354 self["key_red"] = StaticText(_("Cancel"))
355 self["key_green"] = StaticText(_("OK"))
356 self["key_yellow"] = StaticText()
357 self["key_blue"] = StaticText()
358 self["introduction"] = StaticText()
361 self.onLayoutFinish.append(self.layoutFinished)
363 def layoutFinished(self):
364 self.setTitle(self.setup_title)
366 def createSetup(self):
368 self.overwriteConfigfilesEntry = getConfigListEntry(_("Overwrite configuration files ?"), config.plugins.SoftwareManager.overwriteConfigFiles)
369 self.list.append(self.overwriteConfigfilesEntry)
370 self["config"].list = self.list
371 self["config"].l.setSeperation(400)
372 self["config"].l.setList(self.list)
373 if not self.selectionChanged in self["config"].onSelectionChanged:
374 self["config"].onSelectionChanged.append(self.selectionChanged)
375 self.selectionChanged()
377 def selectionChanged(self):
378 if self["config"].getCurrent() == self.overwriteConfigfilesEntry:
379 self["introduction"].setText(_("Overwrite configuration files during software upgrade?"))
381 self["introduction"].setText("")
387 ConfigListScreen.keyLeft(self)
390 ConfigListScreen.keyRight(self)
392 def confirm(self, confirmed):
394 print "not confirmed"
400 self.session.openWithCallback(self.confirm, MessageBox, _("Use this settings?"), MessageBox.TYPE_YESNO, timeout = 20, default = True)
402 def cancelConfirm(self, result):
405 for x in self["config"].list:
410 if self["config"].isChanged():
411 self.session.openWithCallback(self.cancelConfirm, MessageBox, _("Really close without saving settings?"), MessageBox.TYPE_YESNO, timeout = 20, default = True)
416 def changedEntry(self):
417 for x in self.onChangedEntry:
419 self.selectionChanged()
421 def getCurrentEntry(self):
422 return self["config"].getCurrent()[0]
424 def getCurrentValue(self):
425 return str(self["config"].getCurrent()[1].value)
427 def createSummary(self):
428 from Screens.Setup import SetupSummary
432 class SoftwareManagerInfo(Screen):
434 <screen name="SoftwareManagerInfo" position="center,center" size="560,440" title="SoftwareManager information">
435 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
436 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
437 <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" alphatest="on" />
438 <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" alphatest="on" />
439 <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
440 <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
441 <widget source="key_yellow" render="Label" position="280,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#a08500" transparent="1" />
442 <widget source="key_blue" render="Label" position="420,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#18188b" transparent="1" />
443 <widget source="list" render="Listbox" position="5,50" size="550,340" scrollbarMode="showOnDemand" selectionDisabled="0">
444 <convert type="TemplatedMultiContent">
446 MultiContentEntryText(pos = (5, 0), size = (540, 26), font=0, flags = RT_HALIGN_LEFT | RT_HALIGN_CENTER, text = 0), # index 0 is the name
448 "fonts": [gFont("Regular", 24),gFont("Regular", 22)],
453 <ePixmap pixmap="skin_default/div-h.png" position="0,400" zPosition="1" size="560,2" />
454 <widget source="introduction" render="Label" position="5,410" size="550,30" zPosition="10" font="Regular;21" halign="center" valign="center" backgroundColor="#25062748" transparent="1" />
457 def __init__(self, session, skin_path = None, mode = None):
458 Screen.__init__(self, session)
459 self.session = session
461 self.skin_path = skin_path
462 if self.skin_path == None:
463 self.skin_path = resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager")
465 self["actions"] = ActionMap(["ShortcutActions", "WizardActions"],
472 self["list"] = List(self.list)
474 self["key_red"] = StaticText(_("Close"))
475 self["key_green"] = StaticText()
476 self["key_yellow"] = StaticText()
477 self["key_blue"] = StaticText()
478 self["introduction"] = StaticText()
480 self.onLayoutFinish.append(self.layoutFinished)
482 def layoutFinished(self):
483 self.setTitle(_("Softwaremanager information"))
484 if self.mode is not None:
488 if self.mode == "backupinfo":
490 backupfiles = config.plugins.configurationbackup.backupdirs.value
491 for entry in backupfiles:
493 self.list.append((entry,))
494 self['list'].setList(self.list)
497 class PluginManager(Screen, DreamInfoHandler):
500 <screen name="PluginManager" position="center,center" size="560,440" title="Extensions management" >
501 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
502 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
503 <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" alphatest="on" />
504 <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" alphatest="on" />
505 <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
506 <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
507 <widget source="key_yellow" render="Label" position="280,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#a08500" transparent="1" />
508 <widget source="key_blue" render="Label" position="420,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#18188b" transparent="1" />
509 <widget source="list" render="Listbox" position="5,50" size="550,360" scrollbarMode="showOnDemand">
510 <convert type="TemplatedMultiContent">
513 MultiContentEntryText(pos = (0, 1), size = (470, 24), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
514 MultiContentEntryText(pos = (0, 25), size = (470, 24), font=1, flags = RT_HALIGN_LEFT, text = 2), # index 2 is the description
515 MultiContentEntryPixmapAlphaTest(pos = (475, 0), size = (48, 48), png = 5), # index 5 is the status pixmap
516 MultiContentEntryPixmapAlphaTest(pos = (0, 49), size = (550, 2), png = 6), # index 6 is the div pixmap
519 MultiContentEntryText(pos = (30, 0), size = (500, 22), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
520 MultiContentEntryText(pos = (30, 22), size = (500, 16), font=2, flags = RT_HALIGN_LEFT, text = 1), # index 1 is the description
521 MultiContentEntryPixmapAlphaTest(pos = (0, 38), size = (550, 2), png = 3), # index 3 is the div pixmap
524 "fonts": [gFont("Regular", 22),gFont("Regular", 20),gFont("Regular", 16)],
529 <widget source="status" render="Label" position="5,410" zPosition="10" size="540,30" halign="center" valign="center" font="Regular;22" transparent="1" shadowColor="black" shadowOffset="-1,-1" />
532 def __init__(self, session, plugin_path = None, args = None):
533 Screen.__init__(self, session)
534 self.session = session
535 self.skin_path = plugin_path
536 if self.skin_path == None:
537 self.skin_path = resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager")
539 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions", "InfobarEPGActions", "HelpActions" ],
541 "ok": self.handleCurrent,
544 "green": self.handleCurrent,
545 "yellow": self.handleSelected,
546 "showEventInfo": self.handleSelected,
547 "displayHelp": self.handleHelp,
552 self.selectedFiles = []
553 self.categoryList = []
555 self["list"] = List(self.list)
556 self["key_red"] = StaticText(_("Close"))
557 self["key_green"] = StaticText("")
558 self["key_yellow"] = StaticText("")
559 self["key_blue"] = StaticText("")
560 self["status"] = StaticText("")
563 self.oktext = _("\nAfter pressing OK, please wait!")
564 if not self.selectionChanged in self["list"].onSelectionChanged:
565 self["list"].onSelectionChanged.append(self.selectionChanged)
568 self.currentSelectedTag = None
569 self.currentSelectedIndex = None
570 self.currentSelectedPackage = None
571 self.saved_currentSelectedPackage = None
573 self.onShown.append(self.setWindowTitle)
574 self.onLayoutFinish.append(self.getUpdateInfos)
576 def setWindowTitle(self):
577 self.setTitle(_("Extensions management"))
580 if self.currList == "packages":
581 self.currList = "category"
582 self.currentSelectedTag = None
583 self["list"].style = "category"
584 self['list'].setList(self.categoryList)
585 self["list"].setIndex(self.currentSelectedIndex)
586 self["list"].updateList(self.categoryList)
587 self.selectionChanged()
589 iSoftwareTools.cleanupSoftwareTools()
590 self.prepareInstall()
591 if len(self.cmdList):
592 self.session.openWithCallback(self.runExecute, PluginManagerInfo, self.skin_path, self.cmdList)
596 def handleHelp(self):
597 if self.currList != "status":
598 self.session.open(PluginManagerHelp, self.skin_path)
600 def setState(self,status = None):
602 self.currList = "status"
604 self["key_green"].setText("")
605 self["key_blue"].setText("")
606 self["key_yellow"].setText("")
607 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
608 if status == 'update':
609 statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgrade.png"))
610 self.statuslist.append(( _("Updating software catalog"), '', _("Searching for available updates. Please wait..." ),'', '', statuspng, divpng, None, '' ))
611 elif status == 'sync':
612 statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgrade.png"))
613 self.statuslist.append(( _("Package list update"), '', _("Searching for new installed or removed packages. Please wait..." ),'', '', statuspng, divpng, None, '' ))
614 elif status == 'error':
615 self["key_green"].setText(_("Continue"))
616 statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
617 self.statuslist.append(( _("Error"), '', _("There was an error downloading the packetlist. Please try again." ),'', '', statuspng, divpng, None, '' ))
618 self["list"].style = "default"
619 self['list'].setList(self.statuslist)
622 def getUpdateInfos(self):
623 if (iSoftwareTools.lastDownloadDate is not None and iSoftwareTools.NetworkConnectionAvailable is False):
626 self.setState('update')
627 iSoftwareTools.startSoftwareTools(self.getUpdateInfosCB)
629 def getUpdateInfosCB(self, retval = None):
630 if retval is not None:
632 if iSoftwareTools.available_updates is not 0:
633 self["status"].setText(_("There are at least ") + str(iSoftwareTools.available_updates) + _(" updates available."))
635 self["status"].setText(_("There are no updates available."))
637 elif retval is False:
638 if iSoftwareTools.lastDownloadDate is None:
639 self.setState('error')
640 if iSoftwareTools.NetworkConnectionAvailable:
641 self["status"].setText(_("Updatefeed not available."))
643 self["status"].setText(_("No network connection available."))
645 iSoftwareTools.lastDownloadDate = time()
646 iSoftwareTools.list_updating = True
647 self.setState('update')
648 iSoftwareTools.getUpdates(self.getUpdateInfosCB)
650 def rebuildList(self, retval = None):
651 if self.currentSelectedTag is None:
652 self.buildCategoryList()
654 self.buildPacketList(self.currentSelectedTag)
656 def selectionChanged(self):
657 current = self["list"].getCurrent()
658 self["status"].setText("")
660 if self.currList == "packages":
661 self["key_red"].setText(_("Back"))
662 if current[4] == 'installed':
663 self["key_green"].setText(_("Uninstall"))
664 elif current[4] == 'installable':
665 self["key_green"].setText(_("Install"))
666 if iSoftwareTools.NetworkConnectionAvailable is False:
667 self["key_green"].setText("")
668 elif current[4] == 'remove':
669 self["key_green"].setText(_("Undo uninstall"))
670 elif current[4] == 'install':
671 self["key_green"].setText(_("Undo install"))
672 if iSoftwareTools.NetworkConnectionAvailable is False:
673 self["key_green"].setText("")
674 self["key_yellow"].setText(_("View details"))
675 self["key_blue"].setText("")
676 if len(self.selectedFiles) == 0 and iSoftwareTools.available_updates is not 0:
677 self["status"].setText(_("There are at least ") + str(iSoftwareTools.available_updates) + _(" updates available."))
678 elif len(self.selectedFiles) is not 0:
679 self["status"].setText(str(len(self.selectedFiles)) + _(" packages selected."))
681 self["status"].setText(_("There are currently no outstanding actions."))
682 elif self.currList == "category":
683 self["key_red"].setText(_("Close"))
684 self["key_green"].setText("")
685 self["key_yellow"].setText("")
686 self["key_blue"].setText("")
687 if len(self.selectedFiles) == 0 and iSoftwareTools.available_updates is not 0:
688 self["status"].setText(_("There are at least ") + str(iSoftwareTools.available_updates) + _(" updates available."))
689 self["key_yellow"].setText(_("Update"))
690 elif len(self.selectedFiles) is not 0:
691 self["status"].setText(str(len(self.selectedFiles)) + _(" packages selected."))
692 self["key_yellow"].setText(_("Process"))
694 self["status"].setText(_("There are currently no outstanding actions."))
696 def getSelectionState(self, detailsFile):
697 for entry in self.selectedFiles:
698 if entry[0] == detailsFile:
702 def handleCurrent(self):
703 current = self["list"].getCurrent()
705 if self.currList == "category":
706 self.currentSelectedIndex = self["list"].index
707 selectedTag = current[2]
708 self.buildPacketList(selectedTag)
709 elif self.currList == "packages":
710 if current[7] is not '':
711 idx = self["list"].getIndex()
712 detailsFile = self.list[idx][1]
713 if self.list[idx][7] == True:
714 for entry in self.selectedFiles:
715 if entry[0] == detailsFile:
716 self.selectedFiles.remove(entry)
718 alreadyinList = False
719 for entry in self.selectedFiles:
720 if entry[0] == detailsFile:
722 if not alreadyinList:
723 if (iSoftwareTools.NetworkConnectionAvailable is False and current[4] in ('installable','install')):
726 self.selectedFiles.append((detailsFile,current[4],current[3]))
727 self.currentSelectedPackage = ((detailsFile,current[4],current[3]))
728 if current[4] == 'installed':
729 self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'remove', True)
730 elif current[4] == 'installable':
731 if iSoftwareTools.NetworkConnectionAvailable:
732 self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'install', True)
733 elif current[4] == 'remove':
734 self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'installed', False)
735 elif current[4] == 'install':
736 if iSoftwareTools.NetworkConnectionAvailable:
737 self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'installable',False)
738 self["list"].setList(self.list)
739 self["list"].setIndex(idx)
740 self["list"].updateList(self.list)
741 self.selectionChanged()
742 elif self.currList == "status":
743 iSoftwareTools.lastDownloadDate = time()
744 iSoftwareTools.list_updating = True
745 self.setState('update')
746 iSoftwareTools.getUpdates(self.getUpdateInfosCB)
748 def handleSelected(self):
749 current = self["list"].getCurrent()
751 if self.currList == "packages":
752 if current[7] is not '':
753 detailsfile = iSoftwareTools.directory[0] + "/" + current[1]
754 if (os_path.exists(detailsfile) == True):
755 self.saved_currentSelectedPackage = self.currentSelectedPackage
756 self.session.openWithCallback(self.detailsClosed, PluginDetails, self.skin_path, current)
758 self.session.open(MessageBox, _("Sorry, no Details available!"), MessageBox.TYPE_INFO, timeout = 10)
759 elif self.currList == "category":
760 self.prepareInstall()
761 if len(self.cmdList):
762 self.session.openWithCallback(self.runExecute, PluginManagerInfo, self.skin_path, self.cmdList)
764 def detailsClosed(self, result = None):
765 if result is not None:
766 if result is not False:
767 self.setState('sync')
768 iSoftwareTools.lastDownloadDate = time()
769 for entry in self.selectedFiles:
770 if entry == self.saved_currentSelectedPackage:
771 self.selectedFiles.remove(entry)
772 iSoftwareTools.startIpkgListInstalled(self.rebuildList)
774 def buildEntryComponent(self, name, details, description, packagename, state, selected = False):
775 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
776 installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installed.png"))
777 installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installable.png"))
778 removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
779 installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/install.png"))
780 if state == 'installed':
781 return((name, details, description, packagename, state, installedpng, divpng, selected))
782 elif state == 'installable':
783 return((name, details, description, packagename, state, installablepng, divpng, selected))
784 elif state == 'remove':
785 return((name, details, description, packagename, state, removepng, divpng, selected))
786 elif state == 'install':
787 return((name, details, description, packagename, state, installpng, divpng, selected))
789 def buildPacketList(self, categorytag = None):
790 if categorytag is not None:
791 self.currList = "packages"
792 self.currentSelectedTag = categorytag
794 for package in iSoftwareTools.packagesIndexlist[:]:
795 prerequisites = package[0]["prerequisites"]
796 if prerequisites.has_key("tag"):
797 for foundtag in prerequisites["tag"]:
798 if categorytag == foundtag:
799 attributes = package[0]["attributes"]
800 if attributes.has_key("packagetype"):
801 if attributes["packagetype"] == "internal":
803 self.packetlist.append([attributes["name"], attributes["details"], attributes["shortdescription"], attributes["packagename"]])
805 self.packetlist.append([attributes["name"], attributes["details"], attributes["shortdescription"], attributes["packagename"]])
807 for x in self.packetlist:
810 details = x[1].strip()
811 description = x[2].strip()
812 packagename = x[3].strip()
813 selectState = self.getSelectionState(details)
814 if iSoftwareTools.installed_packetlist.has_key(packagename):
815 if selectState == True:
819 self.list.append(self.buildEntryComponent(name, _(details), _(description), packagename, status, selected = selectState))
821 if selectState == True:
824 status = "installable"
825 self.list.append(self.buildEntryComponent(name, _(details), _(description), packagename, status, selected = selectState))
827 self.list.sort(key=lambda x: x[0])
828 self["list"].style = "default"
829 self['list'].setList(self.list)
830 self["list"].updateList(self.list)
831 self.selectionChanged()
833 def buildCategoryList(self):
834 self.currList = "category"
836 self.categoryList = []
837 for package in iSoftwareTools.packagesIndexlist[:]:
838 prerequisites = package[0]["prerequisites"]
839 if prerequisites.has_key("tag"):
840 for foundtag in prerequisites["tag"]:
841 attributes = package[0]["attributes"]
842 if foundtag not in self.categories:
843 self.categories.append(foundtag)
844 self.categoryList.append(self.buildCategoryComponent(foundtag))
845 self.categoryList.sort(key=lambda x: x[0])
846 self["list"].style = "category"
847 self['list'].setList(self.categoryList)
848 self["list"].updateList(self.categoryList)
849 self.selectionChanged()
851 def buildCategoryComponent(self, tag = None):
852 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
855 return(( _("System"), _("View list of available system extensions" ), tag, divpng ))
857 return(( _("Skins"), _("View list of available skins" ), tag, divpng ))
858 elif tag == 'Recording':
859 return(( _("Recordings"), _("View list of available recording extensions" ), tag, divpng ))
860 elif tag == 'Network':
861 return(( _("Network"), _("View list of available networking extensions" ), tag, divpng ))
863 return(( _("CommonInterface"), _("View list of available CommonInterface extensions" ), tag, divpng ))
864 elif tag == 'Default':
865 return(( _("Default Settings"), _("View list of available default settings" ), tag, divpng ))
867 return(( _("Satellite equipment"), _("View list of available Satellite equipment extensions." ), tag, divpng ))
868 elif tag == 'Software':
869 return(( _("Software"), _("View list of available software extensions" ), tag, divpng ))
870 elif tag == 'Multimedia':
871 return(( _("Multimedia"), _("View list of available multimedia extensions." ), tag, divpng ))
872 elif tag == 'Display':
873 return(( _("Display and Userinterface"), _("View list of available Display and Userinterface extensions." ), tag, divpng ))
875 return(( _("Electronic Program Guide"), _("View list of available EPG extensions." ), tag, divpng ))
876 elif tag == 'Communication':
877 return(( _("Communication"), _("View list of available communication extensions." ), tag, divpng ))
878 else: # dynamically generate non existent tags
879 return(( str(tag), _("View list of available ") + str(tag) + _(" extensions." ), tag, divpng ))
881 def prepareInstall(self):
883 if iSoftwareTools.available_updates > 0:
884 self.cmdList.append((IpkgComponent.CMD_UPGRADE, { "test_only": False }))
885 if self.selectedFiles and len(self.selectedFiles):
886 for plugin in self.selectedFiles:
887 detailsfile = iSoftwareTools.directory[0] + "/" + plugin[0]
888 if (os_path.exists(detailsfile) == True):
889 iSoftwareTools.fillPackageDetails(plugin[0])
890 self.package = iSoftwareTools.packageDetails[0]
891 if self.package[0].has_key("attributes"):
892 self.attributes = self.package[0]["attributes"]
893 if self.attributes.has_key("package"):
894 self.packagefiles = self.attributes["package"]
895 if plugin[1] == 'installed':
896 if self.packagefiles:
897 for package in self.packagefiles[:]:
898 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": package["name"] }))
900 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": plugin[2] }))
902 if self.packagefiles:
903 for package in self.packagefiles[:]:
904 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package["name"] }))
906 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": plugin[2] }))
908 if plugin[1] == 'installed':
909 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": plugin[2] }))
911 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": plugin[2] }))
913 def runExecute(self, result = None):
914 if result is not None:
915 if result[0] is True:
916 self.session.openWithCallback(self.runExecuteFinished, Ipkg, cmdList = self.cmdList)
917 elif result[0] is False:
918 self.cmdList = result[1]
919 self.session.openWithCallback(self.runExecuteFinished, Ipkg, cmdList = self.cmdList)
923 def runExecuteFinished(self):
924 self.session.openWithCallback(self.ExecuteReboot, MessageBox, _("Install or remove finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
926 def ExecuteReboot(self, result):
930 self.reloadPluginlist()
931 self.selectedFiles = []
932 self.detailsClosed(True)
936 def reloadPluginlist(self):
937 plugins.readPluginList(resolveFilename(SCOPE_PLUGINS))
940 class PluginManagerInfo(Screen):
942 <screen name="PluginManagerInfo" position="center,center" size="560,450" title="Plugin manager activity information" >
943 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
944 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
945 <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" />
946 <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" />
947 <widget source="list" render="Listbox" position="5,50" size="550,350" scrollbarMode="showOnDemand" selectionDisabled="1">
948 <convert type="TemplatedMultiContent">
950 MultiContentEntryText(pos = (50, 0), size = (150, 26), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
951 MultiContentEntryText(pos = (50, 27), size = (540, 23), font=1, flags = RT_HALIGN_LEFT, text = 1), # index 1 is the state
952 MultiContentEntryPixmapAlphaTest(pos = (0, 1), size = (48, 48), png = 2), # index 2 is the status pixmap
953 MultiContentEntryPixmapAlphaTest(pos = (0, 48), size = (550, 2), png = 3), # index 3 is the div pixmap
955 "fonts": [gFont("Regular", 24),gFont("Regular", 22)],
960 <ePixmap pixmap="skin_default/div-h.png" position="0,404" zPosition="10" size="560,2" transparent="1" alphatest="on" />
961 <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" />
964 def __init__(self, session, plugin_path, cmdlist = None):
965 Screen.__init__(self, session)
966 self.session = session
967 self.skin_path = plugin_path
968 self.cmdlist = cmdlist
970 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"],
972 "ok": self.process_all,
975 "green": self.process_extensions,
979 self["list"] = List(self.list)
980 self["key_red"] = StaticText(_("Cancel"))
981 self["key_green"] = StaticText(_("Only extensions."))
982 self["status"] = StaticText(_("Following tasks will be done after you press OK!"))
984 self.onShown.append(self.setWindowTitle)
985 self.onLayoutFinish.append(self.rebuildList)
987 def setWindowTitle(self):
988 self.setTitle(_("Plugin manager activity information"))
990 def rebuildList(self):
992 if self.cmdlist is not None:
993 for entry in self.cmdlist:
1005 info = args['package']
1007 info = args['package']
1009 info = _("Dreambox software because updates are available.")
1011 self.list.append(self.buildEntryComponent(action,info))
1012 self['list'].setList(self.list)
1013 self['list'].updateList(self.list)
1015 def buildEntryComponent(self, action,info):
1016 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
1017 upgradepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgrade.png"))
1018 installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/install.png"))
1019 removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
1020 if action == 'install':
1021 return(( _('Installing'), info, installpng, divpng))
1022 elif action == 'remove':
1023 return(( _('Removing'), info, removepng, divpng))
1025 return(( _('Upgrading'), info, upgradepng, divpng))
1030 def process_all(self):
1031 self.close((True,None))
1033 def process_extensions(self):
1035 if self.cmdlist is not None:
1036 for entry in self.cmdlist:
1038 if entry[0] in (0,2):
1039 self.list.append((entry))
1040 self.close((False,self.list))
1043 class PluginManagerHelp(Screen):
1045 <screen name="PluginManagerHelp" position="center,center" size="560,450" title="Plugin manager help" >
1046 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1047 <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" />
1048 <widget source="list" render="Listbox" position="5,50" size="550,350" scrollbarMode="showOnDemand" selectionDisabled="1">
1049 <convert type="TemplatedMultiContent">
1051 MultiContentEntryText(pos = (50, 0), size = (540, 26), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
1052 MultiContentEntryText(pos = (50, 27), size = (540, 23), font=1, flags = RT_HALIGN_LEFT, text = 1), # index 1 is the state
1053 MultiContentEntryPixmapAlphaTest(pos = (0, 1), size = (48, 48), png = 2), # index 2 is the status pixmap
1054 MultiContentEntryPixmapAlphaTest(pos = (0, 48), size = (550, 2), png = 3), # index 3 is the div pixmap
1056 "fonts": [gFont("Regular", 24),gFont("Regular", 22)],
1061 <ePixmap pixmap="skin_default/div-h.png" position="0,404" zPosition="10" size="560,2" transparent="1" alphatest="on" />
1062 <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" />
1065 def __init__(self, session, plugin_path):
1066 Screen.__init__(self, session)
1067 self.session = session
1068 self.skin_path = plugin_path
1070 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"],
1077 self["list"] = List(self.list)
1078 self["key_red"] = StaticText(_("Close"))
1079 self["status"] = StaticText(_("A small overview of the available icon states and actions."))
1081 self.onShown.append(self.setWindowTitle)
1082 self.onLayoutFinish.append(self.rebuildList)
1084 def setWindowTitle(self):
1085 self.setTitle(_("Plugin manager help"))
1087 def rebuildList(self):
1089 self.list.append(self.buildEntryComponent('install'))
1090 self.list.append(self.buildEntryComponent('installable'))
1091 self.list.append(self.buildEntryComponent('installed'))
1092 self.list.append(self.buildEntryComponent('remove'))
1093 self['list'].setList(self.list)
1094 self['list'].updateList(self.list)
1096 def buildEntryComponent(self, state):
1097 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
1098 installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installed.png"))
1099 installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installable.png"))
1100 removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
1101 installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/install.png"))
1103 if state == 'installed':
1104 return(( _('This plugin is installed.'), _('You can remove this plugin.'), installedpng, divpng))
1105 elif state == 'installable':
1106 return(( _('This plugin is not installed.'), _('You can install this plugin.'), installablepng, divpng))
1107 elif state == 'install':
1108 return(( _('This plugin will be installed.'), _('You can cancel the installation.'), installpng, divpng))
1109 elif state == 'remove':
1110 return(( _('This plugin will be removed.'), _('You can cancel the removal.'), removepng, divpng))
1116 class PluginDetails(Screen, DreamInfoHandler):
1118 <screen name="PluginDetails" position="center,center" size="600,440" title="Plugin details" >
1119 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1120 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1121 <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" />
1122 <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" />
1123 <widget source="author" render="Label" position="10,50" size="500,25" zPosition="10" font="Regular;21" transparent="1" />
1124 <widget name="statuspic" position="550,40" size="48,48" alphatest="on"/>
1125 <widget name="divpic" position="0,80" size="600,2" alphatest="on"/>
1126 <widget name="detailtext" position="10,90" size="270,330" zPosition="10" font="Regular;21" transparent="1" halign="left" valign="top"/>
1127 <widget name="screenshot" position="290,90" size="300,330" alphatest="on"/>
1129 def __init__(self, session, plugin_path, packagedata = None):
1130 Screen.__init__(self, session)
1131 self.skin_path = plugin_path
1132 self.language = language.getLanguage()[:2] # getLanguage returns e.g. "fi_FI" for "language_country"
1133 self.attributes = None
1134 DreamInfoHandler.__init__(self, self.statusCallback, blocking = False)
1135 self.directory = resolveFilename(SCOPE_METADIR)
1137 self.pluginname = packagedata[0]
1138 self.details = packagedata[1]
1139 self.pluginstate = packagedata[4]
1140 self.statuspicinstance = packagedata[5]
1141 self.divpicinstance = packagedata[6]
1142 self.fillPackageDetails(self.details)
1146 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"],
1152 "down": self.pageDown,
1153 "left": self.pageUp,
1154 "right": self.pageDown,
1157 self["key_red"] = StaticText(_("Close"))
1158 self["key_green"] = StaticText("")
1159 self["author"] = StaticText()
1160 self["statuspic"] = Pixmap()
1161 self["divpic"] = Pixmap()
1162 self["screenshot"] = Pixmap()
1163 self["detailtext"] = ScrollLabel()
1165 self["statuspic"].hide()
1166 self["screenshot"].hide()
1167 self["divpic"].hide()
1169 self.package = self.packageDetails[0]
1170 if self.package[0].has_key("attributes"):
1171 self.attributes = self.package[0]["attributes"]
1174 self.oktext = _("\nAfter pressing OK, please wait!")
1175 self.picload = ePicLoad()
1176 self.picload.PictureData.get().append(self.paintScreenshotPixmapCB)
1177 self.onShown.append(self.setWindowTitle)
1178 self.onLayoutFinish.append(self.setInfos)
1180 def setWindowTitle(self):
1181 self.setTitle(_("Details for plugin: ") + self.pluginname )
1187 self["detailtext"].pageUp()
1190 self["detailtext"].pageDown()
1192 def statusCallback(self, status, progress):
1196 if self.attributes.has_key("screenshot"):
1197 self.loadThumbnail(self.attributes)
1199 if self.attributes.has_key("name"):
1200 self.pluginname = self.attributes["name"]
1202 self.pluginname = _("unknown")
1204 if self.attributes.has_key("author"):
1205 self.author = self.attributes["author"]
1207 self.author = _("unknown")
1209 if self.attributes.has_key("description"):
1210 self.description = _(self.attributes["description"].replace("\\n", "\n"))
1212 self.description = _("No description available.")
1214 self["author"].setText(_("Author: ") + self.author)
1215 self["detailtext"].setText(_(self.description))
1216 if self.pluginstate in ('installable', 'install'):
1217 if iSoftwareTools.NetworkConnectionAvailable:
1218 self["key_green"].setText(_("Install"))
1220 self["key_green"].setText("")
1222 self["key_green"].setText(_("Remove"))
1224 def loadThumbnail(self, entry):
1226 if entry.has_key("screenshot"):
1227 thumbnailUrl = entry["screenshot"]
1228 if self.language == "de":
1229 if thumbnailUrl[-7:] == "_en.jpg":
1230 thumbnailUrl = thumbnailUrl[:-7] + "_de.jpg"
1232 if thumbnailUrl is not None:
1233 self.thumbnail = "/tmp/" + thumbnailUrl.split('/')[-1]
1234 print "[PluginDetails] downloading screenshot " + thumbnailUrl + " to " + self.thumbnail
1235 if iSoftwareTools.NetworkConnectionAvailable:
1236 client.downloadPage(thumbnailUrl,self.thumbnail).addCallback(self.setThumbnail).addErrback(self.fetchFailed)
1238 self.setThumbnail(noScreenshot = True)
1240 self.setThumbnail(noScreenshot = True)
1242 def setThumbnail(self, noScreenshot = False):
1243 if not noScreenshot:
1244 filename = self.thumbnail
1246 filename = resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/noprev.png")
1248 sc = AVSwitch().getFramebufferScale()
1249 self.picload.setPara((self["screenshot"].instance.size().width(), self["screenshot"].instance.size().height(), sc[0], sc[1], False, 1, "#00000000"))
1250 self.picload.startDecode(filename)
1252 if self.statuspicinstance != None:
1253 self["statuspic"].instance.setPixmap(self.statuspicinstance.__deref__())
1254 self["statuspic"].show()
1255 if self.divpicinstance != None:
1256 self["divpic"].instance.setPixmap(self.divpicinstance.__deref__())
1257 self["divpic"].show()
1259 def paintScreenshotPixmapCB(self, picInfo=None):
1260 ptr = self.picload.getData()
1262 self["screenshot"].instance.setPixmap(ptr.__deref__())
1263 self["screenshot"].show()
1265 self.setThumbnail(noScreenshot = True)
1268 if self.attributes.has_key("package"):
1269 self.packagefiles = self.attributes["package"]
1271 if self.pluginstate in ('installed', 'remove'):
1272 if self.packagefiles:
1273 for package in self.packagefiles[:]:
1274 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": package["name"] }))
1275 if len(self.cmdList):
1276 self.session.openWithCallback(self.runRemove, MessageBox, _("Do you want to remove the package:\n") + self.pluginname + "\n" + self.oktext)
1278 if iSoftwareTools.NetworkConnectionAvailable:
1279 if self.packagefiles:
1280 for package in self.packagefiles[:]:
1281 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package["name"] }))
1282 if len(self.cmdList):
1283 self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to install the package:\n") + self.pluginname + "\n" + self.oktext)
1285 def runUpgrade(self, result):
1287 self.session.openWithCallback(self.runUpgradeFinished, Ipkg, cmdList = self.cmdList)
1289 def runUpgradeFinished(self):
1290 self.session.openWithCallback(self.UpgradeReboot, MessageBox, _("Installation finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
1292 def UpgradeReboot(self, result):
1300 def runRemove(self, result):
1302 self.session.openWithCallback(self.runRemoveFinished, Ipkg, cmdList = self.cmdList)
1304 def runRemoveFinished(self):
1305 self.session.openWithCallback(self.RemoveReboot, MessageBox, _("Remove finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
1307 def RemoveReboot(self, result):
1315 def reloadPluginlist(self):
1316 plugins.readPluginList(resolveFilename(SCOPE_PLUGINS))
1318 def fetchFailed(self,string):
1319 self.setThumbnail(noScreenshot = True)
1320 print "[PluginDetails] fetch failed " + string.getErrorMessage()
1323 class UpdatePlugin(Screen):
1325 <screen name="UpdatePlugin" position="center,center" size="550,300" title="Software update" >
1326 <widget name="activityslider" position="0,0" size="550,5" />
1327 <widget name="slider" position="0,150" size="550,30" />
1328 <widget source="package" render="Label" position="10,30" size="540,20" font="Regular;18" halign="center" valign="center" backgroundColor="#25062748" transparent="1" />
1329 <widget source="status" render="Label" position="10,180" size="540,100" font="Regular;20" halign="center" valign="center" backgroundColor="#25062748" transparent="1" />
1332 def __init__(self, session, args = None):
1333 Screen.__init__(self, session)
1335 self.sliderPackages = { "dreambox-dvb-modules": 1, "enigma2": 2, "tuxbox-image-info": 3 }
1337 self.slider = Slider(0, 4)
1338 self["slider"] = self.slider
1339 self.activityslider = Slider(0, 100)
1340 self["activityslider"] = self.activityslider
1341 self.status = StaticText(_("Please wait..."))
1342 self["status"] = self.status
1343 self.package = StaticText(_("Verifying your internet connection..."))
1344 self["package"] = self.package
1345 self.oktext = _("Press OK on your remote control to continue.")
1349 self.processed_packages = []
1352 self.activityTimer = eTimer()
1353 self.activityTimer.callback.append(self.doActivityTimer)
1355 self.ipkg = IpkgComponent()
1356 self.ipkg.addCallback(self.ipkgCallback)
1358 self.updating = False
1360 self["actions"] = ActionMap(["WizardActions"],
1366 iNetwork.checkNetworkState(self.checkNetworkCB)
1367 self.onClose.append(self.cleanup)
1370 iNetwork.stopPingConsole()
1372 def checkNetworkCB(self,data):
1373 if data is not None:
1375 self.updating = True
1376 self.activityTimer.start(100, False)
1377 self.package.setText(_("Package list update"))
1378 self.status.setText(_("Upgrading Dreambox... Please wait"))
1379 self.ipkg.startCmd(IpkgComponent.CMD_UPDATE)
1381 self.package.setText(_("Your network is not working. Please try again."))
1382 self.status.setText(self.oktext)
1384 def doActivityTimer(self):
1386 if self.activity == 100:
1388 self.activityslider.setValue(self.activity)
1390 def ipkgCallback(self, event, param):
1391 if event == IpkgComponent.EVENT_DOWNLOAD:
1392 self.status.setText(_("Downloading"))
1393 elif event == IpkgComponent.EVENT_UPGRADE:
1394 if self.sliderPackages.has_key(param):
1395 self.slider.setValue(self.sliderPackages[param])
1396 self.package.setText(param)
1397 self.status.setText(_("Upgrading"))
1398 if not param in self.processed_packages:
1399 self.processed_packages.append(param)
1401 elif event == IpkgComponent.EVENT_INSTALL:
1402 self.package.setText(param)
1403 self.status.setText(_("Installing"))
1404 if not param in self.processed_packages:
1405 self.processed_packages.append(param)
1407 elif event == IpkgComponent.EVENT_REMOVE:
1408 self.package.setText(param)
1409 self.status.setText(_("Removing"))
1410 if not param in self.processed_packages:
1411 self.processed_packages.append(param)
1413 elif event == IpkgComponent.EVENT_CONFIGURING:
1414 self.package.setText(param)
1415 self.status.setText(_("Configuring"))
1417 elif event == IpkgComponent.EVENT_MODIFIED:
1418 if config.plugins.SoftwareManager.overwriteConfigFiles.value in ("N", "Y"):
1419 self.ipkg.write(True and config.plugins.SoftwareManager.overwriteConfigFiles.value)
1421 self.session.openWithCallback(
1422 self.modificationCallback,
1424 _("A configuration file (%s) was modified since Installation.\nDo you want to keep your version?") % (param)
1426 elif event == IpkgComponent.EVENT_ERROR:
1428 elif event == IpkgComponent.EVENT_DONE:
1430 self.updating = False
1431 self.ipkg.startCmd(IpkgComponent.CMD_UPGRADE, args = {'test_only': False})
1432 elif self.error == 0:
1433 self.slider.setValue(4)
1435 self.activityTimer.stop()
1436 self.activityslider.setValue(0)
1438 self.package.setText(_("Done - Installed or upgraded %d packages") % self.packages)
1439 self.status.setText(self.oktext)
1441 self.activityTimer.stop()
1442 self.activityslider.setValue(0)
1443 error = _("your dreambox might be unusable now. Please consult the manual for further assistance before rebooting your dreambox.")
1444 if self.packages == 0:
1445 error = _("No packages were upgraded yet. So you can check your network and try again.")
1447 error = _("Your dreambox isn't connected to the internet properly. Please check it and try again.")
1448 self.status.setText(_("Error") + " - " + error)
1449 #print event, "-", param
1452 def modificationCallback(self, res):
1453 self.ipkg.write(res and "N" or "Y")
1456 if not self.ipkg.isRunning():
1457 if self.packages != 0 and self.error == 0:
1458 self.session.openWithCallback(self.exitAnswer, MessageBox, _("Upgrade finished.") +" "+_("Do you want to reboot your Dreambox?"))
1462 if not self.updating:
1465 def exitAnswer(self, result):
1466 if result is not None and result:
1472 class IPKGMenu(Screen):
1474 <screen name="IPKGMenu" position="center,center" size="560,400" title="Select upgrade source to edit." >
1475 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1476 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1477 <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" />
1478 <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" />
1479 <widget name="filelist" position="5,50" size="550,340" scrollbarMode="showOnDemand" />
1482 def __init__(self, session, plugin_path):
1483 Screen.__init__(self, session)
1484 self.skin_path = plugin_path
1486 self["key_red"] = StaticText(_("Close"))
1487 self["key_green"] = StaticText(_("Edit"))
1496 self["actions"] = NumberActionMap(["SetupActions"],
1499 "cancel": self.keyCancel
1502 self["shortcuts"] = ActionMap(["ShortcutActions"],
1504 "red": self.keyCancel,
1505 "green": self.KeyOk,
1508 self["filelist"] = MenuList(self.flist)
1510 self.onLayoutFinish.append(self.layoutFinished)
1512 def layoutFinished(self):
1513 self.setWindowTitle()
1515 def setWindowTitle(self):
1516 self.setTitle(_("Select upgrade source to edit."))
1518 def fill_list(self):
1520 self.path = '/etc/opkg/'
1521 if (os_path.exists(self.path) == False):
1524 for file in listdir(self.path):
1525 if (file.endswith(".conf")):
1526 if file != 'arch.conf':
1527 self.flist.append((file))
1529 self["filelist"].l.setList(self.flist)
1532 if (self.exe == False) and (self.entry == True):
1533 self.sel = self["filelist"].getCurrent()
1534 self.val = self.path + self.sel
1535 self.session.open(IPKGSource, self.val)
1537 def keyCancel(self):
1544 class IPKGSource(Screen):
1546 <screen name="IPKGSource" position="center,center" size="560,80" title="Edit upgrade source url." >
1547 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1548 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1549 <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" />
1550 <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" />
1551 <widget name="text" position="5,50" size="550,25" font="Regular;20" backgroundColor="background" foregroundColor="#cccccc" />
1554 def __init__(self, session, configfile = None):
1555 Screen.__init__(self, session)
1556 self.session = session
1557 self.configfile = configfile
1561 fp = file(configfile, 'r')
1562 sources = fp.readlines()
1569 desk = getDesktop(0)
1570 x= int(desk.size().width())
1571 y= int(desk.size().height())
1573 self["key_red"] = StaticText(_("Cancel"))
1574 self["key_green"] = StaticText(_("Save"))
1577 self["text"] = Input(text, maxSize=False, type=Input.TEXT)
1579 self["text"] = Input(text, maxSize=False, visible_width = 55, type=Input.TEXT)
1581 self["actions"] = NumberActionMap(["WizardActions", "InputActions", "TextEntryActions", "KeyboardInputActions","ShortcutActions"],
1587 "left": self.keyLeft,
1588 "right": self.keyRight,
1589 "home": self.keyHome,
1591 "deleteForward": self.keyDeleteForward,
1592 "deleteBackward": self.keyDeleteBackward,
1593 "1": self.keyNumberGlobal,
1594 "2": self.keyNumberGlobal,
1595 "3": self.keyNumberGlobal,
1596 "4": self.keyNumberGlobal,
1597 "5": self.keyNumberGlobal,
1598 "6": self.keyNumberGlobal,
1599 "7": self.keyNumberGlobal,
1600 "8": self.keyNumberGlobal,
1601 "9": self.keyNumberGlobal,
1602 "0": self.keyNumberGlobal
1605 self.onLayoutFinish.append(self.layoutFinished)
1607 def layoutFinished(self):
1608 self.setWindowTitle()
1609 self["text"].right()
1611 def setWindowTitle(self):
1612 self.setTitle(_("Edit upgrade source url."))
1615 text = self["text"].getText()
1617 fp = file(self.configfile, 'w')
1627 self["text"].right()
1635 def keyDeleteForward(self):
1636 self["text"].delete()
1638 def keyDeleteBackward(self):
1639 self["text"].deleteBackward()
1641 def keyNumberGlobal(self, number):
1642 self["text"].number(number)
1645 class PacketManager(Screen, NumericalTextInput):
1647 <screen name="PacketManager" position="center,center" size="530,420" title="Packet manager" >
1648 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1649 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1650 <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" />
1651 <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" />
1652 <widget source="list" render="Listbox" position="5,50" size="520,365" scrollbarMode="showOnDemand">
1653 <convert type="TemplatedMultiContent">
1655 MultiContentEntryText(pos = (5, 1), size = (440, 28), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
1656 MultiContentEntryText(pos = (5, 26), size = (440, 20), font=1, flags = RT_HALIGN_LEFT, text = 2), # index 2 is the description
1657 MultiContentEntryPixmapAlphaTest(pos = (445, 2), size = (48, 48), png = 4), # index 4 is the status pixmap
1658 MultiContentEntryPixmapAlphaTest(pos = (5, 50), size = (510, 2), png = 5), # index 4 is the div pixmap
1660 "fonts": [gFont("Regular", 22),gFont("Regular", 14)],
1667 def __init__(self, session, plugin_path, args = None):
1668 Screen.__init__(self, session)
1669 NumericalTextInput.__init__(self)
1670 self.session = session
1671 self.skin_path = plugin_path
1673 self.setUseableChars(u'1234567890abcdefghijklmnopqrstuvwxyz')
1675 self["shortcuts"] = NumberActionMap(["ShortcutActions", "WizardActions", "NumberActions", "InputActions", "InputAsciiActions", "KeyboardInputActions" ],
1680 "green": self.reload,
1681 "gotAsciiCode": self.keyGotAscii,
1682 "1": self.keyNumberGlobal,
1683 "2": self.keyNumberGlobal,
1684 "3": self.keyNumberGlobal,
1685 "4": self.keyNumberGlobal,
1686 "5": self.keyNumberGlobal,
1687 "6": self.keyNumberGlobal,
1688 "7": self.keyNumberGlobal,
1689 "8": self.keyNumberGlobal,
1690 "9": self.keyNumberGlobal,
1691 "0": self.keyNumberGlobal
1695 self.statuslist = []
1696 self["list"] = List(self.list)
1697 self["key_red"] = StaticText(_("Close"))
1698 self["key_green"] = StaticText(_("Reload"))
1700 self.list_updating = True
1701 self.packetlist = []
1702 self.installed_packetlist = {}
1703 self.upgradeable_packages = {}
1704 self.Console = Console()
1707 self.cache_ttl = 86400 #600 is default, 0 disables, Seconds cache is considered valid (24h should be ok for caching ipkgs)
1708 self.cache_file = eEnv.resolve('${libdir}/enigma2/python/Plugins/SystemPlugins/SoftwareManager/packetmanager.cache') #Path to cache directory
1709 self.oktext = _("\nAfter pressing OK, please wait!")
1710 self.unwanted_extensions = ('-dbg', '-dev', '-doc', 'busybox')
1712 self.ipkg = IpkgComponent()
1713 self.ipkg.addCallback(self.ipkgCallback)
1714 self.onShown.append(self.setWindowTitle)
1715 self.onLayoutFinish.append(self.rebuildList)
1717 rcinput = eRCInput.getInstance()
1718 rcinput.setKeyboardMode(rcinput.kmAscii)
1720 def keyNumberGlobal(self, val):
1721 key = self.getKey(val)
1723 keyvalue = key.encode("utf-8")
1724 if len(keyvalue) == 1:
1725 self.setNextIdx(keyvalue[0])
1727 def keyGotAscii(self):
1728 keyvalue = unichr(getPrevAsciiCode()).encode("utf-8")
1729 if len(keyvalue) == 1:
1730 self.setNextIdx(keyvalue[0])
1732 def setNextIdx(self,char):
1733 if char in ("0", "1", "a"):
1734 self["list"].setIndex(0)
1736 idx = self.getNextIdx(char)
1737 if idx and idx <= self["list"].count:
1738 self["list"].setIndex(idx)
1740 def getNextIdx(self,char):
1742 for i in self["list"].list:
1749 if self.Console is not None:
1750 if len(self.Console.appContainers):
1751 for name in self.Console.appContainers.keys():
1752 self.Console.kill(name)
1753 rcinput = eRCInput.getInstance()
1754 rcinput.setKeyboardMode(rcinput.kmNone)
1758 if (os_path.exists(self.cache_file) == True):
1759 remove(self.cache_file)
1760 self.list_updating = True
1763 def setWindowTitle(self):
1764 self.setTitle(_("Packet manager"))
1766 def setStatus(self,status = None):
1768 self.statuslist = []
1769 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
1770 if status == 'update':
1771 statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgrade.png"))
1772 self.statuslist.append(( _("Package list update"), '', _("Trying to download a new packetlist. Please wait..." ),'',statuspng, divpng ))
1773 self['list'].setList(self.statuslist)
1774 elif status == 'error':
1775 statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
1776 self.statuslist.append(( _("Error"), '', _("There was an error downloading the packetlist. Please try again." ),'',statuspng, divpng ))
1777 self['list'].setList(self.statuslist)
1779 def rebuildList(self):
1780 self.setStatus('update')
1782 self.vc = valid_cache(self.cache_file, self.cache_ttl)
1783 if self.cache_ttl > 0 and self.vc != 0:
1785 self.buildPacketList()
1788 if self.cache_ttl == 0 or self.inv_cache == 1 or self.vc == 0:
1790 self.ipkg.startCmd(IpkgComponent.CMD_UPDATE)
1792 def go(self, returnValue = None):
1793 cur = self["list"].getCurrent()
1798 if status == 'installed':
1799 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": package }))
1800 if len(self.cmdList):
1801 self.session.openWithCallback(self.runRemove, MessageBox, _("Do you want to remove the package:\n") + package + "\n" + self.oktext)
1802 elif status == 'upgradeable':
1803 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package }))
1804 if len(self.cmdList):
1805 self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to upgrade the package:\n") + package + "\n" + self.oktext)
1806 elif status == "installable":
1807 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package }))
1808 if len(self.cmdList):
1809 self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to install the package:\n") + package + "\n" + self.oktext)
1811 def runRemove(self, result):
1813 self.session.openWithCallback(self.runRemoveFinished, Ipkg, cmdList = self.cmdList)
1815 def runRemoveFinished(self):
1816 self.session.openWithCallback(self.RemoveReboot, MessageBox, _("Remove finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
1818 def RemoveReboot(self, result):
1822 cur = self["list"].getCurrent()
1824 item = self['list'].getIndex()
1825 self.list[item] = self.buildEntryComponent(cur[0], cur[1], cur[2], 'installable')
1826 self.cachelist[item] = [cur[0], cur[1], cur[2], 'installable']
1827 self['list'].setList(self.list)
1828 write_cache(self.cache_file, self.cachelist)
1829 self.reloadPluginlist()
1833 def runUpgrade(self, result):
1835 self.session.openWithCallback(self.runUpgradeFinished, Ipkg, cmdList = self.cmdList)
1837 def runUpgradeFinished(self):
1838 self.session.openWithCallback(self.UpgradeReboot, MessageBox, _("Upgrade finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
1840 def UpgradeReboot(self, result):
1844 cur = self["list"].getCurrent()
1846 item = self['list'].getIndex()
1847 self.list[item] = self.buildEntryComponent(cur[0], cur[1], cur[2], 'installed')
1848 self.cachelist[item] = [cur[0], cur[1], cur[2], 'installed']
1849 self['list'].setList(self.list)
1850 write_cache(self.cache_file, self.cachelist)
1851 self.reloadPluginlist()
1855 def ipkgCallback(self, event, param):
1856 if event == IpkgComponent.EVENT_ERROR:
1857 self.list_updating = False
1858 self.setStatus('error')
1859 elif event == IpkgComponent.EVENT_DONE:
1860 if self.list_updating:
1861 self.list_updating = False
1862 if not self.Console:
1863 self.Console = Console()
1865 self.Console.ePopen(cmd, self.IpkgList_Finished)
1866 #print event, "-", param
1869 def IpkgList_Finished(self, result, retval, extra_args = None):
1871 self.packetlist = []
1873 for x in result.splitlines():
1874 tokens = x.split(' - ')
1875 name = tokens[0].strip()
1876 if not any(name.endswith(x) for x in self.unwanted_extensions):
1878 version = l > 1 and tokens[1].strip() or ""
1879 descr = l > 2 and tokens[2].strip() or ""
1880 if name == last_name:
1883 self.packetlist.append([name, version, descr])
1885 if not self.Console:
1886 self.Console = Console()
1887 cmd = "opkg list_installed"
1888 self.Console.ePopen(cmd, self.IpkgListInstalled_Finished)
1890 def IpkgListInstalled_Finished(self, result, retval, extra_args = None):
1892 self.installed_packetlist = {}
1893 for x in result.splitlines():
1894 tokens = x.split(' - ')
1895 name = tokens[0].strip()
1896 if not any(name.endswith(x) for x in self.unwanted_extensions):
1898 version = l > 1 and tokens[1].strip() or ""
1899 self.installed_packetlist[name] = version
1900 if not self.Console:
1901 self.Console = Console()
1902 cmd = "opkg list-upgradable"
1903 self.Console.ePopen(cmd, self.OpkgListUpgradeable_Finished)
1905 def OpkgListUpgradeable_Finished(self, result, retval, extra_args = None):
1907 self.upgradeable_packages = {}
1908 for x in result.splitlines():
1909 tokens = x.split(' - ')
1910 name = tokens[0].strip()
1911 if not any(name.endswith(x) for x in self.unwanted_extensions):
1913 version = l > 2 and tokens[2].strip() or ""
1914 self.upgradeable_packages[name] = version
1915 self.buildPacketList()
1917 def buildEntryComponent(self, name, version, description, state):
1918 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
1919 if state == 'installed':
1920 installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installed.png"))
1921 return((name, version, _(description), state, installedpng, divpng))
1922 elif state == 'upgradeable':
1923 upgradeablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgradeable.png"))
1924 return((name, version, _(description), state, upgradeablepng, divpng))
1926 installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installable.png"))
1927 return((name, version, _(description), state, installablepng, divpng))
1929 def buildPacketList(self):
1932 if self.cache_ttl > 0 and self.vc != 0:
1933 print 'Loading packagelist cache from ',self.cache_file
1935 self.cachelist = load_cache(self.cache_file)
1936 if len(self.cachelist) > 0:
1937 for x in self.cachelist:
1938 self.list.append(self.buildEntryComponent(x[0], x[1], x[2], x[3]))
1939 self['list'].setList(self.list)
1943 if self.cache_ttl == 0 or self.inv_cache == 1 or self.vc == 0:
1944 print 'rebuilding fresh package list'
1945 for x in self.packetlist:
1947 if self.installed_packetlist.has_key(x[0]):
1948 if self.upgradeable_packages.has_key(x[0]):
1949 status = "upgradeable"
1951 status = "installed"
1953 status = "installable"
1954 self.list.append(self.buildEntryComponent(x[0], x[1], x[2], status))
1955 self.cachelist.append([x[0], x[1], x[2], status])
1956 write_cache(self.cache_file, self.cachelist)
1957 self['list'].setList(self.list)
1959 def reloadPluginlist(self):
1960 plugins.readPluginList(resolveFilename(SCOPE_PLUGINS))
1963 class IpkgInstaller(Screen):
1965 <screen name="IpkgInstaller" position="center,center" size="550,450" title="Install extensions" >
1966 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1967 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1968 <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" />
1969 <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" />
1970 <widget name="list" position="5,50" size="540,360" />
1971 <ePixmap pixmap="skin_default/div-h.png" position="0,410" zPosition="10" size="560,2" transparent="1" alphatest="on" />
1972 <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" />
1975 def __init__(self, session, list):
1976 Screen.__init__(self, session)
1978 self.list = SelectionList()
1979 self["list"] = self.list
1980 for listindex in range(len(list)):
1981 self.list.addSelection(list[listindex], list[listindex], listindex, True)
1983 self["key_red"] = StaticText(_("Close"))
1984 self["key_green"] = StaticText(_("Install"))
1985 self["introduction"] = StaticText(_("Press OK to toggle the selection."))
1987 self["actions"] = ActionMap(["OkCancelActions", "ColorActions"],
1989 "ok": self.list.toggleSelection,
1990 "cancel": self.close,
1992 "green": self.install
1996 list = self.list.getSelectionsList()
1999 cmdList.append((IpkgComponent.CMD_INSTALL, { "package": item[1] }))
2000 self.session.open(Ipkg, cmdList = cmdList)
2003 def filescan_open(list, session, **kwargs):
2004 filelist = [x.path for x in list]
2005 session.open(IpkgInstaller, filelist) # list
2007 def filescan(**kwargs):
2008 from Components.Scanner import Scanner, ScanPath
2010 Scanner(mimetypes = ["application/x-debian-package"],
2013 ScanPath(path = "ipk", with_subdirs = True),
2014 ScanPath(path = "", with_subdirs = False),
2017 description = _("Install extensions."),
2018 openfnc = filescan_open, )
2022 def UpgradeMain(session, **kwargs):
2023 session.open(UpdatePluginMenu)
2025 def startSetup(menuid):
2026 if menuid != "setup":
2028 return [(_("Software management"), UpgradeMain, "software_manager", 50)]
2031 def Plugins(path, **kwargs):
2035 PluginDescriptor(name=_("Software management"), description=_("Manage your receiver's software"), where = PluginDescriptor.WHERE_MENU, fnc=startSetup),
2036 PluginDescriptor(name=_("Ipkg"), where = PluginDescriptor.WHERE_FILESCAN, fnc = filescan)
2038 if config.usage.setup_level.index >= 2: # expert+
2039 list.append(PluginDescriptor(name=_("Software management"), description=_("Manage your receiver's software"), where = PluginDescriptor.WHERE_EXTENSIONSMENU, fnc=UpgradeMain))