promenade/promenade/renderer.py

60 lines
1.8 KiB
Python

from . import logging
import jinja2
import os
import pkg_resources
__all__ = ['Renderer']
LOG = logging.getLogger(__name__)
class Renderer:
def __init__(self, *, node_data, target_dir):
self.data = node_data
self.target_dir = target_dir
@property
def template_paths(self):
return ['common'] + self.data['current_node']['roles']
def render(self):
for template_dir in self.template_paths:
self.render_template_dir(template_dir)
def render_template_dir(self, template_dir):
source_root = pkg_resources.resource_filename(
'promenade', os.path.join('templates', template_dir))
LOG.debug('Searching for templates in: "%s"', source_root)
for root, _dirnames, filenames in os.walk(source_root,
followlinks=True):
for source_filename in filenames:
source_path = os.path.join(root, source_filename)
self.render_template_file(path=source_path,
root=source_root)
def render_template_file(self, *, path, root):
base_path = os.path.relpath(path, root)
target_path = os.path.join(self.target_dir, base_path)
_ensure_path(target_path)
LOG.debug('Templating "%s" into "%s"', path, target_path)
env = jinja2.Environment(undefined=jinja2.StrictUndefined)
with open(path) as f:
template = env.from_string(f.read())
rendered_data = template.render(**self.data)
with open(target_path, 'w') as f:
f.write(rendered_data)
LOG.info('Installed "%s"', os.path.join('/', base_path))
def _ensure_path(path):
base = os.path.dirname(path)
os.makedirs(base, mode=0o775, exist_ok=True)