91 lines
3.1 KiB
Python
91 lines
3.1 KiB
Python
from rich import print as rprint
|
|
|
|
import git
|
|
from util import *
|
|
from jinja2 import Environment, FileSystemLoader, select_autoescape
|
|
import fire
|
|
from collections.abc import Callable
|
|
import process
|
|
import functools
|
|
import shutil
|
|
|
|
|
|
def make_absurl_filter(site_conf: any) -> Callable[[str], str]:
|
|
return functools.partial(get_absolute_url, site_conf)
|
|
|
|
class CLI:
|
|
@staticmethod
|
|
def g(*args, **kwargs):
|
|
return CLI.generate(*args, **kwargs)
|
|
|
|
@staticmethod
|
|
def generate(base_dir: str, output_dir: str = "_dist"):
|
|
base_dir = Path(base_dir)
|
|
output_dir = Path(output_dir)
|
|
html_dir = output_dir / "html"
|
|
|
|
if output_dir.exists() and not is_directory_empty(output_dir):
|
|
rprint(
|
|
WARN_LEADER
|
|
+ f"A directory called [bold]{output_dir}[/bold] already exists and is not "
|
|
f"empty"
|
|
)
|
|
|
|
with open(base_dir / "config.yml") as f:
|
|
site_config = load_yaml(f.read())
|
|
assert (
|
|
"build" not in site_config
|
|
), "build section of site config must not exist so it can be written at runtime"
|
|
site_config["build"] = {
|
|
"hash": git.get_latest_commit_hash(base_dir)[:7],
|
|
"date": datetime.datetime.utcnow(),
|
|
}
|
|
|
|
jinja_env = Environment(
|
|
loader=FileSystemLoader("site/content"), autoescape=select_autoescape()
|
|
)
|
|
|
|
jinja_env.filters["absurl"] = make_absurl_filter(site_config)
|
|
jinja_env.filters["fmtdate"] = lambda x: x.strftime("%Y-%m-%d")
|
|
|
|
process.content(base_dir, html_dir, jinja_env, site_config)
|
|
process.blog(base_dir, html_dir, jinja_env, site_config)
|
|
process.caddy_config(base_dir, output_dir, jinja_env, site_config)
|
|
|
|
thing_overrides = {"rendered": "page"}
|
|
res_parts = []
|
|
for (key, count) in get_counts().items():
|
|
s = "" if count == 1 else "s"
|
|
res_parts.append(f"{key} {count} {thing_overrides.get(key, 'file')}{s}")
|
|
|
|
rprint(INFO_LEADER + "Finished working, " + ", ".join(res_parts))
|
|
|
|
@staticmethod
|
|
def watch(base_dir: str, output_dir: str = "_dist"):
|
|
import pyinotify
|
|
|
|
if os.path.exists(output_dir):
|
|
rprint(WARN_LEADER + f"{output_dir} already exists and will be clobbered when regeneration is triggered")
|
|
|
|
@debounce(1)
|
|
def run():
|
|
if os.path.exists(output_dir):
|
|
shutil.rmtree(output_dir)
|
|
reset_counts() # boys and girls, this is why global state is bad
|
|
CLI.generate(base_dir, output_dir=output_dir)
|
|
|
|
class OnWriteHandler(pyinotify.ProcessEvent):
|
|
def process_IN_MODIFY(self, event):
|
|
rprint(INFO_LEADER + f"Change detected in {event.pathname}")
|
|
run()
|
|
|
|
wm = pyinotify.WatchManager()
|
|
notifier = pyinotify.Notifier(wm, default_proc_fun=OnWriteHandler())
|
|
wm.add_watch(base_dir, pyinotify.ALL_EVENTS, rec=True, auto_add=True)
|
|
|
|
rprint(INFO_LEADER + f"Watching {base_dir}")
|
|
notifier.loop()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
fire.Fire(CLI)
|