From afe93944810d7250d3ec354fb36124b30202d0f3 Mon Sep 17 00:00:00 2001 From: Izalia Mae Date: Sat, 7 Mar 2020 08:25:20 -0500 Subject: [PATCH] add untested jinja template functions --- IzzyLib/logging.py | 2 +- IzzyLib/template.py | 166 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 167 insertions(+), 1 deletion(-) create mode 100644 IzzyLib/template.py diff --git a/IzzyLib/logging.py b/IzzyLib/logging.py index cc91e9f..809ab09 100644 --- a/IzzyLib/logging.py +++ b/IzzyLib/logging.py @@ -1,6 +1,5 @@ ''' Simple logging module -I only created this because working with Sanic's logging is a fuck tbh ''' import sys @@ -81,6 +80,7 @@ class Log(): stdout.flush() + def log(self, level, msg): '''log to the console''' levelNum = self._lvlCheck(level) diff --git a/IzzyLib/template.py b/IzzyLib/template.py new file mode 100644 index 0000000..e1dfa2a --- /dev/null +++ b/IzzyLib/template.py @@ -0,0 +1,166 @@ +import codecs, traceback, os, json + +from os import listdir, makedirs +from os.path import isfile, isdir, getmtime, abspath + +from jinja2 import Environment, FileSystemLoader, ChoiceLoader +from hamlpy.hamlpy import Compiler +from markdown import markdown + +from . import logging + + +__all__ = ['addSearchPath', 'delSearchPath', 'addBuildPath', 'delSearchPath', 'setup', 'render_template', 'build_templates'] + + +env = None + +global_variables = { + 'markdown': markdown, + 'lighten': color().lighten, + 'darken': color().darken, + 'saturate': color().saturate, + 'desaturate': color().desaturate, + 'rgba': color().rgba +} + +config = { + search_path: str(), + build_path_pairs: dict() +} + + +def addSearchPath(path): + tplPath = abspath(path) + + if tplPath not in search_path: + search_path.append(tplPath) + + +def delSearchPath(path): + tplPath = abspath(path) + + if tplPath in search_path: + search_path.remove(tplPath) + + +def addBuildPath(name, source, destination): + src = abspath(source) + dest = abspath(destination) + + if not isdir(src): + raise FileNotFoundError('Source path doesn\'t exist: {src}') + + build_path_pairs.update({ + name: { + 'source': src, + 'destination': dest + } + }) + + addSearchPath(dest) + + +def delBuildPath(name): + if not build_path_pairs.get(name): + raise ValueError(f'"{name}" not in build paths') + + del build_path_pairs(src) + + +def getBuildPath(name=None): + paths = list() + template = build_path_pairs.get(name) + + if name: + if template: + paths.append((template['source'], template['destination'])) + + else: + raise ValueError(f'"{name}" not in build paths') + + else: + for k, tpl in build_path_pairs.items(): + paths.append((tpl['source'], tpl['destination'])) + + return paths + + +def setup(): + env = Environment( + loader=ChoiceLoader([FileSystemLoader(path) for path in tpl_paths]) + ) + + +def render_template(tplfile, context, headers=None, cookies=None, status=200): + data = global_variables.copy() + data.update(context) + + if headers: + data['headers'] = request + + if cookies: + data['cookies'] = cookies + + if not isinstance(context, dict): + raise TypeError(f'Context for {tplfile} not a dict') + + return env.get_template(tplfile).render(data) + + +def build_templates(name=None): + paths = getBuildPath(name) + + for tplPaths in paths: + src = tplPaths['source'] + dest = tplPaths['destination'] + + timefile = f'{dest}/times.json' + updated = False + + if not isdir(f'{dest}'): + makedirs(f'{dest}') + + if isfile(timefile): + try: + times = json.load(open(timefile)) + + except: + times = {} + + else: + times = {} + + for filename in listdir(f'{src}/templates'): + fullPath = f'{src}/{filename}' + modtime = getmtime(fullPath) + base, ext = filename.split('.') + + if ext != 'haml': + pass + + elif base not in times or times.get(base) != modtime: + updated = True + logging.verbose(f"Template '{filename}' was changed. Building...") + + try: + destination = f'{dest}/{base}.html' + haml_lines = codecs.open(fullPath, 'r', encoding='utf-8').read().splitlines() + + compiler = Compiler() + output = compiler.process_lines(haml_lines) + outfile = codecs.open(destination, 'w', encoding='utf-8') + outfile.write(output) + + logging.info(f"Template '{filename}' has been built") + + except Exception as e: + '''I'm actually not sure what sort of errors can happen here, so generic catch-all for now''' + traceback.print_exc() + logging.error(f'Failed to build {filename}: {e}') + + times[base] = modtime + + if updated: + with open(timefile, 'w') as filename: + filename.write(json.dumps(times))