3 import os, sys, re, time
4 from PyJobTransformsCore
import dummyaccess, rfio
5 import stat
as statconsts
7 __doc__ =
"""A set of file utilities that can be used for several file systems (local files, rfio, castor)"""
11 defaultRetryMaxTime = 1.0
12 defaultRetryStartTime = 0.1
15 retryMaxTime = defaultRetryMaxTime,
16 retryStartTime = defaultRetryMaxTime ):
17 """Call function several times if it throws a <retryException>.
18 It will wait an increasing amount of time in between tries.
19 First waiting time is <retryStartTime>, which is increased by
20 a factor of 2 for each retry. It will give up and raise the
21 original exception if it still fails after a total retry time of <retryMaxTime>.
22 <func>: function to be called
23 <args>: tuple with the function arguments, or the single function argument"""
24 if type(args)
is not tuple: args = (args,)
25 retryDelay = retryStartTime
26 if retryDelay <= 0: retryDelay = 0.1
33 except retryException:
35 dt = time.time() - tStart
36 argsStr =
', '.
join( [
'%r' % a
for a
in args ] )
38 print (
"%s(%s) Failed" % (func.__name__,argsStr))
40 time.sleep(retryDelay)
42 print (
"Retrying %s(%s)" % (func.__name__,argsStr))
48 retryMaxTime = defaultRetryMaxTime,
49 retryStartTime = defaultRetryMaxTime ):
54 def __init__(self, name, matchPattern, replaceWith, baseModule, pathModule):
63 return re.search( self.
matchPat, filename )
is not None
71 IO_LOCAL =
AccessType(
'local' ,
r'(.*)' ,
r'\1' , os , os.path)
72 IO_RFIO =
AccessType(
'rfio' ,
r'^rfio:' ,
r'rfio:' , rfio, rfio)
73 IO_CASTOR =
AccessType(
'castor',
r'^(?:rfio:)?/castor/',
'rfio:/castor/', rfio, rfio)
74 IO_XROOTD =
AccessType(
'xrootd',
r'^root:' ,
r'root:' , dummyaccess, dummyaccess )
75 IO_LFN =
AccessType(
'lfn' ,
r'^LFN:' ,
r'LFN:' , dummyaccess, dummyaccess )
76 _accessTypes = ( IO_LFN, IO_XROOTD, IO_CASTOR, IO_RFIO, IO_LOCAL )
80 """A file utility like unix 'tee'. It writes any output to a file and to screen (stdout by default).
81 <option> if it has an 'a', append to logfile file, otherwise overwrite existing file."""
82 def __init__(self,filename,options='',screen=sys.stdout):
87 self.
f = open (filename,fileMode)
110 for at
in _accessTypes:
111 if at.matches( filename ):
return at
151 """Remove file <filename> if it exists. Only supported for local files."""
156 print (
"WARNING: file %s file %s can not be removed" %
161 """Test if a file exists in the same directory as <filename>, with the
162 same name, but with an additional suffix given as a regular expression
163 in <suffixRE>. It returns a list of all matching suffices, or an empty
164 list if no matching filename+suffix was found."""
166 dirname = os.path.dirname(filename)
or os.curdir
168 if not os.path.isdir(dirname):
return []
169 filename = os.path.basename(filename)
170 pat = re.compile(
'^%s(%s)' % (filename,suffixRE) )
173 sufs.append( pat.sub(
r'\1', f ) )
179 """Test if a file exists in the same directory as <filename>, with the same name,
180 but a non-negative integer added at the end of the name. It returns the filename
181 with the highest number added, or None if no such file exists."""
189 found = filename + suf
199 """Return the unix like string corresponding to the file access mode (rwxd etc)"""
202 if statconsts.S_ISDIR(mode):
204 elif statconsts.S_ISLNK(mode):
207 if mode & statconsts.S_IRUSR: modeList[1] =
'r'
208 if mode & statconsts.S_IWUSR: modeList[2] =
'w'
209 if mode & statconsts.S_ISUID: modeList[3] =
's'
210 elif mode & statconsts.S_IXUSR: modeList[3] =
'x'
212 if mode & statconsts.S_IRGRP: modeList[4] =
'r'
213 if mode & statconsts.S_IWGRP: modeList[5] =
'w'
214 if mode & statconsts.S_ISGID: modeList[6] =
's'
215 elif mode & statconsts.S_IXGRP: modeList[6] =
'x'
217 if mode & statconsts.S_IROTH: modeList[7] =
'r'
218 if mode & statconsts.S_IWOTH: modeList[8] =
'w'
219 if mode & statconsts.S_IXOTH: modeList[9] =
'x'
221 return ''.
join(modeList)