1
2 """ Utility functions
3
4 Can be used via a class or as functions"""
5
6 import sys
7 from PyFoam.ThirdParty.six import print_
8 from PyFoam.Error import warning
9 import subprocess
10 import os,fnmatch
11
12 if sys.version_info<(2,6):
13 from popen2 import popen4
14 else:
15 from subprocess import Popen,PIPE,STDOUT
16 from os import listdir,path,remove as removeFile
17
18 import re
19
20 try:
21 import shutil
22 except ImportError:
23
24 pass
25
27 """Class with utility methods
28
29 Can be inherited without side effects by classes that need these
30 methods"""
31
34
35 - def execute(self,cmd,debug=False,workdir=None,echo=None):
36 """Execute the command cmd. If specified change the working directory
37
38 Currently no error-handling is done
39 @return: A list with all the output-lines of the execution"""
40 if debug:
41 print_(cmd)
42
43 oldDir=None
44 if workdir:
45 oldDir=os.getcwd()
46 os.chdir(workdir)
47
48 if sys.version_info<(2,6):
49 raus,rein = popen4(cmd)
50 else:
51 p = Popen(cmd, shell=True,
52 stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
53 (rein,raus)=(p.stdin,p.stdout)
54 if echo!=None:
55 tmp=[]
56 while p.poll()==None:
57 l=raus.readline()
58 print_(echo,l,end="")
59 tmp.append(l)
60 else:
61 tmp=raus.readlines()
62
63
64
65
66
67 if oldDir:
68 os.chdir(oldDir)
69
70 return tmp
71
73 """Remove a file if it exists."""
74 if path.exists(f):
75 removeFile(f)
76
77 - def rmtree(self,dst,ignore_errors=False):
78 """Encapsulates the shutil rmtree and provides an alternative for
79 old Python-version"""
80 try:
81 if path.isdir(dst):
82 shutil.rmtree(dst,ignore_errors=ignore_errors)
83 else:
84 os.remove(dst)
85 except NameError:
86 self.execute("rm -rf "+dst)
87
88 - def copytree(self,src,dst,
89 symlinks=False,force=False):
90 """Encapsulates the shutil copytree and provides an alternative for
91 old Python-version"""
92 if force and path.exists(dst):
93 if path.isdir(dst):
94 self.rmtree(dst)
95 else:
96 os.remove(dst)
97 try:
98 if path.isdir(dst):
99 dst=path.join(dst,path.basename(path.abspath(src)))
100
101 if path.islink(src) and symlinks:
102 os.symlink(path.realpath(src),dst)
103 elif path.isdir(src):
104 shutil.copytree(src,dst,
105 symlinks=symlinks)
106 else:
107 self.copyfile(src,dst)
108 except NameError:
109 cpOptions="-R"
110 if not symlinks:
111 cpOptions+=" -L"
112 self.execute("cp "+cpOptions+" "+src+" "+dst)
113
115 """Encapsulates the shutil copyfile and provides an alternative for
116 old Python-version"""
117 try:
118 if path.isdir(dst):
119 dst=path.join(dst,path.basename(path.abspath(src)))
120 shutil.copyfile(src,dst)
121 shutil.copymode(src,dst)
122 except NameError:
123 self.execute("cp "+src+" "+dst)
124
126 """Writes a dummy header so OpenFOAM accepts the file as a dictionary
127 @param f: The file to write to
128 @type f: file"""
129
130 f.write("""
131 // * * * * * * * * * //
132 FoamFile
133 {
134 version 0.5;
135 format ascii;
136 root "ROOT";
137 case "CASE";
138 class dictionary;
139 object nix;
140 }
141 """)
142
143 excludeNames=["^.svn$" , "~$"]
144
146 """Lists the files in a directory, but excludes certain names
147 and files with certain endings
148 @param d: The directory to list
149 @return: List of the found files and directories"""
150
151 result=[]
152
153 excludes=list(map(re.compile,self.excludeNames))
154
155 for n in listdir(d):
156 ok=True
157
158 for e in excludes:
159 if e.search(n):
160 ok=False
161 break
162
163 if ok:
164 result.append(n)
165
166 return result
167
168 - def which(self,progname):
169 """Get the full path. Return None if not found"""
170 pipe = subprocess.Popen('which '+progname,
171 shell=True,
172 stdout=subprocess.PIPE,
173 stderr=subprocess.STDOUT)
174
175 (fullname, errout) = pipe.communicate(input=input)
176
177 stat = pipe.returncode
178
179 if stat:
180 warning("which can not find a match for",progname)
181 return None
182 else:
183 return fullname
184
185 - def find(self,pattern, path,directoriesToo=True):
186 """Find all files whose names match
187 @param pattern: glob-style pattern
188 @param path: path under which this files are to be searched
189 @param directoriesToo: also match directories?"""
190 result = []
191 for root, dirs, files in os.walk(path):
192 for name in files:
193 if fnmatch.fnmatch(name, pattern):
194 result.append(os.path.join(root, name))
195 if directoriesToo:
196 for name in dirs:
197 if fnmatch.fnmatch(name, pattern):
198 result.append(os.path.join(root, name))
199 return result
200
202 """Lifted from http://stackoverflow.com/questions/1094841/reusable-library-to-get-human-readable-version-of-file-size
203 Gets a number in bytes and returns a human readable string"""
204 for x in ['bytes','KB','MB','GB']:
205 if num < 1024.0 and num > -1024.0:
206 return "%3.1f%s" % (num, x)
207 num /= 1024.0
208 return "%3.1f%s" % (num, 'TB')
209
213
215 """Calls the method of the same name from the Utilites class"""
216 return Utilities().which(prog)
217
218 -def execute(cmd,debug=False,workdir=None,echo=None):
219 """Calls the method of the same name from the Utilites class"""
220 return Utilities().execute(cmd,debug,workdir,echo)
221
225
229
230 -def rmtree(path,ignore_errors=False):
231 """Calls the method of the same name from the Utilites class"""
232 return Utilities().rmtree(path,ignore_errors=ignore_errors)
233
234 -def copytree(src,dest,symlinks=False,force=False):
235 """Calls the method of the same name from the Utilites class"""
236 return Utilities().copytree(src,dest,symlinks=symlinks,force=force)
237
239 """Calls the method of the same name from the Utilites class"""
240 return Utilities().remove(f)
241
243 """Calls the method of the same name from the Utilites class"""
244 return Utilities().copyfile(src,dest)
245
246 -def find(pattern,path,directoriesToo=True):
247 """Calls the method of the same name from the Utilites class"""
248 return Utilities().find(pattern,path,directoriesToo=directoriesToo)
249
250
251