"""Builder for websites."""
import datetime as dt
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,
dereference_institution,
document_by_value,
filter_projects,
filter_publications,
fuzzy_retrieval,
get_formatted_crossref_reference,
make_bibtex_file,
)
PROJ_URL_BASE = "https://gitlab.thebillingegroup.com/talks/"
[docs]
class InternalHtmlBuilder(BuilderBase):
"""Build HTML files for website"""
btype = "internalhtml"
needed_colls = ["people", "meetings"]
def __init__(self, rc):
super().__init__(rc)
# TODO: get this from the RC
self.cmds = [
"root_index",
"meetings",
"nojekyll",
"cname",
]
[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["meetings"] = list(all_docs_from_collection(rc.client, "meetings"))
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)
shutil.copytree(stsrc, stdst)
[docs]
def root_index(self):
"""Render root index"""
self.render("introot_index.html", "intindex.html", title="Home")
[docs]
def meetings(self):
"""Render projects"""
rc = self.rc
mtgsi = all_docs_from_collection(rc.client, "meetings")
pp_mtgs, f_mtgs, jclub_cumulative = [], [], []
for mtg in mtgsi:
if not mtg.get("lead"):
print("{} missing a meeting lead".format(mtg["_id"]))
if not mtg.get("scribe"):
print("{} missing a meeting scribe".format(mtg["_id"]))
lead = fuzzy_retrieval(
all_docs_from_collection(rc.client, "people"), ["_id", "name", "aka"], mtg.get("lead")
)
if not lead:
print("{} lead {} not found in people".format(mtg["_id"], mtg.get("lead")))
mtg["lead"] = lead["name"]
scribe = fuzzy_retrieval(
all_docs_from_collection(rc.client, "people"), ["_id", "name", "aka"], mtg.get("scribe")
)
if not scribe:
print("{} scribe {} not found in people".format(mtg["_id"], mtg.get("scribe")))
mtg["scribe"] = scribe["name"]
if mtg.get("journal_club"):
prsn_id = mtg["journal_club"].get("presenter", "None")
prsn = fuzzy_retrieval(
all_docs_from_collection(rc.client, "people"), ["_id", "name", "aka"], prsn_id
)
if not prsn:
if prsn_id.lower() not in ["tbd", "hold", "na"]:
print(
"WARNING: {} presenter {} not found in people".format(
mtg["_id"], mtg["presentation"].get("presenter")
)
)
prsn = {"name": prsn_id}
mtg["journal_club"]["presenter"] = prsn["name"]
mtg_jc_doi = mtg["journal_club"].get("doi", "tbd")
mtg_jc_doi_casefold = mtg_jc_doi.casefold()
if mtg_jc_doi_casefold == "na":
mtg["journal_club"]["doi"] = "N/A"
elif mtg_jc_doi_casefold != "tbd":
if not mtg_jc_doi_casefold.startswith("arxiv"):
ref, _ = get_formatted_crossref_reference(mtg["journal_club"].get("doi"))
mtg["journal_club"]["doi"] = ref
else:
ref = mtg_jc_doi
jclub_cumulative.append((ref, get_dates(mtg).get("date", "no date")))
if mtg.get("presentation"):
prsn_id = mtg["presentation"].get("presenter", "None")
prsn = fuzzy_retrieval(
all_docs_from_collection(rc.client, "people"), ["_id", "name", "aka"], prsn_id
)
if not prsn:
if prsn_id.lower() not in ["tbd", "hold", "na"]:
print(
"WARNING: {} presenter {} not found in people".format(
mtg["_id"], mtg["presentation"].get("presenter")
)
)
prsn = {"name": prsn_id}
mtg["presentation"]["presenter"] = prsn["name"]
mtg["presentation"]["link"] = mtg["presentation"].get("link", "tbd")
mtg["date"] = dt.date(mtg.get("year"), mtg.get("month"), mtg.get("day"))
mtg["datestr"] = mtg["date"].strftime("%m/%d/%Y")
today = dt.date.today()
if mtg["date"] >= today:
f_mtgs.append(mtg)
else:
pp_mtgs.append(mtg)
jclub_cumulative = sorted(jclub_cumulative, key=lambda x: x[1], reverse=True)
pp_mtgs = sorted(pp_mtgs, key=lambda x: x.get("date"), reverse=True)
f_mtgs = sorted(f_mtgs, key=lambda x: x.get("date"))
self.render(
"grpmeetings.html",
"grpmeetings.html",
title="Group Meetings",
ppmeetings=pp_mtgs,
fmeetings=f_mtgs,
jclublist=jclub_cumulative,
)
[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)
[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)
ene = p.get("employment", []) + p.get("education", [])
ene.sort(key=ene_date_key, reverse=True)
for e in ene:
dereference_institution(e, self.gtx["institutions"])
projs = filter_projects(all_docs_from_collection(rc.client, "projects"), names)
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"]),
)