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 Tools.Directories import fileExists, resolveFilename, SCOPE_PLUGINS, SCOPE_SKIN_IMAGE
20 from Tools.LoadPixmap import LoadPixmap
21 from enigma import eTimer, quitMainloop, RT_HALIGN_LEFT, RT_VALIGN_CENTER, eListboxPythonMultiContent, eListbox, gFont
22 from cPickle import dump, load
24 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
25 from time import time, gmtime, strftime, localtime
26 from stat import ST_MTIME
27 from datetime import date
29 from ImageWizard import ImageWizard
30 from BackupRestore import BackupSelection, RestoreMenu, BackupScreen, RestoreScreen, getBackupPath, getBackupFilename
32 config.plugins.configurationbackup = ConfigSubsection()
33 config.plugins.configurationbackup.backuplocation = ConfigText(default = '/media/hdd/', visible_width = 50, fixed_size = False)
34 config.plugins.configurationbackup.backupdirs = ConfigLocations(default=['/etc/enigma2/', '/etc/network/interfaces', '/etc/wpa_supplicant.conf'])
36 def write_cache(cache_file, cache_data):
38 if not os_path.isdir( os_path.dirname(cache_file) ):
40 mkdir( os_path.dirname(cache_file) )
42 print os_path.dirname(cache_file), 'is a file'
43 fd = open(cache_file, 'w')
44 dump(cache_data, fd, -1)
47 def valid_cache(cache_file, cache_ttl):
48 #See if the cache file exists and is still living
50 mtime = stat(cache_file)[ST_MTIME]
54 if (curr_time - mtime) > cache_ttl:
59 def load_cache(cache_file):
67 class UpdatePluginMenu(Screen):
69 <screen name="UpdatePluginMenu" position="90,130" size="550,330" title="Softwaremanager..." >
70 <ePixmap pixmap="skin_default/border_menu.png" position="10,10" zPosition="1" size="250,300" transparent="1" alphatest="on" />
71 <widget source="menu" render="Listbox" position="20,20" size="230,260" scrollbarMode="showOnDemand">
72 <convert type="TemplatedMultiContent">
74 MultiContentEntryText(pos = (2, 2), size = (230, 22), flags = RT_HALIGN_LEFT, text = 1), # index 0 is the MenuText,
76 "fonts": [gFont("Regular", 20)],
81 <widget source="menu" render="Listbox" position="280,10" size="230,300" scrollbarMode="showNever" selectionDisabled="1">
82 <convert type="TemplatedMultiContent">
84 MultiContentEntryText(pos = (2, 2), size = (230, 300), flags = RT_HALIGN_CENTER|RT_VALIGN_CENTER|RT_WRAP, text = 2), # index 0 is the MenuText,
86 "fonts": [gFont("Regular", 20)],
93 def __init__(self, session, args = 0):
94 Screen.__init__(self, session)
95 self.skin_path = plugin_path
98 self.oktext = _("\nPress OK on your remote control to continue.")
99 self.backupdirs = ' '.join( config.plugins.configurationbackup.backupdirs.value )
101 self.list.append(("software-update", _("Software update"), _("\nOnline update of your Dreambox software." ) + self.oktext) )
102 self.list.append(("software-restore", _("Software restore"), _("\nRestore your Dreambox with a new firmware." ) + self.oktext))
103 self.list.append(("system-backup", _("Backup system settings"), _("\nBackup your Dreambox settings." ) + self.oktext))
104 self.list.append(("system-restore",_("Restore system settings"), _("\nRestore your Dreambox settings." ) + self.oktext))
105 if config.usage.setup_level.index >= 2: # expert+
106 self.list.append(("advanced", _("Advanced Options"), _("\nAdvanced options and settings." ) + self.oktext))
108 self.list.append(("ipkg-manager", _("Packet management"), _("\nView, install and remove available or installed packages." ) + self.oktext))
109 self.list.append(("ipkg-install", _("Install local IPKG"), _("\nScan for local packages and install them." ) + self.oktext))
110 self.list.append(("advancedrestore", _("Advanced restore"), _("\nRestore your backups by date." ) + self.oktext))
111 self.list.append(("backuplocation", _("Choose backup location"), _("\nSelect your backup device.\nCurrent device: " ) + config.plugins.configurationbackup.backuplocation.value + self.oktext ))
112 self.list.append(("backupfiles", _("Choose backup files"), _("Select files for backup. Currently selected:\n" ) + self.backupdirs + self.oktext))
113 self.list.append(("ipkg-source",_("Choose upgrade source"), _("\nEdit the upgrade source address." ) + self.oktext))
115 self["menu"] = List(self.list)
117 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"],
124 self.onLayoutFinish.append(self.layoutFinished)
125 self.backuppath = getBackupPath()
126 self.backupfile = getBackupFilename()
127 self.fullbackupfilename = self.backuppath + "/" + self.backupfile
128 self.onShown.append(self.setWindowTitle)
130 def layoutFinished(self):
132 self["menu"].index = idx
134 def setWindowTitle(self):
135 self.setTitle(_("Software manager..."))
138 current = self["menu"].getCurrent()
142 if (current == "software-restore"):
143 self.session.open(ImageWizard)
144 elif (current == "software-update"):
145 self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to update your Dreambox?")+"\n"+_("\nAfter pressing OK, please wait!"))
146 elif (current == "advanced"):
147 self.session.open(UpdatePluginMenu, 1)
148 elif (current == "system-backup"):
149 self.session.openWithCallback(self.backupDone,BackupScreen, runBackup = True)
150 elif (current == "system-restore"):
151 if os_path.exists(self.fullbackupfilename):
152 self.session.openWithCallback(self.startRestore, MessageBox, _("Are you sure you want to restore your Enigma2 backup?\nEnigma2 will restart after the restore"))
154 self.session.open(MessageBox, _("Sorry no backups found!"), MessageBox.TYPE_INFO)
156 if (current == "ipkg-manager"):
157 self.session.open(PacketManager, self.skin_path)
158 elif (current == "ipkg-source"):
159 self.session.open(IPKGSource)
160 elif (current == "ipkg-install"):
162 from Plugins.Extensions.MediaScanner.plugin import main
165 self.session.open(MessageBox, _("Sorry MediaScanner is not installed!"), MessageBox.TYPE_INFO)
166 elif (current == "backuplocation"):
167 parts = [ (r.description, r.mountpoint, self.session) for r in harddiskmanager.getMountedPartitions(onlyhotplug = False)]
169 if not access(x[1], F_OK|R_OK|W_OK) or x[1] == '/':
172 if x[1].startswith('/autofs/'):
175 self.session.openWithCallback(self.backuplocation_choosen, ChoiceBox, title = _("Please select medium to use as backup location"), list = parts)
176 elif (current == "backupfiles"):
177 self.session.openWithCallback(self.backupfiles_choosen,BackupSelection)
178 elif (current == "advancedrestore"):
179 self.session.open(RestoreMenu, self.skin_path)
181 def backupfiles_choosen(self, ret):
182 self.backupdirs = ' '.join( config.plugins.configurationbackup.backupdirs.value )
184 def backuplocation_choosen(self, option):
185 if option is not None:
186 config.plugins.configurationbackup.backuplocation.value = str(option[1])
187 config.plugins.configurationbackup.backuplocation.save()
188 config.plugins.configurationbackup.save()
190 self.createBackupfolders()
192 def runUpgrade(self, result):
194 self.session.open(UpdatePlugin, self.skin_path)
196 """def runFinished(self):
197 self.session.openWithCallback(self.reboot, MessageBox, _("Upgrade finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
199 def reboot(self, result):
205 def createBackupfolders(self):
206 print "Creating backup folder if not already there..."
207 self.backuppath = getBackupPath()
209 if (os_path.exists(self.backuppath) == False):
210 makedirs(self.backuppath)
212 self.session.open(MessageBox, _("Sorry, your backup destination is not writeable.\n\nPlease choose another one."), MessageBox.TYPE_INFO)
214 def backupDone(self,retval = None):
216 self.session.open(MessageBox, _("Backup done."), MessageBox.TYPE_INFO)
218 self.session.open(MessageBox, _("Backup failed."), MessageBox.TYPE_INFO)
220 def startRestore(self, ret = False):
223 self.session.open(RestoreScreen, runRestore = True)
226 class IPKGSource(Screen):
228 <screen position="100,100" size="550,60" title="IPKG source" >
229 <widget name="text" position="0,0" size="550,25" font="Regular;20" backgroundColor="background" foregroundColor="#cccccc" />
232 def __init__(self, session, args = None):
233 Screen.__init__(self, session)
234 self.session = session
236 #FIXMEEEE add handling for more than one feed conf file!
239 fp = file('/etc/ipkg/official-feed.conf', 'r')
240 sources = fp.readlines()
247 self["text"] = Input(text, maxSize=False, type=Input.TEXT)
249 self["actions"] = NumberActionMap(["WizardActions", "InputActions", "TextEntryActions", "KeyboardInputActions"],
253 "left": self.keyLeft,
254 "right": self.keyRight,
255 "home": self.keyHome,
257 "deleteForward": self.keyDeleteForward,
258 "deleteBackward": self.keyDeleteBackward,
259 "1": self.keyNumberGlobal,
260 "2": self.keyNumberGlobal,
261 "3": self.keyNumberGlobal,
262 "4": self.keyNumberGlobal,
263 "5": self.keyNumberGlobal,
264 "6": self.keyNumberGlobal,
265 "7": self.keyNumberGlobal,
266 "8": self.keyNumberGlobal,
267 "9": self.keyNumberGlobal,
268 "0": self.keyNumberGlobal
272 text = self["text"].getText()
274 fp = file('/etc/ipkg/official-feed.conf', 'w')
291 def keyDeleteForward(self):
292 self["text"].delete()
294 def keyDeleteBackward(self):
295 self["text"].deleteBackward()
297 def keyNumberGlobal(self, number):
298 print "pressed", number
299 self["text"].number(number)
301 class PacketList(MenuList):
302 def __init__(self, list, enableWrapAround=True):
303 MenuList.__init__(self, list, enableWrapAround, eListboxPythonMultiContent)
304 self.l.setFont(0, gFont("Regular", 22))
305 self.l.setFont(1, gFont("Regular", 14))
306 self.l.setItemHeight(52)
308 class PacketManager(Screen):
310 <screen position="90,80" size="530,420" title="IPKG upgrade..." >
311 <widget name="list" position="5,10" size="520,365" zPosition="1" scrollbarMode="showOnDemand" />
312 <widget name="status" position="30,160" size="530,40" zPosition="4" font="Regular;22" halign="left" transparent="1" />
313 <ePixmap pixmap="skin_default/buttons/red.png" position="10,380" zPosition="2" size="140,40" transparent="1" alphatest="on" />
314 <widget name="closetext" position="20,390" size="140,21" zPosition="10" font="Regular;21" transparent="1" />
315 <ePixmap pixmap="skin_default/buttons/green.png" position="160,380" zPosition="2" size="140,40" transparent="1" alphatest="on" />
316 <widget name="reloadtext" position="170,390" size="300,21" zPosition="10" font="Regular;21" transparent="1" />
319 def __init__(self, session, plugin_path, args = None):
320 Screen.__init__(self, session)
321 self.session = session
322 self.skin_path = plugin_path
324 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"],
329 "green": self.reload,
333 self["list"] = PacketList(self.list)
334 self.status = Label()
335 self["closetext"] = Label(_("Close"))
336 self["reloadtext"] = Label(_("Reload"))
337 self["status"] = self.status
339 self.list_updating = True
341 self.installed_packetlist = {}
342 self.Console = Console()
345 self.cache_ttl = 86400 #600 is default, 0 disables, Seconds cache is considered valid (24h should be ok for caching ipkgs)
346 self.cache_file = '/usr/lib/enigma2/python/Plugins/SystemPlugins/SoftwareManager/packetmanager.cache' #Path to cache directory
347 self.oktext = _("\nAfter pressing OK, please wait!")
349 self.ipkg = IpkgComponent()
350 self.ipkg.addCallback(self.ipkgCallback)
351 self.onShown.append(self.setWindowTitle)
352 self.onLayoutFinish.append(self.rebuildList)
353 self.onClose.append(self.cleanup)
357 if self.Console is not None:
361 if (os_path.exists(self.cache_file) == True):
362 remove(self.cache_file)
363 self.list_updating = True
366 def setWindowTitle(self):
367 self.setTitle(_("Packet manager"))
369 def rebuildList(self):
370 self["list"].instance.hide()
371 self.status.setText(_("Package list update"))
374 self.vc = valid_cache(self.cache_file, self.cache_ttl)
375 if self.cache_ttl > 0 and self.vc != 0:
377 self.buildPacketList()
380 if self.cache_ttl == 0 or self.inv_cache == 1 or self.vc == 0:
382 self.ipkg.startCmd(IpkgComponent.CMD_UPDATE)
384 def go(self, returnValue = None):
385 cur = self['list'].l.getCurrentSelection()
389 if returnValue[3] == 'installed':
390 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": returnValue[0] }))
391 if len(self.cmdList):
392 self.session.openWithCallback(self.runRemove, MessageBox, _("Do you want to remove the package:\n" + returnValue[0] + "\n" + self.oktext))
393 elif returnValue[3] == 'upgradeable':
394 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": returnValue[0] }))
395 if len(self.cmdList):
396 self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to upgrade the package:\n" + returnValue[0] + "\n" + self.oktext))
398 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": returnValue[0] }))
399 if len(self.cmdList):
400 self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to install the package:\n" + returnValue[0] + "\n" + self.oktext))
402 def runRemove(self, result):
404 self.session.openWithCallback(self.runRemoveFinished, Ipkg, cmdList = self.cmdList)
406 def runRemoveFinished(self):
407 self.session.openWithCallback(self.RemoveReboot, MessageBox, _("Remove finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
409 def RemoveReboot(self, result):
413 cur = self['list'].l.getCurrentSelection()
416 item = self['list'].l.getCurrentSelectionIndex()
417 self.list[item] = self.buildEntryComponent(entry[0], entry[1], entry[2], 'installable')
418 self.cachelist[item] = [entry[0], entry[1], entry[2], 'installable']
419 self['list'].l.setList(self.list)
420 write_cache(self.cache_file, self.cachelist)
424 def runUpgrade(self, result):
426 self.session.openWithCallback(self.runUpgradeFinished, Ipkg, cmdList = self.cmdList)
428 def runUpgradeFinished(self):
429 self.session.openWithCallback(self.UpgradeReboot, MessageBox, _("Upgrade finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
431 def UpgradeReboot(self, result):
435 cur = self['list'].l.getCurrentSelection()
438 item = self['list'].l.getCurrentSelectionIndex()
439 self.list[item] = self.buildEntryComponent(entry[0], entry[1], entry[2], 'installed')
440 self.cachelist[item] = [entry[0], entry[1], entry[2], 'installed']
441 self['list'].l.setList(self.list)
442 write_cache(self.cache_file, self.cachelist)
446 def ipkgCallback(self, event, param):
447 if event == IpkgComponent.EVENT_ERROR:
448 self.list_updating = False
449 self.status.setText(_("An error occured!"))
450 elif event == IpkgComponent.EVENT_DONE:
451 if self.list_updating:
452 self.list_updating = False
454 self.Console = Console()
456 self.Console.ePopen(cmd, self.IpkgList_Finished)
457 #print event, "-", param
460 def IpkgList_Finished(self, result, retval, extra_args = None):
463 for x in result.splitlines():
464 split = x.split(' - ')
465 self.packetlist.append([split[0].strip(), split[1].strip(),split[2].strip()])
467 self.Console = Console()
468 cmd = "ipkg list_installed"
469 self.Console.ePopen(cmd, self.IpkgListInstalled_Finished)
471 def IpkgListInstalled_Finished(self, result, retval, extra_args = None):
473 self.installed_packetlist = {}
474 for x in result.splitlines():
475 split = x.split(' - ')
476 self.installed_packetlist[split[0].strip()] = split[1].strip()
477 self.buildPacketList()
479 def PacketEntryComponent(self,entry):
481 res.append(MultiContentEntryText(pos=(5, 1), size=(440, 28), font=0, text= entry[0]))
482 res.append(MultiContentEntryText(pos=(5, 26), size=(440, 20), font=1, text=entry[2]))
483 res.append(MultiContentEntryPixmapAlphaTest(pos=(445, 2), size=(48, 48), png = entry[4]))
484 res.append(MultiContentEntryPixmapAlphaTest(pos=(5, 50), size=(510, 2), png = entry[5]))
487 def buildEntryComponent(self, name, version, description, state):
488 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/div-h.png"))
489 if state == 'installed':
490 installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_PLUGINS, "SystemPlugins/SoftwareManager/installed.png"))
491 return(self.PacketEntryComponent([name, version, description, state, installedpng, divpng]))
492 elif state == 'upgradeable':
493 upgradeablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_PLUGINS, "SystemPlugins/SoftwareManager/upgradeable.png"))
494 return(self.PacketEntryComponent([name, version, description, state, upgradeablepng, divpng]))
496 installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_PLUGINS, "SystemPlugins/SoftwareManager/installable.png"))
497 return(self.PacketEntryComponent([name, version, description, state, installablepng, divpng]))
499 def buildPacketList(self):
503 if self.cache_ttl > 0 and self.vc != 0:
504 print 'Loading packagelist cache from ',self.cache_file
506 self.cachelist = load_cache(self.cache_file)
507 if len(self.cachelist) > 0:
508 for x in self.cachelist:
509 self.list.append(self.buildEntryComponent(x[0], x[1], x[2], x[3]))
510 self['list'].l.setList(self.list)
511 self["list"].instance.show()
516 if self.cache_ttl == 0 or self.inv_cache == 1 or self.vc == 0:
517 print 'rebuilding fresh package list'
518 for x in self.packetlist:
520 if self.installed_packetlist.has_key(x[0].strip()):
521 if self.installed_packetlist[x[0].strip()] == x[1].strip():
523 self.list.append(self.buildEntryComponent(x[0].strip(), x[1].strip(), x[2].strip(), status))
525 status = "upgradeable"
526 self.list.append(self.buildEntryComponent(x[0].strip(), x[1].strip(), x[2].strip(), status))
528 status = "installable"
529 self.list.append(self.buildEntryComponent(x[0].strip(), x[1].strip(), x[2].strip(), status))
530 self.cachelist.append([x[0].strip(), x[1].strip(), x[2].strip(), status])
531 write_cache(self.cache_file, self.cachelist)
532 self['list'].l.setList(self.list)
533 self["list"].instance.show()
536 def reloadPluginlist(self):
537 plugins.readPluginList(resolveFilename(SCOPE_PLUGINS))
539 class UpdatePlugin(Screen):
541 <screen position="100,100" size="550,200" title="Software Update..." >
542 <widget name="activityslider" position="0,0" size="550,5" />
543 <widget name="slider" position="0,100" size="550,30" />
544 <widget name="package" position="10,30" size="540,20" font="Regular;18"/>
545 <widget name="status" position="10,60" size="540,45" font="Regular;18"/>
548 def __init__(self, session, args = None):
549 self.skin = UpdatePlugin.skin
550 Screen.__init__(self, session)
552 self.sliderPackages = { "dreambox-dvb-modules": 1, "enigma2": 2, "tuxbox-image-info": 3 }
554 self.slider = Slider(0, 4)
555 self["slider"] = self.slider
556 self.activityslider = Slider(0, 100)
557 self["activityslider"] = self.activityslider
558 self.status = Label(_("Upgrading Dreambox... Please wait"))
559 self["status"] = self.status
560 self.package = Label()
561 self["package"] = self.package
567 self.activityTimer = eTimer()
568 self.activityTimer.callback.append(self.doActivityTimer)
569 self.activityTimer.start(100, False)
571 self.ipkg = IpkgComponent()
572 self.ipkg.addCallback(self.ipkgCallback)
575 self.package.setText(_("Package list update"))
576 self.ipkg.startCmd(IpkgComponent.CMD_UPDATE)
578 self["actions"] = ActionMap(["WizardActions"],
584 def doActivityTimer(self):
586 if self.activity == 100:
588 self.activityslider.setValue(self.activity)
590 def ipkgCallback(self, event, param):
591 if event == IpkgComponent.EVENT_DOWNLOAD:
592 self.status.setText(_("Downloading"))
593 elif event == IpkgComponent.EVENT_UPGRADE:
594 if self.sliderPackages.has_key(param):
595 self.slider.setValue(self.sliderPackages[param])
596 self.package.setText(param)
597 self.status.setText(_("Upgrading"))
599 elif event == IpkgComponent.EVENT_INSTALL:
600 self.package.setText(param)
601 self.status.setText(_("Installing"))
603 elif event == IpkgComponent.EVENT_CONFIGURING:
604 self.package.setText(param)
605 self.status.setText(_("Configuring"))
606 elif event == IpkgComponent.EVENT_MODIFIED:
607 self.session.openWithCallback(
608 self.modificationCallback,
610 _("A configuration file (%s) was modified since Installation.\nDo you want to keep your version?") % (param)
612 elif event == IpkgComponent.EVENT_ERROR:
614 elif event == IpkgComponent.EVENT_DONE:
616 self.updating = False
617 self.ipkg.startCmd(IpkgComponent.CMD_UPGRADE, args = {'test_only': False})
618 elif self.error == 0:
619 self.slider.setValue(4)
621 self.activityTimer.stop()
622 self.activityslider.setValue(0)
624 self.package.setText("")
625 self.status.setText(_("Done - Installed or upgraded %d packages") % self.packages)
627 self.activityTimer.stop()
628 self.activityslider.setValue(0)
629 error = _("your dreambox might be unusable now. Please consult the manual for further assistance before rebooting your dreambox.")
630 if self.packages == 0:
631 error = _("No packages were upgraded yet. So you can check your network and try again.")
633 error = _("Your dreambox isn't connected to the internet properly. Please check it and try again.")
634 self.status.setText(_("Error") + " - " + error)
635 #print event, "-", param
638 def modificationCallback(self, res):
639 self.ipkg.write(res and "N" or "Y")
642 if not self.ipkg.isRunning():
643 if self.packages != 0 and self.error == 0:
644 self.session.openWithCallback(self.exitAnswer, MessageBox, _("Upgrade finished.") +" "+_("Do you want to reboot your Dreambox?"))
648 def exitAnswer(self, result):
649 if result is not None and result:
655 class IpkgInstaller(Screen):
657 <screen position="100,100" size="550,400" title="..." >
658 <widget name="red" halign="center" valign="center" position="0,0" size="140,60" backgroundColor="red" font="Regular;21" />
659 <widget name="green" halign="center" valign="center" position="140,0" text="Install selected" size="140,60" backgroundColor="green" font="Regular;21" />
660 <widget name="yellow" halign="center" valign="center" position="280,0" size="140,60" backgroundColor="yellow" font="Regular;21" />
661 <widget name="blue" halign="center" valign="center" position="420,0" size="140,60" backgroundColor="blue" font="Regular;21" />
662 <widget name="list" position="0,60" size="550,360" />
666 def __init__(self, session, list):
667 self.skin = IpkgInstaller.skin
668 Screen.__init__(self, session)
670 self.list = SelectionList()
671 self["list"] = self.list
672 for listindex in range(len(list)):
673 self.list.addSelection(list[listindex], list[listindex], listindex, True)
675 self["red"] = Label()
676 self["green"] = Label()
677 self["yellow"] = Label()
678 self["blue"] = Label()
680 self["actions"] = ActionMap(["OkCancelActions", "ColorActions"],
682 "ok": self.list.toggleSelection,
683 "cancel": self.close,
684 "green": self.install
688 list = self.list.getSelectionsList()
691 cmdList.append((IpkgComponent.CMD_INSTALL, { "package": item[1] }))
692 self.session.open(Ipkg, cmdList = cmdList)
694 def filescan_open(list, session, **kwargs):
695 filelist = [x.path for x in list]
696 session.open(IpkgInstaller, filelist) # list
698 def filescan(**kwargs):
699 from Components.Scanner import Scanner, ScanPath
701 Scanner(mimetypes = ["application/x-debian-package"],
704 ScanPath(path = "ipk", with_subdirs = True),
705 ScanPath(path = "", with_subdirs = False),
708 description = "Install software updates...",
709 openfnc = filescan_open, )
711 def UpgradeMain(session, **kwargs):
712 session.open(UpdatePluginMenu)
714 def startSetup(menuid):
715 if menuid != "setup":
717 return [(_("Software manager") + "...", UpgradeMain, "software_manager", 50)]
719 def Plugins(path, **kwargs):
723 PluginDescriptor(name=_("Software manager"), description=_("Manage your receiver's software"), where = PluginDescriptor.WHERE_MENU, fnc=startSetup),
724 #PluginDescriptor(name=_("Software manager"), description=_("Manage your receiver's software"), icon="update.png", where = PluginDescriptor.WHERE_PLUGINMENU, fnc=UpgradeMain),
725 PluginDescriptor(name=_("Ipkg"), where = PluginDescriptor.WHERE_FILESCAN, fnc = filescan)