root/tags/release-0.6.2/scripts/make-addons-list.py

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

Initial import.

  • Property svn:executable set to *
Line 
1 #!/usr/bin/env python
2
3 import sys
4 import os
5 import zipfile
6 import md5
7 import xml.dom.minidom
8 import xml.dom.ext
9
10 #
11 # Add-ons description file generator for OpenDict
12 # Copyright (c) 2005 Martynas Jocius <mjoc@akl.lt>
13 #
14 # Fast code, dirty code
15 #
16
17 def parsePluginConfig(xmlData):
18     """Parse plugin configuration"""
19
20     doc = xml.dom.minidom.parseString(xmlData)
21
22     name = None
23     version = None
24     authors = []
25     description = None
26    
27     pluginElement = doc.getElementsByTagName('plugin')[0]
28     pluginType = pluginElement.getAttribute('type')
29
30     if pluginType != 'dictionary':
31         raise Exception, "Plugin is not dictionary plugin"
32
33     # Get name
34     for nameElement in doc.getElementsByTagName('name'):
35         for node in nameElement.childNodes:
36             if node.nodeType == node.TEXT_NODE:
37                 name = node.data
38
39     # Get version
40     for versionElement in doc.getElementsByTagName('version'):
41         for node in versionElement.childNodes:
42             if node.nodeType == node.TEXT_NODE:
43                 version = node.data
44
45     # Get authors
46     for authorElement in doc.getElementsByTagName('author'):
47         authorName = authorElement.getAttribute('name')
48         authorEMail = authorElement.getAttribute('email')
49         authors.append({'name': authorName, 'email': authorEMail})
50
51     # Get description
52     for descElement in doc.getElementsByTagName('description'):
53         for node in descElement.childNodes:
54             if node.nodeType == node.TEXT_NODE:
55                 description = node.data
56
57
58    
59     result = {}
60     result['name'] = name
61     result['version'] = version
62     result['authors'] = authors
63     result['description'] = description
64
65     return result
66
67
68 def parsePlainConfig(xmlData):
69     """Parse plain dict configuration"""
70
71     doc = xml.dom.minidom.parseString(xmlData)
72     name = None
73     version = None
74     authors = []
75     description = None
76
77     registers = doc.getElementsByTagName('plain-dictionary')
78     if len(registers) == 0:
79         raise "Invalid configuration"
80
81     registerElement = registers[0]
82
83     for nameElement in registerElement.getElementsByTagName('name'):
84         for node in nameElement.childNodes:
85             name = node.data
86
87     for versionElement in registerElement.getElementsByTagName('version'):
88         for node in versionElement.childNodes:
89             version = node.data.strip()
90
91     for authorElement in registerElement.getElementsByTagName('author'):
92         authors.append({'name': authorElement.getAttribute('name'),
93                         'email': authorElement.getAttribute('email')})
94
95     for descElement in \
96             registerElement.getElementsByTagName('description'):
97         for node in descElement.childNodes:
98             description = (description or '') + node.data.strip()
99
100     result = {}
101     result['name'] = name
102     result['version'] = version
103     result['authors'] = authors
104     result['description'] = description
105
106     return result
107
108
109 def generateElement(**args):
110     """Generate add-on XML DOM elemente"""
111    
112     doc = xml.dom.minidom.Document()
113
114     addonElement = doc.createElement('add-on')
115     addonElement.setAttribute('type', args.get('type'))
116
117     # Name element
118     nameElement = doc.createElement('name')
119     addonElement.appendChild(nameElement)
120     nameElement.appendChild(doc.createTextNode(args.get('name')))
121
122     # Version element
123     versionElement = doc.createElement('version')
124     addonElement.appendChild(versionElement)
125     versionElement.appendChild(doc.createTextNode(args.get('version')))
126
127     # Authors element
128     authorsElement = doc.createElement('authors')
129     addonElement.appendChild(authorsElement)
130     for author in (args.get('authors') or []):
131         authorElement = doc.createElement('author')
132         authorsElement.appendChild(authorElement)
133         authorElement.setAttribute('name', author.get('name'))
134         authorElement.setAttribute('email', author.get('email'))
135
136     # Description element
137     descElement = doc.createElement('description')
138     addonElement.appendChild(descElement)
139     descEscaped = "%s" % args.get('description', '')
140     descElement.appendChild(doc.createTextNode(descEscaped))
141
142     # MD5 element
143     md5Element = doc.createElement('md5')
144     addonElement.appendChild(md5Element)
145     md5Element.appendChild(doc.createTextNode(args.get('md5sum')))
146
147     # URL element
148     urlElement = doc.createElement('url')
149     addonElement.appendChild(urlElement)
150     urlElement.appendChild(doc.createTextNode(args.get('url')))
151
152     # Size element
153     sizeElement = doc.createElement('size')
154     addonElement.appendChild(sizeElement)
155     sizeElement.appendChild(doc.createTextNode(str(args.get('size'))))
156
157     return addonElement
158
159
160 def listFiles(start, followLinks, myDepth, maxDepth):
161     """Return file list"""
162    
163     files = []
164    
165     try:
166         dirList = os.listdir(start)
167     except:
168         if os.path.isdir(start):
169             print 'ERROR: Cannot list directory %s' % start
170         return files
171    
172     for item in dirList:
173         path = os.path.join(start, item)
174        
175         if os.path.isdir(path) and (followLinks or \
176                              (not followLinks and not islink(path))):
177             files.extend(listFiles(path, followLinks,
178                                   myDepth + 1,
179                                   maxDepth))
180         else:
181             files.append(path)
182
183     return files
184
185
186 def makeDocument(addons):
187     """Connect add-on elements to one XML document"""
188
189     doc = xml.dom.minidom.Document()
190     addonsElement = doc.createElement('opendict-add-ons')
191     doc.appendChild(addonsElement)
192
193     for addon in addons:
194         addonsElement.appendChild(addon)
195
196     return doc   
197
198
199 def main():
200     """Main procedure"""
201    
202     if len(sys.argv) < 3:
203         print "Usage: %s <directory> <base URL>" % sys.argv[0]
204         print "(Example: '%s . http://xxx.yyy.net/dicts')" % sys.argv[0]
205         sys.exit(1)
206
207     d = sys.argv[1]
208     baseURL = sys.argv[2]
209     xmlElements = []
210
211     for filePath in listFiles(d, True, 0, None):
212
213         try:
214             zipFile = zipfile.ZipFile(filePath, 'r')
215         except Exception, e:
216             print "ERROR: %s: %s" % (filePath, e)
217             continue
218        
219         # Test CRC
220         if zipFile.testzip():
221             raise Exception, _("Dictionary plugin file is corrupted")
222        
223         # Check if empty
224         try:
225             topDirectory = zipFile.namelist()[0]
226         except Exception, e:
227             raise Exception, _("Plugin file is empty (%s)" % e)
228        
229         # Check for validity
230         for fileInZip in zipFile.namelist():
231             dirName = os.path.dirname(fileInZip)
232             fileName = os.path.basename(fileInZip)
233
234         topDir = zipFile.namelist()[0]
235
236         plainConfigPath = os.path.join(topDir, 'conf', 'config.xml')
237         pluginConfigPath = os.path.join(topDir, 'plugin.xml')
238
239         info = {}
240
241         if plainConfigPath in zipFile.namelist():
242             info.update(parsePlainConfig(zipFile.read(plainConfigPath)))
243             info['type'] = 'plain-dictionary'
244         elif pluginConfigPath in zipFile.namelist():
245             info.update(parsePluginConfig(zipFile.read(pluginConfigPath)))
246             info['type'] = 'plugin-dictionary'
247
248         sz = os.stat(filePath)[6] / 1000
249
250         fd = open(filePath)
251         m = md5.new(fd.read())
252         fd.close()
253         checksum = m.hexdigest()
254
255         location = baseURL + '/' + filePath
256
257         xmlElements.append(generateElement(type=info.get('type'),
258                                            name=info.get('name'),
259                                            version=info.get('version'),
260                                            authors=info.get('authors'),
261                                            description=info.get('description'),
262                                            url=location,
263                                            md5sum=checksum,
264                                            size=sz))
265
266         print "* %s" % filePath
267
268     doc = makeDocument(xmlElements)
269     fd = open('opendict-add-ons.xml', 'w')
270     xml.dom.ext.PrettyPrint(doc, fd)
271     fd.close()
272    
273
274 if __name__ == "__main__":
275     main()
276    
Note: See TracBrowser for help on using the browser.