1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 import __builtin__
24
25
26 try:
27 from bz2 import BZ2File
28 __builtin__.bz2_module = 1
29 except ImportError, message:
30 __builtin__.bz2_module = 0
31 __builtin__.bz2_module_message = message.args[0]
32
33
34 from gzip import GzipFile
35
36
37 try:
38 from os import devnull
39 __builtin__.devnull_import = 1
40 except ImportError, message:
41 __builtin__.devnull_import = 0
42 __builtin__.devnull_import_message = message.args[0]
43
44 from os import F_OK, X_OK, access, altsep, getenv, makedirs, pathsep, remove, sep, stat
45 from os.path import expanduser
46 from re import match, search
47 from string import split
48 import sys
49 from sys import stdin, stdout, stderr
50
51
54 """Class containing the file operations.
55
56 IO streams
57 ~~~~~~~~~~
58
59 Standard python IO streams:
60
61 sys.stdin = self.python_stdin
62 sys.stdout = self.python_stdout
63 sys.stderr = self.python_stderr
64
65 Logging IO streams:
66
67 sys.stdin = self.log_stdin = self.python_stdin
68 sys.stdout = self.log_stdout = self.log_file
69 sys.stderr = self.log_stdout = (self.python_stderr, self.log_file)
70
71 Tee IO streams:
72
73 sys.stdin = self.tee_stdin = self.python_stdin
74 sys.stdout = self.tee_stdout = (self.python_stdout, self.tee_file)
75 sys.stderr = self.tee_stdout = (self.python_stderr, self.tee_file)
76 """
77
78 self.relax = relax
79
80
81 self.python_stdin = stdin
82 self.python_stdout = stdout
83 self.python_stderr = stderr
84
85
86 self.log_stdin = stdin
87 self.log_stdout = None
88 self.log_stderr = SplitIO()
89
90
91 self.tee_stdin = stdin
92 self.tee_stdout = SplitIO()
93 self.tee_stderr = SplitIO()
94
95
96 - def delete(self, file_name=None, dir=None):
114
115
117 """Open the file 'file' and return all the data."""
118
119
120 if not file_data:
121
122 file = self.open_read_file(file_name=file_name, dir=dir, compress_type=compress_type)
123
124
125 file_data = file.readlines()
126
127
128 data = []
129 for i in xrange(len(file_data)):
130 if sep:
131 row = split(file_data[i], sep)
132 else:
133 row = split(file_data[i])
134 data.append(row)
135 return data
136
137
138 if not file_data:
139 file.close()
140
141
142 - def file_path(self, file_name=None, dir=None):
157
158
159 - def log(self, file_name=None, dir=None, compress_type=0, print_flag=1):
160 """Function for turning logging on."""
161
162
163 self.log_file, file_path = self.open_write_file(file_name=file_name, dir=dir, force=1, compress_type=compress_type, print_flag=print_flag, return_path=1)
164
165
166 if print_flag:
167 print "Redirecting the sys.stdin IO stream to the python stdin IO stream."
168 print "Redirecting the sys.stdout IO stream to the log file '%s'." % file_path
169 print "Redirecting the sys.stderr IO stream to both the python stderr IO stream and the log file '%s'." % file_path
170
171
172 self.log_stdout = self.log_file
173 self.log_stderr.split(self.python_stderr, self.log_file)
174
175
176 sys.stdin = self.log_stdin
177 sys.stdout = self.log_stdout
178 sys.stderr = self.log_stderr
179
180
181 - def logging_off(self, file_name=None, dir=None, print_flag=1):
182 """Function for turning logging and teeing off."""
183
184
185 if print_flag:
186 print "Redirecting the sys.stdin IO stream to the python stdin IO stream."
187 print "Redirecting the sys.stdout IO stream to the python stdout IO stream."
188 print "Redirecting the sys.stderr IO stream to the python stderr IO stream."
189
190
191 sys.stdin = self.python_stdin
192 sys.stdout = self.python_stdout
193 sys.stderr = self.python_stderr
194
195
196 - def mkdir(self, dir=None, print_flag=1):
197 """Create the given directory, or exit if the directory exists."""
198
199
200 if dir == None:
201 return
202
203
204 try:
205 makedirs(dir)
206 except OSError:
207 if print_flag:
208 print "Directory ./" + dir + " already exists.\n"
209
210
211 - def open_read_file(self, file_name=None, dir=None, compress_type=0, print_flag=1):
212 """Open the file 'file' and return all the data."""
213
214
215 file_path = self.file_path(file_name, dir)
216
217
218 if access(file_path, F_OK):
219 compress_type = 0
220 if search('.bz2$', file_path):
221 compress_type = 1
222 elif search('.gz$', file_path):
223 compress_type = 2
224 elif access(file_path + '.bz2', F_OK):
225 file_path = file_path + '.bz2'
226 compress_type = 1
227 elif access(file_path + '.gz', F_OK):
228 file_path = file_path + '.gz'
229 compress_type = 2
230 else:
231 raise RelaxFileError, file_path
232
233
234 try:
235 if print_flag:
236 print "Opening the file " + `file_path` + " for reading."
237 if compress_type == 0:
238 file = open(file_path, 'r')
239 elif compress_type == 1:
240 if bz2_module:
241 file = BZ2File(file_path, 'r')
242 else:
243 raise RelaxError, "Cannot open the file " + `file_path` + ", try uncompressing first. " + bz2_module_message + "."
244 elif compress_type == 2:
245 file = GzipFile(file_path, 'r')
246 except IOError, message:
247 raise RelaxError, "Cannot open the file " + `file_path` + ". " + message.args[1] + "."
248
249
250 return file
251
252
253 - def open_write_file(self, file_name=None, dir=None, force=0, compress_type=0, print_flag=1, return_path=0):
254 """Function for opening a file for writing and creating directories if necessary."""
255
256
257 if search('devnull', file_name):
258
259 if not devnull_import:
260 raise RelaxError, devnull_import_message + ". To use devnull, please upgrade to Python >= 2.4."
261
262
263 if print_flag:
264 print "Opening the null device file for writing."
265
266
267 file = open(devnull, 'w')
268
269
270 if return_path:
271 return file, None
272 else:
273 return file
274
275
276 self.mkdir(dir, print_flag=0)
277
278
279 file_path = self.file_path(file_name, dir)
280
281
282 if compress_type == 1 and not search('.bz2$', file_path):
283
284 if bz2_module:
285 file_path = file_path + '.bz2'
286
287
288 else:
289 print "Cannot use bz2 compression, using gzip compression instead. " + bz2_module_message + "."
290 compress_type = 2
291
292
293 if compress_type == 2 and not search('.gz$', file_path):
294 file_path = file_path + '.gz'
295
296
297 if access(file_path, F_OK) and not force:
298 raise RelaxFileOverwriteError, (file_path, 'force flag')
299
300
301 try:
302 if print_flag:
303 print "Opening the file " + `file_path` + " for writing."
304 if compress_type == 0:
305 file = open(file_path, 'w')
306 elif compress_type == 1:
307 file = BZ2File(file_path, 'w')
308 elif compress_type == 2:
309 file = GzipFile(file_path, 'w')
310 except IOError, message:
311 raise RelaxError, "Cannot open the file " + `file_path` + ". " + message.args[1] + "."
312
313
314 if return_path:
315 return file, file_path
316 else:
317 return file
318
319
321 """Function to remove all comment and empty lines from the file data structure."""
322
323
324 new = []
325
326
327 for i in xrange(len(data)):
328
329 if len(data[i]) == 0:
330 continue
331
332
333 elif match("#", data[i][0]):
334 continue
335
336
337 else:
338 new.append(data[i])
339
340
341 return new
342
343
344 - def tee(self, file_name=None, dir=None, compress_type=0, print_flag=1):
345 """Function for turning logging on."""
346
347
348 self.tee_file, file_path = self.open_write_file(file_name=file_name, dir=dir, force=1, compress_type=compress_type, print_flag=print_flag, return_path=1)
349
350
351 if print_flag:
352 print "Redirecting the sys.stdin IO stream to the python stdin IO stream."
353 print "Redirecting the sys.stdout IO stream to both the python stdout IO stream and the log file '%s'." % file_path
354 print "Redirecting the sys.stderr IO stream to both the python stderr IO stream and the log file '%s'." % file_path
355
356
357 self.tee_stdout.split(self.python_stdout, self.tee_file)
358 self.tee_stderr.split(self.python_stderr, self.tee_file)
359
360
361 sys.stdin = self.tee_stdin
362 sys.stdout = self.tee_stdout
363 sys.stderr = self.tee_stderr
364
365
367 """Function for testing that the binary string corresponds to a valid executable file."""
368
369
370 if altsep:
371 path_sep = '[' + sep + altsep + ']'
372 else:
373 path_sep = sep
374
375
376 if search(path_sep, binary):
377
378 if not access(binary, F_OK):
379 raise RelaxMissingBinaryError, binary
380
381
382 if not access(binary, X_OK):
383 raise RelaxNonExecError, binary
384
385
386 else:
387
388 path = getenv('PATH')
389
390
391 path_list = split(path, pathsep)
392
393
394 for path in path_list:
395 if access(path + sep + binary, F_OK):
396 return
397
398
399 raise RelaxNoInPathError, binary
400
401
404 """Class for splitting an IO stream to two outputs."""
405
406
407 - def split(self, stream1, stream2):
408 """Function for setting the streams."""
409
410
411 self.stream1 = stream1
412 self.stream2 = stream2
413
414
416 """Replacement write function."""
417
418
419 self.stream1.write(text)
420
421
422 self.stream2.write(text)
423