allaroundhere.org/build.py

123 lines
2.9 KiB
Python

import argparse
import datetime
from dataclasses import dataclass
from pathlib import Path
from typing import NamedTuple
from typing import Optional
from typing import Sequence
from typing import Union
import jinja2
import marshmallow as msh
import ruamel.yaml
yaml = ruamel.yaml.YAML(typ="safe")
@dataclass
class MediaContainer:
title: str
asset: str
anchor: Optional[Union[str, int]] = None
source: Optional[str] = None
content: Optional[str] = None
hide_source: bool = False
class MediaSerializer(msh.Schema):
title = msh.fields.String()
asset = msh.fields.URL()
anchor = msh.fields.String(required=False)
source = msh.fields.URL(required=False)
content = msh.fields.String(required=False)
hide_source = msh.fields.Boolean(required=False)
@dataclass
class LinkContainer:
link: str
title: Optional[str] = None
icon: Optional[str] = None
class LinkSerializer(msh.Schema):
link = msh.fields.URL()
title = msh.fields.String(required=False)
icon = msh.fields.String(required=False)
class Location(NamedTuple):
title: str
link: str
class LocationSeralizer(msh.Schema):
title = msh.fields.String()
link = msh.fields.URL()
@dataclass
class PostContainer:
title: str
location: Location
date: datetime.date
banner: str
media: Sequence[MediaContainer]
links: Sequence[LinkContainer] = ()
slug: Optional[str] = None
class PostSerializer(msh.Schema):
title = msh.fields.String()
location = msh.fields.Nested(LocationSeralizer)
date = msh.fields.Date()
banner = msh.fields.URL()
slug = msh.fields.String(required=False)
links = msh.fields.List(msh.fields.Nested(LinkSerializer), required=False)
media = msh.fields.List()
def get_args() -> argparse.Namespace:
parser = argparse.ArgumentParser()
parser.add_argument(
"-c", "--check", action="store_true", help="Check the config without building"
)
return parser.parse_args()
def main():
cwd = Path.cwd().resolve()
output = cwd / "explore"
with (cwd / "config.yaml").open() as infile:
config = yaml.load(infile)
env = jinja2.Environment(
loader=jinja2.FileSystemLoader(str(cwd / "templates")),
autoescape=jinja2.select_autoescape(["html", "xml"]),
)
if not output.exists():
output.mkdir()
index = env.get_template("index.html.j2").render(config=config)
with (output / "index.html").open("w") as outfile:
outfile.write(index)
post_template = env.get_template("post.html.j2")
for post_data in config["posts"]:
post = post_template.render(post=post_data)
with (output / f"{post_data['slug']}.html").open("w") as outfile:
outfile.write(post)
nginx = env.get_template("nginx.conf.d.j2").render(config=config)
with (cwd / "nginx.conf").open("w") as outfile:
outfile.write(nginx)
if __name__ == "__main__":
main()