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 enigma import eConsoleAppContainer
8 class InfoHandlerParseError(Exception):
9 def __init__(self, value):
12 return repr(self.value)
14 class InfoHandler(xml.sax.ContentHandler):
15 def __init__(self, prerequisiteMet, directory):
17 self.directory = directory
19 self.globalprerequisites = {}
20 self.prerequisites = {}
22 self.validFileTypes = ["skin", "config", "services", "favourites", "package"]
23 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"]:
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):
102 self.console = eConsoleAppContainer()
103 self.console.appClosed.get().append(self.installNext)
105 self.statusCallback = statusCallback
106 self.setStatus(self.STATUS_INIT)
108 self.packageslist = []
110 def readInfo(self, directory, file):
111 print "Reading .info file", file
112 handler = InfoHandler(self.prerequisiteMet, directory)
114 xml.sax.parse(file, handler)
115 for entry in handler.list:
116 self.packageslist.append((entry,file))
117 except InfoHandlerParseError:
118 print "file", file, "ignored due to errors in the file"
121 # prerequisites = True: give only packages matching the prerequisites
122 def fillPackagesList(self, prerequisites = True):
123 self.packageslist = []
124 packages = crawlDirectory(self.directory, ".*\.info$")
125 for package in packages:
126 self.readInfo(package[0] + "/", package[0] + "/" + package[1])
129 for package in self.packageslist[:]:
130 if not self.prerequisiteMet(package[0]["prerequisites"]):
131 self.packageslist.remove(package)
134 def prerequisiteMet(self, prerequisites):
135 # TODO: we need to implement a hardware detection here...
136 print "prerequisites:", prerequisites
138 if prerequisites.has_key("bcastsystem"):
139 for bcastsystem in prerequisites["bcastsystem"]:
140 if nimmanager.hasNimType(bcastsystem):
143 if prerequisites.has_key("hardware"):
144 for hardware in prerequisites["hardware"]:
145 # TODO: hardware detection
149 def installPackage(self, index):
150 print "installing package with index", index, "and name", self.packageslist[index][0]["attributes"]["name"]
152 attributes = self.packageslist[index][0]["attributes"]
153 self.installingAttributes = attributes
154 self.attributeNames = ["skin", "config", "favourites", "package", "services"]
155 self.currentAttributeIndex = 0
156 self.currentIndex = -1
159 def setStatus(self, status):
161 self.statusCallback(self.status, None)
163 def installNext(self, *args, **kwargs):
164 self.currentIndex += 1
165 attributes = self.installingAttributes
167 if self.currentAttributeIndex >= len(self.attributeNames): # end reached
168 self.setStatus(self.STATUS_DONE)
171 self.setStatus(self.STATUS_WORKING)
173 currentAttribute = self.attributeNames[self.currentAttributeIndex]
175 print "installing", currentAttribute, "with index", self.currentIndex
177 if attributes.has_key(currentAttribute):
178 if self.currentIndex >= len(attributes[currentAttribute]): # all jobs done for current attribute
179 self.currentIndex = -1
180 self.currentAttributeIndex += 1
183 else: # nothing to install here
184 self.currentAttributeIndex += 1
188 if currentAttribute == "skin":
189 skin = attributes["skin"][self.currentIndex]
190 self.installSkin(skin["directory"], skin["name"])
191 elif currentAttribute == "config":
192 if self.currentIndex == 0:
193 from Components.config import configfile
195 config = attributes["config"][self.currentIndex]
196 self.mergeConfig(config["directory"], config["name"])
197 elif currentAttribute == "favourites":
198 favourite = attributes["favourites"][self.currentIndex]
199 self.installFavourites(favourite["directory"], favourite["name"])
200 elif currentAttribute == "package":
201 package = attributes["package"][self.currentIndex]
202 self.installIPK(package["directory"], package["name"])
203 elif currentAttribute == "services":
204 service = attributes["services"][self.currentIndex]
205 self.mergeServices(service["directory"], service["name"])
207 def readfile(self, filename):
209 lines = fd.readlines()
213 def mergeConfig(self, directory, name, merge = True):
214 print "merging config:", directory, " - ", name
216 newconfig = self.readfile(directory + name)
221 oldconfig = self.readfile(resolveFilename(SCOPE_CONFIG) + "settings")
227 # merge with duplicate removal through dictionary
229 for list in oldconfig, newconfig:
231 splitentry = entry.split("=")
232 if len(splitentry) != 2: # wrong entry
234 mergeddict[splitentry[0]] = splitentry[1].strip()
237 fd = open(resolveFilename(SCOPE_CONFIG) + "settings", "w")
238 for entry in mergeddict.keys():
239 print entry + "=" + mergeddict[entry]
240 fd.write(entry + "=" + mergeddict[entry] + '\n')
246 def installIPK(self, directory, name):
247 self.ipkg = IpkgComponent()
248 self.ipkg.addCallback(self.ipkgCallback)
249 self.ipkg.startCmd(IpkgComponent.CMD_INSTALL, {'package': directory + name})
251 def ipkgCallback(self, event, param):
253 if event == IpkgComponent.EVENT_DONE:
255 elif event == IpkgComponent.EVENT_ERROR:
258 def installSkin(self, directory, name):
259 print "installing skin:", directory, " - ", name
260 print "cp -a %s %s" % (directory, resolveFilename(SCOPE_SKIN))
261 if self.console.execute("cp -a %s %s" % (directory, resolveFilename(SCOPE_SKIN))):
262 print "execute failed"
265 def readServices(self, filename):
266 newservicesfile = self.readfile(filename)
270 status = 0 # 0 = start, 1 = transponders, 2 = services
272 while count < len(newservicesfile):
274 if newservicesfile[count].strip() == "transponders":
276 elif status == 1: # reading transponders
277 if newservicesfile[count].strip() == "end": # finished reading transponders
279 elif newservicesfile[count].strip() == "services": # start of services section
282 transponders.append(''.join(newservicesfile[count:count + 3]))
284 elif status == 2: # reading services
285 if newservicesfile[count].strip() == "end": # finished reading file
288 services.append(''.join(newservicesfile[count:count + 3]))
291 return (transponders, services)
293 def mergeServices(self, directory, name, merge = False):
294 print "merging services:", directory, " - ", name
296 newtransponders, newservices = self.readServices(directory + name)
298 oldtransponders, oldservices = self.readServices(resolveFilename(SCOPE_CONFIG) + "lamedb")
300 oldtransponders, oldservices = [], []
302 fp = open(resolveFilename(SCOPE_CONFIG) + "lamedb", "w")
303 fp.write("eDVB services /3/\n")
305 fp.write("transponders\n")
306 for transponderlist in oldtransponders, newtransponders:
307 for transponder in transponderlist:
308 fp.write(transponder)
311 fp.write("services\n")
312 for serviceslist in oldservices, newservices:
313 for service in serviceslist:
320 def installFavourites(self, directory, name):
321 print "installing favourites:", directory, " - ", name
323 if self.console.execute("cp %s %s" % ((directory + name), resolveFilename(SCOPE_CONFIG))):
324 print "execute failed"