2 from Tools.Directories import crawlDirectory, resolveFilename, SCOPE_CONFIG, SCOPE_SKIN
3 from Components.NimManager import nimmanager
4 from Components.Ipkg import IpkgComponent
5 from Components.config import config, configfile
6 from enigma import eConsoleAppContainer, eDVBDB
9 class InfoHandlerParseError(Exception):
10 def __init__(self, value):
13 return repr(self.value)
15 class InfoHandler(xml.sax.ContentHandler):
16 def __init__(self, prerequisiteMet, directory):
18 self.directory = directory
20 self.globalprerequisites = {}
21 self.prerequisites = {}
23 self.validFileTypes = ["skin", "config", "services", "favourites", "package"]
24 self.prerequisitesMet = prerequisiteMet
26 def printError(self, error):
27 print "Error in defaults xml files:", error
28 raise InfoHandlerParseError, error
30 def startElement(self, name, attrs):
31 #print name, ":", attrs.items()
32 self.elements.append(name)
33 if name in ["hardware", "bcastsystem", "satellite", "tag"]:
34 if not attrs.has_key("type"):
35 self.printError(str(name) + " tag with no type attribute")
36 if self.elements[-3] == "default":
37 prerequisites = self.globalprerequisites
39 prerequisites = self.prerequisites
40 if not prerequisites.has_key(name):
41 prerequisites[name] = []
42 prerequisites[name].append(str(attrs["type"]))
44 if attrs.has_key("type"):
45 if attrs["type"] == "directories":
46 self.attributes["filestype"] = "directories"
47 # TODO add a compressed archive type
49 self.prerequisites = {}
50 if not attrs.has_key("type"):
51 self.printError("file tag with no type attribute")
53 if not attrs.has_key("name"):
54 self.printError("file tag with no name attribute")
56 if not attrs.has_key("directory"):
57 directory = self.directory
59 if not type in self.validFileTypes:
60 self.printError("file tag with invalid type attribute")
63 self.fileattrs = attrs
64 def endElement(self, name):
66 #print "self.elements:", self.elements
69 #print "prerequisites:", self.prerequisites
70 if len(self.prerequisites) == 0 or self.prerequisitesMet(self.prerequisites):
71 if not self.attributes.has_key(self.filetype):
72 self.attributes[self.filetype] = []
73 if self.fileattrs.has_key("directory"):
74 directory = str(self.fileattrs["directory"])
75 if len(directory) < 1 or directory[0] != "/":
76 directory = self.directory + directory
78 directory = self.directory
79 self.attributes[self.filetype].append({ "name": str(self.fileattrs["name"]), "directory": directory })
82 self.list.append({"attributes": self.attributes, 'prerequisites': self.globalprerequisites})
84 self.globalprerequisites = {}
86 def characters(self, data):
87 if self.elements[-1] == "author":
88 self.attributes["author"] = str(data)
89 if self.elements[-1] == "name":
90 self.attributes["name"] = str(data)
91 #print "characters", data
93 class DreamInfoHandler:
99 def __init__(self, statusCallback, blocking = False, neededTag = None):
102 self.neededTag = neededTag
104 # caution: blocking should only be used, if further execution in enigma2 depends on the outcome of
106 self.blocking = blocking
108 self.currentlyInstallingMetaIndex = None
110 self.console = eConsoleAppContainer()
111 self.console.appClosed.get().append(self.installNext)
112 self.reloadFavourites = False
114 self.statusCallback = statusCallback
115 self.setStatus(self.STATUS_INIT)
117 self.packageslist = []
119 def readInfo(self, directory, file):
120 print "Reading .info file", file
121 handler = InfoHandler(self.prerequisiteMet, directory)
123 xml.sax.parse(file, handler)
124 for entry in handler.list:
125 self.packageslist.append((entry,file))
126 except InfoHandlerParseError:
127 print "file", file, "ignored due to errors in the file"
130 # prerequisites = True: give only packages matching the prerequisites
131 def fillPackagesList(self, prerequisites = True):
132 self.packageslist = []
134 if not isinstance(self.directory, list):
135 self.directory = [self.directory]
137 for directory in self.directory:
138 packages += crawlDirectory(directory, ".*\.info$")
140 for package in packages:
141 self.readInfo(package[0] + "/", package[0] + "/" + package[1])
144 for package in self.packageslist[:]:
145 if not self.prerequisiteMet(package[0]["prerequisites"]):
146 self.packageslist.remove(package)
147 return self.packageslist
149 def prerequisiteMet(self, prerequisites):
150 # TODO: we need to implement a hardware detection here...
151 print "prerequisites:", prerequisites
153 if self.neededTag is None:
154 if prerequisites.has_key("tag"):
157 if prerequisites.has_key("tag"):
158 if not self.neededTag in prerequisites["tag"]:
163 if prerequisites.has_key("satellite"):
164 for sat in prerequisites["satellite"]:
165 if int(sat) not in nimmanager.getConfiguredSats():
167 if prerequisites.has_key("bcastsystem"):
168 for bcastsystem in prerequisites["bcastsystem"]:
169 if nimmanager.hasNimType(bcastsystem):
172 if prerequisites.has_key("hardware"):
173 for hardware in prerequisites["hardware"]:
174 # TODO: hardware detection
178 def installPackages(self, indexes):
179 print "installing packages", indexes
180 if len(indexes) == 0:
181 self.setStatus(self.STATUS_DONE)
183 self.installIndexes = indexes
184 print "+++++++++++++++++++++++bla"
185 self.currentlyInstallingMetaIndex = 0
186 self.installPackage(self.installIndexes[self.currentlyInstallingMetaIndex])
188 def installPackage(self, index):
189 print "installing package with index", index, "and name", self.packageslist[index][0]["attributes"]["name"]
191 attributes = self.packageslist[index][0]["attributes"]
192 self.installingAttributes = attributes
193 self.attributeNames = ["skin", "config", "favourites", "package", "services"]
194 self.currentAttributeIndex = 0
195 self.currentIndex = -1
198 def setStatus(self, status):
200 self.statusCallback(self.status, None)
202 def installNext(self, *args, **kwargs):
203 if self.reloadFavourites:
204 self.reloadFavourites = False
205 db = eDVBDB.getInstance().reloadBouquets()
207 self.currentIndex += 1
208 attributes = self.installingAttributes
209 #print "attributes:", attributes
211 if self.currentAttributeIndex >= len(self.attributeNames): # end of package reached
212 print "end of package reached"
213 if self.currentlyInstallingMetaIndex is None or self.currentlyInstallingMetaIndex >= len(self.installIndexes) - 1:
214 print "set status to DONE"
215 self.setStatus(self.STATUS_DONE)
218 print "increment meta index to install next package"
219 self.currentlyInstallingMetaIndex += 1
220 self.currentAttributeIndex = 0
221 self.installPackage(self.installIndexes[self.currentlyInstallingMetaIndex])
224 self.setStatus(self.STATUS_WORKING)
226 print "currentAttributeIndex:", self.currentAttributeIndex
227 currentAttribute = self.attributeNames[self.currentAttributeIndex]
229 print "installing", currentAttribute, "with index", self.currentIndex
231 if attributes.has_key(currentAttribute):
232 if self.currentIndex >= len(attributes[currentAttribute]): # all jobs done for current attribute
233 self.currentIndex = -1
234 self.currentAttributeIndex += 1
237 else: # nothing to install here
238 self.currentIndex = -1
239 self.currentAttributeIndex += 1
243 if currentAttribute == "skin":
244 skin = attributes["skin"][self.currentIndex]
245 self.installSkin(skin["directory"], skin["name"])
246 elif currentAttribute == "config":
247 if self.currentIndex == 0:
248 from Components.config import configfile
250 config = attributes["config"][self.currentIndex]
251 self.mergeConfig(config["directory"], config["name"])
252 elif currentAttribute == "favourites":
253 favourite = attributes["favourites"][self.currentIndex]
254 self.installFavourites(favourite["directory"], favourite["name"])
255 elif currentAttribute == "package":
256 package = attributes["package"][self.currentIndex]
257 self.installIPK(package["directory"], package["name"])
258 elif currentAttribute == "services":
259 service = attributes["services"][self.currentIndex]
260 self.mergeServices(service["directory"], service["name"])
262 def readfile(self, filename):
263 if not os.path.isfile(filename):
266 lines = fd.readlines()
270 def mergeConfig(self, directory, name, merge = True):
271 print "merging config:", directory, " - ", name
272 if os.path.isfile(directory + name):
273 config.loadFromFile(directory + name)
277 def installIPK(self, directory, name):
279 os.system("ipkg install " + directory + name)
282 self.ipkg = IpkgComponent()
283 self.ipkg.addCallback(self.ipkgCallback)
284 self.ipkg.startCmd(IpkgComponent.CMD_INSTALL, {'package': directory + name})
286 def ipkgCallback(self, event, param):
288 if event == IpkgComponent.EVENT_DONE:
290 elif event == IpkgComponent.EVENT_ERROR:
293 def installSkin(self, directory, name):
294 print "installing skin:", directory, " - ", name
295 print "cp -a %s %s" % (directory, resolveFilename(SCOPE_SKIN))
297 os.system("cp -a %s %s" % (directory, resolveFilename(SCOPE_SKIN)))
300 if self.console.execute("cp -a %s %s" % (directory, resolveFilename(SCOPE_SKIN))):
301 print "execute failed"
304 def mergeServices(self, directory, name, merge = False):
305 print "merging services:", directory, " - ", name
306 if os.path.isfile(directory + name):
307 db = eDVBDB.getInstance()
308 db.reloadServicelist()
309 db.loadServicelist(directory + name)
313 def installFavourites(self, directory, name):
314 print "installing favourites:", directory, " - ", name
315 self.reloadFavourites = True
318 os.system("cp %s %s" % ((directory + name), resolveFilename(SCOPE_CONFIG)))
321 if self.console.execute("cp %s %s" % ((directory + name), resolveFilename(SCOPE_CONFIG))):
322 print "execute failed"