Add simple mechanism for fast re-render.
This commit is contained in:
parent
a8c4d6ef48
commit
57ed8fa15c
100
scripts/blog.py
100
scripts/blog.py
@ -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:
|
||||
|
@ -7,8 +7,8 @@
|
||||
<link rel="stylesheet" href="../css/style.css" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<article>
|
||||
<h2 class="post-title">{{ title }}</h2>
|
||||
{{ content | safe }}
|
||||
</article>
|
||||
</body>
|
||||
|
Loading…
Reference in New Issue
Block a user