from datetime import datetime
from pathlib import Path
import sys
from typing import Any, Dict, List

from jinja2 import Environment, FileSystemLoader
import pytz
import yaml

from .models import Author, Entry

root_dir = Path(__file__).parent.parent
data_dir = root_dir / "data"
source_dir = root_dir / "source"
output_dir = root_dir / "output"
loader = FileSystemLoader(str(source_dir), encoding="utf-8")
env = Environment(loader=loader)

today = datetime.now(pytz.timezone("Asia/Tokyo")).date()


def load_authors() -> Dict[str, Author]:
    with open(data_dir / "authors.yml") as f:
        authors_list = yaml.load(f, Loader=yaml.SafeLoader)
    authors = [Author(**d) for d in authors_list]
    return {author.name: author for author in authors}


def load_entries() -> Dict[int, List[Entry]]:
    authors = load_authors()

    def load_entry(d: Dict[str, Any]) -> Entry:
        entry = Entry(**d)

        if entry.author is not None:
            entry.author_url = authors[entry.author].url

        if entry.date > today:
            # Not ready
            entry.url = None

        return entry

    with open(data_dir / "entries.yml") as f:
        entries = [load_entry(d) for d in yaml.load(f, Loader=yaml.SafeLoader)]

    # Aggregate
    entries_by_year = {}
    years = list({e.date.year for e in entries})
    for year in sorted(years, reverse=True):
        entries_by_year[year] = [e for e in entries if e.date.year == year]

    return entries_by_year


def minify_html(html: str) -> str:
    lines = iter(html.split("\n"))
    lines = filter(lambda line: line != "", map(lambda l: l.strip(), lines))
    return "\n".join(lines)


def run(debug: bool = False) -> None:
    context = {
        "debug": debug,
        "description": (
            "京都の学生コミュニティ CAMPHOR- の Advent Calendar 特設ページです。"
            "様々な記事を毎日追加していきます。"),
        "entries_for_years": load_entries(),
        "root": "https://advent.camph.net/",
        "title": "CAMPHOR- Advent Calendar"
    }

    filename = "index.html"
    template = env.get_template(filename)
    html = minify_html(template.render(**context))
    with open(output_dir / filename, "w") as f:
        f.write(html)

    filename = "amp.html"
    template = env.get_template(filename)
    html = minify_html(template.render(**context))
    with open(output_dir / filename, "w") as f:
        f.write(html)


def main() -> None:
    debug = "--debug" in sys.argv[1:]
    run(debug=debug)


main()

@@ -88,16 +88,26 @@
 y, Dict,
+ Iterable,
  List%0A%0Af
@@ -782,18 +782,8 @@
 ) -%3E
- Dict%5Bint,
  Lis
@@ -790,17 +790,16 @@
 t%5BEntry%5D
-%5D
 :%0A    au
@@ -1158,41 +1158,35 @@
     
-entries = %5Bload_entry(d) for d in
+return list(map(load_entry,
  yam
@@ -1222,26 +1222,91 @@
 der)
-%5D%0A%0A    # Aggregate
+))%0A%0A%0Adef group_entries_by_year(entries: Iterable%5BEntry%5D) -%3E Dict%5Bint, List%5BEntry%5D%5D:
 %0A   
@@ -1497,17 +1497,16 @@
 = year%5D%0A
-%0A
     retu
@@ -1737,24 +1737,106 @@
 e) -%3E None:%0A
+    entries = load_entries()%0A    entries_by_year = group_entries_by_year(entries)%0A
     context 
@@ -2013,30 +2013,31 @@
 years%22: 
-load_
 entries
-()
+_by_year
 ,%0A      

Split load_entries to multiple functions