root/trunk/lib/util.py

Revision 15, 8.7 kB (checked in by mjoc, 1 year ago)

Atnaujinti vertimai. Pridėti nauji copyright'ai. Pakeista konfigūracija.

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 Utility functions
24 """
25
26 import wx
27 _ = wx.GetTranslation
28
29 import os
30 import md5
31 import threading
32 import time
33 import urllib2
34 import traceback
35
36 from lib import info
37 from lib.logger import systemLog, debugLog, DEBUG, INFO, WARNING, ERROR
38
39
40 class UniqueIdGenerator:
41     """Unique ID generator (using singleton design pattern)"""
42
43
44     class _RealGenerator:
45         """Unique ID generator"""
46
47         def __init__(self, start=0):
48             """Set starting ID value"""
49            
50             self.id = start
51            
52            
53         def getID(self):
54             """Return unique ID"""
55            
56             self.id += 1
57             return self.id
58
59    
60     __instance = None
61
62
63     def __init__(self, start=0):
64         """Create new instance if not exists yet"""
65
66         if UniqueIdGenerator.__instance is None:
67             UniqueIdGenerator.__instance = self._RealGenerator(start)
68
69
70     def getID(self):
71         """Return unique ID"""
72
73         return self.__instance.getID()
74
75
76 def generateUniqueID():
77     """Helper function for getting unique ID"""
78
79     gen = UniqueIdGenerator(7000)
80     return gen.getID()
81
82
83 def getMD5Sum(filePath):
84     """Return MD5 checksum for given file"""
85
86
87     fd = open(filePath, 'rb')
88     data = fd.read()
89     fd.close()
90
91     generator = md5.new(data)
92
93     return generator.hexdigest()
94
95
96 def makeDirectories():
97     """Make needed directories if not exist"""
98
99     if not os.path.exists(info.LOCAL_HOME):
100         os.mkdir(info.LOCAL_HOME)
101
102     logDir = os.path.join(info.LOCAL_HOME, info.LOG_DIR)
103
104     if not os.path.exists(logDir):
105         os.mkdir(logDir)
106
107     plainDir = os.path.join(info.LOCAL_HOME,
108                             info.PLAIN_DICT_DIR)
109     pluginDir = os.path.join(info.LOCAL_HOME,
110                              info.PLUGIN_DICT_DIR)
111
112
113     if not os.path.exists(info.LOCAL_HOME):
114         try:
115             systemLog(DEBUG, "%s does not exist, creating..." \
116                       % info.LOCAL_HOME)
117             os.mkdir(info.LOCAL_HOME)
118         except Exception, e:
119             systemLog(ERROR, "Unable to create %s (%s)" % (info.LOCAL_HOME, e))
120
121     if not os.path.exists(os.path.join(info.LOCAL_HOME, info.__DICT_DIR)):
122         try:
123             systemLog(DEBUG, "%s does not exist, creating..." \
124                   % os.path.join(info.LOCAL_HOME, info.__DICT_DIR))
125             os.mkdir(os.path.join(info.LOCAL_HOME, info.__DICT_DIR))
126         except Exception, e:
127             systemLog(ERROR, "Unable to create %s (%s)" \
128                   % (os.path.join(info.LOCAL_HOME, info.__DICT_DIR), e))
129
130     if not os.path.exists(plainDir):
131         try:
132             systemLog(DEBUG, "%s does not exist, creating..." % plainDir)
133             os.mkdir(plainDir)
134         except Exception, e:
135             systemLog(ERROR, "Unable to create %s (%s)" % (plainDir, e))
136
137    
138     if not os.path.exists(pluginDir):
139         try:
140             os.mkdir(pluginDir)
141         except Exception, e:
142             systemLog(ERROR, "Unable to create %s (%s)" % (pluginDir, e))
143
144
145 class DownloadThread:
146     """Non-blocking download thread
147    
148     Can be used to connect and download files from the Internet.
149     """
150
151     def __init__(self, url):
152         """Initialize variables"""
153
154         self.url = url
155         self.thread = threading.Thread(target=self.worker)
156         self.thread.setDaemon(True) # Daemonize for fast exiting
157         self.statusMessage = ''
158         self.errorMessage = None
159         self.percents = 0
160         self.stopRequested = False
161         self.done = False
162         self.buffer = ''
163
164
165     def start(self):
166         """Start thread"""
167
168         self.thread.start()
169
170
171     def stop(self):
172         """Request thread to stop, may hang for some time"""
173
174         self.stopRequested = True
175
176
177     def getMessage(self):
178         """Return status message"""
179
180         return self.statusMessage
181
182
183     def getErrorMessage(self):
184         """Return error message"""
185
186         return self.errorMessage
187
188
189     def getPercentage(self):
190         """Return percentage"""
191
192         return self.percents
193
194
195     def finished(self):
196         """Return True if finished, False otherwise"""
197
198         return self.done
199
200
201     def getBytes(self):
202         """Return buffered bytes and clear the buffer"""
203
204         bytes = self.buffer
205         self.buffer = ''
206
207         return bytes
208
209
210     def worker(self):
211         """Main worker method"""
212
213         try:
214             serverName = '/'.join(self.url.split('/')[:3])
215         except:
216             serverName = self.url
217
218         try:
219             self.statusMessage = _("Connecting to %s...") % serverName
220             self.up = urllib2.urlopen(self.url)
221             fileSize = int(self.up.info().getheader('Content-length'))
222         except Exception, e:
223             self.errorMessage = "Unable to connect to %s" % serverName
224             self.done = True
225             return
226
227         count = 0
228
229         try:
230             while not self.stopRequested and count < fileSize:
231                 bytes = self.up.read(1024)
232                 count += len(bytes)
233                 self.buffer += bytes
234                 self.percents = int(float(count) / fileSize * 100)
235                 self.statusMessage = _("Downloading... %d%%") % self.percents
236                 time.sleep(0.005) # To lower CPU usage
237                
238             self.up.close()
239             self.done = True
240             self.statusMessage = _("Done")
241         except Exception, e:
242             self.errorMessage = "Error while fetching data from %s: %s" \
243                                 % (self.url, e)
244             self.done =  True
245
246
247
248 class AgreementsManager:
249     """Manages information about licence agreements for dictionaries"""
250
251     def __init__(self, filePath):
252         """Initialize variables"""
253
254         self.filePath = filePath
255         self.dictPaths = []
256
257         self._load()
258
259
260     def addAgreement(self, dictConfigPath):
261         """Mark dictionary licence as accepted"""
262
263         dictConfigPath = os.path.realpath(dictConfigPath)
264
265         if not dictConfigPath in self.dictPaths:
266             self.dictPaths.append(dictConfigPath)
267             self._updateFile()
268
269
270     def removeAgreement(self, dictConfigPath):
271         """Mark dictionary licence as rejected,
272         i.e. remove from accepted list"""
273
274         dictConfigPath = os.path.realpath(dictConfigPath)
275
276         if dictConfigPath in self.dictPaths:
277             self.dictPaths.remove(dictConfigPath)
278             self._updateFile()
279
280
281     def getAccepted(self, dictConfigPath):
282         """Return True if dictionary licence is marked as accepted"""
283
284         dictConfigPath = os.path.realpath(dictConfigPath)
285
286         if dictConfigPath in self.dictPaths:
287             return True
288         else:
289             return False
290
291
292     def _load(self):
293         """Read data from file"""
294
295         try:
296             fd = open(self.filePath)
297             update = False
298            
299             for line in fd:
300                 line = line.strip()
301                 if os.path.exists(line) and not line in self.dictPaths:
302                     self.dictPaths.append(line)
303                 else:
304                     update = True
305             fd.close()
306
307             # Rewrite contents if non-existent directories exist
308             if update:
309                 self._updateFile()
310         except:
311             pass
312
313
314     def _updateFile(self):
315         """Write changes to file"""
316
317         fd = open(self.filePath, 'w')
318         for path in self.dictPaths:
319             print >> fd, path
320         fd.close()
321
322
323 #
324 # FIXME: doesn't work correctly
325 #
326 def correctDictName(dictInstance):
327     """Set name to 'Name (X)', where X is Xth occurance of the name"""
328
329     return
330
331     def _nameMatches(name, nameList):
332         matches = 0
333         for n in nameList:
334             try:
335                 if n.startswith(name):
336                     matches += 1
337             except Exception, e:
338                 print "WARNING:", e
339         return matches
340
341     import wx
342     dictionaries = wx.GetApp().dictionaries # Sucks!
343
344     matches = _nameMatches(dictInstance.getName(), dictionaries.keys())
345
346     if matches:
347         dictInstance.setName("%s (%d)" % (dictInstance.getName(), matches+1))
348
Note: See TracBrowser for help on using the browser.