105 lines
3.5 KiB
Python
105 lines
3.5 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
|
|
from pathlib import Path
|
|
import os
|
|
import time
|
|
|
|
|
|
def make_absurl_filter(site_conf: any) -> Callable[[str], str]:
|
|
return functools.partial(get_absolute_url, site_conf)
|
|
|
|
|
|
class CLI:
|
|
@staticmethod
|
|
def generate(
|
|
base_dir: str = "site", output_dir: str = "_dist", production: bool = False
|
|
):
|
|
start = time.time()
|
|
|
|
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": git.get_latest_commit_datetime(base_dir),
|
|
}
|
|
|
|
jinja_env = build_jinja_env(site_config)
|
|
|
|
# rprint(INFO_LEADER + "Processing content")
|
|
process.content(base_dir, html_dir, jinja_env, site_config)
|
|
# rprint(INFO_LEADER + "Processing blog")
|
|
process.blog(base_dir, html_dir, jinja_env, site_config)
|
|
# rprint(INFO_LEADER + "Generating Caddy config")
|
|
process.caddy_config(base_dir, output_dir, jinja_env, site_config)
|
|
# rprint(INFO_LEADER + "Processing Sass")
|
|
process.sass(base_dir, output_dir)
|
|
|
|
if production:
|
|
# rprint(INFO_LEADER + "Compressing PNG")
|
|
process.compress_png(output_dir)
|
|
# rprint(INFO_LEADER + "Stripping EXIF data")
|
|
process.strip_exif(output_dir)
|
|
|
|
end = time.time()
|
|
|
|
rprint(INFO_LEADER + f"Finished working in {round(end-start, 3)} seconds")
|
|
|
|
@staticmethod
|
|
def watch(base_dir: str = "site", output_dir: str = "_dist"):
|
|
import inotify.adapters
|
|
import inotify.constants
|
|
import threading
|
|
import http.server
|
|
|
|
if os.path.exists(output_dir):
|
|
rprint(WARN_LEADER + f"clobbering {output_dir}")
|
|
|
|
def run():
|
|
if os.path.exists(output_dir):
|
|
shutil.rmtree(output_dir)
|
|
CLI.generate(base_dir, output_dir=output_dir)
|
|
|
|
debounced_run = debounce(1)(run)
|
|
run()
|
|
|
|
server = http.server.HTTPServer(
|
|
("127.0.0.1", 8000),
|
|
lambda a, b, c: http.server.SimpleHTTPRequestHandler(
|
|
a, b, c, directory=Path(output_dir) / "html"
|
|
),
|
|
)
|
|
threading.Thread(target=server.serve_forever, daemon=True).start()
|
|
|
|
i = inotify.adapters.InotifyTree(base_dir, mask=inotify.constants.IN_CLOSE_WRITE|inotify.constants.IN_MOVE|inotify.constants.IN_CREATE|inotify.constants.IN_DELETE)
|
|
|
|
rprint(INFO_LEADER + f"Listening on http://127.0.0.1:8000")
|
|
rprint(INFO_LEADER + f"Watching {base_dir} directory for updates")
|
|
|
|
for (header, type_names, path, filename) in i.event_gen(yield_nones=False):
|
|
rprint(INFO_LEADER + f"Change detected in {path}/{filename}")
|
|
debounced_run()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
fire.Fire(CLI)
|