Files

206 lines
6.2 KiB
Python

from pathlib import Path
from typing import Literal, Sequence
import fitz # type: ignore
def make_geometry_pdf(path: Path) -> Path:
"""Create the same non-empty geometry fixture used for the legacy golden."""
doc = fitz.open()
page = doc.new_page(width=792, height=612)
page.draw_rect(page.rect, color=(1, 1, 1), fill=(1, 1, 1), width=0)
page.draw_rect(
fitz.Rect(0, 0, 96, 48),
color=(1, 0, 0),
fill=(1, 0, 0),
width=0,
)
page.draw_rect(
fitz.Rect(696, 564, 792, 612),
color=(0, 0, 1),
fill=(0, 0, 1),
width=0,
)
page.draw_line(
fitz.Point(0, 306),
fitz.Point(792, 306),
color=(0, 0, 0),
width=2,
)
page.insert_text(
(310, 320),
"GEOMETRY FIXTURE",
fontsize=20,
color=(0, 0, 0),
)
doc.save(path)
doc.close()
return path
def _make_subsplash_roster_pdf(
path: Path,
roster_type: Literal["main", "nursery_only"],
dates: Sequence[str],
) -> Path:
"""Create a realistic one-page, vector Subsplash-style roster fixture.
The fixture deliberately resembles the structure of ``input/original.pdf``:
dates run across the top, role headings and assignment labels run down the
left, and the cells contain volunteer names. It is not used by the legacy
geometry golden, so changes here cannot mask a single-roster regression.
"""
if not dates:
raise ValueError("at least one date is required")
document = fitz.open()
page = document.new_page(width=792, height=612)
page.draw_rect(page.rect, color=None, fill=(1, 1, 1), width=0)
if roster_type == "main":
table = fitz.Rect(34, 48, 758, 446)
roles = (
("MEDIA", "Sound", "Alex Morgan"),
("NURSERY", "Nursery Workers", "Jamie Rivera"),
("LITTLE WADERS", "Teacher", "Taylor Brooks"),
("RIVER KID", "Teacher", "Jordan Lee"),
("GREETERS", "Greet", "Morgan Reed"),
("USHERS", "Usher", "Casey Miller"),
("OFFERING MESSAGE", "Speaker", "Riley Davis"),
("PRAYER", "Prayer", "Avery Wilson"),
)
else:
# Mirrors the compact real nursery strip: roughly 36 points of date
# header plus about 66 points for the band and worker row.
table = fitz.Rect(14, 188, 778, 290)
roles = (("NURSERY WORKERS", "Nursery Workers", "Jamie Rivera"),)
first_column_width = 154
header_height = 42 if roster_type == "main" else 36
date_width = (table.width - first_column_width) / len(dates)
role_height = (table.height - header_height) / len(roles)
navy = (0.06, 0.18, 0.25)
pale_blue = (0.90, 0.95, 0.97)
grid = (0.36, 0.43, 0.47)
page.draw_rect(table, color=grid, fill=(1, 1, 1), width=0.8)
page.draw_rect(
fitz.Rect(table.x0, table.y0, table.x1, table.y0 + header_height),
color=grid,
fill=navy,
width=0.8,
)
page.insert_text(
(table.x0 + 8, table.y0 + 26),
"SERVING SCHEDULE",
fontname="helv",
fontsize=10,
color=(1, 1, 1),
)
first_date_x = table.x0 + first_column_width
page.draw_line(
fitz.Point(first_date_x, table.y0),
fitz.Point(first_date_x, table.y1),
color=grid,
width=0.8,
)
for index, date_label in enumerate(dates):
x = first_date_x + index * date_width
if index:
page.draw_line(
fitz.Point(x, table.y0),
fitz.Point(x, table.y1),
color=grid,
width=0.6,
)
page.insert_text(
(x + 8, table.y0 + 18),
date_label,
fontname="hebo",
fontsize=9,
color=(1, 1, 1),
)
page.insert_text(
(x + 8, table.y0 + 32),
"7:00pm" if date_label.lower().startswith(("wed", "thu")) else "10:00am",
fontname="helv",
fontsize=8,
color=(1, 1, 1),
)
for role_index, (heading, assignment, volunteer) in enumerate(roles):
y0 = table.y0 + header_height + role_index * role_height
y1 = y0 + role_height
if role_index:
page.draw_line(
fitz.Point(table.x0, y0),
fitz.Point(table.x1, y0),
color=grid,
width=0.6,
)
page.draw_rect(
fitz.Rect(table.x0, y0, first_date_x, y1),
color=None,
fill=pale_blue,
width=0,
)
page.insert_text(
(table.x0 + 7, y0 + 15),
heading,
fontname="hebo",
fontsize=7.5,
color=navy,
)
page.insert_text(
(
table.x0 + 7,
min(y1 - 5, y0 + (31 if roster_type == "main" else 43)),
),
assignment,
fontname="helv",
fontsize=7.5,
color=(0.12, 0.12, 0.12),
)
for date_index in range(len(dates)):
x = first_date_x + date_index * date_width + 7
name = volunteer if date_index % 2 == 0 else f"{volunteer.split()[0]} Kim"
page.insert_text(
(
x,
y0
+ min(
27 if roster_type == "main" else 41,
role_height * 0.72,
),
),
name,
fontname="helv",
fontsize=7.5,
color=(0.08, 0.08, 0.08),
)
document.save(path)
document.close()
return path
def make_main_roster_pdf(
path: Path,
dates: Sequence[str] = ("Sun 6 Sep", "Sun 13 Sep", "Sun 20 Sep", "Sun 27 Sep"),
) -> Path:
"""Create a full roster with several broad ministry-role headings."""
return _make_subsplash_roster_pdf(path, "main", dates)
def make_nursery_only_roster_pdf(
path: Path,
dates: Sequence[str] = ("Wed 2 Sep", "Wed 9 Sep", "Wed 16 Sep", "Wed 23 Sep"),
) -> Path:
"""Create a roster whose only ministry role is Nursery Workers."""
return _make_subsplash_roster_pdf(path, "nursery_only", dates)