uncia/uncia/templates.py

119 lines
2.8 KiB
Python

import codecs, traceback, os
import ujson as json
from os import listdir
from os.path import isfile, isdir, getmtime
from jinja2 import Environment, FileSystemLoader, ChoiceLoader
from hamlpy.hamlpy import Compiler
from sanic import response
from markdown import markdown
from .log import logging
from .functions import cssts, color
from .config import version, stor_path, script_path
from .database import get
global_variables = {
'get': get,
'version': version,
'markdown': markdown,
'lighten': color().lighten,
'darken': color().darken,
'saturate': color().saturate,
'desaturate': color().desaturate,
'rgba': color().rgba,
'cssts': cssts,
'len': len,
'type': type
}
env = Environment(
loader=ChoiceLoader([
FileSystemLoader(f'{stor_path}/build'),
FileSystemLoader(f'{script_path}/frontend')
])
)
def render(tplfile, request, context, headers=None, status=200):
data = global_variables.copy()
data['request'] = request
data.update(context)
if type(context) != dict:
logging.error(f'Context for {template} not a dict')
resp = response.html(env.get_template(tplfile).render(data))
if headers:
resp.headers.update(headers)
return resp
def error(request, msg, status):
if 'json' in request.headers.get('accept', '') or (request.path == '/inbox' and 'mozilla' not in request.headers.get('user-agent', '').lower()):
return response.json({'err': msg}, status=status)
data = {'msg': msg, 'code': str(status), 'config': get.config('all')}
return render('error.html', request, data, status=status)
def build_templates():
timefile = f'{stor_path}/build/times.json'
updated = False
if not isdir(f'{stor_path}/build'):
os.makedirs(f'{stor_path}/build')
if isfile(timefile):
try:
times = json.load(open(timefile))
except:
times = {}
else:
times = {}
for filename in listdir(f'{script_path}/frontend/templates'):
modtime = getmtime(f'{script_path}/frontend/templates/{filename}')
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:
template = f'{script_path}/frontend/templates/{filename}'
destination = f'{stor_path}/build/{base}.html'
haml_lines = codecs.open(template, 'r', encoding='utf-8').read().splitlines()
if not isfile(template):
return False
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:
traceback.print_exc()
logging.error(f'Failed to build {filename}')
times[base] = modtime
if updated:
with open(timefile, 'w') as filename:
filename.write(json.dumps(times))