1
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
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
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
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
76 """ closes the file"""
77 self.fh.close()
78 self.fh=None
79
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
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
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
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
129 """ Parse a string that is to be the content, to be overriden
130 by the sub-classes"""
131
132 return cnt
133
135 """Build a string from self.content, to be overriden by sub-classes"""
136
137 return self.content
138
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
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
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
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
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
250
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
282
286
287
288