Package PyFoam :: Package RunDictionary :: Module FileBasis
[hide private]
[frames] | no frames]

Source Code for Module PyFoam.RunDictionary.FileBasis

  1  #  ICE Revision: $Id$ 
  2  """Basis for the handling of OpenFOAM-files 
  3   
  4  Transparently accepts gnuzipped files""" 
  5   
  6  import os,re 
  7  from os import path 
  8  from tempfile import mktemp 
  9  import gzip 
 10   
 11   
 12  from PyFoam.Basics.Utilities import Utilities 
 13  from PyFoam.Basics.LineReader import LineReader 
 14   
 15  from PyFoam.Error import warning 
 16   
 17  from PyFoam.ThirdParty.six import PY3 
 18   
19 -class FileBasis(Utilities):
20 """ Base class for the other OpenFOAM--file-classes""" 21 22 removedString="//PyFoamRemoved: " 23 """Comment for lines that were overwritten by PyFoam-routines""" 24 25 addedString="//PyFoamAdded" 26 """Comment for lines that were added by PyFoam-routines""" 27
28 - def __init__(self,name,createZipped=True):
29 """@param name: Name of the file. If the field is zipped the .gz is 30 appended 31 @param createZipped: if the file doesnot exist: should it be created 32 as a zipped file?""" 33 self.name = path.abspath(name) 34 self.exists = False 35 36 if path.exists(self.name): 37 self.exists = True 38 self.zipped=False 39 if path.splitext(self.name)[1]==".gz": 40 self.zipped=True 41 elif path.exists(self.name+".gz"): 42 warning(self.name+".gz","and",self.name,"existing - using the unzipped") 43 elif path.exists(self.name+".gz"): 44 self.zipped=True 45 self.exists = True 46 else: 47 self.zipped=createZipped 48 49 if path.splitext(self.name)[1]==".gz": 50 self.name=self.name[:-3] 51 52 self.fh=None 53 self.content=None
54
55 - def realName(self):
56 """The full filename with appended .gz (if zipped)""" 57 if self.zipped: 58 return self.name+".gz" 59 else: 60 return self.name
61
62 - def baseName(self):
63 """Returns the basic file name (without .gz)""" 64 return path.basename(self.name)
65
66 - def openFile(self,keepContent=False,mode="r"):
67 """opens the file. To be overloaded by derived classes""" 68 if not keepContent: 69 self.content=None 70 if self.zipped: 71 self.fh=gzip.open(self.name+".gz",mode) 72 else: 73 self.fh=open(self.name,mode)
74
75 - def closeFile(self):
76 """ closes the file""" 77 self.fh.close() 78 self.fh=None
79
80 - def readFile(self):
81 """ read the whole File into memory""" 82 self.openFile() 83 txt=self.fh.read() 84 if PY3 and self.zipped: 85 txt=str(txt,"utf-8") 86 self.content=self.parse(txt) 87 self.closeFile()
88
89 - def writeFile(self,content=None):
90 """ write the whole File from memory 91 @param content: content that should replace the old content""" 92 if content!=None: 93 self.content=content 94 if self.content!=None: 95 self.openFile(keepContent=True,mode="w") 96 txt=str(self) 97 self.fh.write(self.encode(txt)) 98 self.closeFile()
99
100 - def encode(self,txt):
101 """Encode a string to byte if necessary (for Python3)""" 102 if PY3 and self.zipped: 103 return bytes(txt,"utf-8") 104 else: 105 return txt
106
107 - def writeFileAs(self,name):
108 """ Writes a copy of the file. Extends with .gz if the original 109 is zipped 110 @param name: Name under which the file is written""" 111 if path.abspath(self.name)==path.abspath(name): 112 warning(name,"and",self.name,"seem to be the same. Nothing done") 113 return 114 115 erase=False 116 if self.content==None: 117 erase=True 118 self.readFile() 119 120 tmp=self.name 121 self.name=name 122 self.writeFile() 123 self.name=tmp 124 125 if erase: 126 self.content=None
127
128 - def parse(self,cnt):
129 """ Parse a string that is to be the content, to be overriden 130 by the sub-classes""" 131 132 return cnt
133
134 - def __str__(self):
135 """Build a string from self.content, to be overriden by sub-classes""" 136 137 return self.content
138
139 - def makeTemp(self):
140 """creates a temporary file""" 141 fn=mktemp(dir=path.dirname(self.name)) 142 if self.zipped: 143 fh=gzip.open(fn,"w") 144 else: 145 fh=open(fn,"w") 146 147 return fh,fn
148
149 - def writeEncoded(self,out,txt):
150 """Convert the text to 'bytes' is we encounter a zipped file""" 151 if PY3: 152 if type(out) is gzip.GzipFile: 153 txt=bytes(txt,"utf-8") 154 out.write(txt)
155
156 - def goTo(self,l,s,out=None,echoLast=False,stop=None):
157 """Read lines until a token is found 158 159 @param l: a LineReader object 160 @param s: the string to look for 161 @param out: filehandle to echo the lines to 162 @param stop: pattern that indicates that exp will never be found (only passed through to goMatch) 163 @param echoLast: echo the line with the string""" 164 exp=re.compile("( |^)"+s+"( |$)") 165 self.goMatch(l,exp,out=out,stop=stop) 166 if out!=None and echoLast: 167 self.writeEncoded(out,l.line+"\n")
168
169 - def goMatch(self,l,exp,out=None,stop=None):
170 """Read lines until a regular expression is matched 171 172 @param l: a LineReader object 173 @param exp: the expression to look for 174 @param out: filehandle to echo the lines to 175 @param stop: pattern that indicates that exp will never be found 176 @return: match-object if exp is found, the line if stop is found and None if the end of the file is reached""" 177 while l.read(self.fh): 178 m=exp.match(l.line) 179 if m!=None: 180 return m 181 elif stop!=None: 182 if stop.match(l.line): 183 return l.line 184 if out!=None: 185 self.writeEncoded(out,l.line+"\n") 186 187 return None
188
189 - def copyRest(self,l,out):
190 """Copy the rest of the file 191 192 @param l: a LineReader object 193 @param out: filehandle to echo the lines to""" 194 while l.read(self.fh): 195 self.writeEncoded(out,l.line+"\n")
196
197 - def purgeFile(self):
198 """Undo all the manipulations done by PyFOAM 199 200 Goes through the file and removes all lines that were added""" 201 rmExp= re.compile("^"+self.removedString+"(.*)$") 202 addExp=re.compile("^(.*)"+self.addedString+"$") 203 204 l=LineReader() 205 self.openFile() 206 207 (fh,fn)=self.makeTemp() 208 209 while l.read(self.fh): 210 toPrint=l.line 211 212 m=addExp.match(l.line) 213 if m!=None: 214 continue 215 216 m=rmExp.match(l.line) 217 if m!=None: 218 toPrint=m.group(1) 219 220 self.writeEncoded(fh,toPrint+"\n") 221 222 self.closeFile() 223 fh.close() 224 os.rename(fn,self.name)
225
226 - def getCaseDir(self):
227 """Return the path to the case of this file (if any valid case is found). 228 Else return None""" 229 230 from .SolutionDirectory import NoTouchSolutionDirectory 231 232 caseDir=None 233 comp=path.split(self.name)[0] 234 while len(comp)>1: 235 if NoTouchSolutionDirectory(comp).isValid(): 236 caseDir=comp 237 break 238 comp=path.split(comp)[0] 239 240 return caseDir
241
242 -class FileBasisBackup(FileBasis):
243 """A file with a backup-copy""" 244 245 counter={} 246
247 - def __init__(self,name,backup=False,createZipped=True):
248 """@param name: The name of the parameter file 249 @type name: str 250 @param backup: create a backup-copy of the file 251 @type backup: boolean""" 252 253 FileBasis.__init__(self,name,createZipped=createZipped) 254 255 if backup: 256 self.backupName=self.name+".backup" 257 try: 258 FileBasisBackup.counter[self.name]+=1 259 except KeyError: 260 FileBasisBackup.counter[self.name]=1 261 self.copyfile(self.name,self.backupName) 262 else: 263 self.backupName=None
264
265 - def restore(self):
266 """if a backup-copy was made the file is restored from this""" 267 if self.backupName!=None: 268 FileBasisBackup.counter[self.name]-=1 269 if FileBasisBackup.counter[self.name]==0: 270 self.copyfile(self.backupName,self.name) 271 self.remove(self.backupName) 272 del FileBasisBackup.counter[self.name]
273
274 -def exists(name):
275 f=FileBasis(name) 276 return f.exists
277 278 # Should work with Python3 and Python2 279