"""Builder for websites."""
import os
import shutil
from regolith.builders.basebuilder import BuilderBase
from regolith.dates import get_dates
from regolith.fsclient import _id_key
from regolith.sorters import ene_date_key, position_key
from regolith.tools import (
all_docs_from_collection,
filter_publications,
filter_projects,
make_bibtex_file,
document_by_value,
dereference_institution,
)
[docs]class HtmlBuilder(BuilderBase):
"""Build HTML files for website"""
btype = "html"
def __init__(self, rc):
super().__init__(rc)
# TODO: get this from the RC
self.cmds = [
"root_index",
"people",
"projects",
"blog",
"jobs",
"abstracts",
"nojekyll",
"cname",
"finish",
]
[docs] def construct_global_ctx(self):
"""Constructs the global context"""
super().construct_global_ctx()
gtx = self.gtx
rc = self.rc
gtx["jobs"] = list(all_docs_from_collection(rc.client, "jobs"))
gtx["people"] = sorted(
all_docs_from_collection(rc.client, "people"),
key=position_key,
reverse=True,
)
gtx["abstracts"] = list(
all_docs_from_collection(rc.client, "abstracts")
)
gtx["group"] = document_by_value(
all_docs_from_collection(rc.client, "groups"), "name", rc.groupname
)
gtx["all_docs_from_collection"] = all_docs_from_collection
gtx["institutions"] = sorted(
all_docs_from_collection(rc.client, "institutions"), key=_id_key
)
[docs] def finish(self):
"""Move files over to their destination and remove them from the
source"""
# static
stsrc = os.path.join(
getattr(self.rc, "static_source", "templates"), "static"
)
stdst = os.path.join(self.bldir, "static")
if os.path.isdir(stdst):
shutil.rmtree(stdst)
if os.path.isdir(stsrc):
shutil.copytree(stsrc, stdst)
[docs] def root_index(self):
"""Render root index"""
self.render("root_index.html", "index.html", title="Home")
make_bibtex_file(list(all_docs_from_collection(self.rc.client,
"citations")),
pid='group',
person_dir=self.bldir,
)
[docs] def people(self):
"""Render people, former members, and each person"""
rc = self.rc
peeps_dir = os.path.join(self.bldir, "people")
former_peeps_dir = os.path.join(self.bldir, "former")
os.makedirs(peeps_dir, exist_ok=True)
os.makedirs(former_peeps_dir, exist_ok=True)
peeps = self.gtx["people"]
for p in peeps:
names = frozenset(p.get("aka", []) + [p["name"]])
pubs = filter_publications(
all_docs_from_collection(rc.client, "citations"),
names,
reverse=True,
bold=False,
)
bibfile = make_bibtex_file(
pubs, pid=p["_id"], person_dir=peeps_dir
)
emps = p.get("employment", [])
emps = [em for em in emps
if not em.get("not_in_cv", False)]
for e in emps:
e['position'] = e.get('position_full', e.get('position').title())
ene = emps + p.get("education", [])
ene.sort(key=ene_date_key, reverse=True)
for e in ene:
dereference_institution(e,
all_docs_from_collection(
rc.client, "institutions"))
projs = filter_projects(
all_docs_from_collection(rc.client, "projects"), names
)
for serve in p.get("service", []):
serve_dates = get_dates(serve)
date = serve_dates.get("date")
if not date:
date = serve_dates.get("end_date")
if not date:
date = serve_dates.get("begin_date")
serve["year"] = date.year
serve["month"] = date.month
sns = p.get("service", [])
sns.sort(key=ene_date_key, reverse=True)
p["service"] = sns
self.render(
"person.html",
os.path.join("people", p["_id"] + ".html"),
p=p,
title=p.get("name", ""),
pubs=pubs,
names=names,
bibfile=bibfile,
education_and_employment=ene,
projects=projs,
)
self.render(
"people.html", os.path.join("people", "index.html"), title="People"
)
self.render(
"former.html",
os.path.join("former", "index.html"),
title="Former Members",
)
[docs] def projects(self):
"""Render projects"""
rc = self.rc
projs = all_docs_from_collection(rc.client, "projects")
self.render(
"projects.html", "projects.html", title="Projects", projects=projs
)
[docs] def blog(self):
"""Render the blog and rss"""
rc = self.rc
blog_dir = os.path.join(self.bldir, "blog")
os.makedirs(blog_dir, exist_ok=True)
posts = list(all_docs_from_collection(rc.client, "blog"))
posts.sort(key=ene_date_key, reverse=True)
for post in posts:
self.render(
"blog_post.html",
os.path.join("blog", post["_id"] + ".html"),
post=post,
title=post["title"],
)
self.render(
"blog_index.html",
os.path.join("blog", "index.html"),
title="Blog",
posts=posts,
)
self.render("rss.xml", os.path.join("blog", "rss.xml"), items=posts)
[docs] def jobs(self):
"""Render the jobs and each job"""
jobs_dir = os.path.join(self.bldir, "jobs")
os.makedirs(jobs_dir, exist_ok=True)
for job in self.gtx["jobs"]:
self.render(
"job.html",
os.path.join("jobs", job["_id"] + ".html"),
job=job,
title="{0} ({1})".format(job["title"], job["_id"]),
)
self.render(
"jobs.html", os.path.join("jobs", "index.html"), title="Jobs"
)
[docs] def abstracts(self):
"""Render each abstract"""
abs_dir = os.path.join(self.bldir, "abstracts")
os.makedirs(abs_dir, exist_ok=True)
for ab in self.gtx["abstracts"]:
self.render(
"abstract.html",
os.path.join("abstracts", ab["_id"] + ".html"),
abstract=ab,
title="{0} {1} - {2}".format(
ab["firstname"], ab["lastname"], ab["title"]
),
)
[docs] def nojekyll(self):
"""Touches a nojekyll file in the build dir"""
with open(os.path.join(self.bldir, ".nojekyll"), "a+"):
pass
[docs] def cname(self):
"""Add CNAME"""
rc = self.rc
if not hasattr(rc, "cname"):
return
with open(
os.path.join(self.bldir, "CNAME"), "w", encoding="utf-8"
) as f:
f.write(rc.cname)