#!/usr/bin/env python """Python program used to get and set XML variables """ from __future__ import print_function import sys if sys.hexversion < 0x02070000: print(70 * "*") print("ERROR: {0} requires python >= 2.7.x. ".format(sys.argv[0])) print("It appears that you are running python {0}".format( ".".join(str(x) for x in sys.version_info[0:3]))) print(70 * "*") sys.exit(1) # # built-in modules # import argparse import glob from operator import itemgetter import os import re import traceback try: import lxml.etree as etree except: import xml.etree.ElementTree as etree # get the postprocess virtualenv path from the env_postprocess.xml file env_file = './env_postprocess.xml' postprocess_path = '' standalone = '' if os.path.isfile(env_file): xml_tree = etree.ElementTree() xml_tree.parse(env_file) for entry_tag in xml_tree.findall('entry'): if entry_tag.get('id') == 'POSTPROCESS_PATH': postprocess_path = entry_tag.get('value') if entry_tag.get('id') == 'STANDALONE': standalone = entry_tag.get('value') else: err_msg = ('pp_config ERROR: env_postprocess.xml does not exist in this directory.') raise OSError(err_msg) # check if virtualenv is activated if hasattr(sys, 'real_prefix'): try: import jinja2 except: # # activate the virtual environment that was created by create_python_env.sh # activate_file = '{0}/cesm-env2/bin/activate_this.py'.format(postprocess_path) if not os.path.isfile(activate_file): err_msg = ('pp_config ERROR: the virtual environment in {0} does not exist.'.format(postprocess_path) \ + 'Please run {0}/create_python_env.sh -cimeroot [cimeroot] -machine [machine name]'.format(postprocess_path)) raise OSError(err_msg) try: execfile(activate_file, dict(__file__=activate_file)) except: raise OSError('pp_config ERROR: Unable to activate python virtualenv {0}'.format(activate_file)) else: # # activate the virtual environment that was created by create_python_env.sh # activate_file = '{0}/cesm-env2/bin/activate_this.py'.format(postprocess_path) if not os.path.isfile(activate_file): err_msg = ('pp_config ERROR: the virtual environment in {0} does not exist.'.format(postprocess_path) \ + 'Please run {0}/create_python_env.sh -cimeroot [cimeroot] -machine [machine name]'.format(postprocess_path)) raise OSError(err_msg) try: execfile(activate_file, dict(__file__=activate_file)) except: raise OSError('pp_config ERROR: Unable to activate python virtualenv {0}'.format(activate_file)) if sys.version_info[0] == 2: from ConfigParser import SafeConfigParser as config_parser else: from configparser import ConfigParser as config_parser # # import virtualenv installed modules # from cesm_utils import cesmEnvLib, processXmlLib from asaptools import vprinter # ------------------------------------------------------------------------------- # User input # ------------------------------------------------------------------------------- def commandline_options(): """Process the command line arguments. """ parser = argparse.ArgumentParser( description=('pp_config: get and set post-processing ' 'configuration variables.')) parser.add_argument('-backtrace', '--backtrace', action='store_true', help='show exception backtraces as extra debugging ' 'output') parser.add_argument('-caseroot','--caseroot', nargs=1, default=['.'], help='path to postprocessing case directory. Defaults to current directory.') parser.add_argument('-debug', '--debug', nargs=1, required=False, type=int, default=0, help='debugging verbosity level output: 0 = none, 1 = minimum, 2 = maximum. 0 is default') parser.add_argument('-get', '--get', nargs=1, default=[], help='variable name to retreive') parser.add_argument('-set', '--set', nargs=1, default=[], help=('variable and value to set in the form: ' '"key=value". Values with a "$" must be escaped using "\$" ' 'unless you want the shell to replace the value with the value of the ' 'expanded environment variable.')) parser.add_argument('-value', '--value', action='store_true', help=('print only the value of the variable.' 'Works in conjunction with the --get option')) options = parser.parse_args() return options # ------------------------------------------------------------------------------- # main # ------------------------------------------------------------------------------- def main(options): debugMsg = vprinter.VPrinter(header='', verbosity=0) if options.debug: header = 'pp_config: DEBUG... ' debugMsg = vprinter.VPrinter(header=header, verbosity=options.debug[0]) case_dir = options.caseroot[0] debugMsg("Using case directory : {0}".format(case_dir), header=True, verbosity=1) os.chdir(case_dir) xml_filenames = glob.glob('*.xml') xml_trees = [] for filename in xml_filenames: file_path = os.path.join(case_dir, filename) file_path = os.path.abspath(file_path) if os.path.isfile(file_path): xml_trees.append(etree.parse(file_path)) else: msg = 'pp_config WARNING: {0} does not exist.'.format(file_path) print(msg) # assume that all env*.xml files are the same version in a case xml_processor = processXmlLib.post_processing_xml_factory(xml_trees[0]) envDict = os.environ.copy() for tree in xml_trees: xml_processor.xml_to_dict(tree, envDict) # # 'get' user input # if options.get: entry_id = options.get[0] if options.value: print("{0}".format(envDict[entry_id])) else: print("{0}={1}".format(entry_id, envDict[entry_id])) # # 'set' user input # if options.set: key_value = options.set[0].split('=') new_entry_id = key_value[0].strip() new_entry_value = key_value[1].strip().replace('\n','') # get the component name based on the entry_id entry_parts = new_entry_id.split('_') comp = entry_parts[0][:3] if comp.upper() not in ['ATM','ICE','LND','OCN'] or len(entry_parts[0]) == 3: comp = '' xml_processor.write(envDict, comp.lower(), new_entry_id, new_entry_value) if __name__ == "__main__": try: options = commandline_options() status = main(options) sys.exit(status) except Exception as error: print(str(error)) if options.backtrace: traceback.print_exc() sys.exit(1)