2021-09-08 06:33:47 +02:00
#!/usr/bin/env python3
2020-02-23 21:40:16 +01:00
2021-09-08 07:39:38 +02:00
import os , sys , json , traceback , subprocess
2020-04-08 02:06:32 +02:00
2021-09-08 06:33:47 +02:00
# Definitions
def stdout ( string , end = ' \n ' , flush = False ) :
print ( string , end = end , file = sys . stdout , flush = flush )
2020-02-23 21:40:16 +01:00
2021-09-08 06:33:47 +02:00
def stderr ( string , end = ' \n ' , flush = False ) :
print ( string , end = end , file = sys . stderr , flush = flush )
2020-04-08 02:06:32 +02:00
2021-09-08 07:39:38 +02:00
exit_codes = {
" normal exit " : 0 ,
" wrong usage " : 1 ,
" error while processing " : 2
}
2021-09-08 09:58:42 +02:00
stderr ( " -------------------------------------------------------------------------------- \n Variable Grabbler - version 5.0 \n -------------------------------------------------------------------------------- " )
2021-09-08 06:33:47 +02:00
################################################################################
# Chnages in this version:
2021-09-08 07:39:38 +02:00
# - complete rewrite in Python 3
2021-09-08 06:33:47 +02:00
# - output to stdout instead of rewriting the file
#===============================================================================
# Full documentation: tbd
#===============================================================================
2020-02-23 21:40:16 +01:00
2021-09-08 06:33:47 +02:00
# Command line input handling
usage = " Usage: python3 " + sys . argv [ 0 ] + " <macro config file> <file to be processed> "
2020-02-24 00:56:44 +01:00
if not len ( sys . argv ) == 3 :
2021-09-08 06:33:47 +02:00
stderr ( " E: Wrong amount of arguments. " )
stderr ( usage )
2021-09-08 07:39:38 +02:00
sys . exit ( exit_codes [ " wrong usage " ] )
2021-09-08 06:33:47 +02:00
if sys . argv [ 1 ] == sys . argv [ 2 ] :
stderr ( " E: Both input files are the same. " )
stderr ( usage )
2021-09-08 07:39:38 +02:00
sys . exit ( exit_codes [ " wrong usage " ] )
2020-04-08 03:52:18 +02:00
2021-09-08 07:39:38 +02:00
# load macros into a dict
stderr ( " I: Reading macro definitions... " )
2021-09-08 06:33:47 +02:00
macros = { }
try :
if os . path . isfile ( sys . argv [ 1 ] ) :
macro_file = open ( sys . argv [ 1 ] , " r " )
macros = json . loads ( macro_file . read ( ) )
macro_file . close ( )
elif sys . argv [ 1 ] == ' - ' :
macros = json . loads ( sys . stdin . read ( ) )
2020-04-08 02:06:32 +02:00
else :
2021-09-08 06:33:47 +02:00
stderr ( " E: Not a valid file: " + sys . argv [ 1 ] )
2021-09-08 07:39:38 +02:00
sys . exit ( exit_codes [ " error while processing " ] )
2021-09-08 06:33:47 +02:00
except :
stderr ( " E: An exception occurred while trying to read macro definitions: " )
traceback . print_exc ( )
2021-09-08 07:39:38 +02:00
sys . exit ( exit_codes [ " error while processing " ] )
# process "file" and "exec" macros
stderr ( " I: Loading templates and processing commands... " )
for macro in macros :
if macros [ macro ] [ 0 ] == " file " :
if os . path . isfile ( macros [ macro ] [ 1 ] ) :
try :
stderr ( " I: Loading template: " + macro )
template = open ( macros [ macro ] [ 1 ] , " r " )
macros [ macro ] = template . read ( )
template . close ( )
except :
stderr ( " E: An exception occurred while trying to read the template: " )
traceback . print_exc ( )
sys . exit ( exit_codes [ " error while processing " ] )
else :
stderr ( " E: Macro \" " + macro + " \" : template \" " + macros [ macro ] [ 1 ] + " \" is not a valid file. " )
sys . exit ( exit_codes [ " error while processing " ] )
elif macros [ macro ] [ 0 ] == " exec " :
try :
stderr ( " I: Running command: " + macro )
process = subprocess . Popen ( macros [ macro ] [ 1 ] , shell = True , stdout = subprocess . PIPE , stderr = subprocess . PIPE )
process_stdout , process_stderr = process . communicate ( )
2021-09-08 09:52:07 +02:00
macros [ macro ] = process_stdout . decode ( " utf-8 " )
2021-09-08 07:39:38 +02:00
if len ( process_stderr ) > 0 :
stderr ( " Output on stderr: \n " + process_stderr )
if not process . returncode == 0 :
stderr ( " E: Command execution failed with exit code " + str ( process . returncode ) )
sys . exit ( exit_codes [ " error while processing " ] )
except :
stderr ( " E: An exception occurred while trying to process the command: " )
traceback . print_exc ( )
sys . exit ( exit_codes [ " error while processing " ] )
2020-04-08 03:52:18 +02:00
2021-09-08 07:39:38 +02:00
# open file to be processed and iterate over it
stderr ( " I: Preparing to process input file... " )
2021-09-08 06:33:47 +02:00
try :
input_file = sys . stdin
if os . path . isfile ( sys . argv [ 2 ] ) :
input_file = open ( sys . argv [ 2 ] , " r " )
elif sys . argv [ 2 ] == ' - ' :
# nothing to do here bc input_file is already set to sys.stdin
pass
else :
stderr ( " E: Not a valid file: " + sys . argv [ 2 ] )
2021-09-08 07:39:38 +02:00
sys . exit ( exit_codes [ " error while processing " ] )
# make the magic happen
stderr ( " I: Processing input file... " )
2021-09-08 06:33:47 +02:00
for line in input_file :
2021-09-08 07:39:38 +02:00
for macro in macros :
line = line . replace ( " % " + macro + " % " , str ( macros [ macro ] ) )
2021-09-08 06:33:47 +02:00
stdout ( line , end = " " )
# close input file if it's not sys.stdin, assume sys.stdin is being handled for us
if not input_file == sys . stdin :
input_file . close ( )
except :
stderr ( " E: An exception occured while processing " + input_file . name + " : " )
traceback . print_exc ( )
2021-09-08 07:39:38 +02:00
sys . exit ( exit_codes [ " error while processing " ] )