Merge branch 'master' of git://git.opendreambox.org/git/acidburn/enigma2-master
authorFelix Domke <tmbinc@elitedvb.net>
Fri, 13 Feb 2009 14:11:21 +0000 (15:11 +0100)
committerFelix Domke <tmbinc@elitedvb.net>
Fri, 13 Feb 2009 14:11:21 +0000 (15:11 +0100)
49 files changed:
configure.ac [changed mode: 0644->0755]
data/imagewizard.xml [deleted file]
data/skin_default.xml
lib/python/Components/FileList.py [changed mode: 0644->0755]
lib/python/Components/Harddisk.py [changed mode: 0644->0755]
lib/python/Components/Ipkg.py [changed mode: 0644->0755]
lib/python/Plugins/Extensions/IpkgInstaller/.cvsignore [deleted file]
lib/python/Plugins/Extensions/IpkgInstaller/Makefile.am [deleted file]
lib/python/Plugins/Extensions/IpkgInstaller/__init__.py [deleted file]
lib/python/Plugins/Extensions/IpkgInstaller/plugin.py [deleted file]
lib/python/Plugins/Extensions/Makefile.am [changed mode: 0644->0755]
lib/python/Plugins/Extensions/MediaScanner/plugin.py [changed mode: 0644->0755]
lib/python/Plugins/SystemPlugins/ConfigurationBackup/.cvsignore [deleted file]
lib/python/Plugins/SystemPlugins/ConfigurationBackup/LICENSE [deleted file]
lib/python/Plugins/SystemPlugins/ConfigurationBackup/Makefile.am [deleted file]
lib/python/Plugins/SystemPlugins/ConfigurationBackup/__init__.py [deleted file]
lib/python/Plugins/SystemPlugins/ConfigurationBackup/backup.png [deleted file]
lib/python/Plugins/SystemPlugins/ConfigurationBackup/blue.png [deleted file]
lib/python/Plugins/SystemPlugins/ConfigurationBackup/green.png [deleted file]
lib/python/Plugins/SystemPlugins/ConfigurationBackup/plugin.py [deleted file]
lib/python/Plugins/SystemPlugins/ConfigurationBackup/red.png [deleted file]
lib/python/Plugins/SystemPlugins/ConfigurationBackup/yellow.png [deleted file]
lib/python/Plugins/SystemPlugins/Makefile.am [changed mode: 0644->0755]
lib/python/Plugins/SystemPlugins/SoftwareManager/.cvsignore [new file with mode: 0644]
lib/python/Plugins/SystemPlugins/SoftwareManager/BackupRestore.py [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/SoftwareManager/ImageWizard.py [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/SoftwareManager/LICENSE [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/SoftwareManager/Makefile.am [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/SoftwareManager/__init__.py [new file with mode: 0644]
lib/python/Plugins/SystemPlugins/SoftwareManager/blue.png [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/SoftwareManager/green.png [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/SoftwareManager/imagewizard.xml [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/SoftwareManager/installable.png [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/SoftwareManager/installed.png [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/SoftwareManager/plugin.py [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/SoftwareManager/red.png [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/SoftwareManager/update.png [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/SoftwareManager/upgradeable.png [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/SoftwareManager/yellow.png [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/SoftwareUpdate/.cvsignore [deleted file]
lib/python/Plugins/SystemPlugins/SoftwareUpdate/Makefile.am [deleted file]
lib/python/Plugins/SystemPlugins/SoftwareUpdate/__init__.py [deleted file]
lib/python/Plugins/SystemPlugins/SoftwareUpdate/plugin.py [deleted file]
lib/python/Plugins/SystemPlugins/SoftwareUpdate/update.png [deleted file]
lib/python/Screens/ImageWizard.py [deleted file]
lib/python/Screens/Ipkg.py [changed mode: 0644->0755]
lib/python/Screens/Makefile.am
mytest.py [changed mode: 0644->0755]
po/Makefile.am [changed mode: 0644->0755]

old mode 100644 (file)
new mode 100755 (executable)
index 719baa1..b94272d
@@ -108,11 +108,10 @@ lib/python/Components/Sources/Makefile
 lib/python/Screens/Makefile
 lib/python/Plugins/Makefile
 lib/python/Plugins/SystemPlugins/Makefile
-lib/python/Plugins/SystemPlugins/SoftwareUpdate/Makefile
+lib/python/Plugins/SystemPlugins/SoftwareManager/Makefile
 lib/python/Plugins/SystemPlugins/FrontprocessorUpgrade/Makefile
 lib/python/Plugins/SystemPlugins/PositionerSetup/Makefile
 lib/python/Plugins/SystemPlugins/Hotplug/Makefile
-lib/python/Plugins/SystemPlugins/ConfigurationBackup/Makefile
 lib/python/Plugins/SystemPlugins/DefaultServicesScanner/Makefile
 lib/python/Plugins/SystemPlugins/NFIFlash/Makefile
 lib/python/Plugins/SystemPlugins/Satfinder/Makefile
@@ -124,7 +123,6 @@ lib/python/Plugins/SystemPlugins/DiseqcTester/Makefile
 lib/python/Plugins/DemoPlugins/Makefile
 lib/python/Plugins/DemoPlugins/TestPlugin/Makefile
 lib/python/Plugins/Extensions/Makefile
-lib/python/Plugins/Extensions/IpkgInstaller/Makefile
 lib/python/Plugins/Extensions/TuxboxPlugins/Makefile
 lib/python/Plugins/Extensions/FileManager/Makefile
 lib/python/Plugins/Extensions/CutListEditor/Makefile
diff --git a/data/imagewizard.xml b/data/imagewizard.xml
deleted file mode 100644 (file)
index 8c40e3f..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-<wizard>
-               <step id="restorequestion">
-                       <condition>
-from Screens.ImageWizard import checkConfigBackup
-self.backuppath = checkConfigBackup()
-self.condition = (self.backuppath is not None)
-                       </condition>
-                       <text value="Do you want to restore your settings?" />
-                       <list>
-                               <listentry caption="Yes, restore the settings now" step="restore" />
-                               <listentry caption="No, just start my dreambox" step="end" />
-                       </list>
-               </step>
-
-               <step id="welcome">
-                       <text value="Welcome to the Image upgrade wizard. The wizard will assist you in upgrading the firmware of your Dreambox by providing a backup facility for your current settings and a short explanation of how to upgrade your firmware." />
-                       <list>
-                               <listentry caption="OK, guide me through the upgrade process" step="backupquestion" />
-                               <listentry caption="Exit the wizard" step="end" />
-                       </list>
-               </step>
-
-               <step id="backupquestion">
-                       <text value="The wizard can backup your current settings. Do you want to do a backup now?" />
-                       <list>
-                               <listentry caption="Yes, backup my settings!" step="backupwhere" />
-                               <listentry caption="No backup needed" step="upgrade" />
-                       </list>
-               </step>
-
-               <step id="backupwhere">
-                       <text value="Where do you want to backup your settings?" />
-                       <list>
-                               <listentry caption="Harddisk" step="hdd" />
-                               <listentry caption="Compact flash card" step="cf" />
-                               <listentry caption="USB" step="usb" />
-                               <listentry caption="Somewhere else" step="file" />
-                       </list>
-               </step>
-
-               <step id="hdd" nextstep="backup">
-                       <condition>
-from Components.Harddisk import harddiskmanager
-self.condition = harddiskmanager.HDDCount() > 0
-                       </condition>
-                       <text value="You have chosen to backup to your harddisk. Please press OK to start the backup now." />
-                       <code pos="after">
-self.backuppath = '/media/hdd/'
-                       </code>
-               </step>
-
-               <step id="hddfailed" nextstep="backupwhere">
-                       <condition>
-from Components.Harddisk import harddiskmanager
-self.condition = harddiskmanager.HDDCount() == 0
-                       </condition>
-                       <text value="You do not seem to have a harddisk in your Dreambox. So backing up to a harddisk is not an option for you." />
-               </step>
-               
-               <step id="cf" nextstep="backup">
-                       <text value="You have chosen to backup to a compact flash card. The card must be in the slot. We do not verify if it is really used at the moment. So better backup to the harddisk!\nPlease press OK to start the backup now." />
-                       <code pos="after">
-self.backuppath = '/media/cf/'
-                       </code>
-               </step>
-
-               <step id="usb" nextstep="backup">
-                       <text value="You have chosen to backup to an usb drive. Better backup to the harddisk!\nPlease press OK to start the backup now." />
-                       <code pos="after">
-self.backuppath = '/media/usb/'
-                       </code>
-               </step>
-
-               <step id="file" nextstep="backupwhere">
-                       <text value="This is unsupported at the moment." />
-               </step>
-
-               <step id="backup" nextstep="backupresult">
-                       <code>
-from Screens.ImageWizard import doBackup
-doBackup(self.backuppath)
-                       </code>
-                       <text value="Backup is done. Please press OK to see the result." />
-               </step>
-               
-               <step id="backupresult" nextstep="upgrade">
-                       <condition>
-from Screens.ImageWizard import checkConfigBackup
-self.backuppath = checkConfigBackup()
-self.condition = (self.backuppath is not None)
-                       </condition>
-                       <text value="Your backup succeeded. We will now continue to explain the further upgrade process." />
-               </step>
-
-               <step id="backupresultfailed" nextstep="backupwhere">
-                       <condition>
-from Screens.ImageWizard import checkConfigBackup
-self.backuppath = checkConfigBackup()
-self.condition = (self.backuppath is None)
-                       </condition>
-                       <text value="The backup failed. Please choose a different backup location." />
-               </step>
-               
-               <step id="restore" nextstep="activate">
-                       <code>
-from Screens.ImageWizard import doRestore
-doRestore(self.backuppath)
-                       </code>
-                       <text value="Restoring the settings is done. Please press OK to activate the restored settings now." />
-               </step>
-               
-               <step id="activate" nextstep="activate">
-                       <code>
-import os
-from Screens.ImageWizard import backupfile
-print 'mv ' + self.backuppath + backupfile + ' ' + self.backuppath + backupfile + '.old'
-os.system('mv ' + self.backuppath + backupfile + ' ' + self.backuppath + backupfile + '.old')
-os.system('killall -9 enigma2') # ugly... no better solution atm
-                       </code>
-               </step>
-               
-               <step id="upgrade">
-                       <text value="You need a PC connected to your dreambox. If you need further instructions, please visit the website http://www.dm7025.de.\nYour dreambox will now be halted. After you have performed the update instructions from the website, your new firmware will ask you to restore your settings." />
-                       <list>
-                               <listentry caption="Yes, perform a shutdown now." step="shutdown" />
-                               <listentry caption="No, do nothing." step="end" />
-                       </list>
-               </step>
-
-               <step id="shutdown" nextstep="shutdown">
-                       <code>
-from enigma import quitMainloop
-quitMainloop(1)
-                       </code>
-                       <text value="Your dreambox is shutting down. Please stand by..." />
-               </step>
-               
-               <step id="end">
-                       <text value="The wizard is finished now." />
-               </step>
-</wizard>
index d60933e..f99e1a7 100755 (executable)
@@ -368,12 +368,6 @@ self.instance.move(ePoint((720-wsizex)/2, (576-wsizey)/(count &gt; 7 and 2 or 3)
                <widget name="arrowup2" pixmap="skin_default/arrowup.png" position="-100,-100" zPosition="11" size="37,70" alphatest="on" />
                <widget name="long_key" position="320,520" size="350,50" font="Regular;25" halign="right" foregroundColor="yellow" />
        </screen>
-       <!-- Image Wizard -->
-       <screen name="ImageWizard" position="0,0" size="720,576" title="Welcome..." flags="wfNoBorder">
-               <widget name="text" position="50,100" size="440,250" font="Regular;22" />
-               <widget name="list" position="50,350" zPosition="1" size="440,200" />
-               <widget name="config" position="50,350" zPosition="1" size="440,200" transparent="1" scrollbarMode="showOnDemand" />
-       </screen>
        <!-- Inputbox -->
        <screen name="InputBox" position="80,250" size="550,90" title="Input">
                <widget name="text" position="10,20" size="550,25" font="Regular;23" />
old mode 100644 (file)
new mode 100755 (executable)
index 84abf32..f969709
@@ -248,3 +248,189 @@ class FileList(MenuList):
                self.refreshMountpoints()
                if self.current_directory is None:
                        self.refresh()
+
+
+def MultiFileSelectEntryComponent(name, absolute = None, isDir = False, selected = False):
+       res = [ (absolute, isDir, selected, name) ]
+       res.append((eListboxPythonMultiContent.TYPE_TEXT, 55, 1, 470, 20, 0, RT_HALIGN_LEFT, name))
+       if isDir:
+               png = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "extensions/directory.png"))
+       else:
+               extension = name.split('.')
+               extension = extension[-1].lower()
+               if EXTENSIONS.has_key(extension):
+                       png = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "extensions/" + EXTENSIONS[extension] + ".png"))
+               else:
+                       png = None
+       if png is not None:
+               res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, 30, 2, 20, 20, png))
+
+       if not name.startswith('<'):
+               if selected is False:
+                       icon = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/icons/lock_off.png"))
+                       res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, 2, 0, 25, 25, icon))
+               else:
+                       icon = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/icons/lock_on.png"))
+                       res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, 2, 0, 25, 25, icon))
+       
+       return res
+
+
+class MultiFileSelectList(FileList):
+       def __init__(self, preselectedFiles, directory, showMountpoints = False, matchingPattern = None, showDirectories = True, showFiles = True,  useServiceRef = False, inhibitDirs = False, inhibitMounts = False, isTop = False, enableWrapAround = False, additionalExtensions = None):
+               self.selectedFiles = preselectedFiles
+               if self.selectedFiles is None:
+                       self.selectedFiles = []
+               FileList.__init__(self, directory, showMountpoints = showMountpoints, matchingPattern = matchingPattern, showDirectories = showDirectories, showFiles = showFiles,  useServiceRef = useServiceRef, inhibitDirs = inhibitDirs, inhibitMounts = inhibitMounts, isTop = isTop, enableWrapAround = enableWrapAround, additionalExtensions = additionalExtensions)
+               self.changeDir(directory)                       
+               self.l.setItemHeight(25)
+               self.l.setFont(0, gFont("Regular", 20))
+               self.onSelectionChanged = [ ]
+
+       def selectionChanged(self):
+               for f in self.onSelectionChanged:
+                       f()
+
+       def changeSelectionState(self):
+               idx = self.l.getCurrentSelectionIndex()
+               count = 0
+               newList = []
+               for x in self.list:
+                       if idx == count:
+                               if x[0][3].startswith('<'):
+                                       newList.append(x)
+                               else:
+                                       if x[0][1] is True:
+                                               realPathname = x[0][0]
+                                       else:
+                                               realPathname = self.current_directory + x[0][0]
+                                       if x[0][2] == True:
+                                               SelectState = False
+                                               for entry in self.selectedFiles:
+                                                       if entry == realPathname:
+                                                               self.selectedFiles.remove(entry)
+       
+                                       else:
+                                               SelectState = True
+                                               alreadyinList = False   
+                                               for entry in self.selectedFiles:
+                                                       if entry == realPathname:
+                                                               alreadyinList = True
+                                               if not alreadyinList:
+                                                       self.selectedFiles.append(realPathname)
+                                       newList.append(MultiFileSelectEntryComponent(name = x[0][3], absolute = x[0][0], isDir = x[0][1], selected = SelectState ))
+                       else:
+                               newList.append(x)
+                       
+                       count += 1
+               
+               self.list = newList
+               self.l.setList(self.list)
+       
+       def getSelectedList(self):
+               return self.selectedFiles
+
+       def changeDir(self, directory, select = None):
+               self.list = []
+
+               # if we are just entering from the list of mount points:
+               if self.current_directory is None:
+                       if directory and self.showMountpoints:
+                               self.current_mountpoint = self.getMountpointLink(directory)
+                       else:
+                               self.current_mountpoint = None
+               self.current_directory = directory
+               directories = []
+               files = []
+
+               if directory is None and self.showMountpoints: # present available mountpoints
+                       for p in harddiskmanager.getMountedPartitions():
+                               path = os_path.join(p.mountpoint, "")
+                               if path not in self.inhibitMounts and not self.inParentDirs(path, self.inhibitDirs):
+                                       self.list.append(MultiFileSelectEntryComponent(name = p.description, absolute = path, isDir = True))
+                       files = [ ]
+                       directories = [ ]
+               elif directory is None:
+                       files = [ ]
+                       directories = [ ]
+               elif self.useServiceRef:
+                       root = eServiceReference("2:0:1:0:0:0:0:0:0:0:" + directory)
+                       if self.additional_extensions:
+                               root.setName(self.additional_extensions)
+                       serviceHandler = eServiceCenter.getInstance()
+                       list = serviceHandler.list(root)
+
+                       while 1:
+                               s = list.getNext()
+                               if not s.valid():
+                                       del list
+                                       break
+                               if s.flags & s.mustDescent:
+                                       directories.append(s.getPath())
+                               else:
+                                       files.append(s)
+                       directories.sort()
+                       files.sort()
+               else:
+                       if os_path.exists(directory):
+                               files = listdir(directory)
+                               files.sort()
+                               tmpfiles = files[:]
+                               for x in tmpfiles:
+                                       if os_path.isdir(directory + x):
+                                               directories.append(directory + x + "/")
+                                               files.remove(x)
+
+               if directory is not None and self.showDirectories and not self.isTop:
+                       if directory == self.current_mountpoint and self.showMountpoints:
+                               self.list.append(MultiFileSelectEntryComponent(name = "<" +_("List of Storage Devices") + ">", absolute = None, isDir = True))
+                       elif (directory != "/") and not (self.inhibitMounts and self.getMountpoint(directory) in self.inhibitMounts):
+                               self.list.append(MultiFileSelectEntryComponent(name = "<" +_("Parent Directory") + ">", absolute = '/'.join(directory.split('/')[:-2]) + '/', isDir = True))
+
+               if self.showDirectories:
+                       for x in directories:
+                               if not (self.inhibitMounts and self.getMountpoint(x) in self.inhibitMounts) and not self.inParentDirs(x, self.inhibitDirs):
+                                       name = x.split('/')[-2]
+                                       alreadySelected = False
+                                       for entry in self.selectedFiles:
+                                               if entry  == x:
+                                                       alreadySelected = True                                  
+                                       if alreadySelected:             
+                                               self.list.append(MultiFileSelectEntryComponent(name = name, absolute = x, isDir = True, selected = True))
+                                       else:
+                                               self.list.append(MultiFileSelectEntryComponent(name = name, absolute = x, isDir = True, selected = False))
+                                               
+               if self.showFiles:
+                       for x in files:
+                               if self.useServiceRef:
+                                       path = x.getPath()
+                                       name = path.split('/')[-1]
+                               else:
+                                       path = directory + x
+                                       name = x
+
+                               if (self.matchingPattern is None) or re_compile(self.matchingPattern).search(path):
+                                       alreadySelected = False
+                                       for entry in self.selectedFiles:
+                                               if os_path.basename(entry)  == x:
+                                                       alreadySelected = True  
+                                       if alreadySelected:
+                                               self.list.append(MultiFileSelectEntryComponent(name = name, absolute = x , isDir = False, selected = True))
+                                       else:
+                                               self.list.append(MultiFileSelectEntryComponent(name = name, absolute = x , isDir = False, selected = False))
+
+               self.l.setList(self.list)
+
+               if select is not None:
+                       i = 0
+                       self.moveToIndex(0)
+                       for x in self.list:
+                               p = x[0][0]
+                               
+                               if isinstance(p, eServiceReference):
+                                       p = p.getPath()
+                               
+                               if p == select:
+                                       self.moveToIndex(i)
+                               i += 1
+
old mode 100644 (file)
new mode 100755 (executable)
index d165e26..75d68fa
@@ -519,4 +519,18 @@ class HarddiskManager:
                        description += " (Partition %d)" % part
                return description
 
+       def addMountedPartition(self, device, desc):
+               already_mounted = False
+               for x in self.partitions[:]:
+                       if x.mountpoint == device:
+                               already_mounted = True
+               if not already_mounted:
+                       self.partitions.append(Partition(mountpoint = device, description = desc))
+               
+       def removeMountedPartition(self, mountpoint):
+               for x in self.partitions[:]:
+                       if x.mountpoint == mountpoint:
+                               self.partitions.remove(x)
+                               self.on_partition_list_change("remove", x)
+
 harddiskmanager = HarddiskManager()
old mode 100644 (file)
new mode 100755 (executable)
index 31889bc..0ba1165
@@ -52,6 +52,8 @@ class IpkgComponent:
                                self.runCmd("list")
                elif cmd == self.CMD_INSTALL:
                        self.runCmd("install " + args['package'])
+               elif cmd == self.CMD_REMOVE:
+                       self.runCmd("remove " + args['package'])
                self.setCurrentCommand(cmd)
        
        def cmdFinished(self, retval):
@@ -90,6 +92,8 @@ class IpkgComponent:
                                self.callCallbacks(self.EVENT_UPGRADE, data.split('    ', 1)[1].split(' ')[0])
                        elif data.find('Installing') == 0:
                                self.callCallbacks(self.EVENT_INSTALL, data.split(' ', 1)[1].split(' ')[0])
+                       elif data.find('Removing') == 0:
+                               self.callCallbacks(self.EVENT_REMOVE, data.split(' ', 1)[1].split(' ')[1])
                        elif data.find('Configuring') == 0:
                                self.callCallbacks(self.EVENT_CONFIGURING, data.split(' ', 1)[1].split(' ')[0])
                        elif data.find('An error occurred') == 0:
diff --git a/lib/python/Plugins/Extensions/IpkgInstaller/.cvsignore b/lib/python/Plugins/Extensions/IpkgInstaller/.cvsignore
deleted file mode 100644 (file)
index 138b9cc..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-*.pyc
-*.pyo
-Makefile
-Makefile.in
diff --git a/lib/python/Plugins/Extensions/IpkgInstaller/Makefile.am b/lib/python/Plugins/Extensions/IpkgInstaller/Makefile.am
deleted file mode 100644 (file)
index ece0698..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-installdir = $(LIBDIR)/enigma2/python/Plugins/Extensions/IpkgInstaller
-
-install_PYTHON =       \
-       __init__.py \
-       plugin.py 
diff --git a/lib/python/Plugins/Extensions/IpkgInstaller/__init__.py b/lib/python/Plugins/Extensions/IpkgInstaller/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/lib/python/Plugins/Extensions/IpkgInstaller/plugin.py b/lib/python/Plugins/Extensions/IpkgInstaller/plugin.py
deleted file mode 100644 (file)
index 4893dc4..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-from Components.ActionMap import ActionMap
-from Components.Ipkg import IpkgComponent
-from Components.Label import Label
-from Components.SelectionList import SelectionList
-from Plugins.Plugin import PluginDescriptor
-from Screens.Ipkg import Ipkg
-from Screens.Screen import Screen
-
-class IpkgInstaller(Screen):
-       skin = """
-               <screen position="100,100" size="550,400" title="..." >
-                       <widget name="red" halign="center" valign="center" position="0,0" size="140,60" backgroundColor="red" font="Regular;21" />
-                       <widget name="green" halign="center" valign="center" position="140,0" text="Install selected" size="140,60" backgroundColor="green" font="Regular;21" />
-                       <widget name="yellow" halign="center" valign="center" position="280,0" size="140,60" backgroundColor="yellow" font="Regular;21" />
-                       <widget name="blue" halign="center" valign="center" position="420,0" size="140,60" backgroundColor="blue" font="Regular;21" />
-                       <widget name="list" position="0,60" size="550,360" />
-               </screen>
-               """
-       
-       def __init__(self, session, list):
-               self.skin = IpkgInstaller.skin
-               Screen.__init__(self, session)
-
-               self.list = SelectionList()
-               self["list"] = self.list
-               for listindex in range(len(list)):
-                       self.list.addSelection(list[listindex], list[listindex], listindex, True)
-
-               self["red"] = Label()
-               self["green"] = Label()
-               self["yellow"] = Label()
-               self["blue"] = Label()
-               
-               self["actions"] = ActionMap(["OkCancelActions", "ColorActions"], 
-               {
-                       "ok": self.list.toggleSelection, 
-                       "cancel": self.close, 
-                       "green": self.install
-               }, -1)
-               
-       def install(self):
-               list = self.list.getSelectionsList()
-               cmdList = []
-               for item in list:
-                       cmdList.append((IpkgComponent.CMD_INSTALL, { "package": item[1] }))
-               print cmdList
-               self.session.open(Ipkg, cmdList = cmdList)
-
-def filescan_open(list, session, **kwargs):
-       filelist = [x.path for x in list]
-       session.open(IpkgInstaller, filelist) # list
-
-def filescan(**kwargs):
-       from Components.Scanner import Scanner, ScanPath
-       return \
-               Scanner(mimetypes = ["application/x-debian-package"], 
-                       paths_to_scan = 
-                               [
-                                       ScanPath(path = "ipk", with_subdirs = True), 
-                                       ScanPath(path = "", with_subdirs = False), 
-                               ], 
-                       name = "Ipkg", 
-                       description = "Install software updates...", 
-                       openfnc = filescan_open, )
-
-def Plugins(**kwargs):
-       return [ PluginDescriptor(name="Ipkg", where = PluginDescriptor.WHERE_FILESCAN, fnc = filescan) ]
old mode 100644 (file)
new mode 100755 (executable)
index 9f3737a..edbd208
@@ -1 +1 @@
-SUBDIRS = TuxboxPlugins FileManager CutListEditor PicturePlayer MediaScanner MediaPlayer IpkgInstaller GraphMultiEPG SocketMMI DVDPlayer DVDBurn
+SUBDIRS = TuxboxPlugins FileManager CutListEditor PicturePlayer MediaScanner MediaPlayer GraphMultiEPG SocketMMI DVDPlayer DVDBurn
old mode 100644 (file)
new mode 100755 (executable)
index 88b917e..2c31197
@@ -42,6 +42,9 @@ def scan(session):
 
        parts = [ (r.description, r.mountpoint, session) for r in harddiskmanager.getMountedPartitions(onlyhotplug = False)]
        if len(parts):
+               for x in parts:
+                       if not access(x[1], F_OK|R_OK):
+                               parts.remove(x) 
                session.openWithCallback(mountpoint_choosen, ChoiceBox, title = _("Please Select Medium to be Scanned"), list = parts)
 
 def main(session, **kwargs):
diff --git a/lib/python/Plugins/SystemPlugins/ConfigurationBackup/.cvsignore b/lib/python/Plugins/SystemPlugins/ConfigurationBackup/.cvsignore
deleted file mode 100644 (file)
index 138b9cc..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-*.pyc
-*.pyo
-Makefile
-Makefile.in
diff --git a/lib/python/Plugins/SystemPlugins/ConfigurationBackup/LICENSE b/lib/python/Plugins/SystemPlugins/ConfigurationBackup/LICENSE
deleted file mode 100644 (file)
index 9970059..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-This plugin is licensed under the Creative Commons 
-Attribution-NonCommercial-ShareAlike 3.0 Unported 
-License. To view a copy of this license, visit
-http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter to Creative
-Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
-
-Alternatively, this plugin may be distributed and executed on hardware which
-is licensed by Dream Multimedia GmbH.
-
-This plugin is NOT free software. It is open source, you are allowed to
-modify it (if you keep the license), but it may not be commercially 
-distributed other than under the conditions noted above.
diff --git a/lib/python/Plugins/SystemPlugins/ConfigurationBackup/Makefile.am b/lib/python/Plugins/SystemPlugins/ConfigurationBackup/Makefile.am
deleted file mode 100644 (file)
index d50236d..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-installdir = $(LIBDIR)/enigma2/python/Plugins/SystemPlugins/ConfigurationBackup
-
-install_PYTHON =       \
-       __init__.py \
-       plugin.py       red.png yellow.png green.png blue.png backup.png
-
-install_DATA = LICENSE
-
diff --git a/lib/python/Plugins/SystemPlugins/ConfigurationBackup/__init__.py b/lib/python/Plugins/SystemPlugins/ConfigurationBackup/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/lib/python/Plugins/SystemPlugins/ConfigurationBackup/backup.png b/lib/python/Plugins/SystemPlugins/ConfigurationBackup/backup.png
deleted file mode 100644 (file)
index 4962a05..0000000
Binary files a/lib/python/Plugins/SystemPlugins/ConfigurationBackup/backup.png and /dev/null differ
diff --git a/lib/python/Plugins/SystemPlugins/ConfigurationBackup/blue.png b/lib/python/Plugins/SystemPlugins/ConfigurationBackup/blue.png
deleted file mode 100644 (file)
index a392bbe..0000000
Binary files a/lib/python/Plugins/SystemPlugins/ConfigurationBackup/blue.png and /dev/null differ
diff --git a/lib/python/Plugins/SystemPlugins/ConfigurationBackup/green.png b/lib/python/Plugins/SystemPlugins/ConfigurationBackup/green.png
deleted file mode 100644 (file)
index f168e4d..0000000
Binary files a/lib/python/Plugins/SystemPlugins/ConfigurationBackup/green.png and /dev/null differ
diff --git a/lib/python/Plugins/SystemPlugins/ConfigurationBackup/plugin.py b/lib/python/Plugins/SystemPlugins/ConfigurationBackup/plugin.py
deleted file mode 100644 (file)
index 7a918da..0000000
+++ /dev/null
@@ -1,221 +0,0 @@
-from Screens.Screen import Screen
-from Screens.MessageBox import MessageBox
-from Screens.Console import Console
-from Components.ActionMap import ActionMap, NumberActionMap
-from Components.Pixmap import Pixmap
-from Components.Label import Label
-from Components.MenuList import MenuList
-from Components.config import ConfigSelection, ConfigSubsection, KEY_LEFT, KEY_RIGHT, KEY_0, getConfigListEntry
-from Components.ConfigList import ConfigList
-from Plugins.Plugin import PluginDescriptor
-
-from Tools.Directories import *
-from os import path, makedirs, listdir
-from time import localtime
-from datetime import date
-
-plugin_path = ""
-
-# FIXME: harddiskmanager has a better overview about available mointpoints!
-BackupPath = {
-               "hdd" : "/media/hdd/backup",
-               "usb" : "/media/usb/backup",
-               "cf" : "/media/cf/backup"
-       }
-
-MountPoints = {
-               "hdd" : "/media/hdd",
-               "usb" : "/media/usb",
-               "cf" : "/media/cf"
-       }
-
-class BackupSetup(Screen):
-       skin = """
-               <screen position="135,144" size="450,300" title="Backup and Restore" >
-                       <widget name="config" position="10,10" size="430,240" />
-                       <widget name="cancel" position="10,255" size="100,40" pixmap="~/red.png" transparent="1" alphatest="on" />
-                       <widget name="canceltext" position="0,0" size="0,0" valign="center" halign="center" zPosition="2" font="Regular;20" transparent="1" foregroundColor="black" />
-                       <widget name="ok" position="120,255" size="100,40" pixmap="~/green.png" transparent="1" alphatest="on" />
-                       <widget name="oktext" position="0,0" size="0,0" valign="center" halign="center" zPosition="2" font="Regular;20" transparent="1"  foregroundColor="black" />
-                       <widget name="restore" position="230,255" size="100,40" pixmap="~/yellow.png" transparent="1" alphatest="on" />
-                       <widget name="restoretext" position="0,0" size="0,0" valign="center" halign="center" zPosition="2" font="Regular;20" transparent="1"  foregroundColor="black" />
-                       <widget name="backup" position="340,255" size="100,40" pixmap="~/blue.png" transparent="1" alphatest="on" />
-                       <widget name="backuptext" position="0,0" size="0,0" valign="center" halign="center" zPosition="2" font="Regular;20" transparent="1"  foregroundColor="black" />
-               </screen>"""
-               
-       def keyLeft(self):
-               self["config"].handleKey(KEY_LEFT)
-
-       def keyRight(self):
-               self["config"].handleKey(KEY_RIGHT)
-
-       def keyNumberGlobal(self, number):
-               print "You pressed number", number
-               if (self["config"].getCurrent()[1].parent.enabled == True):
-                       self["config"].handleKey(KEY_0+number)
-
-       def keyCancel(self):
-               for x in self["config"].list:
-                       x[1].cancel()
-               self.close()
-
-       def keySave(self):
-               for x in self["config"].list:
-                       x[1].save()
-               self.close()
-
-       def __init__(self, session, args = None):
-               Screen.__init__(self, session)
-               self.skin_path = plugin_path
-               
-               self["oktext"] = Label(_("OK"))
-               self["canceltext"] = Label(_("Cancel"))
-               self["backuptext"] = Label(_("Backup"))
-               self["restoretext"] = Label(_("Restore"))
-               self["restore"] = Pixmap()
-               self["backup"] = Pixmap()
-               self["ok"] = Pixmap()
-               self["cancel"] = Pixmap()
-               
-               self.path = ""
-               self.list = []
-               self["config"] = ConfigList(self.list)
-               self.createSetup()
-               
-               self["actions"] = NumberActionMap(["SetupActions"],
-               {
-                       "ok": self.keySave,
-                       "cancel": self.keyCancel,
-                       "left": self.keyLeft,
-                       "right": self.keyRight
-               }, -1)
-               
-               self["shortcuts"] = ActionMap(["ShortcutActions"],
-               {
-                       "red": self.keyCancel,
-                       "green": self.keySave,
-                       "blue": self.Backup,
-                       "yellow": self.Restore,
-               })
-               
-
-       def createSetup(self):
-               print "Creating BackupSetup"
-               self.list = [ ]
-               self["config"] = ConfigList(self.list)
-               self.backup = ConfigSubsection()
-               self.backup.type = ConfigSelection(choices = [("settings", _("enigma2 and network")), ("var", _("/var directory")), ("skin", _("/usr/share/enigma2 directory"))], default="settings")
-               self.backup.location = ConfigSelection(choices = [("hdd", _("Harddisk")), ("usb", _("USB Stick")), ("cf", _("CF Drive"))])
-               self.list.append(getConfigListEntry(_("Backup Mode"), self.backup.type))
-               self.list.append(getConfigListEntry(_("Backup Location"), self.backup.location))
-
-       def createBackupfolders(self):
-               self.path = BackupPath[self.backup.location.value]
-               print "Creating Backup Folder if not already there..."
-               if (path.exists(self.path) == False):
-                       makedirs(self.path)
-
-       def Backup(self):
-               print "this will start the backup now!"
-               self.session.openWithCallback(self.runBackup, MessageBox, _("Do you want to backup now?\nAfter pressing OK, please wait!"))     
-
-       def Restore(self):
-               print "this will start the restore now!"
-               self.session.open(RestoreMenu, self.backup)
-
-       def runBackup(self, result):
-               if result:
-                       if path.ismount(MountPoints[self.backup.location.value]):
-                               self.createBackupfolders()
-                               d = localtime()
-                               dt = date(d.tm_year, d.tm_mon, d.tm_mday)
-                               self.path = BackupPath[self.backup.location.value]
-                               if self.backup.type.value == "settings":
-                                       print "Backup Mode: Settings"
-                                       self.session.open(Console, title = "Backup running", cmdlist = ["tar -czvf " + self.path + "/" + str(dt) + "_settings_backup.tar.gz /etc/enigma2/ /etc/network/interfaces /etc/wpa_supplicant.conf"])
-                               elif self.backup.type.value == "var":
-                                       print "Backup Mode: var"
-                                       self.session.open(Console, title = "Backup running", cmdlist = [ "tar -czvf " + self.path + "/" + str(dt) + "_var_backup.tar.gz /var/"])
-                               elif self.backup.type.value == "skin":
-                                       print "Backup Mode: skin"
-                                       self.session.open(Console, title ="Backup running", cmdlist = [ "tar -czvf " + self.path + "/" + str(dt) + "_skin_backup.tar.gz /usr/share/enigma2/"])
-                       else:
-                               self.session.open(MessageBox, _("Sorry your Backup destination does not exist\n\nPlease choose an other one."), MessageBox.TYPE_INFO)
-
-class RestoreMenu(Screen):
-       skin = """
-               <screen position="135,144" size="450,300" title="Restore Backups" >
-               <widget name="filelist" position="10,10" size="430,240" scrollbarMode="showOnDemand" />
-               <widget name="cancel" position="120,255" size="100,40" pixmap="~/red.png" transparent="1" alphatest="on" />             
-               <widget name="canceltext" position="0,0" size="0,0" valign="center" halign="center" zPosition="2" font="Regular;20" transparent="1" foregroundColor="black" />
-               <widget name="restore" position="230,255" size="100,40" pixmap="~/yellow.png" transparent="1" alphatest="on" />
-               <widget name="restoretext" position="0,0" size="0,0" valign="center" halign="center" zPosition="2" font="Regular;20" transparent="1"  foregroundColor="black" />
-               </screen>"""
-
-       def __init__(self, session, backup):
-               Screen.__init__(self, session)
-               self.skin_path = plugin_path
-               self.backup = backup
-
-               self["canceltext"] = Label(_("Cancel"))
-               self["restoretext"] = Label(_("Restore"))
-               self["restore"] = Pixmap()
-               self["cancel"] = Pixmap()
-
-               self.sel = []
-               self.val = []
-               self.entry = False
-               self.exe = False
-               
-               self.path = ""
-
-               self["actions"] = NumberActionMap(["SetupActions"],
-               {
-                       "ok": self.KeyOk,
-                       "cancel": self.keyCancel
-               }, -1)
-
-               self["shortcuts"] = ActionMap(["ShortcutActions"],
-               {
-                       "red": self.keyCancel,
-                       "yellow": self.KeyOk,
-               })
-               self.flist = []
-               self["filelist"] = MenuList(self.flist)
-               self.fill_list()
-
-       def fill_list(self):
-               self.flist = []
-               self.path = BackupPath[self.backup.location.value]
-               if (path.exists(self.path) == False):
-                       makedirs(self.path)
-               for file in listdir(self.path):
-                       if (file.endswith(".tar.gz")):
-                               self.flist.append((file))
-                               self.entry = True
-                               self["filelist"].l.setList(self.flist)
-
-       def KeyOk(self):
-               if (self.exe == False) and (self.entry == True):
-                       self.sel = self["filelist"].getCurrent()
-                       self.val = self.path + self.sel
-                       self.session.openWithCallback(self.startRestore, MessageBox, _("are you sure you want to restore\nfollowing backup:\n" + self.sel + "\nEnigma2 will restart after the restore"))
-
-       def keyCancel(self):
-               self.close()
-
-       def startRestore(self, ret = False):
-               if (ret == True):
-                       self.exe = True
-                       self.session.open(Console, title = "Restore running", cmdlist = ["tar -xzvf " + self.path + "/" + self.sel + " -C /", "killall -9 enigma2"])
-
-       def Exit(self):
-               self.close()
-
-def BackupMain(session, **kwargs):
-       session.open(BackupSetup)
-
-def Plugins(path, **kwargs):
-       global plugin_path
-       plugin_path = path
-       return PluginDescriptor(name="Backup/Restore", description="Backup and Restore your Settings", icon="backup.png", where = PluginDescriptor.WHERE_PLUGINMENU, fnc=BackupMain)
diff --git a/lib/python/Plugins/SystemPlugins/ConfigurationBackup/red.png b/lib/python/Plugins/SystemPlugins/ConfigurationBackup/red.png
deleted file mode 100644 (file)
index 8096045..0000000
Binary files a/lib/python/Plugins/SystemPlugins/ConfigurationBackup/red.png and /dev/null differ
diff --git a/lib/python/Plugins/SystemPlugins/ConfigurationBackup/yellow.png b/lib/python/Plugins/SystemPlugins/ConfigurationBackup/yellow.png
deleted file mode 100644 (file)
index dacb80e..0000000
Binary files a/lib/python/Plugins/SystemPlugins/ConfigurationBackup/yellow.png and /dev/null differ
old mode 100644 (file)
new mode 100755 (executable)
index 4491eaf..10151f2
@@ -1 +1 @@
-SUBDIRS = SoftwareUpdate FrontprocessorUpgrade PositionerSetup ConfigurationBackup Satfinder SkinSelector SatelliteEquipmentControl Videomode VideoTune Hotplug DefaultServicesScanner NFIFlash DiseqcTester
+SUBDIRS = SoftwareManager FrontprocessorUpgrade PositionerSetup Satfinder SkinSelector SatelliteEquipmentControl Videomode VideoTune Hotplug DefaultServicesScanner NFIFlash DiseqcTester
diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/.cvsignore b/lib/python/Plugins/SystemPlugins/SoftwareManager/.cvsignore
new file mode 100644 (file)
index 0000000..138b9cc
--- /dev/null
@@ -0,0 +1,4 @@
+*.pyc
+*.pyo
+Makefile
+Makefile.in
diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/BackupRestore.py b/lib/python/Plugins/SystemPlugins/SoftwareManager/BackupRestore.py
new file mode 100755 (executable)
index 0000000..947452e
--- /dev/null
@@ -0,0 +1,312 @@
+from Screens.Screen import Screen
+from Screens.MessageBox import MessageBox
+from Screens.Console import Console
+from Components.ActionMap import ActionMap, NumberActionMap
+from Components.Pixmap import Pixmap
+from Components.Label import Label
+from Components.MenuList import MenuList
+from Components.config import getConfigListEntry, configfile, ConfigSelection, ConfigSubsection, ConfigText, ConfigLocations
+from Components.config import config
+from Components.ConfigList import ConfigList,ConfigListScreen
+from Components.FileList import MultiFileSelectList
+from Plugins.Plugin import PluginDescriptor
+from enigma import eTimer
+from Tools.Directories import *
+from os import popen, path, makedirs, listdir, access, stat, rename, remove, W_OK, R_OK
+from time import gmtime, strftime, localtime
+from datetime import date
+
+
+config.plugins.configurationbackup = ConfigSubsection()
+config.plugins.configurationbackup.backuplocation = ConfigText(default = '/media/hdd/', visible_width = 50, fixed_size = False)
+config.plugins.configurationbackup.backupdirs = ConfigLocations(default=['/etc/enigma2/', '/etc/network/interfaces', '/etc/wpa_supplicant.conf'])
+
+def getBackupPath():
+       backuppath = config.plugins.configurationbackup.backuplocation.value
+       if backuppath.endswith('/'):
+               return backuppath + 'backup'
+       else:
+               return backuppath + '/backup'
+
+def getBackupFilename():
+       return "enigma2settingsbackup.tar.gz"
+               
+
+class BackupScreen(Screen, ConfigListScreen):
+       skin = """
+               <screen position="135,144" size="350,310" title="Backup running..." >
+               <widget name="config" position="10,10" size="330,250" transparent="1" scrollbarMode="showOnDemand" />
+               </screen>"""
+               
+       def __init__(self, session, runBackup = False):
+               Screen.__init__(self, session)
+               self.session = session
+               self.runBackup = runBackup
+               self["actions"] = ActionMap(["WizardActions", "DirectionActions"], 
+               {
+                       "ok": self.close,
+                       "back": self.close,
+                       "cancel": self.close,
+               }, -1)
+               self.finished_cb = None
+               self.backuppath = getBackupPath()
+               self.backupfile = getBackupFilename()
+               self.fullbackupfilename = self.backuppath + "/" + self.backupfile
+               self.list = []
+               ConfigListScreen.__init__(self, self.list)
+               self.onLayoutFinish.append(self.layoutFinished)
+               if self.runBackup:
+                       self.onShown.append(self.doBackup)
+
+       def layoutFinished(self):
+               self.setWindowTitle()
+
+       def setWindowTitle(self):
+               self.setTitle(_("Backup running..."))
+
+       def doBackup(self):
+               try:
+                       if (path.exists(self.backuppath) == False):
+                               makedirs(self.backuppath)
+                       self.backupdirs = ' '.join( config.plugins.configurationbackup.backupdirs.value )
+                       if path.exists(self.fullbackupfilename):
+                               dt = str(date.fromtimestamp(stat(self.fullbackupfilename).st_ctime))
+                               self.newfilename = self.backuppath + "/" + dt + '-' + self.backupfile
+                               if path.exists(self.newfilename):
+                                       remove(self.newfilename)
+                               rename(self.fullbackupfilename,self.newfilename)
+                       if self.finished_cb:
+                               self.session.openWithCallback(self.finished_cb, Console, title = _("Backup running"), cmdlist = ["tar -czvf " + self.fullbackupfilename + " " + self.backupdirs],finishedCallback = self.backupFinishedCB,closeOnSuccess = True)
+                       else:
+                               self.session.open(Console, title = _("Backup running"), cmdlist = ["tar -czvf " + self.fullbackupfilename + " " + self.backupdirs],finishedCallback = self.backupFinishedCB, closeOnSuccess = True)
+               except OSError:
+                       if self.finished_cb:
+                               self.session.openWithCallback(self.finished_cb, MessageBox, _("Sorry your backup destination is not writeable.\nPlease choose an other one."), MessageBox.TYPE_INFO)
+                       else:
+                               self.session.openWithCallback(self.backupErrorCB,MessageBox, _("Sorry your backup destination is not writeable.\nPlease choose an other one."), MessageBox.TYPE_INFO)
+
+       def backupFinishedCB(self,retval = None):
+               self.close(True)
+
+       def backupErrorCB(self,retval = None):
+               self.close(False)
+
+       def runAsync(self, finished_cb):
+               self.finished_cb = finished_cb
+               self.doBackup()
+               
+
+class BackupSelection(Screen):
+       skin = """
+       <screen position="135,125" size="450,310" title="Select files/folders to backup...">
+               <widget name="checkList" position="10,10" size="430,250" transparent="1" scrollbarMode="showOnDemand" />
+               <ePixmap position="0,265" zPosition="1" size="135,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" />
+               <widget name="key_red" position="0,265" zPosition="2" size="135,40" halign="center" valign="center" font="Regular;22" transparent="1" shadowColor="black" shadowOffset="-1,-1" />       
+               <ePixmap position="135,265" zPosition="1" size="135,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" />
+               <widget name="key_green" position="135,265" zPosition="2" size="135,40" halign="center" valign="center" font="Regular;22" transparent="1" shadowColor="black" shadowOffset="-1,-1" />
+               <ePixmap position="270,265" zPosition="1" size="135,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" />
+               <widget name="key_yellow" position="270,265" zPosition="2" size="135,40" halign="center" valign="center" font="Regular;22" transparent="1" shadowColor="black" shadowOffset="-1,-1" />
+       </screen>"""
+
+       def __init__(self, session):
+               Screen.__init__(self, session)
+               self["key_red"] = Label(_("Cancel"))
+               self["key_green"] = Label(_("Save"))
+               self["key_yellow"] = Label()
+               
+               self.selectedFiles = config.plugins.configurationbackup.backupdirs.value
+               defaultDir = '/'
+               inhibitDirs = ["/bin", "/boot", "/dev", "/autofs", "/lib", "/proc", "/sbin", "/sys", "/hdd", "/tmp", "/mnt", "/media"]
+               self.filelist = MultiFileSelectList(self.selectedFiles, defaultDir, inhibitDirs = inhibitDirs )
+               self["checkList"] = self.filelist
+               
+               self["actions"] = ActionMap(["DirectionActions", "OkCancelActions", "ShortcutActions"],
+               {
+                       "cancel": self.exit,
+                       "red": self.exit,
+                       "yellow": self.changeSelectionState,
+                       "green": self.saveSelection,
+                       "ok": self.okClicked,
+                       "left": self.left,
+                       "right": self.right,
+                       "down": self.down,
+                       "up": self.up
+               }, -1)
+               if not self.selectionChanged in self["checkList"].onSelectionChanged:
+                       self["checkList"].onSelectionChanged.append(self.selectionChanged)
+               self.onLayoutFinish.append(self.layoutFinished)
+
+       def layoutFinished(self):
+               idx = 0
+               self["checkList"].moveToIndex(idx)
+               self.setWindowTitle()
+               self.selectionChanged()
+
+       def setWindowTitle(self):
+               self.setTitle(_("Select files/folders to backup..."))
+
+       def selectionChanged(self):
+               current = self["checkList"].getCurrent()[0]
+               if current[2] is True:
+                       self["key_yellow"].setText(_("Deselect"))
+               else:
+                       self["key_yellow"].setText(_("Select"))
+               
+       def up(self):
+               self["checkList"].up()
+
+       def down(self):
+               self["checkList"].down()
+
+       def left(self):
+               self["checkList"].pageUp()
+
+       def right(self):
+               self["checkList"].pageDown()
+
+       def changeSelectionState(self):
+               self["checkList"].changeSelectionState()
+               self.selectedFiles = self["checkList"].getSelectedList()
+
+       def saveSelection(self):
+               self.selectedFiles = self["checkList"].getSelectedList()
+               config.plugins.configurationbackup.backupdirs.value = self.selectedFiles
+               config.plugins.configurationbackup.backupdirs.save()
+               config.plugins.configurationbackup.save()
+               config.save()
+               self.close(None)
+
+       def exit(self):
+               self.close(None)
+
+       def okClicked(self):
+               if self.filelist.canDescent():
+                       self.filelist.descent()
+
+
+class RestoreMenu(Screen):
+       skin = """
+               <screen position="135,144" size="450,300" title="Restore backups..." >
+               <widget name="filelist" position="10,10" size="430,240" scrollbarMode="showOnDemand" />
+               <widget name="cancel" position="120,255" size="100,40" pixmap="~/red.png" transparent="1" alphatest="on" />             
+               <widget name="canceltext" position="0,0" size="0,0" valign="center" halign="center" zPosition="2" font="Regular;20" transparent="1" foregroundColor="black" />
+               <widget name="restore" position="230,255" size="100,40" pixmap="~/yellow.png" transparent="1" alphatest="on" />
+               <widget name="restoretext" position="0,0" size="0,0" valign="center" halign="center" zPosition="2" font="Regular;20" transparent="1"  foregroundColor="black" />
+               </screen>"""
+
+       def __init__(self, session, plugin_path):
+               Screen.__init__(self, session)
+               self.skin_path = plugin_path
+               
+               self["canceltext"] = Label(_("Cancel"))
+               self["restoretext"] = Label(_("Restore"))
+               self["restore"] = Pixmap()
+               self["cancel"] = Pixmap()
+
+               self.sel = []
+               self.val = []
+               self.entry = False
+               self.exe = False
+               
+               self.path = ""
+
+               self["actions"] = NumberActionMap(["SetupActions"],
+               {
+                       "ok": self.KeyOk,
+                       "cancel": self.keyCancel
+               }, -1)
+
+               self["shortcuts"] = ActionMap(["ShortcutActions"],
+               {
+                       "red": self.keyCancel,
+                       "yellow": self.KeyOk,
+               })
+               self.flist = []
+               self["filelist"] = MenuList(self.flist)
+               self.fill_list()
+               self.onLayoutFinish.append(self.layoutFinished)
+
+       def layoutFinished(self):
+               self.setWindowTitle()
+
+       def setWindowTitle(self):
+               self.setTitle(_("Restore backups..."))
+
+
+       def fill_list(self):
+               self.flist = []
+               self.path = getBackupPath()
+               if (path.exists(self.path) == False):
+                       makedirs(self.path)
+               for file in listdir(self.path):
+                       if (file.endswith(".tar.gz")):
+                               self.flist.append((file))
+                               self.entry = True
+                               self["filelist"].l.setList(self.flist)
+
+       def KeyOk(self):
+               if (self.exe == False) and (self.entry == True):
+                       self.sel = self["filelist"].getCurrent()
+                       self.val = self.path + self.sel
+                       self.session.openWithCallback(self.startRestore, MessageBox, _("Are you sure you want to restore\nfollowing backup:\n" + self.sel + "\nSystem will restart after the restore!"))
+
+       def keyCancel(self):
+               self.close()
+
+       def startRestore(self, ret = False):
+               if (ret == True):
+                       self.exe = True
+                       self.session.open(Console, title = _("Restore running"), cmdlist = ["tar -xzvf " + self.path + "/" + self.sel + " -C /", "killall -9 enigma2"])
+
+       def Exit(self):
+               self.close()
+
+class RestoreScreen(Screen, ConfigListScreen):
+       skin = """
+               <screen position="135,144" size="350,310" title="Restore running..." >
+               <widget name="config" position="10,10" size="330,250" transparent="1" scrollbarMode="showOnDemand" />
+               </screen>"""
+               
+       def __init__(self, session, runRestore = False):
+               Screen.__init__(self, session)
+               self.session = session
+               self.runRestore = runRestore
+               self["actions"] = ActionMap(["WizardActions", "DirectionActions"], 
+               {
+                       "ok": self.close,
+                       "back": self.close,
+                       "cancel": self.close,
+               }, -1)
+               self.finished_cb = None
+               self.backuppath = getBackupPath()
+               self.backupfile = getBackupFilename()
+               self.fullbackupfilename = self.backuppath + "/" + self.backupfile
+               self.list = []
+               ConfigListScreen.__init__(self, self.list)
+               self.onLayoutFinish.append(self.layoutFinished)
+               if self.runRestore:
+                       self.onShown.append(self.doRestore)
+
+       def layoutFinished(self):
+               self.setWindowTitle()
+
+       def setWindowTitle(self):
+               self.setTitle(_("Restore running..."))
+
+       def doRestore(self):
+               if self.finished_cb:
+                       self.session.openWithCallback(self.finished_cb, Console, title = _("Restore running"), cmdlist = ["tar -xzvf " + self.fullbackupfilename + " -C /", "killall -9 enigma2"])
+               else:
+                       self.session.open(Console, title = _("Restore running"), cmdlist = ["tar -xzvf " + self.fullbackupfilename + " -C /", "killall -9 enigma2"])
+
+       def backupFinishedCB(self,retval = None):
+               self.close(True)
+
+       def backupErrorCB(self,retval = None):
+               self.close(False)
+
+       def runAsync(self, finished_cb):
+               self.finished_cb = finished_cb
+               self.doRestore()
+               
+       
\ No newline at end of file
diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/ImageWizard.py b/lib/python/Plugins/SystemPlugins/SoftwareManager/ImageWizard.py
new file mode 100755 (executable)
index 0000000..1797e4f
--- /dev/null
@@ -0,0 +1,120 @@
+from Screens.Wizard import WizardSummary
+from Screens.WizardLanguage import WizardLanguage
+from Screens.Wizard import wizardManager
+from Screens.Rc import Rc
+from Components.Label import Label
+from Components.MenuList import MenuList
+from Components.PluginComponent import plugins
+from Plugins.Plugin import PluginDescriptor
+from Tools.Directories import fileExists, resolveFilename, SCOPE_PLUGINS, SCOPE_SKIN_IMAGE
+from Components.Pixmap import Pixmap, MovingPixmap, MultiPixmap
+from os import popen, path, makedirs, listdir, access, stat, rename, remove, W_OK, R_OK
+
+from Components.config import config, getConfigListEntry, ConfigSubsection, ConfigText, ConfigLocations, ConfigBoolean
+from Components.Harddisk import harddiskmanager
+config.misc.firstrun = ConfigBoolean(default = True)
+config.plugins.configurationbackup = ConfigSubsection()
+config.plugins.configurationbackup.backuplocation = ConfigText(default = '/media/hdd/', visible_width = 50, fixed_size = False)
+config.plugins.configurationbackup.backupdirs = ConfigLocations(default=['/etc/enigma2/', '/etc/network/interfaces', '/etc/wpa_supplicant.conf'])
+
+
+backupfile = "enigma2settingsbackup.tar.gz"
+
+def checkConfigBackup():
+       parts = [ (r.description, r.mountpoint) for r in harddiskmanager.getMountedPartitions(onlyhotplug = False)]
+       for x in parts:
+               if x[1] == '/':
+                       parts.remove(x)
+       if len(parts):
+               for x in parts:
+                       if x[1].endswith('/'):
+                               fullbackupfile =  x[1] + 'backup/' + backupfile
+                               if fileExists(fullbackupfile):
+                                       config.plugins.configurationbackup.backuplocation.value = str(x[1])
+                                       config.plugins.configurationbackup.backuplocation.save()
+                                       config.plugins.configurationbackup.save()
+                                       return x
+                       else:
+                               fullbackupfile =  x[1] + '/backup/' + backupfile
+                               if fileExists(fullbackupfile):
+                                       config.plugins.configurationbackup.backuplocation.value = str(x[1])
+                                       config.plugins.configurationbackup.backuplocation.save()
+                                       config.plugins.configurationbackup.save()
+                                       return x
+               return None             
+
+def checkBackupFile():
+       backuplocation = config.plugins.configurationbackup.backuplocation.value
+       if backuplocation.endswith('/'):
+               fullbackupfile =  backuplocation + 'backup/' + backupfile
+               if fileExists(fullbackupfile):
+                       return True
+               else:
+                       return False
+       else:
+               fullbackupfile =  backuplocation + '/backup/' + backupfile
+               if fileExists(fullbackupfile):
+                       return True
+               else:
+                       return False
+
+if checkConfigBackup() is None:
+       backupAvailable = 0
+else:
+       backupAvailable = 1
+
+class ImageWizard(WizardLanguage, Rc):
+       skin = """
+               <screen name="ImageWizard" position="0,0" size="720,576" title="Welcome..." flags="wfNoBorder" >
+                       <widget name="text" position="153,40" size="340,330" font="Regular;22" />
+                       <widget source="list" render="Listbox" position="43,340" size="490,180" scrollbarMode="showOnDemand" >
+                               <convert type="StringList" />
+                       </widget>
+                       <widget name="config" position="53,340" zPosition="1" size="440,180" transparent="1" scrollbarMode="showOnDemand" />
+                       <ePixmap pixmap="skin_default/buttons/button_red.png" position="40,225" zPosition="0" size="15,16" transparent="1" alphatest="on" />
+                       <widget name="languagetext" position="55,225" size="95,30" font="Regular;18" />
+                       <widget name="wizard" pixmap="skin_default/wizard.png" position="40,50" zPosition="10" size="110,174" alphatest="on" />
+                       <widget name="rc" pixmaps="skin_default/rc.png,skin_default/rcold.png" position="530,50" zPosition="10" size="154,500" alphatest="on" />
+                       <widget name="arrowdown" pixmap="skin_default/arrowdown.png" position="-100,-100" zPosition="11" size="37,70" alphatest="on" />
+                       <widget name="arrowdown2" pixmap="skin_default/arrowdown.png" position="-100,-100" zPosition="11" size="37,70" alphatest="on" />
+                       <widget name="arrowup" pixmap="skin_default/arrowup.png" position="-100,-100" zPosition="11" size="37,70" alphatest="on" />
+                       <widget name="arrowup2" pixmap="skin_default/arrowup.png" position="-100,-100" zPosition="11" size="37,70" alphatest="on" />
+               </screen>"""
+       def __init__(self, session):
+               self.xmlfile = resolveFilename(SCOPE_PLUGINS, "SystemPlugins/SoftwareManager/imagewizard.xml")
+               WizardLanguage.__init__(self, session, showSteps = False, showStepSlider = False)
+               Rc.__init__(self)
+               self.session = session
+               self["wizard"] = Pixmap()
+               self.selectedDevice = None
+               
+       def markDone(self):
+               pass
+
+       def listDevices(self):
+               list = [ (r.description, r.mountpoint) for r in harddiskmanager.getMountedPartitions(onlyhotplug = False)]
+               for x in list:
+                       result = access(x[1], W_OK) and access(x[1], R_OK)
+                       if result is False or x[1] == '/':
+                               list.remove(x)
+               for x in list:
+                       if x[1].startswith('/autofs/'):
+                               list.remove(x)  
+               return list
+
+       def deviceSelectionMade(self, index):
+               self.deviceSelect(index)
+               
+       def deviceSelectionMoved(self):
+               self.deviceSelect(self.selection)
+               
+       def deviceSelect(self, device):
+               self.selectedDevice = device
+               config.plugins.configurationbackup.backuplocation.value = self.selectedDevice
+               config.plugins.configurationbackup.backuplocation.save()
+               config.plugins.configurationbackup.save()
+
+       
+if config.misc.firstrun.value:
+       wizardManager.registerWizard(ImageWizard, backupAvailable, priority = 10)
+
diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/LICENSE b/lib/python/Plugins/SystemPlugins/SoftwareManager/LICENSE
new file mode 100755 (executable)
index 0000000..835b9dc
--- /dev/null
@@ -0,0 +1,17 @@
+This plugin is licensed under the Creative Commons 
+Attribution-NonCommercial-ShareAlike 3.0 Unported 
+License. To view a copy of this license, visit
+http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter to Creative
+Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
+
+Alternatively, this plugin may be distributed and executed on hardware which
+is licensed by Dream Multimedia GmbH.
+
+This plugin is NOT free software. It is open source, you are allowed to
+modify it (if you keep the license), but it may not be commercially 
+distributed other than under the conditions noted above.
+
+Some Icons used are taken from NX10 icons by Mazenl77
+(http://www.iconspedia.com/pack/nx10-1-6/)
+licensed under Creative Commons Attribution 3.0 Unported
+http://creativecommons.org/licenses/by/3.0/
diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/Makefile.am b/lib/python/Plugins/SystemPlugins/SoftwareManager/Makefile.am
new file mode 100755 (executable)
index 0000000..f94498f
--- /dev/null
@@ -0,0 +1,12 @@
+installdir = $(LIBDIR)/enigma2/python/Plugins/SystemPlugins/SoftwareManager
+
+install_PYTHON =       \
+       __init__.py \
+       plugin.py \
+       BackupRestore.py \
+       ImageWizard.py \
+       imagewizard.xml \
+       *.png 
+
+install_DATA = LICENSE
diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/__init__.py b/lib/python/Plugins/SystemPlugins/SoftwareManager/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/blue.png b/lib/python/Plugins/SystemPlugins/SoftwareManager/blue.png
new file mode 100755 (executable)
index 0000000..a392bbe
Binary files /dev/null and b/lib/python/Plugins/SystemPlugins/SoftwareManager/blue.png differ
diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/green.png b/lib/python/Plugins/SystemPlugins/SoftwareManager/green.png
new file mode 100755 (executable)
index 0000000..f168e4d
Binary files /dev/null and b/lib/python/Plugins/SystemPlugins/SoftwareManager/green.png differ
diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/imagewizard.xml b/lib/python/Plugins/SystemPlugins/SoftwareManager/imagewizard.xml
new file mode 100755 (executable)
index 0000000..98658b7
--- /dev/null
@@ -0,0 +1,100 @@
+<wizard>\r
+       <step id="restorequestion">\r
+               <condition>\r
+from Plugins.SystemPlugins.SoftwareManager.ImageWizard import checkConfigBackup\r
+self.backuppath = checkConfigBackup()\r
+self.condition = (self.backuppath is not None and config.misc.firstrun.value)\r
+               </condition>\r
+               <text value="Do you want to restore your settings?" />\r
+               <list>\r
+                       <listentry caption="Yes, restore the settings now" step="restore" />\r
+                       <listentry caption="No, just start my dreambox" step="end" />\r
+               </list>\r
+               <code>\r
+self.clearSelectedKeys()\r
+self.selectKey("OK")\r
+               </code>\r
+       </step>\r
+\r
+       <step id="welcome">\r
+               <text value="Welcome to the Image upgrade wizard. The wizard will assist you in upgrading the firmware of your Dreambox by providing a backup facility for your current settings and a short explanation of how to upgrade your firmware." />\r
+               <list>\r
+                       <listentry caption="OK, guide me through the upgrade process" step="backupquestion" />\r
+                       <listentry caption="Exit the wizard" step="end" />\r
+               </list>\r
+       </step>\r
+\r
+       <step id="backupquestion">\r
+               <text value="The wizard can backup your current settings. Do you want to do a backup now?" />\r
+               <list>\r
+                       <listentry caption="Yes, backup my settings!" step="backupwhere" />\r
+                       <listentry caption="No backup needed" step="upgrade" />\r
+               </list>\r
+       </step>\r
+\r
+       <step id="backupwhere" nextstep="backup">\r
+               <text value="Where do you want to backup your settings?" />\r
+               <list type="dynamic" source="listDevices" evaluation="deviceSelectionMade" onselect="deviceSelectionMoved" />\r
+       </step>\r
+\r
+       <step id="backup" nextstep="backupresult">\r
+               <text value="You have chosen to backup your settings. Please press OK to start the backup now." />\r
+               <config screen="BackupScreen" module="Plugins.SystemPlugins.SoftwareManager.BackupRestore" type="ConfigList" />\r
+               <code pos="after" async="yes">\r
+self.currStep = self.getStepWithID('backupresult')\r
+self.afterAsyncCode()\r
+               </code> \r
+       </step>\r
+               \r
+       <step id="backupresult" nextstep="upgrade">\r
+               <condition>\r
+from Plugins.SystemPlugins.SoftwareManager.ImageWizard import checkBackupFile\r
+self.backuppath = checkBackupFile()\r
+self.condition = (self.backuppath is True)\r
+               </condition>\r
+               <text value="Your backup succeeded. We will now continue to explain the further upgrade process." />\r
+       </step>\r
+\r
+       <step id="backupresult" nextstep="backupwhere">\r
+               <condition>\r
+from Plugins.SystemPlugins.SoftwareManager.ImageWizard import checkBackupFile\r
+self.backuppath = checkBackupFile()\r
+self.condition = (self.backuppath is False)\r
+               </condition>\r
+               <text value="The backup failed. Please choose a different backup location." />\r
+       </step>\r
+\r
+       <step id="restore" nextstep="backupresult">\r
+               <text value="You have chosen to restore your settings. Enigma2 will restart after restore. Please press OK to start the restore now." />\r
+               <config screen="RestoreScreen" module="Plugins.SystemPlugins.SoftwareManager.BackupRestore" type="ConfigList" />\r
+       </step>\r
+               \r
+\r
+       <step id="upgradehow">\r
+               <text value="The wizard can backup your current settings. Do you want to do a backup now?" />\r
+               <list>\r
+                       <listentry caption="Install a new image with your web browser" step="upgrade" />\r
+                       <listentry caption="Install a new image with a USB stick" step="upgradeUSB" />\r
+               </list>\r
+       </step>\r
+               \r
+       <step id="upgrade">\r
+               <text value="You need a PC connected to your dreambox. If you need further instructions, please visit the website http://www.dm7025.de.\nYour dreambox will now be halted. After you have performed the update instructions from the website, your new firmware will ask you to restore your settings." />\r
+               <list>\r
+                       <listentry caption="Yes, perform a shutdown now." step="shutdown" />\r
+                       <listentry caption="No, do nothing." step="end" />\r
+               </list>\r
+       </step>\r
+\r
+       <step id="shutdown" nextstep="shutdown">\r
+               <code>\r
+from enigma import quitMainloop\r
+quitMainloop(1)\r
+               </code>\r
+               <text value="Your dreambox is shutting down. Please stand by..." />\r
+       </step>\r
+               \r
+       <step id="end">\r
+               <text value="The wizard is finished now." />\r
+       </step>\r
+</wizard>\r
diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/installable.png b/lib/python/Plugins/SystemPlugins/SoftwareManager/installable.png
new file mode 100755 (executable)
index 0000000..710f420
Binary files /dev/null and b/lib/python/Plugins/SystemPlugins/SoftwareManager/installable.png differ
diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/installed.png b/lib/python/Plugins/SystemPlugins/SoftwareManager/installed.png
new file mode 100755 (executable)
index 0000000..d6a1bc1
Binary files /dev/null and b/lib/python/Plugins/SystemPlugins/SoftwareManager/installed.png differ
diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/plugin.py b/lib/python/Plugins/SystemPlugins/SoftwareManager/plugin.py
new file mode 100755 (executable)
index 0000000..85d2328
--- /dev/null
@@ -0,0 +1,706 @@
+from Plugins.Plugin import PluginDescriptor
+from Screens.Console import Console
+from Screens.ChoiceBox import ChoiceBox
+from Screens.MessageBox import MessageBox
+from Screens.Screen import Screen
+from Screens.Ipkg import Ipkg
+from Components.ActionMap import ActionMap, NumberActionMap
+from Components.Input import Input
+from Components.Ipkg import IpkgComponent
+from Components.Label import Label
+from Components.MenuList import MenuList
+from Components.Sources.List import List
+from Components.Slider import Slider
+from Components.Harddisk import harddiskmanager
+from Components.config import config,getConfigListEntry, ConfigSubsection, ConfigText, ConfigLocations
+from Components.Console import Console
+from Components.MultiContent import MultiContentEntryText, MultiContentEntryPixmapAlphaTest
+from Components.SelectionList import SelectionList
+from Tools.Directories import fileExists, resolveFilename, SCOPE_PLUGINS, SCOPE_SKIN_IMAGE
+from Tools.LoadPixmap import LoadPixmap
+from enigma import eTimer,  loadPNG, quitMainloop, RT_HALIGN_LEFT, RT_VALIGN_CENTER, eListboxPythonMultiContent, eListbox, gFont
+from cPickle import dump, load
+
+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
+from time import time, gmtime, strftime, localtime
+from stat import ST_MTIME
+from datetime import date
+
+from ImageWizard import ImageWizard
+from BackupRestore import BackupSelection, RestoreMenu, BackupScreen, RestoreScreen, getBackupPath, getBackupFilename
+
+config.plugins.configurationbackup = ConfigSubsection()
+config.plugins.configurationbackup.backuplocation = ConfigText(default = '/media/hdd/', visible_width = 50, fixed_size = False)
+config.plugins.configurationbackup.backupdirs = ConfigLocations(default=['/etc/enigma2/', '/etc/network/interfaces', '/etc/wpa_supplicant.conf'])
+
+
+def write_cache(cache_file, cache_data):
+       #Does a cPickle dump
+       if not os_path.isdir( os_path.dirname(cache_file) ):
+               try:
+                       mkdir( os_path.dirname(cache_file) )
+               except OSError:
+                           print os_path.dirname(cache_file), 'is a file'
+       fd = open(cache_file, 'w')
+       dump(cache_data, fd, -1)
+       fd.close()
+
+def valid_cache(cache_file, cache_ttl):
+       #See if the cache file exists and is still living
+       try:
+               mtime = stat(cache_file)[ST_MTIME]
+       except:
+               return 0
+       curr_time = time()
+       if (curr_time - mtime) > cache_ttl:
+               return 0
+       else:
+               return 1
+
+def load_cache(cache_file):
+       #Does a cPickle load
+       fd = open(cache_file)
+       cache_data = load(fd)
+       fd.close()
+       return cache_data
+
+
+class UpdatePluginMenu(Screen):
+       skin = """
+               <screen name="UpdatePluginMenu" position="90,130" size="550,330" title="Softwaremanager..." >
+                       <ePixmap pixmap="skin_default/border_menu.png" position="10,10" zPosition="1" size="250,300" transparent="1" alphatest="on" />
+                       <widget source="menu" render="Listbox" position="20,20" size="230,260" scrollbarMode="showOnDemand">
+                               <convert type="TemplatedMultiContent">
+                                       {"template": [
+                                                       MultiContentEntryText(pos = (2, 2), size = (230, 22), flags = RT_HALIGN_LEFT, text = 1), # index 0 is the MenuText,
+                                               ],
+                                       "fonts": [gFont("Regular", 20)],
+                                       "itemHeight": 25
+                                       }
+                               </convert>
+                       </widget>
+                       <widget source="menu" render="Listbox" position="280,10" size="230,300" scrollbarMode="showNever" selectionDisabled="1">
+                               <convert type="TemplatedMultiContent">
+                                       {"template": [
+                                                       MultiContentEntryText(pos = (2, 2), size = (230, 300), flags = RT_HALIGN_CENTER|RT_VALIGN_CENTER|RT_WRAP, text = 2), # index 0 is the MenuText,
+                                               ],
+                                       "fonts": [gFont("Regular", 20)],
+                                       "itemHeight": 230
+                                       }
+                               </convert>
+                       </widget>
+               </screen>"""
+               
+       def __init__(self, session, args = 0):
+               Screen.__init__(self, session)
+               self.skin_path = plugin_path
+               self.menu = args
+               self.list = []
+               self.oktext = _("\nPress OK on your remote control to continue.")
+               self.backupdirs = ' '.join( config.plugins.configurationbackup.backupdirs.value )
+               if self.menu == 0:
+                       self.list.append(("software-update", _("Software update"), _("\nOnline update of your Dreambox software." ) + self.oktext) )
+                       self.list.append(("software-restore", _("Software restore"), _("\nRestore your Dreambox with a new firmware." ) + self.oktext))
+                       self.list.append(("system-backup", _("Backup system settings"), _("\nBackup your Dreambox settings." ) + self.oktext))
+                       self.list.append(("system-restore",_("Restore system settings"), _("\nRestore your Dreambox settings." ) + self.oktext))
+                       if config.usage.setup_level.index >= 2: # expert+
+                               self.list.append(("advanced", _("Advanced Options"), _("\nAdvanced options and settings." ) + self.oktext))
+               elif self.menu == 1:
+                       self.list.append(("ipkg-manager", _("Packet management"),  _("\nView, install and remove available or installed packages." ) + self.oktext))
+                       self.list.append(("ipkg-install", _("Install local IPKG"),  _("\nScan for local packages and install them." ) + self.oktext))
+                       self.list.append(("advancedrestore", _("Advanced restore"), _("\nRestore your backups by date." ) + self.oktext))
+                       self.list.append(("backuplocation", _("Choose backup location"),  _("\nSelect your backup device.\nCurrent device: " ) + config.plugins.configurationbackup.backuplocation.value + self.oktext ))
+                       self.list.append(("backupfiles", _("Choose backup files"),  _("Select files for backup. Currently selected:\n" ) + self.backupdirs + self.oktext))
+                       self.list.append(("ipkg-source",_("Choose upgrade source"), _("\nEdit the upgrade source address." ) + self.oktext))
+
+               self["menu"] = List(self.list)
+                               
+               self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"],
+               {
+                       "ok": self.go,
+                       "back": self.close,
+                       "red": self.close,
+               }, -1)
+
+               self.onLayoutFinish.append(self.layoutFinished)
+               self.backuppath = getBackupPath()
+               self.backupfile = getBackupFilename()
+               self.fullbackupfilename = self.backuppath + "/" + self.backupfile
+               self.onShown.append(self.setWindowTitle)
+               
+       def layoutFinished(self):
+               idx = 0
+               self["menu"].index = idx
+               
+       def setWindowTitle(self):
+               self.setTitle(_("Software manager..."))
+               
+       def go(self):
+               current = self["menu"].getCurrent()[0]
+               if self.menu == 0:
+                       if (current == "software-restore"):
+                               self.session.open(ImageWizard)
+                       elif (current == "software-update"):
+                               self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to update your Dreambox?")+"\n"+_("\nAfter pressing OK, please wait!"))
+                       elif (current == "advanced"):
+                               self.session.open(UpdatePluginMenu, 1)
+                       elif (current == "system-backup"):
+                               self.session.openWithCallback(self.backupDone,BackupScreen, runBackup = True)
+                       elif (current == "system-restore"):
+                               if os_path.exists(self.fullbackupfilename):
+                                       self.session.openWithCallback(self.startRestore, MessageBox, _("Are you sure you want to restore your Enigma2 backup?\nEnigma2 will restart after the restore"))
+                               else:   
+                                       self.session.open(MessageBox, _("Sorry no backups found!"), MessageBox.TYPE_INFO)
+               if self.menu == 1:
+                       if (current == "ipkg-manager"):
+                               self.session.open(PacketManager, self.skin_path)
+                       elif (current == "ipkg-source"):
+                               self.session.open(IPKGSource)
+                       elif (current == "ipkg-install"):
+                               try:
+                                       from Plugins.Extensions.MediaScanner.plugin import main
+                                       main(self.session)
+                               except:
+                                       self.session.open(MessageBox, _("Sorry MediaScanner is not installed!"), MessageBox.TYPE_INFO)
+                       elif (current == "backuplocation"):
+                               parts = [ (r.description, r.mountpoint, self.session) for r in harddiskmanager.getMountedPartitions(onlyhotplug = False)]
+                               for x in parts:
+                                       if not access(x[1], F_OK|R_OK|W_OK) or x[1] == '/':
+                                               parts.remove(x)
+                               for x in parts:
+                                       if x[1].startswith('/autofs/'):
+                                               parts.remove(x)                                 
+                               if len(parts):
+                                       self.session.openWithCallback(self.backuplocation_choosen, ChoiceBox, title = _("Please select medium to use as backup location"), list = parts)
+                       elif (current == "backupfiles"):
+                               self.session.openWithCallback(self.backupfiles_choosen,BackupSelection)
+                       elif (current == "advancedrestore"):
+                               self.session.open(RestoreMenu, self.skin_path)                  
+
+       def backupfiles_choosen(self, ret):
+               self.backupdirs = ' '.join( config.plugins.configurationbackup.backupdirs.value )
+
+       def backuplocation_choosen(self, option):
+               if option is not None:
+                       config.plugins.configurationbackup.backuplocation.value = str(option[1])
+               config.plugins.configurationbackup.backuplocation.save()
+               config.plugins.configurationbackup.save()
+               config.save()
+               self.createBackupfolders()
+       
+       def runUpgrade(self, result):
+               if result:
+                       self.session.open(UpdatePlugin, self.skin_path)
+
+       """def runFinished(self):
+               self.session.openWithCallback(self.reboot, MessageBox, _("Upgrade finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
+               
+       def reboot(self, result):
+               if result is None:
+                       return
+               if result:
+                       quitMainloop(3)"""
+
+       def createBackupfolders(self):
+               print "Creating backup folder if not already there..."
+               self.backuppath = getBackupPath()
+               try:
+                       if (os_path.exists(self.backuppath) == False):
+                               makedirs(self.backuppath)
+               except OSError:
+                       self.session.open(MessageBox, _("Sorry, your backup destination is not writeable.\n\nPlease choose another one."), MessageBox.TYPE_INFO)
+
+       def backupDone(self,retval = None):
+               if retval is True:
+                       self.session.open(MessageBox, _("Backup done."), MessageBox.TYPE_INFO)
+               else:
+                       self.session.open(MessageBox, _("Backup failed."), MessageBox.TYPE_INFO)
+
+       def startRestore(self, ret = False):
+               if (ret == True):
+                       self.exe = True
+                       self.session.open(RestoreScreen, runRestore = True)
+
+
+class IPKGSource(Screen):
+       skin = """
+               <screen position="100,100" size="550,60" title="IPKG source" >
+                       <widget name="text" position="0,0" size="550,25" font="Regular;20" backgroundColor="background" foregroundColor="#cccccc" />
+               </screen>"""
+               
+       def __init__(self, session, args = None):
+               Screen.__init__(self, session)
+               self.session = session
+               
+               fp = file('/etc/ipkg/official-feed.conf', 'r')
+               sources = fp.readlines()
+               fp.close()
+               
+               self["text"] = Input(sources[0], maxSize=False, type=Input.TEXT)
+                               
+               self["actions"] = NumberActionMap(["WizardActions", "InputActions", "TextEntryActions", "KeyboardInputActions"], 
+               {
+                       "ok": self.go,
+                       "back": self.close,
+                       "left": self.keyLeft,
+                       "right": self.keyRight,
+                       "home": self.keyHome,
+                       "end": self.keyEnd,
+                       "deleteForward": self.keyDeleteForward,
+                       "deleteBackward": self.keyDeleteBackward,
+                       "1": self.keyNumberGlobal,
+                       "2": self.keyNumberGlobal,
+                       "3": self.keyNumberGlobal,
+                       "4": self.keyNumberGlobal,
+                       "5": self.keyNumberGlobal,
+                       "6": self.keyNumberGlobal,
+                       "7": self.keyNumberGlobal,
+                       "8": self.keyNumberGlobal,
+                       "9": self.keyNumberGlobal,
+                       "0": self.keyNumberGlobal
+               }, -1)
+               
+       def go(self):
+               fp = file('/etc/ipkg/official-feed.conf', 'w')
+               fp.write(self["text"].getText())
+               fp.close()
+               self.close()
+               
+       def keyLeft(self):
+               self["text"].left()
+       
+       def keyRight(self):
+               self["text"].right()
+       
+       def keyHome(self):
+               self["text"].home()
+       
+       def keyEnd(self):
+               self["text"].end()
+       
+       def keyDeleteForward(self):
+               self["text"].delete()
+       
+       def keyDeleteBackward(self):
+               self["text"].deleteBackward()
+       
+       def keyNumberGlobal(self, number):
+               print "pressed", number
+               self["text"].number(number)
+
+
+class PacketList(MenuList):
+       def __init__(self, list, enableWrapAround=True):
+               MenuList.__init__(self, list, enableWrapAround, eListboxPythonMultiContent)
+               self.l.setFont(0, gFont("Regular", 22))
+               self.l.setFont(1, gFont("Regular", 14))
+               self.l.setItemHeight(52)
+
+class PacketManager(Screen):
+       skin = """
+               <screen position="90,80" size="530,420" title="IPKG upgrade..." >
+                       <widget name="list" position="5,10" size="520,365" zPosition="1" scrollbarMode="showOnDemand" />
+                       <widget name="status" position="30,160" size="530,40" zPosition="4" font="Regular;22" halign="left" transparent="1" />
+                       <ePixmap pixmap="skin_default/buttons/red.png" position="10,380" zPosition="2" size="140,40" transparent="1" alphatest="on" />
+                       <widget name="closetext" position="20,390" size="140,21" zPosition="10" font="Regular;21" transparent="1" />
+                       <ePixmap pixmap="skin_default/buttons/green.png" position="160,380" zPosition="2" size="140,40" transparent="1" alphatest="on" />
+                       <widget name="reloadtext" position="170,390" size="300,21" zPosition="10" font="Regular;21" transparent="1" />
+               </screen>"""
+               
+       def __init__(self, session, plugin_path, args = None):
+               Screen.__init__(self, session)
+               self.session = session
+               self.skin_path = plugin_path
+
+               self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"], 
+               {
+                       "ok": self.go,
+                       "back": self.close,
+                       "red": self.close,
+                       "green": self.reload,
+               }, -1)
+               
+               self.list = []
+               self["list"] = PacketList(self.list)
+               self.status = Label()
+               self["closetext"] = Label(_("Close"))
+               self["reloadtext"] = Label(_("Reload"))
+               self["status"] = self.status                            
+
+               self.list_updating = True
+               self.packetlist = []
+               self.installed_packetlist = {}
+               self.Console = Console()
+               self.cmdList = []
+               self.cachelist = []
+               self.cache_ttl = 86400  #600 is default, 0 disables, Seconds cache is considered valid (24h should be ok for caching ipkgs)
+               self.cache_file = '/usr/lib/enigma2/python/Plugins/SystemPlugins/SoftwareManager/packetmanager.cache' #Path to cache directory   
+               self.oktext = _("\nAfter pressing OK, please wait!")
+
+               self.ipkg = IpkgComponent()
+               self.ipkg.addCallback(self.ipkgCallback)
+               self.onShown.append(self.setWindowTitle)
+               self.onLayoutFinish.append(self.rebuildList)
+               self.onClose.append(self.cleanup)
+               
+       def cleanup(self):
+               self.ipkg.stop()
+               if self.Console is not None:
+                       del self.Console
+
+       def reload(self):
+               if (os_path.exists(self.cache_file) == True):
+                       remove(self.cache_file)
+                       self.list_updating = True
+                       self.rebuildList()
+                       
+       def setWindowTitle(self):
+               self.setTitle(_("Packet manager"))
+
+       def rebuildList(self):
+               self["list"].instance.hide()
+               self.status.setText(_("Package list update"))
+               self.status.show()
+               self.inv_cache = 0
+               self.vc = valid_cache(self.cache_file, self.cache_ttl)
+               if self.cache_ttl > 0 and self.vc != 0:
+                       try:
+                               self.buildPacketList()
+                       except:
+                               self.inv_cache = 1
+               if self.cache_ttl == 0 or self.inv_cache == 1 or self.vc == 0:
+                       self.run = 0
+                       self.ipkg.startCmd(IpkgComponent.CMD_UPDATE)
+
+       def go(self, returnValue = None):
+               returnValue = self['list'].l.getCurrentSelection()[0]
+               self.cmdList = []
+               if returnValue[3] == 'installed':
+                       self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": returnValue[0] }))
+                       if len(self.cmdList):
+                               self.session.openWithCallback(self.runRemove, MessageBox, _("Do you want to remove the package:\n" + returnValue[0] + "\n" + self.oktext))
+               elif returnValue[3] == 'upgradeable':
+                       self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": returnValue[0] }))
+                       if len(self.cmdList):
+                               self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to upgrade the package:\n" + returnValue[0] + "\n" + self.oktext))
+               else:
+                       self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": returnValue[0] }))
+                       if len(self.cmdList):
+                               self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to install the package:\n" + returnValue[0] + "\n" + self.oktext))
+
+       def runRemove(self, result):
+               if result:
+                       self.session.openWithCallback(self.runRemoveFinished, Ipkg, cmdList = self.cmdList)
+
+       def runRemoveFinished(self):
+               self.session.openWithCallback(self.RemoveReboot, MessageBox, _("Remove finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
+
+       def RemoveReboot(self, result):
+               if result is None:
+                       return
+               if result is False:
+                       entry = self['list'].l.getCurrentSelection()[0]
+                       item = self['list'].l.getCurrentSelectionIndex()
+                       self.list[item] = PacketEntryComponent([entry[0], entry[1], entry[2], 'installable'])
+                       self.cachelist[item] = [entry[0], entry[1], entry[2], 'installable']
+                       self['list'].l.setList(self.list)
+                       write_cache(self.cache_file, self.cachelist)
+               if result:
+                       quitMainloop(3)
+
+       def runUpgrade(self, result):
+               if result:
+                       self.session.openWithCallback(self.runUpgradeFinished, Ipkg, cmdList = self.cmdList)
+
+       def runUpgradeFinished(self):
+               self.session.openWithCallback(self.UpgradeReboot, MessageBox, _("Upgrade finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
+               
+       def UpgradeReboot(self, result):
+               if result is None:
+                       return
+               if result is False:
+                       entry = self['list'].l.getCurrentSelection()[0]
+                       item = self['list'].l.getCurrentSelectionIndex()
+                       self.list[item] = PacketEntryComponent([entry[0], entry[1], entry[2], 'installed'])
+                       self.cachelist[item] = [entry[0], entry[1], entry[2], 'installed']
+                       self['list'].l.setList(self.list)
+                       write_cache(self.cache_file, self.cachelist)
+               if result:
+                       quitMainloop(3)
+
+       def ipkgCallback(self, event, param):
+               if event == IpkgComponent.EVENT_ERROR:
+                       self.list_updating = False
+                       self.status.setText(_("An error occured!"))
+               elif event == IpkgComponent.EVENT_DONE:
+                       if self.list_updating:
+                               self.list_updating = False
+                               if not self.Console:
+                                       self.Console = Console()
+                               cmd = "ipkg list"
+                               self.Console.ePopen(cmd, self.IpkgList_Finished)
+               #print event, "-", param
+               pass
+
+       def IpkgList_Finished(self, result, retval, extra_args = None):
+               if len(result):
+                       self.packetlist = []
+                       for x in result.splitlines():
+                               split = x.split(' - ')
+                               self.packetlist.append([split[0].strip(), split[1].strip(),split[2].strip()])
+               cmd = "ipkg list_installed"
+               self.Console.ePopen(cmd, self.IpkgListInstalled_Finished)
+
+       def IpkgListInstalled_Finished(self, result, retval, extra_args = None):
+               if len(result):
+                       self.installed_packetlist = {}
+                       for x in result.splitlines():
+                               split = x.split(' - ')
+                               self.installed_packetlist[split[0].strip()] = split[1].strip()
+               self.buildPacketList()
+
+       def PacketEntryComponent(self,entry):
+               res = [ entry ]
+               res.append(MultiContentEntryText(pos=(5, 1), size=(440, 28), font=0, text= entry[0]))
+               res.append(MultiContentEntryText(pos=(5, 26), size=(440, 20), font=1, text=entry[2]))
+               res.append(MultiContentEntryPixmapAlphaTest(pos=(445, 2), size=(48, 48), png = entry[4]))
+               res.append(MultiContentEntryPixmapAlphaTest(pos=(5, 50), size=(510, 2), png = entry[5]))
+               
+               return res
+
+
+       def buildPacketList(self):
+               self.list = []
+               self.cachelist = []
+               installedpng = loadPNG(resolveFilename(SCOPE_PLUGINS, "SystemPlugins/SoftwareManager/installed.png"))
+               upgradeablepng = loadPNG(resolveFilename(SCOPE_PLUGINS, "SystemPlugins/SoftwareManager/upgradeable.png"))
+               installablepng = loadPNG(resolveFilename(SCOPE_PLUGINS, "SystemPlugins/SoftwareManager/installable.png"))
+               divpng = loadPNG(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/div-h.png"))
+
+               if self.cache_ttl > 0 and self.vc != 0:
+                       print 'Loading packagelist cache from ',self.cache_file
+                       try:
+                               self.cachelist = load_cache(self.cache_file)
+                               if len(self.cachelist) > 0:
+                                       for x in self.cachelist:
+                                               if x[3] == 'installed':
+                                                       self.list.append(self.PacketEntryComponent([x[0], x[1], x[2], x[3],installedpng,divpng]))
+                                               elif x[3] == 'upgradeable':
+                                                       self.list.append(self.PacketEntryComponent([x[0], x[1], x[2], x[3],upgradeablepng,divpng]))
+                                               else:
+                                                       self.list.append(self.PacketEntryComponent([x[0], x[1], x[2], x[3],installablepng,divpng]))
+                                       self['list'].l.setList(self.list)
+                                       self["list"].instance.show()
+                                       self.status.hide()
+                       except:
+                               self.inv_cache = 1
+
+               if self.cache_ttl == 0 or self.inv_cache == 1 or self.vc == 0:
+                       print 'rebuilding fresh package list'
+                       for x in self.packetlist:
+                               status = ""
+                               if self.installed_packetlist.has_key(x[0].strip()):
+                                       if self.installed_packetlist[x[0].strip()] == x[1].strip():
+                                               status = "installed"
+                                               self.list.append(self.PacketEntryComponent([x[0].strip(), x[1].strip(), x[2].strip(), status,installedpng,divpng]))
+                                       else:
+                                               status = "upgradeable"
+                                               self.list.append(self.PacketEntryComponent([x[0].strip(), x[1].strip(), x[2].strip(), status,upgradeablepng,divpng]))
+                               else:
+                                       status = "installable"
+                                       self.list.append(self.PacketEntryComponent([x[0].strip(), x[1].strip(), x[2].strip(), status,installablepng,divpng]))
+                               self.cachelist.append([x[0].strip(), x[1].strip(), x[2].strip(), status])       
+                       write_cache(self.cache_file, self.cachelist)
+                       self['list'].l.setList(self.list)
+                       self["list"].instance.show()
+                       self.status.hide()
+
+
+class UpdatePlugin(Screen):
+       skin = """
+               <screen position="100,100" size="550,200" title="Software Update..." >
+                       <widget name="activityslider" position="0,0" size="550,5"  />
+                       <widget name="slider" position="0,100" size="550,30"  />
+                       <widget name="package" position="10,30" size="540,20" font="Regular;18"/>
+                       <widget name="status" position="10,60" size="540,45" font="Regular;18"/>
+               </screen>"""
+               
+       def __init__(self, session, args = None):
+               self.skin = UpdatePlugin.skin
+               Screen.__init__(self, session)
+               
+               self.sliderPackages = { "dreambox-dvb-modules": 1, "enigma2": 2, "tuxbox-image-info": 3 }
+               
+               self.slider = Slider(0, 4)
+               self["slider"] = self.slider
+               self.activityslider = Slider(0, 100)
+               self["activityslider"] = self.activityslider
+               self.status = Label(_("Upgrading Dreambox... Please wait"))
+               self["status"] = self.status
+               self.package = Label()
+               self["package"] = self.package
+               
+               self.packages = 0
+               self.error = 0
+               
+               self.activity = 0
+               self.activityTimer = eTimer()
+               self.activityTimer.callback.append(self.doActivityTimer)
+               self.activityTimer.start(100, False)
+                               
+               self.ipkg = IpkgComponent()
+               self.ipkg.addCallback(self.ipkgCallback)
+               
+               self.updating = True
+               self.package.setText(_("Package list update"))
+               self.ipkg.startCmd(IpkgComponent.CMD_UPDATE)
+                       
+               self["actions"] = ActionMap(["WizardActions"], 
+               {
+                       "ok": self.exit,
+                       "back": self.exit
+               }, -1)
+               
+       def doActivityTimer(self):
+               self.activity += 1
+               if self.activity == 100:
+                       self.activity = 0
+               self.activityslider.setValue(self.activity)
+               
+       def ipkgCallback(self, event, param):
+               if event == IpkgComponent.EVENT_DOWNLOAD:
+                       self.status.setText(_("Downloading"))
+               elif event == IpkgComponent.EVENT_UPGRADE:
+                       if self.sliderPackages.has_key(param):
+                               self.slider.setValue(self.sliderPackages[param])
+                       self.package.setText(param)
+                       self.status.setText(_("Upgrading"))
+                       self.packages += 1
+               elif event == IpkgComponent.EVENT_INSTALL:
+                       self.package.setText(param)
+                       self.status.setText(_("Installing"))
+                       self.packages += 1
+               elif event == IpkgComponent.EVENT_CONFIGURING:
+                       self.package.setText(param)
+                       self.status.setText(_("Configuring"))
+               elif event == IpkgComponent.EVENT_MODIFIED:
+                       self.session.openWithCallback(
+                               self.modificationCallback,
+                               MessageBox,
+                               _("A configuration file (%s) was modified since Installation.\nDo you want to keep your version?") % (param)
+                       )
+               elif event == IpkgComponent.EVENT_ERROR:
+                       self.error += 1
+               elif event == IpkgComponent.EVENT_DONE:
+                       if self.updating:
+                               self.updating = False
+                               self.ipkg.startCmd(IpkgComponent.CMD_UPGRADE, args = {'test_only': False})
+                       elif self.error == 0:
+                               self.slider.setValue(4)
+                               
+                               self.activityTimer.stop()
+                               self.activityslider.setValue(0)
+                               
+                               self.package.setText("")
+                               self.status.setText(_("Done - Installed or upgraded %d packages") % self.packages)
+                       else:
+                               self.activityTimer.stop()
+                               self.activityslider.setValue(0)
+                               error = _("your dreambox might be unusable now. Please consult the manual for further assistance before rebooting your dreambox.")
+                               if self.packages == 0:
+                                       error = _("No packages were upgraded yet. So you can check your network and try again.")
+                               if self.updating:
+                                       error = _("Your dreambox isn't connected to the internet properly. Please check it and try again.")
+                               self.status.setText(_("Error") +  " - " + error)
+               #print event, "-", param
+               pass
+
+       def modificationCallback(self, res):
+               self.ipkg.write(res and "N" or "Y")
+
+       def exit(self):
+               if not self.ipkg.isRunning():
+                       if self.packages != 0 and self.error == 0:
+                               self.session.openWithCallback(self.exitAnswer, MessageBox, _("Upgrade finished.") +" "+_("Do you want to reboot your Dreambox?"))
+                       else:
+                               self.close()
+                       
+       def exitAnswer(self, result):
+               if result is not None and result:
+                       quitMainloop(2)
+               self.close()
+
+
+
+class IpkgInstaller(Screen):
+       skin = """
+               <screen position="100,100" size="550,400" title="..." >
+                       <widget name="red" halign="center" valign="center" position="0,0" size="140,60" backgroundColor="red" font="Regular;21" />
+                       <widget name="green" halign="center" valign="center" position="140,0" text="Install selected" size="140,60" backgroundColor="green" font="Regular;21" />
+                       <widget name="yellow" halign="center" valign="center" position="280,0" size="140,60" backgroundColor="yellow" font="Regular;21" />
+                       <widget name="blue" halign="center" valign="center" position="420,0" size="140,60" backgroundColor="blue" font="Regular;21" />
+                       <widget name="list" position="0,60" size="550,360" />
+               </screen>
+               """
+       
+       def __init__(self, session, list):
+               self.skin = IpkgInstaller.skin
+               Screen.__init__(self, session)
+
+               self.list = SelectionList()
+               self["list"] = self.list
+               for listindex in range(len(list)):
+                       self.list.addSelection(list[listindex], list[listindex], listindex, True)
+
+               self["red"] = Label()
+               self["green"] = Label()
+               self["yellow"] = Label()
+               self["blue"] = Label()
+               
+               self["actions"] = ActionMap(["OkCancelActions", "ColorActions"], 
+               {
+                       "ok": self.list.toggleSelection, 
+                       "cancel": self.close, 
+                       "green": self.install
+               }, -1)
+               
+       def install(self):
+               list = self.list.getSelectionsList()
+               cmdList = []
+               for item in list:
+                       cmdList.append((IpkgComponent.CMD_INSTALL, { "package": item[1] }))
+               self.session.open(Ipkg, cmdList = cmdList)
+
+def filescan_open(list, session, **kwargs):
+       filelist = [x.path for x in list]
+       session.open(IpkgInstaller, filelist) # list
+
+def filescan(**kwargs):
+       from Components.Scanner import Scanner, ScanPath
+       return \
+               Scanner(mimetypes = ["application/x-debian-package"], 
+                       paths_to_scan = 
+                               [
+                                       ScanPath(path = "ipk", with_subdirs = True), 
+                                       ScanPath(path = "", with_subdirs = False), 
+                               ], 
+                       name = "Ipkg", 
+                       description = "Install software updates...", 
+                       openfnc = filescan_open, )
+
+def UpgradeMain(session, **kwargs):
+       session.open(UpdatePluginMenu)
+
+def startSetup(menuid):
+       if menuid != "setup": 
+               return [ ]
+       return [(_("Software manager") + "...", UpgradeMain, "software_manager", 50)]
+
+def Plugins(path, **kwargs):
+       global plugin_path
+       plugin_path = path
+       return [
+               PluginDescriptor(name=_("Software manager"), description=_("Manage your receiver's software"), where = PluginDescriptor.WHERE_MENU, fnc=startSetup), 
+               #PluginDescriptor(name=_("Software manager"), description=_("Manage your receiver's software"), icon="update.png", where = PluginDescriptor.WHERE_PLUGINMENU, fnc=UpgradeMain),
+               PluginDescriptor(name=_("Ipkg"), where = PluginDescriptor.WHERE_FILESCAN, fnc = filescan)
+       ]
diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/red.png b/lib/python/Plugins/SystemPlugins/SoftwareManager/red.png
new file mode 100755 (executable)
index 0000000..8096045
Binary files /dev/null and b/lib/python/Plugins/SystemPlugins/SoftwareManager/red.png differ
diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/update.png b/lib/python/Plugins/SystemPlugins/SoftwareManager/update.png
new file mode 100755 (executable)
index 0000000..0ece6c7
Binary files /dev/null and b/lib/python/Plugins/SystemPlugins/SoftwareManager/update.png differ
diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/upgradeable.png b/lib/python/Plugins/SystemPlugins/SoftwareManager/upgradeable.png
new file mode 100755 (executable)
index 0000000..edbbdee
Binary files /dev/null and b/lib/python/Plugins/SystemPlugins/SoftwareManager/upgradeable.png differ
diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/yellow.png b/lib/python/Plugins/SystemPlugins/SoftwareManager/yellow.png
new file mode 100755 (executable)
index 0000000..dacb80e
Binary files /dev/null and b/lib/python/Plugins/SystemPlugins/SoftwareManager/yellow.png differ
diff --git a/lib/python/Plugins/SystemPlugins/SoftwareUpdate/.cvsignore b/lib/python/Plugins/SystemPlugins/SoftwareUpdate/.cvsignore
deleted file mode 100644 (file)
index 138b9cc..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-*.pyc
-*.pyo
-Makefile
-Makefile.in
diff --git a/lib/python/Plugins/SystemPlugins/SoftwareUpdate/Makefile.am b/lib/python/Plugins/SystemPlugins/SoftwareUpdate/Makefile.am
deleted file mode 100644 (file)
index 9848f3d..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-installdir = $(LIBDIR)/enigma2/python/Plugins/SystemPlugins/SoftwareUpdate
-
-install_PYTHON =       \
-       __init__.py \
-       plugin.py       \
-       update.png 
-
diff --git a/lib/python/Plugins/SystemPlugins/SoftwareUpdate/__init__.py b/lib/python/Plugins/SystemPlugins/SoftwareUpdate/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/lib/python/Plugins/SystemPlugins/SoftwareUpdate/plugin.py b/lib/python/Plugins/SystemPlugins/SoftwareUpdate/plugin.py
deleted file mode 100644 (file)
index 8127514..0000000
+++ /dev/null
@@ -1,360 +0,0 @@
-from Components.ActionMap import ActionMap, NumberActionMap
-from Components.GUIComponent import GUIComponent
-from Components.Input import Input
-from Components.Ipkg import IpkgComponent
-from Components.Label import Label
-from Components.MenuList import MenuList
-from Components.Slider import Slider
-from Plugins.Plugin import PluginDescriptor
-from Screens.Console import Console
-from Screens.ImageWizard import ImageWizard
-from Screens.MessageBox import MessageBox
-from Screens.MessageBox import MessageBox
-from Screens.Screen import Screen
-from enigma import eTimer, quitMainloop, RT_HALIGN_LEFT, RT_VALIGN_CENTER, eListboxPythonMultiContent, eListbox, gFont
-from os import popen
-
-
-class UpdatePluginMenu(Screen):
-       skin = """
-               <screen position="200,100" size="300,250" title="Update..." >
-                       <widget name="menu" position="10,10" size="290,175" scrollbarMode="showOnDemand" />
-               </screen>"""
-               
-       def __init__(self, session, args = 0):
-               self.skin = UpdatePluginMenu.skin
-               Screen.__init__(self, session)
-               
-               self.menu = args
-               
-               list = []
-               if self.menu == 0:
-                       list.append((_("Image-Upgrade"), "image"))
-                       list.append((_("Online-Upgrade"), "upgrade"))
-                       list.append((_("Advanced"), "advanced"))
-               elif self.menu == 1:
-                       list.append((_("Choose source"), "source"))
-                       list.append((_("Packet management"), "ipkg"))
-                       list.append((_("Settings"), "setup"))
-               
-               self["menu"] = MenuList(list)
-                               
-               self["actions"] = ActionMap(["WizardActions", "DirectionActions"], 
-               {
-                       "ok": self.go,
-                       "back": self.close,
-               }, -1)
-               
-       def go(self):
-               if self.menu == 0:
-                       if (self["menu"].l.getCurrentSelection()[1] == "image"):
-                               self.session.open(ImageWizard)
-                       if (self["menu"].l.getCurrentSelection()[1] == "upgrade"):
-                               self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to update your Dreambox?\nAfter pressing OK, please wait!"))
-                       if (self["menu"].l.getCurrentSelection()[1] == "advanced"):
-                               self.session.open(UpdatePluginMenu, 1)
-               if self.menu == 1:
-                       if (self["menu"].l.getCurrentSelection()[1] == "source"):
-                               self.session.open(IPKGSource)
-                       elif (self["menu"].l.getCurrentSelection()[1] == "ipkg"):
-                               self.session.open(Ipkg)
-                       elif (self["menu"].l.getCurrentSelection()[1] == "setup"):
-                               self.session.open(MessageBox, _("Function not yet implemented"), MessageBox.TYPE_ERROR)
-       
-       def runUpgrade(self, result):
-               if result:
-                       self.session.open(Console, title = "Upgrade running...", cmdlist = ["ipkg update", "ipkg upgrade -force-defaults -force-overwrite"], finishedCallback = self.runFinished)
-
-       def runFinished(self):
-               self.session.openWithCallback(self.reboot, MessageBox, _("Upgrade finished. Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
-               
-       def reboot(self, result):
-               if result is None:
-                       return
-               if result:
-                       quitMainloop(3)
-
-class IPKGSource(Screen):
-       skin = """
-               <screen position="100,100" size="550,60" title="IPKG source" >
-                       <widget name="text" position="0,0" size="550,25" font="Regular;20" />
-               </screen>"""
-               
-       def __init__(self, session, args = None):
-               self.skin = IPKGSource.skin
-               Screen.__init__(self, session)
-               
-               fp = file('/etc/ipkg/official-feed.conf', 'r')
-               sources = fp.readlines()
-               fp.close()
-               
-               self["text"] = Input(sources[0], maxSize=False, type=Input.TEXT)
-                               
-               self["actions"] = NumberActionMap(["WizardActions", "InputActions", "TextEntryActions", "KeyboardInputActions"], 
-               {
-                       "ok": self.go,
-                       "back": self.close,
-                       "left": self.keyLeft,
-                       "right": self.keyRight,
-                       "home": self.keyHome,
-                       "end": self.keyEnd,
-                       "deleteForward": self.deleteForward,
-                       "deleteBackward": self.deleteBackward,
-                       "1": self.keyNumberGlobal,
-                       "2": self.keyNumberGlobal,
-                       "3": self.keyNumberGlobal,
-                       "4": self.keyNumberGlobal,
-                       "5": self.keyNumberGlobal,
-                       "6": self.keyNumberGlobal,
-                       "7": self.keyNumberGlobal,
-                       "8": self.keyNumberGlobal,
-                       "9": self.keyNumberGlobal,
-                       "0": self.keyNumberGlobal
-               }, -1)
-               
-       def go(self):
-               fp = file('/etc/ipkg/official-feed.conf', 'w')
-               fp.write(self["text"].getText())
-               fp.close()
-               self.close()
-               
-       def keyLeft(self):
-               self["text"].left()
-       
-       def keyRight(self):
-               self["text"].right()
-       
-       def keyHome(self):
-               self["text"].home()
-       
-       def keyEnd(self):
-               self["text"].end()
-       
-       def keyDeleteForward(self):
-               self["text"].delete()
-       
-       def keyDeleteBackward(self):
-               self["text"].deleteBackward()
-       
-       def keyNumberGlobal(self, number):
-               print "pressed", number
-               self["text"].number(number)
-
-def PacketEntryComponent(packet):
-       res = [ packet ]
-       
-       res.append((eListboxPythonMultiContent.TYPE_TEXT, 0, 0,250, 30, 0, RT_HALIGN_LEFT|RT_VALIGN_CENTER, packet[0]))
-       res.append((eListboxPythonMultiContent.TYPE_TEXT, 250, 0, 200, 30, 1, RT_HALIGN_LEFT|RT_VALIGN_CENTER, packet[1]))
-       res.append((eListboxPythonMultiContent.TYPE_TEXT, 450, 0, 100, 30, 1, RT_HALIGN_LEFT|RT_VALIGN_CENTER, packet[2]))
-       return res
-
-class PacketList(GUIComponent):
-       def __init__(self, list):
-               GUIComponent.__init__(self)
-               self.l = eListboxPythonMultiContent()
-               self.l.setList(list)
-               self.l.setFont(0, gFont("Regular", 20))
-               self.l.setFont(1, gFont("Regular", 18))
-       
-       def getCurrent(self):
-               return self.l.getCurrentSelection()
-       
-       def GUIcreate(self, parent):
-               self.instance = eListbox(parent)
-               self.instance.setContent(self.l)
-               self.instance.setItemHeight(30)
-       
-       def GUIdelete(self):
-               self.instance.setContent(None)
-               self.instance = None
-
-       def invalidate(self):
-               self.l.invalidate()
-
-class Ipkg2(Screen):
-       skin = """
-               <screen position="100,100" size="550,400" title="IPKG upgrade..." >
-                       <widget name="list" position="0,0" size="550,400" scrollbarMode="showOnDemand" />
-               </screen>"""
-               
-       def __init__(self, session, args = None):
-               self.skin = Ipkg.skin
-               Screen.__init__(self, session)
-       
-               list = []
-               self.list = list
-               self.fillPacketList()
-
-               self["list"] = PacketList(self.list)
-                               
-               self["actions"] = ActionMap(["WizardActions"], 
-               {
-                       "ok": self.close,
-                       "back": self.close
-               }, -1)
-               
-
-       def fillPacketList(self):
-               lines = popen("ipkg list", "r").readlines()
-               packetlist = []
-               for x in lines:
-                       split = x.split(' - ')
-                       packetlist.append([split[0].strip(), split[1].strip()])
-               
-               lines = popen("ipkg list_installed", "r").readlines()
-               
-               installedlist = {}
-               for x in lines:
-                       split = x.split(' - ')
-                       installedlist[split[0].strip()] = split[1].strip()
-               
-               for x in packetlist:
-                       status = ""
-                       if installedlist.has_key(x[0]):
-                               if installedlist[x[0]] == x[1]:
-                                       status = "installed"
-                               else:
-                                       status = "upgradable"
-                       self.list.append(PacketEntryComponent([x[0], x[1], status]))
-               
-       def go(self):
-               if self.update:
-                       self.session.openWithCallback(self.doUpdate, MessageBox, _("Do you want to update your Dreambox?\nAfter pressing OK, please wait!"))            
-               else:
-                       self.close()
-       
-       def doUpdateDelay(self):
-               lines = popen("ipkg update && ipkg upgrade", "r").readlines()
-               string = ""
-               for x in lines:
-                       string += x
-               self["text"].setText(_("Updating finished. Here is the result:") + "\n\n" + string)
-               self.update = False
-                       
-       
-       def doUpdate(self, val = False):
-               if val == True:
-                       self["text"].setText(_("Updating... Please wait... This can take some minutes..."))
-                       self.delayTimer.start(0, 1)
-               else:
-                       self.close()
-                       
-class UpdatePlugin(Screen):
-       skin = """
-               <screen position="100,100" size="550,200" title="Software Update..." >
-                       <widget name="activityslider" position="0,0" size="550,5"  />
-                       <widget name="slider" position="0,100" size="550,30"  />
-                       <widget name="package" position="10,30" size="540,20" font="Regular;18"/>
-                       <widget name="status" position="10,60" size="540,45" font="Regular;18"/>
-               </screen>"""
-               
-       def __init__(self, session, args = None):
-               self.skin = UpdatePlugin.skin
-               Screen.__init__(self, session)
-               
-               self.sliderPackages = { "dreambox-dvb-modules": 1, "enigma2": 2, "tuxbox-image-info": 3 }
-               
-               self.slider = Slider(0, 4)
-               self["slider"] = self.slider
-               self.activityslider = Slider(0, 100)
-               self["activityslider"] = self.activityslider
-               self.status = Label(_("Upgrading Dreambox... Please wait"))
-               self["status"] = self.status
-               self.package = Label()
-               self["package"] = self.package
-               
-               self.packages = 0
-               self.error = 0
-               
-               self.activity = 0
-               self.activityTimer = eTimer()
-               self.activityTimer.callback.append(self.doActivityTimer)
-               self.activityTimer.start(100, False)
-                               
-               self.ipkg = IpkgComponent()
-               self.ipkg.addCallback(self.ipkgCallback)
-               
-               self.updating = True
-               self.package.setText(_("Package list update"))
-               self.ipkg.startCmd(IpkgComponent.CMD_UPDATE)
-                       
-               self["actions"] = ActionMap(["WizardActions"], 
-               {
-                       "ok": self.exit,
-                       "back": self.exit
-               }, -1)
-               
-       def doActivityTimer(self):
-               self.activity += 1
-               if self.activity == 100:
-                       self.activity = 0
-               self.activityslider.setValue(self.activity)
-               
-       def ipkgCallback(self, event, param):
-               if event == IpkgComponent.EVENT_DOWNLOAD:
-                       self.status.setText(_("Downloading"))
-               elif event == IpkgComponent.EVENT_UPGRADE:
-                       if self.sliderPackages.has_key(param):
-                               self.slider.setValue(self.sliderPackages[param])
-                       self.package.setText(param)
-                       self.status.setText(_("Upgrading"))
-                       self.packages += 1
-               elif event == IpkgComponent.EVENT_INSTALL:
-                       self.package.setText(param)
-                       self.status.setText(_("Installing"))
-                       self.packages += 1
-               elif event == IpkgComponent.EVENT_CONFIGURING:
-                       self.package.setText(param)
-                       self.status.setText(_("Configuring"))
-               elif event == IpkgComponent.EVENT_MODIFIED:
-                       self.session.openWithCallback(
-                               self.modificationCallback,
-                               MessageBox,
-                               _("A configuration file (%s) was modified since Installation.\nDo you want to keep your version?") % (param)
-                       )
-               elif event == IpkgComponent.EVENT_ERROR:
-                       self.error += 1
-               elif event == IpkgComponent.EVENT_DONE:
-                       if self.updating:
-                               self.updating = False
-                               self.ipkg.startCmd(IpkgComponent.CMD_UPGRADE, args = {'test_only': False})
-                       elif self.error == 0:
-                               self.slider.setValue(4)
-                               
-                               self.activityTimer.stop()
-                               self.activityslider.setValue(0)
-                               
-                               self.package.setText("")
-                               self.status.setText(_("Done - Installed or upgraded %d packages") % self.packages)
-                       else:
-                               self.activityTimer.stop()
-                               self.activityslider.setValue(0)
-                               error = _("your dreambox might be unusable now. Please consult the manual for further assistance before rebooting your dreambox.")
-                               if self.packages == 0:
-                                       error = _("No packages were upgraded yet. So you can check your network and try again.")
-                               if self.updating:
-                                       error = _("Your dreambox isn't connected to the internet properly. Please check it and try again.")
-                               self.status.setText(_("Error") +  " - " + error)
-               #print event, "-", param
-               pass
-
-       def modificationCallback(self, res):
-               self.ipkg.write(res and "N" or "Y")
-
-       def exit(self):
-               if not self.ipkg.isRunning():
-                       if self.packages != 0 and self.error == 0:
-                               self.session.openWithCallback(self.exitAnswer, MessageBox, _("Upgrade finished. Do you want to reboot your Dreambox?"))
-                       else:
-                               self.close()
-                       
-       def exitAnswer(self, result):
-               if result is not None and result:
-                       quitMainloop(2)
-               self.close()
-
-def UpgradeMain(session, **kwargs):
-       session.open(UpdatePlugin)
-
-def Plugins(**kwargs):
-       return PluginDescriptor(name="Softwareupdate", description=_("Updates your receiver's software"), icon="update.png", where = PluginDescriptor.WHERE_PLUGINMENU, fnc=UpgradeMain)
diff --git a/lib/python/Plugins/SystemPlugins/SoftwareUpdate/update.png b/lib/python/Plugins/SystemPlugins/SoftwareUpdate/update.png
deleted file mode 100644 (file)
index 0ece6c7..0000000
Binary files a/lib/python/Plugins/SystemPlugins/SoftwareUpdate/update.png and /dev/null differ
diff --git a/lib/python/Screens/ImageWizard.py b/lib/python/Screens/ImageWizard.py
deleted file mode 100644 (file)
index faf6120..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-from Wizard import Wizard, wizardManager
-
-from Tools.Directories import fileExists
-
-import os
-
-backupfile = "backupenigma2settings.tar"
-
-def checkConfigBackup():
-       paths = ['/media/hdd/', '/media/cf/']
-       for x in paths:
-               if fileExists(x + backupfile):
-                       return x
-       return None
-
-if checkConfigBackup() is None:
-       backupAvailable = 0
-else:
-       backupAvailable = 1
-
-class ImageWizard(Wizard):
-       def __init__(self, session):
-               self.xmlfile = "imagewizard.xml"
-               Wizard.__init__(self, session, showSteps=False, showStepSlider=False, showList=True, showConfig=True)
-
-       def markDone(self):
-               pass
-
-wizardManager.registerWizard(ImageWizard, backupAvailable, priority = 10)
-
-def doBackup(path):
-       os.system('tar cvpf ' + path + backupfile + ' /etc/enigma2')
-
-def doRestore(path):
-       os.system('cd / && /bin/tar xvpf ' + path + backupfile)
-       
-
-               
\ No newline at end of file
old mode 100644 (file)
new mode 100755 (executable)
index eac0347..9687633
@@ -54,7 +54,7 @@ class Ipkg(Screen):
                        self.slider.setValue(len(self.cmdList))
                                
                        self.package.setText("")
-                       self.status.setText(_("Done - Installed or upgraded %d packages with %d errors") % (self.packages, self.error))
+                       self.status.setText(_("Done - Installed, upgraded or removed %d packages with %d errors") % (self.packages, self.error))
                        return False
                else:
                        cmd = self.cmdList[self.runningCmd]
@@ -90,6 +90,10 @@ class Ipkg(Screen):
                        self.package.setText(param)
                        self.status.setText(_("Installing"))
                        self.packages += 1
+               elif event == IpkgComponent.EVENT_REMOVE:
+                       self.package.setText(param)
+                       self.status.setText(_("Removing"))
+                       self.packages += 1
                elif event == IpkgComponent.EVENT_CONFIGURING:
                        self.package.setText(param)
                        self.status.setText(_("Configuring"))
index cde2d6c..00204a9 100755 (executable)
@@ -9,7 +9,7 @@ install_PYTHON = \
        InfoBarGenerics.py HelpMenu.py Wizard.py __init__.py \
        Dish.py LanguageSelection.py StartWizard.py PiPSetup.py Subtitles.py \
        TutorialWizard.py PluginBrowser.py MinuteInput.py Scart.py PVRState.py \
-       Console.py InputBox.py ChoiceBox.py SimpleSummary.py ImageWizard.py \
+       Console.py InputBox.py ChoiceBox.py SimpleSummary.py \
        TimerSelection.py PictureInPicture.py TimeDateInput.py \
        SubtitleDisplay.py SubservicesQuickzap.py ParentalControlSetup.py NumericalTextInputHelpDialog.py \
        SleepTimerEdit.py Ipkg.py RdsDisplay.py Globals.py DefaultWizard.py \
old mode 100644 (file)
new mode 100755 (executable)
index ee22e20..c335bf2
--- a/mytest.py
+++ b/mytest.py
@@ -76,7 +76,6 @@ from Components.PluginComponent import plugins
 profile("LOAD:Wizard")
 from Screens.Wizard import wizardManager
 from Screens.DefaultWizard import *
-from Screens.ImageWizard import *
 from Screens.StartWizard import *
 from Screens.TutorialWizard import *
 import Screens.Rc
old mode 100644 (file)
new mode 100755 (executable)
index 26518b5..986f0ae
@@ -30,6 +30,7 @@ enigma2.pot:
 
        ./xml2po.py     ../data/ >> enigma2.pot
        ./xml2po.py     ../lib/python/Plugins/SystemPlugins/Videomode/ >> enigma2.pot
+       ./xml2po.py     ../lib/python/Plugins/SystemPlugins/SoftwareManager/ >> enigma2.pot
        msguniq -o enigma2uniq.pot enigma2.pot
        $(RM) enigma2.pot
        mv enigma2uniq.pot enigma2.pot