xml_cmd.py 4.99 KB
Newer Older
1
#!/usr/bin/python
2 3 4 5 6 7 8 9 10


"""@package Python command creator

With this package, you can generate ALTA command lines with XML formated
files. The documentation of the XML format can be found in the Format
page.
"""

11
import sys
12 13
from sys import argv
from xml.etree.ElementTree import parse
14
import subprocess
15
import os
16 17
from os import listdir
from os.path import isfile, join
18

19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
""" Color capable outputing
"""
BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8)

#following from Python cookbook, #475186
def has_colours(stream):
	if not hasattr(stream, "isatty"):
		return False
	if not stream.isatty():
		return False # auto color only on TTYs
	try:
		import curses

		curses.setupterm()
		return curses.tigetnum("colors") > 2
	except:
		# guess false in case of error
		return False


has_colours = has_colours(sys.stdout)


def printout(text, colour=WHITE):
	if has_colours:
		seq = "\x1b[1;%dm" % (30 + colour) + text + "\x1b[0m"
		sys.stdout.write(seq)
	else:
		sys.stdout.write(text)
	sys.stdout.flush()





54
# Test if file argv[1] exists
55 56 57 58 59 60
if len(argv) != 2:
	print '<<PYTHON>> you did not specify the input argument correctly:'
	print '           xml_cmd file.xml'
	exit()
#end

61 62 63 64 65

# Open the file argv[1] and parse it
tree = parse(argv[1])
root = tree.getroot()

66 67

def baseName():
68 69
	return './build/'

70 71 72
#end

def libName(name):
73 74
	if sys.platform == 'darwin':
		return 'lib' + name + '.dylib'
75
	elif os.name == 'nt':
76 77 78
		return name + ".dll" 
	else:
		return 'lib' + name + '.so'
79
	#endif
80

81 82
#end

83
##Directory delimiter
84
dd = '/'
85
if os.name == 'nt':
86
	dd = '\\'
87

88
## Relative directories
89 90 91
lib_dir = ''
dat_dir = ''
out_dir = ''
Laurent Belcour's avatar
Laurent Belcour committed
92

93 94 95 96 97

## Parse the configuration part of the XML file, this will set the global
## parameters such as the relative directories.
##
def parseConfiguration(xmlNode):
98
	global lib_dir, dat_dir, out_dir
Laurent Belcour's avatar
Laurent Belcour committed
99 100

	for param in xmlNode.findall('parameter'):
101

102 103
		if (param.attrib['name'] == 'lib-dir'):
			lib_dir = param.attrib['value']
104

105 106
		elif (param.attrib['name'] == 'dat-dir'):
			dat_dir = param.attrib["value"]
107

108 109
		elif (param.attrib['name'] == 'out-dir'):
			dat_dir = param.attrib["value"]
110

Laurent Belcour's avatar
Laurent Belcour committed
111
		#end
112
	#end
Laurent Belcour's avatar
Laurent Belcour committed
113
#end
114

115
def parseFunction(xmlNode):
116
	global lib_dir
117

118
	cmd = ''
119 120
	#cmd = lib_dir + dd + libName(xmlNode.attrib['name'])
	cmd = xmlNode.attrib['name']
121 122 123

	# Parse the parameters of the function
	for param in xmlNode.findall('parameter'):
124
		cmd += ' --' + param.attrib['name'] + ' ' + param.attrib['value']
125 126
	#end

127
	fresnel = xmlNode.find('fresnel')
128
	if not (fresnel is None):
129
		cmd += ' --fresnel ' + lib_dir + dd + libName(fresnel.attrib['name'])
130 131
	#end

132 133
	return cmd

134 135 136
#end

def parseFunctions(xmlNodes):
137 138 139 140 141
	list_len = len(xmlNodes)
	if list_len == 0:
		return ''
	elif list_len == 1:
		return ' --func ' + parseFunction(xmlNodes[0])
142
	else:
143 144 145 146 147
		cmd = ' --func ['
		for index in range(0, list_len):
			cmd += parseFunction(xmlNodes[index])
			if index != list_len - 1:
				cmd += ', '
148 149
			#end
		#end
150 151
		cmd += ']'
		return cmd
152
	#end
153

154
#end
155

Laurent Belcour's avatar
Laurent Belcour committed
156
def parseAction(xmlNode):
157 158
	global lib_dir, dat_dir, out_dir
	cmd = ''
Laurent Belcour's avatar
Laurent Belcour committed
159

160
	cmd += parseFunctions(xmlNode.findall('function'))
161

Laurent Belcour's avatar
Laurent Belcour committed
162
	for plugin in xmlNode.findall('plugin'):
163
		cmd += ' --' + plugin.attrib['type']
164 165
		#cmd += ' ' + lib_dir + dd + libName(plugin.attrib['name'])
                cmd += ' ' + plugin.attrib['name']
Laurent Belcour's avatar
Laurent Belcour committed
166
	#end
167

Laurent Belcour's avatar
Laurent Belcour committed
168
	for param in xmlNode.findall('parameter'):
169 170
		cmd += ' --' + param.attrib['name']
		cmd += ' ' + param.attrib['value']
171 172
	#end

173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
        # Search the input file to the command. It is possible for the xml
        # command to loop over a list of file present in a directory using
        # the directory attrib. In that case, cmd is duplicated into a cmd
        # list.
	inputNode = xmlNode.find('input')
	outputNode = xmlNode.find('output')
	if not (inputNode is None) and not (outputNode is None):
            if 'directory' in inputNode.attrib:
                dirname = inputNode.attrib['directory']
                cmds = [cmd + ' --input ' + join(dirname, f) + ' --output ' + f + '.out' for f in listdir(dirname) if isfile(join(dirname, f))]
                cmd = cmds;
            else:
	        cmd += ' --input '  + inputNode.attrib['name']
		cmd += ' --output ' + outputNode.attrib['name']
                cmd = [cmd]
            #end
	#end

        return cmd
192

193 194 195
#end


Laurent Belcour's avatar
Laurent Belcour committed
196 197
## Parse the configuration part of the file
##
198
conf = root.find("configuration")
199 200
if not (conf is None):
    parseConfiguration(conf)
201

202

Laurent Belcour's avatar
Laurent Belcour committed
203 204 205 206 207
## Command lines creation
##
for child in root.findall('action'):

	# Create the cmd string with the command name
208 209 210 211 212 213
        cmd = ''
        if lib_dir != '':
	    cmd = lib_dir + dd + child.attrib['name']
        else:
	    cmd = child.attrib['name']

214

Laurent Belcour's avatar
Laurent Belcour committed
215
	# Parse the action
216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231
        try:
            for act in parseAction(child):

                printout(cmd + act, GREEN)
                print

	        ret = subprocess.check_call(cmd + act, shell=True)
                if ret != 0:
	            printout('<<PYTHON>> the action was not performed', RED)
	        #end
	        print '\n'
            #end
        except:
            printout('<<PYTHON>> exception caught, stopping', RED)
            print '\n'
            exit(0)
232
#end