1 |
#!/usr/bin/env python |
2 |
|
3 |
# Copyright (C) 2004-2005 Paul Cochrane |
4 |
# |
5 |
# This program is free software; you can redistribute it and/or |
6 |
# modify it under the terms of the GNU General Public License |
7 |
# as published by the Free Software Foundation; either version 2 |
8 |
# of the License, or (at your option) any later version. |
9 |
# |
10 |
# This program is distributed in the hope that it will be useful, |
11 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 |
# GNU General Public License for more details. |
14 |
# |
15 |
# You should have received a copy of the GNU General Public License |
16 |
# along with this program; if not, write to the Free Software |
17 |
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
18 |
|
19 |
# $Id: skel_module.py,v 1.8 2005/02/24 04:23:12 paultcochrane Exp $ |
20 |
|
21 |
import string,sys,os |
22 |
|
23 |
if (len(sys.argv) != 2): |
24 |
print "Usage: python skel_module.py <moduleName>" |
25 |
sys.exit(1) |
26 |
|
27 |
baseClassNames = [ |
28 |
'item', |
29 |
'scene', |
30 |
'renderer', |
31 |
'axes', |
32 |
'camera', |
33 |
'image', |
34 |
'plane', |
35 |
'plot', |
36 |
'text', |
37 |
] |
38 |
|
39 |
imageClassNames = [ |
40 |
'JpegImage', |
41 |
'PbmImage', |
42 |
'PdfImage', |
43 |
'PngImage', |
44 |
'PnmImage', |
45 |
'PsImage', |
46 |
'TiffImage', |
47 |
] |
48 |
|
49 |
plotClassNames = [ |
50 |
'ArrowPlot', |
51 |
'ContourPlot', |
52 |
'LinePlot', |
53 |
'SurfacePlot', |
54 |
] |
55 |
|
56 |
# this is the name of the module, and the name of the directory to create |
57 |
moduleName = sys.argv[1] |
58 |
|
59 |
def createDirs(): |
60 |
# create the file structure (module directory plus tests subdirectory) |
61 |
os.mkdir(moduleName) |
62 |
testDirName = "%s/tests" % moduleName |
63 |
os.mkdir(testDirName) |
64 |
|
65 |
# the copyright string to put at the top of the file |
66 |
copyrightStr = """# Copyright (C) 2004-2005 Paul Cochrane |
67 |
# |
68 |
# This program is free software; you can redistribute it and/or |
69 |
# modify it under the terms of the GNU General Public License |
70 |
# as published by the Free Software Foundation; either version 2 |
71 |
# of the License, or (at your option) any later version. |
72 |
# |
73 |
# This program is distributed in the hope that it will be useful, |
74 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
75 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
76 |
# GNU General Public License for more details. |
77 |
# |
78 |
# You should have received a copy of the GNU General Public License |
79 |
# along with this program; if not, write to the Free Software |
80 |
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
81 |
|
82 |
# $""" |
83 |
|
84 |
# doing this to get around cvs keyword expansion issues |
85 |
copyrightStr += "Id" |
86 |
copyrightStr += "$\n\n" |
87 |
|
88 |
# this gets vim to "do the right thing" wrt spaces and tabs etc |
89 |
vimStr = "# vim: expandtab shiftwidth=4:" |
90 |
|
91 |
def writeInitFile(): |
92 |
""" |
93 |
Generate the __init__.py file |
94 |
""" |
95 |
|
96 |
initText = "## @file __init__.py" |
97 |
initText += """ |
98 |
|
99 |
\"\"\" |
100 |
Initialisation of the %s renderer module |
101 |
\"\"\" |
102 |
""" % moduleName |
103 |
|
104 |
initText += """ |
105 |
from pyvisi.renderers.%s.common \\ |
106 |
import _rendererName, _rendererVersion, _rendererRevision |
107 |
print \"This is the \\\"%%s\\\" renderer module version %%s-%%s\" %% \\ |
108 |
(_rendererName, _rendererVersion, _rendererRevision) |
109 |
|
110 |
__author__ = 'Insert author name here' |
111 |
__version__ = _rendererVersion |
112 |
__revision__ = _rendererRevision |
113 |
|
114 |
""" % moduleName |
115 |
|
116 |
for baseClass in baseClassNames: |
117 |
if baseClass == 'plot': |
118 |
initText += "from pyvisi.renderers.%s.%s import %s, \\\n" % \ |
119 |
(moduleName, baseClass.lower(), baseClass.capitalize()) |
120 |
initText += " " |
121 |
for i in range(len(plotClassNames)-1): |
122 |
initText += "%s, " % plotClassNames[i] |
123 |
initText += "%s\n" % plotClassNames[-1] |
124 |
elif baseClass == 'image': |
125 |
initText += "from pyvisi.renderers.%s.%s import %s, \\\n" % \ |
126 |
(moduleName, baseClass.lower(), baseClass.capitalize()) |
127 |
initText += " " |
128 |
for i in range(len(imageClassNames)-1): |
129 |
initText += "%s, " % imageClassNames[i] |
130 |
initText += "%s\n" % imageClassNames[-1] |
131 |
else: |
132 |
initText += "from pyvisi.renderers.%s.%s import %s\n" % \ |
133 |
(moduleName, baseClass.lower(), baseClass.capitalize()) |
134 |
|
135 |
fname = moduleName + '/__init__.py' |
136 |
f = open(fname, 'w') |
137 |
f.write(copyrightStr) |
138 |
f.write(initText + "\n") |
139 |
f.write(vimStr + "\n") |
140 |
f.close() |
141 |
|
142 |
def writeCommonFile(): |
143 |
""" |
144 |
Generate the common.py file |
145 |
""" |
146 |
|
147 |
commonText = "## @file common.py" |
148 |
commonText += """ |
149 |
|
150 |
\"\"\" |
151 |
Variables common to all classes and functions |
152 |
\"\"\" |
153 |
|
154 |
_debug = 1 |
155 |
_rendererName = \'%s\' |
156 |
_rendererVersion = \'Enter renderer version number\' |
157 |
_rendererRevision = \'Enter renderer revision text\' |
158 |
|
159 |
__revision__ = \'$ |
160 |
""" |
161 |
# this bit here is to get around cvs keyword expansion issues |
162 |
commonText += "Revision" |
163 |
commonText += """$\' |
164 |
|
165 |
""" % moduleName.upper() |
166 |
|
167 |
commonText += """ |
168 |
def debugMsg(message): |
169 |
\"\"\" |
170 |
Convenience function for debugging messages. |
171 |
|
172 |
This function will print out a debugging message if the debug variable |
173 |
is set. |
174 |
|
175 |
@param message: the message to output if the debug flag is set |
176 |
@type message: string |
177 |
\"\"\" |
178 |
if _debug: |
179 |
print \"\\t%s: %s\" % (_rendererName, message) |
180 |
|
181 |
def unsupportedError(): |
182 |
\"\"\" |
183 |
Print an error message when a method is called that is defined in pyvisi |
184 |
but is not supported at the renderer module level. |
185 |
\"\"\" |
186 |
errorString = \"Sorry, but %s doesn't support this method.\" % _rendererName |
187 |
raise NotImplementedError, errorString |
188 |
|
189 |
def getRevision(): |
190 |
\"\"\" |
191 |
Get the revision string/number |
192 |
\"\"\" |
193 |
return _rendererRevision |
194 |
""" |
195 |
|
196 |
fname = moduleName + '/common.py' |
197 |
f = open(fname, 'w') |
198 |
f.write(copyrightStr) |
199 |
f.write(commonText + "\n") |
200 |
f.write(vimStr + "\n") |
201 |
f.close() |
202 |
|
203 |
def getClassFileHeader(className, baseClassName): |
204 |
# epydoc documentation strings for info about the file itself |
205 |
fileDoxStr = "## @file %s.py\n" % className.lower() |
206 |
|
207 |
# the header of the file |
208 |
fileHeaderStr = """ |
209 |
\"\"\" |
210 |
Brief introduction to what the file contains/does |
211 |
\"\"\" |
212 |
|
213 |
from pyvisi.renderers.%s.common import debugMsg, overrideWarning |
214 |
|
215 |
from pyvisi.renderers.%s.%s import %s |
216 |
|
217 |
__revision__ = '$ |
218 |
""" |
219 |
# this is here to get around cvs keyword expansion problems |
220 |
fileHeaderStr += "Revision" |
221 |
fileHeaderStr += """$' |
222 |
|
223 |
""" % (moduleName, moduleName, baseClassName.lower(), baseClassName) |
224 |
return copyrightStr + fileDoxStr + fileHeaderStr |
225 |
|
226 |
def getBaseClassFileHeader(className, baseClassName): |
227 |
# epydoc documentation strings for info about the file itself |
228 |
fileDoxStr = "## @file %s.py\n" % className.lower() |
229 |
|
230 |
# the header of the file |
231 |
fileHeaderStr = """ |
232 |
\"\"\" |
233 |
Brief introduction to what the file contains/does |
234 |
\"\"\" |
235 |
|
236 |
from pyvisi.renderers.%s.common import debugMsg, overrideWarning, getRevision |
237 |
|
238 |
from pyvisi.%s import %s as %s |
239 |
""" % (moduleName, className.lower(), className.capitalize(), baseClassName) |
240 |
|
241 |
if className.lower() == 'scene': |
242 |
fileHeaderStr += """ |
243 |
from pyvisi.renderers.%s.renderer import Renderer |
244 |
""" % moduleName |
245 |
|
246 |
fileHeaderStr += """ |
247 |
|
248 |
__revision__ = getRevision() |
249 |
|
250 |
""" |
251 |
return copyrightStr + fileDoxStr + fileHeaderStr |
252 |
|
253 |
def getClassFileBody(className, baseClassName): |
254 |
""" |
255 |
Gets the text of the class body skeleton |
256 |
|
257 |
@param className: the name of the class body skeleton |
258 |
@type className: string |
259 |
|
260 |
@param baseClassName: the name of the class' base class |
261 |
@type baseClassName: string |
262 |
""" |
263 |
|
264 |
# the class body skeleton, with epydoc strings added, and a dummy function |
265 |
classStr = """ |
266 |
class %s(%s): |
267 |
""" % (className, baseClassName) |
268 |
classStr += """ |
269 |
\"\"\" |
270 |
Brief introduction to what the class does |
271 |
\"\"\" |
272 |
|
273 |
def __init__(self, arg): |
274 |
\"\"\" |
275 |
Brief description of the init function |
276 |
|
277 |
@param arg: a description of the argument |
278 |
@type arg: the type of the argument |
279 |
\"\"\" |
280 |
debugMsg(\"Called %s.__init__()\") |
281 |
%s.__init__(self) # initialisation of base class |
282 |
|
283 |
def myfunc(self, myarg): |
284 |
\"\"\" |
285 |
Brief description of what the function does |
286 |
|
287 |
Replace the text given here with an actual description of what |
288 |
the function does. Also change the name of the function and |
289 |
the name of the argument. |
290 |
|
291 |
@param myarg: Description of what the parameter means/does |
292 |
@type myarg: the type of the argument |
293 |
\"\"\" |
294 |
return |
295 |
|
296 |
""" % (baseClassName, className) |
297 |
return classStr |
298 |
|
299 |
def writeClassFile(classFileText, className): |
300 |
""" |
301 |
Write the text of the generated class skeleton out to file |
302 |
""" |
303 |
|
304 |
fname = moduleName + '/' + className + '.py' |
305 |
f = open(fname, 'w') |
306 |
f.write(classFileText + "\n") |
307 |
f.write(vimStr + "\n") |
308 |
f.close() |
309 |
|
310 |
# now biff out the stuff for the test file |
311 |
def getTestFileHeader(className): |
312 |
""" |
313 |
Get the text of the generated header for the test file |
314 |
""" |
315 |
|
316 |
fileDoxStr = '## @file test_' + className.lower() + '.py' |
317 |
|
318 |
headerTextStr = """ |
319 |
|
320 |
import unittest |
321 |
import sys,os,string |
322 |
here = os.getcwd() + '/../../' |
323 |
sys.path.append(here) |
324 |
# this should import all of the pyvisi stuff needed |
325 |
from pyvisi import * |
326 |
# this should import the renderer specific stuff |
327 |
from pyvisi.renderers.%s import * |
328 |
""" % moduleName |
329 |
return copyrightStr + fileDoxStr + headerTextStr |
330 |
|
331 |
def getTestFileBody(className): |
332 |
""" |
333 |
Get the text of the generated body for the test class |
334 |
""" |
335 |
|
336 |
bodyTextStr = """ |
337 |
\"\"\" |
338 |
Class and functions for testing the %s class |
339 |
\"\"\" |
340 |
|
341 |
class Test%s(unittest.TestCase): |
342 |
\"\"\" |
343 |
The main test class |
344 |
\"\"\" |
345 |
|
346 |
def testFunction(self): |
347 |
\"\"\" |
348 |
A test function |
349 |
\"\"\" |
350 |
self.assertEqual() |
351 |
self.assertRaises() |
352 |
self.assert_() |
353 |
|
354 |
if __name__ == '__main__': |
355 |
unittest.main() |
356 |
|
357 |
""" % (className, className) |
358 |
return bodyTextStr |
359 |
|
360 |
def writeTestFile(testFileText, className): |
361 |
""" |
362 |
Write the generated test skeleton to file |
363 |
""" |
364 |
|
365 |
fname = moduleName + '/tests/' + 'test_' + className + '.py' |
366 |
f = open(fname, 'w') |
367 |
f.write(testFileText + "\n") |
368 |
f.write(vimStr + "\n") |
369 |
f.close() |
370 |
|
371 |
|
372 |
# right, now do stuff |
373 |
createDirs() |
374 |
writeInitFile() |
375 |
writeCommonFile() |
376 |
for name in baseClassNames: |
377 |
if name == 'item' or name == 'scene' or name == 'renderer': |
378 |
# write the class file |
379 |
baseName = "Base" + name.capitalize() |
380 |
classFileText = getBaseClassFileHeader(name.capitalize(), baseName) |
381 |
classFileText += getClassFileBody(name.capitalize(), baseName) |
382 |
writeClassFile(classFileText, name) |
383 |
# write the test file |
384 |
testFileText = getTestFileHeader(name.capitalize()) |
385 |
testFileText += getTestFileBody(name.capitalize()) |
386 |
writeTestFile(testFileText, name) |
387 |
elif name == 'axes': |
388 |
# write the class file |
389 |
baseName = 'Plot' |
390 |
classFileText = getClassFileHeader(name.capitalize(), baseName) |
391 |
classFileText += getClassFileBody(name.capitalize(), baseName) |
392 |
writeClassFile(classFileText, name) |
393 |
# write the test file |
394 |
testFileText = getTestFileHeader(name.capitalize()) |
395 |
testFileText += getTestFileBody(name.capitalize()) |
396 |
writeTestFile(testFileText, name) |
397 |
else: |
398 |
# write the class file |
399 |
baseName = 'Item' |
400 |
classFileText = getClassFileHeader(name.capitalize(), baseName) |
401 |
classFileText += getClassFileBody(name.capitalize(), baseName) |
402 |
testFileText = getTestFileHeader(name.capitalize()) |
403 |
testFileText += getTestFileBody(name.capitalize()) |
404 |
if name == 'plot': |
405 |
for subClass in plotClassNames: |
406 |
classFileText += getClassFileBody(subClass, name.capitalize()) |
407 |
testFileText += getTestFileBody(subClass) |
408 |
elif name == 'image': |
409 |
for subClass in imageClassNames: |
410 |
classFileText += getClassFileBody(subClass, name.capitalize()) |
411 |
testFileText += getTestFileBody(subClass) |
412 |
writeClassFile(classFileText, name) |
413 |
# write the test file |
414 |
writeTestFile(testFileText, name) |
415 |
|
416 |
# vim: expandtab shiftwidth=4: |