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/ipkg/'
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')
1711 self.opkgAvail = fileExists('/usr/bin/opkg')
1713 self.ipkg = IpkgComponent()
1714 self.ipkg.addCallback(self.ipkgCallback)
1715 self.onShown.append(self.setWindowTitle)
1716 self.onLayoutFinish.append(self.rebuildList)
1718 rcinput = eRCInput.getInstance()
1719 rcinput.setKeyboardMode(rcinput.kmAscii)
1721 def keyNumberGlobal(self, val):
1722 key = self.getKey(val)
1724 keyvalue = key.encode("utf-8")
1725 if len(keyvalue) == 1:
1726 self.setNextIdx(keyvalue[0])
1728 def keyGotAscii(self):
1729 keyvalue = unichr(getPrevAsciiCode()).encode("utf-8")
1730 if len(keyvalue) == 1:
1731 self.setNextIdx(keyvalue[0])
1733 def setNextIdx(self,char):
1734 if char in ("0", "1", "a"):
1735 self["list"].setIndex(0)
1737 idx = self.getNextIdx(char)
1738 if idx and idx <= self["list"].count:
1739 self["list"].setIndex(idx)
1741 def getNextIdx(self,char):
1743 for i in self["list"].list:
1750 if self.Console is not None:
1751 if len(self.Console.appContainers):
1752 for name in self.Console.appContainers.keys():
1753 self.Console.kill(name)
1754 rcinput = eRCInput.getInstance()
1755 rcinput.setKeyboardMode(rcinput.kmNone)
1759 if (os_path.exists(self.cache_file) == True):
1760 remove(self.cache_file)
1761 self.list_updating = True
1764 def setWindowTitle(self):
1765 self.setTitle(_("Packet manager"))
1767 def setStatus(self,status = None):
1769 self.statuslist = []
1770 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
1771 if status == 'update':
1772 statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgrade.png"))
1773 self.statuslist.append(( _("Package list update"), '', _("Trying to download a new packetlist. Please wait..." ),'',statuspng, divpng ))
1774 self['list'].setList(self.statuslist)
1775 elif status == 'error':
1776 statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
1777 self.statuslist.append(( _("Error"), '', _("There was an error downloading the packetlist. Please try again." ),'',statuspng, divpng ))
1778 self['list'].setList(self.statuslist)
1780 def rebuildList(self):
1781 self.setStatus('update')
1783 self.vc = valid_cache(self.cache_file, self.cache_ttl)
1784 if self.cache_ttl > 0 and self.vc != 0:
1786 self.buildPacketList()
1789 if self.cache_ttl == 0 or self.inv_cache == 1 or self.vc == 0:
1791 self.ipkg.startCmd(IpkgComponent.CMD_UPDATE)
1793 def go(self, returnValue = None):
1794 cur = self["list"].getCurrent()
1799 if status == 'installed':
1800 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": package }))
1801 if len(self.cmdList):
1802 self.session.openWithCallback(self.runRemove, MessageBox, _("Do you want to remove the package:\n") + package + "\n" + self.oktext)
1803 elif status == 'upgradeable':
1804 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package }))
1805 if len(self.cmdList):
1806 self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to upgrade the package:\n") + package + "\n" + self.oktext)
1807 elif status == "installable":
1808 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package }))
1809 if len(self.cmdList):
1810 self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to install the package:\n") + package + "\n" + self.oktext)
1812 def runRemove(self, result):
1814 self.session.openWithCallback(self.runRemoveFinished, Ipkg, cmdList = self.cmdList)
1816 def runRemoveFinished(self):
1817 self.session.openWithCallback(self.RemoveReboot, MessageBox, _("Remove finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
1819 def RemoveReboot(self, result):
1823 cur = self["list"].getCurrent()
1825 item = self['list'].getIndex()
1826 self.list[item] = self.buildEntryComponent(cur[0], cur[1], cur[2], 'installable')
1827 self.cachelist[item] = [cur[0], cur[1], cur[2], 'installable']
1828 self['list'].setList(self.list)
1829 write_cache(self.cache_file, self.cachelist)
1830 self.reloadPluginlist()
1834 def runUpgrade(self, result):
1836 self.session.openWithCallback(self.runUpgradeFinished, Ipkg, cmdList = self.cmdList)
1838 def runUpgradeFinished(self):
1839 self.session.openWithCallback(self.UpgradeReboot, MessageBox, _("Upgrade finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
1841 def UpgradeReboot(self, result):
1845 cur = self["list"].getCurrent()
1847 item = self['list'].getIndex()
1848 self.list[item] = self.buildEntryComponent(cur[0], cur[1], cur[2], 'installed')
1849 self.cachelist[item] = [cur[0], cur[1], cur[2], 'installed']
1850 self['list'].setList(self.list)
1851 write_cache(self.cache_file, self.cachelist)
1852 self.reloadPluginlist()
1856 def ipkgCallback(self, event, param):
1857 if event == IpkgComponent.EVENT_ERROR:
1858 self.list_updating = False
1859 self.setStatus('error')
1860 elif event == IpkgComponent.EVENT_DONE:
1861 if self.list_updating:
1862 self.list_updating = False
1863 if not self.Console:
1864 self.Console = Console()
1866 self.Console.ePopen(cmd, self.IpkgList_Finished)
1867 #print event, "-", param
1870 def IpkgList_Finished(self, result, retval, extra_args = None):
1872 self.packetlist = []
1874 for x in result.splitlines():
1875 tokens = x.split(' - ')
1876 name = tokens[0].strip()
1877 if not any(name.endswith(x) for x in self.unwanted_extensions):
1879 version = l > 1 and tokens[1].strip() or ""
1880 descr = l > 2 and tokens[2].strip() or ""
1881 if name == last_name:
1884 self.packetlist.append([name, version, descr])
1886 if not self.Console:
1887 self.Console = Console()
1888 cmd = "ipkg list_installed"
1889 self.Console.ePopen(cmd, self.IpkgListInstalled_Finished)
1891 def IpkgListInstalled_Finished(self, result, retval, extra_args = None):
1893 self.installed_packetlist = {}
1894 for x in result.splitlines():
1895 tokens = x.split(' - ')
1896 name = tokens[0].strip()
1897 if not any(name.endswith(x) for x in self.unwanted_extensions):
1899 version = l > 1 and tokens[1].strip() or ""
1900 self.installed_packetlist[name] = version
1902 if not self.Console:
1903 self.Console = Console()
1904 cmd = "opkg list-upgradable"
1905 self.Console.ePopen(cmd, self.OpkgListUpgradeable_Finished)
1907 self.buildPacketList()
1909 def OpkgListUpgradeable_Finished(self, result, retval, extra_args = None):
1911 self.upgradeable_packages = {}
1912 for x in result.splitlines():
1913 tokens = x.split(' - ')
1914 name = tokens[0].strip()
1915 if not any(name.endswith(x) for x in self.unwanted_extensions):
1917 version = l > 2 and tokens[2].strip() or ""
1918 self.upgradeable_packages[name] = version
1919 self.buildPacketList()
1921 def buildEntryComponent(self, name, version, description, state):
1922 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
1923 if state == 'installed':
1924 installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installed.png"))
1925 return((name, version, _(description), state, installedpng, divpng))
1926 elif state == 'upgradeable':
1927 upgradeablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgradeable.png"))
1928 return((name, version, _(description), state, upgradeablepng, divpng))
1930 installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installable.png"))
1931 return((name, version, _(description), state, installablepng, divpng))
1933 def buildPacketList(self):
1936 if self.cache_ttl > 0 and self.vc != 0:
1937 print 'Loading packagelist cache from ',self.cache_file
1939 self.cachelist = load_cache(self.cache_file)
1940 if len(self.cachelist) > 0:
1941 for x in self.cachelist:
1942 self.list.append(self.buildEntryComponent(x[0], x[1], x[2], x[3]))
1943 self['list'].setList(self.list)
1947 if self.cache_ttl == 0 or self.inv_cache == 1 or self.vc == 0:
1948 print 'rebuilding fresh package list'
1949 for x in self.packetlist:
1951 if self.installed_packetlist.has_key(x[0]):
1953 if self.upgradeable_packages.has_key(x[0]):
1954 status = "upgradeable"
1956 status = "installed"
1958 if self.installed_packetlist[x[0]] == x[1]:
1959 status = "installed"
1961 status = "upgradeable"
1963 status = "installable"
1964 self.list.append(self.buildEntryComponent(x[0], x[1], x[2], status))
1965 self.cachelist.append([x[0], x[1], x[2], status])
1966 write_cache(self.cache_file, self.cachelist)
1967 self['list'].setList(self.list)
1969 def reloadPluginlist(self):
1970 plugins.readPluginList(resolveFilename(SCOPE_PLUGINS))
1973 class IpkgInstaller(Screen):
1975 <screen name="IpkgInstaller" position="center,center" size="550,450" title="Install extensions" >
1976 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1977 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1978 <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" />
1979 <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" />
1980 <widget name="list" position="5,50" size="540,360" />
1981 <ePixmap pixmap="skin_default/div-h.png" position="0,410" zPosition="10" size="560,2" transparent="1" alphatest="on" />
1982 <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" />
1985 def __init__(self, session, list):
1986 Screen.__init__(self, session)
1988 self.list = SelectionList()
1989 self["list"] = self.list
1990 for listindex in range(len(list)):
1991 self.list.addSelection(list[listindex], list[listindex], listindex, True)
1993 self["key_red"] = StaticText(_("Close"))
1994 self["key_green"] = StaticText(_("Install"))
1995 self["introduction"] = StaticText(_("Press OK to toggle the selection."))
1997 self["actions"] = ActionMap(["OkCancelActions", "ColorActions"],
1999 "ok": self.list.toggleSelection,
2000 "cancel": self.close,
2002 "green": self.install
2006 list = self.list.getSelectionsList()
2009 cmdList.append((IpkgComponent.CMD_INSTALL, { "package": item[1] }))
2010 self.session.open(Ipkg, cmdList = cmdList)
2013 def filescan_open(list, session, **kwargs):
2014 filelist = [x.path for x in list]
2015 session.open(IpkgInstaller, filelist) # list
2017 def filescan(**kwargs):
2018 from Components.Scanner import Scanner, ScanPath
2020 Scanner(mimetypes = ["application/x-debian-package"],
2023 ScanPath(path = "ipk", with_subdirs = True),
2024 ScanPath(path = "", with_subdirs = False),
2027 description = _("Install extensions."),
2028 openfnc = filescan_open, )
2032 def UpgradeMain(session, **kwargs):
2033 session.open(UpdatePluginMenu)
2035 def startSetup(menuid):
2036 if menuid != "setup":
2038 return [(_("Software management"), UpgradeMain, "software_manager", 50)]
2041 def Plugins(path, **kwargs):
2045 PluginDescriptor(name=_("Software management"), description=_("Manage your receiver's software"), where = PluginDescriptor.WHERE_MENU, fnc=startSetup),
2046 PluginDescriptor(name=_("Ipkg"), where = PluginDescriptor.WHERE_FILESCAN, fnc = filescan)
2048 if config.usage.setup_level.index >= 2: # expert+
2049 list.append(PluginDescriptor(name=_("Software management"), description=_("Manage your receiver's software"), where = PluginDescriptor.WHERE_EXTENSIONSMENU, fnc=UpgradeMain))