1 from Plugins.Plugin import PluginDescriptor
2 from Screens.Console import Console
3 from Screens.ChoiceBox import ChoiceBox
4 from Screens.MessageBox import MessageBox
5 from Screens.Screen import Screen
6 from Screens.Ipkg import Ipkg
7 from Components.ActionMap import ActionMap, NumberActionMap
8 from Components.Input import Input
9 from Components.Ipkg import IpkgComponent
10 from Components.Sources.StaticText import StaticText
11 from Components.ScrollLabel import ScrollLabel
12 from Components.Pixmap import Pixmap
13 from Components.MenuList import MenuList
14 from Components.Sources.List import List
15 from Components.Slider import Slider
16 from Components.Harddisk import harddiskmanager
17 from Components.config import config,getConfigListEntry, ConfigSubsection, ConfigText, ConfigLocations, ConfigYesNo, ConfigSelection
18 from Components.ConfigList import ConfigListScreen
19 from Components.Console import Console
20 from Components.MultiContent import MultiContentEntryText, MultiContentEntryPixmapAlphaTest
21 from Components.SelectionList import SelectionList
22 from Components.PluginComponent import plugins
23 from Components.About import about
24 from Components.DreamInfoHandler import DreamInfoHandler
25 from Components.Language import language
26 from Components.AVSwitch import AVSwitch
27 from Components.Network import iNetwork
28 from Tools.Directories import pathExists, fileExists, resolveFilename, SCOPE_PLUGINS, SCOPE_CURRENT_PLUGIN, SCOPE_CURRENT_SKIN, SCOPE_METADIR
29 from Tools.LoadPixmap import LoadPixmap
30 from Tools.NumericalTextInput import NumericalTextInput
31 from enigma import eTimer, quitMainloop, RT_HALIGN_LEFT, RT_VALIGN_CENTER, eListboxPythonMultiContent, eListbox, gFont, getDesktop, ePicLoad, eRCInput, getPrevAsciiCode
32 from cPickle import dump, load
33 from os import path as os_path, system as os_system, unlink, stat, mkdir, popen, makedirs, listdir, access, rename, remove, W_OK, R_OK, F_OK
34 from time import time, gmtime, strftime, localtime
35 from stat import ST_MTIME
36 from datetime import date
37 from twisted.web import client
38 from twisted.internet import reactor
40 from ImageWizard import ImageWizard
41 from BackupRestore import BackupSelection, RestoreMenu, BackupScreen, RestoreScreen, getBackupPath, getBackupFilename
42 from SoftwareTools import iSoftwareTools
44 config.plugins.configurationbackup = ConfigSubsection()
45 config.plugins.configurationbackup.backuplocation = ConfigText(default = '/media/hdd/', visible_width = 50, fixed_size = False)
46 config.plugins.configurationbackup.backupdirs = ConfigLocations(default=['/etc/enigma2/', '/etc/network/interfaces', '/etc/wpa_supplicant.conf', '/etc/resolv.conf', '/etc/default_gw', '/etc/hostname'])
48 config.plugins.SoftwareManager = ConfigSubsection()
49 config.plugins.SoftwareManager.overwriteConfigFiles = ConfigSelection(
51 ("Y", _("Yes, always")),
52 ("N", _("No, never")),
53 ("ask", _("Always ask"))
56 def write_cache(cache_file, cache_data):
58 if not os_path.isdir( os_path.dirname(cache_file) ):
60 mkdir( os_path.dirname(cache_file) )
62 print os_path.dirname(cache_file), 'is a file'
63 fd = open(cache_file, 'w')
64 dump(cache_data, fd, -1)
67 def valid_cache(cache_file, cache_ttl):
68 #See if the cache file exists and is still living
70 mtime = stat(cache_file)[ST_MTIME]
74 if (curr_time - mtime) > cache_ttl:
79 def load_cache(cache_file):
87 class UpdatePluginMenu(Screen):
89 <screen name="UpdatePluginMenu" position="center,center" size="610,410" title="Software management" >
90 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
91 <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
92 <ePixmap pixmap="skin_default/border_menu_350.png" position="5,50" zPosition="1" size="350,300" transparent="1" alphatest="on" />
93 <widget source="menu" render="Listbox" position="15,60" size="330,290" scrollbarMode="showOnDemand">
94 <convert type="TemplatedMultiContent">
96 MultiContentEntryText(pos = (2, 2), size = (330, 24), flags = RT_HALIGN_LEFT, text = 1), # index 0 is the MenuText,
98 "fonts": [gFont("Regular", 22)],
103 <widget source="menu" render="Listbox" position="360,50" size="240,300" scrollbarMode="showNever" selectionDisabled="1">
104 <convert type="TemplatedMultiContent">
106 MultiContentEntryText(pos = (2, 2), size = (240, 300), flags = RT_HALIGN_CENTER|RT_VALIGN_CENTER|RT_WRAP, text = 2), # index 2 is the Description,
108 "fonts": [gFont("Regular", 22)],
113 <widget source="status" render="Label" position="5,360" zPosition="10" size="600,50" halign="center" valign="center" font="Regular;22" transparent="1" shadowColor="black" shadowOffset="-1,-1" />
116 def __init__(self, session, args = 0):
117 Screen.__init__(self, session)
118 self.skin_path = plugin_path
121 self.oktext = _("\nPress OK on your remote control to continue.")
122 self.menutext = _("Press MENU on your remote control for additional options.")
123 self.infotext = _("Press INFO on your remote control for additional information.")
125 self.backupdirs = ' '.join( config.plugins.configurationbackup.backupdirs.value )
127 print "building menu entries"
128 self.list.append(("install-extensions", _("Manage extensions"), _("\nManage extensions or plugins for your Dreambox" ) + self.oktext, None))
129 self.list.append(("software-update", _("Software update"), _("\nOnline update of your Dreambox software." ) + self.oktext, None))
130 self.list.append(("software-restore", _("Software restore"), _("\nRestore your Dreambox with a new firmware." ) + self.oktext, None))
131 self.list.append(("system-backup", _("Backup system settings"), _("\nBackup your Dreambox settings." ) + self.oktext + "\n\n" + self.infotext, None))
132 self.list.append(("system-restore",_("Restore system settings"), _("\nRestore your Dreambox settings." ) + self.oktext, None))
133 self.list.append(("ipkg-install", _("Install local extension"), _("\nScan for local extensions and install them." ) + self.oktext, None))
134 for p in plugins.getPlugins(PluginDescriptor.WHERE_SOFTWAREMANAGER):
135 if p.__call__.has_key("SoftwareSupported"):
136 callFnc = p.__call__["SoftwareSupported"](None)
137 if callFnc is not None:
138 if p.__call__.has_key("menuEntryName"):
139 menuEntryName = p.__call__["menuEntryName"](None)
141 menuEntryName = _('Extended Software')
142 if p.__call__.has_key("menuEntryDescription"):
143 menuEntryDescription = p.__call__["menuEntryDescription"](None)
145 menuEntryDescription = _('Extended Software Plugin')
146 self.list.append(('default-plugin', menuEntryName, menuEntryDescription + self.oktext, callFnc))
147 if config.usage.setup_level.index >= 2: # expert+
148 self.list.append(("advanced", _("Advanced Options"), _("\nAdvanced options and settings." ) + self.oktext, None))
150 self.list.append(("advancedrestore", _("Advanced restore"), _("\nRestore your backups by date." ) + self.oktext, None))
151 self.list.append(("backuplocation", _("Choose backup location"), _("\nSelect your backup device.\nCurrent device: " ) + config.plugins.configurationbackup.backuplocation.value + self.oktext, None))
152 self.list.append(("backupfiles", _("Choose backup files"), _("Select files for backup.") + self.oktext + "\n\n" + self.infotext, None))
153 if config.usage.setup_level.index >= 2: # expert+
154 self.list.append(("ipkg-manager", _("Packet management"), _("\nView, install and remove available or installed packages." ) + self.oktext, None))
155 self.list.append(("ipkg-source",_("Choose upgrade source"), _("\nEdit the upgrade source address." ) + self.oktext, None))
156 for p in plugins.getPlugins(PluginDescriptor.WHERE_SOFTWAREMANAGER):
157 if p.__call__.has_key("AdvancedSoftwareSupported"):
158 callFnc = p.__call__["AdvancedSoftwareSupported"](None)
159 if callFnc is not None:
160 if p.__call__.has_key("menuEntryName"):
161 menuEntryName = p.__call__["menuEntryName"](None)
163 menuEntryName = _('Advanced Software')
164 if p.__call__.has_key("menuEntryDescription"):
165 menuEntryDescription = p.__call__["menuEntryDescription"](None)
167 menuEntryDescription = _('Advanced Software Plugin')
168 self.list.append(('advanced-plugin', menuEntryName, menuEntryDescription + self.oktext, callFnc))
170 self["menu"] = List(self.list)
171 self["key_red"] = StaticText(_("Close"))
172 self["status"] = StaticText(self.menutext)
174 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions", "InfobarEPGActions", "MenuActions"],
179 "menu": self.handleMenu,
180 "showEventInfo": self.handleInfo,
182 self.onLayoutFinish.append(self.layoutFinished)
183 self.backuppath = getBackupPath()
184 self.backupfile = getBackupFilename()
185 self.fullbackupfilename = self.backuppath + "/" + self.backupfile
186 self.onShown.append(self.setWindowTitle)
188 def layoutFinished(self):
190 self["menu"].index = idx
192 def setWindowTitle(self):
193 self.setTitle(_("Software management"))
196 iNetwork.stopPingConsole()
197 iSoftwareTools.cleanupSoftwareTools()
199 def getUpdateInfos(self):
201 if iSoftwareTools.NetworkConnectionAvailable == True:
202 if iSoftwareTools.list_updating is False:
203 if iSoftwareTools.available_updates is not 0:
204 self.text = _("There are at least ") + str(iSoftwareTools.available_updates) + _(" updates available.")
206 self.text = "" #_("There are no updates available.")
208 if iSoftwareTools.available_updates is not 0:
209 self.text = _("There are at least ") + str(iSoftwareTools.available_updates) + _(" updates available.")
211 self.text = "" #_("There are no updates available.")
212 self.text += "\n" + _("A search for available updates is currently in progress.")
214 self.text = _("No network connection available.")
215 self["status"].setText(self.text)
217 def handleMenu(self):
218 self.session.open(SoftwareManagerSetup)
220 def handleInfo(self):
221 current = self["menu"].getCurrent()
223 currentEntry = current[0]
224 if currentEntry in ("system-backup","backupfiles"):
225 self.session.open(SoftwareManagerInfo, mode = "backupinfo")
228 current = self["menu"].getCurrent()
230 currentEntry = current[0]
232 if (currentEntry == "software-update"):
233 self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to update your Dreambox?")+"\n"+_("\nAfter pressing OK, please wait!"))
234 elif (currentEntry == "software-restore"):
235 self.session.open(ImageWizard)
236 elif (currentEntry == "install-extensions"):
237 self.session.open(PluginManager, self.skin_path)
238 elif (currentEntry == "system-backup"):
239 self.session.openWithCallback(self.backupDone,BackupScreen, runBackup = True)
240 elif (currentEntry == "system-restore"):
241 if os_path.exists(self.fullbackupfilename):
242 self.session.openWithCallback(self.startRestore, MessageBox, _("Are you sure you want to restore your Enigma2 backup?\nEnigma2 will restart after the restore"))
244 self.session.open(MessageBox, _("Sorry no backups found!"), MessageBox.TYPE_INFO, timeout = 10)
245 elif (currentEntry == "ipkg-install"):
247 from Plugins.Extensions.MediaScanner.plugin import main
250 self.session.open(MessageBox, _("Sorry MediaScanner is not installed!"), MessageBox.TYPE_INFO, timeout = 10)
251 elif (currentEntry == "default-plugin"):
252 self.extended = current[3]
253 self.extended(self.session, None)
254 elif (currentEntry == "advanced"):
255 self.session.open(UpdatePluginMenu, 1)
257 if (currentEntry == "ipkg-manager"):
258 self.session.open(PacketManager, self.skin_path)
259 elif (currentEntry == "backuplocation"):
260 parts = [ (r.description, r.mountpoint, self.session) for r in harddiskmanager.getMountedPartitions(onlyhotplug = False)]
262 if not access(x[1], F_OK|R_OK|W_OK) or x[1] == '/':
265 if x[1].startswith('/autofs/'):
268 self.session.openWithCallback(self.backuplocation_choosen, ChoiceBox, title = _("Please select medium to use as backup location"), list = parts)
269 elif (currentEntry == "backupfiles"):
270 self.session.openWithCallback(self.backupfiles_choosen,BackupSelection)
271 elif (currentEntry == "advancedrestore"):
272 self.session.open(RestoreMenu, self.skin_path)
273 elif (currentEntry == "ipkg-source"):
274 self.session.open(IPKGMenu, self.skin_path)
275 elif (currentEntry == "advanced-plugin"):
276 self.extended = current[3]
277 self.extended(self.session, None)
279 def backupfiles_choosen(self, ret):
280 self.backupdirs = ' '.join( config.plugins.configurationbackup.backupdirs.value )
282 def backuplocation_choosen(self, option):
283 if option is not None:
284 config.plugins.configurationbackup.backuplocation.value = str(option[1])
285 config.plugins.configurationbackup.backuplocation.save()
286 config.plugins.configurationbackup.save()
288 self.createBackupfolders()
290 def runUpgrade(self, result):
292 self.session.open(UpdatePlugin, self.skin_path)
294 def createBackupfolders(self):
295 print "Creating backup folder if not already there..."
296 self.backuppath = getBackupPath()
298 if (os_path.exists(self.backuppath) == False):
299 makedirs(self.backuppath)
301 self.session.open(MessageBox, _("Sorry, your backup destination is not writeable.\n\nPlease choose another one."), MessageBox.TYPE_INFO, timeout = 10)
303 def backupDone(self,retval = None):
305 self.session.open(MessageBox, _("Backup done."), MessageBox.TYPE_INFO, timeout = 10)
307 self.session.open(MessageBox, _("Backup failed."), MessageBox.TYPE_INFO, timeout = 10)
309 def startRestore(self, ret = False):
312 self.session.open(RestoreScreen, runRestore = True)
314 class SoftwareManagerSetup(Screen, ConfigListScreen):
317 <screen name="SoftwareManagerSetup" position="center,center" size="560,440" title="SoftwareManager setup">
318 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
319 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
320 <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" alphatest="on" />
321 <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" alphatest="on" />
322 <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
323 <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
324 <widget source="key_yellow" render="Label" position="280,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#a08500" transparent="1" />
325 <widget source="key_blue" render="Label" position="420,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#18188b" transparent="1" />
326 <widget name="config" position="5,50" size="550,350" scrollbarMode="showOnDemand" />
327 <ePixmap pixmap="skin_default/div-h.png" position="0,400" zPosition="1" size="560,2" />
328 <widget source="introduction" render="Label" position="5,410" size="550,30" zPosition="10" font="Regular;21" halign="center" valign="center" backgroundColor="#25062748" transparent="1" />
331 def __init__(self, session, skin_path = None):
332 Screen.__init__(self, session)
333 self.session = session
334 self.skin_path = skin_path
335 if self.skin_path == None:
336 self.skin_path = resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager")
338 self.onChangedEntry = [ ]
339 self.setup_title = _("Software manager setup")
340 self.overwriteConfigfilesEntry = None
343 ConfigListScreen.__init__(self, self.list, session = session, on_change = self.changedEntry)
345 self["actions"] = ActionMap(["SetupActions"],
347 "cancel": self.keyCancel,
351 self["key_red"] = StaticText(_("Cancel"))
352 self["key_green"] = StaticText(_("OK"))
353 self["key_yellow"] = StaticText()
354 self["key_blue"] = StaticText()
355 self["introduction"] = StaticText()
358 self.onLayoutFinish.append(self.layoutFinished)
360 def layoutFinished(self):
361 self.setTitle(self.setup_title)
363 def createSetup(self):
365 self.overwriteConfigfilesEntry = getConfigListEntry(_("Overwrite configuration files ?"), config.plugins.SoftwareManager.overwriteConfigFiles)
366 self.list.append(self.overwriteConfigfilesEntry)
367 self["config"].list = self.list
368 self["config"].l.setSeperation(400)
369 self["config"].l.setList(self.list)
370 if not self.selectionChanged in self["config"].onSelectionChanged:
371 self["config"].onSelectionChanged.append(self.selectionChanged)
372 self.selectionChanged()
374 def selectionChanged(self):
375 if self["config"].getCurrent() == self.overwriteConfigfilesEntry:
376 self["introduction"].setText(_("Overwrite configuration files during software upgrade?"))
378 self["introduction"].setText("")
384 ConfigListScreen.keyLeft(self)
387 ConfigListScreen.keyRight(self)
389 def confirm(self, confirmed):
391 print "not confirmed"
397 self.session.openWithCallback(self.confirm, MessageBox, _("Use this settings?"), MessageBox.TYPE_YESNO, timeout = 20, default = True)
399 def cancelConfirm(self, result):
402 for x in self["config"].list:
407 if self["config"].isChanged():
408 self.session.openWithCallback(self.cancelConfirm, MessageBox, _("Really close without saving settings?"), MessageBox.TYPE_YESNO, timeout = 20, default = True)
413 def changedEntry(self):
414 for x in self.onChangedEntry:
416 self.selectionChanged()
418 def getCurrentEntry(self):
419 return self["config"].getCurrent()[0]
421 def getCurrentValue(self):
422 return str(self["config"].getCurrent()[1].value)
424 def createSummary(self):
425 from Screens.Setup import SetupSummary
429 class SoftwareManagerInfo(Screen):
431 <screen name="SoftwareManagerInfo" position="center,center" size="560,440" title="SoftwareManager information">
432 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
433 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
434 <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" alphatest="on" />
435 <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" alphatest="on" />
436 <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
437 <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
438 <widget source="key_yellow" render="Label" position="280,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#a08500" transparent="1" />
439 <widget source="key_blue" render="Label" position="420,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#18188b" transparent="1" />
440 <widget source="list" render="Listbox" position="5,50" size="550,340" scrollbarMode="showOnDemand" selectionDisabled="0">
441 <convert type="TemplatedMultiContent">
443 MultiContentEntryText(pos = (5, 0), size = (540, 26), font=0, flags = RT_HALIGN_LEFT | RT_HALIGN_CENTER, text = 0), # index 0 is the name
445 "fonts": [gFont("Regular", 24),gFont("Regular", 22)],
450 <ePixmap pixmap="skin_default/div-h.png" position="0,400" zPosition="1" size="560,2" />
451 <widget source="introduction" render="Label" position="5,410" size="550,30" zPosition="10" font="Regular;21" halign="center" valign="center" backgroundColor="#25062748" transparent="1" />
454 def __init__(self, session, skin_path = None, mode = None):
455 Screen.__init__(self, session)
456 self.session = session
458 self.skin_path = skin_path
459 if self.skin_path == None:
460 self.skin_path = resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager")
462 self["actions"] = ActionMap(["ShortcutActions", "WizardActions"],
469 self["list"] = List(self.list)
471 self["key_red"] = StaticText(_("Close"))
472 self["key_green"] = StaticText()
473 self["key_yellow"] = StaticText()
474 self["key_blue"] = StaticText()
475 self["introduction"] = StaticText()
477 self.onLayoutFinish.append(self.layoutFinished)
479 def layoutFinished(self):
480 self.setTitle(_("Softwaremanager information"))
481 if self.mode is not None:
485 if self.mode == "backupinfo":
487 backupfiles = config.plugins.configurationbackup.backupdirs.value
488 for entry in backupfiles:
490 self.list.append((entry,))
491 self['list'].setList(self.list)
494 class PluginManager(Screen, DreamInfoHandler):
497 <screen name="PluginManager" position="center,center" size="560,440" title="Extensions management" >
498 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
499 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
500 <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" alphatest="on" />
501 <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" alphatest="on" />
502 <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
503 <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
504 <widget source="key_yellow" render="Label" position="280,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#a08500" transparent="1" />
505 <widget source="key_blue" render="Label" position="420,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#18188b" transparent="1" />
506 <widget source="list" render="Listbox" position="5,50" size="550,360" scrollbarMode="showOnDemand">
507 <convert type="TemplatedMultiContent">
510 MultiContentEntryText(pos = (0, 1), size = (470, 24), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
511 MultiContentEntryText(pos = (0, 25), size = (470, 24), font=1, flags = RT_HALIGN_LEFT, text = 2), # index 2 is the description
512 MultiContentEntryPixmapAlphaTest(pos = (475, 0), size = (48, 48), png = 5), # index 5 is the status pixmap
513 MultiContentEntryPixmapAlphaTest(pos = (0, 49), size = (550, 2), png = 6), # index 6 is the div pixmap
516 MultiContentEntryText(pos = (30, 0), size = (500, 22), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
517 MultiContentEntryText(pos = (30, 22), size = (500, 16), font=2, flags = RT_HALIGN_LEFT, text = 1), # index 1 is the description
518 MultiContentEntryPixmapAlphaTest(pos = (0, 38), size = (550, 2), png = 3), # index 3 is the div pixmap
521 "fonts": [gFont("Regular", 22),gFont("Regular", 20),gFont("Regular", 16)],
526 <widget source="status" render="Label" position="5,410" zPosition="10" size="540,30" halign="center" valign="center" font="Regular;22" transparent="1" shadowColor="black" shadowOffset="-1,-1" />
529 def __init__(self, session, plugin_path = None, args = None):
530 Screen.__init__(self, session)
531 self.session = session
532 self.skin_path = plugin_path
533 if self.skin_path == None:
534 self.skin_path = resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager")
536 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions", "InfobarEPGActions", "HelpActions" ],
538 "ok": self.handleCurrent,
541 "green": self.handleCurrent,
542 "yellow": self.handleSelected,
543 "showEventInfo": self.handleSelected,
544 "displayHelp": self.handleHelp,
549 self.selectedFiles = []
550 self.categoryList = []
552 self["list"] = List(self.list)
553 self["key_red"] = StaticText(_("Close"))
554 self["key_green"] = StaticText("")
555 self["key_yellow"] = StaticText("")
556 self["key_blue"] = StaticText("")
557 self["status"] = StaticText("")
560 self.oktext = _("\nAfter pressing OK, please wait!")
561 if not self.selectionChanged in self["list"].onSelectionChanged:
562 self["list"].onSelectionChanged.append(self.selectionChanged)
565 self.currentSelectedTag = None
566 self.currentSelectedIndex = None
567 self.currentSelectedPackage = None
568 self.saved_currentSelectedPackage = None
570 self.onShown.append(self.setWindowTitle)
571 self.onLayoutFinish.append(self.getUpdateInfos)
573 def setWindowTitle(self):
574 self.setTitle(_("Extensions management"))
577 if self.currList == "packages":
578 self.currList = "category"
579 self.currentSelectedTag = None
580 self["list"].style = "category"
581 self['list'].setList(self.categoryList)
582 self["list"].setIndex(self.currentSelectedIndex)
583 self["list"].updateList(self.categoryList)
584 self.selectionChanged()
586 iSoftwareTools.cleanupSoftwareTools()
587 self.prepareInstall()
588 if len(self.cmdList):
589 self.session.openWithCallback(self.runExecute, PluginManagerInfo, self.skin_path, self.cmdList)
593 def handleHelp(self):
594 if self.currList != "status":
595 self.session.open(PluginManagerHelp, self.skin_path)
597 def setState(self,status = None):
599 self.currList = "status"
601 self["key_green"].setText("")
602 self["key_blue"].setText("")
603 self["key_yellow"].setText("")
604 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
605 if status == 'update':
606 statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgrade.png"))
607 self.statuslist.append(( _("Updating software catalog"), '', _("Searching for available updates. Please wait..." ),'', '', statuspng, divpng, None, '' ))
608 elif status == 'sync':
609 statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgrade.png"))
610 self.statuslist.append(( _("Package list update"), '', _("Searching for new installed or removed packages. Please wait..." ),'', '', statuspng, divpng, None, '' ))
611 elif status == 'error':
612 statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
613 self.statuslist.append(( _("Error"), '', _("There was an error downloading the packetlist. Please try again." ),'', '', statuspng, divpng, None, '' ))
614 self["list"].style = "default"
615 self['list'].setList(self.statuslist)
618 def getUpdateInfos(self):
619 self.setState('update')
620 iSoftwareTools.startSoftwareTools(self.getUpdateInfosCB)
622 def getUpdateInfosCB(self, retval = None):
623 if retval is not None:
625 if iSoftwareTools.available_updates is not 0:
626 self["status"].setText(_("There are at least ") + str(iSoftwareTools.available_updates) + _(" updates available."))
628 self["status"].setText(_("There are no updates available."))
630 elif retval is False:
631 self.setState('error')
632 if iSoftwareTools.NetworkConnectionAvailable:
633 self["status"].setText(_("Updatefeed not available."))
635 self["status"].setText(_("No network connection available."))
637 def rebuildList(self, retval = None):
638 if self.currentSelectedTag is None:
639 self.buildCategoryList()
641 self.buildPacketList(self.currentSelectedTag)
643 def selectionChanged(self):
644 current = self["list"].getCurrent()
645 self["status"].setText("")
647 if self.currList == "packages":
648 self["key_red"].setText(_("Back"))
649 if current[4] == 'installed':
650 self["key_green"].setText(_("Uninstall"))
651 elif current[4] == 'installable':
652 self["key_green"].setText(_("Install"))
653 elif current[4] == 'remove':
654 self["key_green"].setText(_("Undo uninstall"))
655 elif current[4] == 'install':
656 self["key_green"].setText(_("Undo install"))
657 self["key_yellow"].setText(_("View details"))
658 self["key_blue"].setText("")
659 if len(self.selectedFiles) == 0 and iSoftwareTools.available_updates is not 0:
660 self["status"].setText(_("There are at least ") + str(iSoftwareTools.available_updates) + _(" updates available."))
661 elif len(self.selectedFiles) is not 0:
662 self["status"].setText(str(len(self.selectedFiles)) + _(" packages selected."))
664 self["status"].setText(_("There are currently no outstanding actions."))
665 elif self.currList == "category":
666 self["key_red"].setText(_("Close"))
667 self["key_green"].setText("")
668 self["key_yellow"].setText("")
669 self["key_blue"].setText("")
670 if len(self.selectedFiles) == 0 and iSoftwareTools.available_updates is not 0:
671 self["status"].setText(_("There are at least ") + str(iSoftwareTools.available_updates) + _(" updates available."))
672 self["key_yellow"].setText(_("Update"))
673 elif len(self.selectedFiles) is not 0:
674 self["status"].setText(str(len(self.selectedFiles)) + _(" packages selected."))
675 self["key_yellow"].setText(_("Process"))
677 self["status"].setText(_("There are currently no outstanding actions."))
679 def getSelectionState(self, detailsFile):
680 for entry in self.selectedFiles:
681 if entry[0] == detailsFile:
685 def handleCurrent(self):
686 current = self["list"].getCurrent()
688 if self.currList == "category":
689 self.currentSelectedIndex = self["list"].index
690 selectedTag = current[2]
691 self.buildPacketList(selectedTag)
692 elif self.currList == "packages":
693 if current[7] is not '':
694 idx = self["list"].getIndex()
695 detailsFile = self.list[idx][1]
696 if self.list[idx][7] == True:
697 for entry in self.selectedFiles:
698 if entry[0] == detailsFile:
699 self.selectedFiles.remove(entry)
701 alreadyinList = False
702 for entry in self.selectedFiles:
703 if entry[0] == detailsFile:
705 if not alreadyinList:
706 self.selectedFiles.append((detailsFile,current[4],current[3]))
707 self.currentSelectedPackage = ((detailsFile,current[4],current[3]))
708 if current[4] == 'installed':
709 self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'remove', True)
710 elif current[4] == 'installable':
711 self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'install', True)
712 elif current[4] == 'remove':
713 self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'installed', False)
714 elif current[4] == 'install':
715 self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'installable',False)
716 self["list"].setList(self.list)
717 self["list"].setIndex(idx)
718 self["list"].updateList(self.list)
719 self.selectionChanged()
721 def handleSelected(self):
722 current = self["list"].getCurrent()
724 if self.currList == "packages":
725 if current[7] is not '':
726 detailsfile = iSoftwareTools.directory[0] + "/" + current[1]
727 if (os_path.exists(detailsfile) == True):
728 self.saved_currentSelectedPackage = self.currentSelectedPackage
729 self.session.openWithCallback(self.detailsClosed, PluginDetails, self.skin_path, current)
731 self.session.open(MessageBox, _("Sorry, no Details available!"), MessageBox.TYPE_INFO, timeout = 10)
732 elif self.currList == "category":
733 self.prepareInstall()
734 if len(self.cmdList):
735 self.session.openWithCallback(self.runExecute, PluginManagerInfo, self.skin_path, self.cmdList)
737 def detailsClosed(self, result = None):
738 if result is not None:
739 if result is not False:
740 self.setState('sync')
741 iSoftwareTools.lastDownloadDate = time()
742 for entry in self.selectedFiles:
743 if entry == self.saved_currentSelectedPackage:
744 self.selectedFiles.remove(entry)
745 iSoftwareTools.startIpkgListInstalled(self.rebuildList)
747 def buildEntryComponent(self, name, details, description, packagename, state, selected = False):
748 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
749 installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installed.png"))
750 installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installable.png"))
751 removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
752 installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/install.png"))
753 if state == 'installed':
754 return((name, details, description, packagename, state, installedpng, divpng, selected))
755 elif state == 'installable':
756 return((name, details, description, packagename, state, installablepng, divpng, selected))
757 elif state == 'remove':
758 return((name, details, description, packagename, state, removepng, divpng, selected))
759 elif state == 'install':
760 return((name, details, description, packagename, state, installpng, divpng, selected))
762 def buildPacketList(self, categorytag = None):
763 if categorytag is not None:
764 self.currList = "packages"
765 self.currentSelectedTag = categorytag
767 for package in iSoftwareTools.packagesIndexlist[:]:
768 prerequisites = package[0]["prerequisites"]
769 if prerequisites.has_key("tag"):
770 for foundtag in prerequisites["tag"]:
771 if categorytag == foundtag:
772 attributes = package[0]["attributes"]
773 if attributes.has_key("packagetype"):
774 if attributes["packagetype"] == "internal":
776 self.packetlist.append([attributes["name"], attributes["details"], attributes["shortdescription"], attributes["packagename"]])
778 self.packetlist.append([attributes["name"], attributes["details"], attributes["shortdescription"], attributes["packagename"]])
780 for x in self.packetlist:
783 details = x[1].strip()
784 description = x[2].strip()
785 packagename = x[3].strip()
786 selectState = self.getSelectionState(details)
787 if iSoftwareTools.installed_packetlist.has_key(packagename):
788 if selectState == True:
792 self.list.append(self.buildEntryComponent(name, details, description, packagename, status, selected = selectState))
794 if selectState == True:
797 status = "installable"
798 self.list.append(self.buildEntryComponent(name, details, description, packagename, status, selected = selectState))
800 self.list.sort(key=lambda x: x[0])
801 self["list"].style = "default"
802 self['list'].setList(self.list)
803 self["list"].updateList(self.list)
804 self.selectionChanged()
806 def buildCategoryList(self):
807 self.currList = "category"
809 self.categoryList = []
810 for package in iSoftwareTools.packagesIndexlist[:]:
811 prerequisites = package[0]["prerequisites"]
812 if prerequisites.has_key("tag"):
813 for foundtag in prerequisites["tag"]:
814 attributes = package[0]["attributes"]
815 if foundtag not in self.categories:
816 self.categories.append(foundtag)
817 self.categoryList.append(self.buildCategoryComponent(foundtag))
818 self.categoryList.sort(key=lambda x: x[0])
819 self["list"].style = "category"
820 self['list'].setList(self.categoryList)
821 self["list"].updateList(self.categoryList)
822 self.selectionChanged()
824 def buildCategoryComponent(self, tag = None):
825 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
828 return(( _("System"), _("View list of available system extensions" ), tag, divpng ))
830 return(( _("Skins"), _("View list of available skins" ), tag, divpng ))
831 elif tag == 'Recording':
832 return(( _("Recordings"), _("View list of available recording extensions" ), tag, divpng ))
833 elif tag == 'Network':
834 return(( _("Network"), _("View list of available networking extensions" ), tag, divpng ))
836 return(( _("CommonInterface"), _("View list of available CommonInterface extensions" ), tag, divpng ))
837 elif tag == 'Default':
838 return(( _("Default Settings"), _("View list of available default settings" ), tag, divpng ))
840 return(( _("Satellite equipment"), _("View list of available Satellite equipment extensions." ), tag, divpng ))
841 elif tag == 'Software':
842 return(( _("Software"), _("View list of available software extensions" ), tag, divpng ))
843 elif tag == 'Multimedia':
844 return(( _("Multimedia"), _("View list of available multimedia extensions." ), tag, divpng ))
845 elif tag == 'Display':
846 return(( _("Display and Userinterface"), _("View list of available Display and Userinterface extensions." ), tag, divpng ))
848 return(( _("Electronic Program Guide"), _("View list of available EPG extensions." ), tag, divpng ))
849 elif tag == 'Communication':
850 return(( _("Communication"), _("View list of available communication extensions." ), tag, divpng ))
851 else: # dynamically generate non existent tags
852 return(( str(tag), _("View list of available ") + str(tag) + _(" extensions." ), tag, divpng ))
854 def prepareInstall(self):
856 if iSoftwareTools.available_updates > 0:
857 self.cmdList.append((IpkgComponent.CMD_UPGRADE, { "test_only": False }))
858 if self.selectedFiles and len(self.selectedFiles):
859 for plugin in self.selectedFiles:
860 detailsfile = iSoftwareTools.directory[0] + "/" + plugin[0]
861 if (os_path.exists(detailsfile) == True):
862 iSoftwareTools.fillPackageDetails(plugin[0])
863 self.package = iSoftwareTools.packageDetails[0]
864 if self.package[0].has_key("attributes"):
865 self.attributes = self.package[0]["attributes"]
866 if self.attributes.has_key("package"):
867 self.packagefiles = self.attributes["package"]
868 if plugin[1] == 'installed':
869 if self.packagefiles:
870 for package in self.packagefiles[:]:
871 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": package["name"] }))
873 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": plugin[2] }))
875 if self.packagefiles:
876 for package in self.packagefiles[:]:
877 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package["name"] }))
879 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": plugin[2] }))
881 if plugin[1] == 'installed':
882 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": plugin[2] }))
884 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": plugin[2] }))
886 def runExecute(self, result = None):
887 if result is not None:
888 if result[0] is True:
889 self.session.openWithCallback(self.runExecuteFinished, Ipkg, cmdList = self.cmdList)
890 elif result[0] is False:
891 self.cmdList = result[1]
892 self.session.openWithCallback(self.runExecuteFinished, Ipkg, cmdList = self.cmdList)
896 def runExecuteFinished(self):
897 self.session.openWithCallback(self.ExecuteReboot, MessageBox, _("Install or remove finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
899 def ExecuteReboot(self, result):
903 self.reloadPluginlist()
904 self.selectedFiles = []
905 self.detailsClosed(True)
909 def reloadPluginlist(self):
910 plugins.readPluginList(resolveFilename(SCOPE_PLUGINS))
913 class PluginManagerInfo(Screen):
915 <screen name="PluginManagerInfo" position="center,center" size="560,450" title="Plugin manager activity information" >
916 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
917 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
918 <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
919 <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
920 <widget source="list" render="Listbox" position="5,50" size="550,350" scrollbarMode="showOnDemand" selectionDisabled="1">
921 <convert type="TemplatedMultiContent">
923 MultiContentEntryText(pos = (50, 0), size = (150, 26), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
924 MultiContentEntryText(pos = (50, 27), size = (540, 23), font=1, flags = RT_HALIGN_LEFT, text = 1), # index 1 is the state
925 MultiContentEntryPixmapAlphaTest(pos = (0, 1), size = (48, 48), png = 2), # index 2 is the status pixmap
926 MultiContentEntryPixmapAlphaTest(pos = (0, 48), size = (550, 2), png = 3), # index 3 is the div pixmap
928 "fonts": [gFont("Regular", 24),gFont("Regular", 22)],
933 <ePixmap pixmap="skin_default/div-h.png" position="0,404" zPosition="10" size="560,2" transparent="1" alphatest="on" />
934 <widget source="status" render="Label" position="5,408" zPosition="10" size="550,44" halign="center" valign="center" font="Regular;22" transparent="1" shadowColor="black" shadowOffset="-1,-1" />
937 def __init__(self, session, plugin_path, cmdlist = None):
938 Screen.__init__(self, session)
939 self.session = session
940 self.skin_path = plugin_path
941 self.cmdlist = cmdlist
943 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"],
945 "ok": self.process_all,
948 "green": self.process_extensions,
952 self["list"] = List(self.list)
953 self["key_red"] = StaticText(_("Cancel"))
954 self["key_green"] = StaticText(_("Only extensions."))
955 self["status"] = StaticText(_("Following tasks will be done after you press OK!"))
957 self.onShown.append(self.setWindowTitle)
958 self.onLayoutFinish.append(self.rebuildList)
960 def setWindowTitle(self):
961 self.setTitle(_("Plugin manager activity information"))
963 def rebuildList(self):
965 if self.cmdlist is not None:
966 for entry in self.cmdlist:
978 info = args['package']
980 info = args['package']
982 info = _("Dreambox software because updates are available.")
984 self.list.append(self.buildEntryComponent(action,info))
985 self['list'].setList(self.list)
986 self['list'].updateList(self.list)
988 def buildEntryComponent(self, action,info):
989 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
990 upgradepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgrade.png"))
991 installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/install.png"))
992 removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
993 if action == 'install':
994 return(( _('Installing'), info, installpng, divpng))
995 elif action == 'remove':
996 return(( _('Removing'), info, removepng, divpng))
998 return(( _('Upgrading'), info, upgradepng, divpng))
1003 def process_all(self):
1004 self.close((True,None))
1006 def process_extensions(self):
1008 if self.cmdlist is not None:
1009 for entry in self.cmdlist:
1011 if entry[0] in (0,2):
1012 self.list.append((entry))
1013 self.close((False,self.list))
1016 class PluginManagerHelp(Screen):
1018 <screen name="PluginManagerHelp" position="center,center" size="560,450" title="Plugin manager help" >
1019 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1020 <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
1021 <widget source="list" render="Listbox" position="5,50" size="550,350" scrollbarMode="showOnDemand" selectionDisabled="1">
1022 <convert type="TemplatedMultiContent">
1024 MultiContentEntryText(pos = (50, 0), size = (540, 26), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
1025 MultiContentEntryText(pos = (50, 27), size = (540, 23), font=1, flags = RT_HALIGN_LEFT, text = 1), # index 1 is the state
1026 MultiContentEntryPixmapAlphaTest(pos = (0, 1), size = (48, 48), png = 2), # index 2 is the status pixmap
1027 MultiContentEntryPixmapAlphaTest(pos = (0, 48), size = (550, 2), png = 3), # index 3 is the div pixmap
1029 "fonts": [gFont("Regular", 24),gFont("Regular", 22)],
1034 <ePixmap pixmap="skin_default/div-h.png" position="0,404" zPosition="10" size="560,2" transparent="1" alphatest="on" />
1035 <widget source="status" render="Label" position="5,408" zPosition="10" size="550,44" halign="center" valign="center" font="Regular;22" transparent="1" shadowColor="black" shadowOffset="-1,-1" />
1038 def __init__(self, session, plugin_path):
1039 Screen.__init__(self, session)
1040 self.session = session
1041 self.skin_path = plugin_path
1043 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"],
1050 self["list"] = List(self.list)
1051 self["key_red"] = StaticText(_("Close"))
1052 self["status"] = StaticText(_("A small overview of the available icon states and actions."))
1054 self.onShown.append(self.setWindowTitle)
1055 self.onLayoutFinish.append(self.rebuildList)
1057 def setWindowTitle(self):
1058 self.setTitle(_("Plugin manager help"))
1060 def rebuildList(self):
1062 self.list.append(self.buildEntryComponent('install'))
1063 self.list.append(self.buildEntryComponent('installable'))
1064 self.list.append(self.buildEntryComponent('installed'))
1065 self.list.append(self.buildEntryComponent('remove'))
1066 self['list'].setList(self.list)
1067 self['list'].updateList(self.list)
1069 def buildEntryComponent(self, state):
1070 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
1071 installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installed.png"))
1072 installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installable.png"))
1073 removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
1074 installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/install.png"))
1076 if state == 'installed':
1077 return(( _('This plugin is installed.'), _('You can remove this plugin.'), installedpng, divpng))
1078 elif state == 'installable':
1079 return(( _('This plugin is not installed.'), _('You can install this plugin.'), installablepng, divpng))
1080 elif state == 'install':
1081 return(( _('This plugin will be installed.'), _('You can cancel the installation.'), installpng, divpng))
1082 elif state == 'remove':
1083 return(( _('This plugin will be removed.'), _('You can cancel the removal.'), removepng, divpng))
1089 class PluginDetails(Screen, DreamInfoHandler):
1091 <screen name="PluginDetails" position="center,center" size="600,440" title="Plugin details" >
1092 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1093 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1094 <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
1095 <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
1096 <widget source="author" render="Label" position="10,50" size="500,25" zPosition="10" font="Regular;21" transparent="1" />
1097 <widget name="statuspic" position="550,40" size="48,48" alphatest="on"/>
1098 <widget name="divpic" position="0,80" size="600,2" alphatest="on"/>
1099 <widget name="detailtext" position="10,90" size="270,330" zPosition="10" font="Regular;21" transparent="1" halign="left" valign="top"/>
1100 <widget name="screenshot" position="290,90" size="300,330" alphatest="on"/>
1102 def __init__(self, session, plugin_path, packagedata = None):
1103 Screen.__init__(self, session)
1104 self.skin_path = plugin_path
1105 self.language = language.getLanguage()[:2] # getLanguage returns e.g. "fi_FI" for "language_country"
1106 self.attributes = None
1107 self.translatedAttributes = None
1108 DreamInfoHandler.__init__(self, self.statusCallback, blocking = False, language = self.language)
1109 self.directory = resolveFilename(SCOPE_METADIR)
1111 self.pluginname = packagedata[0]
1112 self.details = packagedata[1]
1113 self.pluginstate = packagedata[4]
1114 self.statuspicinstance = packagedata[5]
1115 self.divpicinstance = packagedata[6]
1116 self.fillPackageDetails(self.details)
1120 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"],
1126 "down": self.pageDown,
1127 "left": self.pageUp,
1128 "right": self.pageDown,
1131 self["key_red"] = StaticText(_("Close"))
1132 self["key_green"] = StaticText("")
1133 self["author"] = StaticText()
1134 self["statuspic"] = Pixmap()
1135 self["divpic"] = Pixmap()
1136 self["screenshot"] = Pixmap()
1137 self["detailtext"] = ScrollLabel()
1139 self["statuspic"].hide()
1140 self["screenshot"].hide()
1141 self["divpic"].hide()
1143 self.package = self.packageDetails[0]
1144 if self.package[0].has_key("attributes"):
1145 self.attributes = self.package[0]["attributes"]
1146 if self.package[0].has_key("translation"):
1147 self.translatedAttributes = self.package[0]["translation"]
1150 self.oktext = _("\nAfter pressing OK, please wait!")
1151 self.picload = ePicLoad()
1152 self.picload.PictureData.get().append(self.paintScreenshotPixmapCB)
1153 self.onShown.append(self.setWindowTitle)
1154 self.onLayoutFinish.append(self.setInfos)
1156 def setWindowTitle(self):
1157 self.setTitle(_("Details for extension: " + self.pluginname))
1163 self["detailtext"].pageUp()
1166 self["detailtext"].pageDown()
1168 def statusCallback(self, status, progress):
1172 if self.translatedAttributes.has_key("name"):
1173 self.pluginname = self.translatedAttributes["name"]
1174 elif self.attributes.has_key("name"):
1175 self.pluginname = self.attributes["name"]
1177 self.pluginname = _("unknown")
1179 if self.translatedAttributes.has_key("author"):
1180 self.author = self.translatedAttributes["author"]
1181 elif self.attributes.has_key("author"):
1182 self.author = self.attributes["author"]
1184 self.author = _("unknown")
1186 if self.translatedAttributes.has_key("description"):
1187 self.description = self.translatedAttributes["description"]
1188 elif self.attributes.has_key("description"):
1189 self.description = self.attributes["description"]
1191 self.description = _("No description available.")
1193 if self.translatedAttributes.has_key("screenshot"):
1194 self.loadThumbnail(self.translatedAttributes)
1196 self.loadThumbnail(self.attributes)
1198 self["author"].setText(_("Author: ") + self.author)
1199 self["detailtext"].setText(self.description.strip())
1200 if self.pluginstate in ('installable', 'install'):
1201 self["key_green"].setText(_("Install"))
1203 self["key_green"].setText(_("Remove"))
1205 def loadThumbnail(self, entry):
1207 if entry.has_key("screenshot"):
1208 thumbnailUrl = entry["screenshot"]
1209 if thumbnailUrl is not None:
1210 self.thumbnail = "/tmp/" + thumbnailUrl.split('/')[-1]
1211 print "[PluginDetails] downloading screenshot " + thumbnailUrl + " to " + self.thumbnail
1212 client.downloadPage(thumbnailUrl,self.thumbnail).addCallback(self.setThumbnail).addErrback(self.fetchFailed)
1214 self.setThumbnail(noScreenshot = True)
1216 def setThumbnail(self, noScreenshot = False):
1217 if not noScreenshot:
1218 filename = self.thumbnail
1220 filename = resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/noprev.png")
1222 sc = AVSwitch().getFramebufferScale()
1223 self.picload.setPara((self["screenshot"].instance.size().width(), self["screenshot"].instance.size().height(), sc[0], sc[1], False, 1, "#00000000"))
1224 self.picload.startDecode(filename)
1226 if self.statuspicinstance != None:
1227 self["statuspic"].instance.setPixmap(self.statuspicinstance.__deref__())
1228 self["statuspic"].show()
1229 if self.divpicinstance != None:
1230 self["divpic"].instance.setPixmap(self.divpicinstance.__deref__())
1231 self["divpic"].show()
1233 def paintScreenshotPixmapCB(self, picInfo=None):
1234 ptr = self.picload.getData()
1236 self["screenshot"].instance.setPixmap(ptr.__deref__())
1237 self["screenshot"].show()
1239 self.setThumbnail(noScreenshot = True)
1242 if self.attributes.has_key("package"):
1243 self.packagefiles = self.attributes["package"]
1245 if self.pluginstate in ('installed', 'remove'):
1246 if self.packagefiles:
1247 for package in self.packagefiles[:]:
1248 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": package["name"] }))
1249 if len(self.cmdList):
1250 self.session.openWithCallback(self.runRemove, MessageBox, _("Do you want to remove the package:\n") + self.pluginname + "\n" + self.oktext)
1252 if self.packagefiles:
1253 for package in self.packagefiles[:]:
1254 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package["name"] }))
1255 if len(self.cmdList):
1256 self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to install the package:\n") + self.pluginname + "\n" + self.oktext)
1258 def runUpgrade(self, result):
1260 self.session.openWithCallback(self.runUpgradeFinished, Ipkg, cmdList = self.cmdList)
1262 def runUpgradeFinished(self):
1263 self.session.openWithCallback(self.UpgradeReboot, MessageBox, _("Installation finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
1265 def UpgradeReboot(self, result):
1273 def runRemove(self, result):
1275 self.session.openWithCallback(self.runRemoveFinished, Ipkg, cmdList = self.cmdList)
1277 def runRemoveFinished(self):
1278 self.session.openWithCallback(self.RemoveReboot, MessageBox, _("Remove finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
1280 def RemoveReboot(self, result):
1288 def reloadPluginlist(self):
1289 plugins.readPluginList(resolveFilename(SCOPE_PLUGINS))
1291 def fetchFailed(self,string):
1292 self.setThumbnail(noScreenshot = True)
1293 print "[PluginDetails] fetch failed " + string.getErrorMessage()
1296 class UpdatePlugin(Screen):
1298 <screen name="UpdatePlugin" position="center,center" size="550,300" title="Software update" >
1299 <widget name="activityslider" position="0,0" size="550,5" />
1300 <widget name="slider" position="0,150" size="550,30" />
1301 <widget source="package" render="Label" position="10,30" size="540,20" font="Regular;18" halign="center" valign="center" backgroundColor="#25062748" transparent="1" />
1302 <widget source="status" render="Label" position="10,60" size="540,45" font="Regular;20" halign="center" valign="center" backgroundColor="#25062748" transparent="1" />
1305 def __init__(self, session, args = None):
1306 Screen.__init__(self, session)
1308 self.sliderPackages = { "dreambox-dvb-modules": 1, "enigma2": 2, "tuxbox-image-info": 3 }
1310 self.slider = Slider(0, 4)
1311 self["slider"] = self.slider
1312 self.activityslider = Slider(0, 100)
1313 self["activityslider"] = self.activityslider
1314 self.status = StaticText(_("Upgrading Dreambox... Please wait"))
1315 self["status"] = self.status
1316 self.package = StaticText()
1317 self["package"] = self.package
1318 self.oktext = _("Press OK on your remote control to continue.")
1322 self.processed_packages = []
1325 self.activityTimer = eTimer()
1326 self.activityTimer.callback.append(self.doActivityTimer)
1327 self.activityTimer.start(100, False)
1329 self.ipkg = IpkgComponent()
1330 self.ipkg.addCallback(self.ipkgCallback)
1332 self.updating = True
1333 self.package.setText(_("Package list update"))
1334 self.ipkg.startCmd(IpkgComponent.CMD_UPDATE)
1336 self["actions"] = ActionMap(["WizardActions"],
1342 def doActivityTimer(self):
1344 if self.activity == 100:
1346 self.activityslider.setValue(self.activity)
1348 def ipkgCallback(self, event, param):
1349 if event == IpkgComponent.EVENT_DOWNLOAD:
1350 self.status.setText(_("Downloading"))
1351 elif event == IpkgComponent.EVENT_UPGRADE:
1352 if self.sliderPackages.has_key(param):
1353 self.slider.setValue(self.sliderPackages[param])
1354 self.package.setText(param)
1355 self.status.setText(_("Upgrading"))
1356 if not param in self.processed_packages:
1357 self.processed_packages.append(param)
1359 elif event == IpkgComponent.EVENT_INSTALL:
1360 self.package.setText(param)
1361 self.status.setText(_("Installing"))
1362 if not param in self.processed_packages:
1363 self.processed_packages.append(param)
1365 elif event == IpkgComponent.EVENT_REMOVE:
1366 self.package.setText(param)
1367 self.status.setText(_("Removing"))
1368 if not param in self.processed_packages:
1369 self.processed_packages.append(param)
1371 elif event == IpkgComponent.EVENT_CONFIGURING:
1372 self.package.setText(param)
1373 self.status.setText(_("Configuring"))
1375 elif event == IpkgComponent.EVENT_MODIFIED:
1376 if config.plugins.SoftwareManager.overwriteConfigFiles.value in ("N", "Y"):
1377 self.ipkg.write(True and config.plugins.SoftwareManager.overwriteConfigFiles.value)
1379 self.session.openWithCallback(
1380 self.modificationCallback,
1382 _("A configuration file (%s) was modified since Installation.\nDo you want to keep your version?") % (param)
1384 elif event == IpkgComponent.EVENT_ERROR:
1386 elif event == IpkgComponent.EVENT_DONE:
1388 self.updating = False
1389 self.ipkg.startCmd(IpkgComponent.CMD_UPGRADE, args = {'test_only': False})
1390 elif self.error == 0:
1391 self.slider.setValue(4)
1393 self.activityTimer.stop()
1394 self.activityslider.setValue(0)
1396 self.package.setText("")
1397 self.status.setText(_("Done - Installed or upgraded %d packages") % self.packages + "\n\n" + self.oktext)
1399 self.activityTimer.stop()
1400 self.activityslider.setValue(0)
1401 error = _("your dreambox might be unusable now. Please consult the manual for further assistance before rebooting your dreambox.")
1402 if self.packages == 0:
1403 error = _("No packages were upgraded yet. So you can check your network and try again.")
1405 error = _("Your dreambox isn't connected to the internet properly. Please check it and try again.")
1406 self.status.setText(_("Error") + " - " + error)
1407 #print event, "-", param
1410 def modificationCallback(self, res):
1411 self.ipkg.write(res and "N" or "Y")
1414 if not self.ipkg.isRunning():
1415 if self.packages != 0 and self.error == 0:
1416 self.session.openWithCallback(self.exitAnswer, MessageBox, _("Upgrade finished.") +" "+_("Do you want to reboot your Dreambox?"))
1420 def exitAnswer(self, result):
1421 if result is not None and result:
1427 class IPKGMenu(Screen):
1429 <screen name="IPKGMenu" position="center,center" size="560,400" title="Select upgrade source to edit." >
1430 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1431 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1432 <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" />
1433 <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" />
1434 <widget name="filelist" position="5,50" size="550,340" scrollbarMode="showOnDemand" />
1437 def __init__(self, session, plugin_path):
1438 Screen.__init__(self, session)
1439 self.skin_path = plugin_path
1441 self["key_red"] = StaticText(_("Close"))
1442 self["key_green"] = StaticText(_("Edit"))
1451 self["actions"] = NumberActionMap(["SetupActions"],
1454 "cancel": self.keyCancel
1457 self["shortcuts"] = ActionMap(["ShortcutActions"],
1459 "red": self.keyCancel,
1460 "green": self.KeyOk,
1463 self["filelist"] = MenuList(self.flist)
1465 self.onLayoutFinish.append(self.layoutFinished)
1467 def layoutFinished(self):
1468 self.setWindowTitle()
1470 def setWindowTitle(self):
1471 self.setTitle(_("Select upgrade source to edit."))
1473 def fill_list(self):
1475 self.path = '/etc/ipkg/'
1476 if (os_path.exists(self.path) == False):
1479 for file in listdir(self.path):
1480 if (file.endswith(".conf")):
1481 if file != 'arch.conf':
1482 self.flist.append((file))
1484 self["filelist"].l.setList(self.flist)
1487 if (self.exe == False) and (self.entry == True):
1488 self.sel = self["filelist"].getCurrent()
1489 self.val = self.path + self.sel
1490 self.session.open(IPKGSource, self.val)
1492 def keyCancel(self):
1499 class IPKGSource(Screen):
1501 <screen name="IPKGSource" position="center,center" size="560,80" title="Edit upgrade source url." >
1502 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1503 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1504 <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" />
1505 <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" />
1506 <widget name="text" position="5,50" size="550,25" font="Regular;20" backgroundColor="background" foregroundColor="#cccccc" />
1509 def __init__(self, session, configfile = None):
1510 Screen.__init__(self, session)
1511 self.session = session
1512 self.configfile = configfile
1516 fp = file(configfile, 'r')
1517 sources = fp.readlines()
1524 desk = getDesktop(0)
1525 x= int(desk.size().width())
1526 y= int(desk.size().height())
1528 self["key_red"] = StaticText(_("Cancel"))
1529 self["key_green"] = StaticText(_("Save"))
1532 self["text"] = Input(text, maxSize=False, type=Input.TEXT)
1534 self["text"] = Input(text, maxSize=False, visible_width = 55, type=Input.TEXT)
1536 self["actions"] = NumberActionMap(["WizardActions", "InputActions", "TextEntryActions", "KeyboardInputActions","ShortcutActions"],
1542 "left": self.keyLeft,
1543 "right": self.keyRight,
1544 "home": self.keyHome,
1546 "deleteForward": self.keyDeleteForward,
1547 "deleteBackward": self.keyDeleteBackward,
1548 "1": self.keyNumberGlobal,
1549 "2": self.keyNumberGlobal,
1550 "3": self.keyNumberGlobal,
1551 "4": self.keyNumberGlobal,
1552 "5": self.keyNumberGlobal,
1553 "6": self.keyNumberGlobal,
1554 "7": self.keyNumberGlobal,
1555 "8": self.keyNumberGlobal,
1556 "9": self.keyNumberGlobal,
1557 "0": self.keyNumberGlobal
1560 self.onLayoutFinish.append(self.layoutFinished)
1562 def layoutFinished(self):
1563 self.setWindowTitle()
1564 self["text"].right()
1566 def setWindowTitle(self):
1567 self.setTitle(_("Edit upgrade source url."))
1570 text = self["text"].getText()
1572 fp = file(self.configfile, 'w')
1582 self["text"].right()
1590 def keyDeleteForward(self):
1591 self["text"].delete()
1593 def keyDeleteBackward(self):
1594 self["text"].deleteBackward()
1596 def keyNumberGlobal(self, number):
1597 self["text"].number(number)
1600 class PacketManager(Screen, NumericalTextInput):
1602 <screen name="PacketManager" position="center,center" size="530,420" title="Packet manager" >
1603 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1604 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1605 <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" />
1606 <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" />
1607 <widget source="list" render="Listbox" position="5,50" size="520,365" scrollbarMode="showOnDemand">
1608 <convert type="TemplatedMultiContent">
1610 MultiContentEntryText(pos = (5, 1), size = (440, 28), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
1611 MultiContentEntryText(pos = (5, 26), size = (440, 20), font=1, flags = RT_HALIGN_LEFT, text = 2), # index 2 is the description
1612 MultiContentEntryPixmapAlphaTest(pos = (445, 2), size = (48, 48), png = 4), # index 4 is the status pixmap
1613 MultiContentEntryPixmapAlphaTest(pos = (5, 50), size = (510, 2), png = 5), # index 4 is the div pixmap
1615 "fonts": [gFont("Regular", 22),gFont("Regular", 14)],
1622 def __init__(self, session, plugin_path, args = None):
1623 Screen.__init__(self, session)
1624 NumericalTextInput.__init__(self)
1625 self.session = session
1626 self.skin_path = plugin_path
1628 self.setUseableChars(u'1234567890abcdefghijklmnopqrstuvwxyz')
1630 self["shortcuts"] = NumberActionMap(["ShortcutActions", "WizardActions", "NumberActions", "InputActions", "InputAsciiActions", "KeyboardInputActions" ],
1635 "green": self.reload,
1636 "gotAsciiCode": self.keyGotAscii,
1637 "1": self.keyNumberGlobal,
1638 "2": self.keyNumberGlobal,
1639 "3": self.keyNumberGlobal,
1640 "4": self.keyNumberGlobal,
1641 "5": self.keyNumberGlobal,
1642 "6": self.keyNumberGlobal,
1643 "7": self.keyNumberGlobal,
1644 "8": self.keyNumberGlobal,
1645 "9": self.keyNumberGlobal,
1646 "0": self.keyNumberGlobal
1650 self.statuslist = []
1651 self["list"] = List(self.list)
1652 self["key_red"] = StaticText(_("Close"))
1653 self["key_green"] = StaticText(_("Reload"))
1655 self.list_updating = True
1656 self.packetlist = []
1657 self.installed_packetlist = {}
1658 self.Console = Console()
1661 self.cache_ttl = 86400 #600 is default, 0 disables, Seconds cache is considered valid (24h should be ok for caching ipkgs)
1662 self.cache_file = '/usr/lib/enigma2/python/Plugins/SystemPlugins/SoftwareManager/packetmanager.cache' #Path to cache directory
1663 self.oktext = _("\nAfter pressing OK, please wait!")
1664 self.unwanted_extensions = ('-dbg', '-dev', '-doc', 'busybox')
1666 self.ipkg = IpkgComponent()
1667 self.ipkg.addCallback(self.ipkgCallback)
1668 self.onShown.append(self.setWindowTitle)
1669 self.onLayoutFinish.append(self.rebuildList)
1671 rcinput = eRCInput.getInstance()
1672 rcinput.setKeyboardMode(rcinput.kmAscii)
1674 def keyNumberGlobal(self, val):
1675 key = self.getKey(val)
1677 keyvalue = key.encode("utf-8")
1678 if len(keyvalue) == 1:
1679 self.setNextIdx(keyvalue[0])
1681 def keyGotAscii(self):
1682 keyvalue = unichr(getPrevAsciiCode()).encode("utf-8")
1683 if len(keyvalue) == 1:
1684 self.setNextIdx(keyvalue[0])
1686 def setNextIdx(self,char):
1687 if char in ("0", "1", "a"):
1688 self["list"].setIndex(0)
1690 idx = self.getNextIdx(char)
1691 if idx and idx <= self["list"].count:
1692 self["list"].setIndex(idx)
1694 def getNextIdx(self,char):
1696 for i in self["list"].list:
1703 if self.Console is not None:
1704 if len(self.Console.appContainers):
1705 for name in self.Console.appContainers.keys():
1706 self.Console.kill(name)
1707 rcinput = eRCInput.getInstance()
1708 rcinput.setKeyboardMode(rcinput.kmNone)
1712 if (os_path.exists(self.cache_file) == True):
1713 remove(self.cache_file)
1714 self.list_updating = True
1717 def setWindowTitle(self):
1718 self.setTitle(_("Packet manager"))
1720 def setStatus(self,status = None):
1722 self.statuslist = []
1723 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
1724 if status == 'update':
1725 statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgrade.png"))
1726 self.statuslist.append(( _("Package list update"), '', _("Trying to download a new packetlist. Please wait..." ),'',statuspng, divpng ))
1727 self['list'].setList(self.statuslist)
1728 elif status == 'error':
1729 statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
1730 self.statuslist.append(( _("Error"), '', _("There was an error downloading the packetlist. Please try again." ),'',statuspng, divpng ))
1731 self['list'].setList(self.statuslist)
1733 def rebuildList(self):
1734 self.setStatus('update')
1736 self.vc = valid_cache(self.cache_file, self.cache_ttl)
1737 if self.cache_ttl > 0 and self.vc != 0:
1739 self.buildPacketList()
1742 if self.cache_ttl == 0 or self.inv_cache == 1 or self.vc == 0:
1744 self.ipkg.startCmd(IpkgComponent.CMD_UPDATE)
1746 def go(self, returnValue = None):
1747 cur = self["list"].getCurrent()
1752 if status == 'installed':
1753 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": package }))
1754 if len(self.cmdList):
1755 self.session.openWithCallback(self.runRemove, MessageBox, _("Do you want to remove the package:\n") + package + "\n" + self.oktext)
1756 elif status == 'upgradeable':
1757 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package }))
1758 if len(self.cmdList):
1759 self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to upgrade the package:\n") + package + "\n" + self.oktext)
1760 elif status == "installable":
1761 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package }))
1762 if len(self.cmdList):
1763 self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to install the package:\n") + package + "\n" + self.oktext)
1765 def runRemove(self, result):
1767 self.session.openWithCallback(self.runRemoveFinished, Ipkg, cmdList = self.cmdList)
1769 def runRemoveFinished(self):
1770 self.session.openWithCallback(self.RemoveReboot, MessageBox, _("Remove finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
1772 def RemoveReboot(self, result):
1776 cur = self["list"].getCurrent()
1778 item = self['list'].getIndex()
1779 self.list[item] = self.buildEntryComponent(cur[0], cur[1], cur[2], 'installable')
1780 self.cachelist[item] = [cur[0], cur[1], cur[2], 'installable']
1781 self['list'].setList(self.list)
1782 write_cache(self.cache_file, self.cachelist)
1783 self.reloadPluginlist()
1787 def runUpgrade(self, result):
1789 self.session.openWithCallback(self.runUpgradeFinished, Ipkg, cmdList = self.cmdList)
1791 def runUpgradeFinished(self):
1792 self.session.openWithCallback(self.UpgradeReboot, MessageBox, _("Upgrade finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
1794 def UpgradeReboot(self, result):
1798 cur = self["list"].getCurrent()
1800 item = self['list'].getIndex()
1801 self.list[item] = self.buildEntryComponent(cur[0], cur[1], cur[2], 'installed')
1802 self.cachelist[item] = [cur[0], cur[1], cur[2], 'installed']
1803 self['list'].setList(self.list)
1804 write_cache(self.cache_file, self.cachelist)
1805 self.reloadPluginlist()
1809 def ipkgCallback(self, event, param):
1810 if event == IpkgComponent.EVENT_ERROR:
1811 self.list_updating = False
1812 self.setStatus('error')
1813 elif event == IpkgComponent.EVENT_DONE:
1814 if self.list_updating:
1815 self.list_updating = False
1816 if not self.Console:
1817 self.Console = Console()
1819 self.Console.ePopen(cmd, self.IpkgList_Finished)
1820 #print event, "-", param
1823 def IpkgList_Finished(self, result, retval, extra_args = None):
1825 self.packetlist = []
1826 for x in result.splitlines():
1827 tokens = x.split(' - ') #self.blacklisted_packages
1828 name = tokens[0].strip()
1829 if not any(name.endswith(x) for x in self.unwanted_extensions):
1831 version = l > 1 and tokens[1].strip() or ""
1832 descr = l > 2 and tokens[2].strip() or ""
1833 self.packetlist.append([name, version, descr])
1834 if not self.Console:
1835 self.Console = Console()
1836 cmd = "ipkg list_installed"
1837 self.Console.ePopen(cmd, self.IpkgListInstalled_Finished)
1839 def IpkgListInstalled_Finished(self, result, retval, extra_args = None):
1841 self.installed_packetlist = {}
1842 for x in result.splitlines():
1843 tokens = x.split(' - ') #self.blacklisted_packages
1844 name = tokens[0].strip()
1845 if not any(name.endswith(x) for x in self.unwanted_extensions):
1847 version = l > 1 and tokens[1].strip() or ""
1848 self.installed_packetlist[name] = version
1849 self.buildPacketList()
1851 def buildEntryComponent(self, name, version, description, state):
1852 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
1853 if state == 'installed':
1854 installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installed.png"))
1855 return((name, version, description, state, installedpng, divpng))
1856 elif state == 'upgradeable':
1857 upgradeablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgradeable.png"))
1858 return((name, version, description, state, upgradeablepng, divpng))
1860 installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installable.png"))
1861 return((name, version, description, state, installablepng, divpng))
1863 def buildPacketList(self):
1867 if self.cache_ttl > 0 and self.vc != 0:
1868 print 'Loading packagelist cache from ',self.cache_file
1870 self.cachelist = load_cache(self.cache_file)
1871 if len(self.cachelist) > 0:
1872 for x in self.cachelist:
1873 self.list.append(self.buildEntryComponent(x[0], x[1], x[2], x[3]))
1874 self['list'].setList(self.list)
1878 if self.cache_ttl == 0 or self.inv_cache == 1 or self.vc == 0:
1879 print 'rebuilding fresh package list'
1880 for x in self.packetlist:
1882 if self.installed_packetlist.has_key(x[0].strip()):
1883 if self.installed_packetlist[x[0].strip()] == x[1].strip():
1884 status = "installed"
1885 self.list.append(self.buildEntryComponent(x[0].strip(), x[1].strip(), x[2].strip(), status))
1887 status = "upgradeable"
1888 self.list.append(self.buildEntryComponent(x[0].strip(), x[1].strip(), x[2].strip(), status))
1890 status = "installable"
1891 self.list.append(self.buildEntryComponent(x[0].strip(), x[1].strip(), x[2].strip(), status))
1892 if not any(x[0].strip().endswith(x) for x in self.unwanted_extensions):
1893 self.cachelist.append([x[0].strip(), x[1].strip(), x[2].strip(), status])
1894 write_cache(self.cache_file, self.cachelist)
1895 self['list'].setList(self.list)
1897 def reloadPluginlist(self):
1898 plugins.readPluginList(resolveFilename(SCOPE_PLUGINS))
1900 class IpkgInstaller(Screen):
1902 <screen name="IpkgInstaller" position="center,center" size="550,450" title="Install extensions" >
1903 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1904 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1905 <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" />
1906 <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" />
1907 <widget name="list" position="5,50" size="540,360" />
1908 <ePixmap pixmap="skin_default/div-h.png" position="0,410" zPosition="10" size="560,2" transparent="1" alphatest="on" />
1909 <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" />
1912 def __init__(self, session, list):
1913 Screen.__init__(self, session)
1915 self.list = SelectionList()
1916 self["list"] = self.list
1917 for listindex in range(len(list)):
1918 self.list.addSelection(list[listindex], list[listindex], listindex, True)
1920 self["key_red"] = StaticText(_("Close"))
1921 self["key_green"] = StaticText(_("Install"))
1922 self["introduction"] = StaticText(_("Press OK to toggle the selection."))
1924 self["actions"] = ActionMap(["OkCancelActions", "ColorActions"],
1926 "ok": self.list.toggleSelection,
1927 "cancel": self.close,
1929 "green": self.install
1933 list = self.list.getSelectionsList()
1936 cmdList.append((IpkgComponent.CMD_INSTALL, { "package": item[1] }))
1937 self.session.open(Ipkg, cmdList = cmdList)
1940 def filescan_open(list, session, **kwargs):
1941 filelist = [x.path for x in list]
1942 session.open(IpkgInstaller, filelist) # list
1944 def filescan(**kwargs):
1945 from Components.Scanner import Scanner, ScanPath
1947 Scanner(mimetypes = ["application/x-debian-package"],
1950 ScanPath(path = "ipk", with_subdirs = True),
1951 ScanPath(path = "", with_subdirs = False),
1954 description = _("Install extensions."),
1955 openfnc = filescan_open, )
1959 def UpgradeMain(session, **kwargs):
1960 session.open(UpdatePluginMenu)
1962 def startSetup(menuid):
1963 if menuid != "setup":
1965 return [(_("Software management"), UpgradeMain, "software_manager", 50)]
1968 def Plugins(path, **kwargs):
1972 PluginDescriptor(name=_("Software management"), description=_("Manage your receiver's software"), where = PluginDescriptor.WHERE_MENU, fnc=startSetup),
1973 PluginDescriptor(name=_("Ipkg"), where = PluginDescriptor.WHERE_FILESCAN, fnc = filescan)
1975 if config.usage.setup_level.index >= 2: # expert+
1976 list.append(PluginDescriptor(name=_("Software management"), description=_("Manage your receiver's software"), where = PluginDescriptor.WHERE_EXTENSIONSMENU, fnc=UpgradeMain))