"""Render REVIEW.html, the page a reviewer works in, and pick out role words for each group.
No clustering code, so the tests load it instantly. The page is one self-contained file:
the template (review_page.html) with the rules (review_page_logic.cjs) and the run's data
inlined, so it opens by double-clicking with no server and nothing installed.
"""
import collections, html, json, pathlib, re
import review_format as rf
HERE = pathlib.Path(__file__).resolve().parent
# People the summaries mention by role. Offered as click-to-fill words on the page, because
# naming the two people in a situation was the hardest part of the first review. A fixed list
# rather than anything clever: it only has to suggest, and the reviewer can type anything.
ROLE_WORDS = set("""
wife husband daughter son father mother uncle aunt nephew niece brother sister cousin friend
suitor fiance fiancee bride groom lover admirer rival sweetheart widow widower
boss employer employee clerk typist stenographer secretary partner manager foreman
cop policeman officer captain detective marshal judge lawyer
landlady landlord tenant lodger boarder roomer housekeeper
waiter waitress cook chef bartender proprietor owner shopkeeper storekeeper merchant salesman
saleslady shopgirl customer patron guest host servant maid butler chambermaid
driver cabby cabman coachman chauffeur
artist painter poet writer author editor reporter journalist actor actress singer dancer model
doctor nurse patient preacher teacher student professor
stranger neighbour neighbor visitor newcomer millionaire banker broker gambler thief crook
burglar tramp beggar vagrant panhandler worker girl woman man boy child
""".split())
def role_hints(members, limit=8):
"""The role words that turn up most in a group's summaries."""
counts = collections.Counter()
for m in members:
for word in re.findall(r"[a-z]+", m['summary'].lower()):
if word in ROLE_WORDS:
counts[word] += 1
return [word for word, _ in counts.most_common(limit)]
def page_data(document):
return {'run': document['run'], 'rules': rf.RULES, 'candidates': document['candidates']}
def render_page(document):
template = (HERE / 'review_page.html').read_text(encoding='utf-8')
logic = (HERE / 'review_page_logic.cjs').read_text(encoding='utf-8')
for marker in ('/*__LOGIC__*/', '/*__DATA__*/null', '__RUN_ID__'):
if marker not in template:
raise ValueError(f'review_page.html is missing the {marker} marker')
# Data inside a "
# would end the script early. Escaping "" is enough and is still valid JSON.
data = json.dumps(page_data(document), ensure_ascii=False).replace('', '<\\/')
logic = logic.replace('