2 from Tools.Directories import crawlDirectory, resolveFilename, SCOPE_CONFIG, SCOPE_SKIN, copyfile, copytree
3 from Components.NimManager import nimmanager
4 from Components.Ipkg import IpkgComponent
5 from Components.config import config, configfile
6 from Tools.HardwareInfo import HardwareInfo
7 from enigma import eConsoleAppContainer, eDVBDB
10 class InfoHandlerParseError(Exception):
11 def __init__(self, value):
14 return repr(self.value)
16 class InfoHandler(xml.sax.ContentHandler):
17 def __init__(self, prerequisiteMet, directory):
19 self.directory = directory
21 self.globalprerequisites = {}
22 self.prerequisites = {}
24 self.validFileTypes = ["skin", "config", "services", "favourites", "package"]
25 self.prerequisitesMet = prerequisiteMet
27 def printError(self, error):
28 print "Error in defaults xml files:", error
29 raise InfoHandlerParseError, error
31 def startElement(self, name, attrs):
32 #print name, ":", attrs.items()
33 self.elements.append(name)
34 if name in ["hardware", "bcastsystem", "satellite", "tag"]:
35 if not attrs.has_key("type"):
36 self.printError(str(name) + " tag with no type attribute")
37 if self.elements[-3] == "default":
38 prerequisites = self.globalprerequisites
40 prerequisites = self.prerequisites
41 if not prerequisites.has_key(name):
42 prerequisites[name] = []
43 prerequisites[name].append(str(attrs["type"]))
45 if attrs.has_key("type"):
46 if attrs["type"] == "directories":
47 self.attributes["filestype"] = "directories"
48 # TODO add a compressed archive type
50 self.prerequisites = {}
51 if not attrs.has_key("type"):
52 self.printError("file tag with no type attribute")
54 if not attrs.has_key("name"):
55 self.printError("file tag with no name attribute")
57 if not attrs.has_key("directory"):
58 directory = self.directory
60 if not type in self.validFileTypes:
61 self.printError("file tag with invalid type attribute")
64 self.fileattrs = attrs
65 def endElement(self, name):
67 #print "self.elements:", self.elements
70 #print "prerequisites:", self.prerequisites
71 if len(self.prerequisites) == 0 or self.prerequisitesMet(self.prerequisites):
72 if not self.attributes.has_key(self.filetype):
73 self.attributes[self.filetype] = []
74 if self.fileattrs.has_key("directory"):
75 directory = str(self.fileattrs["directory"])
76 if len(directory) < 1 or directory[0] != "/":
77 directory = self.directory + directory
79 directory = self.directory
80 self.attributes[self.filetype].append({ "name": str(self.fileattrs["name"]), "directory": directory })
83 self.list.append({"attributes": self.attributes, 'prerequisites': self.globalprerequisites})
85 self.globalprerequisites = {}
87 def characters(self, data):
88 if self.elements[-1] == "author":
89 self.attributes["author"] = str(data)
90 if self.elements[-1] == "name":
91 self.attributes["name"] = str(data)
92 #print "characters", data
94 class DreamInfoHandler:
100 def __init__(self, statusCallback, blocking = False, neededTag = None):
101 self.hardware_info = HardwareInfo()
104 self.neededTag = neededTag
106 # caution: blocking should only be used, if further execution in enigma2 depends on the outcome of
108 self.blocking = blocking
110 self.currentlyInstallingMetaIndex = None
112 self.console = eConsoleAppContainer()
113 self.console.appClosed.get().append(self.installNext)
114 self.reloadFavourites = False
116 self.statusCallback = statusCallback
117 self.setStatus(self.STATUS_INIT)
119 self.packageslist = []
121 def readInfo(self, directory, file):
122 print "Reading .info file", file
123 handler = InfoHandler(self.prerequisiteMet, directory)
125 xml.sax.parse(file, handler)
126 for entry in handler.list:
127 self.packageslist.append((entry,file))
128 except InfoHandlerParseError:
129 print "file", file, "ignored due to errors in the file"
132 # prerequisites = True: give only packages matching the prerequisites
133 def fillPackagesList(self, prerequisites = True):
134 self.packageslist = []
136 if not isinstance(self.directory, list):
137 self.directory = [self.directory]
139 for directory in self.directory:
140 packages += crawlDirectory(directory, ".*\.info$")
142 for package in packages:
143 self.readInfo(package[0] + "/", package[0] + "/" + package[1])
146 for package in self.packageslist[:]:
147 if not self.prerequisiteMet(package[0]["prerequisites"]):
148 self.packageslist.remove(package)
149 return self.packageslist
151 def prerequisiteMet(self, prerequisites):
152 # TODO: we need to implement a hardware detection here...
153 print "prerequisites:", prerequisites
155 if self.neededTag is None:
156 if prerequisites.has_key("tag"):
159 if prerequisites.has_key("tag"):
160 if not self.neededTag in prerequisites["tag"]:
165 if prerequisites.has_key("satellite"):
166 for sat in prerequisites["satellite"]:
167 if int(sat) not in nimmanager.getConfiguredSats():
169 if prerequisites.has_key("bcastsystem"):
171 for bcastsystem in prerequisites["bcastsystem"]:
172 if nimmanager.hasNimType(bcastsystem):
176 if prerequisites.has_key("hardware"):
177 hardware_found = False
178 for hardware in prerequisites["hardware"]:
179 if hardware == self.hardware_info.device_name:
180 hardware_found = True
181 if not hardware_found:
185 def installPackages(self, indexes):
186 print "installing packages", indexes
187 if len(indexes) == 0:
188 self.setStatus(self.STATUS_DONE)
190 self.installIndexes = indexes
191 print "+++++++++++++++++++++++bla"
192 self.currentlyInstallingMetaIndex = 0
193 self.installPackage(self.installIndexes[self.currentlyInstallingMetaIndex])
195 def installPackage(self, index):
196 print "self.packageslist:", self.packageslist
197 if len(self.packageslist) <= index:
198 print "no package with index", index, "found... installing nothing"
200 print "installing package with index", index, "and name", self.packageslist[index][0]["attributes"]["name"]
202 attributes = self.packageslist[index][0]["attributes"]
203 self.installingAttributes = attributes
204 self.attributeNames = ["skin", "config", "favourites", "package", "services"]
205 self.currentAttributeIndex = 0
206 self.currentIndex = -1
209 def setStatus(self, status):
211 self.statusCallback(self.status, None)
213 def installNext(self, *args, **kwargs):
214 if self.reloadFavourites:
215 self.reloadFavourites = False
216 db = eDVBDB.getInstance().reloadBouquets()
218 self.currentIndex += 1
219 attributes = self.installingAttributes
220 #print "attributes:", attributes
222 if self.currentAttributeIndex >= len(self.attributeNames): # end of package reached
223 print "end of package reached"
224 if self.currentlyInstallingMetaIndex is None or self.currentlyInstallingMetaIndex >= len(self.installIndexes) - 1:
225 print "set status to DONE"
226 self.setStatus(self.STATUS_DONE)
229 print "increment meta index to install next package"
230 self.currentlyInstallingMetaIndex += 1
231 self.currentAttributeIndex = 0
232 self.installPackage(self.installIndexes[self.currentlyInstallingMetaIndex])
235 self.setStatus(self.STATUS_WORKING)
237 print "currentAttributeIndex:", self.currentAttributeIndex
238 currentAttribute = self.attributeNames[self.currentAttributeIndex]
240 print "installing", currentAttribute, "with index", self.currentIndex
242 if attributes.has_key(currentAttribute):
243 if self.currentIndex >= len(attributes[currentAttribute]): # all jobs done for current attribute
244 self.currentIndex = -1
245 self.currentAttributeIndex += 1
248 else: # nothing to install here
249 self.currentIndex = -1
250 self.currentAttributeIndex += 1
254 if currentAttribute == "skin":
255 skin = attributes["skin"][self.currentIndex]
256 self.installSkin(skin["directory"], skin["name"])
257 elif currentAttribute == "config":
258 if self.currentIndex == 0:
259 from Components.config import configfile
261 config = attributes["config"][self.currentIndex]
262 self.mergeConfig(config["directory"], config["name"])
263 elif currentAttribute == "favourites":
264 favourite = attributes["favourites"][self.currentIndex]
265 self.installFavourites(favourite["directory"], favourite["name"])
266 elif currentAttribute == "package":
267 package = attributes["package"][self.currentIndex]
268 self.installIPK(package["directory"], package["name"])
269 elif currentAttribute == "services":
270 service = attributes["services"][self.currentIndex]
271 self.mergeServices(service["directory"], service["name"])
273 def readfile(self, filename):
274 if not os.path.isfile(filename):
277 lines = fd.readlines()
281 def mergeConfig(self, directory, name, merge = True):
282 print "merging config:", directory, " - ", name
283 if os.path.isfile(directory + name):
284 config.loadFromFile(directory + name)
288 def installIPK(self, directory, name):
290 os.system("ipkg install " + directory + name)
293 self.ipkg = IpkgComponent()
294 self.ipkg.addCallback(self.ipkgCallback)
295 self.ipkg.startCmd(IpkgComponent.CMD_INSTALL, {'package': directory + name})
297 def ipkgCallback(self, event, param):
299 if event == IpkgComponent.EVENT_DONE:
301 elif event == IpkgComponent.EVENT_ERROR:
304 def installSkin(self, directory, name):
305 print "installing skin:", directory, " - ", name
306 print "cp -a %s %s" % (directory, resolveFilename(SCOPE_SKIN))
308 copytree(directory, resolveFilename(SCOPE_SKIN))
311 if self.console.execute("cp -a %s %s" % (directory, resolveFilename(SCOPE_SKIN))):
312 print "execute failed"
315 def mergeServices(self, directory, name, merge = False):
316 print "merging services:", directory, " - ", name
317 if os.path.isfile(directory + name):
318 db = eDVBDB.getInstance()
319 db.reloadServicelist()
320 db.loadServicelist(directory + name)
324 def installFavourites(self, directory, name):
325 print "installing favourites:", directory, " - ", name
326 self.reloadFavourites = True
329 copyfile(directory + name, resolveFilename(SCOPE_CONFIG))
332 if self.console.execute("cp %s %s" % ((directory + name), resolveFilename(SCOPE_CONFIG))):
333 print "execute failed"