#!/usr/bin/env python """ This script parses the given fan presence definition yaml file and generates a header file based on the defined methods for determining when a fan is present. """ import os import sys import yaml from argparse import ArgumentParser # TODO Convert to using a mako template def get_filename(): """ Constructs and returns the fully qualified header filename. """ script_dir = os.path.dirname(os.path.abspath(__file__)) header_file = os.path.join(script_dir, "fan_detect_defs.cpp") return header_file def create_and_add_header(header_file): """ Creates the header file based on the header filename value given within. The associated fan presence detection application includes this header. Parameter descriptions: header_file Header filename to create """ with open(header_file, 'w') as ofile: ofile.write("/* WARNING: This header contains code generated ") ofile.write("by " + __file__ + " */\n") ofile.write("/* !!! DO NOT EDIT THIS FILE BY HAND !!! */\n") ofile.write("#include \"fan_detect_defs.hpp\"\n\n") ofile.write("const std::map>") ofile.write("\nfanDetectMap = {\n") def add_detect(header_fd, dmethod): """ Adds the detection method map entry for listing the fan(s) that should be detected using the supported method. Parameter descriptions: header_fd Header file to add the detection method to dmethod The detection method to be added """ header_fd.write(" {\"" + dmethod + "\",{\n") def add_fan(header_fd, fan_info): """ Adds each fan's yaml entry presence detection information to the corresponding header file for the defined detection method Parameter descriptions: header_fd Header file to add fan information to fan_info Fan presence detection information """ tab = ' ' * 4 header_fd.write(tab * 2 + "std::make_tuple(\"" + fan_info['Inventory'] + "\",\n") header_fd.write(tab * 6 + "\"" +fan_info['Description'] + "\",\n") header_fd.write(tab * 6 + "std::vector({") for sensors in fan_info['Sensors']: if sensors != fan_info['Sensors'][-1]: header_fd.write("\"" + sensors + "\",") else: header_fd.write("\"" + sensors + "\"})),\n") def close_detect(header_fd): """ Closes the current detection method map entry. Parameter descriptions: header_fd Header file to add detection method closing to """ header_fd.write(" }},\n") def add_closing(header_fd): """ Appends final closing tags to the header file given. This essentially ends writing to the header file generated. Parameter descriptions: header_fd Header file to add closing tags to """ header_fd.write("};\n") def parse_yaml(yaml_file): """ Parse the given yaml file, creating a header file for each 'Detection' types found to be included within the app supporting presence detection by that type. Parameter descriptions: yaml_file File to be parsed for fan presences definitions """ with open(yaml_file, 'r') as input_file: yaml_input = yaml.safe_load(input_file) header_file = get_filename() create_and_add_header(header_file) header_fd = open(header_file, 'a') if yaml_input: for detect in yaml_input: for dmethod in detect: add_detect(header_fd, dmethod.replace(" ", "-").lower()) for fan in detect[dmethod]: add_fan(header_fd, fan) close_detect(header_fd) add_closing(header_fd) header_fd.close() if __name__ == '__main__': parser = ArgumentParser() # Input yaml containing how each fan's presence detection should be done parser.add_argument("-y", "--yaml", dest="pres_yaml", default= "example/fan-detect.yaml", help= "Input fan presences definition yaml file to parse") args = parser.parse_args(sys.argv[1:]) # Verify given yaml file exists yaml_file = os.path.abspath(args.pres_yaml) if not os.path.isfile(yaml_file): print "Unable to find input yaml file " + yaml_file exit(1) parse_yaml(yaml_file)