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 self["key_green"].setText(_("Continue"))
613 statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
614 self.statuslist.append(( _("Error"), '', _("There was an error downloading the packetlist. Please try again." ),'', '', statuspng, divpng, None, '' ))
615 self["list"].style = "default"
616 self['list'].setList(self.statuslist)
619 def getUpdateInfos(self):
620 if (iSoftwareTools.lastDownloadDate is not None and iSoftwareTools.NetworkConnectionAvailable is False):
623 self.setState('update')
624 iSoftwareTools.startSoftwareTools(self.getUpdateInfosCB)
626 def getUpdateInfosCB(self, retval = None):
627 if retval is not None:
629 if iSoftwareTools.available_updates is not 0:
630 self["status"].setText(_("There are at least ") + str(iSoftwareTools.available_updates) + _(" updates available."))
632 self["status"].setText(_("There are no updates available."))
634 elif retval is False:
635 if iSoftwareTools.lastDownloadDate is None:
636 self.setState('error')
637 if iSoftwareTools.NetworkConnectionAvailable:
638 self["status"].setText(_("Updatefeed not available."))
640 self["status"].setText(_("No network connection available."))
642 iSoftwareTools.lastDownloadDate = time()
643 iSoftwareTools.list_updating = True
644 self.setState('update')
645 iSoftwareTools.getUpdates(self.getUpdateInfosCB)
647 def rebuildList(self, retval = None):
648 if self.currentSelectedTag is None:
649 self.buildCategoryList()
651 self.buildPacketList(self.currentSelectedTag)
653 def selectionChanged(self):
654 current = self["list"].getCurrent()
655 self["status"].setText("")
657 if self.currList == "packages":
658 self["key_red"].setText(_("Back"))
659 if current[4] == 'installed':
660 self["key_green"].setText(_("Uninstall"))
661 elif current[4] == 'installable':
662 self["key_green"].setText(_("Install"))
663 if iSoftwareTools.NetworkConnectionAvailable is False:
664 self["key_green"].setText("")
665 elif current[4] == 'remove':
666 self["key_green"].setText(_("Undo uninstall"))
667 elif current[4] == 'install':
668 self["key_green"].setText(_("Undo install"))
669 if iSoftwareTools.NetworkConnectionAvailable is False:
670 self["key_green"].setText("")
671 self["key_yellow"].setText(_("View details"))
672 self["key_blue"].setText("")
673 if len(self.selectedFiles) == 0 and iSoftwareTools.available_updates is not 0:
674 self["status"].setText(_("There are at least ") + str(iSoftwareTools.available_updates) + _(" updates available."))
675 elif len(self.selectedFiles) is not 0:
676 self["status"].setText(str(len(self.selectedFiles)) + _(" packages selected."))
678 self["status"].setText(_("There are currently no outstanding actions."))
679 elif self.currList == "category":
680 self["key_red"].setText(_("Close"))
681 self["key_green"].setText("")
682 self["key_yellow"].setText("")
683 self["key_blue"].setText("")
684 if len(self.selectedFiles) == 0 and iSoftwareTools.available_updates is not 0:
685 self["status"].setText(_("There are at least ") + str(iSoftwareTools.available_updates) + _(" updates available."))
686 self["key_yellow"].setText(_("Update"))
687 elif len(self.selectedFiles) is not 0:
688 self["status"].setText(str(len(self.selectedFiles)) + _(" packages selected."))
689 self["key_yellow"].setText(_("Process"))
691 self["status"].setText(_("There are currently no outstanding actions."))
693 def getSelectionState(self, detailsFile):
694 for entry in self.selectedFiles:
695 if entry[0] == detailsFile:
699 def handleCurrent(self):
700 current = self["list"].getCurrent()
702 if self.currList == "category":
703 self.currentSelectedIndex = self["list"].index
704 selectedTag = current[2]
705 self.buildPacketList(selectedTag)
706 elif self.currList == "packages":
707 if current[7] is not '':
708 idx = self["list"].getIndex()
709 detailsFile = self.list[idx][1]
710 if self.list[idx][7] == True:
711 for entry in self.selectedFiles:
712 if entry[0] == detailsFile:
713 self.selectedFiles.remove(entry)
715 alreadyinList = False
716 for entry in self.selectedFiles:
717 if entry[0] == detailsFile:
719 if not alreadyinList:
720 if (iSoftwareTools.NetworkConnectionAvailable is False and current[4] in ('installable','install')):
723 self.selectedFiles.append((detailsFile,current[4],current[3]))
724 self.currentSelectedPackage = ((detailsFile,current[4],current[3]))
725 if current[4] == 'installed':
726 self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'remove', True)
727 elif current[4] == 'installable':
728 if iSoftwareTools.NetworkConnectionAvailable:
729 self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'install', True)
730 elif current[4] == 'remove':
731 self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'installed', False)
732 elif current[4] == 'install':
733 if iSoftwareTools.NetworkConnectionAvailable:
734 self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'installable',False)
735 self["list"].setList(self.list)
736 self["list"].setIndex(idx)
737 self["list"].updateList(self.list)
738 self.selectionChanged()
739 elif self.currList == "status":
740 iSoftwareTools.lastDownloadDate = time()
741 iSoftwareTools.list_updating = True
742 self.setState('update')
743 iSoftwareTools.getUpdates(self.getUpdateInfosCB)
745 def handleSelected(self):
746 current = self["list"].getCurrent()
748 if self.currList == "packages":
749 if current[7] is not '':
750 detailsfile = iSoftwareTools.directory[0] + "/" + current[1]
751 if (os_path.exists(detailsfile) == True):
752 self.saved_currentSelectedPackage = self.currentSelectedPackage
753 self.session.openWithCallback(self.detailsClosed, PluginDetails, self.skin_path, current)
755 self.session.open(MessageBox, _("Sorry, no Details available!"), MessageBox.TYPE_INFO, timeout = 10)
756 elif self.currList == "category":
757 self.prepareInstall()
758 if len(self.cmdList):
759 self.session.openWithCallback(self.runExecute, PluginManagerInfo, self.skin_path, self.cmdList)
761 def detailsClosed(self, result = None):
762 if result is not None:
763 if result is not False:
764 self.setState('sync')
765 iSoftwareTools.lastDownloadDate = time()
766 for entry in self.selectedFiles:
767 if entry == self.saved_currentSelectedPackage:
768 self.selectedFiles.remove(entry)
769 iSoftwareTools.startIpkgListInstalled(self.rebuildList)
771 def buildEntryComponent(self, name, details, description, packagename, state, selected = False):
772 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
773 installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installed.png"))
774 installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installable.png"))
775 removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
776 installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/install.png"))
777 if state == 'installed':
778 return((name, details, description, packagename, state, installedpng, divpng, selected))
779 elif state == 'installable':
780 return((name, details, description, packagename, state, installablepng, divpng, selected))
781 elif state == 'remove':
782 return((name, details, description, packagename, state, removepng, divpng, selected))
783 elif state == 'install':
784 return((name, details, description, packagename, state, installpng, divpng, selected))
786 def buildPacketList(self, categorytag = None):
787 if categorytag is not None:
788 self.currList = "packages"
789 self.currentSelectedTag = categorytag
791 for package in iSoftwareTools.packagesIndexlist[:]:
792 prerequisites = package[0]["prerequisites"]
793 if prerequisites.has_key("tag"):
794 for foundtag in prerequisites["tag"]:
795 if categorytag == foundtag:
796 attributes = package[0]["attributes"]
797 if attributes.has_key("packagetype"):
798 if attributes["packagetype"] == "internal":
800 self.packetlist.append([attributes["name"], attributes["details"], attributes["shortdescription"], attributes["packagename"]])
802 self.packetlist.append([attributes["name"], attributes["details"], attributes["shortdescription"], attributes["packagename"]])
804 for x in self.packetlist:
807 details = x[1].strip()
808 description = x[2].strip()
809 packagename = x[3].strip()
810 selectState = self.getSelectionState(details)
811 if iSoftwareTools.installed_packetlist.has_key(packagename):
812 if selectState == True:
816 self.list.append(self.buildEntryComponent(name, _(details), _(description), packagename, status, selected = selectState))
818 if selectState == True:
821 status = "installable"
822 self.list.append(self.buildEntryComponent(name, _(details), _(description), packagename, status, selected = selectState))
824 self.list.sort(key=lambda x: x[0])
825 self["list"].style = "default"
826 self['list'].setList(self.list)
827 self["list"].updateList(self.list)
828 self.selectionChanged()
830 def buildCategoryList(self):
831 self.currList = "category"
833 self.categoryList = []
834 for package in iSoftwareTools.packagesIndexlist[:]:
835 prerequisites = package[0]["prerequisites"]
836 if prerequisites.has_key("tag"):
837 for foundtag in prerequisites["tag"]:
838 attributes = package[0]["attributes"]
839 if foundtag not in self.categories:
840 self.categories.append(foundtag)
841 self.categoryList.append(self.buildCategoryComponent(foundtag))
842 self.categoryList.sort(key=lambda x: x[0])
843 self["list"].style = "category"
844 self['list'].setList(self.categoryList)
845 self["list"].updateList(self.categoryList)
846 self.selectionChanged()
848 def buildCategoryComponent(self, tag = None):
849 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
852 return(( _("System"), _("View list of available system extensions" ), tag, divpng ))
854 return(( _("Skins"), _("View list of available skins" ), tag, divpng ))
855 elif tag == 'Recording':
856 return(( _("Recordings"), _("View list of available recording extensions" ), tag, divpng ))
857 elif tag == 'Network':
858 return(( _("Network"), _("View list of available networking extensions" ), tag, divpng ))
860 return(( _("CommonInterface"), _("View list of available CommonInterface extensions" ), tag, divpng ))
861 elif tag == 'Default':
862 return(( _("Default Settings"), _("View list of available default settings" ), tag, divpng ))
864 return(( _("Satellite equipment"), _("View list of available Satellite equipment extensions." ), tag, divpng ))
865 elif tag == 'Software':
866 return(( _("Software"), _("View list of available software extensions" ), tag, divpng ))
867 elif tag == 'Multimedia':
868 return(( _("Multimedia"), _("View list of available multimedia extensions." ), tag, divpng ))
869 elif tag == 'Display':
870 return(( _("Display and Userinterface"), _("View list of available Display and Userinterface extensions." ), tag, divpng ))
872 return(( _("Electronic Program Guide"), _("View list of available EPG extensions." ), tag, divpng ))
873 elif tag == 'Communication':
874 return(( _("Communication"), _("View list of available communication extensions." ), tag, divpng ))
875 else: # dynamically generate non existent tags
876 return(( str(tag), _("View list of available ") + str(tag) + _(" extensions." ), tag, divpng ))
878 def prepareInstall(self):
880 if iSoftwareTools.available_updates > 0:
881 self.cmdList.append((IpkgComponent.CMD_UPGRADE, { "test_only": False }))
882 if self.selectedFiles and len(self.selectedFiles):
883 for plugin in self.selectedFiles:
884 detailsfile = iSoftwareTools.directory[0] + "/" + plugin[0]
885 if (os_path.exists(detailsfile) == True):
886 iSoftwareTools.fillPackageDetails(plugin[0])
887 self.package = iSoftwareTools.packageDetails[0]
888 if self.package[0].has_key("attributes"):
889 self.attributes = self.package[0]["attributes"]
890 if self.attributes.has_key("package"):
891 self.packagefiles = self.attributes["package"]
892 if plugin[1] == 'installed':
893 if self.packagefiles:
894 for package in self.packagefiles[:]:
895 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": package["name"] }))
897 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": plugin[2] }))
899 if self.packagefiles:
900 for package in self.packagefiles[:]:
901 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package["name"] }))
903 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": plugin[2] }))
905 if plugin[1] == 'installed':
906 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": plugin[2] }))
908 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": plugin[2] }))
910 def runExecute(self, result = None):
911 if result is not None:
912 if result[0] is True:
913 self.session.openWithCallback(self.runExecuteFinished, Ipkg, cmdList = self.cmdList)
914 elif result[0] is False:
915 self.cmdList = result[1]
916 self.session.openWithCallback(self.runExecuteFinished, Ipkg, cmdList = self.cmdList)
920 def runExecuteFinished(self):
921 self.session.openWithCallback(self.ExecuteReboot, MessageBox, _("Install or remove finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
923 def ExecuteReboot(self, result):
927 self.reloadPluginlist()
928 self.selectedFiles = []
929 self.detailsClosed(True)
933 def reloadPluginlist(self):
934 plugins.readPluginList(resolveFilename(SCOPE_PLUGINS))
937 class PluginManagerInfo(Screen):
939 <screen name="PluginManagerInfo" position="center,center" size="560,450" title="Plugin manager activity information" >
940 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
941 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
942 <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" />
943 <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" />
944 <widget source="list" render="Listbox" position="5,50" size="550,350" scrollbarMode="showOnDemand" selectionDisabled="1">
945 <convert type="TemplatedMultiContent">
947 MultiContentEntryText(pos = (50, 0), size = (150, 26), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
948 MultiContentEntryText(pos = (50, 27), size = (540, 23), font=1, flags = RT_HALIGN_LEFT, text = 1), # index 1 is the state
949 MultiContentEntryPixmapAlphaTest(pos = (0, 1), size = (48, 48), png = 2), # index 2 is the status pixmap
950 MultiContentEntryPixmapAlphaTest(pos = (0, 48), size = (550, 2), png = 3), # index 3 is the div pixmap
952 "fonts": [gFont("Regular", 24),gFont("Regular", 22)],
957 <ePixmap pixmap="skin_default/div-h.png" position="0,404" zPosition="10" size="560,2" transparent="1" alphatest="on" />
958 <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" />
961 def __init__(self, session, plugin_path, cmdlist = None):
962 Screen.__init__(self, session)
963 self.session = session
964 self.skin_path = plugin_path
965 self.cmdlist = cmdlist
967 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"],
969 "ok": self.process_all,
972 "green": self.process_extensions,
976 self["list"] = List(self.list)
977 self["key_red"] = StaticText(_("Cancel"))
978 self["key_green"] = StaticText(_("Only extensions."))
979 self["status"] = StaticText(_("Following tasks will be done after you press OK!"))
981 self.onShown.append(self.setWindowTitle)
982 self.onLayoutFinish.append(self.rebuildList)
984 def setWindowTitle(self):
985 self.setTitle(_("Plugin manager activity information"))
987 def rebuildList(self):
989 if self.cmdlist is not None:
990 for entry in self.cmdlist:
1002 info = args['package']
1004 info = args['package']
1006 info = _("Dreambox software because updates are available.")
1008 self.list.append(self.buildEntryComponent(action,info))
1009 self['list'].setList(self.list)
1010 self['list'].updateList(self.list)
1012 def buildEntryComponent(self, action,info):
1013 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
1014 upgradepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgrade.png"))
1015 installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/install.png"))
1016 removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
1017 if action == 'install':
1018 return(( _('Installing'), info, installpng, divpng))
1019 elif action == 'remove':
1020 return(( _('Removing'), info, removepng, divpng))
1022 return(( _('Upgrading'), info, upgradepng, divpng))
1027 def process_all(self):
1028 self.close((True,None))
1030 def process_extensions(self):
1032 if self.cmdlist is not None:
1033 for entry in self.cmdlist:
1035 if entry[0] in (0,2):
1036 self.list.append((entry))
1037 self.close((False,self.list))
1040 class PluginManagerHelp(Screen):
1042 <screen name="PluginManagerHelp" position="center,center" size="560,450" title="Plugin manager help" >
1043 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1044 <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" />
1045 <widget source="list" render="Listbox" position="5,50" size="550,350" scrollbarMode="showOnDemand" selectionDisabled="1">
1046 <convert type="TemplatedMultiContent">
1048 MultiContentEntryText(pos = (50, 0), size = (540, 26), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
1049 MultiContentEntryText(pos = (50, 27), size = (540, 23), font=1, flags = RT_HALIGN_LEFT, text = 1), # index 1 is the state
1050 MultiContentEntryPixmapAlphaTest(pos = (0, 1), size = (48, 48), png = 2), # index 2 is the status pixmap
1051 MultiContentEntryPixmapAlphaTest(pos = (0, 48), size = (550, 2), png = 3), # index 3 is the div pixmap
1053 "fonts": [gFont("Regular", 24),gFont("Regular", 22)],
1058 <ePixmap pixmap="skin_default/div-h.png" position="0,404" zPosition="10" size="560,2" transparent="1" alphatest="on" />
1059 <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" />
1062 def __init__(self, session, plugin_path):
1063 Screen.__init__(self, session)
1064 self.session = session
1065 self.skin_path = plugin_path
1067 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"],
1074 self["list"] = List(self.list)
1075 self["key_red"] = StaticText(_("Close"))
1076 self["status"] = StaticText(_("A small overview of the available icon states and actions."))
1078 self.onShown.append(self.setWindowTitle)
1079 self.onLayoutFinish.append(self.rebuildList)
1081 def setWindowTitle(self):
1082 self.setTitle(_("Plugin manager help"))
1084 def rebuildList(self):
1086 self.list.append(self.buildEntryComponent('install'))
1087 self.list.append(self.buildEntryComponent('installable'))
1088 self.list.append(self.buildEntryComponent('installed'))
1089 self.list.append(self.buildEntryComponent('remove'))
1090 self['list'].setList(self.list)
1091 self['list'].updateList(self.list)
1093 def buildEntryComponent(self, state):
1094 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
1095 installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installed.png"))
1096 installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installable.png"))
1097 removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
1098 installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/install.png"))
1100 if state == 'installed':
1101 return(( _('This plugin is installed.'), _('You can remove this plugin.'), installedpng, divpng))
1102 elif state == 'installable':
1103 return(( _('This plugin is not installed.'), _('You can install this plugin.'), installablepng, divpng))
1104 elif state == 'install':
1105 return(( _('This plugin will be installed.'), _('You can cancel the installation.'), installpng, divpng))
1106 elif state == 'remove':
1107 return(( _('This plugin will be removed.'), _('You can cancel the removal.'), removepng, divpng))
1113 class PluginDetails(Screen, DreamInfoHandler):
1115 <screen name="PluginDetails" position="center,center" size="600,440" title="Plugin details" >
1116 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1117 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1118 <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" />
1119 <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" />
1120 <widget source="author" render="Label" position="10,50" size="500,25" zPosition="10" font="Regular;21" transparent="1" />
1121 <widget name="statuspic" position="550,40" size="48,48" alphatest="on"/>
1122 <widget name="divpic" position="0,80" size="600,2" alphatest="on"/>
1123 <widget name="detailtext" position="10,90" size="270,330" zPosition="10" font="Regular;21" transparent="1" halign="left" valign="top"/>
1124 <widget name="screenshot" position="290,90" size="300,330" alphatest="on"/>
1126 def __init__(self, session, plugin_path, packagedata = None):
1127 Screen.__init__(self, session)
1128 self.skin_path = plugin_path
1129 self.language = language.getLanguage()[:2] # getLanguage returns e.g. "fi_FI" for "language_country"
1130 self.attributes = None
1131 DreamInfoHandler.__init__(self, self.statusCallback, blocking = False)
1132 self.directory = resolveFilename(SCOPE_METADIR)
1134 self.pluginname = packagedata[0]
1135 self.details = packagedata[1]
1136 self.pluginstate = packagedata[4]
1137 self.statuspicinstance = packagedata[5]
1138 self.divpicinstance = packagedata[6]
1139 self.fillPackageDetails(self.details)
1143 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"],
1149 "down": self.pageDown,
1150 "left": self.pageUp,
1151 "right": self.pageDown,
1154 self["key_red"] = StaticText(_("Close"))
1155 self["key_green"] = StaticText("")
1156 self["author"] = StaticText()
1157 self["statuspic"] = Pixmap()
1158 self["divpic"] = Pixmap()
1159 self["screenshot"] = Pixmap()
1160 self["detailtext"] = ScrollLabel()
1162 self["statuspic"].hide()
1163 self["screenshot"].hide()
1164 self["divpic"].hide()
1166 self.package = self.packageDetails[0]
1167 if self.package[0].has_key("attributes"):
1168 self.attributes = self.package[0]["attributes"]
1171 self.oktext = _("\nAfter pressing OK, please wait!")
1172 self.picload = ePicLoad()
1173 self.picload.PictureData.get().append(self.paintScreenshotPixmapCB)
1174 self.onShown.append(self.setWindowTitle)
1175 self.onLayoutFinish.append(self.setInfos)
1177 def setWindowTitle(self):
1178 self.setTitle(_("Details for plugin: ") + self.pluginname )
1184 self["detailtext"].pageUp()
1187 self["detailtext"].pageDown()
1189 def statusCallback(self, status, progress):
1193 if self.attributes.has_key("screenshot"):
1194 self.loadThumbnail(self.attributes)
1196 if self.attributes.has_key("name"):
1197 self.pluginname = self.attributes["name"]
1199 self.pluginname = _("unknown")
1201 if self.attributes.has_key("author"):
1202 self.author = self.attributes["author"]
1204 self.author = _("unknown")
1206 if self.attributes.has_key("description"):
1207 self.description = _(self.attributes["description"].replace("\\n", "\n"))
1209 self.description = _("No description available.")
1211 self["author"].setText(_("Author: ") + self.author)
1212 self["detailtext"].setText(_(self.description))
1213 if self.pluginstate in ('installable', 'install'):
1214 if iSoftwareTools.NetworkConnectionAvailable:
1215 self["key_green"].setText(_("Install"))
1217 self["key_green"].setText("")
1219 self["key_green"].setText(_("Remove"))
1221 def loadThumbnail(self, entry):
1223 if entry.has_key("screenshot"):
1224 thumbnailUrl = entry["screenshot"]
1225 if self.language == "de":
1226 if thumbnailUrl[-7:] == "_en.jpg":
1227 thumbnailUrl = thumbnailUrl[:-7] + "_de.jpg"
1229 if thumbnailUrl is not None:
1230 self.thumbnail = "/tmp/" + thumbnailUrl.split('/')[-1]
1231 print "[PluginDetails] downloading screenshot " + thumbnailUrl + " to " + self.thumbnail
1232 if iSoftwareTools.NetworkConnectionAvailable:
1233 client.downloadPage(thumbnailUrl,self.thumbnail).addCallback(self.setThumbnail).addErrback(self.fetchFailed)
1235 self.setThumbnail(noScreenshot = True)
1237 self.setThumbnail(noScreenshot = True)
1239 def setThumbnail(self, noScreenshot = False):
1240 if not noScreenshot:
1241 filename = self.thumbnail
1243 filename = resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/noprev.png")
1245 sc = AVSwitch().getFramebufferScale()
1246 self.picload.setPara((self["screenshot"].instance.size().width(), self["screenshot"].instance.size().height(), sc[0], sc[1], False, 1, "#00000000"))
1247 self.picload.startDecode(filename)
1249 if self.statuspicinstance != None:
1250 self["statuspic"].instance.setPixmap(self.statuspicinstance.__deref__())
1251 self["statuspic"].show()
1252 if self.divpicinstance != None:
1253 self["divpic"].instance.setPixmap(self.divpicinstance.__deref__())
1254 self["divpic"].show()
1256 def paintScreenshotPixmapCB(self, picInfo=None):
1257 ptr = self.picload.getData()
1259 self["screenshot"].instance.setPixmap(ptr.__deref__())
1260 self["screenshot"].show()
1262 self.setThumbnail(noScreenshot = True)
1265 if self.attributes.has_key("package"):
1266 self.packagefiles = self.attributes["package"]
1268 if self.pluginstate in ('installed', 'remove'):
1269 if self.packagefiles:
1270 for package in self.packagefiles[:]:
1271 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": package["name"] }))
1272 if len(self.cmdList):
1273 self.session.openWithCallback(self.runRemove, MessageBox, _("Do you want to remove the package:\n") + self.pluginname + "\n" + self.oktext)
1275 if iSoftwareTools.NetworkConnectionAvailable:
1276 if self.packagefiles:
1277 for package in self.packagefiles[:]:
1278 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package["name"] }))
1279 if len(self.cmdList):
1280 self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to install the package:\n") + self.pluginname + "\n" + self.oktext)
1282 def runUpgrade(self, result):
1284 self.session.openWithCallback(self.runUpgradeFinished, Ipkg, cmdList = self.cmdList)
1286 def runUpgradeFinished(self):
1287 self.session.openWithCallback(self.UpgradeReboot, MessageBox, _("Installation finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
1289 def UpgradeReboot(self, result):
1297 def runRemove(self, result):
1299 self.session.openWithCallback(self.runRemoveFinished, Ipkg, cmdList = self.cmdList)
1301 def runRemoveFinished(self):
1302 self.session.openWithCallback(self.RemoveReboot, MessageBox, _("Remove finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
1304 def RemoveReboot(self, result):
1312 def reloadPluginlist(self):
1313 plugins.readPluginList(resolveFilename(SCOPE_PLUGINS))
1315 def fetchFailed(self,string):
1316 self.setThumbnail(noScreenshot = True)
1317 print "[PluginDetails] fetch failed " + string.getErrorMessage()
1320 class UpdatePlugin(Screen):
1322 <screen name="UpdatePlugin" position="center,center" size="550,300" title="Software update" >
1323 <widget name="activityslider" position="0,0" size="550,5" />
1324 <widget name="slider" position="0,150" size="550,30" />
1325 <widget source="package" render="Label" position="10,30" size="540,20" font="Regular;18" halign="center" valign="center" backgroundColor="#25062748" transparent="1" />
1326 <widget source="status" render="Label" position="10,180" size="540,100" font="Regular;20" halign="center" valign="center" backgroundColor="#25062748" transparent="1" />
1329 def __init__(self, session, args = None):
1330 Screen.__init__(self, session)
1332 self.sliderPackages = { "dreambox-dvb-modules": 1, "enigma2": 2, "tuxbox-image-info": 3 }
1334 self.slider = Slider(0, 4)
1335 self["slider"] = self.slider
1336 self.activityslider = Slider(0, 100)
1337 self["activityslider"] = self.activityslider
1338 self.status = StaticText(_("Please wait..."))
1339 self["status"] = self.status
1340 self.package = StaticText(_("Verifying your internet connection..."))
1341 self["package"] = self.package
1342 self.oktext = _("Press OK on your remote control to continue.")
1346 self.processed_packages = []
1349 self.activityTimer = eTimer()
1350 self.activityTimer.callback.append(self.doActivityTimer)
1352 self.ipkg = IpkgComponent()
1353 self.ipkg.addCallback(self.ipkgCallback)
1355 self.updating = False
1357 self["actions"] = ActionMap(["WizardActions"],
1363 iNetwork.checkNetworkState(self.checkNetworkCB)
1364 self.onClose.append(self.cleanup)
1367 iNetwork.stopPingConsole()
1369 def checkNetworkCB(self,data):
1370 if data is not None:
1372 self.updating = True
1373 self.activityTimer.start(100, False)
1374 self.package.setText(_("Package list update"))
1375 self.status.setText(_("Upgrading Dreambox... Please wait"))
1376 self.ipkg.startCmd(IpkgComponent.CMD_UPDATE)
1378 self.package.setText(_("Your network is not working. Please try again."))
1379 self.status.setText(self.oktext)
1381 def doActivityTimer(self):
1383 if self.activity == 100:
1385 self.activityslider.setValue(self.activity)
1387 def ipkgCallback(self, event, param):
1388 if event == IpkgComponent.EVENT_DOWNLOAD:
1389 self.status.setText(_("Downloading"))
1390 elif event == IpkgComponent.EVENT_UPGRADE:
1391 if self.sliderPackages.has_key(param):
1392 self.slider.setValue(self.sliderPackages[param])
1393 self.package.setText(param)
1394 self.status.setText(_("Upgrading"))
1395 if not param in self.processed_packages:
1396 self.processed_packages.append(param)
1398 elif event == IpkgComponent.EVENT_INSTALL:
1399 self.package.setText(param)
1400 self.status.setText(_("Installing"))
1401 if not param in self.processed_packages:
1402 self.processed_packages.append(param)
1404 elif event == IpkgComponent.EVENT_REMOVE:
1405 self.package.setText(param)
1406 self.status.setText(_("Removing"))
1407 if not param in self.processed_packages:
1408 self.processed_packages.append(param)
1410 elif event == IpkgComponent.EVENT_CONFIGURING:
1411 self.package.setText(param)
1412 self.status.setText(_("Configuring"))
1414 elif event == IpkgComponent.EVENT_MODIFIED:
1415 if config.plugins.SoftwareManager.overwriteConfigFiles.value in ("N", "Y"):
1416 self.ipkg.write(True and config.plugins.SoftwareManager.overwriteConfigFiles.value)
1418 self.session.openWithCallback(
1419 self.modificationCallback,
1421 _("A configuration file (%s) was modified since Installation.\nDo you want to keep your version?") % (param)
1423 elif event == IpkgComponent.EVENT_ERROR:
1425 elif event == IpkgComponent.EVENT_DONE:
1427 self.updating = False
1428 self.ipkg.startCmd(IpkgComponent.CMD_UPGRADE, args = {'test_only': False})
1429 elif self.error == 0:
1430 self.slider.setValue(4)
1432 self.activityTimer.stop()
1433 self.activityslider.setValue(0)
1435 self.package.setText(_("Done - Installed or upgraded %d packages") % self.packages)
1436 self.status.setText(self.oktext)
1438 self.activityTimer.stop()
1439 self.activityslider.setValue(0)
1440 error = _("your dreambox might be unusable now. Please consult the manual for further assistance before rebooting your dreambox.")
1441 if self.packages == 0:
1442 error = _("No packages were upgraded yet. So you can check your network and try again.")
1444 error = _("Your dreambox isn't connected to the internet properly. Please check it and try again.")
1445 self.status.setText(_("Error") + " - " + error)
1446 #print event, "-", param
1449 def modificationCallback(self, res):
1450 self.ipkg.write(res and "N" or "Y")
1453 if not self.ipkg.isRunning():
1454 if self.packages != 0 and self.error == 0:
1455 self.session.openWithCallback(self.exitAnswer, MessageBox, _("Upgrade finished.") +" "+_("Do you want to reboot your Dreambox?"))
1459 if not self.updating:
1462 def exitAnswer(self, result):
1463 if result is not None and result:
1469 class IPKGMenu(Screen):
1471 <screen name="IPKGMenu" position="center,center" size="560,400" title="Select upgrade source to edit." >
1472 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1473 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1474 <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" />
1475 <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" />
1476 <widget name="filelist" position="5,50" size="550,340" scrollbarMode="showOnDemand" />
1479 def __init__(self, session, plugin_path):
1480 Screen.__init__(self, session)
1481 self.skin_path = plugin_path
1483 self["key_red"] = StaticText(_("Close"))
1484 self["key_green"] = StaticText(_("Edit"))
1493 self["actions"] = NumberActionMap(["SetupActions"],
1496 "cancel": self.keyCancel
1499 self["shortcuts"] = ActionMap(["ShortcutActions"],
1501 "red": self.keyCancel,
1502 "green": self.KeyOk,
1505 self["filelist"] = MenuList(self.flist)
1507 self.onLayoutFinish.append(self.layoutFinished)
1509 def layoutFinished(self):
1510 self.setWindowTitle()
1512 def setWindowTitle(self):
1513 self.setTitle(_("Select upgrade source to edit."))
1515 def fill_list(self):
1517 self.path = '/etc/ipkg/'
1518 if (os_path.exists(self.path) == False):
1521 for file in listdir(self.path):
1522 if (file.endswith(".conf")):
1523 if file != 'arch.conf':
1524 self.flist.append((file))
1526 self["filelist"].l.setList(self.flist)
1529 if (self.exe == False) and (self.entry == True):
1530 self.sel = self["filelist"].getCurrent()
1531 self.val = self.path + self.sel
1532 self.session.open(IPKGSource, self.val)
1534 def keyCancel(self):
1541 class IPKGSource(Screen):
1543 <screen name="IPKGSource" position="center,center" size="560,80" title="Edit upgrade source url." >
1544 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1545 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1546 <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" />
1547 <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" />
1548 <widget name="text" position="5,50" size="550,25" font="Regular;20" backgroundColor="background" foregroundColor="#cccccc" />
1551 def __init__(self, session, configfile = None):
1552 Screen.__init__(self, session)
1553 self.session = session
1554 self.configfile = configfile
1558 fp = file(configfile, 'r')
1559 sources = fp.readlines()
1566 desk = getDesktop(0)
1567 x= int(desk.size().width())
1568 y= int(desk.size().height())
1570 self["key_red"] = StaticText(_("Cancel"))
1571 self["key_green"] = StaticText(_("Save"))
1574 self["text"] = Input(text, maxSize=False, type=Input.TEXT)
1576 self["text"] = Input(text, maxSize=False, visible_width = 55, type=Input.TEXT)
1578 self["actions"] = NumberActionMap(["WizardActions", "InputActions", "TextEntryActions", "KeyboardInputActions","ShortcutActions"],
1584 "left": self.keyLeft,
1585 "right": self.keyRight,
1586 "home": self.keyHome,
1588 "deleteForward": self.keyDeleteForward,
1589 "deleteBackward": self.keyDeleteBackward,
1590 "1": self.keyNumberGlobal,
1591 "2": self.keyNumberGlobal,
1592 "3": self.keyNumberGlobal,
1593 "4": self.keyNumberGlobal,
1594 "5": self.keyNumberGlobal,
1595 "6": self.keyNumberGlobal,
1596 "7": self.keyNumberGlobal,
1597 "8": self.keyNumberGlobal,
1598 "9": self.keyNumberGlobal,
1599 "0": self.keyNumberGlobal
1602 self.onLayoutFinish.append(self.layoutFinished)
1604 def layoutFinished(self):
1605 self.setWindowTitle()
1606 self["text"].right()
1608 def setWindowTitle(self):
1609 self.setTitle(_("Edit upgrade source url."))
1612 text = self["text"].getText()
1614 fp = file(self.configfile, 'w')
1624 self["text"].right()
1632 def keyDeleteForward(self):
1633 self["text"].delete()
1635 def keyDeleteBackward(self):
1636 self["text"].deleteBackward()
1638 def keyNumberGlobal(self, number):
1639 self["text"].number(number)
1642 class PacketManager(Screen, NumericalTextInput):
1644 <screen name="PacketManager" position="center,center" size="530,420" title="Packet manager" >
1645 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1646 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1647 <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" />
1648 <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" />
1649 <widget source="list" render="Listbox" position="5,50" size="520,365" scrollbarMode="showOnDemand">
1650 <convert type="TemplatedMultiContent">
1652 MultiContentEntryText(pos = (5, 1), size = (440, 28), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
1653 MultiContentEntryText(pos = (5, 26), size = (440, 20), font=1, flags = RT_HALIGN_LEFT, text = 2), # index 2 is the description
1654 MultiContentEntryPixmapAlphaTest(pos = (445, 2), size = (48, 48), png = 4), # index 4 is the status pixmap
1655 MultiContentEntryPixmapAlphaTest(pos = (5, 50), size = (510, 2), png = 5), # index 4 is the div pixmap
1657 "fonts": [gFont("Regular", 22),gFont("Regular", 14)],
1664 def __init__(self, session, plugin_path, args = None):
1665 Screen.__init__(self, session)
1666 NumericalTextInput.__init__(self)
1667 self.session = session
1668 self.skin_path = plugin_path
1670 self.setUseableChars(u'1234567890abcdefghijklmnopqrstuvwxyz')
1672 self["shortcuts"] = NumberActionMap(["ShortcutActions", "WizardActions", "NumberActions", "InputActions", "InputAsciiActions", "KeyboardInputActions" ],
1677 "green": self.reload,
1678 "gotAsciiCode": self.keyGotAscii,
1679 "1": self.keyNumberGlobal,
1680 "2": self.keyNumberGlobal,
1681 "3": self.keyNumberGlobal,
1682 "4": self.keyNumberGlobal,
1683 "5": self.keyNumberGlobal,
1684 "6": self.keyNumberGlobal,
1685 "7": self.keyNumberGlobal,
1686 "8": self.keyNumberGlobal,
1687 "9": self.keyNumberGlobal,
1688 "0": self.keyNumberGlobal
1692 self.statuslist = []
1693 self["list"] = List(self.list)
1694 self["key_red"] = StaticText(_("Close"))
1695 self["key_green"] = StaticText(_("Reload"))
1697 self.list_updating = True
1698 self.packetlist = []
1699 self.installed_packetlist = {}
1700 self.upgradeable_packages = {}
1701 self.Console = Console()
1704 self.cache_ttl = 86400 #600 is default, 0 disables, Seconds cache is considered valid (24h should be ok for caching ipkgs)
1705 self.cache_file = '/usr/lib/enigma2/python/Plugins/SystemPlugins/SoftwareManager/packetmanager.cache' #Path to cache directory
1706 self.oktext = _("\nAfter pressing OK, please wait!")
1707 self.unwanted_extensions = ('-dbg', '-dev', '-doc', 'busybox')
1708 self.opkgAvail = fileExists('/usr/bin/opkg')
1710 self.ipkg = IpkgComponent()
1711 self.ipkg.addCallback(self.ipkgCallback)
1712 self.onShown.append(self.setWindowTitle)
1713 self.onLayoutFinish.append(self.rebuildList)
1715 rcinput = eRCInput.getInstance()
1716 rcinput.setKeyboardMode(rcinput.kmAscii)
1718 def keyNumberGlobal(self, val):
1719 key = self.getKey(val)
1721 keyvalue = key.encode("utf-8")
1722 if len(keyvalue) == 1:
1723 self.setNextIdx(keyvalue[0])
1725 def keyGotAscii(self):
1726 keyvalue = unichr(getPrevAsciiCode()).encode("utf-8")
1727 if len(keyvalue) == 1:
1728 self.setNextIdx(keyvalue[0])
1730 def setNextIdx(self,char):
1731 if char in ("0", "1", "a"):
1732 self["list"].setIndex(0)
1734 idx = self.getNextIdx(char)
1735 if idx and idx <= self["list"].count:
1736 self["list"].setIndex(idx)
1738 def getNextIdx(self,char):
1740 for i in self["list"].list:
1747 if self.Console is not None:
1748 if len(self.Console.appContainers):
1749 for name in self.Console.appContainers.keys():
1750 self.Console.kill(name)
1751 rcinput = eRCInput.getInstance()
1752 rcinput.setKeyboardMode(rcinput.kmNone)
1756 if (os_path.exists(self.cache_file) == True):
1757 remove(self.cache_file)
1758 self.list_updating = True
1761 def setWindowTitle(self):
1762 self.setTitle(_("Packet manager"))
1764 def setStatus(self,status = None):
1766 self.statuslist = []
1767 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
1768 if status == 'update':
1769 statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgrade.png"))
1770 self.statuslist.append(( _("Package list update"), '', _("Trying to download a new packetlist. Please wait..." ),'',statuspng, divpng ))
1771 self['list'].setList(self.statuslist)
1772 elif status == 'error':
1773 statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
1774 self.statuslist.append(( _("Error"), '', _("There was an error downloading the packetlist. Please try again." ),'',statuspng, divpng ))
1775 self['list'].setList(self.statuslist)
1777 def rebuildList(self):
1778 self.setStatus('update')
1780 self.vc = valid_cache(self.cache_file, self.cache_ttl)
1781 if self.cache_ttl > 0 and self.vc != 0:
1783 self.buildPacketList()
1786 if self.cache_ttl == 0 or self.inv_cache == 1 or self.vc == 0:
1788 self.ipkg.startCmd(IpkgComponent.CMD_UPDATE)
1790 def go(self, returnValue = None):
1791 cur = self["list"].getCurrent()
1796 if status == 'installed':
1797 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": package }))
1798 if len(self.cmdList):
1799 self.session.openWithCallback(self.runRemove, MessageBox, _("Do you want to remove the package:\n") + package + "\n" + self.oktext)
1800 elif status == 'upgradeable':
1801 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package }))
1802 if len(self.cmdList):
1803 self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to upgrade the package:\n") + package + "\n" + self.oktext)
1804 elif status == "installable":
1805 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package }))
1806 if len(self.cmdList):
1807 self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to install the package:\n") + package + "\n" + self.oktext)
1809 def runRemove(self, result):
1811 self.session.openWithCallback(self.runRemoveFinished, Ipkg, cmdList = self.cmdList)
1813 def runRemoveFinished(self):
1814 self.session.openWithCallback(self.RemoveReboot, MessageBox, _("Remove finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
1816 def RemoveReboot(self, result):
1820 cur = self["list"].getCurrent()
1822 item = self['list'].getIndex()
1823 self.list[item] = self.buildEntryComponent(cur[0], cur[1], cur[2], 'installable')
1824 self.cachelist[item] = [cur[0], cur[1], cur[2], 'installable']
1825 self['list'].setList(self.list)
1826 write_cache(self.cache_file, self.cachelist)
1827 self.reloadPluginlist()
1831 def runUpgrade(self, result):
1833 self.session.openWithCallback(self.runUpgradeFinished, Ipkg, cmdList = self.cmdList)
1835 def runUpgradeFinished(self):
1836 self.session.openWithCallback(self.UpgradeReboot, MessageBox, _("Upgrade finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
1838 def UpgradeReboot(self, result):
1842 cur = self["list"].getCurrent()
1844 item = self['list'].getIndex()
1845 self.list[item] = self.buildEntryComponent(cur[0], cur[1], cur[2], 'installed')
1846 self.cachelist[item] = [cur[0], cur[1], cur[2], 'installed']
1847 self['list'].setList(self.list)
1848 write_cache(self.cache_file, self.cachelist)
1849 self.reloadPluginlist()
1853 def ipkgCallback(self, event, param):
1854 if event == IpkgComponent.EVENT_ERROR:
1855 self.list_updating = False
1856 self.setStatus('error')
1857 elif event == IpkgComponent.EVENT_DONE:
1858 if self.list_updating:
1859 self.list_updating = False
1860 if not self.Console:
1861 self.Console = Console()
1863 self.Console.ePopen(cmd, self.IpkgList_Finished)
1864 #print event, "-", param
1867 def IpkgList_Finished(self, result, retval, extra_args = None):
1869 self.packetlist = []
1871 for x in result.splitlines():
1872 tokens = x.split(' - ')
1873 name = tokens[0].strip()
1874 if not any(name.endswith(x) for x in self.unwanted_extensions):
1876 version = l > 1 and tokens[1].strip() or ""
1877 descr = l > 2 and tokens[2].strip() or ""
1878 if name == last_name:
1881 self.packetlist.append([name, version, descr])
1883 if not self.Console:
1884 self.Console = Console()
1885 cmd = "ipkg list_installed"
1886 self.Console.ePopen(cmd, self.IpkgListInstalled_Finished)
1888 def IpkgListInstalled_Finished(self, result, retval, extra_args = None):
1890 self.installed_packetlist = {}
1891 for x in result.splitlines():
1892 tokens = x.split(' - ')
1893 name = tokens[0].strip()
1894 if not any(name.endswith(x) for x in self.unwanted_extensions):
1896 version = l > 1 and tokens[1].strip() or ""
1897 self.installed_packetlist[name] = version
1899 if not self.Console:
1900 self.Console = Console()
1901 cmd = "opkg list-upgradable"
1902 self.Console.ePopen(cmd, self.OpkgListUpgradeable_Finished)
1904 self.buildPacketList()
1906 def OpkgListUpgradeable_Finished(self, result, retval, extra_args = None):
1908 self.upgradeable_packages = {}
1909 for x in result.splitlines():
1910 tokens = x.split(' - ')
1911 name = tokens[0].strip()
1912 if not any(name.endswith(x) for x in self.unwanted_extensions):
1914 version = l > 2 and tokens[2].strip() or ""
1915 self.upgradeable_packages[name] = version
1916 self.buildPacketList()
1918 def buildEntryComponent(self, name, version, description, state):
1919 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
1920 if state == 'installed':
1921 installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installed.png"))
1922 return((name, version, _(description), state, installedpng, divpng))
1923 elif state == 'upgradeable':
1924 upgradeablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgradeable.png"))
1925 return((name, version, _(description), state, upgradeablepng, divpng))
1927 installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installable.png"))
1928 return((name, version, _(description), state, installablepng, divpng))
1930 def buildPacketList(self):
1933 if self.cache_ttl > 0 and self.vc != 0:
1934 print 'Loading packagelist cache from ',self.cache_file
1936 self.cachelist = load_cache(self.cache_file)
1937 if len(self.cachelist) > 0:
1938 for x in self.cachelist:
1939 self.list.append(self.buildEntryComponent(x[0], x[1], x[2], x[3]))
1940 self['list'].setList(self.list)
1944 if self.cache_ttl == 0 or self.inv_cache == 1 or self.vc == 0:
1945 print 'rebuilding fresh package list'
1946 for x in self.packetlist:
1948 if self.installed_packetlist.has_key(x[0]):
1950 if self.upgradeable_packages.has_key(x[0]):
1951 status = "upgradeable"
1953 status = "installed"
1955 if self.installed_packetlist[x[0]] == x[1]:
1956 status = "installed"
1958 status = "upgradeable"
1960 status = "installable"
1961 self.list.append(self.buildEntryComponent(x[0], x[1], x[2], status))
1962 self.cachelist.append([x[0], x[1], x[2], status])
1963 write_cache(self.cache_file, self.cachelist)
1964 self['list'].setList(self.list)
1966 def reloadPluginlist(self):
1967 plugins.readPluginList(resolveFilename(SCOPE_PLUGINS))
1970 class IpkgInstaller(Screen):
1972 <screen name="IpkgInstaller" position="center,center" size="550,450" title="Install extensions" >
1973 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1974 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1975 <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" />
1976 <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" />
1977 <widget name="list" position="5,50" size="540,360" />
1978 <ePixmap pixmap="skin_default/div-h.png" position="0,410" zPosition="10" size="560,2" transparent="1" alphatest="on" />
1979 <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" />
1982 def __init__(self, session, list):
1983 Screen.__init__(self, session)
1985 self.list = SelectionList()
1986 self["list"] = self.list
1987 for listindex in range(len(list)):
1988 self.list.addSelection(list[listindex], list[listindex], listindex, True)
1990 self["key_red"] = StaticText(_("Close"))
1991 self["key_green"] = StaticText(_("Install"))
1992 self["introduction"] = StaticText(_("Press OK to toggle the selection."))
1994 self["actions"] = ActionMap(["OkCancelActions", "ColorActions"],
1996 "ok": self.list.toggleSelection,
1997 "cancel": self.close,
1999 "green": self.install
2003 list = self.list.getSelectionsList()
2006 cmdList.append((IpkgComponent.CMD_INSTALL, { "package": item[1] }))
2007 self.session.open(Ipkg, cmdList = cmdList)
2010 def filescan_open(list, session, **kwargs):
2011 filelist = [x.path for x in list]
2012 session.open(IpkgInstaller, filelist) # list
2014 def filescan(**kwargs):
2015 from Components.Scanner import Scanner, ScanPath
2017 Scanner(mimetypes = ["application/x-debian-package"],
2020 ScanPath(path = "ipk", with_subdirs = True),
2021 ScanPath(path = "", with_subdirs = False),
2024 description = _("Install extensions."),
2025 openfnc = filescan_open, )
2029 def UpgradeMain(session, **kwargs):
2030 session.open(UpdatePluginMenu)
2032 def startSetup(menuid):
2033 if menuid != "setup":
2035 return [(_("Software management"), UpgradeMain, "software_manager", 50)]
2038 def Plugins(path, **kwargs):
2042 PluginDescriptor(name=_("Software management"), description=_("Manage your receiver's software"), where = PluginDescriptor.WHERE_MENU, fnc=startSetup),
2043 PluginDescriptor(name=_("Ipkg"), where = PluginDescriptor.WHERE_FILESCAN, fnc = filescan)
2045 if config.usage.setup_level.index >= 2: # expert+
2046 list.append(PluginDescriptor(name=_("Software management"), description=_("Manage your receiver's software"), where = PluginDescriptor.WHERE_EXTENSIONSMENU, fnc=UpgradeMain))