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 __enter__(self):
140 """Making the 'with'-statement happy""" 141 return self
142
143 - def __exit__(self,typ,value,traceback):
144 """Making the 'with'-statement happy""" 145 if self.fh!=None: 146 self.closeFile()
147
148 - def makeTemp(self):
149 """creates a temporary file""" 150 fn=mktemp(dir=path.dirname(self.name)) 151 if self.zipped: 152 fh=gzip.open(fn,"w") 153 else: 154 fh=open(fn,"w") 155 156 return fh,fn
157
158 - def writeEncoded(self,out,txt):
159 """Convert the text to 'bytes' is we encounter a zipped file""" 160 if PY3: 161 if type(out) is gzip.GzipFile: 162 txt=bytes(txt,"utf-8") 163 out.write(txt)
164
165 - def goTo(self,l,s,out=None,echoLast=False,stop=None):
166 """Read lines until a token is found 167 168 @param l: a LineReader object 169 @param s: the string to look for 170 @param out: filehandle to echo the lines to 171 @param stop: pattern that indicates that exp will never be found (only passed through to goMatch) 172 @param echoLast: echo the line with the string""" 173 exp=re.compile("( |^)"+s+"( |$)") 174 self.goMatch(l,exp,out=out,stop=stop) 175 if out!=None and echoLast: 176 self.writeEncoded(out,l.line+"\n")
177
178 - def goMatch(self,l,exp,out=None,stop=None):
179 """Read lines until a regular expression is matched 180 181 @param l: a LineReader object 182 @param exp: the expression to look for 183 @param out: filehandle to echo the lines to 184 @param stop: pattern that indicates that exp will never be found 185 @return: match-object if exp is found, the line if stop is found and None if the end of the file is reached""" 186 while l.read(self.fh): 187 m=exp.match(l.line) 188 if m!=None: 189 return m 190 elif stop!=None: 191 if stop.match(l.line): 192 return l.line 193 if out!=None: 194 self.writeEncoded(out,l.line+"\n") 195 196 return None
197
198 - def copyRest(self,l,out):
199 """Copy the rest of the file 200 201 @param l: a LineReader object 202 @param out: filehandle to echo the lines to""" 203 while l.read(self.fh): 204 self.writeEncoded(out,l.line+"\n")
205
206 - def purgeFile(self):
207 """Undo all the manipulations done by PyFOAM 208 209 Goes through the file and removes all lines that were added""" 210 rmExp= re.compile("^"+self.removedString+"(.*)$") 211 addExp=re.compile("^(.*)"+self.addedString+"$") 212 213 l=LineReader() 214 self.openFile() 215 216 (fh,fn)=self.makeTemp() 217 218 while l.read(self.fh): 219 toPrint=l.line 220 221 m=addExp.match(l.line) 222 if m!=None: 223 continue 224 225 m=rmExp.match(l.line) 226 if m!=None: 227 toPrint=m.group(1) 228 229 self.writeEncoded(fh,toPrint+"\n") 230 231 self.closeFile() 232 fh.close() 233 os.rename(fn,self.name)
234
235 - def getCaseDir(self):
236 """Return the path to the case of this file (if any valid case is found). 237 Else return None""" 238 239 from .SolutionDirectory import NoTouchSolutionDirectory 240 241 caseDir=None 242 comp=path.split(self.name)[0] 243 while len(comp)>1: 244 if NoTouchSolutionDirectory(comp).isValid(): 245 caseDir=comp 246 break 247 comp=path.split(comp)[0] 248 249 return caseDir
250
251 -class FileBasisBackup(FileBasis):
252 """A file with a backup-copy""" 253 254 counter={} 255
256 - def __init__(self,name,backup=False,createZipped=True):
257 """@param name: The name of the parameter file 258 @type name: str 259 @param backup: create a backup-copy of the file 260 @type backup: boolean""" 261 262 FileBasis.__init__(self,name,createZipped=createZipped) 263 264 if backup: 265 self.backupName=self.name+".backup" 266 try: 267 FileBasisBackup.counter[self.name]+=1 268 except KeyError: 269 FileBasisBackup.counter[self.name]=1 270 self.copyfile(self.name,self.backupName) 271 else: 272 self.backupName=None
273
274 - def restore(self):
275 """if a backup-copy was made the file is restored from this""" 276 if self.backupName!=None: 277 FileBasisBackup.counter[self.name]-=1 278 if FileBasisBackup.counter[self.name]==0: 279 self.copyfile(self.backupName,self.name) 280 self.remove(self.backupName) 281 del FileBasisBackup.counter[self.name]
282
283 -def exists(name):
284 f=FileBasis(name) 285 return f.exists
286 287 # Should work with Python3 and Python2 288