114 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			Python
		
	
	
			
		
		
	
	
			114 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			Python
		
	
	
| #!/usr/bin/env python3
 | |
| 
 | |
| import os, sys, json, traceback, subprocess
 | |
| 
 | |
| # Definitions
 | |
| def stdout(string, end='\n', flush=False):
 | |
|     print(string, end=end, file=sys.stdout, flush=flush)
 | |
| 
 | |
| def stderr(string, end='\n', flush=False):
 | |
|     print(string, end=end, file=sys.stderr, flush=flush)
 | |
| 
 | |
| exit_codes = {
 | |
|   "normal exit":            0,
 | |
|   "wrong usage":            1,
 | |
|   "error while processing": 2
 | |
| }
 | |
| 
 | |
| stderr("--------------------------------------------------------------------------------\nVariable Grabbler - version 5.0\n--------------------------------------------------------------------------------")
 | |
| ################################################################################
 | |
| # Chnages in this version:
 | |
| # - complete rewrite in Python 3
 | |
| # - output to stdout instead of rewriting the file
 | |
| #===============================================================================
 | |
| # Full documentation: tbd
 | |
| #===============================================================================
 | |
| 
 | |
| # Command line input handling
 | |
| usage = "Usage: python3 "+sys.argv[0]+" <macro config file> <file to be processed>"
 | |
| if not len(sys.argv)==3:
 | |
|     stderr("E: Wrong amount of arguments.")
 | |
|     stderr(usage)
 | |
|     sys.exit(exit_codes["wrong usage"])
 | |
| if sys.argv[1] == sys.argv[2]:
 | |
|     stderr("E: Both input files are the same.")
 | |
|     stderr(usage)
 | |
|     sys.exit(exit_codes["wrong usage"])
 | |
| 
 | |
| # load macros into a dict
 | |
| stderr("I: Reading macro definitions... ")
 | |
| 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())
 | |
|     else:
 | |
|         stderr("E: Not a valid file: "+sys.argv[1])
 | |
|         sys.exit(exit_codes["error while processing"])
 | |
| except:
 | |
|     stderr("E: An exception occurred while trying to read macro definitions:")
 | |
|     traceback.print_exc()
 | |
|     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()
 | |
|             macros[macro] = process_stdout.decode("utf-8")
 | |
|             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"])
 | |
| 
 | |
| # open file to be processed and iterate over it
 | |
| stderr("I: Preparing to process input file...")
 | |
| 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])
 | |
|         sys.exit(exit_codes["error while processing"])
 | |
|     # make the magic happen
 | |
|     stderr("I: Processing input file...")
 | |
|     for line in input_file:
 | |
|         for macro in macros:
 | |
|             line = line.replace("%" + macro + "%", str(macros[macro]))
 | |
|         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()
 | |
|     sys.exit(exit_codes["error while processing"])
 |