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
11 class InfoHandlerParseError(Exception):
12 def __init__(self, value):
15 return repr(self.value)
17 class InfoHandler(xml.sax.ContentHandler):
18 def __init__(self, prerequisiteMet, directory, language = None):
20 self.directory = directory
22 self.globalprerequisites = {}
23 self.prerequisites = {}
25 self.validFileTypes = ["skin", "config", "services", "favourites", "package"]
26 self.prerequisitesMet = prerequisiteMet
28 self.languagedata = ""
29 self.language = language
31 def printError(self, error):
32 print "Error in defaults xml files:", error
33 raise InfoHandlerParseError, error
35 def startElement(self, name, attrs):
36 #print name, ":", attrs.items()
37 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"]))
49 if attrs.has_key("type"):
50 if attrs["type"] == "directories":
51 self.attributes["filestype"] = "directories"
52 elif attrs["type"] == "package":
53 self.attributes["filestype"] = "package"
54 # TODO add a compressed archive type
56 self.prerequisites = {}
57 if not attrs.has_key("type"):
58 self.printError("file tag with no type attribute")
60 if not attrs.has_key("name"):
61 self.printError("file tag with no name attribute")
63 if not attrs.has_key("directory"):
64 directory = self.directory
66 if not type in self.validFileTypes:
67 self.printError("file tag with invalid type attribute")
70 self.fileattrs = attrs
73 if attrs.has_key("details"):
74 self.attributes["details"] = str(attrs["details"])
75 if attrs.has_key("name"):
76 self.attributes["name"] = str(attrs["name"].encode("utf-8"))
77 if attrs.has_key("packagename"):
78 self.attributes["packagename"] = str(attrs["packagename"].encode("utf-8"))
79 if attrs.has_key("shortdescription"):
80 self.attributes["shortdescription"] = str(attrs["shortdescription"].encode("utf-8"))
82 if name == "screenshot":
83 if attrs.has_key("src"):
84 self.attributes["screenshot"] = str(attrs["src"])
86 def endElement(self, name):
88 #print "self.elements:", self.elements
91 #print "prerequisites:", self.prerequisites
92 if len(self.prerequisites) == 0 or self.prerequisitesMet(self.prerequisites):
93 if not self.attributes.has_key(self.filetype):
94 self.attributes[self.filetype] = []
95 if self.fileattrs.has_key("directory"):
96 directory = str(self.fileattrs["directory"])
97 if len(directory) < 1 or directory[0] != "/":
98 directory = self.directory + directory
100 directory = self.directory
101 self.attributes[self.filetype].append({ "name": str(self.fileattrs["name"]), "directory": directory })
103 if name in ( "default", "package" ):
104 self.list.append({"attributes": self.attributes, 'prerequisites': self.globalprerequisites})
106 self.globalprerequisites = {}
108 def characters(self, data):
109 if self.elements[-1] == "author":
110 self.attributes["author"] = str(data)
111 if self.elements[-1] == "name":
112 self.attributes["name"] = str(data)
113 if self.elements[-1] == "packagename":
114 self.attributes["packagename"] = str(data.encode("utf-8"))
115 if self.elements[-1] == "shortdescription":
116 self.attributes["shortdescription"] = str(data.encode("utf-8"))
117 if self.elements[-1] == "description":
118 self.data += data.strip()
119 self.attributes["description"] = str(self.data.encode("utf-8"))
120 if self.language is not None:
121 if self.elements[-1] == ("name_" + str(self.language)):
122 self.attributes["name"] = str(data.encode("utf-8"))
123 if self.elements[-1] == ("shortdescription_" + str(self.language)):
124 self.attributes["shortdescription"] = str(data.encode("utf-8"))
125 if self.elements[-1] == ("description_" + str(self.language)):
126 self.languagedata += data.strip()
127 self.attributes["description"] = str(self.languagedata.encode("utf-8"))
128 #print "characters", data
130 class DreamInfoHandler:
136 def __init__(self, statusCallback, blocking = False, neededTag = None, neededFlag = None, language = None):
137 self.hardware_info = HardwareInfo()
140 self.neededTag = neededTag
141 self.neededFlag = neededFlag
142 self.language = language
144 # caution: blocking should only be used, if further execution in enigma2 depends on the outcome of
146 self.blocking = blocking
148 self.currentlyInstallingMetaIndex = None
150 self.console = eConsoleAppContainer()
151 self.console.appClosed.append(self.installNext)
152 self.reloadFavourites = False
154 self.statusCallback = statusCallback
155 self.setStatus(self.STATUS_INIT)
157 self.packageslist = []
158 self.packagesIndexlist = []
159 self.packageDetails = []
161 def readInfo(self, directory, file):
162 print "Reading .info file", file
163 handler = InfoHandler(self.prerequisiteMet, directory)
165 xml.sax.parse(file, handler)
166 for entry in handler.list:
167 self.packageslist.append((entry,file))
168 except InfoHandlerParseError:
169 print "file", file, "ignored due to errors in the file"
172 def readIndex(self, directory, file):
173 print "Reading .xml meta index file", file
174 handler = InfoHandler(self.prerequisiteMet, directory, self.language)
176 xml.sax.parse(file, handler)
177 for entry in handler.list:
178 self.packagesIndexlist.append((entry,file))
179 except InfoHandlerParseError:
180 print "file", file, "ignored due to errors in the file"
183 def readDetails(self, directory, file):
184 print "Reading .xml meta details file", file
185 handler = InfoHandler(self.prerequisiteMet, directory, self.language)
187 xml.sax.parse(file, handler)
188 for entry in handler.list:
189 self.packageDetails.append((entry,file))
190 except InfoHandlerParseError:
191 print "file", file, "ignored due to errors in the file"
194 # prerequisites = True: give only packages matching the prerequisites
195 def fillPackagesList(self, prerequisites = True):
196 self.packageslist = []
198 if not isinstance(self.directory, list):
199 self.directory = [self.directory]
201 for directory in self.directory:
202 packages += crawlDirectory(directory, ".*\.info$")
204 for package in packages:
205 self.readInfo(package[0] + "/", package[0] + "/" + package[1])
208 for package in self.packageslist[:]:
209 if not self.prerequisiteMet(package[0]["prerequisites"]):
210 self.packageslist.remove(package)
211 return self.packageslist
213 # prerequisites = True: give only packages matching the prerequisites
214 def fillPackagesIndexList(self, prerequisites = True):
215 self.packagesIndexlist = []
216 if self.language is not None:
217 indexfile = 'index_' + self.language + '.xml'
219 indexfile = 'index.xml'
220 if not isinstance(self.directory, list):
221 self.directory = [self.directory]
222 self.readIndex(self.directory[0] + "/", self.directory[0] + "/" + indexfile)
225 for package in self.packagesIndexlist[:]:
226 if not self.prerequisiteMet(package[0]["prerequisites"]):
227 self.packagesIndexlist.remove(package)
228 return self.packagesIndexlist
230 # prerequisites = True: give only packages matching the prerequisites
231 def fillPackageDetails(self, details = None):
232 self.packageDetails = []
233 detailsfile = details
234 if not isinstance(self.directory, list):
235 self.directory = [self.directory]
236 self.readDetails(self.directory[0] + "/", self.directory[0] + "/" + detailsfile)
237 return self.packageDetails
239 def prerequisiteMet(self, prerequisites):
240 # TODO: we need to implement a hardware detection here...
241 print "prerequisites:", prerequisites
243 if self.neededTag is None:
244 if prerequisites.has_key("tag"):
246 elif self.neededTag == 'ALL_TAGS':
249 if prerequisites.has_key("tag"):
250 if not self.neededTag in prerequisites["tag"]:
255 if self.neededFlag is None:
256 if prerequisites.has_key("flag"):
259 if prerequisites.has_key("flag"):
260 if not self.neededFlag in prerequisites["flag"]:
263 return True # No flag found, assuming all flags valid
265 if prerequisites.has_key("satellite"):
266 for sat in prerequisites["satellite"]:
267 if int(sat) not in nimmanager.getConfiguredSats():
269 if prerequisites.has_key("bcastsystem"):
271 for bcastsystem in prerequisites["bcastsystem"]:
272 if nimmanager.hasNimType(bcastsystem):
276 if prerequisites.has_key("hardware"):
277 hardware_found = False
278 for hardware in prerequisites["hardware"]:
279 if hardware == self.hardware_info.device_name:
280 hardware_found = True
281 if not hardware_found:
285 def installPackages(self, indexes):
286 print "installing packages", indexes
287 if len(indexes) == 0:
288 self.setStatus(self.STATUS_DONE)
290 self.installIndexes = indexes
291 print "+++++++++++++++++++++++bla"
292 self.currentlyInstallingMetaIndex = 0
293 self.installPackage(self.installIndexes[self.currentlyInstallingMetaIndex])
295 def installPackage(self, index):
296 print "self.packageslist:", self.packageslist
297 if len(self.packageslist) <= index:
298 print "no package with index", index, "found... installing nothing"
300 print "installing package with index", index, "and name", self.packageslist[index][0]["attributes"]["name"]
302 attributes = self.packageslist[index][0]["attributes"]
303 self.installingAttributes = attributes
304 self.attributeNames = ["skin", "config", "favourites", "package", "services"]
305 self.currentAttributeIndex = 0
306 self.currentIndex = -1
309 def setStatus(self, status):
311 self.statusCallback(self.status, None)
313 def installNext(self, *args, **kwargs):
314 if self.reloadFavourites:
315 self.reloadFavourites = False
316 db = eDVBDB.getInstance().reloadBouquets()
318 self.currentIndex += 1
319 attributes = self.installingAttributes
320 #print "attributes:", attributes
322 if self.currentAttributeIndex >= len(self.attributeNames): # end of package reached
323 print "end of package reached"
324 if self.currentlyInstallingMetaIndex is None or self.currentlyInstallingMetaIndex >= len(self.installIndexes) - 1:
325 print "set status to DONE"
326 self.setStatus(self.STATUS_DONE)
329 print "increment meta index to install next package"
330 self.currentlyInstallingMetaIndex += 1
331 self.currentAttributeIndex = 0
332 self.installPackage(self.installIndexes[self.currentlyInstallingMetaIndex])
335 self.setStatus(self.STATUS_WORKING)
337 print "currentAttributeIndex:", self.currentAttributeIndex
338 currentAttribute = self.attributeNames[self.currentAttributeIndex]
340 print "installing", currentAttribute, "with index", self.currentIndex
342 if attributes.has_key(currentAttribute):
343 if self.currentIndex >= len(attributes[currentAttribute]): # all jobs done for current attribute
344 self.currentIndex = -1
345 self.currentAttributeIndex += 1
348 else: # nothing to install here
349 self.currentIndex = -1
350 self.currentAttributeIndex += 1
354 if currentAttribute == "skin":
355 skin = attributes["skin"][self.currentIndex]
356 self.installSkin(skin["directory"], skin["name"])
357 elif currentAttribute == "config":
358 if self.currentIndex == 0:
359 from Components.config import configfile
361 config = attributes["config"][self.currentIndex]
362 self.mergeConfig(config["directory"], config["name"])
363 elif currentAttribute == "favourites":
364 favourite = attributes["favourites"][self.currentIndex]
365 self.installFavourites(favourite["directory"], favourite["name"])
366 elif currentAttribute == "package":
367 package = attributes["package"][self.currentIndex]
368 self.installIPK(package["directory"], package["name"])
369 elif currentAttribute == "services":
370 service = attributes["services"][self.currentIndex]
371 self.mergeServices(service["directory"], service["name"])
373 def readfile(self, filename):
374 if not os.path.isfile(filename):
377 lines = fd.readlines()
381 def mergeConfig(self, directory, name, merge = True):
382 print "merging config:", directory, " - ", name
383 if os.path.isfile(directory + name):
384 config.loadFromFile(directory + name)
388 def installIPK(self, directory, name):
390 os.system("ipkg install " + directory + name)
393 self.ipkg = IpkgComponent()
394 self.ipkg.addCallback(self.ipkgCallback)
395 self.ipkg.startCmd(IpkgComponent.CMD_INSTALL, {'package': directory + name})
397 def ipkgCallback(self, event, param):
399 if event == IpkgComponent.EVENT_DONE:
401 elif event == IpkgComponent.EVENT_ERROR:
404 def installSkin(self, directory, name):
405 print "installing skin:", directory, " - ", name
406 print "cp -a %s %s" % (directory, resolveFilename(SCOPE_SKIN))
408 copytree(directory, resolveFilename(SCOPE_SKIN))
411 if self.console.execute("cp -a %s %s" % (directory, resolveFilename(SCOPE_SKIN))):
412 print "execute failed"
415 def mergeServices(self, directory, name, merge = False):
416 print "merging services:", directory, " - ", name
417 if os.path.isfile(directory + name):
418 db = eDVBDB.getInstance()
419 db.reloadServicelist()
420 db.loadServicelist(directory + name)
424 def installFavourites(self, directory, name):
425 print "installing favourites:", directory, " - ", name
426 self.reloadFavourites = True
429 copyfile(directory + name, resolveFilename(SCOPE_CONFIG))
432 if self.console.execute("cp %s %s" % ((directory + name), resolveFilename(SCOPE_CONFIG))):
433 print "execute failed"