Source code for ninjadog.ext.pyramid
import typing as T
from pathlib import Path
from shutil import rmtree as rmdir
from pyramid.path import AssetResolver
from ninjadog.ninjadog import render
from ninjadog.constants import TEMPDIR
[docs]def get_and_update(dictionary: dict, key: T.Any, value: T.Any) -> T.Any:
"""
Get the previous value for the key and update with the new value.
Args:
dictionary: dict
key: any
value: any
Returns: the previous value for that key or the value if the key didn't exist
"""
previous = dictionary.setdefault(key, value)
dictionary.update({key: value})
return previous
[docs]def truth(value: T.Union[bool, str]) -> bool:
"""
Return whether the value is True or not.
Args:
value: an element parsed from a settings dictionary
Returns: bool
"""
if isinstance(value, bool):
return value
elif isinstance(value, str):
return value.lower().startswith('t')
[docs]def resolve(path: str, caller=None) -> Path:
"""
Return the path of the given string, given a path or asset spec.
Args:
path: absolute or relative path or asset spec
caller: the python module or package that called the function
Returns: Path to file
"""
if ':' in path:
return Path(AssetResolver().resolve(path).abspath())
elif Path(path).is_absolute():
return Path(path)
return Path(Path(caller.__file__).parent, path).absolute()
[docs]def run_once():
"""
Creates the temporary directory at runtime idempotently.
"""
has_run = False
def logic():
nonlocal has_run
if not has_run:
rmdir(TEMPDIR, ignore_errors=True)
TEMPDIR.mkdir(exist_ok=True)
has_run = True
return logic
reset_tempdir = run_once()
[docs]class PugRendererFactory:
def __init__(self, info):
self.reload = info.settings['reload_all'] or info.settings['reload_templates']
self.static_only = truth(info.settings.get('ninjadog.cache', False))
self.template_path = resolve(info.name,
info.package)
self.template_name = self.template_path.name
self.template_cache = {}
if self.static_only:
reset_tempdir()
def __call__(self, value, system):
if not isinstance(value, dict): raise ValueError('view must return dict')
context = system
context.update(value)
if self.static_only:
template_changed = False
if self.reload:
template_text = self.template_path.read_text()
template_changed = get_and_update(self.template_cache, self.template_name,
template_text) != template_text
template_file = Path(TEMPDIR, self.template_name)
if (not template_file.exists()) or (self.reload and template_changed):
html = render(file=self.template_path, context=context, with_jinja=True)
template_file.write_text(html)
return html
return template_file.read_text()
return render(file=self.template_path, context=context, with_jinja=True)
[docs]def includeme(config):
config.add_renderer('.pug', PugRendererFactory)