root/trunk/lib/plaindict.py

Revision 26, 12.9 kB (checked in by nerijusb, 9 months ago)

fix local variable 'Parser' referenced before assignment and strip whitespace from more xml data

Line 
1 #
2 # OpenDict
3 # Copyright (c) 2003-2006 Martynas Jocius <martynas.jocius@idiles.com>
4 # Copyright (c) 2007 IDILES SYSTEMS, UAB <support@idiles.com>
5 #
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your opinion) any later version.
10 #
11 # This program is distributed in the hope that will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MECHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more detals.
15 #
16 # You shoud have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 # 02111-1307 USA
20 #
21
22 """
23 Module for plain dictionaries
24 """
25
26 import os
27 import traceback
28
29 from lib import info
30 from lib import meta
31 from lib import util
32 from lib import xmltools
33 from lib import util
34 from lib.logger import systemLog, debugLog, DEBUG, INFO, WARNING, ERROR
35
36
37 class PlainDictInfo:
38     """Plain dictionary configuration"""
39
40     def __init__(self, directory):
41         """Store configuration data"""
42
43         raise Exception, "PlainDictInfo is deprecated"
44
45         self.config = xmltools.parsePlainDictConfig(\
46                 os.path.join(directory,
47                              info.__PLAIN_DICT_CONFIG_DIR,
48                              'config.xml'))
49
50         self.directory = directory
51
52         self.name = config.get('name')
53         self.formatString = config.get('format')
54         self.version = config.get('version')
55         self.author = config.get('author')
56         self.path = config.get('path')
57         self.checksum = config.get('md5')
58         self.encoding = config.get('encoding')
59
60
61     def getFormatString(self):
62         """Return format name"""
63
64         return self.formatString
65
66
67     def getName(self):
68         """Return name"""
69
70         return self.name
71
72
73     def getVersion(self):
74         """Return version number"""
75
76         return self.version
77
78
79     def getAuthor(self):
80         """Return author"""
81
82         return self.author
83
84
85     def getPath(self):
86         """Return full file path"""
87
88         return self.path
89
90
91     def getChecksum(self):
92         """Return checksum"""
93
94         return self.checksum
95
96
97     def getEncoding(self):
98         """Return encoding"""
99
100         return self.encoding
101
102
103     def getLicence(self):
104         """Return licence text"""
105
106         filePath = self.licence
107
108         if filePath:
109             if not os.path.exists(filePath):
110                 filePath = os.path.join(self.directory,
111                                         info._PLAIN_DICT_DATA_DIR,
112                                         self.licence)
113                 if not os.path.exists(filePath):
114                     filePath = None
115
116             errMsg = "Error: <i>licence file not found</i>"
117
118             if not filePath:
119                 systemLog(ERROR, "Cannot find defined licence file for %s: %" \
120                           % (self.getName(), e))
121                 return errMsg
122
123             try:
124                 fd = open(filePath)
125                 data = fd.read()
126                 fd.close()
127                 return data
128             except Exception, e:
129                 systemLog(ERROR, "Unable to read licence file for %s: %" \
130                           % (self.getName(), e))
131                 return errMsg
132
133         return None
134
135
136
137 class PlainDictionary(meta.Dictionary):
138     """Plain dictionary class"""
139
140     licenceFile = None
141     version = None
142     authors = []
143    
144
145     def getConfigDir(self):
146         """Return configuration directory path"""
147        
148         if os.path.exists(os.path.join(info.LOCAL_HOME,
149                                        info.PLAIN_DICT_DIR,
150                                        os.path.basename(self.getPath()))):
151             path = os.path.join(info.LOCAL_HOME,
152                                 info.PLAIN_DICT_DIR,
153                                 os.path.basename(self.getPath()))
154         else:
155             path = os.path.join(info.GLOBAL_HOME,
156                                 info.PLAIN_DICT_DIR,
157                                 os.path.basename(self.getPath()))
158            
159         return path
160    
161    
162     def setLicenceFile(self, licenceFile):
163         """Set licence file path"""
164        
165         self.licenceFile = licenceFile
166
167
168     def getLicenceFile(self):
169         """Return licence file"""
170
171         return self.licenceFile
172        
173        
174     def getLicence(self):
175         """Return licence text"""
176        
177         filePath = self.licenceFile
178
179         if filePath:
180             if not os.path.exists(filePath):
181                 filePath = os.path.join(self.getConfigDir(),
182                                         info._PLAIN_DICT_DATA_DIR,
183                                         self.licenceFile)
184
185                 if not os.path.exists(filePath):
186                     filePath = None
187
188             errMsg = "Error: <i>licence file not found</i>"
189
190             if not filePath:
191                 systemLog(ERROR,
192                           "Cannot find defined licence file '%s' for '%s'" \
193                           % (self.licenceFile, self.getName()))
194                 return errMsg
195
196             try:
197                 fd = open(filePath)
198                 data = fd.read()
199                 fd.close()
200                 return data
201             except Exception, e:
202                 systemLog(ERROR, "Unable to read licence file for %s: %" \
203                           % (self.getName(), e))
204                 return errMsg
205
206         return None
207
208
209     def setVersion(self, version):
210         """Set version number"""
211
212         self.version = version
213
214
215     def getVersion(self):
216         """Return version number"""
217
218         return self.version
219
220
221     def setAuthors(self, authors):
222         """Set author"""
223
224         self.authors = authors
225
226
227     def getAuthors(self):
228         """Return author"""
229
230         return self.authors
231
232
233     def setDescription(self, desc):
234         """Set description"""
235
236         self.description = desc
237
238
239     def getDescription(self):
240         """Get description"""
241
242         return self.description
243    
244
245
246 def _loadPlainDictionary(directory):
247     """Load one dictionary and returns dictionary object"""
248
249     from lib import dicttype
250     dictionary = None
251     Parser = None
252
253     try:
254         config = xmltools.parsePlainDictConfig(\
255                 os.path.join(directory,
256                              info.__PLAIN_DICT_CONFIG_DIR,
257                              'config.xml'))
258
259         for t in dicttype.supportedTypes:
260             if t.getIdName() == config.get('format'):
261                 Parser = t.getClass()
262
263         if not Parser:
264             raise Exception, "This is internal error and should not happen: " \
265                   "no parser class found for dictionary in %s" % directory
266
267         filePath = config.get('path')
268         fileName = os.path.basename(filePath)
269         home = info.LOCAL_HOME
270         if directory.startswith(info.GLOBAL_HOME):
271             home = info.GLOBAL_HOME
272
273         if not os.path.exists(filePath):
274             newPath = os.path.join(home, info.PLAIN_DICT_DIR,
275                                    fileName, info.__PLAIN_DICT_FILE_DIR,
276                                    fileName)
277             if os.path.exists(newPath):
278                 filePath = newPath
279             else:
280                 filePath = None
281
282            
283         if not filePath:
284             raise Exception, "Dictionary file not found: %s" % fileName
285
286         dictionary = Parser(filePath)
287         dictionary.setEncoding(config.get('encoding'))
288         dictionary.setName(config.get('name'))
289         dictionary.setVersion(config.get('version'))
290         dictionary.setAuthors(config.get('authors'))
291         dictionary.setChecksum(config.get('md5'))
292         dictionary.setLicenceFile(config.get('licence'))
293         dictionary.setDescription(config.get('description'))
294
295     except Exception, e:
296         traceback.print_exc()
297
298     util.correctDictName(dictionary)
299     return dictionary
300
301
302 def loadPlainDictionaries(dictionaries):
303     """Load dictionaries and return a list of dictionary objects"""
304
305
306     dirs = []
307     globalDictDir = os.path.join(info.GLOBAL_HOME,
308                                  info.PLAIN_DICT_DIR)
309     localDictDir = os.path.join(info.LOCAL_HOME,
310                                 info.PLAIN_DICT_DIR)
311
312
313     if os.path.exists(globalDictDir):
314         for directory in os.listdir(globalDictDir):
315             if os.path.isdir(os.path.join(globalDictDir, directory)):
316                 dirs.append(os.path.join(globalDictDir, directory))
317
318     if os.path.exists(localDictDir):
319         for directory in os.listdir(localDictDir):
320             if os.path.isdir(os.path.join(localDictDir, directory)):
321                 dirs.append(os.path.join(localDictDir, directory))
322
323
324     plainDicts = []
325
326     for directory in dirs:
327         dictionary = _loadPlainDictionary(directory)
328         if dictionary:
329             plainDicts.append(dictionary)
330             dictionaries[dictionary.getName()] = dictionary
331        
332     return plainDicts
333
334
335
336 def indexShouldBeMade(dictionary):
337     """Check if index exists and is up to date.
338
339     Return True if dictionary must be indexed.
340     """
341
342     filePath = dictionary.getPath()
343     fileName = os.path.basename(filePath)
344
345     dictLocalHome = os.path.join(info.LOCAL_HOME,
346                                  info.PLAIN_DICT_DIR,
347                                  fileName)
348
349     dictGlobalHome = os.path.join(info.GLOBAL_HOME,
350                                   info.PLAIN_DICT_DIR,
351                                   fileName)
352
353     if not os.path.exists(os.path.join(dictGlobalHome, 'data', 'index.xml')) \
354            and not os.path.exists(os.path.join(dictLocalHome, 'data',
355                                                'index.xml')):
356         return True
357
358     debugLog(INFO, "Old checksum: %s" % dictionary.getChecksum())
359     newChecksum = util.getMD5Sum(filePath)
360     debugLog(INFO, "New checksum: %s" % newChecksum)
361
362     return dictionary.getChecksum() != newChecksum
363
364
365
366 def makeIndex(dictionary, currentlySetEncoding):
367     """Index dictionary"""
368
369     filePath = dictionary.getPath()
370     fd = open(filePath)
371
372     index = {}
373     count = 0L
374     linenum = -1
375    
376     for line in fd:
377         linenum += 1
378         try:
379             literal = unicode(line.strip(),
380                               dictionary.getEncoding())[:2].lower()
381         except:
382             try:
383                 literal = unicode(line.strip(),
384                                   currentlySetEncoding)[:2].lower()
385                 dictionary.setEncoding(currentlySetEncoding)
386             except:
387                 raise Exception, "Unable to encode data in %s nor %s " \
388                       "at line %d" \
389                       % (dictionary.getEncoding(), currentlySetEncoding,
390                          linenum)
391
392         # Ignore if control character found
393         if literal and not literal in index.keys() and literal[0] > u'\x19':
394             try:
395                 index[literal] = count
396             except Exception, e:
397                 systemLog(ERROR, e)
398
399         count += len(line)
400
401
402     fileName = os.path.basename(filePath)
403
404     dictHome = os.path.join(info.LOCAL_HOME,
405                             info.PLAIN_DICT_DIR,
406                             fileName)
407
408
409     toUnicode = lambda s: unicode(s, dictionary.getEncoding())
410
411     doc = xmltools.generateIndexFile(index)
412     xmltools.writeIndexFile(doc, os.path.join(dictHome, 'data', 'index.xml'))
413
414     savePlainConfiguration(dictionary)
415
416
417
418 def loadIndex(dictionary):
419     """Load index table"""
420
421     dictIndex = os.path.join(dictionary.getConfigDir(),
422                                  'data', 'index.xml')
423
424     index = None
425
426     if os.path.exists(dictIndex):
427         index = xmltools.parseIndexFile(dictIndex)
428     if not index:
429         raise Exception, "Index for %s does not exist" % dictionary.getName()
430
431     return index
432      
433
434 def savePlainConfiguration(dictionary):
435     """Write configuration to disk"""
436
437     from lib import dicttype
438
439     if not dictionary.getType() in dicttype.plainTypes:
440        systemLog(ERROR, "Request to write configuration to %s of type %s" \
441            % (dictionary.getName(), dictionary.getType()))
442        return
443
444     md5sum = util.getMD5Sum(dictionary.getPath())
445     dictDir = dictionary.getConfigDir()
446
447     doc = xmltools.generatePlainDictConfig(name=dictionary.getName(),
448                                            format=dictionary.getType().getIdName(),
449                                            version=dictionary.getVersion(),
450                                            authors=dictionary.getAuthors(),
451                                            path=dictionary.getPath(),
452                                            md5=md5sum,
453                                            encoding=dictionary.getEncoding(),
454                                            description=dictionary.getDescription(),
455                                            licence=dictionary.getLicenceFile())
456
457     xmltools.writePlainDictConfig(doc, os.path.join(dictDir,
458                                                     'conf',
459                                                     'config.xml'))
Note: See TracBrowser for help on using the browser.