DreamInfoHandler.py: no fatal error when no language element in info tag is found...
[enigma2.git] / lib / python / Components / DreamInfoHandler.py
old mode 100644 (file)
new mode 100755 (executable)
index 2f2e757..6cf3b00
@@ -1,11 +1,13 @@
+# -*- coding: iso-8859-1 -*-
 import xml.sax
 import xml.sax
-from Tools.Directories import crawlDirectory, resolveFilename, SCOPE_CONFIG, SCOPE_SKIN, copyfile, copytree
+from Tools.Directories import crawlDirectory, resolveFilename, SCOPE_CONFIG, SCOPE_SKIN, SCOPE_METADIR, copyfile, copytree
 from Components.NimManager import nimmanager
 from Components.Ipkg import IpkgComponent
 from Components.config import config, configfile
 from Tools.HardwareInfo import HardwareInfo
 from enigma import eConsoleAppContainer, eDVBDB
 import os
 from Components.NimManager import nimmanager
 from Components.Ipkg import IpkgComponent
 from Components.config import config, configfile
 from Tools.HardwareInfo import HardwareInfo
 from enigma import eConsoleAppContainer, eDVBDB
 import os
+from re import compile as re_compile, search as re_search, IGNORECASE
 
 class InfoHandlerParseError(Exception):
        def __init__(self, value):
 
 class InfoHandlerParseError(Exception):
        def __init__(self, value):
@@ -14,7 +16,7 @@ class InfoHandlerParseError(Exception):
                return repr(self.value)
 
 class InfoHandler(xml.sax.ContentHandler):
                return repr(self.value)
 
 class InfoHandler(xml.sax.ContentHandler):
-       def __init__(self, prerequisiteMet, directory):
+       def __init__(self, prerequisiteMet, directory, language = None):
                self.attributes = {}
                self.directory = directory
                self.list = []
                self.attributes = {}
                self.directory = directory
                self.list = []
@@ -23,29 +25,51 @@ class InfoHandler(xml.sax.ContentHandler):
                self.elements = []
                self.validFileTypes = ["skin", "config", "services", "favourites", "package"]
                self.prerequisitesMet = prerequisiteMet
                self.elements = []
                self.validFileTypes = ["skin", "config", "services", "favourites", "package"]
                self.prerequisitesMet = prerequisiteMet
-               
+               self.data = ""
+               self.language = language
+               self.translatedPackageInfos = {}
+               self.foundTranslation = None
+
        def printError(self, error):
                print "Error in defaults xml files:", error
                raise InfoHandlerParseError, error
        def printError(self, error):
                print "Error in defaults xml files:", error
                raise InfoHandlerParseError, error
-    
+
        def startElement(self, name, attrs):
                #print name, ":", attrs.items()
                self.elements.append(name)
        def startElement(self, name, attrs):
                #print name, ":", attrs.items()
                self.elements.append(name)
-               if name in ("hardware", "bcastsystem", "satellite", "tag"):
+
+               if name in ("hardware", "bcastsystem", "satellite", "tag", "flag"):
                        if not attrs.has_key("type"):
                                        self.printError(str(name) + " tag with no type attribute")
                        if not attrs.has_key("type"):
                                        self.printError(str(name) + " tag with no type attribute")
-                       if self.elements[-3] == "default":
+                       if self.elements[-3] in ("default", "package"):
                                prerequisites = self.globalprerequisites
                        else:
                                prerequisites = self.prerequisites
                        if not prerequisites.has_key(name):
                                prerequisites[name] = []
                        prerequisites[name].append(str(attrs["type"]))
                                prerequisites = self.globalprerequisites
                        else:
                                prerequisites = self.prerequisites
                        if not prerequisites.has_key(name):
                                prerequisites[name] = []
                        prerequisites[name].append(str(attrs["type"]))
+
+               if name == "info":
+                       self.foundTranslation = None
+                       self.data = ""
+                       if not attrs.has_key("language"):
+                                       print "info tag with no language attribute"
+                       else:
+                               if attrs["language"] == 'en': # read default translations
+                                       self.foundTranslation = False
+                                       self.data = ""
+                               elif attrs["language"] == self.language:
+                                       self.foundTranslation = True
+                                       self.data = ""
+
                if name == "files":
                        if attrs.has_key("type"):
                                if attrs["type"] == "directories":
                                        self.attributes["filestype"] = "directories"
                if name == "files":
                        if attrs.has_key("type"):
                                if attrs["type"] == "directories":
                                        self.attributes["filestype"] = "directories"
+                               elif attrs["type"] == "package":
+                                       self.attributes["filestype"] = "package"
                                # TODO add a compressed archive type
                                # TODO add a compressed archive type
+
                if name == "file":
                        self.prerequisites = {}
                        if not attrs.has_key("type"):
                if name == "file":
                        self.prerequisites = {}
                        if not attrs.has_key("type"):
@@ -62,8 +86,26 @@ class InfoHandler(xml.sax.ContentHandler):
                                        else:
                                                self.filetype = type
                                                self.fileattrs = attrs
                                        else:
                                                self.filetype = type
                                                self.fileattrs = attrs
+
+               if name == "package":
+                       if attrs.has_key("details"):
+                               self.attributes["details"] = str(attrs["details"])
+                       if attrs.has_key("name"):
+                               self.attributes["name"] = str(attrs["name"].encode("utf-8"))
+                       if attrs.has_key("packagename"):
+                               self.attributes["packagename"] = str(attrs["packagename"].encode("utf-8"))
+                       if attrs.has_key("shortdescription"):
+                               self.attributes["shortdescription"] = str(attrs["shortdescription"].encode("utf-8"))
+
+               if name == "screenshot":
+                       if attrs.has_key("src"):
+                               if self.foundTranslation is False:
+                                       self.attributes["screenshot"] = str(attrs["src"])
+                               elif self.foundTranslation is True:
+                                       self.translatedPackageInfos["screenshot"] = str(attrs["src"])
+
        def endElement(self, name):
        def endElement(self, name):
-               #print "end", name
+               #print "endElement", name
                #print "self.elements:", self.elements
                self.elements.pop()
                if name == "file":
                #print "self.elements:", self.elements
                self.elements.pop()
                if name == "file":
@@ -78,46 +120,75 @@ class InfoHandler(xml.sax.ContentHandler):
                                else:
                                        directory = self.directory
                                self.attributes[self.filetype].append({ "name": str(self.fileattrs["name"]), "directory": directory })
                                else:
                                        directory = self.directory
                                self.attributes[self.filetype].append({ "name": str(self.fileattrs["name"]), "directory": directory })
-    
-               if name == "default":
-                       self.list.append({"attributes": self.attributes, 'prerequisites': self.globalprerequisites})
+
+               if name in ( "default", "package" ):
+                       self.list.append({"attributes": self.attributes, 'prerequisites': self.globalprerequisites ,"translation": self.translatedPackageInfos})
                        self.attributes = {}
                        self.globalprerequisites = {}
                        self.attributes = {}
                        self.globalprerequisites = {}
-    
+
        def characters(self, data):
                if self.elements[-1] == "author":
                        self.attributes["author"] = str(data)
                if self.elements[-1] == "name":
                        self.attributes["name"] = str(data)
        def characters(self, data):
                if self.elements[-1] == "author":
                        self.attributes["author"] = str(data)
                if self.elements[-1] == "name":
                        self.attributes["name"] = str(data)
+               if self.foundTranslation is False:
+                       if self.elements[-1] == "author":
+                               self.attributes["author"] = str(data)
+                       if self.elements[-1] == "name":
+                               self.attributes["name"] = str(data)
+                       if self.elements[-1] == "packagename":
+                               self.attributes["packagename"] = str(data.encode("utf-8"))
+                       if self.elements[-1] == "shortdescription":
+                               self.attributes["shortdescription"] = str(data.encode("utf-8"))
+                       if self.elements[-1] == "description":
+                               self.data += data.strip()
+                               self.attributes["description"] = str(self.data.encode("utf-8"))
+               elif self.foundTranslation is True:
+                       if self.elements[-1] == "author":
+                               self.translatedPackageInfos["author"] = str(data)
+                       if self.elements[-1] == "name":
+                               self.translatedPackageInfos["name"] = str(data)
+                       if self.elements[-1] == "description":
+                               self.data += data.strip()
+                               self.translatedPackageInfos["description"] = str(self.data.encode("utf-8"))
+                       if self.elements[-1] == "name":
+                               self.translatedPackageInfos["name"] = str(data.encode("utf-8"))
+                       if self.elements[-1] == "shortdescription":
+                               self.translatedPackageInfos["shortdescription"] = str(data.encode("utf-8"))
                #print "characters", data
                #print "characters", data
-               
+
+
 class DreamInfoHandler:
        STATUS_WORKING = 0
        STATUS_DONE = 1
        STATUS_ERROR = 2
        STATUS_INIT = 4
 class DreamInfoHandler:
        STATUS_WORKING = 0
        STATUS_DONE = 1
        STATUS_ERROR = 2
        STATUS_INIT = 4
-       
-       def __init__(self, statusCallback, blocking = False, neededTag = None):
+
+       def __init__(self, statusCallback, blocking = False, neededTag = None, neededFlag = None, language = None):
                self.hardware_info = HardwareInfo()
                self.directory = "/"
                self.hardware_info = HardwareInfo()
                self.directory = "/"
-               
+
                self.neededTag = neededTag
                self.neededTag = neededTag
-               
+               self.neededFlag = neededFlag
+               self.language = language
+
                # caution: blocking should only be used, if further execution in enigma2 depends on the outcome of
                # the installer!
                self.blocking = blocking
                # caution: blocking should only be used, if further execution in enigma2 depends on the outcome of
                # the installer!
                self.blocking = blocking
-               
+
                self.currentlyInstallingMetaIndex = None
                self.currentlyInstallingMetaIndex = None
-               
+
                self.console = eConsoleAppContainer()
                self.console.appClosed.append(self.installNext)
                self.reloadFavourites = False
                self.console = eConsoleAppContainer()
                self.console.appClosed.append(self.installNext)
                self.reloadFavourites = False
-               
+
                self.statusCallback = statusCallback
                self.setStatus(self.STATUS_INIT)
                self.statusCallback = statusCallback
                self.setStatus(self.STATUS_INIT)
-                               
+
                self.packageslist = []
                self.packageslist = []
-                       
+               self.packagesIndexlist = []
+               self.packageDetails = []
+
        def readInfo(self, directory, file):
                print "Reading .info file", file
                handler = InfoHandler(self.prerequisiteMet, directory)
        def readInfo(self, directory, file):
                print "Reading .info file", file
                handler = InfoHandler(self.prerequisiteMet, directory)
@@ -127,26 +198,89 @@ class DreamInfoHandler:
                                self.packageslist.append((entry,file)) 
                except InfoHandlerParseError:
                        print "file", file, "ignored due to errors in the file"
                                self.packageslist.append((entry,file)) 
                except InfoHandlerParseError:
                        print "file", file, "ignored due to errors in the file"
-               print handler.list
-        
+               #print handler.list
+
+       def readIndex(self, directory, file):
+               print "Reading .xml meta index file", file
+               handler = InfoHandler(self.prerequisiteMet, directory, self.language)
+               try:
+                       xml.sax.parse(file, handler)
+                       for entry in handler.list:
+                               self.packagesIndexlist.append((entry,file))
+               except InfoHandlerParseError:
+                       print "file", file, "ignored due to errors in the file"
+               #print handler.list
+
+       def readDetails(self, directory, file):
+               self.packageDetails = []
+               print "Reading .xml meta details file", file
+               handler = InfoHandler(self.prerequisiteMet, directory, self.language)
+               try:
+                       xml.sax.parse(file, handler)
+                       for entry in handler.list:
+                               self.packageDetails.append((entry,file))
+               except InfoHandlerParseError:
+                       print "file", file, "ignored due to errors in the file"
+               #print handler.list
+
+
        # prerequisites = True: give only packages matching the prerequisites
        def fillPackagesList(self, prerequisites = True):
                self.packageslist = []
                packages = []
                if not isinstance(self.directory, list):
                        self.directory = [self.directory]
        # prerequisites = True: give only packages matching the prerequisites
        def fillPackagesList(self, prerequisites = True):
                self.packageslist = []
                packages = []
                if not isinstance(self.directory, list):
                        self.directory = [self.directory]
-               
+
                for directory in self.directory:
                        packages += crawlDirectory(directory, ".*\.info$")
 
                for package in packages:
                        self.readInfo(package[0] + "/", package[0] + "/" + package[1])
                for directory in self.directory:
                        packages += crawlDirectory(directory, ".*\.info$")
 
                for package in packages:
                        self.readInfo(package[0] + "/", package[0] + "/" + package[1])
-                       
+
                if prerequisites:
                        for package in self.packageslist[:]:
                                if not self.prerequisiteMet(package[0]["prerequisites"]):
                                        self.packageslist.remove(package)
                return self.packageslist
                if prerequisites:
                        for package in self.packageslist[:]:
                                if not self.prerequisiteMet(package[0]["prerequisites"]):
                                        self.packageslist.remove(package)
                return self.packageslist
+
+       # prerequisites = True: give only packages matching the prerequisites
+       def fillPackagesIndexList(self, prerequisites = True):
+               self.packagesIndexlist = []
+               indexfileList = []
+
+               if not isinstance(self.directory, list):
+                       self.directory = [self.directory]
+
+               for indexfile in os.listdir(self.directory[0]):
+                       if indexfile.startswith("index"):
+                               if os.path.splitext(indexfile)[0][-3:-2] is not "_": #we first catch all non translated indexfiles
+                                       indexfileList.append(os.path.splitext(indexfile)[0])
+
+               if len(indexfileList):
+                       for file in indexfileList:
+                               neededFile = self.directory[0] + "/" + file
+                               if self.language is not None:
+                                       if os.path.exists(neededFile + '_' + self.language + '.xml' ):
+                                               #print "translated index file found",neededFile + '_' + self.language + '.xml'
+                                               self.readIndex(self.directory[0] + "/", neededFile + '_' + self.language + '.xml')
+                                       else:
+                                               #print "reading original index file"
+                                               self.readIndex(self.directory[0] + "/", neededFile + '.xml')
+
+               if prerequisites:
+                       for package in self.packagesIndexlist[:]:
+                               if not self.prerequisiteMet(package[0]["prerequisites"]):
+                                       self.packagesIndexlist.remove(package)
+               return self.packagesIndexlist
+
+       # prerequisites = True: give only packages matching the prerequisites
+       def fillPackageDetails(self, details = None):
+               self.packageDetails = []
+               detailsfile = details
+               if not isinstance(self.directory, list):
+                       self.directory = [self.directory]
+               self.readDetails(self.directory[0] + "/", self.directory[0] + "/" + detailsfile)
+               return self.packageDetails
                        
        def prerequisiteMet(self, prerequisites):
                # TODO: we need to implement a hardware detection here...
                        
        def prerequisiteMet(self, prerequisites):
                # TODO: we need to implement a hardware detection here...
@@ -155,12 +289,24 @@ class DreamInfoHandler:
                if self.neededTag is None:
                        if prerequisites.has_key("tag"):
                                return False
                if self.neededTag is None:
                        if prerequisites.has_key("tag"):
                                return False
+               elif self.neededTag == 'ALL_TAGS':
+                               return True
                else:
                        if prerequisites.has_key("tag"):
                                if not self.neededTag in prerequisites["tag"]:
                                        return False
                        else:
                                return False
                else:
                        if prerequisites.has_key("tag"):
                                if not self.neededTag in prerequisites["tag"]:
                                        return False
                        else:
                                return False
+
+               if self.neededFlag is None:
+                       if prerequisites.has_key("flag"):
+                               return False
+               else:
+                       if prerequisites.has_key("flag"):
+                               if not self.neededFlag in prerequisites["flag"]:
+                                       return False
+                       else:
+                               return True # No flag found, assuming all flags valid
                                
                if prerequisites.has_key("satellite"):
                        for sat in prerequisites["satellite"]:
                                
                if prerequisites.has_key("satellite"):
                        for sat in prerequisites["satellite"]: