from flask import Flask, url_for, render_template, abort import os from app.config import PANDOC_LINK, PANDOC_PATH, WHITELIST_PATH from app.hash_manager import hash_file_sha512 from app.page_model import WikiPage from typing import List app = Flask(__name__) @app.context_processor def override_url_for(): return dict(url_for=dated_url_for) def get_all_names(): whitelist = WHITELIST_PATH with open(whitelist, 'r') as f: lines = f.read().splitlines() return lines def get_page(name: str) -> WikiPage: if name not in get_all_names(): raise Exception("Page doesn't exist!") path = f'{PANDOC_PATH}/{name}' with open(f'{path}/config.json', 'r') as f: page = WikiPage.parse_raw(f.read()) return page def get_all_pages() -> List[WikiPage]: return [get_page(name) for name in get_all_names()] def dated_url_for(endpoint, **values): if endpoint == 'static': filename = values.get('filename', None) if filename: file_path = os.path.join(app.root_path, endpoint, filename) values['q'] = int(os.stat(file_path).st_mtime) return url_for(endpoint, **values) def render_page(page: WikiPage): if page.name not in get_all_names(): raise Exception("Page doesn't exist!") in_filename = page.get_file('main.md') out_filename = page.get_file('render.html') os.system(f'pandoc {in_filename} --to html --mathjax --output {out_filename}') print('Creating lock file') os.system(f'echo {hash_file_sha512(in_filename)} > {out_filename}.lock') @app.route(f'/{PANDOC_LINK}/') def get_pandoc_page(name: str): page = get_page(name) if not os.path.exists(page.get_file('render.html')) or not os.path.exists(page.get_file('render.html.lock')): print(f'Rendered page or lockfile for {name} does not exist! Rendering {name}') render_page(page) else: with open(page.get_file('render.html.lock'), 'r') as f: rendered_hash = f.read().strip() current_hash = hash_file_sha512(page.get_file('main.md')) if rendered_hash != current_hash: print(f'CURRENT: {current_hash}, RENDERED: {rendered_hash}') print(f'Integrity test failed, rendering {name}!') render_page(page) template = page.template with open(page.get_file('render.html'), 'r') as f: inserted = f.read() return render_template(template, markdown=inserted, config=page) @app.route('/') def index(): return render_template('index.html', pages=get_all_pages(), PANDOC_LINK=PANDOC_LINK)