1 # -*- coding: iso-8859-1 -*-
3 from Tools.Directories import crawlDirectory, resolveFilename, SCOPE_CONFIG, SCOPE_SKIN, SCOPE_METADIR, copyfile, copytree
4 from Components.NimManager import nimmanager
5 from Components.Ipkg import IpkgComponent
6 from Components.config import config, configfile
7 from Tools.HardwareInfo import HardwareInfo
8 from enigma import eConsoleAppContainer, eDVBDB
10 from re import compile as re_compile, search as re_search, IGNORECASE
12 class InfoHandlerParseError(Exception):
13 def __init__(self, value):
16 return repr(self.value)
18 class InfoHandler(xml.sax.ContentHandler):
19 def __init__(self, prerequisiteMet, directory, language = None):
21 self.directory = directory
23 self.globalprerequisites = {}
24 self.prerequisites = {}
26 self.validFileTypes = ["skin", "config", "services", "favourites", "package"]
27 self.prerequisitesMet = prerequisiteMet
29 self.language = language
30 self.translatedPackageInfos = {}
31 self.foundTranslation = None
33 def printError(self, error):
34 print "Error in defaults xml files:", error
35 raise InfoHandlerParseError, error
37 def startElement(self, name, attrs):
38 #print name, ":", attrs.items()
39 self.elements.append(name)
41 if name in ("hardware", "bcastsystem", "satellite", "tag", "flag"):
42 if not attrs.has_key("type"):
43 self.printError(str(name) + " tag with no type attribute")
44 if self.elements[-3] in ("default", "package"):
45 prerequisites = self.globalprerequisites
47 prerequisites = self.prerequisites
48 if not prerequisites.has_key(name):
49 prerequisites[name] = []
50 prerequisites[name].append(str(attrs["type"]))
53 if not attrs.has_key("language"):
54 self.printError(str(name) + " tag with no language attribute")
56 if attrs["language"] == 'en': # read default translations
57 self.foundTranslation = False
59 elif attrs["language"] == self.language:
60 self.foundTranslation = True
63 self.foundTranslation = None
67 if attrs.has_key("type"):
68 if attrs["type"] == "directories":
69 self.attributes["filestype"] = "directories"
70 elif attrs["type"] == "package":
71 self.attributes["filestype"] = "package"
72 # TODO add a compressed archive type
75 self.prerequisites = {}
76 if not attrs.has_key("type"):
77 self.printError("file tag with no type attribute")
79 if not attrs.has_key("name"):
80 self.printError("file tag with no name attribute")
82 if not attrs.has_key("directory"):
83 directory = self.directory
85 if not type in self.validFileTypes:
86 self.printError("file tag with invalid type attribute")
89 self.fileattrs = attrs
92 if attrs.has_key("details"):
93 self.attributes["details"] = str(attrs["details"])
94 if attrs.has_key("name"):
95 self.attributes["name"] = str(attrs["name"].encode("utf-8"))
96 if attrs.has_key("packagename"):
97 self.attributes["packagename"] = str(attrs["packagename"].encode("utf-8"))
98 if attrs.has_key("shortdescription"):
99 self.attributes["shortdescription"] = str(attrs["shortdescription"].encode("utf-8"))
101 if name == "screenshot":
102 if attrs.has_key("src"):
103 if self.foundTranslation is False:
104 self.attributes["screenshot"] = str(attrs["src"])
105 elif self.foundTranslation is True:
106 self.translatedPackageInfos["screenshot"] = str(attrs["src"])
108 def endElement(self, name):
109 #print "endElement", name
110 #print "self.elements:", self.elements
113 #print "prerequisites:", self.prerequisites
114 if len(self.prerequisites) == 0 or self.prerequisitesMet(self.prerequisites):
115 if not self.attributes.has_key(self.filetype):
116 self.attributes[self.filetype] = []
117 if self.fileattrs.has_key("directory"):
118 directory = str(self.fileattrs["directory"])
119 if len(directory) < 1 or directory[0] != "/":
120 directory = self.directory + directory
122 directory = self.directory
123 self.attributes[self.filetype].append({ "name": str(self.fileattrs["name"]), "directory": directory })
125 if name in ( "default", "package" ):
126 self.list.append({"attributes": self.attributes, 'prerequisites': self.globalprerequisites ,"translation": self.translatedPackageInfos})
128 self.globalprerequisites = {}
130 def characters(self, data):
131 if self.elements[-1] == "author":
132 self.attributes["author"] = str(data)
133 if self.elements[-1] == "name":
134 self.attributes["name"] = str(data)
135 if self.foundTranslation is False:
136 if self.elements[-1] == "author":
137 self.attributes["author"] = str(data)
138 if self.elements[-1] == "name":
139 self.attributes["name"] = str(data)
140 if self.elements[-1] == "packagename":
141 self.attributes["packagename"] = str(data.encode("utf-8"))
142 if self.elements[-1] == "shortdescription":
143 self.attributes["shortdescription"] = str(data.encode("utf-8"))
144 if self.elements[-1] == "description":
145 self.data += data.strip()
146 self.attributes["description"] = str(self.data.encode("utf-8"))
147 elif self.foundTranslation is True:
148 if self.elements[-1] == "author":
149 self.translatedPackageInfos["author"] = str(data)
150 if self.elements[-1] == "name":
151 self.translatedPackageInfos["name"] = str(data)
152 if self.elements[-1] == "description":
153 self.data += data.strip()
154 self.translatedPackageInfos["description"] = str(self.data.encode("utf-8"))
155 if self.elements[-1] == "name":
156 self.translatedPackageInfos["name"] = str(data.encode("utf-8"))
157 if self.elements[-1] == "shortdescription":
158 self.translatedPackageInfos["shortdescription"] = str(data.encode("utf-8"))
159 #print "characters", data
162 class DreamInfoHandler:
168 def __init__(self, statusCallback, blocking = False, neededTag = None, neededFlag = None, language = None):
169 self.hardware_info = HardwareInfo()
172 self.neededTag = neededTag
173 self.neededFlag = neededFlag
174 self.language = language
176 # caution: blocking should only be used, if further execution in enigma2 depends on the outcome of
178 self.blocking = blocking
180 self.currentlyInstallingMetaIndex = None
182 self.console = eConsoleAppContainer()
183 self.console.appClosed.append(self.installNext)
184 self.reloadFavourites = False
186 self.statusCallback = statusCallback
187 self.setStatus(self.STATUS_INIT)
189 self.packageslist = []
190 self.packagesIndexlist = []
191 self.packageDetails = []
193 def readInfo(self, directory, file):
194 print "Reading .info file", file
195 handler = InfoHandler(self.prerequisiteMet, directory)
197 xml.sax.parse(file, handler)
198 for entry in handler.list:
199 self.packageslist.append((entry,file))
200 except InfoHandlerParseError:
201 print "file", file, "ignored due to errors in the file"
204 def readIndex(self, directory, file):
205 print "Reading .xml meta index file", file
206 handler = InfoHandler(self.prerequisiteMet, directory, self.language)
208 xml.sax.parse(file, handler)
209 for entry in handler.list:
210 self.packagesIndexlist.append((entry,file))
211 except InfoHandlerParseError:
212 print "file", file, "ignored due to errors in the file"
215 def readDetails(self, directory, file):
216 self.packageDetails = []
217 print "Reading .xml meta details file", file
218 handler = InfoHandler(self.prerequisiteMet, directory, self.language)
220 xml.sax.parse(file, handler)
221 for entry in handler.list:
222 self.packageDetails.append((entry,file))
223 except InfoHandlerParseError:
224 print "file", file, "ignored due to errors in the file"
228 # prerequisites = True: give only packages matching the prerequisites
229 def fillPackagesList(self, prerequisites = True):
230 self.packageslist = []
232 if not isinstance(self.directory, list):
233 self.directory = [self.directory]
235 for directory in self.directory:
236 packages += crawlDirectory(directory, ".*\.info$")
238 for package in packages:
239 self.readInfo(package[0] + "/", package[0] + "/" + package[1])
242 for package in self.packageslist[:]:
243 if not self.prerequisiteMet(package[0]["prerequisites"]):
244 self.packageslist.remove(package)
245 return self.packageslist
247 # prerequisites = True: give only packages matching the prerequisites
248 def fillPackagesIndexList(self, prerequisites = True):
249 self.packagesIndexlist = []
252 if not isinstance(self.directory, list):
253 self.directory = [self.directory]
255 for indexfile in os.listdir(self.directory[0]):
256 if indexfile.startswith("index"):
257 if os.path.splitext(indexfile)[0][-3:-2] is not "_": #we first catch all non translated indexfiles
258 indexfileList.append(os.path.splitext(indexfile)[0])
260 if len(indexfileList):
261 for file in indexfileList:
262 neededFile = self.directory[0] + "/" + file
263 if self.language is not None:
264 if os.path.exists(neededFile + '_' + self.language + '.xml' ):
265 #print "translated index file found",neededFile + '_' + self.language + '.xml'
266 self.readIndex(self.directory[0] + "/", neededFile + '_' + self.language + '.xml')
268 #print "reading original index file"
269 self.readIndex(self.directory[0] + "/", neededFile + '.xml')
272 for package in self.packagesIndexlist[:]:
273 if not self.prerequisiteMet(package[0]["prerequisites"]):
274 self.packagesIndexlist.remove(package)
275 return self.packagesIndexlist
277 # prerequisites = True: give only packages matching the prerequisites
278 def fillPackageDetails(self, details = None):
279 self.packageDetails = []
280 detailsfile = details
281 if not isinstance(self.directory, list):
282 self.directory = [self.directory]
283 self.readDetails(self.directory[0] + "/", self.directory[0] + "/" + detailsfile)
284 return self.packageDetails
286 def prerequisiteMet(self, prerequisites):
287 # TODO: we need to implement a hardware detection here...
288 print "prerequisites:", prerequisites
290 if self.neededTag is None:
291 if prerequisites.has_key("tag"):
293 elif self.neededTag == 'ALL_TAGS':
296 if prerequisites.has_key("tag"):
297 if not self.neededTag in prerequisites["tag"]:
302 if self.neededFlag is None:
303 if prerequisites.has_key("flag"):
306 if prerequisites.has_key("flag"):
307 if not self.neededFlag in prerequisites["flag"]:
310 return True # No flag found, assuming all flags valid
312 if prerequisites.has_key("satellite"):
313 for sat in prerequisites["satellite"]:
314 if int(sat) not in nimmanager.getConfiguredSats():
316 if prerequisites.has_key("bcastsystem"):
318 for bcastsystem in prerequisites["bcastsystem"]:
319 if nimmanager.hasNimType(bcastsystem):
323 if prerequisites.has_key("hardware"):
324 hardware_found = False
325 for hardware in prerequisites["hardware"]:
326 if hardware == self.hardware_info.device_name:
327 hardware_found = True
328 if not hardware_found:
332 def installPackages(self, indexes):
333 print "installing packages", indexes
334 if len(indexes) == 0:
335 self.setStatus(self.STATUS_DONE)
337 self.installIndexes = indexes
338 print "+++++++++++++++++++++++bla"
339 self.currentlyInstallingMetaIndex = 0
340 self.installPackage(self.installIndexes[self.currentlyInstallingMetaIndex])
342 def installPackage(self, index):
343 print "self.packageslist:", self.packageslist
344 if len(self.packageslist) <= index:
345 print "no package with index", index, "found... installing nothing"
347 print "installing package with index", index, "and name", self.packageslist[index][0]["attributes"]["name"]
349 attributes = self.packageslist[index][0]["attributes"]
350 self.installingAttributes = attributes
351 self.attributeNames = ["skin", "config", "favourites", "package", "services"]
352 self.currentAttributeIndex = 0
353 self.currentIndex = -1
356 def setStatus(self, status):
358 self.statusCallback(self.status, None)
360 def installNext(self, *args, **kwargs):
361 if self.reloadFavourites:
362 self.reloadFavourites = False
363 db = eDVBDB.getInstance().reloadBouquets()
365 self.currentIndex += 1
366 attributes = self.installingAttributes
367 #print "attributes:", attributes
369 if self.currentAttributeIndex >= len(self.attributeNames): # end of package reached
370 print "end of package reached"
371 if self.currentlyInstallingMetaIndex is None or self.currentlyInstallingMetaIndex >= len(self.installIndexes) - 1:
372 print "set status to DONE"
373 self.setStatus(self.STATUS_DONE)
376 print "increment meta index to install next package"
377 self.currentlyInstallingMetaIndex += 1
378 self.currentAttributeIndex = 0
379 self.installPackage(self.installIndexes[self.currentlyInstallingMetaIndex])
382 self.setStatus(self.STATUS_WORKING)
384 print "currentAttributeIndex:", self.currentAttributeIndex
385 currentAttribute = self.attributeNames[self.currentAttributeIndex]
387 print "installing", currentAttribute, "with index", self.currentIndex
389 if attributes.has_key(currentAttribute):
390 if self.currentIndex >= len(attributes[currentAttribute]): # all jobs done for current attribute
391 self.currentIndex = -1
392 self.currentAttributeIndex += 1
395 else: # nothing to install here
396 self.currentIndex = -1
397 self.currentAttributeIndex += 1
401 if currentAttribute == "skin":
402 skin = attributes["skin"][self.currentIndex]
403 self.installSkin(skin["directory"], skin["name"])
404 elif currentAttribute == "config":
405 if self.currentIndex == 0:
406 from Components.config import configfile
408 config = attributes["config"][self.currentIndex]
409 self.mergeConfig(config["directory"], config["name"])
410 elif currentAttribute == "favourites":
411 favourite = attributes["favourites"][self.currentIndex]
412 self.installFavourites(favourite["directory"], favourite["name"])
413 elif currentAttribute == "package":
414 package = attributes["package"][self.currentIndex]
415 self.installIPK(package["directory"], package["name"])
416 elif currentAttribute == "services":
417 service = attributes["services"][self.currentIndex]
418 self.mergeServices(service["directory"], service["name"])
420 def readfile(self, filename):
421 if not os.path.isfile(filename):
424 lines = fd.readlines()
428 def mergeConfig(self, directory, name, merge = True):
429 print "merging config:", directory, " - ", name
430 if os.path.isfile(directory + name):
431 config.loadFromFile(directory + name)
435 def installIPK(self, directory, name):
437 os.system("ipkg install " + directory + name)
440 self.ipkg = IpkgComponent()
441 self.ipkg.addCallback(self.ipkgCallback)
442 self.ipkg.startCmd(IpkgComponent.CMD_INSTALL, {'package': directory + name})
444 def ipkgCallback(self, event, param):
446 if event == IpkgComponent.EVENT_DONE:
448 elif event == IpkgComponent.EVENT_ERROR:
451 def installSkin(self, directory, name):
452 print "installing skin:", directory, " - ", name
453 print "cp -a %s %s" % (directory, resolveFilename(SCOPE_SKIN))
455 copytree(directory, resolveFilename(SCOPE_SKIN))
458 if self.console.execute("cp -a %s %s" % (directory, resolveFilename(SCOPE_SKIN))):
459 print "execute failed"
462 def mergeServices(self, directory, name, merge = False):
463 print "merging services:", directory, " - ", name
464 if os.path.isfile(directory + name):
465 db = eDVBDB.getInstance()
466 db.reloadServicelist()
467 db.loadServicelist(directory + name)
471 def installFavourites(self, directory, name):
472 print "installing favourites:", directory, " - ", name
473 self.reloadFavourites = True
476 copyfile(directory + name, resolveFilename(SCOPE_CONFIG))
479 if self.console.execute("cp %s %s" % ((directory + name), resolveFilename(SCOPE_CONFIG))):
480 print "execute failed"