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):
21 self.directory = directory
23 self.globalprerequisites = {}
24 self.prerequisites = {}
26 self.validFileTypes = ["skin", "config", "services", "favourites", "package"]
27 self.prerequisitesMet = prerequisiteMet
30 def printError(self, error):
31 print "Error in defaults xml files:", error
32 raise InfoHandlerParseError, error
34 def startElement(self, name, attrs):
35 #print name, ":", attrs.items()
36 self.elements.append(name)
38 if name in ("hardware", "bcastsystem", "satellite", "tag", "flag"):
39 if not attrs.has_key("type"):
40 self.printError(str(name) + " tag with no type attribute")
41 if self.elements[-3] in ("default", "package"):
42 prerequisites = self.globalprerequisites
44 prerequisites = self.prerequisites
45 if not prerequisites.has_key(name):
46 prerequisites[name] = []
47 prerequisites[name].append(str(attrs["type"]))
50 self.foundTranslation = None
54 if attrs.has_key("type"):
55 if attrs["type"] == "directories":
56 self.attributes["filestype"] = "directories"
57 elif attrs["type"] == "package":
58 self.attributes["filestype"] = "package"
59 # TODO add a compressed archive type
62 self.prerequisites = {}
63 if not attrs.has_key("type"):
64 self.printError("file tag with no type attribute")
66 if not attrs.has_key("name"):
67 self.printError("file tag with no name attribute")
69 if not attrs.has_key("directory"):
70 directory = self.directory
72 if not type in self.validFileTypes:
73 self.printError("file tag with invalid type attribute")
76 self.fileattrs = attrs
79 if attrs.has_key("details"):
80 self.attributes["details"] = str(attrs["details"])
81 if attrs.has_key("name"):
82 self.attributes["name"] = str(attrs["name"])
83 if attrs.has_key("packagename"):
84 self.attributes["packagename"] = str(attrs["packagename"])
85 if attrs.has_key("packagetype"):
86 self.attributes["packagetype"] = str(attrs["packagetype"])
87 if attrs.has_key("needsRestart"):
88 self.attributes["needsRestart"] = str(attrs["needsRestart"])
89 if attrs.has_key("shortdescription"):
90 self.attributes["shortdescription"] = str(attrs["shortdescription"])
92 if name == "screenshot":
93 if attrs.has_key("src"):
94 self.attributes["screenshot"] = str(attrs["src"])
96 def endElement(self, name):
97 #print "endElement", name
98 #print "self.elements:", self.elements
101 #print "prerequisites:", self.prerequisites
102 if len(self.prerequisites) == 0 or self.prerequisitesMet(self.prerequisites):
103 if not self.attributes.has_key(self.filetype):
104 self.attributes[self.filetype] = []
105 if self.fileattrs.has_key("directory"):
106 directory = str(self.fileattrs["directory"])
107 if len(directory) < 1 or directory[0] != "/":
108 directory = self.directory + directory
110 directory = self.directory
111 self.attributes[self.filetype].append({ "name": str(self.fileattrs["name"]), "directory": directory })
113 if name in ( "default", "package" ):
114 self.list.append({"attributes": self.attributes, 'prerequisites': self.globalprerequisites})
116 self.globalprerequisites = {}
118 def characters(self, data):
119 if self.elements[-1] == "author":
120 self.attributes["author"] = str(data)
121 if self.elements[-1] == "name":
122 self.attributes["name"] = str(data)
123 if self.elements[-1] == "packagename":
124 self.attributes["packagename"] = str(data)
125 if self.elements[-1] == "needsRestart":
126 self.attributes["needsRestart"] = str(data)
127 if self.elements[-1] == "shortdescription":
128 self.attributes["shortdescription"] = str(data)
129 if self.elements[-1] == "description":
130 self.data += data.strip()
131 self.attributes["description"] = str(self.data)
132 #print "characters", data
135 class DreamInfoHandler:
141 def __init__(self, statusCallback, blocking = False, neededTag = None, neededFlag = None):
142 self.hardware_info = HardwareInfo()
145 self.neededTag = neededTag
146 self.neededFlag = neededFlag
148 # caution: blocking should only be used, if further execution in enigma2 depends on the outcome of
150 self.blocking = blocking
152 self.currentlyInstallingMetaIndex = None
154 self.console = eConsoleAppContainer()
155 self.console.appClosed.append(self.installNext)
156 self.reloadFavourites = False
158 self.statusCallback = statusCallback
159 self.setStatus(self.STATUS_INIT)
161 self.packageslist = []
162 self.packagesIndexlist = []
163 self.packageDetails = []
165 def readInfo(self, directory, file):
166 print "Reading .info file", file
167 handler = InfoHandler(self.prerequisiteMet, directory)
169 xml.sax.parse(file, handler)
170 for entry in handler.list:
171 self.packageslist.append((entry,file))
172 except InfoHandlerParseError:
173 print "file", file, "ignored due to errors in the file"
176 def readIndex(self, directory, file):
177 print "Reading .xml meta index file", directory, file
178 handler = InfoHandler(self.prerequisiteMet, directory)
180 xml.sax.parse(file, handler)
181 for entry in handler.list:
182 self.packagesIndexlist.append((entry,file))
183 except InfoHandlerParseError:
184 print "file", file, "ignored due to errors in the file"
187 def readDetails(self, directory, file):
188 self.packageDetails = []
189 print "Reading .xml meta details file", file
190 handler = InfoHandler(self.prerequisiteMet, directory)
192 xml.sax.parse(file, handler)
193 for entry in handler.list:
194 self.packageDetails.append((entry,file))
195 except InfoHandlerParseError:
196 print "file", file, "ignored due to errors in the file"
199 # prerequisites = True: give only packages matching the prerequisites
200 def fillPackagesList(self, prerequisites = True):
201 self.packageslist = []
203 if not isinstance(self.directory, list):
204 self.directory = [self.directory]
206 for directory in self.directory:
207 packages += crawlDirectory(directory, ".*\.info$")
209 for package in packages:
210 self.readInfo(package[0] + "/", package[0] + "/" + package[1])
213 for package in self.packageslist[:]:
214 if not self.prerequisiteMet(package[0]["prerequisites"]):
215 self.packageslist.remove(package)
216 return self.packageslist
218 # prerequisites = True: give only packages matching the prerequisites
219 def fillPackagesIndexList(self, prerequisites = True):
220 self.packagesIndexlist = []
223 if not isinstance(self.directory, list):
224 self.directory = [self.directory]
226 for indexfile in os.listdir(self.directory[0]):
227 if indexfile.startswith("index-"):
228 if indexfile.endswith(".xml"):
229 if indexfile[-7:-6] == "_":
231 indexfileList.append(indexfile)
232 if len(indexfileList):
233 for file in indexfileList:
234 neededFile = self.directory[0] + "/" + file
235 if os.path.isfile(neededFile):
236 self.readIndex(self.directory[0] + "/" , neededFile)
239 for package in self.packagesIndexlist[:]:
240 if not self.prerequisiteMet(package[0]["prerequisites"]):
241 self.packagesIndexlist.remove(package)
242 return self.packagesIndexlist
244 # prerequisites = True: give only packages matching the prerequisites
245 def fillPackageDetails(self, details = None):
246 self.packageDetails = []
247 detailsfile = details
248 if not isinstance(self.directory, list):
249 self.directory = [self.directory]
250 self.readDetails(self.directory[0] + "/", self.directory[0] + "/" + detailsfile)
251 return self.packageDetails
253 def prerequisiteMet(self, prerequisites):
254 # TODO: we need to implement a hardware detection here...
255 print "prerequisites:", prerequisites
257 if self.neededTag is None:
258 if prerequisites.has_key("tag"):
260 elif self.neededTag == 'ALL_TAGS':
263 if prerequisites.has_key("tag"):
264 if not self.neededTag in prerequisites["tag"]:
269 if self.neededFlag is None:
270 if prerequisites.has_key("flag"):
273 if prerequisites.has_key("flag"):
274 if not self.neededFlag in prerequisites["flag"]:
277 return True # No flag found, assuming all flags valid
279 if prerequisites.has_key("satellite"):
280 for sat in prerequisites["satellite"]:
281 if int(sat) not in nimmanager.getConfiguredSats():
283 if prerequisites.has_key("bcastsystem"):
285 for bcastsystem in prerequisites["bcastsystem"]:
286 if nimmanager.hasNimType(bcastsystem):
290 if prerequisites.has_key("hardware"):
291 hardware_found = False
292 for hardware in prerequisites["hardware"]:
293 if hardware == self.hardware_info.device_name:
294 hardware_found = True
295 if not hardware_found:
299 def installPackages(self, indexes):
300 print "installing packages", indexes
301 if len(indexes) == 0:
302 self.setStatus(self.STATUS_DONE)
304 self.installIndexes = indexes
305 print "+++++++++++++++++++++++bla"
306 self.currentlyInstallingMetaIndex = 0
307 self.installPackage(self.installIndexes[self.currentlyInstallingMetaIndex])
309 def installPackage(self, index):
310 print "self.packageslist:", self.packageslist
311 if len(self.packageslist) <= index:
312 print "no package with index", index, "found... installing nothing"
314 print "installing package with index", index, "and name", self.packageslist[index][0]["attributes"]["name"]
316 attributes = self.packageslist[index][0]["attributes"]
317 self.installingAttributes = attributes
318 self.attributeNames = ["skin", "config", "favourites", "package", "services"]
319 self.currentAttributeIndex = 0
320 self.currentIndex = -1
323 def setStatus(self, status):
325 self.statusCallback(self.status, None)
327 def installNext(self, *args, **kwargs):
328 if self.reloadFavourites:
329 self.reloadFavourites = False
330 db = eDVBDB.getInstance().reloadBouquets()
332 self.currentIndex += 1
333 attributes = self.installingAttributes
334 #print "attributes:", attributes
336 if self.currentAttributeIndex >= len(self.attributeNames): # end of package reached
337 print "end of package reached"
338 if self.currentlyInstallingMetaIndex is None or self.currentlyInstallingMetaIndex >= len(self.installIndexes) - 1:
339 print "set status to DONE"
340 self.setStatus(self.STATUS_DONE)
343 print "increment meta index to install next package"
344 self.currentlyInstallingMetaIndex += 1
345 self.currentAttributeIndex = 0
346 self.installPackage(self.installIndexes[self.currentlyInstallingMetaIndex])
349 self.setStatus(self.STATUS_WORKING)
351 print "currentAttributeIndex:", self.currentAttributeIndex
352 currentAttribute = self.attributeNames[self.currentAttributeIndex]
354 print "installing", currentAttribute, "with index", self.currentIndex
356 if attributes.has_key(currentAttribute):
357 if self.currentIndex >= len(attributes[currentAttribute]): # all jobs done for current attribute
358 self.currentIndex = -1
359 self.currentAttributeIndex += 1
362 else: # nothing to install here
363 self.currentIndex = -1
364 self.currentAttributeIndex += 1
368 if currentAttribute == "skin":
369 skin = attributes["skin"][self.currentIndex]
370 self.installSkin(skin["directory"], skin["name"])
371 elif currentAttribute == "config":
372 if self.currentIndex == 0:
373 from Components.config import configfile
375 config = attributes["config"][self.currentIndex]
376 self.mergeConfig(config["directory"], config["name"])
377 elif currentAttribute == "favourites":
378 favourite = attributes["favourites"][self.currentIndex]
379 self.installFavourites(favourite["directory"], favourite["name"])
380 elif currentAttribute == "package":
381 package = attributes["package"][self.currentIndex]
382 self.installIPK(package["directory"], package["name"])
383 elif currentAttribute == "services":
384 service = attributes["services"][self.currentIndex]
385 self.mergeServices(service["directory"], service["name"])
387 def readfile(self, filename):
388 if not os.path.isfile(filename):
391 lines = fd.readlines()
395 def mergeConfig(self, directory, name, merge = True):
396 print "merging config:", directory, " - ", name
397 if os.path.isfile(directory + name):
398 config.loadFromFile(directory + name)
402 def installIPK(self, directory, name):
404 os.system("opkg install " + directory + name)
407 self.ipkg = IpkgComponent()
408 self.ipkg.addCallback(self.ipkgCallback)
409 self.ipkg.startCmd(IpkgComponent.CMD_INSTALL, {'package': directory + name})
411 def ipkgCallback(self, event, param):
413 if event == IpkgComponent.EVENT_DONE:
415 elif event == IpkgComponent.EVENT_ERROR:
418 def installSkin(self, directory, name):
419 print "installing skin:", directory, " - ", name
420 print "cp -a %s %s" % (directory, resolveFilename(SCOPE_SKIN))
422 copytree(directory, resolveFilename(SCOPE_SKIN))
425 if self.console.execute("cp -a %s %s" % (directory, resolveFilename(SCOPE_SKIN))):
426 print "execute failed"
429 def mergeServices(self, directory, name, merge = False):
430 print "merging services:", directory, " - ", name
431 if os.path.isfile(directory + name):
432 db = eDVBDB.getInstance()
433 db.reloadServicelist()
434 db.loadServicelist(directory + name)
438 def installFavourites(self, directory, name):
439 print "installing favourites:", directory, " - ", name
440 self.reloadFavourites = True
443 copyfile(directory + name, resolveFilename(SCOPE_CONFIG))
446 if self.console.execute("cp %s %s" % ((directory + name), resolveFilename(SCOPE_CONFIG))):
447 print "execute failed"