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
18 from Components.Console import Console
19 from Components.MultiContent import MultiContentEntryText, MultiContentEntryPixmapAlphaTest
20 from Components.SelectionList import SelectionList
21 from Components.PluginComponent import plugins
22 from Components.About import about
23 from Components.DreamInfoHandler import DreamInfoHandler
24 from Components.Language import language
25 from Components.AVSwitch import AVSwitch
26 from Components.Network import iNetwork
27 from Tools.Directories import pathExists, fileExists, resolveFilename, SCOPE_PLUGINS, SCOPE_CURRENT_PLUGIN, SCOPE_CURRENT_SKIN, SCOPE_METADIR
28 from Tools.LoadPixmap import LoadPixmap
29 from enigma import eTimer, quitMainloop, RT_HALIGN_LEFT, RT_VALIGN_CENTER, eListboxPythonMultiContent, eListbox, gFont, getDesktop, ePicLoad
30 from cPickle import dump, load
31 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
32 from time import time, gmtime, strftime, localtime
33 from stat import ST_MTIME
34 from datetime import date
35 from twisted.web import client
36 from twisted.internet import reactor
38 from ImageWizard import ImageWizard
39 from BackupRestore import BackupSelection, RestoreMenu, BackupScreen, RestoreScreen, getBackupPath, getBackupFilename
40 from SoftwareTools import iSoftwareTools
42 config.plugins.configurationbackup = ConfigSubsection()
43 config.plugins.configurationbackup.backuplocation = ConfigText(default = '/media/hdd/', visible_width = 50, fixed_size = False)
44 config.plugins.configurationbackup.backupdirs = ConfigLocations(default=['/etc/enigma2/', '/etc/network/interfaces', '/etc/wpa_supplicant.conf', '/etc/resolv.conf', '/etc/default_gw', '/etc/hostname'])
46 def write_cache(cache_file, cache_data):
48 if not os_path.isdir( os_path.dirname(cache_file) ):
50 mkdir( os_path.dirname(cache_file) )
52 print os_path.dirname(cache_file), 'is a file'
53 fd = open(cache_file, 'w')
54 dump(cache_data, fd, -1)
57 def valid_cache(cache_file, cache_ttl):
58 #See if the cache file exists and is still living
60 mtime = stat(cache_file)[ST_MTIME]
64 if (curr_time - mtime) > cache_ttl:
69 def load_cache(cache_file):
77 class UpdatePluginMenu(Screen):
79 <screen name="UpdatePluginMenu" position="center,center" size="610,410" title="Software management" >
80 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
81 <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" />
82 <ePixmap pixmap="skin_default/border_menu_350.png" position="5,50" zPosition="1" size="350,300" transparent="1" alphatest="on" />
83 <widget source="menu" render="Listbox" position="15,60" size="330,290" scrollbarMode="showOnDemand">
84 <convert type="TemplatedMultiContent">
86 MultiContentEntryText(pos = (2, 2), size = (330, 24), flags = RT_HALIGN_LEFT, text = 1), # index 0 is the MenuText,
88 "fonts": [gFont("Regular", 22)],
93 <widget source="menu" render="Listbox" position="360,50" size="240,300" scrollbarMode="showNever" selectionDisabled="1">
94 <convert type="TemplatedMultiContent">
96 MultiContentEntryText(pos = (2, 2), size = (240, 300), flags = RT_HALIGN_CENTER|RT_VALIGN_CENTER|RT_WRAP, text = 2), # index 2 is the Description,
98 "fonts": [gFont("Regular", 22)],
103 <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" />
106 def __init__(self, session, args = 0):
107 Screen.__init__(self, session)
108 self.skin_path = plugin_path
111 self.oktext = _("\nPress OK on your remote control to continue.")
113 self.backupdirs = ' '.join( config.plugins.configurationbackup.backupdirs.value )
115 self.list.append(("install-extensions", _("Manage extensions"), _("\nManage extensions or plugins for your Dreambox" ) + self.oktext, None))
116 self.list.append(("software-update", _("Software update"), _("\nOnline update of your Dreambox software." ) + self.oktext, None))
117 self.list.append(("software-restore", _("Software restore"), _("\nRestore your Dreambox with a new firmware." ) + self.oktext, None))
118 self.list.append(("system-backup", _("Backup system settings"), _("\nBackup your Dreambox settings." ) + self.oktext, None))
119 self.list.append(("system-restore",_("Restore system settings"), _("\nRestore your Dreambox settings." ) + self.oktext, None))
120 self.list.append(("ipkg-install", _("Install local extension"), _("\nScan for local extensions and install them." ) + self.oktext, None))
121 for p in plugins.getPlugins(PluginDescriptor.WHERE_SOFTWAREMANAGER):
122 if p.__call__.has_key("SoftwareSupported"):
123 callFnc = p.__call__["SoftwareSupported"](None)
124 if callFnc is not None:
125 if p.__call__.has_key("menuEntryName"):
126 menuEntryName = p.__call__["menuEntryName"](None)
128 menuEntryName = _('Extended Software')
129 if p.__call__.has_key("menuEntryDescription"):
130 menuEntryDescription = p.__call__["menuEntryDescription"](None)
132 menuEntryDescription = _('Extended Software Plugin')
133 self.list.append(('default-plugin', menuEntryName, menuEntryDescription + self.oktext, callFnc))
134 if config.usage.setup_level.index >= 2: # expert+
135 self.list.append(("advanced", _("Advanced Options"), _("\nAdvanced options and settings." ) + self.oktext, None))
137 self.list.append(("advancedrestore", _("Advanced restore"), _("\nRestore your backups by date." ) + self.oktext, None))
138 self.list.append(("backuplocation", _("Choose backup location"), _("\nSelect your backup device.\nCurrent device: " ) + config.plugins.configurationbackup.backuplocation.value + self.oktext, None))
139 self.list.append(("backupfiles", _("Choose backup files"), _("Select files for backup. Currently selected:\n" ) + self.backupdirs + self.oktext, None))
140 #if config.usage.setup_level.index >= 2: # expert+
141 # self.list.append(("ipkg-manager", _("Packet management"), _("\nView, install and remove available or installed packages." ) + self.oktext, None))
142 self.list.append(("ipkg-source",_("Choose upgrade source"), _("\nEdit the upgrade source address." ) + self.oktext, None))
143 for p in plugins.getPlugins(PluginDescriptor.WHERE_SOFTWAREMANAGER):
144 if p.__call__.has_key("AdvancedSoftwareSupported"):
145 callFnc = p.__call__["AdvancedSoftwareSupported"](None)
146 if callFnc is not None:
147 if p.__call__.has_key("menuEntryName"):
148 menuEntryName = p.__call__["menuEntryName"](None)
150 menuEntryName = _('Advanced Software')
151 if p.__call__.has_key("menuEntryDescription"):
152 menuEntryDescription = p.__call__["menuEntryDescription"](None)
154 menuEntryDescription = _('Advanced Software Plugin')
155 self.list.append(('advanced-plugin', menuEntryName, menuEntryDescription + self.oktext, callFnc))
157 self["menu"] = List(self.list)
158 self["key_red"] = StaticText(_("Close"))
159 self["status"] = StaticText("")
161 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions", "InfobarEPGActions"],
167 self.onLayoutFinish.append(self.layoutFinished)
168 self.backuppath = getBackupPath()
169 self.backupfile = getBackupFilename()
170 self.fullbackupfilename = self.backuppath + "/" + self.backupfile
171 self.onShown.append(self.setWindowTitle)
172 #self.onClose.append(self.cleanup)
174 def layoutFinished(self):
176 self["menu"].index = idx
177 #self.getUpdateInfos()
179 def setWindowTitle(self):
180 self.setTitle(_("Software management"))
183 iNetwork.stopPingConsole()
184 iSoftwareTools.cleanupSoftwareTools()
186 def getUpdateInfos(self):
188 if iSoftwareTools.NetworkConnectionAvailable == True:
189 if iSoftwareTools.list_updating is False:
190 if iSoftwareTools.available_updates is not 0:
191 self.text = _("There are at least ") + str(iSoftwareTools.available_updates) + _(" updates available.")
193 self.text = "" #_("There are no updates available.")
195 if iSoftwareTools.available_updates is not 0:
196 self.text = _("There are at least ") + str(iSoftwareTools.available_updates) + _(" updates available.")
198 self.text = "" #_("There are no updates available.")
199 self.text += "\n" + _("A search for available updates is currently in progress.")
201 self.text = _("No network connection available.")
202 self["status"].setText(self.text)
206 #iNetwork.stopPingConsole()
207 current = self["menu"].getCurrent()
209 currentEntry = current[0]
211 if (currentEntry == "software-update"):
212 self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to update your Dreambox?")+"\n"+_("\nAfter pressing OK, please wait!"))
213 elif (currentEntry == "software-restore"):
214 self.session.open(ImageWizard)
215 elif (currentEntry == "install-extensions"):
216 self.session.open(PluginManager, self.skin_path)
217 elif (currentEntry == "system-backup"):
218 self.session.openWithCallback(self.backupDone,BackupScreen, runBackup = True)
219 elif (currentEntry == "system-restore"):
220 if os_path.exists(self.fullbackupfilename):
221 self.session.openWithCallback(self.startRestore, MessageBox, _("Are you sure you want to restore your Enigma2 backup?\nEnigma2 will restart after the restore"))
223 self.session.open(MessageBox, _("Sorry no backups found!"), MessageBox.TYPE_INFO, timeout = 10)
224 elif (currentEntry == "ipkg-install"):
226 from Plugins.Extensions.MediaScanner.plugin import main
229 self.session.open(MessageBox, _("Sorry MediaScanner is not installed!"), MessageBox.TYPE_INFO, timeout = 10)
230 elif (currentEntry == "default-plugin"):
231 self.extended = current[3]
232 self.extended(self.session, None)
233 elif (currentEntry == "advanced"):
234 self.session.open(UpdatePluginMenu, 1)
236 if (currentEntry == "ipkg-manager"):
237 self.session.open(PacketManager, self.skin_path)
238 elif (currentEntry == "backuplocation"):
239 parts = [ (r.description, r.mountpoint, self.session) for r in harddiskmanager.getMountedPartitions(onlyhotplug = False)]
241 if not access(x[1], F_OK|R_OK|W_OK) or x[1] == '/':
244 if x[1].startswith('/autofs/'):
247 self.session.openWithCallback(self.backuplocation_choosen, ChoiceBox, title = _("Please select medium to use as backup location"), list = parts)
248 elif (currentEntry == "backupfiles"):
249 self.session.openWithCallback(self.backupfiles_choosen,BackupSelection)
250 elif (currentEntry == "advancedrestore"):
251 self.session.open(RestoreMenu, self.skin_path)
252 elif (currentEntry == "ipkg-source"):
253 self.session.open(IPKGMenu, self.skin_path)
254 elif (currentEntry == "advanced-plugin"):
255 self.extended = current[3]
256 self.extended(self.session, None)
258 def backupfiles_choosen(self, ret):
259 self.backupdirs = ' '.join( config.plugins.configurationbackup.backupdirs.value )
261 def backuplocation_choosen(self, option):
262 if option is not None:
263 config.plugins.configurationbackup.backuplocation.value = str(option[1])
264 config.plugins.configurationbackup.backuplocation.save()
265 config.plugins.configurationbackup.save()
267 self.createBackupfolders()
269 def runUpgrade(self, result):
271 self.session.open(UpdatePlugin, self.skin_path)
273 def createBackupfolders(self):
274 print "Creating backup folder if not already there..."
275 self.backuppath = getBackupPath()
277 if (os_path.exists(self.backuppath) == False):
278 makedirs(self.backuppath)
280 self.session.open(MessageBox, _("Sorry, your backup destination is not writeable.\n\nPlease choose another one."), MessageBox.TYPE_INFO, timeout = 10)
282 def backupDone(self,retval = None):
284 self.session.open(MessageBox, _("Backup done."), MessageBox.TYPE_INFO, timeout = 10)
286 self.session.open(MessageBox, _("Backup failed."), MessageBox.TYPE_INFO, timeout = 10)
288 def startRestore(self, ret = False):
291 self.session.open(RestoreScreen, runRestore = True)
294 class PluginManager(Screen, DreamInfoHandler):
297 <screen name="PluginManager" position="center,center" size="560,440" title="Extensions management" >
298 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
299 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
300 <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" alphatest="on" />
301 <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" alphatest="on" />
302 <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" />
303 <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" />
304 <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" />
305 <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" />
306 <widget source="list" render="Listbox" position="5,50" size="550,360" scrollbarMode="showOnDemand">
307 <convert type="TemplatedMultiContent">
310 MultiContentEntryText(pos = (30, 1), size = (470, 24), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
311 MultiContentEntryText(pos = (30, 25), size = (470, 24), font=1, flags = RT_HALIGN_LEFT, text = 2), # index 2 is the description
312 MultiContentEntryPixmapAlphaTest(pos = (475, 0), size = (48, 48), png = 5), # index 5 is the status pixmap
313 MultiContentEntryPixmapAlphaTest(pos = (0, 49), size = (550, 2), png = 6), # index 6 is the div pixmap
316 MultiContentEntryText(pos = (30, 0), size = (500, 22), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
317 MultiContentEntryText(pos = (30, 22), size = (500, 16), font=2, flags = RT_HALIGN_LEFT, text = 1), # index 1 is the description
318 MultiContentEntryPixmapAlphaTest(pos = (0, 38), size = (550, 2), png = 3), # index 3 is the div pixmap
321 "fonts": [gFont("Regular", 22),gFont("Regular", 20),gFont("Regular", 16)],
326 <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" />
329 def __init__(self, session, plugin_path, args = None):
330 Screen.__init__(self, session)
331 self.session = session
332 self.skin_path = plugin_path
334 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions", "InfobarEPGActions", "HelpActions" ],
336 "ok": self.handleCurrent,
339 "green": self.handleCurrent,
340 "yellow": self.handleSelected,
341 "showEventInfo": self.handleSelected,
342 "displayHelp": self.handleHelp,
347 self.selectedFiles = []
348 self.categoryList = []
350 self["list"] = List(self.list)
351 self["key_red"] = StaticText(_("Close"))
352 self["key_green"] = StaticText("")
353 self["key_yellow"] = StaticText("")
354 self["key_blue"] = StaticText("")
355 self["status"] = StaticText("")
358 self.oktext = _("\nAfter pressing OK, please wait!")
359 if not self.selectionChanged in self["list"].onSelectionChanged:
360 self["list"].onSelectionChanged.append(self.selectionChanged)
363 self.currentSelectedTag = None
364 self.currentSelectedIndex = None
365 self.currentSelectedPackage = None
366 self.saved_currentSelectedPackage = None
368 self.onShown.append(self.setWindowTitle)
369 self.onLayoutFinish.append(self.getUpdateInfos)
371 def setWindowTitle(self):
372 self.setTitle(_("Extensions management"))
375 if self.currList == "packages":
376 self.currList = "category"
377 self.currentSelectedTag = None
378 self["list"].style = "category"
379 self['list'].setList(self.categoryList)
380 self["list"].setIndex(self.currentSelectedIndex)
381 self["list"].updateList(self.categoryList)
382 self.selectionChanged()
384 iSoftwareTools.cleanupSoftwareTools()
385 self.prepareInstall()
386 if len(self.cmdList):
387 self.session.openWithCallback(self.runExecute, PluginManagerInfo, self.skin_path, self.cmdList)
391 def handleHelp(self):
392 if self.currList != "status":
393 self.session.open(PluginManagerHelp, self.skin_path)
395 def setState(self,status = None):
397 self.currList = "status"
399 self["key_green"].setText("")
400 self["key_blue"].setText("")
401 self["key_yellow"].setText("")
402 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
403 if status == 'update':
404 statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgrade.png"))
405 self.statuslist.append(( _("Updating software catalog"), '', _("Searching for available updates. Please wait..." ),'', '', statuspng, divpng, None, '' ))
406 self["list"].style = "default"
407 self['list'].setList(self.statuslist)
408 elif status == 'sync':
409 statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgrade.png"))
410 self.statuslist.append(( _("Package list update"), '', _("Searching for new installed or removed packages. Please wait..." ),'', '', statuspng, divpng, None, '' ))
411 self["list"].style = "default"
412 self['list'].setList(self.statuslist)
413 elif status == 'error':
414 statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
415 self.statuslist.append(( _("Error"), '', _("There was an error downloading the packetlist. Please try again." ),'', '', statuspng, divpng, None, '' ))
416 self["list"].style = "default"
417 self['list'].setList(self.statuslist)
419 def getUpdateInfos(self):
420 self.setState('update')
421 iSoftwareTools.getUpdates(self.getUpdateInfosCB)
423 def getUpdateInfosCB(self, retval = None):
424 if retval is not None:
426 if iSoftwareTools.available_updates is not 0:
427 self["status"].setText(_("There are at least ") + str(iSoftwareTools.available_updates) + _(" updates available."))
429 self["status"].setText(_("There are no updates available."))
430 elif retval is False:
431 self["status"].setText(_("No network connection available."))
434 def rebuildList(self, retval = None):
435 if self.currentSelectedTag is None:
436 self.buildCategoryList()
438 self.buildPacketList(self.currentSelectedTag)
440 def selectionChanged(self):
441 current = self["list"].getCurrent()
442 self["status"].setText("")
444 if self.currList == "packages":
445 self["key_red"].setText(_("Back"))
446 if current[4] == 'installed':
447 self["key_green"].setText(_("Uninstall"))
448 elif current[4] == 'installable':
449 self["key_green"].setText(_("Install"))
450 elif current[4] == 'remove':
451 self["key_green"].setText(_("Undo uninstall"))
452 elif current[4] == 'install':
453 self["key_green"].setText(_("Undo install"))
454 self["key_yellow"].setText(_("View details"))
455 self["key_blue"].setText("")
456 if len(self.selectedFiles) == 0 and iSoftwareTools.available_updates is not 0:
457 self["status"].setText(_("There are at least ") + str(iSoftwareTools.available_updates) + _(" updates available."))
458 elif len(self.selectedFiles) is not 0:
459 self["status"].setText(str(len(self.selectedFiles)) + _(" packages selected."))
461 self["status"].setText(_("There are currently no outstanding actions."))
462 elif self.currList == "category":
463 self["key_red"].setText(_("Close"))
464 self["key_green"].setText("")
465 self["key_yellow"].setText("")
466 self["key_blue"].setText("")
467 if len(self.selectedFiles) == 0 and iSoftwareTools.available_updates is not 0:
468 self["status"].setText(_("There are at least ") + str(iSoftwareTools.available_updates) + _(" updates available."))
469 self["key_yellow"].setText(_("Update"))
470 elif len(self.selectedFiles) is not 0:
471 self["status"].setText(str(len(self.selectedFiles)) + _(" packages selected."))
472 self["key_yellow"].setText(_("Process"))
474 self["status"].setText(_("There are currently no outstanding actions."))
476 def getSelectionState(self, detailsFile):
477 for entry in self.selectedFiles:
478 if entry[0] == detailsFile:
482 def handleCurrent(self):
483 current = self["list"].getCurrent()
485 if self.currList == "category":
486 self.currentSelectedIndex = self["list"].index
487 selectedTag = current[2]
488 self.buildPacketList(selectedTag)
489 elif self.currList == "packages":
490 if current[7] is not '':
491 idx = self["list"].getIndex()
492 detailsFile = self.list[idx][1]
493 if self.list[idx][7] == True:
494 for entry in self.selectedFiles:
495 if entry[0] == detailsFile:
496 self.selectedFiles.remove(entry)
498 alreadyinList = False
499 for entry in self.selectedFiles:
500 if entry[0] == detailsFile:
502 if not alreadyinList:
503 self.selectedFiles.append((detailsFile,current[4],current[3]))
504 self.currentSelectedPackage = ((detailsFile,current[4],current[3]))
505 if current[4] == 'installed':
506 self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'remove', True)
507 elif current[4] == 'installable':
508 self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'install', True)
509 elif current[4] == 'remove':
510 self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'installed', False)
511 elif current[4] == 'install':
512 self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'installable',False)
513 self["list"].setList(self.list)
514 self["list"].setIndex(idx)
515 self["list"].updateList(self.list)
516 self.selectionChanged()
518 def handleSelected(self):
519 current = self["list"].getCurrent()
521 if self.currList == "packages":
522 if current[7] is not '':
523 detailsfile = iSoftwareTools.directory[0] + "/" + current[1]
524 if (os_path.exists(detailsfile) == True):
525 self.saved_currentSelectedPackage = self.currentSelectedPackage
526 self.session.openWithCallback(self.detailsClosed, PluginDetails, self.skin_path, current)
528 self.session.open(MessageBox, _("Sorry, no Details available!"), MessageBox.TYPE_INFO, timeout = 10)
529 elif self.currList == "category":
530 self.prepareInstall()
531 if len(self.cmdList):
532 self.session.openWithCallback(self.runExecute, PluginManagerInfo, self.skin_path, self.cmdList)
534 def detailsClosed(self, result = None):
535 if result is not None:
536 if result is not False:
537 self.setState('sync')
538 iSoftwareTools.lastDownloadDate = time()
539 for entry in self.selectedFiles:
540 if entry == self.saved_currentSelectedPackage:
541 self.selectedFiles.remove(entry)
542 iSoftwareTools.startIpkgListInstalled(self.rebuildList)
544 def buildEntryComponent(self, name, details, description, packagename, state, selected = False):
545 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
546 installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installed.png"))
547 installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installable.png"))
548 removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
549 installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/install.png"))
550 if state == 'installed':
551 return((name, details, description, packagename, state, installedpng, divpng, selected))
552 elif state == 'installable':
553 return((name, details, description, packagename, state, installablepng, divpng, selected))
554 elif state == 'remove':
555 return((name, details, description, packagename, state, removepng, divpng, selected))
556 elif state == 'install':
557 return((name, details, description, packagename, state, installpng, divpng, selected))
559 def buildPacketList(self, categorytag = None):
560 if categorytag is not None:
561 self.currList = "packages"
562 self.currentSelectedTag = categorytag
564 for package in iSoftwareTools.packagesIndexlist[:]:
565 prerequisites = package[0]["prerequisites"]
566 if prerequisites.has_key("tag"):
567 for foundtag in prerequisites["tag"]:
568 if categorytag == foundtag:
569 attributes = package[0]["attributes"]
570 if attributes.has_key("packagetype"):
571 if attributes["packagetype"] == "internal":
573 self.packetlist.append([attributes["name"], attributes["details"], attributes["shortdescription"], attributes["packagename"]])
575 self.packetlist.append([attributes["name"], attributes["details"], attributes["shortdescription"], attributes["packagename"]])
577 for x in self.packetlist:
580 details = x[1].strip()
581 description = x[2].strip()
582 packagename = x[3].strip()
583 selectState = self.getSelectionState(details)
584 if iSoftwareTools.installed_packetlist.has_key(packagename):
585 if selectState == True:
589 self.list.append(self.buildEntryComponent(name, details, description, packagename, status, selected = selectState))
591 if selectState == True:
594 status = "installable"
595 self.list.append(self.buildEntryComponent(name, details, description, packagename, status, selected = selectState))
597 self.list.sort(key=lambda x: x[0])
598 self["list"].style = "default"
599 self['list'].setList(self.list)
600 self["list"].updateList(self.list)
601 self.selectionChanged()
603 def buildCategoryList(self):
604 self.currList = "category"
606 self.categoryList = []
607 for package in iSoftwareTools.packagesIndexlist[:]:
608 prerequisites = package[0]["prerequisites"]
609 if prerequisites.has_key("tag"):
610 for foundtag in prerequisites["tag"]:
611 attributes = package[0]["attributes"]
612 if foundtag not in self.categories:
613 self.categories.append(foundtag)
614 self.categoryList.append(self.buildCategoryComponent(foundtag))
615 self.categoryList.sort(key=lambda x: x[0])
616 self["list"].style = "category"
617 self['list'].setList(self.categoryList)
618 self["list"].updateList(self.categoryList)
619 self.selectionChanged()
621 def buildCategoryComponent(self, tag = None):
622 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
625 return(( _("System"), _("View list of available system extensions" ), tag, divpng ))
627 return(( _("Skins"), _("View list of available skins" ), tag, divpng ))
628 elif tag == 'Recording':
629 return(( _("Recordings"), _("View list of available recording extensions" ), tag, divpng ))
630 elif tag == 'Network':
631 return(( _("Network"), _("View list of available networking extensions" ), tag, divpng ))
633 return(( _("CommonInterface"), _("View list of available CommonInterface extensions" ), tag, divpng ))
634 elif tag == 'Default':
635 return(( _("Default Settings"), _("View list of available default settings" ), tag, divpng ))
637 return(( _("Satteliteequipment"), _("View list of available Satteliteequipment extensions." ), tag, divpng ))
638 elif tag == 'Software':
639 return(( _("Software"), _("View list of available software extensions" ), tag, divpng ))
640 elif tag == 'Multimedia':
641 return(( _("Multimedia"), _("View list of available multimedia extensions." ), tag, divpng ))
642 elif tag == 'Display':
643 return(( _("Display and Userinterface"), _("View list of available Display and Userinterface extensions." ), tag, divpng ))
645 return(( _("Electronic Program Guide"), _("View list of available EPG extensions." ), tag, divpng ))
646 elif tag == 'Communication':
647 return(( _("Communication"), _("View list of available communication extensions." ), tag, divpng ))
648 else: # dynamically generate non existent tags
649 return(( str(tag), _("View list of available ") + str(tag) + _(" extensions." ), tag, divpng ))
651 def prepareInstall(self):
653 if iSoftwareTools.available_updates > 0:
654 self.cmdList.append((IpkgComponent.CMD_UPGRADE, { "test_only": False }))
655 if self.selectedFiles and len(self.selectedFiles):
656 for plugin in self.selectedFiles:
657 detailsfile = iSoftwareTools.directory[0] + "/" + plugin[0]
658 if (os_path.exists(detailsfile) == True):
659 iSoftwareTools.fillPackageDetails(plugin[0])
660 self.package = iSoftwareTools.packageDetails[0]
661 if self.package[0].has_key("attributes"):
662 self.attributes = self.package[0]["attributes"]
663 if self.attributes.has_key("package"):
664 self.packagefiles = self.attributes["package"]
665 if plugin[1] == 'installed':
666 if self.packagefiles:
667 for package in self.packagefiles[:]:
668 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": package["name"] }))
670 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": plugin[2] }))
672 if self.packagefiles:
673 for package in self.packagefiles[:]:
674 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package["name"] }))
676 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": plugin[2] }))
678 if plugin[1] == 'installed':
679 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": plugin[2] }))
681 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": plugin[2] }))
683 def runExecute(self, result = None):
684 if result is not None:
685 if result[0] is True:
686 self.session.openWithCallback(self.runExecuteFinished, Ipkg, cmdList = self.cmdList)
687 elif result[0] is False:
688 self.cmdList = result[1]
689 self.session.openWithCallback(self.runExecuteFinished, Ipkg, cmdList = self.cmdList)
693 def runExecuteFinished(self):
694 self.session.openWithCallback(self.ExecuteReboot, MessageBox, _("Install or remove finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
696 def ExecuteReboot(self, result):
697 print "RESULT im ExecuteReboot",result
701 self.reloadPluginlist()
702 self.selectedFiles = []
703 self.detailsClosed(True)
707 def reloadPluginlist(self):
708 plugins.readPluginList(resolveFilename(SCOPE_PLUGINS))
711 class PluginManagerInfo(Screen):
713 <screen name="PluginManagerInfo" position="center,center" size="560,450" title="Plugin manager activity information" >
714 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
715 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
716 <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" />
717 <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" />
718 <widget source="list" render="Listbox" position="5,50" size="550,350" scrollbarMode="showOnDemand" selectionDisabled="1">
719 <convert type="TemplatedMultiContent">
721 MultiContentEntryText(pos = (50, 0), size = (150, 26), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
722 MultiContentEntryText(pos = (50, 27), size = (540, 23), font=1, flags = RT_HALIGN_LEFT, text = 1), # index 1 is the state
723 MultiContentEntryPixmapAlphaTest(pos = (0, 1), size = (48, 48), png = 2), # index 2 is the status pixmap
724 MultiContentEntryPixmapAlphaTest(pos = (0, 48), size = (550, 2), png = 3), # index 3 is the div pixmap
726 "fonts": [gFont("Regular", 24),gFont("Regular", 22)],
731 <ePixmap pixmap="skin_default/div-h.png" position="0,404" zPosition="10" size="560,2" transparent="1" alphatest="on" />
732 <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" />
735 def __init__(self, session, plugin_path, cmdlist = None):
736 Screen.__init__(self, session)
737 self.session = session
738 self.skin_path = plugin_path
739 self.cmdlist = cmdlist
741 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"],
743 "ok": self.process_all,
746 "green": self.process_extensions,
750 self["list"] = List(self.list)
751 self["key_red"] = StaticText(_("Cancel"))
752 self["key_green"] = StaticText(_("Only extensions."))
753 self["status"] = StaticText(_("Following tasks will be done after you press OK!"))
755 self.onShown.append(self.setWindowTitle)
756 self.onLayoutFinish.append(self.rebuildList)
758 def setWindowTitle(self):
759 self.setTitle(_("Plugin manager activity information"))
761 def rebuildList(self):
763 if self.cmdlist is not None:
764 for entry in self.cmdlist:
776 info = args['package']
778 info = args['package']
780 info = _("Dreambox software because updates are available.")
782 self.list.append(self.buildEntryComponent(action,info))
783 self['list'].setList(self.list)
784 self['list'].updateList(self.list)
786 def buildEntryComponent(self, action,info):
787 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
788 upgradepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgrade.png"))
789 installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/install.png"))
790 removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
791 if action == 'install':
792 return(( _('Installing'), info, installpng, divpng))
793 elif action == 'remove':
794 return(( _('Removing'), info, removepng, divpng))
796 return(( _('Upgrading'), info, upgradepng, divpng))
801 def process_all(self):
802 self.close((True,None))
804 def process_extensions(self):
806 if self.cmdlist is not None:
807 for entry in self.cmdlist:
809 if entry[0] in (0,2):
810 self.list.append((entry))
811 self.close((False,self.list))
814 class PluginManagerHelp(Screen):
816 <screen name="PluginManagerHelp" position="center,center" size="560,450" title="Plugin manager help" >
817 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
818 <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" />
819 <widget source="list" render="Listbox" position="5,50" size="550,350" scrollbarMode="showOnDemand" selectionDisabled="1">
820 <convert type="TemplatedMultiContent">
822 MultiContentEntryText(pos = (50, 0), size = (150, 26), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
823 MultiContentEntryText(pos = (50, 27), size = (540, 23), font=1, flags = RT_HALIGN_LEFT, text = 1), # index 1 is the state
824 MultiContentEntryPixmapAlphaTest(pos = (0, 1), size = (48, 48), png = 2), # index 2 is the status pixmap
825 MultiContentEntryPixmapAlphaTest(pos = (0, 48), size = (550, 2), png = 3), # index 3 is the div pixmap
827 "fonts": [gFont("Regular", 24),gFont("Regular", 22)],
832 <ePixmap pixmap="skin_default/div-h.png" position="0,404" zPosition="10" size="560,2" transparent="1" alphatest="on" />
833 <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" />
836 def __init__(self, session, plugin_path):
837 Screen.__init__(self, session)
838 self.session = session
839 self.skin_path = plugin_path
841 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"],
848 self["list"] = List(self.list)
849 self["key_red"] = StaticText(_("Close"))
850 self["status"] = StaticText(_("A small overview of the available icon states and actions."))
852 self.onShown.append(self.setWindowTitle)
853 self.onLayoutFinish.append(self.rebuildList)
855 def setWindowTitle(self):
856 self.setTitle(_("Plugin manager help"))
858 def rebuildList(self):
860 self.list.append(self.buildEntryComponent('install'))
861 self.list.append(self.buildEntryComponent('installable'))
862 self.list.append(self.buildEntryComponent('installed'))
863 self.list.append(self.buildEntryComponent('remove'))
864 self['list'].setList(self.list)
865 self['list'].updateList(self.list)
867 def buildEntryComponent(self, state):
868 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
869 installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installed.png"))
870 installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installable.png"))
871 removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
872 installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/install.png"))
874 if state == 'installed':
875 return(( _('This plugin is installed.'), _('You can remove this plugin.'), installedpng, divpng))
876 elif state == 'installable':
877 return(( _('This plugin is not installed.'), _('You can install this plugin.'), installablepng, divpng))
878 elif state == 'install':
879 return(( _('This plugin will be installed.'), _('You can cancel the installation.'), installpng, divpng))
880 elif state == 'remove':
881 return(( _('This plugin will be removed.'), _('You can cancel the removal.'), removepng, divpng))
887 class PluginDetails(Screen, DreamInfoHandler):
889 <screen name="PluginDetails" position="center,center" size="600,440" title="Plugin details" >
890 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
891 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
892 <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" />
893 <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" />
894 <widget source="author" render="Label" position="10,50" size="500,25" zPosition="10" font="Regular;21" transparent="1" />
895 <widget name="statuspic" position="550,40" size="48,48" alphatest="on"/>
896 <widget name="divpic" position="0,80" size="600,2" alphatest="on"/>
897 <widget name="detailtext" position="10,90" size="270,330" zPosition="10" font="Regular;21" transparent="1" halign="left" valign="top"/>
898 <widget name="screenshot" position="290,90" size="300,330" alphatest="on"/>
900 def __init__(self, session, plugin_path, packagedata = None):
901 Screen.__init__(self, session)
902 self.skin_path = plugin_path
903 self.language = language.getLanguage()[:2] # getLanguage returns e.g. "fi_FI" for "language_country"
904 self.attributes = None
905 self.translatedAttributes = None
906 DreamInfoHandler.__init__(self, self.statusCallback, blocking = False, language = self.language)
907 self.directory = resolveFilename(SCOPE_METADIR)
909 self.pluginname = packagedata[0]
910 self.details = packagedata[1]
911 self.pluginstate = packagedata[4]
912 self.statuspicinstance = packagedata[5]
913 self.divpicinstance = packagedata[6]
914 self.fillPackageDetails(self.details)
918 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"],
924 "down": self.pageDown,
926 "right": self.pageDown,
929 self["key_red"] = StaticText(_("Close"))
930 self["key_green"] = StaticText("")
931 self["author"] = StaticText()
932 self["statuspic"] = Pixmap()
933 self["divpic"] = Pixmap()
934 self["screenshot"] = Pixmap()
935 self["detailtext"] = ScrollLabel()
937 self["statuspic"].hide()
938 self["screenshot"].hide()
939 self["divpic"].hide()
941 self.package = self.packageDetails[0]
942 if self.package[0].has_key("attributes"):
943 self.attributes = self.package[0]["attributes"]
944 if self.package[0].has_key("translation"):
945 self.translatedAttributes = self.package[0]["translation"]
948 self.oktext = _("\nAfter pressing OK, please wait!")
949 self.picload = ePicLoad()
950 self.picload.PictureData.get().append(self.paintScreenshotPixmapCB)
951 self.onShown.append(self.setWindowTitle)
952 self.onLayoutFinish.append(self.setInfos)
954 def setWindowTitle(self):
955 self.setTitle(_("Details for extension: " + self.pluginname))
961 self["detailtext"].pageUp()
964 self["detailtext"].pageDown()
966 def statusCallback(self, status, progress):
970 if self.translatedAttributes.has_key("name"):
971 self.pluginname = self.translatedAttributes["name"]
972 elif self.attributes.has_key("name"):
973 self.pluginname = self.attributes["name"]
975 self.pluginname = _("unknown")
977 if self.translatedAttributes.has_key("author"):
978 self.author = self.translatedAttributes["author"]
979 elif self.attributes.has_key("author"):
980 self.author = self.attributes["author"]
982 self.author = _("unknown")
984 if self.translatedAttributes.has_key("description"):
985 self.description = self.translatedAttributes["description"]
986 elif self.attributes.has_key("description"):
987 self.description = self.attributes["description"]
989 self.description = _("No description available.")
991 if self.translatedAttributes.has_key("screenshot"):
992 self.loadThumbnail(self.translatedAttributes)
994 self.loadThumbnail(self.attributes)
996 self["author"].setText(_("Author: ") + self.author)
997 self["detailtext"].setText(self.description.strip())
998 if self.pluginstate in ('installable', 'install'):
999 self["key_green"].setText(_("Install"))
1001 self["key_green"].setText(_("Remove"))
1003 def loadThumbnail(self, entry):
1005 if entry.has_key("screenshot"):
1006 thumbnailUrl = entry["screenshot"]
1007 if thumbnailUrl is not None:
1008 self.thumbnail = "/tmp/" + thumbnailUrl.split('/')[-1]
1009 print "[PluginDetails] downloading screenshot " + thumbnailUrl + " to " + self.thumbnail
1010 client.downloadPage(thumbnailUrl,self.thumbnail).addCallback(self.setThumbnail).addErrback(self.fetchFailed)
1012 self.setThumbnail(noScreenshot = True)
1014 def setThumbnail(self, noScreenshot = False):
1015 if not noScreenshot:
1016 filename = self.thumbnail
1018 filename = resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/noprev.png")
1020 sc = AVSwitch().getFramebufferScale()
1021 self.picload.setPara((self["screenshot"].instance.size().width(), self["screenshot"].instance.size().height(), sc[0], sc[1], False, 1, "#00000000"))
1022 self.picload.startDecode(filename)
1024 if self.statuspicinstance != None:
1025 self["statuspic"].instance.setPixmap(self.statuspicinstance.__deref__())
1026 self["statuspic"].show()
1027 if self.divpicinstance != None:
1028 self["divpic"].instance.setPixmap(self.divpicinstance.__deref__())
1029 self["divpic"].show()
1031 def paintScreenshotPixmapCB(self, picInfo=None):
1032 ptr = self.picload.getData()
1034 self["screenshot"].instance.setPixmap(ptr.__deref__())
1035 self["screenshot"].show()
1037 self.setThumbnail(noScreenshot = True)
1040 if self.attributes.has_key("package"):
1041 self.packagefiles = self.attributes["package"]
1043 if self.pluginstate in ('installed', 'remove'):
1044 if self.packagefiles:
1045 for package in self.packagefiles[:]:
1046 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": package["name"] }))
1047 if len(self.cmdList):
1048 self.session.openWithCallback(self.runRemove, MessageBox, _("Do you want to remove the package:\n") + self.pluginname + "\n" + self.oktext)
1050 if self.packagefiles:
1051 for package in self.packagefiles[:]:
1052 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package["name"] }))
1053 if len(self.cmdList):
1054 self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to install the package:\n") + self.pluginname + "\n" + self.oktext)
1056 def runUpgrade(self, result):
1058 self.session.openWithCallback(self.runUpgradeFinished, Ipkg, cmdList = self.cmdList)
1060 def runUpgradeFinished(self):
1061 self.session.openWithCallback(self.UpgradeReboot, MessageBox, _("Installation finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
1063 def UpgradeReboot(self, result):
1071 def runRemove(self, result):
1073 self.session.openWithCallback(self.runRemoveFinished, Ipkg, cmdList = self.cmdList)
1075 def runRemoveFinished(self):
1076 self.session.openWithCallback(self.RemoveReboot, MessageBox, _("Remove finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
1078 def RemoveReboot(self, result):
1086 def reloadPluginlist(self):
1087 plugins.readPluginList(resolveFilename(SCOPE_PLUGINS))
1089 def fetchFailed(self,string):
1090 self.setThumbnail(noScreenshot = True)
1091 print "[PluginDetails] fetch failed " + string.getErrorMessage()
1094 class UpdatePlugin(Screen):
1096 <screen name="UpdatePlugin" position="center,center" size="550,200" title="Software update" >
1097 <widget name="activityslider" position="0,0" size="550,5" />
1098 <widget name="slider" position="0,150" size="550,30" />
1099 <widget source="package" render="Label" position="10,30" size="540,20" font="Regular;18" halign="center" valign="center" backgroundColor="#25062748" transparent="1" />
1100 <widget source="status" render="Label" position="10,60" size="540,45" font="Regular;20" halign="center" valign="center" backgroundColor="#25062748" transparent="1" />
1103 def __init__(self, session, args = None):
1104 Screen.__init__(self, session)
1106 self.sliderPackages = { "dreambox-dvb-modules": 1, "enigma2": 2, "tuxbox-image-info": 3 }
1108 self.slider = Slider(0, 4)
1109 self["slider"] = self.slider
1110 self.activityslider = Slider(0, 100)
1111 self["activityslider"] = self.activityslider
1112 self.status = StaticText(_("Upgrading Dreambox... Please wait"))
1113 self["status"] = self.status
1114 self.package = StaticText()
1115 self["package"] = self.package
1121 self.activityTimer = eTimer()
1122 self.activityTimer.callback.append(self.doActivityTimer)
1123 self.activityTimer.start(100, False)
1125 self.ipkg = IpkgComponent()
1126 self.ipkg.addCallback(self.ipkgCallback)
1128 self.updating = True
1129 self.package.setText(_("Package list update"))
1130 self.ipkg.startCmd(IpkgComponent.CMD_UPDATE)
1132 self["actions"] = ActionMap(["WizardActions"],
1138 def doActivityTimer(self):
1140 if self.activity == 100:
1142 self.activityslider.setValue(self.activity)
1144 def ipkgCallback(self, event, param):
1145 if event == IpkgComponent.EVENT_DOWNLOAD:
1146 self.status.setText(_("Downloading"))
1147 elif event == IpkgComponent.EVENT_UPGRADE:
1148 if self.sliderPackages.has_key(param):
1149 self.slider.setValue(self.sliderPackages[param])
1150 self.package.setText(param)
1151 self.status.setText(_("Upgrading"))
1153 elif event == IpkgComponent.EVENT_INSTALL:
1154 self.package.setText(param)
1155 self.status.setText(_("Installing"))
1157 elif event == IpkgComponent.EVENT_CONFIGURING:
1158 self.package.setText(param)
1159 self.status.setText(_("Configuring"))
1160 elif event == IpkgComponent.EVENT_MODIFIED:
1161 self.session.openWithCallback(
1162 self.modificationCallback,
1164 _("A configuration file (%s) was modified since Installation.\nDo you want to keep your version?") % (param)
1166 elif event == IpkgComponent.EVENT_ERROR:
1168 elif event == IpkgComponent.EVENT_DONE:
1170 self.updating = False
1171 self.ipkg.startCmd(IpkgComponent.CMD_UPGRADE, args = {'test_only': False})
1172 elif self.error == 0:
1173 self.slider.setValue(4)
1175 self.activityTimer.stop()
1176 self.activityslider.setValue(0)
1178 self.package.setText("")
1179 self.status.setText(_("Done - Installed or upgraded %d packages") % self.packages)
1181 self.activityTimer.stop()
1182 self.activityslider.setValue(0)
1183 error = _("your dreambox might be unusable now. Please consult the manual for further assistance before rebooting your dreambox.")
1184 if self.packages == 0:
1185 error = _("No packages were upgraded yet. So you can check your network and try again.")
1187 error = _("Your dreambox isn't connected to the internet properly. Please check it and try again.")
1188 self.status.setText(_("Error") + " - " + error)
1189 #print event, "-", param
1192 def modificationCallback(self, res):
1193 self.ipkg.write(res and "N" or "Y")
1196 if not self.ipkg.isRunning():
1197 if self.packages != 0 and self.error == 0:
1198 self.session.openWithCallback(self.exitAnswer, MessageBox, _("Upgrade finished.") +" "+_("Do you want to reboot your Dreambox?"))
1202 def exitAnswer(self, result):
1203 if result is not None and result:
1209 class IPKGMenu(Screen):
1211 <screen name="IPKGMenu" position="center,center" size="560,400" title="Select upgrade source to edit." >
1212 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1213 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1214 <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" />
1215 <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" />
1216 <widget name="filelist" position="5,50" size="550,340" scrollbarMode="showOnDemand" />
1219 def __init__(self, session, plugin_path):
1220 Screen.__init__(self, session)
1221 self.skin_path = plugin_path
1223 self["key_red"] = StaticText(_("Close"))
1224 self["key_green"] = StaticText(_("Edit"))
1233 self["actions"] = NumberActionMap(["SetupActions"],
1236 "cancel": self.keyCancel
1239 self["shortcuts"] = ActionMap(["ShortcutActions"],
1241 "red": self.keyCancel,
1242 "green": self.KeyOk,
1245 self["filelist"] = MenuList(self.flist)
1247 self.onLayoutFinish.append(self.layoutFinished)
1249 def layoutFinished(self):
1250 self.setWindowTitle()
1252 def setWindowTitle(self):
1253 self.setTitle(_("Select upgrade source to edit."))
1255 def fill_list(self):
1257 self.path = '/etc/ipkg/'
1258 if (os_path.exists(self.path) == False):
1261 for file in listdir(self.path):
1262 if (file.endswith(".conf")):
1263 if file != 'arch.conf':
1264 self.flist.append((file))
1266 self["filelist"].l.setList(self.flist)
1269 if (self.exe == False) and (self.entry == True):
1270 self.sel = self["filelist"].getCurrent()
1271 self.val = self.path + self.sel
1272 self.session.open(IPKGSource, self.val)
1274 def keyCancel(self):
1281 class IPKGSource(Screen):
1283 <screen name="IPKGSource" position="center,center" size="560,80" title="Edit upgrade source url." >
1284 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1285 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1286 <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" />
1287 <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" />
1288 <widget name="text" position="5,50" size="550,25" font="Regular;20" backgroundColor="background" foregroundColor="#cccccc" />
1291 def __init__(self, session, configfile = None):
1292 Screen.__init__(self, session)
1293 self.session = session
1294 self.configfile = configfile
1298 fp = file(configfile, 'r')
1299 sources = fp.readlines()
1306 desk = getDesktop(0)
1307 x= int(desk.size().width())
1308 y= int(desk.size().height())
1310 self["key_red"] = StaticText(_("Cancel"))
1311 self["key_green"] = StaticText(_("Save"))
1314 self["text"] = Input(text, maxSize=False, type=Input.TEXT)
1316 self["text"] = Input(text, maxSize=False, visible_width = 55, type=Input.TEXT)
1318 self["actions"] = NumberActionMap(["WizardActions", "InputActions", "TextEntryActions", "KeyboardInputActions","ShortcutActions"],
1324 "left": self.keyLeft,
1325 "right": self.keyRight,
1326 "home": self.keyHome,
1328 "deleteForward": self.keyDeleteForward,
1329 "deleteBackward": self.keyDeleteBackward,
1330 "1": self.keyNumberGlobal,
1331 "2": self.keyNumberGlobal,
1332 "3": self.keyNumberGlobal,
1333 "4": self.keyNumberGlobal,
1334 "5": self.keyNumberGlobal,
1335 "6": self.keyNumberGlobal,
1336 "7": self.keyNumberGlobal,
1337 "8": self.keyNumberGlobal,
1338 "9": self.keyNumberGlobal,
1339 "0": self.keyNumberGlobal
1342 self.onLayoutFinish.append(self.layoutFinished)
1344 def layoutFinished(self):
1345 self.setWindowTitle()
1346 self["text"].right()
1348 def setWindowTitle(self):
1349 self.setTitle(_("Edit upgrade source url."))
1352 text = self["text"].getText()
1354 fp = file(self.configfile, 'w')
1364 self["text"].right()
1372 def keyDeleteForward(self):
1373 self["text"].delete()
1375 def keyDeleteBackward(self):
1376 self["text"].deleteBackward()
1378 def keyNumberGlobal(self, number):
1379 self["text"].number(number)
1382 class PacketManager(Screen):
1384 <screen name="PacketManager" position="center,center" size="530,420" title="Packet manager" >
1385 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1386 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1387 <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" />
1388 <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" />
1389 <widget source="list" render="Listbox" position="5,50" size="520,365" scrollbarMode="showOnDemand">
1390 <convert type="TemplatedMultiContent">
1392 MultiContentEntryText(pos = (5, 1), size = (440, 28), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
1393 MultiContentEntryText(pos = (5, 26), size = (440, 20), font=1, flags = RT_HALIGN_LEFT, text = 2), # index 2 is the description
1394 MultiContentEntryPixmapAlphaTest(pos = (445, 2), size = (48, 48), png = 4), # index 4 is the status pixmap
1395 MultiContentEntryPixmapAlphaTest(pos = (5, 50), size = (510, 2), png = 5), # index 4 is the div pixmap
1397 "fonts": [gFont("Regular", 22),gFont("Regular", 14)],
1404 def __init__(self, session, plugin_path, args = None):
1405 Screen.__init__(self, session)
1406 self.session = session
1407 self.skin_path = plugin_path
1409 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"],
1414 "green": self.reload,
1418 self.statuslist = []
1419 self["list"] = List(self.list)
1420 self["key_red"] = StaticText(_("Close"))
1421 self["key_green"] = StaticText(_("Reload"))
1423 self.list_updating = True
1424 self.packetlist = []
1425 self.installed_packetlist = {}
1426 self.Console = Console()
1429 self.cache_ttl = 86400 #600 is default, 0 disables, Seconds cache is considered valid (24h should be ok for caching ipkgs)
1430 self.cache_file = '/usr/lib/enigma2/python/Plugins/SystemPlugins/SoftwareManager/packetmanager.cache' #Path to cache directory
1431 self.oktext = _("\nAfter pressing OK, please wait!")
1432 self.unwanted_extensions = ('-dbg', '-dev', '-doc', 'busybox')
1434 self.ipkg = IpkgComponent()
1435 self.ipkg.addCallback(self.ipkgCallback)
1436 self.onShown.append(self.setWindowTitle)
1437 self.onLayoutFinish.append(self.rebuildList)
1441 if self.Console is not None:
1442 if len(self.Console.appContainers):
1443 for name in self.Console.appContainers.keys():
1444 self.Console.kill(name)
1448 if (os_path.exists(self.cache_file) == True):
1449 remove(self.cache_file)
1450 self.list_updating = True
1453 def setWindowTitle(self):
1454 self.setTitle(_("Packet manager"))
1456 def setStatus(self,status = None):
1458 self.statuslist = []
1459 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
1460 if status == 'update':
1461 statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgrade.png"))
1462 self.statuslist.append(( _("Package list update"), '', _("Trying to download a new packetlist. Please wait..." ),'',statuspng, divpng ))
1463 self['list'].setList(self.statuslist)
1464 elif status == 'error':
1465 statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
1466 self.statuslist.append(( _("Error"), '', _("There was an error downloading the packetlist. Please try again." ),'',statuspng, divpng ))
1467 self['list'].setList(self.statuslist)
1469 def rebuildList(self):
1470 self.setStatus('update')
1472 self.vc = valid_cache(self.cache_file, self.cache_ttl)
1473 if self.cache_ttl > 0 and self.vc != 0:
1475 self.buildPacketList()
1478 if self.cache_ttl == 0 or self.inv_cache == 1 or self.vc == 0:
1480 self.ipkg.startCmd(IpkgComponent.CMD_UPDATE)
1482 def go(self, returnValue = None):
1483 cur = self["list"].getCurrent()
1488 if status == 'installed':
1489 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": package }))
1490 if len(self.cmdList):
1491 self.session.openWithCallback(self.runRemove, MessageBox, _("Do you want to remove the package:\n") + package + "\n" + self.oktext)
1492 elif status == 'upgradeable':
1493 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package }))
1494 if len(self.cmdList):
1495 self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to upgrade the package:\n") + package + "\n" + self.oktext)
1496 elif status == "installable":
1497 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package }))
1498 if len(self.cmdList):
1499 self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to install the package:\n") + package + "\n" + self.oktext)
1501 def runRemove(self, result):
1503 self.session.openWithCallback(self.runRemoveFinished, Ipkg, cmdList = self.cmdList)
1505 def runRemoveFinished(self):
1506 self.session.openWithCallback(self.RemoveReboot, MessageBox, _("Remove finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
1508 def RemoveReboot(self, result):
1512 cur = self["list"].getCurrent()
1514 item = self['list'].getIndex()
1515 self.list[item] = self.buildEntryComponent(cur[0], cur[1], cur[2], 'installable')
1516 self.cachelist[item] = [cur[0], cur[1], cur[2], 'installable']
1517 self['list'].setList(self.list)
1518 write_cache(self.cache_file, self.cachelist)
1519 self.reloadPluginlist()
1523 def runUpgrade(self, result):
1525 self.session.openWithCallback(self.runUpgradeFinished, Ipkg, cmdList = self.cmdList)
1527 def runUpgradeFinished(self):
1528 self.session.openWithCallback(self.UpgradeReboot, MessageBox, _("Upgrade finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
1530 def UpgradeReboot(self, result):
1534 cur = self["list"].getCurrent()
1536 item = self['list'].getIndex()
1537 self.list[item] = self.buildEntryComponent(cur[0], cur[1], cur[2], 'installed')
1538 self.cachelist[item] = [cur[0], cur[1], cur[2], 'installed']
1539 self['list'].setList(self.list)
1540 write_cache(self.cache_file, self.cachelist)
1541 self.reloadPluginlist()
1545 def ipkgCallback(self, event, param):
1546 if event == IpkgComponent.EVENT_ERROR:
1547 self.list_updating = False
1548 self.setStatus('error')
1549 elif event == IpkgComponent.EVENT_DONE:
1550 if self.list_updating:
1551 self.list_updating = False
1552 if not self.Console:
1553 self.Console = Console()
1555 self.Console.ePopen(cmd, self.IpkgList_Finished)
1556 #print event, "-", param
1559 def IpkgList_Finished(self, result, retval, extra_args = None):
1561 self.packetlist = []
1562 for x in result.splitlines():
1563 split = x.split(' - ') #self.blacklisted_packages
1564 if not any(split[0].strip().endswith(x) for x in self.unwanted_extensions):
1565 self.packetlist.append([split[0].strip(), split[1].strip(),split[2].strip()])
1566 if not self.Console:
1567 self.Console = Console()
1568 cmd = "ipkg list_installed"
1569 self.Console.ePopen(cmd, self.IpkgListInstalled_Finished)
1571 def IpkgListInstalled_Finished(self, result, retval, extra_args = None):
1573 self.installed_packetlist = {}
1574 for x in result.splitlines():
1575 split = x.split(' - ')
1576 if not any(split[0].strip().endswith(x) for x in self.unwanted_extensions):
1577 self.installed_packetlist[split[0].strip()] = split[1].strip()
1578 self.buildPacketList()
1580 def buildEntryComponent(self, name, version, description, state):
1581 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
1582 if state == 'installed':
1583 installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installed.png"))
1584 return((name, version, description, state, installedpng, divpng))
1585 elif state == 'upgradeable':
1586 upgradeablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgradeable.png"))
1587 return((name, version, description, state, upgradeablepng, divpng))
1589 installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installable.png"))
1590 return((name, version, description, state, installablepng, divpng))
1592 def buildPacketList(self):
1596 if self.cache_ttl > 0 and self.vc != 0:
1597 print 'Loading packagelist cache from ',self.cache_file
1599 self.cachelist = load_cache(self.cache_file)
1600 if len(self.cachelist) > 0:
1601 for x in self.cachelist:
1602 self.list.append(self.buildEntryComponent(x[0], x[1], x[2], x[3]))
1603 self['list'].setList(self.list)
1607 if self.cache_ttl == 0 or self.inv_cache == 1 or self.vc == 0:
1608 print 'rebuilding fresh package list'
1609 for x in self.packetlist:
1611 if self.installed_packetlist.has_key(x[0].strip()):
1612 if self.installed_packetlist[x[0].strip()] == x[1].strip():
1613 status = "installed"
1614 self.list.append(self.buildEntryComponent(x[0].strip(), x[1].strip(), x[2].strip(), status))
1616 status = "upgradeable"
1617 self.list.append(self.buildEntryComponent(x[0].strip(), x[1].strip(), x[2].strip(), status))
1619 status = "installable"
1620 self.list.append(self.buildEntryComponent(x[0].strip(), x[1].strip(), x[2].strip(), status))
1621 if not any(x[0].strip().endswith(x) for x in self.unwanted_extensions):
1622 self.cachelist.append([x[0].strip(), x[1].strip(), x[2].strip(), status])
1623 write_cache(self.cache_file, self.cachelist)
1624 self['list'].setList(self.list)
1626 def reloadPluginlist(self):
1627 plugins.readPluginList(resolveFilename(SCOPE_PLUGINS))
1629 class IpkgInstaller(Screen):
1631 <screen name="IpkgInstaller" position="center,center" size="550,450" title="Install extensions" >
1632 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1633 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1634 <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" />
1635 <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" />
1636 <widget name="list" position="5,50" size="540,360" />
1637 <ePixmap pixmap="skin_default/div-h.png" position="0,410" zPosition="10" size="560,2" transparent="1" alphatest="on" />
1638 <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" />
1641 def __init__(self, session, list):
1642 Screen.__init__(self, session)
1644 self.list = SelectionList()
1645 self["list"] = self.list
1646 for listindex in range(len(list)):
1647 self.list.addSelection(list[listindex], list[listindex], listindex, True)
1649 self["key_red"] = StaticText(_("Close"))
1650 self["key_green"] = StaticText(_("Install"))
1651 self["introduction"] = StaticText(_("Press OK to toggle the selection."))
1653 self["actions"] = ActionMap(["OkCancelActions", "ColorActions"],
1655 "ok": self.list.toggleSelection,
1656 "cancel": self.close,
1658 "green": self.install
1662 list = self.list.getSelectionsList()
1665 cmdList.append((IpkgComponent.CMD_INSTALL, { "package": item[1] }))
1666 self.session.open(Ipkg, cmdList = cmdList)
1669 def filescan_open(list, session, **kwargs):
1670 filelist = [x.path for x in list]
1671 session.open(IpkgInstaller, filelist) # list
1673 def filescan(**kwargs):
1674 from Components.Scanner import Scanner, ScanPath
1676 Scanner(mimetypes = ["application/x-debian-package"],
1679 ScanPath(path = "ipk", with_subdirs = True),
1680 ScanPath(path = "", with_subdirs = False),
1683 description = _("Install extensions."),
1684 openfnc = filescan_open, )
1688 def UpgradeMain(session, **kwargs):
1689 session.open(UpdatePluginMenu)
1691 def startSetup(menuid):
1692 if menuid != "setup":
1694 return [(_("Software management"), UpgradeMain, "software_manager", 50)]
1696 def autostart(reason, **kwargs):
1698 iSoftwareTools.startSoftwareTools()
1700 def Plugins(path, **kwargs):
1704 PluginDescriptor(where = [PluginDescriptor.WHERE_NETWORKCONFIG_READ], fnc = autostart),
1705 PluginDescriptor(name=_("Software management"), description=_("Manage your receiver's software"), where = PluginDescriptor.WHERE_MENU, fnc=startSetup),
1706 PluginDescriptor(name=_("Ipkg"), where = PluginDescriptor.WHERE_FILESCAN, fnc = filescan)
1708 if config.usage.setup_level.index >= 2: # expert+
1709 list.append(PluginDescriptor(name=_("Software management"), description=_("Manage your receiver's software"), where = PluginDescriptor.WHERE_EXTENSIONSMENU, fnc=UpgradeMain))