1
2
3
4
5
6 import sys
7 import os
8 import types
9 import time
10 import errno
11 import atexit
12 import random
13
14
15
16
17
18
19
20
21
22
23
25 timestamp = '%.7f' % time.time()
26 for p in range(3):
27 timestamp += str(random.randint(0,9))
28 return timestamp
29
30
32 """newGUID(value = None) --> guid value - any python object"""
33 tt = time.gmtime()[0:6] + (random.randint(0,9),
34 random.randint(0,9),
35 random.randint(0,9),
36 random.randint(0,9),
37 random.randint(0,9),
38 random.randint(0,9),
39 random.randint(0,9),
40 random.randint(0,9),
41 random.randint(0,9),
42 id(value))
43 return '_' + (''.join(map(str, tt))).replace('-','')
44
45
47 tries = 0
48 while True:
49 tries = tries +1
50 try:
51 guid += '\0'
52 fd = os.open(lockfile, os.O_WRONLY | os.O_CREAT | os.O_EXCL)
53 try:
54 guidlen = os.write(fd, guid)
55 finally:
56 os.close(fd)
57 fd = os.open(lockfile, os.O_RDONLY)
58 try:
59 f_guid = os.read(fd, guidlen)
60 finally:
61 os.close(fd)
62 if f_guid != guid:
63 raise OSError("Guids mismatch in the lock file")
64 except OSError, e:
65 if tries > tries_limit:
66 return False
67 time.sleep(0.05)
68 else:
69 return True
70
71
73 try:
74 os.remove(lockfile)
75 except OSError, e:
76 if e[0] != errno.ENOENT:
77 return False
78 return True
79
80
81
83 - def __init__(self, lockfile = 'Lock', tries_limit = 200):
84 self.lockfile = lockfile
85 self.guid = newGuid(self)
86 self.counter = 0
87 self.tries_limit = tries_limit
88 atexit.register(self.remove)
89
91 if self.counter == 0:
92 if not createLock(self.lockfile, self.guid, self.tries_limit):
93 return False
94 self.counter += 1
95 return True
96
98 if self.counter > 0:
99 if self.counter == 1:
100 if not removeLock(self.lockfile):
101 return
102 self.counter -= 1
103
105 if self.counter == 0:
106 try:
107 f = file(self.lockfile, 'r')
108 try:
109 f_guid = f.read()
110 finally:
111 f.close()
112 except:
113 return
114 if f_guid.endswith('\0'):
115 if f_guid.rstrip('\0') != self.guid:
116 return
117 removeLock(self.lockfile)
118 self.counter = 0
119
120
123 self.fn = fn
124 self.tmp = tmp
126 ff = fn.split('_')
127 fflen = len(ff)
128 if fflen > 1:
129 if ff[0] == self.fn:
130 if self.tmp:
131 if fflen == 3:
132 if ff[2] == '':
133 return True
134 else:
135 if fflen == 2:
136 if ff[1] != '':
137 return True
138 return False
139
140
147
148
150
151 fn = os.path.basename(fn)
152 ff = fn.split('_')
153 if len(ff) > 1:
154 return ff[1].split('.')
155 return (0,0)
156
157
159 x, y = map(getTimeStamp, (x,y))
160 if x[0] < y[0]:
161 return -1
162 elif x[0] == y[0]:
163 if x[1] < y[1]:
164 return -1
165 elif x[1] == y[1]:
166 return 0
167 elif x[1] > y[1]:
168 return 1
169 elif x[0] > y[0]:
170 return 1
171
172
173 -def getHistory(fn, tmp = False):
174
175 dirname, basename = os.path.split(os.path.abspath(fn))
176 ffs = filter(Filterer(basename, tmp), listFiles(dirname))
177 ffs.sort(sorter)
178 return (dirname, ffs)
179
180
182
183 dirname, ffs = getHistory(fn)
184 ffs.reverse()
185 for hf in ffs:
186 hfn = os.path.join(dirname, hf)
187 tmp_fn = hfn + '_'
188 if not os.path.isfile(tmp_fn):
189 break
190 else:
191 raise OSError("Can not find file %s" % fn)
192 return hfn
193
194
195 -def __fillEntry(entries, lentr, i, f):
196
197 line = f.readline()
198 line = line.rstrip('\n')
199 if not line:
200 return False
201 fields = line.split('\0')
202 if i < lentr:
203 entries[i] = fields
204 else:
205 entries.append(fields)
206 return True
207
208
209 -def read(fn, entries = None):
210
211
212
213
214
215 if entries == None:
216 entries = []
217 lentr = len(entries)
218 i = 0
219 f = open(fn, 'r')
220 try:
221 while __fillEntry(entries, lentr, i, f):
222 i += 1
223 return (entries, i)
224 finally:
225 f.close()
226
227
231
232
233 -def move(tmp_fn, fn, tries_limit = 200):
234
235 if os.path.isfile(fn):
236 raise OSError("File exists %s" % fn)
237 os.rename(tmp_fn, fn)
238
239 tries = 0
240 while True:
241 tries = tries +1
242 if os.path.isfile(tmp_fn) or not os.path.isfile(fn):
243 if tries > tries_limit:
244 raise OSError("Can not rename file %s" % tmp_fn)
245 time.sleep(0.05)
246 else:
247 return
248
249
250 -def remove(fn, tries_limit = 200):
251
252 dirname, ffs = getHistory(fn, tmp = False)
253 for hf in ffs:
254 fn = os.path.join(dirname, hf)
255 os.remove(fn)
256
257 tries = 0
258 while True:
259 tries = tries +1
260 if os.path.isfile(fn):
261 if tries > tries_limit:
262 raise OSError("Can not remove file %s" % fn)
263 time.sleep(0.05)
264 else:
265 return
266
267
268 -def write(entries, fn, lines_to_write = -1, tries_limit = 200):
269
270 dirname, ffs = getHistory(fn, tmp = False)
271 dirname, hfs = getHistory(fn, tmp = True)
272 fn = '_'.join([fn, timestampMethod()])
273 tmp_fn = fn + '_'
274 f = open(tmp_fn, 'w')
275 try:
276 for entry in entries:
277 if lines_to_write == 0:
278 break
279 lines_to_write -= 1
280 if not len(entry):
281 continue
282 line=''
283 for field in entry:
284 if len(line):
285 line += '\0'
286 line += str(field)
287 f.write(line + '\n')
288 finally:
289 f.close()
290 move(tmp_fn, fn, tries_limit)
291 for fls in [ffs, hfs]:
292 for hf in fls:
293 hf = os.path.join(dirname, hf)
294 try:
295 os.remove(hf)
296 except OSError:
297 pass
298 return fn
299