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, getDesktop
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 2 is the Description,
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(IPKGMenu, self.skin_path)
161 #self.session.open(IPKGSource)
162 elif (current == "ipkg-install"):
164 from Plugins.Extensions.MediaScanner.plugin import main
167 self.session.open(MessageBox, _("Sorry MediaScanner is not installed!"), MessageBox.TYPE_INFO)
168 elif (current == "backuplocation"):
169 parts = [ (r.description, r.mountpoint, self.session) for r in harddiskmanager.getMountedPartitions(onlyhotplug = False)]
171 if not access(x[1], F_OK|R_OK|W_OK) or x[1] == '/':
174 if x[1].startswith('/autofs/'):
177 self.session.openWithCallback(self.backuplocation_choosen, ChoiceBox, title = _("Please select medium to use as backup location"), list = parts)
178 elif (current == "backupfiles"):
179 self.session.openWithCallback(self.backupfiles_choosen,BackupSelection)
180 elif (current == "advancedrestore"):
181 self.session.open(RestoreMenu, self.skin_path)
183 def backupfiles_choosen(self, ret):
184 self.backupdirs = ' '.join( config.plugins.configurationbackup.backupdirs.value )
186 def backuplocation_choosen(self, option):
187 if option is not None:
188 config.plugins.configurationbackup.backuplocation.value = str(option[1])
189 config.plugins.configurationbackup.backuplocation.save()
190 config.plugins.configurationbackup.save()
192 self.createBackupfolders()
194 def runUpgrade(self, result):
196 self.session.open(UpdatePlugin, self.skin_path)
198 """def runFinished(self):
199 self.session.openWithCallback(self.reboot, MessageBox, _("Upgrade finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
201 def reboot(self, result):
207 def createBackupfolders(self):
208 print "Creating backup folder if not already there..."
209 self.backuppath = getBackupPath()
211 if (os_path.exists(self.backuppath) == False):
212 makedirs(self.backuppath)
214 self.session.open(MessageBox, _("Sorry, your backup destination is not writeable.\n\nPlease choose another one."), MessageBox.TYPE_INFO)
216 def backupDone(self,retval = None):
218 self.session.open(MessageBox, _("Backup done."), MessageBox.TYPE_INFO)
220 self.session.open(MessageBox, _("Backup failed."), MessageBox.TYPE_INFO)
222 def startRestore(self, ret = False):
225 self.session.open(RestoreScreen, runRestore = True)
227 class IPKGMenu(Screen):
229 <screen name="IPKGMenu" position="135,144" size="450,320" title="Select IPKG source......" >
230 <widget name="filelist" position="10,10" size="430,240" scrollbarMode="showOnDemand" />
231 <ePixmap pixmap="skin_default/buttons/red.png" position="10,280" zPosition="2" size="140,40" transparent="1" alphatest="on" />
232 <widget name="closetext" position="20,290" size="140,21" zPosition="10" font="Regular;21" transparent="1" />
233 <ePixmap pixmap="skin_default/buttons/green.png" position="160,280" zPosition="2" size="140,40" transparent="1" alphatest="on" />
234 <widget name="edittext" position="170,290" size="300,21" zPosition="10" font="Regular;21" transparent="1" />
237 def __init__(self, session, plugin_path):
238 Screen.__init__(self, session)
239 self.skin_path = plugin_path
241 self["closetext"] = Label(_("Close"))
242 self["edittext"] = Label(_("Edit"))
251 self["actions"] = NumberActionMap(["SetupActions"],
254 "cancel": self.keyCancel
257 self["shortcuts"] = ActionMap(["ShortcutActions"],
259 "red": self.keyCancel,
263 self["filelist"] = MenuList(self.flist)
265 self.onLayoutFinish.append(self.layoutFinished)
267 def layoutFinished(self):
268 self.setWindowTitle()
270 def setWindowTitle(self):
271 self.setTitle(_("Select IPKG source to edit..."))
276 self.path = '/etc/ipkg/'
277 if (os_path.exists(self.path) == False):
280 for file in listdir(self.path):
281 if (file.endswith(".conf")):
282 if file != 'arch.conf':
283 self.flist.append((file))
285 self["filelist"].l.setList(self.flist)
288 if (self.exe == False) and (self.entry == True):
289 self.sel = self["filelist"].getCurrent()
290 self.val = self.path + self.sel
291 self.session.open(IPKGSource, self.val)
300 class IPKGSource(Screen):
302 <screen name="IPKGSource" position="100,100" size="550,80" title="IPKG source" >
303 <widget name="text" position="10,10" size="530,25" font="Regular;20" backgroundColor="background" foregroundColor="#cccccc" />
304 <ePixmap pixmap="skin_default/buttons/red.png" position="10,40" zPosition="2" size="140,40" transparent="1" alphatest="on" />
305 <widget name="closetext" position="20,50" size="140,21" zPosition="10" font="Regular;21" transparent="1" />
306 <ePixmap pixmap="skin_default/buttons/green.png" position="160,40" zPosition="2" size="140,40" transparent="1" alphatest="on" />
307 <widget name="edittext" position="170,50" size="300,21" zPosition="10" font="Regular;21" transparent="1" />
310 def __init__(self, session, configfile = None):
311 Screen.__init__(self, session)
312 self.session = session
313 self.configfile = configfile
317 fp = file(configfile, 'r')
318 sources = fp.readlines()
326 x= int(desk.size().width())
327 y= int(desk.size().height())
328 #print "[IPKGSource] mainscreen: current desktop size: %dx%d" % (x,y)
330 self["closetext"] = Label(_("Cancel"))
331 self["edittext"] = Label(_("Save"))
334 self["text"] = Input(text, maxSize=False, type=Input.TEXT)
336 self["text"] = Input(text, maxSize=False, visible_width = 55, type=Input.TEXT)
338 self["actions"] = NumberActionMap(["WizardActions", "InputActions", "TextEntryActions", "KeyboardInputActions","ShortcutActions"],
344 "left": self.keyLeft,
345 "right": self.keyRight,
346 "home": self.keyHome,
348 "deleteForward": self.keyDeleteForward,
349 "deleteBackward": self.keyDeleteBackward,
350 "1": self.keyNumberGlobal,
351 "2": self.keyNumberGlobal,
352 "3": self.keyNumberGlobal,
353 "4": self.keyNumberGlobal,
354 "5": self.keyNumberGlobal,
355 "6": self.keyNumberGlobal,
356 "7": self.keyNumberGlobal,
357 "8": self.keyNumberGlobal,
358 "9": self.keyNumberGlobal,
359 "0": self.keyNumberGlobal
362 self.onLayoutFinish.append(self.layoutFinished)
364 def layoutFinished(self):
365 self.setWindowTitle()
368 def setWindowTitle(self):
369 self.setTitle(_("Edit IPKG source URL..."))
372 text = self["text"].getText()
374 fp = file(self.configfile, 'w')
392 def keyDeleteForward(self):
393 self["text"].delete()
395 def keyDeleteBackward(self):
396 self["text"].deleteBackward()
398 def keyNumberGlobal(self, number):
399 print "pressed", number
400 self["text"].number(number)
403 class PacketManager(Screen):
405 <screen position="90,80" size="530,420" title="IPKG upgrade..." >
406 <widget source="list" render="Listbox" position="5,10" size="520,365" scrollbarMode="showOnDemand">
407 <convert type="TemplatedMultiContent">
409 MultiContentEntryText(pos = (5, 1), size = (440, 28), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
410 MultiContentEntryText(pos = (5, 26), size = (440, 20), font=1, flags = RT_HALIGN_LEFT, text = 2), # index 2 is the description
411 MultiContentEntryPixmapAlphaTest(pos = (445, 2), size = (48, 48), png = 4), # index 4 is the status pixmap
412 MultiContentEntryPixmapAlphaTest(pos = (5, 50), size = (510, 2), png = 5), # index 4 is the div pixmap
414 "fonts": [gFont("Regular", 22),gFont("Regular", 14)],
419 <ePixmap pixmap="skin_default/buttons/red.png" position="10,380" zPosition="2" size="140,40" transparent="1" alphatest="on" />
420 <widget name="closetext" position="20,390" size="140,21" zPosition="10" font="Regular;21" transparent="1" />
421 <ePixmap pixmap="skin_default/buttons/green.png" position="160,380" zPosition="2" size="140,40" transparent="1" alphatest="on" />
422 <widget name="reloadtext" position="170,390" size="300,21" zPosition="10" font="Regular;21" transparent="1" />
425 def __init__(self, session, plugin_path, args = None):
426 Screen.__init__(self, session)
427 self.session = session
428 self.skin_path = plugin_path
430 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"],
435 "green": self.reload,
440 self["list"] = List(self.list)
441 self["closetext"] = Label(_("Close"))
442 self["reloadtext"] = Label(_("Reload"))
444 self.list_updating = True
446 self.installed_packetlist = {}
447 self.Console = Console()
450 self.cache_ttl = 86400 #600 is default, 0 disables, Seconds cache is considered valid (24h should be ok for caching ipkgs)
451 self.cache_file = '/usr/lib/enigma2/python/Plugins/SystemPlugins/SoftwareManager/packetmanager.cache' #Path to cache directory
452 self.oktext = _("\nAfter pressing OK, please wait!")
454 self.ipkg = IpkgComponent()
455 self.ipkg.addCallback(self.ipkgCallback)
456 self.onShown.append(self.setWindowTitle)
457 self.onLayoutFinish.append(self.rebuildList)
461 if self.Console is not None:
462 if len(self.Console.appContainers):
463 for name in self.Console.appContainers.keys():
464 self.Console.kill(name)
468 if (os_path.exists(self.cache_file) == True):
469 remove(self.cache_file)
470 self.list_updating = True
473 def setWindowTitle(self):
474 self.setTitle(_("Packet manager"))
476 def setStatus(self,status = None):
479 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/div-h.png"))
480 if status == 'update':
481 statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_PLUGINS, "SystemPlugins/SoftwareManager/installable.png"))
482 self.statuslist.append(( _("Package list update"), '', _("Trying to download a new packetlist. Please wait..." ),'',statuspng, divpng ))
483 self['list'].setList(self.statuslist)
484 elif status == 'error':
485 statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_PLUGINS, "SystemPlugins/SoftwareManager/installed.png"))
486 self.statuslist.append(( _("Error"), '', _("There was an error downloading the packetlist. Please try again." ),'',statuspng, divpng ))
487 self['list'].setList(self.statuslist)
489 def rebuildList(self):
490 self.setStatus('update')
492 self.vc = valid_cache(self.cache_file, self.cache_ttl)
493 if self.cache_ttl > 0 and self.vc != 0:
495 self.buildPacketList()
498 if self.cache_ttl == 0 or self.inv_cache == 1 or self.vc == 0:
500 self.ipkg.startCmd(IpkgComponent.CMD_UPDATE)
502 def go(self, returnValue = None):
503 cur = self["list"].getCurrent()
508 if status == 'installed':
509 self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": package }))
510 if len(self.cmdList):
511 self.session.openWithCallback(self.runRemove, MessageBox, _("Do you want to remove the package:\n" + package + "\n" + self.oktext))
512 elif status == 'upgradeable':
513 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package }))
514 if len(self.cmdList):
515 self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to upgrade the package:\n" + package + "\n" + self.oktext))
516 elif status == "installable":
517 self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package }))
518 if len(self.cmdList):
519 self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to install the package:\n" + package + "\n" + self.oktext))
521 def runRemove(self, result):
523 self.session.openWithCallback(self.runRemoveFinished, Ipkg, cmdList = self.cmdList)
525 def runRemoveFinished(self):
526 self.session.openWithCallback(self.RemoveReboot, MessageBox, _("Remove finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
528 def RemoveReboot(self, result):
532 cur = self["list"].getCurrent()
534 item = self['list'].getIndex()
535 self.list[item] = self.buildEntryComponent(cur[0], cur[1], cur[2], 'installable')
536 self.cachelist[item] = [cur[0], cur[1], cur[2], 'installable']
537 self['list'].setList(self.list)
538 write_cache(self.cache_file, self.cachelist)
539 self.reloadPluginlist()
543 def runUpgrade(self, result):
545 self.session.openWithCallback(self.runUpgradeFinished, Ipkg, cmdList = self.cmdList)
547 def runUpgradeFinished(self):
548 self.session.openWithCallback(self.UpgradeReboot, MessageBox, _("Upgrade finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
550 def UpgradeReboot(self, result):
554 cur = self["list"].getCurrent()
556 item = self['list'].getIndex()
557 self.list[item] = self.buildEntryComponent(cur[0], cur[1], cur[2], 'installed')
558 self.cachelist[item] = [cur[0], cur[1], cur[2], 'installed']
559 self['list'].setList(self.list)
560 write_cache(self.cache_file, self.cachelist)
561 self.reloadPluginlist()
565 def ipkgCallback(self, event, param):
566 if event == IpkgComponent.EVENT_ERROR:
567 self.list_updating = False
568 self.setStatus('error')
569 elif event == IpkgComponent.EVENT_DONE:
570 if self.list_updating:
571 self.list_updating = False
573 self.Console = Console()
575 self.Console.ePopen(cmd, self.IpkgList_Finished)
576 #print event, "-", param
579 def IpkgList_Finished(self, result, retval, extra_args = None):
582 for x in result.splitlines():
583 split = x.split(' - ')
584 if not (split[0].strip().endswith('-dbg') or split[0].strip().endswith('-dev')):
585 self.packetlist.append([split[0].strip(), split[1].strip(),split[2].strip()])
587 self.Console = Console()
588 cmd = "ipkg list_installed"
589 self.Console.ePopen(cmd, self.IpkgListInstalled_Finished)
591 def IpkgListInstalled_Finished(self, result, retval, extra_args = None):
593 self.installed_packetlist = {}
594 for x in result.splitlines():
595 split = x.split(' - ')
596 if not (split[0].strip().endswith('-dbg') or split[0].strip().endswith('-dev')):
597 self.installed_packetlist[split[0].strip()] = split[1].strip()
598 self.buildPacketList()
600 def buildEntryComponent(self, name, version, description, state):
601 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/div-h.png"))
602 if state == 'installed':
603 installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_PLUGINS, "SystemPlugins/SoftwareManager/installed.png"))
604 return((name, version, description, state, installedpng, divpng))
605 elif state == 'upgradeable':
606 upgradeablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_PLUGINS, "SystemPlugins/SoftwareManager/upgradeable.png"))
607 return((name, version, description, state, upgradeablepng, divpng))
609 installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_PLUGINS, "SystemPlugins/SoftwareManager/installable.png"))
610 return((name, version, description, state, installablepng, divpng))
612 def buildPacketList(self):
616 if self.cache_ttl > 0 and self.vc != 0:
617 print 'Loading packagelist cache from ',self.cache_file
619 self.cachelist = load_cache(self.cache_file)
620 if len(self.cachelist) > 0:
621 for x in self.cachelist:
622 self.list.append(self.buildEntryComponent(x[0], x[1], x[2], x[3]))
623 self['list'].setList(self.list)
627 if self.cache_ttl == 0 or self.inv_cache == 1 or self.vc == 0:
628 print 'rebuilding fresh package list'
629 for x in self.packetlist:
631 if self.installed_packetlist.has_key(x[0].strip()):
632 if self.installed_packetlist[x[0].strip()] == x[1].strip():
634 self.list.append(self.buildEntryComponent(x[0].strip(), x[1].strip(), x[2].strip(), status))
636 status = "upgradeable"
637 self.list.append(self.buildEntryComponent(x[0].strip(), x[1].strip(), x[2].strip(), status))
639 status = "installable"
640 self.list.append(self.buildEntryComponent(x[0].strip(), x[1].strip(), x[2].strip(), status))
641 if not (x[0].strip().endswith('-dbg') or x[0].strip().endswith('-dev')):
642 self.cachelist.append([x[0].strip(), x[1].strip(), x[2].strip(), status])
643 write_cache(self.cache_file, self.cachelist)
644 self['list'].setList(self.list)
646 def reloadPluginlist(self):
647 plugins.readPluginList(resolveFilename(SCOPE_PLUGINS))
649 class UpdatePlugin(Screen):
651 <screen position="100,100" size="550,200" title="Software Update..." >
652 <widget name="activityslider" position="0,0" size="550,5" />
653 <widget name="slider" position="0,100" size="550,30" />
654 <widget name="package" position="10,30" size="540,20" font="Regular;18"/>
655 <widget name="status" position="10,60" size="540,45" font="Regular;18"/>
658 def __init__(self, session, args = None):
659 self.skin = UpdatePlugin.skin
660 Screen.__init__(self, session)
662 self.sliderPackages = { "dreambox-dvb-modules": 1, "enigma2": 2, "tuxbox-image-info": 3 }
664 self.slider = Slider(0, 4)
665 self["slider"] = self.slider
666 self.activityslider = Slider(0, 100)
667 self["activityslider"] = self.activityslider
668 self.status = Label(_("Upgrading Dreambox... Please wait"))
669 self["status"] = self.status
670 self.package = Label()
671 self["package"] = self.package
677 self.activityTimer = eTimer()
678 self.activityTimer.callback.append(self.doActivityTimer)
679 self.activityTimer.start(100, False)
681 self.ipkg = IpkgComponent()
682 self.ipkg.addCallback(self.ipkgCallback)
685 self.package.setText(_("Package list update"))
686 self.ipkg.startCmd(IpkgComponent.CMD_UPDATE)
688 self["actions"] = ActionMap(["WizardActions"],
694 def doActivityTimer(self):
696 if self.activity == 100:
698 self.activityslider.setValue(self.activity)
700 def ipkgCallback(self, event, param):
701 if event == IpkgComponent.EVENT_DOWNLOAD:
702 self.status.setText(_("Downloading"))
703 elif event == IpkgComponent.EVENT_UPGRADE:
704 if self.sliderPackages.has_key(param):
705 self.slider.setValue(self.sliderPackages[param])
706 self.package.setText(param)
707 self.status.setText(_("Upgrading"))
709 elif event == IpkgComponent.EVENT_INSTALL:
710 self.package.setText(param)
711 self.status.setText(_("Installing"))
713 elif event == IpkgComponent.EVENT_CONFIGURING:
714 self.package.setText(param)
715 self.status.setText(_("Configuring"))
716 elif event == IpkgComponent.EVENT_MODIFIED:
717 self.session.openWithCallback(
718 self.modificationCallback,
720 _("A configuration file (%s) was modified since Installation.\nDo you want to keep your version?") % (param)
722 elif event == IpkgComponent.EVENT_ERROR:
724 elif event == IpkgComponent.EVENT_DONE:
726 self.updating = False
727 self.ipkg.startCmd(IpkgComponent.CMD_UPGRADE, args = {'test_only': False})
728 elif self.error == 0:
729 self.slider.setValue(4)
731 self.activityTimer.stop()
732 self.activityslider.setValue(0)
734 self.package.setText("")
735 self.status.setText(_("Done - Installed or upgraded %d packages") % self.packages)
737 self.activityTimer.stop()
738 self.activityslider.setValue(0)
739 error = _("your dreambox might be unusable now. Please consult the manual for further assistance before rebooting your dreambox.")
740 if self.packages == 0:
741 error = _("No packages were upgraded yet. So you can check your network and try again.")
743 error = _("Your dreambox isn't connected to the internet properly. Please check it and try again.")
744 self.status.setText(_("Error") + " - " + error)
745 #print event, "-", param
748 def modificationCallback(self, res):
749 self.ipkg.write(res and "N" or "Y")
752 if not self.ipkg.isRunning():
753 if self.packages != 0 and self.error == 0:
754 self.session.openWithCallback(self.exitAnswer, MessageBox, _("Upgrade finished.") +" "+_("Do you want to reboot your Dreambox?"))
758 def exitAnswer(self, result):
759 if result is not None and result:
765 class IpkgInstaller(Screen):
767 <screen position="100,100" size="550,400" title="..." >
768 <widget name="red" halign="center" valign="center" position="0,0" size="140,60" backgroundColor="red" font="Regular;21" />
769 <widget name="green" halign="center" valign="center" position="140,0" text="Install selected" size="140,60" backgroundColor="green" font="Regular;21" />
770 <widget name="yellow" halign="center" valign="center" position="280,0" size="140,60" backgroundColor="yellow" font="Regular;21" />
771 <widget name="blue" halign="center" valign="center" position="420,0" size="140,60" backgroundColor="blue" font="Regular;21" />
772 <widget name="list" position="0,60" size="550,360" />
776 def __init__(self, session, list):
777 self.skin = IpkgInstaller.skin
778 Screen.__init__(self, session)
780 self.list = SelectionList()
781 self["list"] = self.list
782 for listindex in range(len(list)):
783 self.list.addSelection(list[listindex], list[listindex], listindex, True)
785 self["red"] = Label()
786 self["green"] = Label()
787 self["yellow"] = Label()
788 self["blue"] = Label()
790 self["actions"] = ActionMap(["OkCancelActions", "ColorActions"],
792 "ok": self.list.toggleSelection,
793 "cancel": self.close,
794 "green": self.install
798 list = self.list.getSelectionsList()
801 cmdList.append((IpkgComponent.CMD_INSTALL, { "package": item[1] }))
802 self.session.open(Ipkg, cmdList = cmdList)
804 def filescan_open(list, session, **kwargs):
805 filelist = [x.path for x in list]
806 session.open(IpkgInstaller, filelist) # list
808 def filescan(**kwargs):
809 from Components.Scanner import Scanner, ScanPath
811 Scanner(mimetypes = ["application/x-debian-package"],
814 ScanPath(path = "ipk", with_subdirs = True),
815 ScanPath(path = "", with_subdirs = False),
818 description = _("Install software updates..."),
819 openfnc = filescan_open, )
821 def UpgradeMain(session, **kwargs):
822 session.open(UpdatePluginMenu)
824 def startSetup(menuid):
825 if menuid != "setup":
827 return [(_("Software manager") + "...", UpgradeMain, "software_manager", 50)]
829 def Plugins(path, **kwargs):
833 PluginDescriptor(name=_("Software manager"), description=_("Manage your receiver's software"), where = PluginDescriptor.WHERE_MENU, fnc=startSetup),
834 PluginDescriptor(name=_("Ipkg"), where = PluginDescriptor.WHERE_FILESCAN, fnc = filescan)
836 if config.usage.setup_level.index >= 2: # expert+
837 list.append(PluginDescriptor(name=_("Software manager"), description=_("Manage your receiver's software"), where = PluginDescriptor.WHERE_EXTENSIONSMENU, fnc=UpgradeMain))