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 """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
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
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
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
241
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
273
277
278
279