1 """
2 Application-class that implements pyFoamListCases.py
3 """
4 from optparse import OptionGroup
5 from os import path,listdir,stat
6 import time
7 from stat import ST_MTIME
8 import string
9 import subprocess
10 import re
11
12 from PyFoamApplication import PyFoamApplication
13
14 from PyFoam.RunDictionary.SolutionDirectory import SolutionDirectory
15
16 from PyFoam import configuration
17
20 description="""
21 List the valid OpenFOAM-cases in a number of directories along with some
22 basic information (number of timesteps, last timestep, etc). Currently
23 doesn't honor the parallel data
24 """
25 PyFoamApplication.__init__(self,
26 args=args,
27 description=description,
28 usage="%prog [<directories>]",
29 interspersed=True,
30 changeVersion=False,
31 nr=0,
32 exactNr=False)
33
34 sortChoices=["name","first","last","mtime","nrSteps","procs","diskusage","pFirst","pLast","nrParallel"]
35
37 what=OptionGroup(self.parser,
38 "What",
39 "Define what should be shown")
40 self.parser.add_option_group(what)
41
42 what.add_option("--dump",
43 action="store_true",
44 dest="dump",
45 default=False,
46 help="Dump the information as Python-dictionaries")
47
48 what.add_option("--disk-usage",
49 action="store_true",
50 dest="diskusage",
51 default=False,
52 help="Show the disk-usage of the case (in MB) - may take a long time")
53
54 what.add_option("--parallel-info",
55 action="store_true",
56 dest="parallel",
57 default=False,
58 help="Print information about parallel runs (if present): number of processors and processor first and last time. The mtime will be that of the processor-directories")
59
60 how=OptionGroup(self.parser,
61 "How",
62 "How the things should be shown")
63 self.parser.add_option_group(how)
64
65 how.add_option("--sort-by",
66 type="choice",
67 action="store",
68 dest="sort",
69 default=configuration().get("CommandOptionDefaults","sortListCases",default="name"),
70 choices=self.sortChoices,
71 help="Sort the cases by a specific key (Keys: "+string.join(self.sortChoices,", ")+") Default: %default")
72 how.add_option("--reverse-sort",
73 action="store_true",
74 dest="reverse",
75 default=False,
76 help="Sort in reverse order")
77
78 behave=OptionGroup(self.parser,
79 "Behaviour",
80 "Additional output etc")
81 self.parser.add_option_group(behave)
82
83 behave.add_option("--progress",
84 action="store_true",
85 dest="progress",
86 default=False,
87 help="Print the directories while they are being processed")
88
90 dirs=self.parser.getArgs()
91 if len(dirs)==0:
92 dirs=[path.curdir]
93
94 cData=[]
95
96 for d in dirs:
97 for n in listdir(d):
98 cName=path.join(d,n)
99 if path.isdir(cName):
100 sol=SolutionDirectory(cName,archive=None,paraviewLink=False)
101 if sol.isValid():
102 if self.opts.progress:
103 print "Processing",cName
104
105 data={}
106
107 data["mtime"]=stat(cName)[ST_MTIME]
108 times=sol.getTimes()
109 try:
110 data["first"]=times[0]
111 except IndexError:
112 data["first"]="None"
113 try:
114 data["last"]=times[-1]
115 except IndexError:
116 data["last"]="None"
117 data["nrSteps"]=len(times)
118 data["procs"]=sol.nrProcs()
119 data["pFirst"]=-1
120 data["pLast"]=-1
121 data["nrParallel"]=-1
122 if self.opts.parallel:
123 pTimes=sol.getParallelTimes()
124 data["nrParallel"]=len(pTimes)
125 if len(pTimes)>0:
126 data["pFirst"]=pTimes[0]
127 data["pLast"]=pTimes[-1]
128 data["name"]=cName
129 data["diskusage"]=-1
130 if self.opts.diskusage:
131 data["diskusage"]=int(subprocess.Popen(["du","-sm",cName], stdout=subprocess.PIPE).communicate()[0].split()[0])
132 if self.opts.parallel:
133 for f in listdir(cName):
134 if re.compile("processor[0-9]+").match(f):
135 data["mtime"]=max(stat(path.join(cName,f))[ST_MTIME],data["mtime"])
136
137 cData.append(data)
138
139 if self.opts.progress:
140 print "Sorting data"
141
142 if self.opts.reverse:
143 cData.sort(lambda x,y:cmp(y[self.opts.sort],x[self.opts.sort]))
144 else:
145 cData.sort(lambda x,y:cmp(x[self.opts.sort],y[self.opts.sort]))
146
147 if len(cData)==0:
148 print "No cases found"
149 return
150
151 if self.opts.dump:
152 print cData
153 return
154
155 lens={}
156 for k in cData[0].keys():
157 lens[k]=len(k)
158 for c in cData:
159 c["mtime"]=time.asctime(time.localtime(c["mtime"]))
160 for k,v in c.iteritems():
161 lens[k]=max(lens[k],len(str(v)))
162
163 format=""
164 spec=["mtime"," | ","first"," - ","last"," (","nrSteps",") "]
165 if self.opts.parallel:
166 spec+=["| ","procs"," : ","pFirst"," - ","pLast"," (","nrParallel",") | "]
167 if self.opts.diskusage:
168 spec+=["diskusage"," MB "]
169 spec+=["name"]
170
171 for i,l in enumerate(spec):
172 if not l in cData[0].keys():
173 format+=l
174 else:
175 if i<len(spec)-1:
176 format+="%%(%s)%ds" % (l,lens[l])
177 else:
178 format+="%%(%s)s" % (l)
179
180 if self.opts.progress:
181 print "Printing\n\n"
182
183 header=format % dict(zip(cData[0].keys(),cData[0].keys()))
184 print header
185 print "-"*len(header)
186
187 for d in cData:
188 for k in d.keys():
189 d[k]=str(d[k])
190 print format % d
191