#!/usr/bin/env python # # License: BSD # https://raw.githubusercontent.com/splintered-reality/py_trees/devel/LICENSE # ############################################################################## # Documentation ############################################################################## """ .. argparse:: :module: py_trees.programs.render :func: command_line_argument_parser :prog: py-trees-render .. image:: images/render.gif """ ############################################################################## # Imports ############################################################################## import argparse import importlib import json import py_trees import sys import py_trees.console as console ############################################################################## # Classes ############################################################################## def examples(): examples = [console.cyan + "py-trees-render" + console.yellow + " py_trees.demos.stewardship.create_tree" + console.reset, console.cyan + "py-trees-render" + console.yellow + " --with-blackboard-variables" + console.reset, console.cyan + "py-trees-render" + console.yellow + " --name=foo py_trees.demos.stewardship.create_tree" + console.reset, console.cyan + "py-trees-render" + console.yellow + " --kwargs='{\"level\":\"all\"}' py_trees.demos.dot_graphs.create_tree" + console.reset ] return examples def description(): short = "Point this program at a method which creates a root to render to dot/svg/png.\n\n" if py_trees.console.has_colours: banner_line = console.green + "*" * 79 + "\n" + console.reset s = "\n" s += banner_line s += console.bold_white + "Trees".center(79) + "\n" + console.reset s += banner_line s += "\n" s += short s += "\n" s += console.bold + "Examples" + console.reset + "\n\n" s += '\n'.join([" $ " + example for example in examples()]) s += "\n\n" s += banner_line else: # for sphinx documentation (doesn't like raw text) s = short s += "\n" s += console.bold + "**Examples**" + console.reset + "\n\n" s += ".. code-block:: bash\n" s += " \n" s += '\n'.join([" $ {0}".format(example) for example in examples()]) s += "\n" return s def epilog(): if py_trees.console.has_colours: return console.cyan + "And his noodly appendage reached forth to tickle the blessed...\n" + console.reset else: return None def command_line_argument_parser(): parser = argparse.ArgumentParser(description=description(), epilog=epilog(), formatter_class=argparse.RawDescriptionHelpFormatter, ) parser.add_argument('method', default=None, help='space separated list of blackboard variables to watch') parser.add_argument('-l', '--level', action='store', default='fine_detail', choices=['all', 'fine_detail', 'detail', 'component', 'big_picture'], help='visibility level') parser.add_argument('-n', '--name', default=None, help='name to use for the created files (defaults to the root behaviour name)') parser.add_argument('-k', '--kwargs', default="{}", type=json.loads, help='dictionary of keyword arguments to the method') parser.add_argument('-b', '--with-blackboard-variables', default=False, action='store_true', help='add nodes for the blackboard variables') parser.add_argument('-v', '--verbose', default=False, action='store_true', help="embellish each node in the dot graph with extra information") return parser ############################################################################## # Main ############################################################################## def main(): """ Entry point. """ args = command_line_argument_parser().parse_args() args.enum_level = py_trees.common.string_to_visibility_level(args.level) (module_or_class_name, method_name) = args.method.rsplit(".", 1) class_name = None try: module_itself = importlib.import_module(module_or_class_name) module_name = module_or_class_name except ImportError: # maybe it's a class? (module_name, class_name) = module_or_class_name.rsplit(".", 1) try: module_itself = importlib.import_module(module_name) except ImportError: console.logerror("Could not import module [{0}]".format(module_or_class_name)) sys.exit(1) if class_name is not None: class_type = getattr(module_itself, class_name) # first guess - it's a static method method_itself = getattr(class_type, method_name) try: root = method_itself(**(args.kwargs)) except TypeError: # oops, it's an instance method try: method_itself = getattr(class_type(), method_name) except TypeError: console.logerror("Can only instantiate class methods if the class __init__ has no non-default arguments") sys.exit(1) root = method_itself(**(args.kwargs)) else: method_itself = getattr(module_itself, method_name) root = method_itself(**(args.kwargs)) # TODO figure out how to insert keyword arguments py_trees.display.render_dot_tree( root, args.enum_level, args.name, with_blackboard_variables=args.with_blackboard_variables, with_qualified_names=args.verbose )