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):
700 self.reloadPluginlist()
701 self.selectedFiles = []
702 self.detailsClosed(True)
706 def reloadPluginlist(self):
707 plugins.readPluginList(resolveFilename(SCOPE_PLUGINS))
710 class PluginManagerInfo(Screen):
712 <screen name="PluginManagerInfo" position="center,center" size="560,450" title="Plugin manager activity information" >
713 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
714 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
715 <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" />
716 <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" />
717 <widget source="list" render="Listbox" position="5,50" size="550,350" scrollbarMode="showOnDemand" selectionDisabled="1">
718 <convert type="TemplatedMultiContent">
720 MultiContentEntryText(pos = (50, 0), size = (150, 26), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
721 MultiContentEntryText(pos = (50, 27), size = (540, 23), font=1, flags = RT_HALIGN_LEFT, text = 1), # index 1 is the state
722 MultiContentEntryPixmapAlphaTest(pos = (0, 1), size = (48, 48), png = 2), # index 2 is the status pixmap
723 MultiContentEntryPixmapAlphaTest(pos = (0, 48), size = (550, 2), png = 3), # index 3 is the div pixmap
725 "fonts": [gFont("Regular", 24),gFont("Regular", 22)],
730 <ePixmap pixmap="skin_default/div-h.png" position="0,404" zPosition="10" size="560,2" transparent="1" alphatest="on" />
731 <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" />
734 def __init__(self, session, plugin_path, cmdlist = None):
735 Screen.__init__(self, session)
736 self.session = session
737 self.skin_path = plugin_path
738 self.cmdlist = cmdlist
740 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"],
742 "ok": self.process_all,
745 "green": self.process_extensions,
749 self["list"] = List(self.list)
750 self["key_red"] = StaticText(_("Cancel"))
751 self["key_green"] = StaticText(_("Only extensions."))
752 self["status"] = StaticText(_("Following tasks will be done after you press OK!"))
754 self.onShown.append(self.setWindowTitle)
755 self.onLayoutFinish.append(self.rebuildList)
757 def setWindowTitle(self):
758 self.setTitle(_("Plugin manager activity information"))
760 def rebuildList(self):
762 if self.cmdlist is not None:
763 for entry in self.cmdlist:
775 info = args['package']
777 info = args['package']
779 info = _("Dreambox software because updates are available.")
781 self.list.append(self.buildEntryComponent(action,info))
782 self['list'].setList(self.list)
783 self['list'].updateList(self.list)
785 def buildEntryComponent(self, action,info):
786 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
787 upgradepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgrade.png"))
788 installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/install.png"))
789 removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
790 if action == 'install':
791 return(( _('Installing'), info, installpng, divpng))
792 elif action == 'remove':
793 return(( _('Removing'), info, removepng, divpng))
795 return(( _('Upgrading'), info, upgradepng, divpng))
800 def process_all(self):
801 self.close((True,None))
803 def process_extensions(self):
805 if self.cmdlist is not None:
806 for entry in self.cmdlist:
808 if entry[0] in (0,2):
809 self.list.append((entry))
810 self.close((False,self.list))
813 class PluginManagerHelp(Screen):
815 <screen name="PluginManagerHelp" position="center,center" size="560,450" title="Plugin manager help" >
816 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
817 <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" />
818 <widget source="list" render="Listbox" position="5,50" size="550,350" scrollbarMode="showOnDemand" selectionDisabled="1">
819 <convert type="TemplatedMultiContent">
821 MultiContentEntryText(pos = (50, 0), size = (150, 26), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
822 MultiContentEntryText(pos = (50, 27), size = (540, 23), font=1, flags = RT_HALIGN_LEFT, text = 1), # index 1 is the state
823 MultiContentEntryPixmapAlphaTest(pos = (0, 1), size = (48, 48), png = 2), # index 2 is the status pixmap
824 MultiContentEntryPixmapAlphaTest(pos = (0, 48), size = (550, 2), png = 3), # index 3 is the div pixmap
826 "fonts": [gFont("Regular", 24),gFont("Regular", 22)],
831 <ePixmap pixmap="skin_default/div-h.png" position="0,404" zPosition="10" size="560,2" transparent="1" alphatest="on" />
832 <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" />
835 def __init__(self, session, plugin_path):
836 Screen.__init__(self, session)
837 self.session = session
838 self.skin_path = plugin_path
840 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"],
847 self["list"] = List(self.list)
848 self["key_red"] = StaticText(_("Close"))
849 self["status"] = StaticText(_("A small overview of the available icon states and actions."))
851 self.onShown.append(self.setWindowTitle)
852 self.onLayoutFinish.append(self.rebuildList)
854 def setWindowTitle(self):
855 self.setTitle(_("Plugin manager help"))
857 def rebuildList(self):
859 self.list.append(self.buildEntryComponent('install'))
860 self.list.append(self.buildEntryComponent('installable'))
861 self.list.append(self.buildEntryComponent('installed'))
862 self.list.append(self.buildEntryComponent('remove'))
863 self['list'].setList(self.list)
864 self['list'].updateList(self.list)
866 def buildEntryComponent(self, state):
867 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
868 installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installed.png"))
869 installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installable.png"))
870 removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
871 installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/install.png"))
873 if state == 'installed':
874 return(( _('This plugin is installed.'), _('You can remove this plugin.'), installedpng, divpng))
875 elif state == 'installable':
876 return(( _('This plugin is not installed.'), _('You can install this plugin.'), installablepng, divpng))
877 elif state == 'install':
878 return(( _('This plugin will be installed.'), _('You can cancel the installation.'), installpng, divpng))
879 elif state == 'remove':
880 return(( _('This plugin will be removed.'), _('You can cancel the removal.'), removepng, divpng))
886 class PluginDetails(Screen, DreamInfoHandler):
888 <screen name="PluginDetails" position="center,center" size="600,440" title="Plugin details" >
889 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
890 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
891 <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" />
892 <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" />
893 <widget source="author" render="Label" position="10,50" size="500,25" zPosition="10" font="Regular;21" transparent="1" />
894 <widget name="statuspic" position="550,40" size="48,48" alphatest="on"/>
895 <widget name="divpic" position="0,80" size="600,2" alphatest="on"/>
896 <widget name="detailtext" position="10,90" size="270,330" zPosition="10" font="Regular;21" transparent="1" halign="left" valign="top"/>
897 <widget name="screenshot" position="290,90" size="300,330" alphatest="on"/>
899 def __init__(self, session, plugin_path, packagedata = None):
900 Screen.__init__(self, session)
901 self.skin_path = plugin_path
902 self.language = language.getLanguage()[:2] # getLanguage returns e.g. "fi_FI" for "language_country"
903 self.attributes = None
904 self.translatedAttributes = None
905 DreamInfoHandler.__init__(self, self.statusCallback, blocking = False, language = self.language)
906 self.directory = resolveFilename(SCOPE_METADIR)
908 self.pluginname = packagedata[0]
909 self.details = packagedata[1]
910 self.pluginstate = packagedata[4]
911 self.statuspicinstance = packagedata[5]
912 self.divpicinstance = packagedata[6]
913 self.fillPackageDetails(self.details)
917 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"],
923 "down": self.pageDown,
925 "right": self.pageDown,
928 self["key_red"] = StaticText(_("Close"))
929 self["key_green"] = StaticText("")
930 self["author"] = StaticText()
931 self["statuspic"] = Pixmap()
932 self["divpic"] = Pixmap()
933 self["screenshot"] = Pixmap()
934 self["detailtext"] = ScrollLabel()
936 self["statuspic"].hide()
937 self["screenshot"].hide()
938 self["divpic"].hide()
940 self.package = self.packageDetails[0]
941 if self.package[0].has_key("attributes"):
942 self.attributes = self.package[0]["attributes"]
943 if self.package[0].has_key("translation"):
944 self.translatedAttributes = self.package[0]["translation"]
947 self.oktext = _("\nAfter pressing OK, please wait!")
948 self.picload = ePicLoad()
949 self.picload.PictureData.get().append(self.paintScreenshotPixmapCB)
950 self.onShown.append(self.setWindowTitle)
951 self.onLayoutFinish.append(self.setInfos)
953 def setWindowTitle(self):
954 self.setTitle(_("Details for extension: " + self.pluginname))
960 self["detailtext"].pageUp()
963 self["detailtext"].pageDown()
965 def statusCallback(self, status, progress):
969 if self.translatedAttributes.has_key("name"):
970 self.pluginname = self.translatedAttributes["name"]
971 elif self.attributes.has_key("name"):
972 self.pluginname = self.attributes["name"]
974 self.pluginname = _("unknown")
976 if self.translatedAttributes.has_key("author"):
977 self.author = self.translatedAttributes["author"]
978 elif self.attributes.has_key("author"):
979 self.author = self.attributes["author"]
981 self.author = _("unknown")
983 if self.translatedAttributes.has_key("description"):
984 self.description = self.translatedAttributes["description"]
985 elif self.attributes.has_key("description"):
986 self.description = self.attributes["description"]
988 self.description = _("No description available.")
990 if self.translatedAttributes.has_key("screenshot"):
991 self.loadThumbnail(self.translatedAttributes)
993 self.loadThumbnail(self.attributes)
995 self["author"].setText(_("Author: ") + self.author)
996 self["detailtext"].setText(self.description.strip())
997 if self.pluginstate in ('installable', 'install'):
998 self["key_green"].setText(_("Install"))
1000 self["key_green"].setText(_("Remove"))
1002 def loadThumbnail(self, entry):
1004 if entry.has_key("screenshot"):
1005 thumbnailUrl = entry["screenshot"]
1006 if thumbnailUrl is not None:
1007 self.thumbnail = "/tmp/" + thumbnailUrl.split('/')[-1]
1008 print "[PluginDetails] downloading screenshot " + thumbnailUrl + " to " + self.thumbnail
1009 client.downloadPage(thumbnailUrl,self.thumbnail).addCallback(self.setThumbnail).addErrback(self.fetchFailed)
1011 self.setThumbnail(noScreenshot = True)
1013 def setThumbnail(self, noScreenshot = False):
1014 if not noScreenshot:
1015 filename = self.thumbnail
1017 filename = resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/noprev.png")
1019 sc = AVSwitch().getFramebufferScale()
1020 self.picload.setPara((self["screenshot"].instance.size().width(), self["screenshot"].instance.size().height(), sc[0], sc[1], False, 1, "#00000000"))
1021 self.picload.startDecode(filename)
1023 if self.statuspicinstance != None:
1024 self["statuspic"].instance.setPixmap(self.statuspicinstance.__deref__())
1025 self["statuspic"].show()
1026 if self.divpicinstance != None:
1027 self["divpic"].instance.setPixmap(self.divpicinstance.__deref__())
1028 self["divpic"].show()
1030 def paintScreenshotPixmapCB(self, picInfo=None):
1031 ptr = self.picload.getData()
1033 self["screenshot"].instance.setPixmap(ptr.__deref__())
1034 self["screenshot"].show()
1036 self.setThumbnail(noScreenshot = True)
1039 if self.attributes.has_key("package"):
1040 self.packagefiles = self.attributes["package"]
1042 if self.pluginstate in ('installed', 'remove'):
1043 if self.packagefiles:
1044 for package in self.packagefiles[:]:
1045 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": package["name"] }))
1046 if len(self.cmdList):
1047 self.session.openWithCallback(self.runRemove, MessageBox, _("Do you want to remove the package:\n") + self.pluginname + "\n" + self.oktext)
1049 if self.packagefiles:
1050 for package in self.packagefiles[:]:
1051 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package["name"] }))
1052 if len(self.cmdList):
1053 self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to install the package:\n") + self.pluginname + "\n" + self.oktext)
1055 def runUpgrade(self, result):
1057 self.session.openWithCallback(self.runUpgradeFinished, Ipkg, cmdList = self.cmdList)
1059 def runUpgradeFinished(self):
1060 self.session.openWithCallback(self.UpgradeReboot, MessageBox, _("Installation finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
1062 def UpgradeReboot(self, result):
1070 def runRemove(self, result):
1072 self.session.openWithCallback(self.runRemoveFinished, Ipkg, cmdList = self.cmdList)
1074 def runRemoveFinished(self):
1075 self.session.openWithCallback(self.RemoveReboot, MessageBox, _("Remove finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
1077 def RemoveReboot(self, result):
1085 def reloadPluginlist(self):
1086 plugins.readPluginList(resolveFilename(SCOPE_PLUGINS))
1088 def fetchFailed(self,string):
1089 self.setThumbnail(noScreenshot = True)
1090 print "[PluginDetails] fetch failed " + string.getErrorMessage()
1093 class UpdatePlugin(Screen):
1095 <screen name="UpdatePlugin" position="center,center" size="550,200" title="Software update" >
1096 <widget name="activityslider" position="0,0" size="550,5" />
1097 <widget name="slider" position="0,150" size="550,30" />
1098 <widget source="package" render="Label" position="10,30" size="540,20" font="Regular;18" halign="center" valign="center" backgroundColor="#25062748" transparent="1" />
1099 <widget source="status" render="Label" position="10,60" size="540,45" font="Regular;20" halign="center" valign="center" backgroundColor="#25062748" transparent="1" />
1102 def __init__(self, session, args = None):
1103 Screen.__init__(self, session)
1105 self.sliderPackages = { "dreambox-dvb-modules": 1, "enigma2": 2, "tuxbox-image-info": 3 }
1107 self.slider = Slider(0, 4)
1108 self["slider"] = self.slider
1109 self.activityslider = Slider(0, 100)
1110 self["activityslider"] = self.activityslider
1111 self.status = StaticText(_("Upgrading Dreambox... Please wait"))
1112 self["status"] = self.status
1113 self.package = StaticText()
1114 self["package"] = self.package
1120 self.activityTimer = eTimer()
1121 self.activityTimer.callback.append(self.doActivityTimer)
1122 self.activityTimer.start(100, False)
1124 self.ipkg = IpkgComponent()
1125 self.ipkg.addCallback(self.ipkgCallback)
1127 self.updating = True
1128 self.package.setText(_("Package list update"))
1129 self.ipkg.startCmd(IpkgComponent.CMD_UPDATE)
1131 self["actions"] = ActionMap(["WizardActions"],
1137 def doActivityTimer(self):
1139 if self.activity == 100:
1141 self.activityslider.setValue(self.activity)
1143 def ipkgCallback(self, event, param):
1144 if event == IpkgComponent.EVENT_DOWNLOAD:
1145 self.status.setText(_("Downloading"))
1146 elif event == IpkgComponent.EVENT_UPGRADE:
1147 if self.sliderPackages.has_key(param):
1148 self.slider.setValue(self.sliderPackages[param])
1149 self.package.setText(param)
1150 self.status.setText(_("Upgrading"))
1152 elif event == IpkgComponent.EVENT_INSTALL:
1153 self.package.setText(param)
1154 self.status.setText(_("Installing"))
1156 elif event == IpkgComponent.EVENT_CONFIGURING:
1157 self.package.setText(param)
1158 self.status.setText(_("Configuring"))
1159 elif event == IpkgComponent.EVENT_MODIFIED:
1160 self.session.openWithCallback(
1161 self.modificationCallback,
1163 _("A configuration file (%s) was modified since Installation.\nDo you want to keep your version?") % (param)
1165 elif event == IpkgComponent.EVENT_ERROR:
1167 elif event == IpkgComponent.EVENT_DONE:
1169 self.updating = False
1170 self.ipkg.startCmd(IpkgComponent.CMD_UPGRADE, args = {'test_only': False})
1171 elif self.error == 0:
1172 self.slider.setValue(4)
1174 self.activityTimer.stop()
1175 self.activityslider.setValue(0)
1177 self.package.setText("")
1178 self.status.setText(_("Done - Installed or upgraded %d packages") % self.packages)
1180 self.activityTimer.stop()
1181 self.activityslider.setValue(0)
1182 error = _("your dreambox might be unusable now. Please consult the manual for further assistance before rebooting your dreambox.")
1183 if self.packages == 0:
1184 error = _("No packages were upgraded yet. So you can check your network and try again.")
1186 error = _("Your dreambox isn't connected to the internet properly. Please check it and try again.")
1187 self.status.setText(_("Error") + " - " + error)
1188 #print event, "-", param
1191 def modificationCallback(self, res):
1192 self.ipkg.write(res and "N" or "Y")
1195 if not self.ipkg.isRunning():
1196 if self.packages != 0 and self.error == 0:
1197 self.session.openWithCallback(self.exitAnswer, MessageBox, _("Upgrade finished.") +" "+_("Do you want to reboot your Dreambox?"))
1201 def exitAnswer(self, result):
1202 if result is not None and result:
1208 class IPKGMenu(Screen):
1210 <screen name="IPKGMenu" position="center,center" size="560,400" title="Select upgrade source to edit." >
1211 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1212 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1213 <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" />
1214 <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" />
1215 <widget name="filelist" position="5,50" size="550,340" scrollbarMode="showOnDemand" />
1218 def __init__(self, session, plugin_path):
1219 Screen.__init__(self, session)
1220 self.skin_path = plugin_path
1222 self["key_red"] = StaticText(_("Close"))
1223 self["key_green"] = StaticText(_("Edit"))
1232 self["actions"] = NumberActionMap(["SetupActions"],
1235 "cancel": self.keyCancel
1238 self["shortcuts"] = ActionMap(["ShortcutActions"],
1240 "red": self.keyCancel,
1241 "green": self.KeyOk,
1244 self["filelist"] = MenuList(self.flist)
1246 self.onLayoutFinish.append(self.layoutFinished)
1248 def layoutFinished(self):
1249 self.setWindowTitle()
1251 def setWindowTitle(self):
1252 self.setTitle(_("Select upgrade source to edit."))
1254 def fill_list(self):
1256 self.path = '/etc/ipkg/'
1257 if (os_path.exists(self.path) == False):
1260 for file in listdir(self.path):
1261 if (file.endswith(".conf")):
1262 if file != 'arch.conf':
1263 self.flist.append((file))
1265 self["filelist"].l.setList(self.flist)
1268 if (self.exe == False) and (self.entry == True):
1269 self.sel = self["filelist"].getCurrent()
1270 self.val = self.path + self.sel
1271 self.session.open(IPKGSource, self.val)
1273 def keyCancel(self):
1280 class IPKGSource(Screen):
1282 <screen name="IPKGSource" position="center,center" size="560,80" title="Edit upgrade source url." >
1283 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1284 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1285 <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" />
1286 <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" />
1287 <widget name="text" position="5,50" size="550,25" font="Regular;20" backgroundColor="background" foregroundColor="#cccccc" />
1290 def __init__(self, session, configfile = None):
1291 Screen.__init__(self, session)
1292 self.session = session
1293 self.configfile = configfile
1297 fp = file(configfile, 'r')
1298 sources = fp.readlines()
1305 desk = getDesktop(0)
1306 x= int(desk.size().width())
1307 y= int(desk.size().height())
1309 self["key_red"] = StaticText(_("Cancel"))
1310 self["key_green"] = StaticText(_("Save"))
1313 self["text"] = Input(text, maxSize=False, type=Input.TEXT)
1315 self["text"] = Input(text, maxSize=False, visible_width = 55, type=Input.TEXT)
1317 self["actions"] = NumberActionMap(["WizardActions", "InputActions", "TextEntryActions", "KeyboardInputActions","ShortcutActions"],
1323 "left": self.keyLeft,
1324 "right": self.keyRight,
1325 "home": self.keyHome,
1327 "deleteForward": self.keyDeleteForward,
1328 "deleteBackward": self.keyDeleteBackward,
1329 "1": self.keyNumberGlobal,
1330 "2": self.keyNumberGlobal,
1331 "3": self.keyNumberGlobal,
1332 "4": self.keyNumberGlobal,
1333 "5": self.keyNumberGlobal,
1334 "6": self.keyNumberGlobal,
1335 "7": self.keyNumberGlobal,
1336 "8": self.keyNumberGlobal,
1337 "9": self.keyNumberGlobal,
1338 "0": self.keyNumberGlobal
1341 self.onLayoutFinish.append(self.layoutFinished)
1343 def layoutFinished(self):
1344 self.setWindowTitle()
1345 self["text"].right()
1347 def setWindowTitle(self):
1348 self.setTitle(_("Edit upgrade source url."))
1351 text = self["text"].getText()
1353 fp = file(self.configfile, 'w')
1363 self["text"].right()
1371 def keyDeleteForward(self):
1372 self["text"].delete()
1374 def keyDeleteBackward(self):
1375 self["text"].deleteBackward()
1377 def keyNumberGlobal(self, number):
1378 self["text"].number(number)
1381 class PacketManager(Screen):
1383 <screen name="PacketManager" position="center,center" size="530,420" title="Packet manager" >
1384 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1385 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1386 <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" />
1387 <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" />
1388 <widget source="list" render="Listbox" position="5,50" size="520,365" scrollbarMode="showOnDemand">
1389 <convert type="TemplatedMultiContent">
1391 MultiContentEntryText(pos = (5, 1), size = (440, 28), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
1392 MultiContentEntryText(pos = (5, 26), size = (440, 20), font=1, flags = RT_HALIGN_LEFT, text = 2), # index 2 is the description
1393 MultiContentEntryPixmapAlphaTest(pos = (445, 2), size = (48, 48), png = 4), # index 4 is the status pixmap
1394 MultiContentEntryPixmapAlphaTest(pos = (5, 50), size = (510, 2), png = 5), # index 4 is the div pixmap
1396 "fonts": [gFont("Regular", 22),gFont("Regular", 14)],
1403 def __init__(self, session, plugin_path, args = None):
1404 Screen.__init__(self, session)
1405 self.session = session
1406 self.skin_path = plugin_path
1408 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"],
1413 "green": self.reload,
1417 self.statuslist = []
1418 self["list"] = List(self.list)
1419 self["key_red"] = StaticText(_("Close"))
1420 self["key_green"] = StaticText(_("Reload"))
1422 self.list_updating = True
1423 self.packetlist = []
1424 self.installed_packetlist = {}
1425 self.Console = Console()
1428 self.cache_ttl = 86400 #600 is default, 0 disables, Seconds cache is considered valid (24h should be ok for caching ipkgs)
1429 self.cache_file = '/usr/lib/enigma2/python/Plugins/SystemPlugins/SoftwareManager/packetmanager.cache' #Path to cache directory
1430 self.oktext = _("\nAfter pressing OK, please wait!")
1431 self.unwanted_extensions = ('-dbg', '-dev', '-doc', 'busybox')
1433 self.ipkg = IpkgComponent()
1434 self.ipkg.addCallback(self.ipkgCallback)
1435 self.onShown.append(self.setWindowTitle)
1436 self.onLayoutFinish.append(self.rebuildList)
1440 if self.Console is not None:
1441 if len(self.Console.appContainers):
1442 for name in self.Console.appContainers.keys():
1443 self.Console.kill(name)
1447 if (os_path.exists(self.cache_file) == True):
1448 remove(self.cache_file)
1449 self.list_updating = True
1452 def setWindowTitle(self):
1453 self.setTitle(_("Packet manager"))
1455 def setStatus(self,status = None):
1457 self.statuslist = []
1458 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
1459 if status == 'update':
1460 statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgrade.png"))
1461 self.statuslist.append(( _("Package list update"), '', _("Trying to download a new packetlist. Please wait..." ),'',statuspng, divpng ))
1462 self['list'].setList(self.statuslist)
1463 elif status == 'error':
1464 statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
1465 self.statuslist.append(( _("Error"), '', _("There was an error downloading the packetlist. Please try again." ),'',statuspng, divpng ))
1466 self['list'].setList(self.statuslist)
1468 def rebuildList(self):
1469 self.setStatus('update')
1471 self.vc = valid_cache(self.cache_file, self.cache_ttl)
1472 if self.cache_ttl > 0 and self.vc != 0:
1474 self.buildPacketList()
1477 if self.cache_ttl == 0 or self.inv_cache == 1 or self.vc == 0:
1479 self.ipkg.startCmd(IpkgComponent.CMD_UPDATE)
1481 def go(self, returnValue = None):
1482 cur = self["list"].getCurrent()
1487 if status == 'installed':
1488 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": package }))
1489 if len(self.cmdList):
1490 self.session.openWithCallback(self.runRemove, MessageBox, _("Do you want to remove the package:\n") + package + "\n" + self.oktext)
1491 elif status == 'upgradeable':
1492 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package }))
1493 if len(self.cmdList):
1494 self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to upgrade the package:\n") + package + "\n" + self.oktext)
1495 elif status == "installable":
1496 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package }))
1497 if len(self.cmdList):
1498 self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to install the package:\n") + package + "\n" + self.oktext)
1500 def runRemove(self, result):
1502 self.session.openWithCallback(self.runRemoveFinished, Ipkg, cmdList = self.cmdList)
1504 def runRemoveFinished(self):
1505 self.session.openWithCallback(self.RemoveReboot, MessageBox, _("Remove finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
1507 def RemoveReboot(self, result):
1511 cur = self["list"].getCurrent()
1513 item = self['list'].getIndex()
1514 self.list[item] = self.buildEntryComponent(cur[0], cur[1], cur[2], 'installable')
1515 self.cachelist[item] = [cur[0], cur[1], cur[2], 'installable']
1516 self['list'].setList(self.list)
1517 write_cache(self.cache_file, self.cachelist)
1518 self.reloadPluginlist()
1522 def runUpgrade(self, result):
1524 self.session.openWithCallback(self.runUpgradeFinished, Ipkg, cmdList = self.cmdList)
1526 def runUpgradeFinished(self):
1527 self.session.openWithCallback(self.UpgradeReboot, MessageBox, _("Upgrade finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
1529 def UpgradeReboot(self, result):
1533 cur = self["list"].getCurrent()
1535 item = self['list'].getIndex()
1536 self.list[item] = self.buildEntryComponent(cur[0], cur[1], cur[2], 'installed')
1537 self.cachelist[item] = [cur[0], cur[1], cur[2], 'installed']
1538 self['list'].setList(self.list)
1539 write_cache(self.cache_file, self.cachelist)
1540 self.reloadPluginlist()
1544 def ipkgCallback(self, event, param):
1545 if event == IpkgComponent.EVENT_ERROR:
1546 self.list_updating = False
1547 self.setStatus('error')
1548 elif event == IpkgComponent.EVENT_DONE:
1549 if self.list_updating:
1550 self.list_updating = False
1551 if not self.Console:
1552 self.Console = Console()
1554 self.Console.ePopen(cmd, self.IpkgList_Finished)
1555 #print event, "-", param
1558 def IpkgList_Finished(self, result, retval, extra_args = None):
1560 self.packetlist = []
1561 for x in result.splitlines():
1562 split = x.split(' - ') #self.blacklisted_packages
1563 if not any(split[0].strip().endswith(x) for x in self.unwanted_extensions):
1564 self.packetlist.append([split[0].strip(), split[1].strip(),split[2].strip()])
1565 if not self.Console:
1566 self.Console = Console()
1567 cmd = "ipkg list_installed"
1568 self.Console.ePopen(cmd, self.IpkgListInstalled_Finished)
1570 def IpkgListInstalled_Finished(self, result, retval, extra_args = None):
1572 self.installed_packetlist = {}
1573 for x in result.splitlines():
1574 split = x.split(' - ')
1575 if not any(split[0].strip().endswith(x) for x in self.unwanted_extensions):
1576 self.installed_packetlist[split[0].strip()] = split[1].strip()
1577 self.buildPacketList()
1579 def buildEntryComponent(self, name, version, description, state):
1580 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
1581 if state == 'installed':
1582 installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installed.png"))
1583 return((name, version, description, state, installedpng, divpng))
1584 elif state == 'upgradeable':
1585 upgradeablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgradeable.png"))
1586 return((name, version, description, state, upgradeablepng, divpng))
1588 installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installable.png"))
1589 return((name, version, description, state, installablepng, divpng))
1591 def buildPacketList(self):
1595 if self.cache_ttl > 0 and self.vc != 0:
1596 print 'Loading packagelist cache from ',self.cache_file
1598 self.cachelist = load_cache(self.cache_file)
1599 if len(self.cachelist) > 0:
1600 for x in self.cachelist:
1601 self.list.append(self.buildEntryComponent(x[0], x[1], x[2], x[3]))
1602 self['list'].setList(self.list)
1606 if self.cache_ttl == 0 or self.inv_cache == 1 or self.vc == 0:
1607 print 'rebuilding fresh package list'
1608 for x in self.packetlist:
1610 if self.installed_packetlist.has_key(x[0].strip()):
1611 if self.installed_packetlist[x[0].strip()] == x[1].strip():
1612 status = "installed"
1613 self.list.append(self.buildEntryComponent(x[0].strip(), x[1].strip(), x[2].strip(), status))
1615 status = "upgradeable"
1616 self.list.append(self.buildEntryComponent(x[0].strip(), x[1].strip(), x[2].strip(), status))
1618 status = "installable"
1619 self.list.append(self.buildEntryComponent(x[0].strip(), x[1].strip(), x[2].strip(), status))
1620 if not any(x[0].strip().endswith(x) for x in self.unwanted_extensions):
1621 self.cachelist.append([x[0].strip(), x[1].strip(), x[2].strip(), status])
1622 write_cache(self.cache_file, self.cachelist)
1623 self['list'].setList(self.list)
1625 def reloadPluginlist(self):
1626 plugins.readPluginList(resolveFilename(SCOPE_PLUGINS))
1628 class IpkgInstaller(Screen):
1630 <screen name="IpkgInstaller" position="center,center" size="550,450" title="Install extensions" >
1631 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1632 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1633 <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" />
1634 <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" />
1635 <widget name="list" position="5,50" size="540,360" />
1636 <ePixmap pixmap="skin_default/div-h.png" position="0,410" zPosition="10" size="560,2" transparent="1" alphatest="on" />
1637 <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" />
1640 def __init__(self, session, list):
1641 Screen.__init__(self, session)
1643 self.list = SelectionList()
1644 self["list"] = self.list
1645 for listindex in range(len(list)):
1646 self.list.addSelection(list[listindex], list[listindex], listindex, True)
1648 self["key_red"] = StaticText(_("Close"))
1649 self["key_green"] = StaticText(_("Install"))
1650 self["introduction"] = StaticText(_("Press OK to toggle the selection."))
1652 self["actions"] = ActionMap(["OkCancelActions", "ColorActions"],
1654 "ok": self.list.toggleSelection,
1655 "cancel": self.close,
1657 "green": self.install
1661 list = self.list.getSelectionsList()
1664 cmdList.append((IpkgComponent.CMD_INSTALL, { "package": item[1] }))
1665 self.session.open(Ipkg, cmdList = cmdList)
1668 def filescan_open(list, session, **kwargs):
1669 filelist = [x.path for x in list]
1670 session.open(IpkgInstaller, filelist) # list
1672 def filescan(**kwargs):
1673 from Components.Scanner import Scanner, ScanPath
1675 Scanner(mimetypes = ["application/x-debian-package"],
1678 ScanPath(path = "ipk", with_subdirs = True),
1679 ScanPath(path = "", with_subdirs = False),
1682 description = _("Install extensions."),
1683 openfnc = filescan_open, )
1687 def UpgradeMain(session, **kwargs):
1688 session.open(UpdatePluginMenu)
1690 def startSetup(menuid):
1691 if menuid != "setup":
1693 return [(_("Software management"), UpgradeMain, "software_manager", 50)]
1695 def autostart(reason, **kwargs):
1697 iSoftwareTools.startSoftwareTools()
1699 def Plugins(path, **kwargs):
1703 PluginDescriptor(where = [PluginDescriptor.WHERE_NETWORKCONFIG_READ], fnc = autostart),
1704 PluginDescriptor(name=_("Software management"), description=_("Manage your receiver's software"), where = PluginDescriptor.WHERE_MENU, fnc=startSetup),
1705 PluginDescriptor(name=_("Ipkg"), where = PluginDescriptor.WHERE_FILESCAN, fnc = filescan)
1707 if config.usage.setup_level.index >= 2: # expert+
1708 list.append(PluginDescriptor(name=_("Software management"), description=_("Manage your receiver's software"), where = PluginDescriptor.WHERE_EXTENSIONSMENU, fnc=UpgradeMain))