コード例 #1
0
    def test_multiline_template(self):
        input = """{%
                def foo():
                    return "bar"

                bar = foo()
            %}{{bar}}"""
        expected = "bar"
        self.assertEqual(render(input, self.namespace), expected)
コード例 #2
0
ファイル: aina.py プロジェクト: iLoveTux/aina
def _exec_list(exprs, namespace):
    log = logging.getLogger(__name__)
    for expr in exprs:
        _expr = render(expr, namespace)
        if os.path.isfile(_expr):
            log.debug("{} is a file, executing...".format(_expr))
            namespace.update(runpy.run_path(_expr, init_globals=namespace))
        else:
            log.debug("Executing {}".format(_expr))
            exec(_expr, namespace)
コード例 #3
0
ファイル: aina.py プロジェクト: iLoveTux/aina
def render_directory(src, dst, recursive, namespace):
    log = logging.getLogger(__name__)
    src = Path(render(src, namespace))
    dst = Path(render(dst, namespace))
    for root, dirs, filenames in os.walk(str(src), topdown=True):
        log.debug("In directory: {}".format(root))
        for filename in filenames:
            filename = Path(os.path.join(root, filename))
            log.debug("Found file {}".format(filename))
            _dst = os.path.join(str(dst),
                                os.path.relpath(str(filename), str(src)))
            render_file(filename, _dst, namespace)
        if recursive:
            for dirname in dirs:
                new_dir = Path(dst / dirname)
                log.debug("Recursive, rendering to {}".format(new_dir))
                new_dir.mkdir(parents=True, exist_ok=True)
        else:
            log.debug("Not recursive, exiting")
            dirs.clear()
コード例 #4
0
ファイル: aina.py プロジェクト: iLoveTux/aina
def render_file(src, dst, namespace):
    log = logging.getLogger(__name__)
    dst = Path(dst)
    src = Path(src)
    if src not in mtimes or src.stat().st_mtime != mtimes[src]:
        log.warn("Rendering {} -> {}".format(src, dst))
        try:
            dst.write_text(render(src.read_text(), namespace))
        finally:
            mtimes[src] = src.stat().st_mtime
    else:
        log.debug("File {} has not changed, skipping".format(src))
        pass
コード例 #5
0
ファイル: aina.py プロジェクト: iLoveTux/aina
def stream(
    filenames,
    add_paths,
    templates,
    begins,
    begin_lines,
    begin_files,
    end_files,
    tests,
    end_lines,
    ends,
    field_sep,
    namespaces,
    recursive,
    with_filenames,
    logging_config,
    logging_level,
    logging_format,
    suppress_tracebacks,
    add_env,
):
    """Pass streams of data through a processing/templating pipeline"""
    if logging_config:
        with open(logging_config, "r") as fp:
            logging.config.dictConfig(eval(fp.read()))
    else:
        logging.basicConfig(
            stream=sys.stdout,
            level=logging_level,
            format=logging_format,
        )

    log = logging.getLogger(__name__)
    if add_paths is None:
        add_paths = []
    for path in add_paths:
        if os.path.exists(path):
            sys.path.insert(0, path)
        else:
            log.critical("{} not found, invalid path".format(path))
            sys.exit(-2)
    namespace = make_namespace({}, namespaces, add_env)
    if not filenames:
        log.debug("No filenames specified, defaulting to stdin")
        filenames = ["-"]
    _filenames = []
    for filename in filenames:
        if filename == "-":
            _filenames.append("-")
        else:
            _filenames.extend(glob(filename, recursive=recursive))
    filenames = list(filter(lambda x: not os.path.isdir(x), _filenames))
    log.debug("Reading filenames {}".format(filenames))
    last_filename = None
    nr = 0
    if tests is None:
        tests = ["True"]
    if begins is None:
        begins = []
    if begin_lines is None:
        begin_lines = []
    if begin_files is None:
        begin_files = []
    if end_files is None:
        end_files = []
    if end_lines is None:
        end_lines = []
    if ends is None:
        ends = []
    _exec_list(begins, namespace)
    for filename in filenames:
        try:
            with click.open_file(filename, "rb") as fin:
                log.debug("Reading {}".format(filename))
                for line in fin:
                    log.debug("Got line: {}".format(line))
                    if filename != last_filename:
                        if with_filenames:
                            print("===> {} <===".format(
                                os.path.abspath(filename)))
                        namespace.update(
                            {"filename": os.path.abspath(filename)})
                        fnr = 0
                        _exec_list(begin_files, namespace)
                        last_filename = filename
                    fnr, nr = fnr + 1, nr + 1
                    fields = line.split(field_sep)
                    namespace.update({
                        "line": line.decode(),
                        "filename": os.path.abspath(filename),
                        "fields": fields,
                        "nf": len(fields),
                        "nr": nr,
                        "fnr": fnr,
                    })
                    if all(
                            eval(render(test, namespace), namespace)
                            for test in tests):
                        _exec_list(begin_lines, namespace)
                        for template in templates:
                            log.debug(
                                "Rendering template: {}".format(template))
                            try:
                                results = render(template, namespace).strip()
                            except:
                                if not suppress_tracebacks:
                                    log.exception(
                                        "An unhandled exception occurred")
                                continue
                            log.debug("Result: {}".format(results))
                            if results:
                                log.info(results)
                    _exec_list(end_lines, namespace)
            _exec_list(end_files, namespace)
        except:
            if not suppress_tracebacks:
                log.exception("An unhandled exception occurred")
            continue
    _exec_list(ends, namespace)
    return 0
コード例 #6
0
 def test_expression_replaced_with_stdout(self):
     input = "{%print('hello, world')%}"
     expected = "hello, world\n"
     self.assertEqual(render(input, self.namespace), expected)
コード例 #7
0
 def test_multiline_substitution(self):
     input = """{{
         str(["foo", "bar", "baz"])
     }}"""
     expected = "['foo', 'bar', 'baz']"
     self.assertEqual(render(input, self.namespace), expected)
コード例 #8
0
 def test_simple_exec_import(self):
     input = "{% import string %}{{string.ascii_letters}}"
     expected_in = "abcdefghijklmnopqrstuvwxyz"
     self.assertIn(expected_in, render(input, self.namespace))
コード例 #9
0
 def test_simple_exec(self):
     input = "{% x = 5 %}{{str(x)}}"
     expected = "5"
     self.assertEqual(render(input, self.namespace), expected)
     self.assertEqual(self.namespace["x"], 5)
コード例 #10
0
 def test_namespace_substitution_with_function_call(self):
     input = "{{str(x)}}"
     expected = "42"
     self.assertEqual(render(input, self.namespace), expected)
コード例 #11
0
 def test_namespace_simple_substitution(self):
     input = "{{y}}"
     expected = "foo"
     self.assertEqual(render(input, self.namespace), expected)
コード例 #12
0
 def test_simple_substitution(self):
     """Test simple substitution."""
     input = "{{'5'}}"
     expected = "5"
     self.assertEqual(render(input), expected)