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)
421 self.reloadPluginlist()
425 def runUpgrade(self, result):
427 self.session.openWithCallback(self.runUpgradeFinished, Ipkg, cmdList = self.cmdList)
429 def runUpgradeFinished(self):
430 self.session.openWithCallback(self.UpgradeReboot, MessageBox, _("Upgrade finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
432 def UpgradeReboot(self, result):
436 cur = self['list'].l.getCurrentSelection()
439 item = self['list'].l.getCurrentSelectionIndex()
440 self.list[item] = self.buildEntryComponent(entry[0], entry[1], entry[2], 'installed')
441 self.cachelist[item] = [entry[0], entry[1], entry[2], 'installed']
442 self['list'].l.setList(self.list)
443 write_cache(self.cache_file, self.cachelist)
444 self.reloadPluginlist()
448 def ipkgCallback(self, event, param):
449 if event == IpkgComponent.EVENT_ERROR:
450 self.list_updating = False
451 self.status.setText(_("An error occured!"))
452 elif event == IpkgComponent.EVENT_DONE:
453 if self.list_updating:
454 self.list_updating = False
456 self.Console = Console()
458 self.Console.ePopen(cmd, self.IpkgList_Finished)
459 #print event, "-", param
462 def IpkgList_Finished(self, result, retval, extra_args = None):
465 for x in result.splitlines():
466 split = x.split(' - ')
467 self.packetlist.append([split[0].strip(), split[1].strip(),split[2].strip()])
469 self.Console = Console()
470 cmd = "ipkg list_installed"
471 self.Console.ePopen(cmd, self.IpkgListInstalled_Finished)
473 def IpkgListInstalled_Finished(self, result, retval, extra_args = None):
475 self.installed_packetlist = {}
476 for x in result.splitlines():
477 split = x.split(' - ')
478 self.installed_packetlist[split[0].strip()] = split[1].strip()
479 self.buildPacketList()
481 def PacketEntryComponent(self,entry):
483 res.append(MultiContentEntryText(pos=(5, 1), size=(440, 28), font=0, text= entry[0]))
484 res.append(MultiContentEntryText(pos=(5, 26), size=(440, 20), font=1, text=entry[2]))
485 res.append(MultiContentEntryPixmapAlphaTest(pos=(445, 2), size=(48, 48), png = entry[4]))
486 res.append(MultiContentEntryPixmapAlphaTest(pos=(5, 50), size=(510, 2), png = entry[5]))
489 def buildEntryComponent(self, name, version, description, state):
490 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/div-h.png"))
491 if state == 'installed':
492 installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_PLUGINS, "SystemPlugins/SoftwareManager/installed.png"))
493 return(self.PacketEntryComponent([name, version, description, state, installedpng, divpng]))
494 elif state == 'upgradeable':
495 upgradeablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_PLUGINS, "SystemPlugins/SoftwareManager/upgradeable.png"))
496 return(self.PacketEntryComponent([name, version, description, state, upgradeablepng, divpng]))
498 installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_PLUGINS, "SystemPlugins/SoftwareManager/installable.png"))
499 return(self.PacketEntryComponent([name, version, description, state, installablepng, divpng]))
501 def buildPacketList(self):
505 if self.cache_ttl > 0 and self.vc != 0:
506 print 'Loading packagelist cache from ',self.cache_file
508 self.cachelist = load_cache(self.cache_file)
509 if len(self.cachelist) > 0:
510 for x in self.cachelist:
511 self.list.append(self.buildEntryComponent(x[0], x[1], x[2], x[3]))
512 self['list'].l.setList(self.list)
513 self["list"].instance.show()
518 if self.cache_ttl == 0 or self.inv_cache == 1 or self.vc == 0:
519 print 'rebuilding fresh package list'
520 for x in self.packetlist:
522 if self.installed_packetlist.has_key(x[0].strip()):
523 if self.installed_packetlist[x[0].strip()] == x[1].strip():
525 self.list.append(self.buildEntryComponent(x[0].strip(), x[1].strip(), x[2].strip(), status))
527 status = "upgradeable"
528 self.list.append(self.buildEntryComponent(x[0].strip(), x[1].strip(), x[2].strip(), status))
530 status = "installable"
531 self.list.append(self.buildEntryComponent(x[0].strip(), x[1].strip(), x[2].strip(), status))
532 self.cachelist.append([x[0].strip(), x[1].strip(), x[2].strip(), status])
533 write_cache(self.cache_file, self.cachelist)
534 self['list'].l.setList(self.list)
535 self["list"].instance.show()
538 def reloadPluginlist(self):
539 plugins.readPluginList(resolveFilename(SCOPE_PLUGINS))
541 class UpdatePlugin(Screen):
543 <screen position="100,100" size="550,200" title="Software Update..." >
544 <widget name="activityslider" position="0,0" size="550,5" />
545 <widget name="slider" position="0,100" size="550,30" />
546 <widget name="package" position="10,30" size="540,20" font="Regular;18"/>
547 <widget name="status" position="10,60" size="540,45" font="Regular;18"/>
550 def __init__(self, session, args = None):
551 self.skin = UpdatePlugin.skin
552 Screen.__init__(self, session)
554 self.sliderPackages = { "dreambox-dvb-modules": 1, "enigma2": 2, "tuxbox-image-info": 3 }
556 self.slider = Slider(0, 4)
557 self["slider"] = self.slider
558 self.activityslider = Slider(0, 100)
559 self["activityslider"] = self.activityslider
560 self.status = Label(_("Upgrading Dreambox... Please wait"))
561 self["status"] = self.status
562 self.package = Label()
563 self["package"] = self.package
569 self.activityTimer = eTimer()
570 self.activityTimer.callback.append(self.doActivityTimer)
571 self.activityTimer.start(100, False)
573 self.ipkg = IpkgComponent()
574 self.ipkg.addCallback(self.ipkgCallback)
577 self.package.setText(_("Package list update"))
578 self.ipkg.startCmd(IpkgComponent.CMD_UPDATE)
580 self["actions"] = ActionMap(["WizardActions"],
586 def doActivityTimer(self):
588 if self.activity == 100:
590 self.activityslider.setValue(self.activity)
592 def ipkgCallback(self, event, param):
593 if event == IpkgComponent.EVENT_DOWNLOAD:
594 self.status.setText(_("Downloading"))
595 elif event == IpkgComponent.EVENT_UPGRADE:
596 if self.sliderPackages.has_key(param):
597 self.slider.setValue(self.sliderPackages[param])
598 self.package.setText(param)
599 self.status.setText(_("Upgrading"))
601 elif event == IpkgComponent.EVENT_INSTALL:
602 self.package.setText(param)
603 self.status.setText(_("Installing"))
605 elif event == IpkgComponent.EVENT_CONFIGURING:
606 self.package.setText(param)
607 self.status.setText(_("Configuring"))
608 elif event == IpkgComponent.EVENT_MODIFIED:
609 self.session.openWithCallback(
610 self.modificationCallback,
612 _("A configuration file (%s) was modified since Installation.\nDo you want to keep your version?") % (param)
614 elif event == IpkgComponent.EVENT_ERROR:
616 elif event == IpkgComponent.EVENT_DONE:
618 self.updating = False
619 self.ipkg.startCmd(IpkgComponent.CMD_UPGRADE, args = {'test_only': False})
620 elif self.error == 0:
621 self.slider.setValue(4)
623 self.activityTimer.stop()
624 self.activityslider.setValue(0)
626 self.package.setText("")
627 self.status.setText(_("Done - Installed or upgraded %d packages") % self.packages)
629 self.activityTimer.stop()
630 self.activityslider.setValue(0)
631 error = _("your dreambox might be unusable now. Please consult the manual for further assistance before rebooting your dreambox.")
632 if self.packages == 0:
633 error = _("No packages were upgraded yet. So you can check your network and try again.")
635 error = _("Your dreambox isn't connected to the internet properly. Please check it and try again.")
636 self.status.setText(_("Error") + " - " + error)
637 #print event, "-", param
640 def modificationCallback(self, res):
641 self.ipkg.write(res and "N" or "Y")
644 if not self.ipkg.isRunning():
645 if self.packages != 0 and self.error == 0:
646 self.session.openWithCallback(self.exitAnswer, MessageBox, _("Upgrade finished.") +" "+_("Do you want to reboot your Dreambox?"))
650 def exitAnswer(self, result):
651 if result is not None and result:
657 class IpkgInstaller(Screen):
659 <screen position="100,100" size="550,400" title="..." >
660 <widget name="red" halign="center" valign="center" position="0,0" size="140,60" backgroundColor="red" font="Regular;21" />
661 <widget name="green" halign="center" valign="center" position="140,0" text="Install selected" size="140,60" backgroundColor="green" font="Regular;21" />
662 <widget name="yellow" halign="center" valign="center" position="280,0" size="140,60" backgroundColor="yellow" font="Regular;21" />
663 <widget name="blue" halign="center" valign="center" position="420,0" size="140,60" backgroundColor="blue" font="Regular;21" />
664 <widget name="list" position="0,60" size="550,360" />
668 def __init__(self, session, list):
669 self.skin = IpkgInstaller.skin
670 Screen.__init__(self, session)
672 self.list = SelectionList()
673 self["list"] = self.list
674 for listindex in range(len(list)):
675 self.list.addSelection(list[listindex], list[listindex], listindex, True)
677 self["red"] = Label()
678 self["green"] = Label()
679 self["yellow"] = Label()
680 self["blue"] = Label()
682 self["actions"] = ActionMap(["OkCancelActions", "ColorActions"],
684 "ok": self.list.toggleSelection,
685 "cancel": self.close,
686 "green": self.install
690 list = self.list.getSelectionsList()
693 cmdList.append((IpkgComponent.CMD_INSTALL, { "package": item[1] }))
694 self.session.open(Ipkg, cmdList = cmdList)
696 def filescan_open(list, session, **kwargs):
697 filelist = [x.path for x in list]
698 session.open(IpkgInstaller, filelist) # list
700 def filescan(**kwargs):
701 from Components.Scanner import Scanner, ScanPath
703 Scanner(mimetypes = ["application/x-debian-package"],
706 ScanPath(path = "ipk", with_subdirs = True),
707 ScanPath(path = "", with_subdirs = False),
710 description = "Install software updates...",
711 openfnc = filescan_open, )
713 def UpgradeMain(session, **kwargs):
714 session.open(UpdatePluginMenu)
716 def startSetup(menuid):
717 if menuid != "setup":
719 return [(_("Software manager") + "...", UpgradeMain, "software_manager", 50)]
721 def Plugins(path, **kwargs):
725 PluginDescriptor(name=_("Software manager"), description=_("Manage your receiver's software"), where = PluginDescriptor.WHERE_MENU, fnc=startSetup),
726 #PluginDescriptor(name=_("Software manager"), description=_("Manage your receiver's software"), icon="update.png", where = PluginDescriptor.WHERE_PLUGINMENU, fnc=UpgradeMain),
727 PluginDescriptor(name=_("Ipkg"), where = PluginDescriptor.WHERE_FILESCAN, fnc = filescan)