Add simple mechanism for fast re-render.

This commit is contained in:
Sergio Martínez Portela 2022-06-27 21:02:33 +02:00
parent a8c4d6ef48
commit 57ed8fa15c
2 changed files with 89 additions and 13 deletions

View File

@ -17,12 +17,15 @@ import logging
import sys
import os
import datetime
import jinja2
import shutil
import traceback
import time
import re
import jinja2
import inotify.adapters
import yaml
import markdown
import re
from unidecode import unidecode
NIKOLA_DATE_RE = re.compile(r'^([0-2]\d|30|31)\.(0\d|1[012])\.(\d{4}), (\d{1,2}):(\d{2})$')
@ -44,7 +47,24 @@ JINJA_ENV = jinja2.Environment(
loader=jinja2.FileSystemLoader(STATIC_PATH),
autoescape=jinja2.select_autoescape()
)
ARTICLE_TEMPLATE = JINJA_ENV.get_template(ARTICLE_TEMPLATE_NAME)
def update_statics():
global ARTICLE_TEMPLATE
ARTICLE_TEMPLATE = JINJA_ENV.get_template(ARTICLE_TEMPLATE_NAME)
update_statics()
MONITORED_EVENT_TYPES = (
'IN_CREATE',
# 'IN_MODIFY',
'IN_CLOSE_WRITE',
'IN_DELETE',
'IN_MOVED_FROM',
'IN_MOVED_TO',
'IN_DELETE_SELF',
'IN_MOVE_SELF',
)
def parse_nikola_date(match):
return datetime.datetime(year=int(match.group(3)),
@ -53,9 +73,11 @@ def parse_nikola_date(match):
hour=int(match.group(4)),
minute=int(match.group(5)))
def parse_complete_date(match):
return datetime.datetime.strptime(match.group(0), '%Y-%m-%d %H:%M:%S %Z%z')
def slugify(title):
"""
Made for compatibility with Nikola's slugify within CodigoParaLlevar blog.
@ -66,6 +88,7 @@ def slugify(title):
return slug.strip()
def read_markdown(path):
with open(path, 'rt') as f:
data = f.read()
@ -112,7 +135,7 @@ def get_out_path(front_matter):
def load_all(top_dir_relative):
top = os.path.abspath(top_dir_relative)
docs = []
docs = {}
for root, dirs, files in os.walk(top):
for name in files:
@ -124,29 +147,82 @@ def load_all(top_dir_relative):
path = os.path.join(root, name)
doc, front_matter = read_markdown(path)
out_path = get_out_path(front_matter)
docs.append((doc, front_matter, out_path))
docs[path] = (doc, front_matter, out_path)
else:
raise NotImplementedError('Unknown filetype: {}'.format(name))
return docs
def render_article(doc, f):
result = ARTICLE_TEMPLATE.render(content=doc)
def load_doc(filepath):
doc, front_matter = read_markdown(filepath)
out_path = get_out_path(front_matter)
return (doc, front_matter, out_path)
def render_article(doc, front_matter, f):
result = ARTICLE_TEMPLATE.render(content=doc, title=front_matter['title'])
f.write(result)
def main(source_top, dest_top):
docs = load_all(source_top)
for (doc, front_matter, out_path) in docs:
def regen_all(source_top, dest_top, docs=None):
if docs is None:
docs = load_all(source_top)
for (doc, front_matter, out_path) in docs.values():
doc_full_path = os.path.join(dest_top, out_path)
os.makedirs(os.path.dirname(doc_full_path), exist_ok=True)
print("==", doc_full_path)
# print("==", doc_full_path)
with open(doc_full_path + '.html', 'wt') as f:
render_article(doc, f)
render_article(doc, front_matter, f)
for src, dest in STATIC_RESOURCES:
target_dest = os.path.join(dest_top, dest)
os.makedirs(os.path.dirname(target_dest), exist_ok=True)
shutil.copy(os.path.join(STATIC_PATH, src), target_dest)
return docs
def main(source_top, dest_top):
notifier = inotify.adapters.InotifyTrees([source_top, STATIC_PATH])
## Initial load
t0 = time.time()
logging.info("Initial load...")
docs = regen_all(source_top, dest_top)
logging.info("Initial load completed in {:.2f}s".format(time.time() - t0))
## Updating
for event in notifier.event_gen(yield_nones=False):
(ev, types, directory, file) = event
if not any([type in MONITORED_EVENT_TYPES for type in types]):
continue
filepath = os.path.join(directory, file)
if filepath.startswith(STATIC_PATH):
t0 = time.time()
update_statics()
for src, dest in STATIC_RESOURCES:
target_dest = os.path.join(dest_top, dest)
os.makedirs(os.path.dirname(target_dest), exist_ok=True)
shutil.copy(os.path.join(STATIC_PATH, src), target_dest)
docs = regen_all(source_top, dest_top, docs)
logging.info("Updated all in {:.2f}s".format(time.time() - t0))
else:
try:
(doc, front_matter, out_path) = load_doc(filepath)
except:
logging.error(traceback.format_exc())
logging.error("Skipping update 😿")
continue
t0 = time.time()
docs[filepath] = (doc, front_matter, out_path)
doc_full_path = os.path.join(dest_top, out_path)
os.makedirs(os.path.dirname(doc_full_path), exist_ok=True)
# print("==", doc_full_path)
with open(doc_full_path + '.html', 'wt') as f:
render_article(doc, front_matter, f)
logging.info("Updated all in {:.2f}s".format(time.time() - t0))
if __name__ == "__main__":
if len(sys.argv) != 3:

View File

@ -7,8 +7,8 @@
<link rel="stylesheet" href="../css/style.css" />
</head>
<body>
<article>
<h2 class="post-title">{{ title }}</h2>
{{ content | safe }}
</article>
</body>