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.Label import Label
11 from Components.MenuList import MenuList
12 from Components.Sources.List import List
13 from Components.Slider import Slider
14 from Components.Harddisk import harddiskmanager
15 from Components.config import config,getConfigListEntry, ConfigSubsection, ConfigText, ConfigLocations
16 from Components.Console import Console
17 from Components.MultiContent import MultiContentEntryText, MultiContentEntryPixmapAlphaTest
18 from Components.SelectionList import SelectionList
19 from Components.PluginComponent import plugins
20 from Tools.Directories import fileExists, resolveFilename, SCOPE_PLUGINS, SCOPE_SKIN_IMAGE
21 from Tools.LoadPixmap import LoadPixmap
22 from enigma import eTimer, quitMainloop, RT_HALIGN_LEFT, RT_VALIGN_CENTER, eListboxPythonMultiContent, eListbox, gFont
23 from cPickle import dump, load
25 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
26 from time import time, gmtime, strftime, localtime
27 from stat import ST_MTIME
28 from datetime import date
30 from ImageWizard import ImageWizard
31 from BackupRestore import BackupSelection, RestoreMenu, BackupScreen, RestoreScreen, getBackupPath, getBackupFilename
33 config.plugins.configurationbackup = ConfigSubsection()
34 config.plugins.configurationbackup.backuplocation = ConfigText(default = '/media/hdd/', visible_width = 50, fixed_size = False)
35 config.plugins.configurationbackup.backupdirs = ConfigLocations(default=['/etc/enigma2/', '/etc/network/interfaces', '/etc/wpa_supplicant.conf'])
37 def write_cache(cache_file, cache_data):
39 if not os_path.isdir( os_path.dirname(cache_file) ):
41 mkdir( os_path.dirname(cache_file) )
43 print os_path.dirname(cache_file), 'is a file'
44 fd = open(cache_file, 'w')
45 dump(cache_data, fd, -1)
48 def valid_cache(cache_file, cache_ttl):
49 #See if the cache file exists and is still living
51 mtime = stat(cache_file)[ST_MTIME]
55 if (curr_time - mtime) > cache_ttl:
60 def load_cache(cache_file):
68 class UpdatePluginMenu(Screen):
70 <screen name="UpdatePluginMenu" position="90,130" size="550,330" title="Softwaremanager..." >
71 <ePixmap pixmap="skin_default/border_menu.png" position="10,10" zPosition="1" size="250,300" transparent="1" alphatest="on" />
72 <widget source="menu" render="Listbox" position="20,20" size="230,260" scrollbarMode="showOnDemand">
73 <convert type="TemplatedMultiContent">
75 MultiContentEntryText(pos = (2, 2), size = (230, 22), flags = RT_HALIGN_LEFT, text = 1), # index 0 is the MenuText,
77 "fonts": [gFont("Regular", 20)],
82 <widget source="menu" render="Listbox" position="280,10" size="230,300" scrollbarMode="showNever" selectionDisabled="1">
83 <convert type="TemplatedMultiContent">
85 MultiContentEntryText(pos = (2, 2), size = (230, 300), flags = RT_HALIGN_CENTER|RT_VALIGN_CENTER|RT_WRAP, text = 2), # index 0 is the MenuText,
87 "fonts": [gFont("Regular", 20)],
94 def __init__(self, session, args = 0):
95 Screen.__init__(self, session)
96 self.skin_path = plugin_path
99 self.oktext = _("\nPress OK on your remote control to continue.")
100 self.backupdirs = ' '.join( config.plugins.configurationbackup.backupdirs.value )
102 self.list.append(("software-update", _("Software update"), _("\nOnline update of your Dreambox software." ) + self.oktext) )
103 self.list.append(("software-restore", _("Software restore"), _("\nRestore your Dreambox with a new firmware." ) + self.oktext))
104 self.list.append(("system-backup", _("Backup system settings"), _("\nBackup your Dreambox settings." ) + self.oktext))
105 self.list.append(("system-restore",_("Restore system settings"), _("\nRestore your Dreambox settings." ) + self.oktext))
106 if config.usage.setup_level.index >= 2: # expert+
107 self.list.append(("advanced", _("Advanced Options"), _("\nAdvanced options and settings." ) + self.oktext))
109 self.list.append(("ipkg-manager", _("Packet management"), _("\nView, install and remove available or installed packages." ) + self.oktext))
110 self.list.append(("ipkg-install", _("Install local IPKG"), _("\nScan for local packages and install them." ) + self.oktext))
111 self.list.append(("advancedrestore", _("Advanced restore"), _("\nRestore your backups by date." ) + self.oktext))
112 self.list.append(("backuplocation", _("Choose backup location"), _("\nSelect your backup device.\nCurrent device: " ) + config.plugins.configurationbackup.backuplocation.value + self.oktext ))
113 self.list.append(("backupfiles", _("Choose backup files"), _("Select files for backup. Currently selected:\n" ) + self.backupdirs + self.oktext))
114 self.list.append(("ipkg-source",_("Choose upgrade source"), _("\nEdit the upgrade source address." ) + self.oktext))
116 self["menu"] = List(self.list)
118 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"],
125 self.onLayoutFinish.append(self.layoutFinished)
126 self.backuppath = getBackupPath()
127 self.backupfile = getBackupFilename()
128 self.fullbackupfilename = self.backuppath + "/" + self.backupfile
129 self.onShown.append(self.setWindowTitle)
131 def layoutFinished(self):
133 self["menu"].index = idx
135 def setWindowTitle(self):
136 self.setTitle(_("Software manager..."))
139 current = self["menu"].getCurrent()
143 if (current == "software-restore"):
144 self.session.open(ImageWizard)
145 elif (current == "software-update"):
146 self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to update your Dreambox?")+"\n"+_("\nAfter pressing OK, please wait!"))
147 elif (current == "advanced"):
148 self.session.open(UpdatePluginMenu, 1)
149 elif (current == "system-backup"):
150 self.session.openWithCallback(self.backupDone,BackupScreen, runBackup = True)
151 elif (current == "system-restore"):
152 if os_path.exists(self.fullbackupfilename):
153 self.session.openWithCallback(self.startRestore, MessageBox, _("Are you sure you want to restore your Enigma2 backup?\nEnigma2 will restart after the restore"))
155 self.session.open(MessageBox, _("Sorry no backups found!"), MessageBox.TYPE_INFO)
157 if (current == "ipkg-manager"):
158 self.session.open(PacketManager, self.skin_path)
159 elif (current == "ipkg-source"):
160 self.session.open(IPKGSource)
161 elif (current == "ipkg-install"):
163 from Plugins.Extensions.MediaScanner.plugin import main
166 self.session.open(MessageBox, _("Sorry MediaScanner is not installed!"), MessageBox.TYPE_INFO)
167 elif (current == "backuplocation"):
168 parts = [ (r.description, r.mountpoint, self.session) for r in harddiskmanager.getMountedPartitions(onlyhotplug = False)]
170 if not access(x[1], F_OK|R_OK|W_OK) or x[1] == '/':
173 if x[1].startswith('/autofs/'):
176 self.session.openWithCallback(self.backuplocation_choosen, ChoiceBox, title = _("Please select medium to use as backup location"), list = parts)
177 elif (current == "backupfiles"):
178 self.session.openWithCallback(self.backupfiles_choosen,BackupSelection)
179 elif (current == "advancedrestore"):
180 self.session.open(RestoreMenu, self.skin_path)
182 def backupfiles_choosen(self, ret):
183 self.backupdirs = ' '.join( config.plugins.configurationbackup.backupdirs.value )
185 def backuplocation_choosen(self, option):
186 if option is not None:
187 config.plugins.configurationbackup.backuplocation.value = str(option[1])
188 config.plugins.configurationbackup.backuplocation.save()
189 config.plugins.configurationbackup.save()
191 self.createBackupfolders()
193 def runUpgrade(self, result):
195 self.session.open(UpdatePlugin, self.skin_path)
197 """def runFinished(self):
198 self.session.openWithCallback(self.reboot, MessageBox, _("Upgrade finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
200 def reboot(self, result):
206 def createBackupfolders(self):
207 print "Creating backup folder if not already there..."
208 self.backuppath = getBackupPath()
210 if (os_path.exists(self.backuppath) == False):
211 makedirs(self.backuppath)
213 self.session.open(MessageBox, _("Sorry, your backup destination is not writeable.\n\nPlease choose another one."), MessageBox.TYPE_INFO)
215 def backupDone(self,retval = None):
217 self.session.open(MessageBox, _("Backup done."), MessageBox.TYPE_INFO)
219 self.session.open(MessageBox, _("Backup failed."), MessageBox.TYPE_INFO)
221 def startRestore(self, ret = False):
224 self.session.open(RestoreScreen, runRestore = True)
227 class IPKGSource(Screen):
229 <screen position="100,100" size="550,60" title="IPKG source" >
230 <widget name="text" position="0,0" size="550,25" font="Regular;20" backgroundColor="background" foregroundColor="#cccccc" />
233 def __init__(self, session, args = None):
234 Screen.__init__(self, session)
235 self.session = session
237 #FIXMEEEE add handling for more than one feed conf file!
240 fp = file('/etc/ipkg/official-feed.conf', 'r')
241 sources = fp.readlines()
248 self["text"] = Input(text, maxSize=False, type=Input.TEXT)
250 self["actions"] = NumberActionMap(["WizardActions", "InputActions", "TextEntryActions", "KeyboardInputActions"],
254 "left": self.keyLeft,
255 "right": self.keyRight,
256 "home": self.keyHome,
258 "deleteForward": self.keyDeleteForward,
259 "deleteBackward": self.keyDeleteBackward,
260 "1": self.keyNumberGlobal,
261 "2": self.keyNumberGlobal,
262 "3": self.keyNumberGlobal,
263 "4": self.keyNumberGlobal,
264 "5": self.keyNumberGlobal,
265 "6": self.keyNumberGlobal,
266 "7": self.keyNumberGlobal,
267 "8": self.keyNumberGlobal,
268 "9": self.keyNumberGlobal,
269 "0": self.keyNumberGlobal
273 text = self["text"].getText()
275 fp = file('/etc/ipkg/official-feed.conf', 'w')
292 def keyDeleteForward(self):
293 self["text"].delete()
295 def keyDeleteBackward(self):
296 self["text"].deleteBackward()
298 def keyNumberGlobal(self, number):
299 print "pressed", number
300 self["text"].number(number)
303 class PacketManager(Screen):
305 <screen position="90,80" size="530,420" title="IPKG upgrade..." >
306 <widget source="list" render="Listbox" position="5,10" size="520,365" scrollbarMode="showOnDemand">
307 <convert type="TemplatedMultiContent">
309 MultiContentEntryText(pos = (5, 1), size = (440, 28), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
310 MultiContentEntryText(pos = (5, 26), size = (440, 20), font=1, flags = RT_HALIGN_LEFT, text = 2), # index 2 is the description
311 MultiContentEntryPixmapAlphaTest(pos = (445, 2), size = (48, 48), png = 4), # index 4 is the status pixmap
312 MultiContentEntryPixmapAlphaTest(pos = (5, 50), size = (510, 2), png = 5), # index 4 is the div pixmap
314 "fonts": [gFont("Regular", 22),gFont("Regular", 14)],
319 <ePixmap pixmap="skin_default/buttons/red.png" position="10,380" zPosition="2" size="140,40" transparent="1" alphatest="on" />
320 <widget name="closetext" position="20,390" size="140,21" zPosition="10" font="Regular;21" transparent="1" />
321 <ePixmap pixmap="skin_default/buttons/green.png" position="160,380" zPosition="2" size="140,40" transparent="1" alphatest="on" />
322 <widget name="reloadtext" position="170,390" size="300,21" zPosition="10" font="Regular;21" transparent="1" />
325 def __init__(self, session, plugin_path, args = None):
326 Screen.__init__(self, session)
327 self.session = session
328 self.skin_path = plugin_path
330 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"],
335 "green": self.reload,
340 self["list"] = List(self.list)
341 self["closetext"] = Label(_("Close"))
342 self["reloadtext"] = Label(_("Reload"))
344 self.list_updating = True
346 self.installed_packetlist = {}
347 self.Console = Console()
350 self.cache_ttl = 86400 #600 is default, 0 disables, Seconds cache is considered valid (24h should be ok for caching ipkgs)
351 self.cache_file = '/usr/lib/enigma2/python/Plugins/SystemPlugins/SoftwareManager/packetmanager.cache' #Path to cache directory
352 self.oktext = _("\nAfter pressing OK, please wait!")
354 self.ipkg = IpkgComponent()
355 self.ipkg.addCallback(self.ipkgCallback)
356 self.onShown.append(self.setWindowTitle)
357 self.onLayoutFinish.append(self.rebuildList)
361 if self.Console is not None:
362 if len(self.Console.appContainers):
363 for name in self.Console.appContainers.keys():
364 self.Console.kill(name)
368 if (os_path.exists(self.cache_file) == True):
369 remove(self.cache_file)
370 self.list_updating = True
373 def setWindowTitle(self):
374 self.setTitle(_("Packet manager"))
376 def setStatus(self,status = None):
379 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/div-h.png"))
380 if status == 'update':
381 statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_PLUGINS, "SystemPlugins/SoftwareManager/installable.png"))
382 self.statuslist.append(( _("Package list update"), '', _("Trying to download a new packetlist. Please wait..." ),'',statuspng, divpng ))
383 self['list'].setList(self.statuslist)
384 elif status == 'error':
385 statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_PLUGINS, "SystemPlugins/SoftwareManager/installed.png"))
386 self.statuslist.append(( _("Error"), '', _("There was an error downloading the packetlist. Please try again." ),'',statuspng, divpng ))
387 self['list'].setList(self.statuslist)
389 def rebuildList(self):
390 self.setStatus('update')
392 self.vc = valid_cache(self.cache_file, self.cache_ttl)
393 if self.cache_ttl > 0 and self.vc != 0:
395 self.buildPacketList()
398 if self.cache_ttl == 0 or self.inv_cache == 1 or self.vc == 0:
400 self.ipkg.startCmd(IpkgComponent.CMD_UPDATE)
402 def go(self, returnValue = None):
403 cur = self["list"].getCurrent()
408 if status == 'installed':
409 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": package }))
410 if len(self.cmdList):
411 self.session.openWithCallback(self.runRemove, MessageBox, _("Do you want to remove the package:\n" + package + "\n" + self.oktext))
412 elif status == 'upgradeable':
413 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package }))
414 if len(self.cmdList):
415 self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to upgrade the package:\n" + package + "\n" + self.oktext))
416 elif status == "installable":
417 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package }))
418 if len(self.cmdList):
419 self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to install the package:\n" + package + "\n" + self.oktext))
421 def runRemove(self, result):
423 self.session.openWithCallback(self.runRemoveFinished, Ipkg, cmdList = self.cmdList)
425 def runRemoveFinished(self):
426 self.session.openWithCallback(self.RemoveReboot, MessageBox, _("Remove finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
428 def RemoveReboot(self, result):
432 cur = self["list"].getCurrent()
434 item = self['list'].getIndex()
435 self.list[item] = self.buildEntryComponent(cur[0], cur[1], cur[2], 'installable')
436 self.cachelist[item] = [cur[0], cur[1], cur[2], 'installable']
437 self['list'].setList(self.list)
438 write_cache(self.cache_file, self.cachelist)
439 self.reloadPluginlist()
443 def runUpgrade(self, result):
445 self.session.openWithCallback(self.runUpgradeFinished, Ipkg, cmdList = self.cmdList)
447 def runUpgradeFinished(self):
448 self.session.openWithCallback(self.UpgradeReboot, MessageBox, _("Upgrade finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
450 def UpgradeReboot(self, result):
454 cur = self["list"].getCurrent()
456 item = self['list'].getIndex()
457 self.list[item] = self.buildEntryComponent(cur[0], cur[1], cur[2], 'installed')
458 self.cachelist[item] = [cur[0], cur[1], cur[2], 'installed']
459 self['list'].setList(self.list)
460 write_cache(self.cache_file, self.cachelist)
461 self.reloadPluginlist()
465 def ipkgCallback(self, event, param):
466 if event == IpkgComponent.EVENT_ERROR:
467 self.list_updating = False
468 self.setStatus('error')
469 elif event == IpkgComponent.EVENT_DONE:
470 if self.list_updating:
471 self.list_updating = False
473 self.Console = Console()
475 self.Console.ePopen(cmd, self.IpkgList_Finished)
476 #print event, "-", param
479 def IpkgList_Finished(self, result, retval, extra_args = None):
482 for x in result.splitlines():
483 split = x.split(' - ')
484 if not (split[0].strip().endswith('-dbg') or split[0].strip().endswith('-dev')):
485 self.packetlist.append([split[0].strip(), split[1].strip(),split[2].strip()])
487 self.Console = Console()
488 cmd = "ipkg list_installed"
489 self.Console.ePopen(cmd, self.IpkgListInstalled_Finished)
491 def IpkgListInstalled_Finished(self, result, retval, extra_args = None):
493 self.installed_packetlist = {}
494 for x in result.splitlines():
495 split = x.split(' - ')
496 if not (split[0].strip().endswith('-dbg') or split[0].strip().endswith('-dev')):
497 self.installed_packetlist[split[0].strip()] = split[1].strip()
498 self.buildPacketList()
500 def buildEntryComponent(self, name, version, description, state):
501 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/div-h.png"))
502 if state == 'installed':
503 installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_PLUGINS, "SystemPlugins/SoftwareManager/installed.png"))
504 return((name, version, description, state, installedpng, divpng))
505 elif state == 'upgradeable':
506 upgradeablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_PLUGINS, "SystemPlugins/SoftwareManager/upgradeable.png"))
507 return((name, version, description, state, upgradeablepng, divpng))
509 installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_PLUGINS, "SystemPlugins/SoftwareManager/installable.png"))
510 return((name, version, description, state, installablepng, divpng))
512 def buildPacketList(self):
516 if self.cache_ttl > 0 and self.vc != 0:
517 print 'Loading packagelist cache from ',self.cache_file
519 self.cachelist = load_cache(self.cache_file)
520 if len(self.cachelist) > 0:
521 for x in self.cachelist:
522 self.list.append(self.buildEntryComponent(x[0], x[1], x[2], x[3]))
523 self['list'].setList(self.list)
527 if self.cache_ttl == 0 or self.inv_cache == 1 or self.vc == 0:
528 print 'rebuilding fresh package list'
529 for x in self.packetlist:
531 if self.installed_packetlist.has_key(x[0].strip()):
532 if self.installed_packetlist[x[0].strip()] == x[1].strip():
534 self.list.append(self.buildEntryComponent(x[0].strip(), x[1].strip(), x[2].strip(), status))
536 status = "upgradeable"
537 self.list.append(self.buildEntryComponent(x[0].strip(), x[1].strip(), x[2].strip(), status))
539 status = "installable"
540 self.list.append(self.buildEntryComponent(x[0].strip(), x[1].strip(), x[2].strip(), status))
541 if not (x[0].strip().endswith('-dbg') or x[0].strip().endswith('-dev')):
542 self.cachelist.append([x[0].strip(), x[1].strip(), x[2].strip(), status])
543 write_cache(self.cache_file, self.cachelist)
544 self['list'].setList(self.list)
546 def reloadPluginlist(self):
547 plugins.readPluginList(resolveFilename(SCOPE_PLUGINS))
549 class UpdatePlugin(Screen):
551 <screen position="100,100" size="550,200" title="Software Update..." >
552 <widget name="activityslider" position="0,0" size="550,5" />
553 <widget name="slider" position="0,100" size="550,30" />
554 <widget name="package" position="10,30" size="540,20" font="Regular;18"/>
555 <widget name="status" position="10,60" size="540,45" font="Regular;18"/>
558 def __init__(self, session, args = None):
559 self.skin = UpdatePlugin.skin
560 Screen.__init__(self, session)
562 self.sliderPackages = { "dreambox-dvb-modules": 1, "enigma2": 2, "tuxbox-image-info": 3 }
564 self.slider = Slider(0, 4)
565 self["slider"] = self.slider
566 self.activityslider = Slider(0, 100)
567 self["activityslider"] = self.activityslider
568 self.status = Label(_("Upgrading Dreambox... Please wait"))
569 self["status"] = self.status
570 self.package = Label()
571 self["package"] = self.package
577 self.activityTimer = eTimer()
578 self.activityTimer.callback.append(self.doActivityTimer)
579 self.activityTimer.start(100, False)
581 self.ipkg = IpkgComponent()
582 self.ipkg.addCallback(self.ipkgCallback)
585 self.package.setText(_("Package list update"))
586 self.ipkg.startCmd(IpkgComponent.CMD_UPDATE)
588 self["actions"] = ActionMap(["WizardActions"],
594 def doActivityTimer(self):
596 if self.activity == 100:
598 self.activityslider.setValue(self.activity)
600 def ipkgCallback(self, event, param):
601 if event == IpkgComponent.EVENT_DOWNLOAD:
602 self.status.setText(_("Downloading"))
603 elif event == IpkgComponent.EVENT_UPGRADE:
604 if self.sliderPackages.has_key(param):
605 self.slider.setValue(self.sliderPackages[param])
606 self.package.setText(param)
607 self.status.setText(_("Upgrading"))
609 elif event == IpkgComponent.EVENT_INSTALL:
610 self.package.setText(param)
611 self.status.setText(_("Installing"))
613 elif event == IpkgComponent.EVENT_CONFIGURING:
614 self.package.setText(param)
615 self.status.setText(_("Configuring"))
616 elif event == IpkgComponent.EVENT_MODIFIED:
617 self.session.openWithCallback(
618 self.modificationCallback,
620 _("A configuration file (%s) was modified since Installation.\nDo you want to keep your version?") % (param)
622 elif event == IpkgComponent.EVENT_ERROR:
624 elif event == IpkgComponent.EVENT_DONE:
626 self.updating = False
627 self.ipkg.startCmd(IpkgComponent.CMD_UPGRADE, args = {'test_only': False})
628 elif self.error == 0:
629 self.slider.setValue(4)
631 self.activityTimer.stop()
632 self.activityslider.setValue(0)
634 self.package.setText("")
635 self.status.setText(_("Done - Installed or upgraded %d packages") % self.packages)
637 self.activityTimer.stop()
638 self.activityslider.setValue(0)
639 error = _("your dreambox might be unusable now. Please consult the manual for further assistance before rebooting your dreambox.")
640 if self.packages == 0:
641 error = _("No packages were upgraded yet. So you can check your network and try again.")
643 error = _("Your dreambox isn't connected to the internet properly. Please check it and try again.")
644 self.status.setText(_("Error") + " - " + error)
645 #print event, "-", param
648 def modificationCallback(self, res):
649 self.ipkg.write(res and "N" or "Y")
652 if not self.ipkg.isRunning():
653 if self.packages != 0 and self.error == 0:
654 self.session.openWithCallback(self.exitAnswer, MessageBox, _("Upgrade finished.") +" "+_("Do you want to reboot your Dreambox?"))
658 def exitAnswer(self, result):
659 if result is not None and result:
665 class IpkgInstaller(Screen):
667 <screen position="100,100" size="550,400" title="..." >
668 <widget name="red" halign="center" valign="center" position="0,0" size="140,60" backgroundColor="red" font="Regular;21" />
669 <widget name="green" halign="center" valign="center" position="140,0" text="Install selected" size="140,60" backgroundColor="green" font="Regular;21" />
670 <widget name="yellow" halign="center" valign="center" position="280,0" size="140,60" backgroundColor="yellow" font="Regular;21" />
671 <widget name="blue" halign="center" valign="center" position="420,0" size="140,60" backgroundColor="blue" font="Regular;21" />
672 <widget name="list" position="0,60" size="550,360" />
676 def __init__(self, session, list):
677 self.skin = IpkgInstaller.skin
678 Screen.__init__(self, session)
680 self.list = SelectionList()
681 self["list"] = self.list
682 for listindex in range(len(list)):
683 self.list.addSelection(list[listindex], list[listindex], listindex, True)
685 self["red"] = Label()
686 self["green"] = Label()
687 self["yellow"] = Label()
688 self["blue"] = Label()
690 self["actions"] = ActionMap(["OkCancelActions", "ColorActions"],
692 "ok": self.list.toggleSelection,
693 "cancel": self.close,
694 "green": self.install
698 list = self.list.getSelectionsList()
701 cmdList.append((IpkgComponent.CMD_INSTALL, { "package": item[1] }))
702 self.session.open(Ipkg, cmdList = cmdList)
704 def filescan_open(list, session, **kwargs):
705 filelist = [x.path for x in list]
706 session.open(IpkgInstaller, filelist) # list
708 def filescan(**kwargs):
709 from Components.Scanner import Scanner, ScanPath
711 Scanner(mimetypes = ["application/x-debian-package"],
714 ScanPath(path = "ipk", with_subdirs = True),
715 ScanPath(path = "", with_subdirs = False),
718 description = "Install software updates...",
719 openfnc = filescan_open, )
721 def UpgradeMain(session, **kwargs):
722 session.open(UpdatePluginMenu)
724 def startSetup(menuid):
725 if menuid != "setup":
727 return [(_("Software manager") + "...", UpgradeMain, "software_manager", 50)]
729 def Plugins(path, **kwargs):
733 PluginDescriptor(name=_("Software manager"), description=_("Manage your receiver's software"), where = PluginDescriptor.WHERE_MENU, fnc=startSetup),
734 PluginDescriptor(name=_("Ipkg"), where = PluginDescriptor.WHERE_FILESCAN, fnc = filescan)
736 if config.usage.setup_level.index >= 2: # expert+
737 list.append(PluginDescriptor(name=_("Software manager"), description=_("Manage your receiver's software"), where = PluginDescriptor.WHERE_EXTENSIONSMENU, fnc=UpgradeMain))