root/tags/release-0.6.2/lib/xmltools.py

Revision 1, 13.4 kB (checked in by mjoc, 2 years ago)

Initial import.

Line 
1 #
2 # OpenDict
3 # Copyright (c) 2003-2005 Martynas Jocius <mjoc@akl.lt>
4 #
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your opinion) any later version.
9 #
10 # This program is distributed in the hope that will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MECHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more detals.
14 #
15 # You shoud have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 # 02111-1307 USA
19 #
20
21 import xml.dom.minidom
22 import xml.dom.ext
23
24 from lib import meta
25
26
27 def _textData(element):
28     """Return text data from given XML element"""
29
30     text = ''
31     for node in element.childNodes:
32         text = node.data
33
34     return text
35
36
37 class RegisterConfigGenerator:
38     """Class for generating register configuration files"""
39
40     def generate(self, **args):
41         """Generate config XML object"""
42
43         doc = xml.dom.minidom.Document()
44
45         registerElement = doc.createElement('plain-dictionary')
46         doc.appendChild(registerElement)
47
48         # Format element
49         formatElement = doc.createElement('format')
50         registerElement.appendChild(formatElement)
51         formatElement.appendChild(doc.createTextNode(args.get('format')))
52
53         # Name element
54         nameElement = doc.createElement('name')
55         registerElement.appendChild(nameElement)
56         nameElement.appendChild(doc.createTextNode(args.get('name')))
57
58         # Version element
59         versionElement = doc.createElement('version')
60         registerElement.appendChild(versionElement)
61         versionElement.appendChild(doc.createTextNode(args.get('version') \
62                                                       or ''))
63
64         # Authors element
65         authorsElement = doc.createElement('authors')
66         registerElement.appendChild(authorsElement)
67         for author in (args.get('authors') or []):
68             authorElement = doc.createElement('author')
69             authorsElement.appendChild(authorElement)
70             authorElement.setAttribute('name', author.get('name'))
71             authorElement.setAttribute('email', author.get('email'))
72
73         # Path element
74         pathElement = doc.createElement('path')
75         registerElement.appendChild(pathElement)
76         pathElement.appendChild(doc.createTextNode(args.get('path')))
77
78         # MD5 element
79         md5Element = doc.createElement('md5')
80         registerElement.appendChild(md5Element)
81         md5Element.appendChild(doc.createTextNode(args.get('md5')))
82
83         # Encoding element
84         encodingElement = doc.createElement('encoding')
85         registerElement.appendChild(encodingElement)
86         encodingElement.appendChild(doc.createTextNode(args.get('encoding')))
87
88         # Licence element
89         licElement = doc.createElement('licence')
90         registerElement.appendChild(licElement)
91         licElement.appendChild(doc.createTextNode(args.get('licence') \
92                                                    or ''))
93
94         # Description element
95         descElement = doc.createElement('description')
96         registerElement.appendChild(descElement)
97         descElement.appendChild(doc.createTextNode(args.get('description') \
98                                                    or ''))
99
100         return doc
101    
102
103 def generatePlainDictConfig(**args):
104     """Generate configuration and return DOM object"""
105
106     generator = RegisterConfigGenerator()
107     doc = generator.generate(**args)
108
109     return doc
110
111
112 def writePlainDictConfig(doc, path):
113     """Write XML file"""
114
115     fd = open(path, 'w')
116     xml.dom.ext.PrettyPrint(doc, fd)
117     fd.close()
118    
119
120
121 class RegisterConfigParser:
122     """Parse register configuration"""
123
124     def parse(self, xmlData):
125         """Parse XML data"""
126
127         doc = xml.dom.minidom.parseString(xmlData)
128         name = None
129         format = None
130         version = None
131         authors = []
132         path = None
133         md5 = None
134         encoding = None
135         licence = None
136         description = None
137
138         registers = doc.getElementsByTagName('plain-dictionary')
139         if len(registers) == 0:
140             raise "Invalid configuration"
141
142         registerElement = registers[0]
143        
144         for nameElement in registerElement.getElementsByTagName('name'):
145             for node in nameElement.childNodes:
146                 name = node.data
147
148         for formatElement in registerElement.getElementsByTagName('format'):
149             for node in formatElement.childNodes:
150                 format = node.data
151
152         for pathElement in registerElement.getElementsByTagName('path'):
153             for node in pathElement.childNodes:
154                 path = node.data
155
156         for versionElement in registerElement.getElementsByTagName('version'):
157             for node in versionElement.childNodes:
158                 version = node.data.strip()
159
160         for authorElement in registerElement.getElementsByTagName('author'):
161             authors.append({'name': authorElement.getAttribute('name'),
162                             'email': authorElement.getAttribute('email')})
163
164         for md5Element in registerElement.getElementsByTagName('md5'):
165             for node in md5Element.childNodes:
166                 md5 = node.data
167
168         for encodingElement in \
169                 registerElement.getElementsByTagName('encoding'):
170             for node in encodingElement.childNodes:
171                 encoding = node.data
172
173         for licenceElement in \
174                 registerElement.getElementsByTagName('licence'):
175             for node in licenceElement.childNodes:
176                 licence = node.data.strip()
177
178         for descElement in \
179                 registerElement.getElementsByTagName('description'):
180             for node in descElement.childNodes:
181                 description = (description or '') + node.data.strip()
182
183         result = {}
184         result['name'] = name
185         result['format'] = format
186         result['version'] = version
187         result['authors'] = authors
188         result['path'] = path
189         result['md5'] = md5
190         result['encoding'] = encoding
191         result['licence'] = licence
192         result['description'] = description
193
194         return result
195
196
197 def parsePlainDictConfig(configPath):
198     """Parse configuration file and return data dictionary"""
199
200     parser = RegisterConfigParser()
201     fd = open(configPath)
202     xmlData = fd.read()
203     fd.close()
204     data = parser.parse(xmlData)
205
206     return data
207
208
209
210 class IndexFileGenerator:
211     """Class for generating register configuration files"""
212
213     def generate(self, index):
214         """Generate config XML object"""
215
216         doc = xml.dom.minidom.Document()
217
218         indexElement = doc.createElement("index")
219         doc.appendChild(indexElement)
220
221         for data, pos in index.items():
222             startElement = doc.createElement("element")
223             startElement.setAttribute("literal", data)
224             startElement.setAttribute("position", str(pos))
225             indexElement.appendChild(startElement)
226
227         return doc
228    
229
230
231 def generateIndexFile(index):
232     """Generate index data and return DOM object"""
233
234     generator = IndexFileGenerator()
235     doc = generator.generate(index)
236
237     return doc
238
239
240 def writeIndexFile(doc, path):
241     """Write XML file"""
242
243     fd = open(path, 'wb')
244     xml.dom.ext.PrettyPrint(doc, fd)
245     fd.close()
246
247
248
249 class IndexFileParser:
250     """Parse register configuration"""
251
252     def parse(self, xmlData):
253         """Parse XML data"""
254
255         doc = xml.dom.minidom.parseString(xmlData)
256         index = {}
257
258         indexElement = doc.getElementsByTagName('index')[0]
259
260         for element in indexElement.getElementsByTagName('element'):
261             index[element.getAttribute("literal")] = long(element.getAttribute("position"))
262
263         return index
264
265
266 def parseIndexFile(indexPath):
267     """Parse configuration file and return data dictionary"""
268
269     parser = IndexFileParser()
270     fd = open(indexPath, 'rb')
271     xmlData = fd.read()
272     fd.close()
273     index = parser.parse(xmlData)
274
275     return index
276
277
278 class AddOnsParser:
279     """Parse add-ons file"""
280
281     class EmptyDictionary(meta.Dictionary):
282         """Empty dictionary for representing add-on information"""
283
284         name = None
285         version = None
286         size = None
287         checksum = None
288         authors = []
289         location = None
290         desc = None
291         atype = None
292
293         def setType(self, t):
294
295             self.atype = t
296
297
298         def getType(self):
299
300             return self.atype
301        
302
303         def setName(self, name):
304
305             self.name = name
306
307
308         def getName(self):
309
310             return self.name
311
312
313         def setVersion(self, version):
314
315             self.version = version
316
317
318         def getVersion(self):
319
320             return self.version
321
322
323         def setSize(self, size):
324
325             self.size = size
326
327
328         def getSize(self):
329
330             return self.size
331
332
333         def setChecksum(self, checksum):
334
335             self.checksum = checksum
336
337
338         def getChecksum(self):
339
340             return self.checksum
341
342
343         def addAuthor(self, author):
344
345             self.authors.append(author)
346
347
348         def getAuthors(self):
349
350             return self.authors
351
352
353         def setLocation(self, location):
354
355             self.location = location
356
357
358         def getLocation(self):
359
360             return self.location
361
362
363         def setDescription(self, desc):
364
365             self.desc = desc
366
367
368         def getDescription(self):
369
370             return self.desc
371        
372
373     def parse(self, xmlData):
374         """Parse XML data and return name->info dictionary object"""
375
376         doc = xml.dom.minidom.parseString(xmlData)
377
378         addons = {}
379
380         for addonElement in doc.getElementsByTagName('add-on'):
381             name = None
382             version = None
383             authors = []
384             description = None
385             size = None
386             url = None
387             checksum = None
388
389             addonType = addonElement.getAttribute('type')
390
391             for nameElement in addonElement.getElementsByTagName('name'):
392                 name = _textData(nameElement)
393
394             for versionElement in addonElement.getElementsByTagName('version'):
395                 version = _textData(versionElement)
396
397             for authorElement in addonElement.getElementsByTagName('author'):
398                 authors.append({'name': authorElement.getAttribute('name'),
399                                 'email': authorElement.getAttribute('email')})
400                
401             for descElement \
402                     in addonElement.getElementsByTagName('description'):
403                 description = _textData(descElement)
404
405             for urlElement in addonElement.getElementsByTagName('url'):
406                 url = _textData(urlElement)
407
408             for sizeElement in addonElement.getElementsByTagName('size'):
409                 size = long(_textData(sizeElement))
410                
411             for sumElement in addonElement.getElementsByTagName('md5'):
412                 checksum = _textData(sumElement)
413
414
415             emptyDict = self.EmptyDictionary()
416             emptyDict.setName(name)
417             emptyDict.setVersion(version)
418             emptyDict.authors = [] # To forget an old reference
419             for author in authors:
420                 emptyDict.addAuthor(author)
421             emptyDict.setDescription(description)
422             emptyDict.setLocation(url)
423             emptyDict.setSize(size)
424             emptyDict.setChecksum(checksum)
425
426             addons[name] = emptyDict
427
428         return addons
429
430
431 def parseAddOns(xmlData):
432     """Wrap add-ons data parsing"""
433
434     parser = AddOnsParser()
435     result = parser.parse(xmlData)
436     return result
437
438
439
440 class MainConfigParser:
441     """Parse main configuration"""
442
443     def parse(self, xmlData):
444         """Parse XML data"""
445
446         doc = xml.dom.minidom.parseString(xmlData)
447         props = {}
448
449         configs = doc.getElementsByTagName('main-config')
450         if len(configs) == 0:
451             raise "Invalid configuration"
452
453         configElement = configs[0]
454        
455         for node in configElement.childNodes:
456             if not node.nodeType == node.ELEMENT_NODE:
457                 continue
458            
459             for cnode in node.childNodes:
460                 name = node.nodeName
461                 value = cnode.data.strip()
462                 props[name] = value
463
464         return props
465
466
467 def parseMainConfig(configPath):
468     """Parse configuration file and return data dictionary"""
469
470     parser = MainConfigParser()
471     fd = open(configPath)
472     xmlData = fd.read()
473     fd.close()
474     data = parser.parse(xmlData)
475
476     return data
477
478
479
480 class MainConfigGenerator:
481     """Class for generating main configuration file"""
482
483     def generate(self, props):
484         """Generate config XML object"""
485
486         doc = xml.dom.minidom.Document()
487
488         mainElement = doc.createElement("main-config")
489         doc.appendChild(mainElement)
490
491         for key, value in props.items():
492             elem = doc.createElement(key)
493             mainElement.appendChild(elem)
494             if type(value) != unicode:
495                 value = str(value)
496             elem.appendChild(doc.createTextNode(value))
497
498         return doc
499    
500
501 def generateMainConfig(props):
502     """Generate configuration and return DOM object"""
503
504     generator = MainConfigGenerator()
505     doc = generator.generate(props)
506
507     return doc
508
509
510 def writeConfig(doc, path):
511     """Write XML file"""
512
513     fd = open(path, 'w')
514     xml.dom.ext.PrettyPrint(doc, fd)
515     fd.close()
516
Note: See TracBrowser for help on using the browser.