Skip to content

Commit

Permalink
Merge pull request #17 from UdK-VPT/issue16_postexec
Browse files Browse the repository at this point in the history
Issue16 postexec
  • Loading branch information
jraedler authored Mar 24, 2019
2 parents b2420d3 + a6dcc6e commit cc50c4f
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 35 deletions.
26 changes: 10 additions & 16 deletions CoTeTo/CLI.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,24 +82,18 @@ def main():

elif args.data_source:
# execute the generator
o = g.execute(args.data_source)
if len(o) == 1:
# single file output
ext = list(o.keys())[0]
if args.output:
outFile = open(args.output[0] + ext, 'w')
outFile.write(o[ext].read())
outFile.close()
else:
sys.stdout.write(o[ext].read())
if args.output:
# output to files: let the generator handle file saving
g.execute(args.data_source, args.output[0])
else:
# multi file output
if args.output:
for ext in o:
outFile = open(args.output[0] + ext, 'w')
outFile.write(o[ext].read())
outFile.close()
# print to stdout
o = g.execute(args.data_source)
if len(o) == 1:
# single file output
ext = list(o.keys())[0]
sys.stdout.write(o[ext].read())
else:
# files separated by a line
for ext in o:
sys.stdout.write('### FILE: %s\n' % ext)
sys.stdout.write(o[ext].read())
Expand Down
14 changes: 5 additions & 9 deletions CoTeTo/GUI.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,15 +266,11 @@ def executeGenerator(self):
self.outputInput.setText(outputBase)
if not os.path.isabs(outputBase):
outputBase = os.path.abspath(outputBase)
x = self.activeGenerator.execute(uriList)
for ext in x:
outputFile = outputBase + ext
o = open(outputFile, 'w')
o.write(x[ext].read())
o.close()
if self.openOutputButton.isChecked():
QtGui.QDesktopServices.openUrl(QtCore.QUrl.fromLocalFile(outputFile))

x = self.activeGenerator.execute(uriList, outputBase)
if self.openOutputButton.isChecked():
for ext in x:
QtGui.QDesktopServices.openUrl(QtCore.QUrl.fromLocalFile(x[ext]))

def closeEvent(self, e):
# first reset output streams to standard settings
XStream.reset()
Expand Down
43 changes: 33 additions & 10 deletions CoTeTo/Generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,19 +186,41 @@ def executeFilter(self):
function = getattr(module, functionName)
function(self.data, self.controller.systemCfg, self.cfg, self.logger)

def executeTemplates(self):
"""execeute all templates, return the output buffers and extensions"""
def executeTemplates(self, outputBasename=None):
"""execeute all templates, return the output buffers and extensions -
if outputBasename is given, save file and return file names instead of the buffers"""
tmpls = sorted([s for s in self.cfg.sections() if s.upper().startswith('TEMPLATE')])
txt = {}
res = {}
for tmpl in tmpls:
ext = self.cfg[tmpl].get('ext', '')
if ext in txt:
while ext in txt:
if ext in res:
while ext in res:
ext.append('X')
self.logger.error('GEN | file extension already exists, using %s!' % ext)
self.logger.debug('GEN | processing template setup ' + tmpl)
txt[ext] = self.executeTemplate(tmpl)
return txt
buf = self.executeTemplate(tmpl)
if outputBasename is None:
# return buffer
res[ext] = buf
if self.cfg[tmpl].get('postExec', ''):
self.logger.error('GEN | postExec defined but saving to buffer instead of file: skipping postExec in ' + tmpl)
else:
# save file and return file name
fname = outputBasename + ext
o = open(fname, 'w')
o.write(buf.read())
o.close()
# buf.close() ?
res[ext] = fname
# post execution cmd?
cmd = self.cfg[tmpl].get('postExec', '')
if cmd:
self.logger.debug('GEN | starting postExec command: %s: ', cmd)
try:
exec(cmd, globals(), locals())
except BaseException:
self.logger.exception('GEN | error during postExec: %s: ', cmd)
return res

def executeTemplate(self, name):
"""execeute a single template with the data, return the output buffer"""
Expand Down Expand Up @@ -230,16 +252,17 @@ def executeTemplate(self, name):
else:
raise Exception('Unknown template system: ' + tmplType)

def execute(self, uriList=[]):
def execute(self, uriList=[], outputBasename = None):
if not self.loader:
raise Exception('Generator is not valid - canceling execution!')
# fill data model from the loader using the data URIs
self.executeLoader(uriList)
# apply filter
if self.cfg.has_section('FILTER'):
self.executeFilter()
# handle data to template, return text buffer
return self.executeTemplates()
# handle data to templates, return text buffers or file names
return self.executeTemplates(outputBasename)


# make the generator executable
__call__ = execute
21 changes: 21 additions & 0 deletions Generators/TestPostExec/Filters/Filter01.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# a filter function is called with the following arguments:
# d - the data dictionary read from the loader
# systemCfg - system configuration
# generatorCfg - generator configuration
# logger - a logger instance


def filter01(d, systemCfg, generatorCfg, logger):

# spread a message
logger.debug('hi there! This is a filter running from module: ' + __file__)

x = d['dummy']

# manipulate some data
x['foo'] += 1

# add more data
x['bar'] = 2.0 * x['foo']

# no return needed - data is manipulated inplace
22 changes: 22 additions & 0 deletions Generators/TestPostExec/Package.inf
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[GENERATOR]
name = TestPostExec
version = 0.1
description = test the post execution feature
author = Joerg Raedler [email protected]

[LOADER]
name = TestDummy
minVer = 0.1
maxVer = 2.0

[FILTER]
module = Filter01
function = filter01

[TEMPLATE]
topFile = Main.mako
type = mako
# be VERY carefull with the postexec feature, it has complete access
# to the whole namespace and will run this code without checking!
# You can use "fname" to access the name of the generated file
postExec = os.system("dir "+fname)
14 changes: 14 additions & 0 deletions Generators/TestPostExec/Templates/Main.mako
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#
# CoTeTo
# Version: ${systemCfg['version']}
# Platform: ${systemCfg['platform']}
# Path: ${systemCfg['path']}
# Gen-Path: ${', '.join(systemCfg['generatorPath'])}
#
# Generator
# Name: ${generatorCfg['GENERATOR'].get('name')}
# Version: ${generatorCfg['GENERATOR'].get('version')}

The value of foo is ${d['dummy']['foo']}.

<%include file="Sub.mako"/>
2 changes: 2 additions & 0 deletions Generators/TestPostExec/Templates/Sub.mako
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Hello, I'm a sub template!
bar = ${d['dummy']['bar']}

0 comments on commit cc50c4f

Please sign in to comment.