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 print "ATTRIBUTES",attributes
571 if attributes.has_key("packagetype"):
572 print "PACKAGETYPE",attributes["packagetype"]
573 if attributes["packagetype"] == "internal":
575 self.packetlist.append([attributes["name"], attributes["details"], attributes["shortdescription"], attributes["packagename"]])
577 self.packetlist.append([attributes["name"], attributes["details"], attributes["shortdescription"], attributes["packagename"]])
579 for x in self.packetlist:
582 details = x[1].strip()
583 description = x[2].strip()
584 packagename = x[3].strip()
585 selectState = self.getSelectionState(details)
586 if iSoftwareTools.installed_packetlist.has_key(packagename):
587 if selectState == True:
591 self.list.append(self.buildEntryComponent(name, details, description, packagename, status, selected = selectState))
593 if selectState == True:
596 status = "installable"
597 self.list.append(self.buildEntryComponent(name, details, description, packagename, status, selected = selectState))
599 self.list.sort(key=lambda x: x[0])
600 self["list"].style = "default"
601 self['list'].setList(self.list)
602 self["list"].updateList(self.list)
603 self.selectionChanged()
605 def buildCategoryList(self):
606 self.currList = "category"
608 self.categoryList = []
609 for package in iSoftwareTools.packagesIndexlist[:]:
610 prerequisites = package[0]["prerequisites"]
611 if prerequisites.has_key("tag"):
612 for foundtag in prerequisites["tag"]:
613 attributes = package[0]["attributes"]
614 if foundtag not in self.categories:
615 self.categories.append(foundtag)
616 self.categoryList.append(self.buildCategoryComponent(foundtag))
617 self.categoryList.sort(key=lambda x: x[0])
618 self["list"].style = "category"
619 self['list'].setList(self.categoryList)
620 self["list"].updateList(self.categoryList)
621 self.selectionChanged()
623 def buildCategoryComponent(self, tag = None):
624 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
627 return(( _("System"), _("View list of available system extensions" ), tag, divpng ))
629 return(( _("Skins"), _("View list of available skins" ), tag, divpng ))
630 elif tag == 'Recording':
631 return(( _("Recordings"), _("View list of available recording extensions" ), tag, divpng ))
632 elif tag == 'Network':
633 return(( _("Network"), _("View list of available networking extensions" ), tag, divpng ))
635 return(( _("CommonInterface"), _("View list of available CommonInterface extensions" ), tag, divpng ))
636 elif tag == 'Default':
637 return(( _("Default Settings"), _("View list of available default settings" ), tag, divpng ))
639 return(( _("Satteliteequipment"), _("View list of available Satteliteequipment extensions." ), tag, divpng ))
640 elif tag == 'Software':
641 return(( _("Software"), _("View list of available software extensions" ), tag, divpng ))
642 elif tag == 'Multimedia':
643 return(( _("Multimedia"), _("View list of available multimedia extensions." ), tag, divpng ))
644 elif tag == 'Display':
645 return(( _("Display and Userinterface"), _("View list of available Display and Userinterface extensions." ), tag, divpng ))
647 return(( _("Electronic Program Guide"), _("View list of available EPG extensions." ), tag, divpng ))
648 elif tag == 'Communication':
649 return(( _("Communication"), _("View list of available communication extensions." ), tag, divpng ))
650 else: # dynamically generate non existent tags
651 return(( str(tag), _("View list of available ") + str(tag) + _(" extensions." ), tag, divpng ))
653 def prepareInstall(self):
655 if iSoftwareTools.available_updates > 0:
656 self.cmdList.append((IpkgComponent.CMD_UPGRADE, { "test_only": False }))
657 if self.selectedFiles and len(self.selectedFiles):
658 for plugin in self.selectedFiles:
659 detailsfile = iSoftwareTools.directory[0] + "/" + plugin[0]
660 if (os_path.exists(detailsfile) == True):
661 iSoftwareTools.fillPackageDetails(plugin[0])
662 self.package = iSoftwareTools.packageDetails[0]
663 if self.package[0].has_key("attributes"):
664 self.attributes = self.package[0]["attributes"]
665 if self.attributes.has_key("package"):
666 self.packagefiles = self.attributes["package"]
667 if plugin[1] == 'installed':
668 if self.packagefiles:
669 for package in self.packagefiles[:]:
670 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": package["name"] }))
672 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": plugin[2] }))
674 if self.packagefiles:
675 for package in self.packagefiles[:]:
676 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package["name"] }))
678 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": plugin[2] }))
680 if plugin[1] == 'installed':
681 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": plugin[2] }))
683 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": plugin[2] }))
685 def runExecute(self, result = None):
686 if result is not None:
687 if result[0] is True:
688 self.session.openWithCallback(self.runExecuteFinished, Ipkg, cmdList = self.cmdList)
689 elif result[0] is False:
690 self.cmdList = result[1]
691 self.session.openWithCallback(self.runExecuteFinished, Ipkg, cmdList = self.cmdList)
695 def runExecuteFinished(self):
696 self.session.openWithCallback(self.ExecuteReboot, MessageBox, _("Install or remove finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
698 def ExecuteReboot(self, result):
702 self.reloadPluginlist()
703 self.selectedFiles = None
704 self.detailsClosed(True)
708 def reloadPluginlist(self):
709 plugins.readPluginList(resolveFilename(SCOPE_PLUGINS))
712 class PluginManagerInfo(Screen):
714 <screen name="PluginManagerInfo" position="center,center" size="560,450" title="Plugin manager activity information" >
715 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
716 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
717 <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" />
718 <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" />
719 <widget source="list" render="Listbox" position="5,50" size="550,350" scrollbarMode="showOnDemand" selectionDisabled="1">
720 <convert type="TemplatedMultiContent">
722 MultiContentEntryText(pos = (50, 0), size = (150, 26), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
723 MultiContentEntryText(pos = (50, 27), size = (540, 23), font=1, flags = RT_HALIGN_LEFT, text = 1), # index 1 is the state
724 MultiContentEntryPixmapAlphaTest(pos = (0, 1), size = (48, 48), png = 2), # index 2 is the status pixmap
725 MultiContentEntryPixmapAlphaTest(pos = (0, 48), size = (550, 2), png = 3), # index 3 is the div pixmap
727 "fonts": [gFont("Regular", 24),gFont("Regular", 22)],
732 <ePixmap pixmap="skin_default/div-h.png" position="0,404" zPosition="10" size="560,2" transparent="1" alphatest="on" />
733 <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" />
736 def __init__(self, session, plugin_path, cmdlist = None):
737 Screen.__init__(self, session)
738 self.session = session
739 self.skin_path = plugin_path
740 self.cmdlist = cmdlist
742 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"],
744 "ok": self.process_all,
747 "green": self.process_extensions,
751 self["list"] = List(self.list)
752 self["key_red"] = StaticText(_("Cancel"))
753 self["key_green"] = StaticText(_("Only extensions."))
754 self["status"] = StaticText(_("Following tasks will be done after you press OK!"))
756 self.onShown.append(self.setWindowTitle)
757 self.onLayoutFinish.append(self.rebuildList)
759 def setWindowTitle(self):
760 self.setTitle(_("Plugin manager activity information"))
762 def rebuildList(self):
764 if self.cmdlist is not None:
765 for entry in self.cmdlist:
777 info = args['package']
779 info = args['package']
781 info = _("Dreambox software because updates are available.")
783 self.list.append(self.buildEntryComponent(action,info))
784 self['list'].setList(self.list)
785 self['list'].updateList(self.list)
787 def buildEntryComponent(self, action,info):
788 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
789 upgradepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgrade.png"))
790 installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/install.png"))
791 removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
792 if action == 'install':
793 return(( _('Installing'), info, installpng, divpng))
794 elif action == 'remove':
795 return(( _('Removing'), info, removepng, divpng))
797 return(( _('Upgrading'), info, upgradepng, divpng))
802 def process_all(self):
803 self.close((True,None))
805 def process_extensions(self):
807 if self.cmdlist is not None:
808 for entry in self.cmdlist:
810 if entry[0] in (0,2):
811 self.list.append((entry))
812 self.close((False,self.list))
815 class PluginManagerHelp(Screen):
817 <screen name="PluginManagerHelp" position="center,center" size="560,450" title="Plugin manager help" >
818 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
819 <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" />
820 <widget source="list" render="Listbox" position="5,50" size="550,350" scrollbarMode="showOnDemand" selectionDisabled="1">
821 <convert type="TemplatedMultiContent">
823 MultiContentEntryText(pos = (50, 0), size = (150, 26), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
824 MultiContentEntryText(pos = (50, 27), size = (540, 23), font=1, flags = RT_HALIGN_LEFT, text = 1), # index 1 is the state
825 MultiContentEntryPixmapAlphaTest(pos = (0, 1), size = (48, 48), png = 2), # index 2 is the status pixmap
826 MultiContentEntryPixmapAlphaTest(pos = (0, 48), size = (550, 2), png = 3), # index 3 is the div pixmap
828 "fonts": [gFont("Regular", 24),gFont("Regular", 22)],
833 <ePixmap pixmap="skin_default/div-h.png" position="0,404" zPosition="10" size="560,2" transparent="1" alphatest="on" />
834 <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" />
837 def __init__(self, session, plugin_path):
838 Screen.__init__(self, session)
839 self.session = session
840 self.skin_path = plugin_path
842 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"],
849 self["list"] = List(self.list)
850 self["key_red"] = StaticText(_("Close"))
851 self["status"] = StaticText(_("A small overview of the available icon states and actions."))
853 self.onShown.append(self.setWindowTitle)
854 self.onLayoutFinish.append(self.rebuildList)
856 def setWindowTitle(self):
857 self.setTitle(_("Plugin manager help"))
859 def rebuildList(self):
861 self.list.append(self.buildEntryComponent('install'))
862 self.list.append(self.buildEntryComponent('installable'))
863 self.list.append(self.buildEntryComponent('installed'))
864 self.list.append(self.buildEntryComponent('remove'))
865 self['list'].setList(self.list)
866 self['list'].updateList(self.list)
868 def buildEntryComponent(self, state):
869 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
870 installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installed.png"))
871 installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installable.png"))
872 removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
873 installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/install.png"))
875 if state == 'installed':
876 return(( _('This plugin is installed.'), _('You can remove this plugin.'), installedpng, divpng))
877 elif state == 'installable':
878 return(( _('This plugin is not installed.'), _('You can install this plugin.'), installablepng, divpng))
879 elif state == 'install':
880 return(( _('This plugin will be installed.'), _('You can cancel the installation.'), installpng, divpng))
881 elif state == 'remove':
882 return(( _('This plugin will be removed.'), _('You can cancel the removal.'), removepng, divpng))
888 class PluginDetails(Screen, DreamInfoHandler):
890 <screen name="PluginDetails" position="center,center" size="600,440" title="Plugin details" >
891 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
892 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
893 <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" />
894 <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" />
895 <widget source="author" render="Label" position="10,50" size="500,25" zPosition="10" font="Regular;21" transparent="1" />
896 <widget name="statuspic" position="550,40" size="48,48" alphatest="on"/>
897 <widget name="divpic" position="0,80" size="600,2" alphatest="on"/>
898 <widget name="detailtext" position="10,90" size="270,330" zPosition="10" font="Regular;21" transparent="1" halign="left" valign="top"/>
899 <widget name="screenshot" position="290,90" size="300,330" alphatest="on"/>
901 def __init__(self, session, plugin_path, packagedata = None):
902 Screen.__init__(self, session)
903 self.skin_path = plugin_path
904 self.language = language.getLanguage()[:2] # getLanguage returns e.g. "fi_FI" for "language_country"
905 self.attributes = None
906 self.translatedAttributes = None
907 DreamInfoHandler.__init__(self, self.statusCallback, blocking = False, language = self.language)
908 self.directory = resolveFilename(SCOPE_METADIR)
910 self.pluginname = packagedata[0]
911 self.details = packagedata[1]
912 self.pluginstate = packagedata[4]
913 self.statuspicinstance = packagedata[5]
914 self.divpicinstance = packagedata[6]
915 self.fillPackageDetails(self.details)
919 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"],
925 "down": self.pageDown,
927 "right": self.pageDown,
930 self["key_red"] = StaticText(_("Close"))
931 self["key_green"] = StaticText("")
932 self["author"] = StaticText()
933 self["statuspic"] = Pixmap()
934 self["divpic"] = Pixmap()
935 self["screenshot"] = Pixmap()
936 self["detailtext"] = ScrollLabel()
938 self["statuspic"].hide()
939 self["screenshot"].hide()
940 self["divpic"].hide()
942 self.package = self.packageDetails[0]
943 if self.package[0].has_key("attributes"):
944 self.attributes = self.package[0]["attributes"]
945 if self.package[0].has_key("translation"):
946 self.translatedAttributes = self.package[0]["translation"]
949 self.oktext = _("\nAfter pressing OK, please wait!")
950 self.picload = ePicLoad()
951 self.picload.PictureData.get().append(self.paintScreenshotPixmapCB)
952 self.onShown.append(self.setWindowTitle)
953 self.onLayoutFinish.append(self.setInfos)
955 def setWindowTitle(self):
956 self.setTitle(_("Details for extension: " + self.pluginname))
962 self["detailtext"].pageUp()
965 self["detailtext"].pageDown()
967 def statusCallback(self, status, progress):
971 if self.translatedAttributes.has_key("name"):
972 self.pluginname = self.translatedAttributes["name"]
973 elif self.attributes.has_key("name"):
974 self.pluginname = self.attributes["name"]
976 self.pluginname = _("unknown")
978 if self.translatedAttributes.has_key("author"):
979 self.author = self.translatedAttributes["author"]
980 elif self.attributes.has_key("author"):
981 self.author = self.attributes["author"]
983 self.author = _("unknown")
985 if self.translatedAttributes.has_key("description"):
986 self.description = self.translatedAttributes["description"]
987 elif self.attributes.has_key("description"):
988 self.description = self.attributes["description"]
990 self.description = _("No description available.")
992 if self.translatedAttributes.has_key("screenshot"):
993 self.loadThumbnail(self.translatedAttributes)
995 self.loadThumbnail(self.attributes)
997 self["author"].setText(_("Author: ") + self.author)
998 self["detailtext"].setText(self.description.strip())
999 if self.pluginstate in ('installable', 'install'):
1000 self["key_green"].setText(_("Install"))
1002 self["key_green"].setText(_("Remove"))
1004 def loadThumbnail(self, entry):
1006 if entry.has_key("screenshot"):
1007 thumbnailUrl = entry["screenshot"]
1008 if thumbnailUrl is not None:
1009 self.thumbnail = "/tmp/" + thumbnailUrl.split('/')[-1]
1010 print "[PluginDetails] downloading screenshot " + thumbnailUrl + " to " + self.thumbnail
1011 client.downloadPage(thumbnailUrl,self.thumbnail).addCallback(self.setThumbnail).addErrback(self.fetchFailed)
1013 self.setThumbnail(noScreenshot = True)
1015 def setThumbnail(self, noScreenshot = False):
1016 if not noScreenshot:
1017 filename = self.thumbnail
1019 filename = resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/noprev.png")
1021 sc = AVSwitch().getFramebufferScale()
1022 self.picload.setPara((self["screenshot"].instance.size().width(), self["screenshot"].instance.size().height(), sc[0], sc[1], False, 1, "#00000000"))
1023 self.picload.startDecode(filename)
1025 if self.statuspicinstance != None:
1026 self["statuspic"].instance.setPixmap(self.statuspicinstance.__deref__())
1027 self["statuspic"].show()
1028 if self.divpicinstance != None:
1029 self["divpic"].instance.setPixmap(self.divpicinstance.__deref__())
1030 self["divpic"].show()
1032 def paintScreenshotPixmapCB(self, picInfo=None):
1033 ptr = self.picload.getData()
1035 self["screenshot"].instance.setPixmap(ptr.__deref__())
1036 self["screenshot"].show()
1038 self.setThumbnail(noScreenshot = True)
1041 if self.attributes.has_key("package"):
1042 self.packagefiles = self.attributes["package"]
1044 if self.pluginstate in ('installed', 'remove'):
1045 if self.packagefiles:
1046 for package in self.packagefiles[:]:
1047 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": package["name"] }))
1048 if len(self.cmdList):
1049 self.session.openWithCallback(self.runRemove, MessageBox, _("Do you want to remove the package:\n") + self.pluginname + "\n" + self.oktext)
1051 if self.packagefiles:
1052 for package in self.packagefiles[:]:
1053 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package["name"] }))
1054 if len(self.cmdList):
1055 self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to install the package:\n") + self.pluginname + "\n" + self.oktext)
1057 def runUpgrade(self, result):
1059 self.session.openWithCallback(self.runUpgradeFinished, Ipkg, cmdList = self.cmdList)
1061 def runUpgradeFinished(self):
1062 self.session.openWithCallback(self.UpgradeReboot, MessageBox, _("Installation finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
1064 def UpgradeReboot(self, result):
1072 def runRemove(self, result):
1074 self.session.openWithCallback(self.runRemoveFinished, Ipkg, cmdList = self.cmdList)
1076 def runRemoveFinished(self):
1077 self.session.openWithCallback(self.RemoveReboot, MessageBox, _("Remove finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
1079 def RemoveReboot(self, result):
1087 def reloadPluginlist(self):
1088 plugins.readPluginList(resolveFilename(SCOPE_PLUGINS))
1090 def fetchFailed(self,string):
1091 self.setThumbnail(noScreenshot = True)
1092 print "[PluginDetails] fetch failed " + string.getErrorMessage()
1095 class UpdatePlugin(Screen):
1097 <screen name="UpdatePlugin" position="center,center" size="550,200" title="Software update" >
1098 <widget name="activityslider" position="0,0" size="550,5" />
1099 <widget name="slider" position="0,150" size="550,30" />
1100 <widget source="package" render="Label" position="10,30" size="540,20" font="Regular;18" halign="center" valign="center" backgroundColor="#25062748" transparent="1" />
1101 <widget source="status" render="Label" position="10,60" size="540,45" font="Regular;20" halign="center" valign="center" backgroundColor="#25062748" transparent="1" />
1104 def __init__(self, session, args = None):
1105 Screen.__init__(self, session)
1107 self.sliderPackages = { "dreambox-dvb-modules": 1, "enigma2": 2, "tuxbox-image-info": 3 }
1109 self.slider = Slider(0, 4)
1110 self["slider"] = self.slider
1111 self.activityslider = Slider(0, 100)
1112 self["activityslider"] = self.activityslider
1113 self.status = StaticText(_("Upgrading Dreambox... Please wait"))
1114 self["status"] = self.status
1115 self.package = StaticText()
1116 self["package"] = self.package
1122 self.activityTimer = eTimer()
1123 self.activityTimer.callback.append(self.doActivityTimer)
1124 self.activityTimer.start(100, False)
1126 self.ipkg = IpkgComponent()
1127 self.ipkg.addCallback(self.ipkgCallback)
1129 self.updating = True
1130 self.package.setText(_("Package list update"))
1131 self.ipkg.startCmd(IpkgComponent.CMD_UPDATE)
1133 self["actions"] = ActionMap(["WizardActions"],
1139 def doActivityTimer(self):
1141 if self.activity == 100:
1143 self.activityslider.setValue(self.activity)
1145 def ipkgCallback(self, event, param):
1146 if event == IpkgComponent.EVENT_DOWNLOAD:
1147 self.status.setText(_("Downloading"))
1148 elif event == IpkgComponent.EVENT_UPGRADE:
1149 if self.sliderPackages.has_key(param):
1150 self.slider.setValue(self.sliderPackages[param])
1151 self.package.setText(param)
1152 self.status.setText(_("Upgrading"))
1154 elif event == IpkgComponent.EVENT_INSTALL:
1155 self.package.setText(param)
1156 self.status.setText(_("Installing"))
1158 elif event == IpkgComponent.EVENT_CONFIGURING:
1159 self.package.setText(param)
1160 self.status.setText(_("Configuring"))
1161 elif event == IpkgComponent.EVENT_MODIFIED:
1162 self.session.openWithCallback(
1163 self.modificationCallback,
1165 _("A configuration file (%s) was modified since Installation.\nDo you want to keep your version?") % (param)
1167 elif event == IpkgComponent.EVENT_ERROR:
1169 elif event == IpkgComponent.EVENT_DONE:
1171 self.updating = False
1172 self.ipkg.startCmd(IpkgComponent.CMD_UPGRADE, args = {'test_only': False})
1173 elif self.error == 0:
1174 self.slider.setValue(4)
1176 self.activityTimer.stop()
1177 self.activityslider.setValue(0)
1179 self.package.setText("")
1180 self.status.setText(_("Done - Installed or upgraded %d packages") % self.packages)
1182 self.activityTimer.stop()
1183 self.activityslider.setValue(0)
1184 error = _("your dreambox might be unusable now. Please consult the manual for further assistance before rebooting your dreambox.")
1185 if self.packages == 0:
1186 error = _("No packages were upgraded yet. So you can check your network and try again.")
1188 error = _("Your dreambox isn't connected to the internet properly. Please check it and try again.")
1189 self.status.setText(_("Error") + " - " + error)
1190 #print event, "-", param
1193 def modificationCallback(self, res):
1194 self.ipkg.write(res and "N" or "Y")
1197 if not self.ipkg.isRunning():
1198 if self.packages != 0 and self.error == 0:
1199 self.session.openWithCallback(self.exitAnswer, MessageBox, _("Upgrade finished.") +" "+_("Do you want to reboot your Dreambox?"))
1203 def exitAnswer(self, result):
1204 if result is not None and result:
1210 class IPKGMenu(Screen):
1212 <screen name="IPKGMenu" position="center,center" size="560,400" title="Select upgrade source to edit." >
1213 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1214 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1215 <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" />
1216 <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" />
1217 <widget name="filelist" position="5,50" size="550,340" scrollbarMode="showOnDemand" />
1220 def __init__(self, session, plugin_path):
1221 Screen.__init__(self, session)
1222 self.skin_path = plugin_path
1224 self["key_red"] = StaticText(_("Close"))
1225 self["key_green"] = StaticText(_("Edit"))
1234 self["actions"] = NumberActionMap(["SetupActions"],
1237 "cancel": self.keyCancel
1240 self["shortcuts"] = ActionMap(["ShortcutActions"],
1242 "red": self.keyCancel,
1243 "green": self.KeyOk,
1246 self["filelist"] = MenuList(self.flist)
1248 self.onLayoutFinish.append(self.layoutFinished)
1250 def layoutFinished(self):
1251 self.setWindowTitle()
1253 def setWindowTitle(self):
1254 self.setTitle(_("Select upgrade source to edit."))
1256 def fill_list(self):
1258 self.path = '/etc/ipkg/'
1259 if (os_path.exists(self.path) == False):
1262 for file in listdir(self.path):
1263 if (file.endswith(".conf")):
1264 if file != 'arch.conf':
1265 self.flist.append((file))
1267 self["filelist"].l.setList(self.flist)
1270 if (self.exe == False) and (self.entry == True):
1271 self.sel = self["filelist"].getCurrent()
1272 self.val = self.path + self.sel
1273 self.session.open(IPKGSource, self.val)
1275 def keyCancel(self):
1282 class IPKGSource(Screen):
1284 <screen name="IPKGSource" position="center,center" size="560,80" title="Edit upgrade source url." >
1285 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1286 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1287 <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" />
1288 <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" />
1289 <widget name="text" position="5,50" size="550,25" font="Regular;20" backgroundColor="background" foregroundColor="#cccccc" />
1292 def __init__(self, session, configfile = None):
1293 Screen.__init__(self, session)
1294 self.session = session
1295 self.configfile = configfile
1299 fp = file(configfile, 'r')
1300 sources = fp.readlines()
1307 desk = getDesktop(0)
1308 x= int(desk.size().width())
1309 y= int(desk.size().height())
1311 self["key_red"] = StaticText(_("Cancel"))
1312 self["key_green"] = StaticText(_("Save"))
1315 self["text"] = Input(text, maxSize=False, type=Input.TEXT)
1317 self["text"] = Input(text, maxSize=False, visible_width = 55, type=Input.TEXT)
1319 self["actions"] = NumberActionMap(["WizardActions", "InputActions", "TextEntryActions", "KeyboardInputActions","ShortcutActions"],
1325 "left": self.keyLeft,
1326 "right": self.keyRight,
1327 "home": self.keyHome,
1329 "deleteForward": self.keyDeleteForward,
1330 "deleteBackward": self.keyDeleteBackward,
1331 "1": self.keyNumberGlobal,
1332 "2": self.keyNumberGlobal,
1333 "3": self.keyNumberGlobal,
1334 "4": self.keyNumberGlobal,
1335 "5": self.keyNumberGlobal,
1336 "6": self.keyNumberGlobal,
1337 "7": self.keyNumberGlobal,
1338 "8": self.keyNumberGlobal,
1339 "9": self.keyNumberGlobal,
1340 "0": self.keyNumberGlobal
1343 self.onLayoutFinish.append(self.layoutFinished)
1345 def layoutFinished(self):
1346 self.setWindowTitle()
1347 self["text"].right()
1349 def setWindowTitle(self):
1350 self.setTitle(_("Edit upgrade source url."))
1353 text = self["text"].getText()
1355 fp = file(self.configfile, 'w')
1365 self["text"].right()
1373 def keyDeleteForward(self):
1374 self["text"].delete()
1376 def keyDeleteBackward(self):
1377 self["text"].deleteBackward()
1379 def keyNumberGlobal(self, number):
1380 self["text"].number(number)
1383 class PacketManager(Screen):
1385 <screen name="PacketManager" position="center,center" size="530,420" title="Packet manager" >
1386 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1387 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1388 <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" />
1389 <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" />
1390 <widget source="list" render="Listbox" position="5,50" size="520,365" scrollbarMode="showOnDemand">
1391 <convert type="TemplatedMultiContent">
1393 MultiContentEntryText(pos = (5, 1), size = (440, 28), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
1394 MultiContentEntryText(pos = (5, 26), size = (440, 20), font=1, flags = RT_HALIGN_LEFT, text = 2), # index 2 is the description
1395 MultiContentEntryPixmapAlphaTest(pos = (445, 2), size = (48, 48), png = 4), # index 4 is the status pixmap
1396 MultiContentEntryPixmapAlphaTest(pos = (5, 50), size = (510, 2), png = 5), # index 4 is the div pixmap
1398 "fonts": [gFont("Regular", 22),gFont("Regular", 14)],
1405 def __init__(self, session, plugin_path, args = None):
1406 Screen.__init__(self, session)
1407 self.session = session
1408 self.skin_path = plugin_path
1410 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"],
1415 "green": self.reload,
1419 self.statuslist = []
1420 self["list"] = List(self.list)
1421 self["key_red"] = StaticText(_("Close"))
1422 self["key_green"] = StaticText(_("Reload"))
1424 self.list_updating = True
1425 self.packetlist = []
1426 self.installed_packetlist = {}
1427 self.Console = Console()
1430 self.cache_ttl = 86400 #600 is default, 0 disables, Seconds cache is considered valid (24h should be ok for caching ipkgs)
1431 self.cache_file = '/usr/lib/enigma2/python/Plugins/SystemPlugins/SoftwareManager/packetmanager.cache' #Path to cache directory
1432 self.oktext = _("\nAfter pressing OK, please wait!")
1433 self.unwanted_extensions = ('-dbg', '-dev', '-doc', 'busybox')
1435 self.ipkg = IpkgComponent()
1436 self.ipkg.addCallback(self.ipkgCallback)
1437 self.onShown.append(self.setWindowTitle)
1438 self.onLayoutFinish.append(self.rebuildList)
1442 if self.Console is not None:
1443 if len(self.Console.appContainers):
1444 for name in self.Console.appContainers.keys():
1445 self.Console.kill(name)
1449 if (os_path.exists(self.cache_file) == True):
1450 remove(self.cache_file)
1451 self.list_updating = True
1454 def setWindowTitle(self):
1455 self.setTitle(_("Packet manager"))
1457 def setStatus(self,status = None):
1459 self.statuslist = []
1460 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
1461 if status == 'update':
1462 statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgrade.png"))
1463 self.statuslist.append(( _("Package list update"), '', _("Trying to download a new packetlist. Please wait..." ),'',statuspng, divpng ))
1464 self['list'].setList(self.statuslist)
1465 elif status == 'error':
1466 statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
1467 self.statuslist.append(( _("Error"), '', _("There was an error downloading the packetlist. Please try again." ),'',statuspng, divpng ))
1468 self['list'].setList(self.statuslist)
1470 def rebuildList(self):
1471 self.setStatus('update')
1473 self.vc = valid_cache(self.cache_file, self.cache_ttl)
1474 if self.cache_ttl > 0 and self.vc != 0:
1476 self.buildPacketList()
1479 if self.cache_ttl == 0 or self.inv_cache == 1 or self.vc == 0:
1481 self.ipkg.startCmd(IpkgComponent.CMD_UPDATE)
1483 def go(self, returnValue = None):
1484 cur = self["list"].getCurrent()
1489 if status == 'installed':
1490 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": package }))
1491 if len(self.cmdList):
1492 self.session.openWithCallback(self.runRemove, MessageBox, _("Do you want to remove the package:\n") + package + "\n" + self.oktext)
1493 elif status == 'upgradeable':
1494 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package }))
1495 if len(self.cmdList):
1496 self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to upgrade the package:\n") + package + "\n" + self.oktext)
1497 elif status == "installable":
1498 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package }))
1499 if len(self.cmdList):
1500 self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to install the package:\n") + package + "\n" + self.oktext)
1502 def runRemove(self, result):
1504 self.session.openWithCallback(self.runRemoveFinished, Ipkg, cmdList = self.cmdList)
1506 def runRemoveFinished(self):
1507 self.session.openWithCallback(self.RemoveReboot, MessageBox, _("Remove finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
1509 def RemoveReboot(self, result):
1513 cur = self["list"].getCurrent()
1515 item = self['list'].getIndex()
1516 self.list[item] = self.buildEntryComponent(cur[0], cur[1], cur[2], 'installable')
1517 self.cachelist[item] = [cur[0], cur[1], cur[2], 'installable']
1518 self['list'].setList(self.list)
1519 write_cache(self.cache_file, self.cachelist)
1520 self.reloadPluginlist()
1524 def runUpgrade(self, result):
1526 self.session.openWithCallback(self.runUpgradeFinished, Ipkg, cmdList = self.cmdList)
1528 def runUpgradeFinished(self):
1529 self.session.openWithCallback(self.UpgradeReboot, MessageBox, _("Upgrade finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
1531 def UpgradeReboot(self, result):
1535 cur = self["list"].getCurrent()
1537 item = self['list'].getIndex()
1538 self.list[item] = self.buildEntryComponent(cur[0], cur[1], cur[2], 'installed')
1539 self.cachelist[item] = [cur[0], cur[1], cur[2], 'installed']
1540 self['list'].setList(self.list)
1541 write_cache(self.cache_file, self.cachelist)
1542 self.reloadPluginlist()
1546 def ipkgCallback(self, event, param):
1547 if event == IpkgComponent.EVENT_ERROR:
1548 self.list_updating = False
1549 self.setStatus('error')
1550 elif event == IpkgComponent.EVENT_DONE:
1551 if self.list_updating:
1552 self.list_updating = False
1553 if not self.Console:
1554 self.Console = Console()
1556 self.Console.ePopen(cmd, self.IpkgList_Finished)
1557 #print event, "-", param
1560 def IpkgList_Finished(self, result, retval, extra_args = None):
1562 self.packetlist = []
1563 for x in result.splitlines():
1564 split = x.split(' - ') #self.blacklisted_packages
1565 if not any(split[0].strip().endswith(x) for x in self.unwanted_extensions):
1566 self.packetlist.append([split[0].strip(), split[1].strip(),split[2].strip()])
1567 if not self.Console:
1568 self.Console = Console()
1569 cmd = "ipkg list_installed"
1570 self.Console.ePopen(cmd, self.IpkgListInstalled_Finished)
1572 def IpkgListInstalled_Finished(self, result, retval, extra_args = None):
1574 self.installed_packetlist = {}
1575 for x in result.splitlines():
1576 split = x.split(' - ')
1577 if not any(split[0].strip().endswith(x) for x in self.unwanted_extensions):
1578 self.installed_packetlist[split[0].strip()] = split[1].strip()
1579 self.buildPacketList()
1581 def buildEntryComponent(self, name, version, description, state):
1582 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
1583 if state == 'installed':
1584 installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installed.png"))
1585 return((name, version, description, state, installedpng, divpng))
1586 elif state == 'upgradeable':
1587 upgradeablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgradeable.png"))
1588 return((name, version, description, state, upgradeablepng, divpng))
1590 installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installable.png"))
1591 return((name, version, description, state, installablepng, divpng))
1593 def buildPacketList(self):
1597 if self.cache_ttl > 0 and self.vc != 0:
1598 print 'Loading packagelist cache from ',self.cache_file
1600 self.cachelist = load_cache(self.cache_file)
1601 if len(self.cachelist) > 0:
1602 for x in self.cachelist:
1603 self.list.append(self.buildEntryComponent(x[0], x[1], x[2], x[3]))
1604 self['list'].setList(self.list)
1608 if self.cache_ttl == 0 or self.inv_cache == 1 or self.vc == 0:
1609 print 'rebuilding fresh package list'
1610 for x in self.packetlist:
1612 if self.installed_packetlist.has_key(x[0].strip()):
1613 if self.installed_packetlist[x[0].strip()] == x[1].strip():
1614 status = "installed"
1615 self.list.append(self.buildEntryComponent(x[0].strip(), x[1].strip(), x[2].strip(), status))
1617 status = "upgradeable"
1618 self.list.append(self.buildEntryComponent(x[0].strip(), x[1].strip(), x[2].strip(), status))
1620 status = "installable"
1621 self.list.append(self.buildEntryComponent(x[0].strip(), x[1].strip(), x[2].strip(), status))
1622 if not any(x[0].strip().endswith(x) for x in self.unwanted_extensions):
1623 self.cachelist.append([x[0].strip(), x[1].strip(), x[2].strip(), status])
1624 write_cache(self.cache_file, self.cachelist)
1625 self['list'].setList(self.list)
1627 def reloadPluginlist(self):
1628 plugins.readPluginList(resolveFilename(SCOPE_PLUGINS))
1630 class IpkgInstaller(Screen):
1632 <screen name="IpkgInstaller" position="center,center" size="550,450" title="Install extensions" >
1633 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1634 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1635 <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" />
1636 <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" />
1637 <widget name="list" position="5,50" size="540,360" />
1638 <ePixmap pixmap="skin_default/div-h.png" position="0,410" zPosition="10" size="560,2" transparent="1" alphatest="on" />
1639 <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" />
1642 def __init__(self, session, list):
1643 Screen.__init__(self, session)
1645 self.list = SelectionList()
1646 self["list"] = self.list
1647 for listindex in range(len(list)):
1648 self.list.addSelection(list[listindex], list[listindex], listindex, True)
1650 self["key_red"] = StaticText(_("Close"))
1651 self["key_green"] = StaticText(_("Install"))
1652 self["introduction"] = StaticText(_("Press OK to toggle the selection."))
1654 self["actions"] = ActionMap(["OkCancelActions", "ColorActions"],
1656 "ok": self.list.toggleSelection,
1657 "cancel": self.close,
1659 "green": self.install
1663 list = self.list.getSelectionsList()
1666 cmdList.append((IpkgComponent.CMD_INSTALL, { "package": item[1] }))
1667 self.session.open(Ipkg, cmdList = cmdList)
1670 def filescan_open(list, session, **kwargs):
1671 filelist = [x.path for x in list]
1672 session.open(IpkgInstaller, filelist) # list
1674 def filescan(**kwargs):
1675 from Components.Scanner import Scanner, ScanPath
1677 Scanner(mimetypes = ["application/x-debian-package"],
1680 ScanPath(path = "ipk", with_subdirs = True),
1681 ScanPath(path = "", with_subdirs = False),
1684 description = _("Install extensions."),
1685 openfnc = filescan_open, )
1689 def UpgradeMain(session, **kwargs):
1690 session.open(UpdatePluginMenu)
1692 def startSetup(menuid):
1693 if menuid != "setup":
1695 return [(_("Software management"), UpgradeMain, "software_manager", 50)]
1697 def autostart(reason, **kwargs):
1699 iSoftwareTools.startSoftwareTools()
1701 def Plugins(path, **kwargs):
1705 PluginDescriptor(where = [PluginDescriptor.WHERE_NETWORKCONFIG_READ], fnc = autostart),
1706 PluginDescriptor(name=_("Software management"), description=_("Manage your receiver's software"), where = PluginDescriptor.WHERE_MENU, fnc=startSetup),
1707 PluginDescriptor(name=_("Ipkg"), where = PluginDescriptor.WHERE_FILESCAN, fnc = filescan)
1709 if config.usage.setup_level.index >= 2: # expert+
1710 list.append(PluginDescriptor(name=_("Software management"), description=_("Manage your receiver's software"), where = PluginDescriptor.WHERE_EXTENSIONSMENU, fnc=UpgradeMain))