From 3eab672c6c0741afe22e8b17d3cb15e1722591c0 Mon Sep 17 00:00:00 2001 From: Media Date: Sat, 25 Jul 2026 15:13:23 -0500 Subject: [PATCH] V2: Added Webserver for faster formatting --- .dockerignore | 15 + .gitignore | 13 + Dockerfile | 29 + README.md | 118 ++ compose.yaml | 48 + input/original.pdf | Bin 105161 -> 157922 bytes main.py | 158 +-- .../__pycache__/adjust_layout.cpython-311.pyc | Bin 1315 -> 1310 bytes modules/adjust_layout.py | 13 +- output/.gitkeep | 1 + output/JULY 2025 Roster.png | Bin 176035 -> 0 bytes requirements.txt | 32 +- roster_formatter.py | 376 ++++++ server.py | 817 +++++++++++++ tests/__init__.py | 1 + tests/helpers.py | 38 + tests/test_formatter.py | 130 ++ tests/test_server.py | 406 +++++++ web/app.js | 372 ++++++ web/index.html | 209 ++++ web/styles.css | 1074 +++++++++++++++++ web/theme.js | 15 + 22 files changed, 3737 insertions(+), 128 deletions(-) create mode 100644 .dockerignore create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 README.md create mode 100644 compose.yaml create mode 100644 output/.gitkeep delete mode 100644 output/JULY 2025 Roster.png create mode 100644 roster_formatter.py create mode 100644 server.py create mode 100644 tests/__init__.py create mode 100644 tests/helpers.py create mode 100644 tests/test_formatter.py create mode 100644 tests/test_server.py create mode 100644 web/app.js create mode 100644 web/index.html create mode 100644 web/styles.css create mode 100644 web/theme.js diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..5852b6c --- /dev/null +++ b/.dockerignore @@ -0,0 +1,15 @@ +.agents +.codex +.git +.gitignore +Dockerfile +README.md +Roster2 +input +output +tests +venv +.venv +**/__pycache__ +**/*.py[cod] +.DS_Store diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1b26b41 --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +__pycache__/ +*.py[cod] +.venv/ +venv/ +.env +.DS_Store + +# Roster PDFs and generated images contain names and are local working data. +input/*.pdf +output/*.pdf +output/*.png +output/.roster-layout-defaults.json +output/.roster-defaults-*.json diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..8c1cee7 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,29 @@ +FROM python:3.11-slim-bookworm + +ENV PYTHONDONTWRITEBYTECODE=1 \ + PYTHONUNBUFFERED=1 \ + PIP_DISABLE_PIP_VERSION_CHECK=1 + +WORKDIR /app + +COPY requirements.txt ./ +RUN pip install --no-cache-dir --requirement requirements.txt + +ARG APP_UID=1000 +ARG APP_GID=1000 +RUN groupadd --gid "${APP_GID}" roster \ + && useradd --uid "${APP_UID}" --gid roster --create-home --shell /usr/sbin/nologin roster \ + && mkdir -p /app/output \ + && chown -R roster:roster /app + +COPY --chown=roster:roster main.py roster_formatter.py server.py ./ +COPY --chown=roster:roster modules/ ./modules/ +COPY --chown=roster:roster utils/ ./utils/ +COPY --chown=roster:roster assets/ ./assets/ +COPY --chown=roster:roster web/ ./web/ + +USER roster + +EXPOSE 8787 + +CMD ["python", "server.py", "--host", "0.0.0.0", "--port", "8787"] diff --git a/README.md b/README.md new file mode 100644 index 0000000..d17f288 --- /dev/null +++ b/README.md @@ -0,0 +1,118 @@ +# Roster Formatter + +A local browser app that turns the current one-page roster PDF into the established formatted PNG. The web app and command-line tool use the same renderer. + +## Start with Docker Compose + +From this folder: + +```bash +docker compose up -d --build +``` + +Open , upload the roster PDF, choose its month, and select **Format roster**. + +Common commands: + +```bash +docker compose restart # restart it later +docker compose logs -f app # watch logs +docker compose down # stop it +docker compose up -d --build # rebuild after code changes +``` + +The Compose service restarts automatically unless you explicitly stop it. Its direct browser port binds only to `127.0.0.1`. + +The service also joins the existing external `tabernet` Docker network, so Caddy can reach it at `roster-formatter:8787`. For a Caddy hostname, add that hostname to `.env`: + +```dotenv +ROSTER_ALLOWED_HOSTS=roster.example.com +``` + +Then a minimal Caddy route is: + +```caddyfile +roster.example.com { + reverse_proxy roster-formatter:8787 +} +``` + +The `tabernet` network must already exist. Because roster images contain personal information, add authentication in Caddy before exposing this service outside your private network. + +## Saved files and automatic cleanup + +Every successful PNG is returned to the browser with a **Download PNG** button and saved in [`output/`](output). The Compose container mounts that folder, so saved PNGs survive rebuilds and restarts. + +Layout defaults are persistent too. Change values under **Advanced adjustments**, then select **Save as defaults** to prefill them for future rosters. **Reset changes** restores the currently saved values, while **Use original values** loads the production geometry without saving it. The server stores these defaults in `output/.roster-layout-defaults.json`, inside the same mounted volume, and the roster cleanup never removes that settings file. + +On startup, every six hours, and after each successful format, the app removes only filenames matching its roster pattern, such as `MARCH 2026 Roster.png`, when either its roster month or saved-file age is outside the three-calendar-month window. The file-age check prevents an accidentally future-dated filename from bypassing cleanup. Other files are not removed. Cleanup is permanent. + +Change the retention window or browser port with a `.env` file beside `compose.yaml`: + +```dotenv +ROSTER_RETENTION_MONTHS=6 +ROSTER_PORT=8788 +TZ=America/Chicago +``` + +Set `ROSTER_RETENTION_MONTHS=0` to disable cleanup. + +The image runs as UID/GID `1000:1000`, matching this machine. On a host with a different checkout owner, set `ROSTER_UID` and `ROSTER_GID` in `.env`, then rebuild so the container can write to `output/`: + +```dotenv +ROSTER_UID=1001 +ROSTER_GID=1001 +``` + +## Layout guarantees + +With the advanced fields untouched, the renderer preserves the original production values: + +| Setting | Default | +| --- | ---: | +| Canvas | 792 × 612 PDF points | +| PNG export | 1650 × 1275 pixels at 150 DPI | +| Roster vertical shift | 100 | +| Bottom trim | 60 | +| Logo position | X 50, Y -10 | +| Logo scale | 0.27 | +| Date position | X 460, Y 88 | +| Date font size | 48 | + +The web page exposes the layout values in a collapsed **Advanced adjustments** section. Only an intentional field change—or explicitly saving that change as the new default—alters logo/date scale or placement. The canvas size and PNG DPI are not editable. The original production values remain available through **Use original values**. + +The page theme defaults to **System** and follows the browser/operating-system color preference. The **System / Light / Dark** control remembers the choice in that browser. Theme changes affect only the webpage and never the generated PNG. + +Input is deliberately limited to a one-page, unrotated, 11 × 8.5 inch landscape PDF. This prevents a differently sized upload from silently changing the established geometry. + +## Run without Docker + +The existing `venv` already contains the formatter dependencies. Start the web app with: + +```bash +venv/bin/python server.py +``` + +Or create a fresh environment: + +```bash +python3 -m venv .venv +.venv/bin/pip install -r requirements.txt +.venv/bin/python server.py +``` + +The original CLI workflow is still available and now accepts an explicit input path: + +```bash +venv/bin/python main.py --input input/original.pdf --month "July 2026" +``` + +## Tests + +Run the standard-library test suite with: + +```bash +PYTHONDONTWRITEBYTECODE=1 venv/bin/python -m unittest discover -v +``` + +Uploads and intermediate PDFs are created in isolated temporary directories and removed immediately after formatting. Only the final PNG is retained in `output/`. diff --git a/compose.yaml b/compose.yaml new file mode 100644 index 0000000..39dc84a --- /dev/null +++ b/compose.yaml @@ -0,0 +1,48 @@ +name: roster-formatter + +services: + app: + build: + context: . + args: + APP_UID: "${ROSTER_UID:-1000}" + APP_GID: "${ROSTER_GID:-1000}" + image: roster-formatter:local + container_name: roster-formatter + restart: unless-stopped + init: true + ports: + - "127.0.0.1:${ROSTER_PORT:-8787}:8787" + environment: + ROSTER_OUTPUT_DIR: /app/output + ROSTER_RETENTION_MONTHS: "${ROSTER_RETENTION_MONTHS:-3}" + ROSTER_MAX_UPLOAD_MB: "${ROSTER_MAX_UPLOAD_MB:-20}" + ROSTER_ALLOWED_HOSTS: "${ROSTER_ALLOWED_HOSTS:-}" + TZ: "${TZ:-America/Chicago}" + volumes: + - ./output:/app/output:rw + read_only: true + tmpfs: + - /tmp:size=256m,mode=1777 + cap_drop: + - ALL + security_opt: + - no-new-privileges:true + stop_grace_period: 10s + healthcheck: + test: + - CMD + - python + - -c + - "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8787/health', timeout=3).read()" + interval: 30s + timeout: 5s + retries: 3 + start_period: 10s + networks: + - tabernet + +networks: + tabernet: + external: true + name: tabernet diff --git a/input/original.pdf b/input/original.pdf index cb578b59c4b5bca70e97aa15afadd480b80881f4..7860879586af67750c98c8c593b42c3db5690bd7 100644 GIT binary patch literal 157922 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
MIUH55YttUhIZ__|z@)JEFY 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

mA|TwMq#A|O8&s(k`M572aZ!1)SQiva)G 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 B%{u@9 literal 105161 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 g76As^Aco%FpY^mo 1 else str(datetime.now().year) - - # Smart abbreviation - if len(full_month) > 5: - month = full_month[:3].upper() # "September" → "SEP" - else: - month = full_month.upper() # "June" → "JUNE" - - month_year = f"{month} {year}" -else: - today = datetime.now() - target = today if today.day < 15 else today + relativedelta(months=1) - full_month = target.strftime("%B") - year = target.strftime("%Y") - - if len(full_month) > 5: - month = target.strftime("%b").upper() - else: - month = full_month.upper() - - month_year = f"{month} {year}" - -final_pdf_name = f"{month} {year} Roster.pdf" -final_pdf_path = base / "output" / final_pdf_name -final_png_path = final_pdf_path.with_suffix(".png") -date_output = final_pdf_path - -# Paths -date_input = logo_output -font_file = base / "assets/fonts/Roboto-Variable.ttf" - -add_date( - input_path=date_input, - output_path=date_output, - month_year=month_year, - font_path=font_file, - position=(460, 88), - font_size=48 +from roster_formatter import ( + BASE_DIR, + LayoutSettings, + RosterFormatError, + RosterPeriod, + format_roster, ) -convert_pdf_to_png(final_pdf_path, final_png_path) -final_pdf_name = f"{month} {year} Roster.pdf" -final_pdf_path = base / "output" / final_pdf_name +def build_parser() -> argparse.ArgumentParser: + parser = argparse.ArgumentParser(description="Generate a formatted roster PNG") + parser.add_argument( + "--input", + type=Path, + default=BASE_DIR / "input" / "original.pdf", + help="one-page landscape Letter roster PDF", + ) + parser.add_argument( + "--output-dir", + type=Path, + default=BASE_DIR / "output", + help="directory for the formatted PNG", + ) + parser.add_argument( + "--month", + help="override the month/year label (for example, 'September 2026' or '2026-09')", + ) -final_png_name = final_pdf_name.replace(".pdf", ".png") -final_png_path = base / "output" / final_png_name + advanced = parser.add_argument_group("advanced layout adjustments") + advanced.add_argument("--content-shift", type=float, default=100) + advanced.add_argument("--bottom-margin", type=float, default=60) + advanced.add_argument("--logo-x", type=float, default=50) + advanced.add_argument("--logo-y", type=float, default=-10) + advanced.add_argument("--logo-scale", type=float, default=0.27) + advanced.add_argument("--date-x", type=float, default=460) + advanced.add_argument("--date-y", type=float, default=88) + advanced.add_argument("--date-font-size", type=int, default=48) + return parser -# Clean up intermediate PDFs -for path in [shifted_pdf, logo_output, final_pdf_path]: - if path.exists(): - path.unlink() \ No newline at end of file +def main() -> int: + args = build_parser().parse_args() + try: + period = RosterPeriod.parse(args.month) + settings = LayoutSettings( + content_shift=args.content_shift, + bottom_margin=args.bottom_margin, + logo_x=args.logo_x, + logo_y=args.logo_y, + logo_scale=args.logo_scale, + date_x=args.date_x, + date_y=args.date_y, + date_font_size=args.date_font_size, + ) + output_path = args.output_dir / period.output_filename + result = format_roster(args.input, output_path, period, settings) + except RosterFormatError as exc: + raise SystemExit(f"error: {exc}") from exc + + print(f"Created {result.path}") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/modules/__pycache__/adjust_layout.cpython-311.pyc b/modules/__pycache__/adjust_layout.cpython-311.pyc index 0d1b6b7095faf0eeb7808e4ee4204e14121476c8..3be2b01f9f6b9f86b590b26bf63dd16bdb0243ee 100644 GIT binary patch delta 489 zcmZ3?HIIvTIWI340}!0}o|3hHBClka3Xn6MA%!7@F^3_FA%!W5F@-sbDTO79Ih8q$ zF@?2-F^VOHF_=MWN%}uEb}JyjFNw+1nGG2qPCm)3!Y06K|A9eZ@@HmO?HfG2H+Up&@CfvH zfe7yzIv07=R>)rDG5g5LD#7)I0Z4T4eBfi?6r3EzlE8n9*U3L5#NRjG*D=W5({J*A i78x!DpjC`OTx>V_DT{*I1NV>*3=)h2IEf-zpke@YU~QQI delta 561 zcmbQowU~={IWI340}!0}ZIWR6=@KC*7f4kBy||2pfnhZeLqIKO4aWko$6+Ecx`wlc8R$4}7=Ibi6RY7K zV`S)=0(2)2NOtm1MrCG}1-z5xnN*pX!L-WcY$iEIzR6uo-n>r!AtC<0@xG2h?w)>= zFEgn!a!vlpq%qlm*-RT`vjQCaGS<(?&rQ|OO-;#6)DKQB$}A`;)(^@rE=euYpIpvt z$arJ&N@f){ZdUsb4BV41GrKA+5M1E1L1l~9j+8ywCwwm2MO=-}xM-JgQ9SdCcxDIB z0}g@7&MXPqMSMVuie!MqN`@j?5L+5Z{Nk|5%}*)KNwq7I2XYyKxY%s+4HgBt4=lor L0v{MK39x1WhhcDl diff --git a/modules/adjust_layout.py b/modules/adjust_layout.py index 7a6519a..ca3b8f7 100644 --- a/modules/adjust_layout.py +++ b/modules/adjust_layout.py @@ -1,10 +1,10 @@ import fitz # PyMuPDF -LETTER_WIDTH = 792 # 8.5 inches -LETTER_HEIGHT = 612 # 11 inches +LETTER_WIDTH = 792 # 11 inches at 72 points per inch +LETTER_HEIGHT = 612 # 8.5 inches at 72 points per inch BOTTOM_MARGIN = 60 -def adjust_layout(input_path, output_path, shift_amount): +def adjust_layout(input_path, output_path, shift_amount, bottom_margin=BOTTOM_MARGIN): doc = fitz.open(input_path) new_doc = fitz.open() @@ -17,7 +17,12 @@ def adjust_layout(input_path, output_path, shift_amount): # Shift original content down by shift_amount # Clip it back to fit on a Letter-sized page - content_rect = fitz.Rect(0, shift_amount, rect.width, rect.height + shift_amount - BOTTOM_MARGIN) + content_rect = fitz.Rect( + 0, + shift_amount, + rect.width, + rect.height + shift_amount - bottom_margin, + ) new_page.show_pdf_page(content_rect, doc, page.number) diff --git a/output/.gitkeep b/output/.gitkeep new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/output/.gitkeep @@ -0,0 +1 @@ + diff --git a/output/JULY 2025 Roster.png b/output/JULY 2025 Roster.png deleted file mode 100644 index 0142b2ccfaa240ba73839e1b4591205875490b3b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 176035 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ï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 HuTy^jyo(}8 diff --git a/requirements.txt b/requirements.txt index e68f823..883dedb 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,30 +1,2 @@ -Brotli==1.0.9 -certifi==2022.9.24 -chardet==5.1.0 -charset-normalizer==3.0.1 -dbus-python==1.3.2 -httplib2==0.20.4 -idna==3.3 -Mako==1.2.4.dev0 -Markdown==3.4.1 -MarkupSafe==2.1.2 -meson==1.0.1 -mutagen==1.46.0 -pycairo==1.20.1 -pycryptodomex==3.11.0 -pycurl==7.45.2 -Pygments==2.14.0 -PyGObject==3.42.2 -pyparsing==3.0.9 -PySimpleSOAP==1.16.2 -python-apt==2.6.0 -python-debian==0.1.49 -python-debianbts==4.0.1 -pyxattr==0.8.1 -PyYAML==6.0 -reportbug==12.0.0 -requests==2.28.1 -six==1.16.0 -urllib3==1.26.12 -websockets==10.4 -yt-dlp==2023.3.4 +Pillow==11.2.1 +PyMuPDF==1.26.0 diff --git a/roster_formatter.py b/roster_formatter.py new file mode 100644 index 0000000..4c9afbe --- /dev/null +++ b/roster_formatter.py @@ -0,0 +1,376 @@ +"""Shared PDF-to-PNG roster formatter. + +The defaults in :class:`LayoutSettings` are the original production geometry. +Both the CLI and web server call this module so the browser workflow cannot +silently introduce a second rendering path. +""" + +from __future__ import annotations + +from calendar import month_name +from dataclasses import dataclass, fields +from datetime import date, datetime +from math import isfinite +from os import PathLike, fsync, replace +from pathlib import Path +import re +from shutil import copyfileobj +from tempfile import NamedTemporaryFile, TemporaryDirectory +from typing import Mapping + +import fitz # type: ignore + +from modules.add_date import add_date +from modules.add_logo import add_logo +from modules.adjust_layout import adjust_layout + + +BASE_DIR = Path(__file__).resolve().parent +LOGO_PATH = BASE_DIR / "assets" / "logo.png" +FONT_PATH = BASE_DIR / "assets" / "fonts" / "Roboto-Variable.ttf" + +# Fixed export geometry. These are intentionally not web-editable. +PAGE_WIDTH = 792 +PAGE_HEIGHT = 612 +PNG_DPI = 150 +PNG_WIDTH = 1650 +PNG_HEIGHT = 1275 + +_MONTH_ALIASES = { + alias.lower(): number + for number in range(1, 13) + for alias in (month_name[number], month_name[number][:3]) +} +_MONTH_ALIASES["sept"] = 9 +_HUMAN_PERIOD_RE = re.compile(r"^([A-Za-z]+)(?:\s+([0-9]{4}))?$") +_ISO_PERIOD_RE = re.compile(r"^([0-9]{4})-([0-9]{2})$") +_OUTPUT_NAME_RE = re.compile( + r"^(JAN|FEB|MARCH|APRIL|MAY|JUNE|JULY|AUG|SEP|OCT|NOV|DEC) " + r"([0-9]{4}) Roster\.png$" +) +_OUTPUT_LABEL_TO_MONTH = { + "JAN": 1, + "FEB": 2, + "MARCH": 3, + "APRIL": 4, + "MAY": 5, + "JUNE": 6, + "JULY": 7, + "AUG": 8, + "SEP": 9, + "OCT": 10, + "NOV": 11, + "DEC": 12, +} + + +class RosterFormatError(ValueError): + """A safe, user-facing roster formatting error.""" + + +@dataclass(frozen=True, order=True) +class RosterPeriod: + """The month represented by a formatted roster.""" + + year: int + month: int + + def __post_init__(self) -> None: + if not 1 <= self.month <= 12: + raise RosterFormatError("The roster month must be between 1 and 12.") + if not 1900 <= self.year <= 9999: + raise RosterFormatError("The roster year must contain four digits.") + + @property + def month_token(self) -> str: + full_month = month_name[self.month].upper() + return full_month[:3] if len(full_month) > 5 else full_month + + @property + def label(self) -> str: + return f"{self.month_token} {self.year}" + + @property + def html_value(self) -> str: + return f"{self.year:04d}-{self.month:02d}" + + @property + def output_filename(self) -> str: + return f"{self.label} Roster.png" + + @classmethod + def suggested(cls, today: date | datetime | None = None) -> "RosterPeriod": + current = (today or date.today()).date() if isinstance(today, datetime) else (today or date.today()) + year = current.year + month = current.month + if current.day >= 15: + month += 1 + if month == 13: + month = 1 + year += 1 + return cls(year=year, month=month) + + @classmethod + def parse( + cls, + value: str | None, + today: date | datetime | None = None, + ) -> "RosterPeriod": + if value is None or not value.strip(): + return cls.suggested(today) + + cleaned = value.strip() + iso_match = _ISO_PERIOD_RE.fullmatch(cleaned) + if iso_match: + return cls(year=int(iso_match.group(1)), month=int(iso_match.group(2))) + + human_match = _HUMAN_PERIOD_RE.fullmatch(cleaned) + if not human_match: + raise RosterFormatError( + "Use a month and four-digit year, such as July 2026." + ) + + month = _MONTH_ALIASES.get(human_match.group(1).lower()) + if month is None: + raise RosterFormatError(f"Unknown month: {human_match.group(1)}.") + + current = (today or date.today()).date() if isinstance(today, datetime) else (today or date.today()) + year = int(human_match.group(2)) if human_match.group(2) else current.year + return cls(year=year, month=month) + + @classmethod + def from_output_filename(cls, filename: str) -> "RosterPeriod | None": + match = _OUTPUT_NAME_RE.fullmatch(filename) + if not match: + return None + return cls(year=int(match.group(2)), month=_OUTPUT_LABEL_TO_MONTH[match.group(1)]) + + +@dataclass(frozen=True) +class LayoutSettings: + """User-adjustable layout values, with the legacy values as defaults.""" + + content_shift: float = 100 + bottom_margin: float = 60 + logo_x: float = 50 + logo_y: float = -10 + logo_scale: float = 0.27 + date_x: float = 460 + date_y: float = 88 + date_font_size: int = 48 + + def __post_init__(self) -> None: + limits = { + "content_shift": (-300, 500), + "bottom_margin": (0, 500), + "logo_x": (-1000, 2000), + "logo_y": (-1000, 2000), + "logo_scale": (0.01, 2), + "date_x": (-1000, 2000), + "date_y": (-1000, 2000), + } + for name, (minimum, maximum) in limits.items(): + value = getattr(self, name) + if not isinstance(value, (int, float)) or not isfinite(value): + raise RosterFormatError(f"{name.replace('_', ' ').title()} must be a number.") + if not minimum <= value <= maximum: + raise RosterFormatError( + f"{name.replace('_', ' ').title()} must be between {minimum} and {maximum}." + ) + + if self.bottom_margin >= PAGE_HEIGHT: + raise RosterFormatError("Bottom margin must be smaller than the page height.") + if isinstance(self.date_font_size, bool) or not isinstance(self.date_font_size, int): + raise RosterFormatError("Date font size must be a whole number.") + if not 8 <= self.date_font_size <= 200: + raise RosterFormatError("Date font size must be between 8 and 200.") + + @classmethod + def from_mapping( + cls, + values: Mapping[str, str], + defaults: "LayoutSettings | None" = None, + ) -> "LayoutSettings": + fallback = defaults or cls() + + def parse_float(name: str) -> float: + raw = values.get(name) + if raw is None or not raw.strip(): + return float(getattr(fallback, name)) + try: + return float(raw) + except ValueError as exc: + raise RosterFormatError( + f"{name.replace('_', ' ').title()} must be a number." + ) from exc + + raw_font_size = values.get("date_font_size") + if raw_font_size is None or not raw_font_size.strip(): + font_size = fallback.date_font_size + else: + try: + font_size = int(raw_font_size) + except ValueError as exc: + raise RosterFormatError("Date font size must be a whole number.") from exc + + return cls( + content_shift=parse_float("content_shift"), + bottom_margin=parse_float("bottom_margin"), + logo_x=parse_float("logo_x"), + logo_y=parse_float("logo_y"), + logo_scale=parse_float("logo_scale"), + date_x=parse_float("date_x"), + date_y=parse_float("date_y"), + date_font_size=font_size, + ) + + def as_form_values(self) -> dict[str, str]: + return {field.name: str(getattr(self, field.name)) for field in fields(self)} + + def as_json_values(self) -> dict[str, float | int]: + return {field.name: getattr(self, field.name) for field in fields(self)} + + +DEFAULT_LAYOUT = LayoutSettings() + + +@dataclass(frozen=True) +class FormatResult: + path: Path + period: RosterPeriod + + @property + def filename(self) -> str: + return self.period.output_filename + + +def validate_input_pdf(input_path: str | PathLike[str]) -> None: + """Reject inputs whose geometry would make the established layout drift.""" + + path = Path(input_path) + try: + with path.open("rb") as source: + header = source.read(1024) + except OSError as exc: + raise RosterFormatError("The uploaded PDF could not be read.") from exc + + if b"%PDF-" not in header: + raise RosterFormatError("The uploaded file is not a PDF.") + + try: + doc = fitz.open(path) + try: + if doc.needs_pass: + raise RosterFormatError("Password-protected PDFs are not supported.") + if doc.page_count != 1: + raise RosterFormatError("Upload a one-page roster PDF.") + + page = doc.load_page(0) + if page.rotation != 0: + raise RosterFormatError("The roster PDF must not have page rotation metadata.") + if ( + abs(page.rect.width - PAGE_WIDTH) > 0.5 + or abs(page.rect.height - PAGE_HEIGHT) > 0.5 + ): + raise RosterFormatError( + "The roster must be an 11 × 8.5 inch landscape PDF (792 × 612 points)." + ) + finally: + doc.close() + except RosterFormatError: + raise + except Exception as exc: + raise RosterFormatError("The uploaded PDF is damaged or unsupported.") from exc + + +def convert_pdf_to_png( + pdf_path: str | PathLike[str], + output_path: str | PathLike[str], + dpi: int = PNG_DPI, +) -> None: + """Rasterize page one exactly as the original formatter did.""" + + doc = fitz.open(pdf_path) + try: + page = doc.load_page(0) + pix = page.get_pixmap(dpi=dpi) + pix.save(output_path) + finally: + doc.close() + + +def format_roster( + input_pdf: str | PathLike[str], + output_png: str | PathLike[str], + period: RosterPeriod | str | None = None, + settings: LayoutSettings = DEFAULT_LAYOUT, +) -> FormatResult: + """Format one roster using isolated intermediate files and an atomic output.""" + + selected_period = period if isinstance(period, RosterPeriod) else RosterPeriod.parse(period) + input_path = Path(input_pdf) + output_path = Path(output_png) + + validate_input_pdf(input_path) + output_path.parent.mkdir(parents=True, exist_ok=True) + + with TemporaryDirectory(prefix="roster-format-") as temp_dir: + work_dir = Path(temp_dir) + shifted_pdf = work_dir / "shifted.pdf" + logo_pdf = work_dir / "with_logo.pdf" + final_pdf = work_dir / "final.pdf" + staged_png = work_dir / "formatted.png" + + try: + adjust_layout( + input_path, + shifted_pdf, + shift_amount=settings.content_shift, + bottom_margin=settings.bottom_margin, + ) + add_logo( + shifted_pdf, + logo_pdf, + LOGO_PATH, + position=(settings.logo_x, settings.logo_y), + scale=settings.logo_scale, + ) + add_date( + input_path=logo_pdf, + output_path=final_pdf, + month_year=selected_period.label, + font_path=FONT_PATH, + position=(settings.date_x, settings.date_y), + font_size=settings.date_font_size, + ) + convert_pdf_to_png(final_pdf, staged_png) + + # Only the completed PNG crosses into the destination filesystem. + # This keeps working PDFs in /tmp while preserving an atomic replace + # even when /tmp and output_path are different mounts. + destination_temp: Path | None = None + try: + with staged_png.open("rb") as source, NamedTemporaryFile( + mode="wb", + prefix=".roster-output-", + suffix=".png", + dir=output_path.parent, + delete=False, + ) as destination: + destination_temp = Path(destination.name) + copyfileobj(source, destination) + destination.flush() + fsync(destination.fileno()) + replace(destination_temp, output_path) + destination_temp = None + finally: + if destination_temp is not None: + destination_temp.unlink(missing_ok=True) + except RosterFormatError: + raise + except Exception as exc: + raise RosterFormatError( + "The roster could not be formatted. Check that the PDF is valid and try again." + ) from exc + + return FormatResult(path=output_path, period=selected_period) diff --git a/server.py b/server.py new file mode 100644 index 0000000..7a6cdf4 --- /dev/null +++ b/server.py @@ -0,0 +1,817 @@ +"""Small, dependency-free local web server for the roster formatter.""" + +from __future__ import annotations + +import argparse +from dataclasses import dataclass +from datetime import date, datetime, timezone +from email import policy +from email.parser import BytesParser +from http import HTTPStatus +from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer +import json +import logging +import os +from pathlib import Path +import stat as stat_module +from tempfile import NamedTemporaryFile, TemporaryDirectory +from threading import Event, Lock, Thread +from typing import Mapping +from urllib.parse import quote, unquote, urlsplit + +from roster_formatter import ( + BASE_DIR, + DEFAULT_LAYOUT, + LayoutSettings, + RosterFormatError, + RosterPeriod, + format_roster, +) + + +LOGGER = logging.getLogger("roster.web") +DEFAULT_HOST = "127.0.0.1" +DEFAULT_PORT = 8787 +DEFAULT_RETENTION_MONTHS = 3 +DEFAULT_MAX_UPLOAD_MB = 20 +RETENTION_CHECK_SECONDS = 6 * 60 * 60 +DEFAULT_ALLOWED_HOSTS = frozenset({"127.0.0.1", "localhost", "::1", "0.0.0.0"}) +LAYOUT_DEFAULTS_FILENAME = ".roster-layout-defaults.json" +MAX_DEFAULTS_REQUEST_BYTES = 16 * 1024 + + +class RequestError(ValueError): + def __init__(self, status: HTTPStatus, message: str) -> None: + super().__init__(message) + self.status = status + self.message = message + + +@dataclass(frozen=True) +class UploadedFile: + filename: str + content_type: str + data: bytes + + +class OutputStore: + """Atomic persistent PNG storage with filename-based calendar retention.""" + + def __init__(self, root: Path, retention_months: int = DEFAULT_RETENTION_MONTHS) -> None: + if retention_months < 0: + raise ValueError("retention_months cannot be negative") + self.root = root.resolve() + self.retention_months = retention_months + self._lock = Lock() + self.root.mkdir(parents=True, exist_ok=True) + + @property + def layout_defaults_path(self) -> Path: + return self.root / LAYOUT_DEFAULTS_FILENAME + + @staticmethod + def _read_regular_file(path: Path, max_bytes: int | None = None) -> bytes | None: + try: + path_stat = path.stat(follow_symlinks=False) + except OSError: + return None + if not stat_module.S_ISREG(path_stat.st_mode): + return None + if max_bytes is not None and path_stat.st_size > max_bytes: + return None + + flags = os.O_RDONLY | getattr(os, "O_CLOEXEC", 0) | getattr(os, "O_NOFOLLOW", 0) + try: + descriptor = os.open(path, flags) + except OSError: + return None + try: + opened_stat = os.fstat(descriptor) + if not stat_module.S_ISREG(opened_stat.st_mode): + return None + if max_bytes is not None and opened_stat.st_size > max_bytes: + return None + source = os.fdopen(descriptor, "rb") + descriptor = -1 + with source: + return source.read() + finally: + if descriptor >= 0: + os.close(descriptor) + + def load_layout_defaults(self) -> LayoutSettings: + with self._lock: + raw = self._read_regular_file( + self.layout_defaults_path, + max_bytes=MAX_DEFAULTS_REQUEST_BYTES, + ) + if raw is None: + return DEFAULT_LAYOUT + + try: + payload = json.loads(raw.decode("utf-8")) + if not isinstance(payload, dict) or payload.get("version") != 1: + raise ValueError("unsupported settings format") + layout = payload.get("layout") + expected = set(DEFAULT_LAYOUT.as_form_values()) + if not isinstance(layout, dict) or set(layout) != expected: + raise ValueError("settings fields do not match") + values = {name: str(value) for name, value in layout.items()} + return LayoutSettings.from_mapping(values) + except (UnicodeDecodeError, json.JSONDecodeError, ValueError, TypeError) as exc: + LOGGER.warning("Ignoring invalid saved layout defaults: %s", exc) + return DEFAULT_LAYOUT + + def save_layout_defaults(self, settings: LayoutSettings) -> None: + data = ( + json.dumps( + {"version": 1, "layout": settings.as_json_values()}, + indent=2, + sort_keys=True, + ) + + "\n" + ).encode("utf-8") + + with self._lock: + temporary_path: Path | None = None + try: + with NamedTemporaryFile( + mode="wb", + prefix=".roster-defaults-", + suffix=".json", + dir=self.root, + delete=False, + ) as temporary: + temporary.write(data) + temporary.flush() + os.fsync(temporary.fileno()) + temporary_path = Path(temporary.name) + os.replace(temporary_path, self.layout_defaults_path) + temporary_path = None + finally: + if temporary_path is not None: + temporary_path.unlink(missing_ok=True) + + @staticmethod + def _cutoff(today: date | datetime, months: int) -> RosterPeriod: + current = today.date() if isinstance(today, datetime) else today + month_index = current.year * 12 + current.month - 1 - months + return RosterPeriod(year=month_index // 12, month=month_index % 12 + 1) + + def _prune_locked(self, today: date | datetime) -> list[str]: + if self.retention_months == 0: + return [] + + cutoff = self._cutoff(today, self.retention_months) + cutoff_date = date(cutoff.year, cutoff.month, 1) + removed: list[str] = [] + for path in self.root.iterdir(): + try: + path_stat = path.stat(follow_symlinks=False) + except OSError: + continue + if not stat_module.S_ISREG(path_stat.st_mode): + continue + period = RosterPeriod.from_output_filename(path.name) + modified_date = datetime.fromtimestamp(path_stat.st_mtime).date() + if period is None or (period >= cutoff and modified_date >= cutoff_date): + continue + path.unlink() + removed.append(path.name) + return sorted(removed) + + def prune(self, today: date | datetime | None = None) -> list[str]: + with self._lock: + return self._prune_locked(today or date.today()) + + def save( + self, + filename: str, + data: bytes, + today: date | datetime | None = None, + ) -> tuple[Path, list[str], bool]: + if RosterPeriod.from_output_filename(filename) is None: + raise ValueError("Refusing to store an unexpected roster filename") + + with self._lock: + temporary_path: Path | None = None + try: + with NamedTemporaryFile( + mode="wb", + prefix=".roster-", + suffix=".tmp", + dir=self.root, + delete=False, + ) as temporary: + temporary.write(data) + temporary.flush() + os.fsync(temporary.fileno()) + temporary_path = Path(temporary.name) + + final_path = self.root / filename + os.replace(temporary_path, final_path) + temporary_path = None + removed = self._prune_locked(today or date.today()) + return final_path, removed, final_path.exists() + finally: + if temporary_path is not None: + temporary_path.unlink(missing_ok=True) + + def list_items(self) -> list[dict[str, object]]: + with self._lock: + items: list[tuple[RosterPeriod, dict[str, object]]] = [] + for path in self.root.iterdir(): + try: + path_stat = path.stat(follow_symlinks=False) + except OSError: + continue + if not stat_module.S_ISREG(path_stat.st_mode): + continue + period = RosterPeriod.from_output_filename(path.name) + if period is None: + continue + items.append( + ( + period, + { + "filename": path.name, + "label": period.label, + "url": f"/downloads/{quote(path.name)}", + "size": path_stat.st_size, + "modified": datetime.fromtimestamp( + path_stat.st_mtime, + tz=timezone.utc, + ).isoformat(), + }, + ) + ) + items.sort(key=lambda item: item[0], reverse=True) + return [item for _, item in items] + + def verify_writable(self) -> None: + """Exercise both file creation and deletion for the health check.""" + + with self._lock: + with NamedTemporaryFile( + mode="wb", + prefix=".roster-health-", + suffix=".tmp", + dir=self.root, + ) as probe: + probe.write(b"ok") + probe.flush() + + def read(self, filename: str) -> bytes | None: + if RosterPeriod.from_output_filename(filename) is None: + return None + with self._lock: + return self._read_regular_file(self.root / filename) + + +class RosterWebApp: + def __init__( + self, + output_dir: Path, + retention_months: int = DEFAULT_RETENTION_MONTHS, + max_upload_bytes: int = DEFAULT_MAX_UPLOAD_MB * 1024 * 1024, + allowed_hosts: set[str] | None = None, + ) -> None: + self.web_dir = BASE_DIR / "web" + self.logo_path = BASE_DIR / "assets" / "logo.png" + self.store = OutputStore(output_dir, retention_months) + self.max_upload_bytes = max_upload_bytes + self.max_request_bytes = max_upload_bytes + 1024 * 1024 + self.allowed_hosts = DEFAULT_ALLOWED_HOSTS | frozenset( + host.lower().rstrip(".") for host in (allowed_hosts or set()) + ) + # PyMuPDF does not support concurrent rendering in multiple threads. + self._format_lock = Lock() + + def index_html(self) -> bytes: + template = (self.web_dir / "index.html").read_text(encoding="utf-8") + saved_layout = self.store.load_layout_defaults() + replacements = { + "__DEFAULT_MONTH__": RosterPeriod.suggested().html_value, + "__RETENTION_MONTHS__": str(self.store.retention_months), + "__MAX_UPLOAD_MB__": str(self.max_upload_bytes // (1024 * 1024)), + "__CONTENT_SHIFT__": str(saved_layout.content_shift), + "__BOTTOM_MARGIN__": str(saved_layout.bottom_margin), + "__LOGO_X__": str(saved_layout.logo_x), + "__LOGO_Y__": str(saved_layout.logo_y), + "__LOGO_SCALE__": str(saved_layout.logo_scale), + "__DATE_X__": str(saved_layout.date_x), + "__DATE_Y__": str(saved_layout.date_y), + "__DATE_FONT_SIZE__": str(saved_layout.date_font_size), + "__FACTORY_CONTENT_SHIFT__": str(DEFAULT_LAYOUT.content_shift), + "__FACTORY_BOTTOM_MARGIN__": str(DEFAULT_LAYOUT.bottom_margin), + "__FACTORY_LOGO_X__": str(DEFAULT_LAYOUT.logo_x), + "__FACTORY_LOGO_Y__": str(DEFAULT_LAYOUT.logo_y), + "__FACTORY_LOGO_SCALE__": str(DEFAULT_LAYOUT.logo_scale), + "__FACTORY_DATE_X__": str(DEFAULT_LAYOUT.date_x), + "__FACTORY_DATE_Y__": str(DEFAULT_LAYOUT.date_y), + "__FACTORY_DATE_FONT_SIZE__": str(DEFAULT_LAYOUT.date_font_size), + } + rendered = template + for placeholder, value in replacements.items(): + rendered = rendered.replace(placeholder, value) + return rendered.encode("utf-8") + + def format_upload( + self, + upload: UploadedFile, + values: Mapping[str, str], + ) -> tuple[bytes, str, bool, list[str]]: + if not upload.filename: + raise RosterFormatError("Choose a roster PDF to upload.") + if Path(upload.filename).suffix.lower() != ".pdf": + raise RosterFormatError("Choose a file whose name ends in .pdf.") + if not upload.data: + raise RosterFormatError("The uploaded PDF is empty.") + if len(upload.data) > self.max_upload_bytes: + maximum = self.max_upload_bytes // (1024 * 1024) + raise RequestError( + HTTPStatus.REQUEST_ENTITY_TOO_LARGE, + f"The PDF must be {maximum} MB or smaller.", + ) + + period = RosterPeriod.parse(values.get("month")) + settings = LayoutSettings.from_mapping( + values, + defaults=self.store.load_layout_defaults(), + ) + + with self._format_lock: + with TemporaryDirectory(prefix="roster-web-") as temp_dir: + work_dir = Path(temp_dir) + input_path = work_dir / "upload.pdf" + output_path = work_dir / period.output_filename + input_path.write_bytes(upload.data) + format_roster(input_path, output_path, period, settings) + png = output_path.read_bytes() + + _, removed, saved = self.store.save(period.output_filename, png) + return png, period.output_filename, saved, removed + + def save_layout_defaults(self, values: Mapping[str, str]) -> LayoutSettings: + expected = set(DEFAULT_LAYOUT.as_form_values()) + if set(values) != expected: + raise RosterFormatError("Submit every layout setting before saving defaults.") + if any(not values[name].strip() for name in expected): + raise RosterFormatError("Layout defaults cannot contain blank values.") + settings = LayoutSettings.from_mapping(values) + self.store.save_layout_defaults(settings) + return settings + + +def parse_multipart(content_type: str, body: bytes) -> tuple[dict[str, str], UploadedFile]: + if "\r" in content_type or "\n" in content_type: + raise RequestError(HTTPStatus.BAD_REQUEST, "Invalid upload content type.") + + try: + header = ( + f"Content-Type: {content_type}\r\nMIME-Version: 1.0\r\n\r\n" + ).encode("ascii", errors="strict") + except UnicodeEncodeError as exc: + raise RequestError(HTTPStatus.BAD_REQUEST, "Invalid upload content type.") from exc + message = BytesParser(policy=policy.default).parsebytes(header + body) + if not message.is_multipart(): + raise RequestError( + HTTPStatus.BAD_REQUEST, + "The upload must use multipart form data.", + ) + + values: dict[str, str] = {} + uploads: list[UploadedFile] = [] + for part in message.iter_parts(): + if part.get_content_disposition() != "form-data": + continue + name = part.get_param("name", header="content-disposition") + if not name: + continue + + payload = part.get_payload(decode=True) + if payload is None: + payload = b"" + filename = part.get_filename() + if filename is not None: + if name == "roster": + uploads.append( + UploadedFile( + filename=filename, + content_type=part.get_content_type(), + data=payload, + ) + ) + continue + + if len(payload) > 4096: + raise RequestError(HTTPStatus.BAD_REQUEST, "A form value is too long.") + charset = part.get_content_charset() or "utf-8" + try: + values[name] = payload.decode(charset) + except (LookupError, UnicodeDecodeError) as exc: + raise RequestError(HTTPStatus.BAD_REQUEST, "Invalid form text encoding.") from exc + + if len(uploads) != 1: + raise RequestError( + HTTPStatus.BAD_REQUEST, + "Upload exactly one roster PDF.", + ) + return values, uploads[0] + + +class RosterHTTPServer(ThreadingHTTPServer): + allow_reuse_address = True + daemon_threads = True + + def __init__(self, address: tuple[str, int], app: RosterWebApp) -> None: + self.web_app = app + super().__init__(address, RosterRequestHandler) + + +class RosterRequestHandler(BaseHTTPRequestHandler): + protocol_version = "HTTP/1.1" + server_version = "RosterServer/1.0" + sys_version = "" + + @property + def app(self) -> RosterWebApp: + return self.server.web_app # type: ignore[attr-defined] + + def setup(self) -> None: + super().setup() + self.connection.settimeout(30) + + def end_headers(self) -> None: + self.send_header("X-Content-Type-Options", "nosniff") + self.send_header("X-Frame-Options", "DENY") + self.send_header("Referrer-Policy", "no-referrer") + self.send_header( + "Content-Security-Policy", + "default-src 'self'; script-src 'self'; style-src 'self'; " + "img-src 'self' blob:; connect-src 'self'; base-uri 'none'; " + "form-action 'self'; frame-ancestors 'none'", + ) + super().end_headers() + + def _send_bytes( + self, + status: HTTPStatus, + data: bytes, + content_type: str, + headers: Mapping[str, str] | None = None, + ) -> None: + self.send_response(status) + self.send_header("Content-Type", content_type) + self.send_header("Content-Length", str(len(data))) + if self.close_connection: + self.send_header("Connection", "close") + if headers: + for name, value in headers.items(): + self.send_header(name, value) + self.end_headers() + if self.command != "HEAD": + self.wfile.write(data) + + def _send_json(self, status: HTTPStatus, payload: Mapping[str, object]) -> None: + data = json.dumps(payload, separators=(",", ":")).encode("utf-8") + self._send_bytes( + status, + data, + "application/json; charset=utf-8", + {"Cache-Control": "no-store"}, + ) + + def _same_origin(self) -> bool: + origin = self.headers.get("Origin") + if not origin: + return True + try: + parsed = urlsplit(origin) + except ValueError: + return False + return ( + parsed.scheme in {"http", "https"} + and parsed.netloc.lower() == self.headers.get("Host", "").lower() + ) + + def _host_allowed(self) -> bool: + raw_host = self.headers.get("Host", "") + if not raw_host or any(character in raw_host for character in ("@", "/", "\\", " ", "\t")): + return False + try: + parsed = urlsplit(f"//{raw_host}") + host = parsed.hostname + parsed.port # Force validation of a supplied port. + except ValueError: + return False + return bool(host and host.lower().rstrip(".") in self.app.allowed_hosts) + + def do_GET(self) -> None: # noqa: N802 - BaseHTTPRequestHandler API + path = urlsplit(self.path).path + try: + if not self._host_allowed(): + self._send_json(HTTPStatus.FORBIDDEN, {"error": "Host is not allowed."}) + return + if path == "/": + self._send_bytes( + HTTPStatus.OK, + self.app.index_html(), + "text/html; charset=utf-8", + {"Cache-Control": "no-store"}, + ) + return + if path == "/static/styles.css": + self._send_bytes( + HTTPStatus.OK, + (self.app.web_dir / "styles.css").read_bytes(), + "text/css; charset=utf-8", + {"Cache-Control": "no-store"}, + ) + return + if path == "/static/app.js": + self._send_bytes( + HTTPStatus.OK, + (self.app.web_dir / "app.js").read_bytes(), + "text/javascript; charset=utf-8", + {"Cache-Control": "no-store"}, + ) + return + if path == "/static/theme.js": + self._send_bytes( + HTTPStatus.OK, + (self.app.web_dir / "theme.js").read_bytes(), + "text/javascript; charset=utf-8", + {"Cache-Control": "no-store"}, + ) + return + if path == "/assets/logo.png": + self._send_bytes( + HTTPStatus.OK, + self.app.logo_path.read_bytes(), + "image/png", + {"Cache-Control": "no-store"}, + ) + return + if path == "/health": + try: + self.app.store.verify_writable() + except OSError: + self._send_json( + HTTPStatus.SERVICE_UNAVAILABLE, + {"status": "error", "error": "Output directory is not writable."}, + ) + return + self._send_json(HTTPStatus.OK, {"status": "ok"}) + return + if path == "/api/history": + self._send_json( + HTTPStatus.OK, + { + "items": self.app.store.list_items(), + "retention_months": self.app.store.retention_months, + }, + ) + return + if path.startswith("/downloads/"): + filename = unquote(path.removeprefix("/downloads/")) + data = self.app.store.read(filename) + if data is None: + self._send_json(HTTPStatus.NOT_FOUND, {"error": "Roster not found."}) + return + self._send_bytes( + HTTPStatus.OK, + data, + "image/png", + { + "Content-Disposition": f'attachment; filename="{filename}"', + "Cache-Control": "no-store", + }, + ) + return + + self._send_json(HTTPStatus.NOT_FOUND, {"error": "Not found."}) + except (BrokenPipeError, ConnectionResetError): + return + except Exception: + LOGGER.exception("GET %s failed", path) + self._send_json(HTTPStatus.INTERNAL_SERVER_ERROR, {"error": "Server error."}) + + def do_POST(self) -> None: # noqa: N802 - BaseHTTPRequestHandler API + # Never reuse a connection after a POST. Some validation happens before + # the request body is read, so closing prevents leftover bytes from being + # interpreted as a second, Origin-less request. + self.close_connection = True + path = urlsplit(self.path).path + try: + if not self._host_allowed(): + raise RequestError(HTTPStatus.FORBIDDEN, "Host is not allowed.") + if path not in {"/format", "/api/layout-defaults"}: + raise RequestError(HTTPStatus.NOT_FOUND, "Not found.") + if not self._same_origin(): + raise RequestError(HTTPStatus.FORBIDDEN, "Cross-origin requests are not allowed.") + if self.headers.get("Transfer-Encoding") is not None: + raise RequestError( + HTTPStatus.BAD_REQUEST, + "Transfer-encoded requests are not supported.", + ) + + raw_length = self.headers.get("Content-Length") + if raw_length is None: + raise RequestError(HTTPStatus.LENGTH_REQUIRED, "Request size is required.") + try: + content_length = int(raw_length) + except ValueError as exc: + raise RequestError(HTTPStatus.BAD_REQUEST, "Invalid upload size.") from exc + if content_length <= 0: + raise RequestError(HTTPStatus.BAD_REQUEST, "The request is empty.") + + content_type = self.headers.get("Content-Type", "") + if path == "/api/layout-defaults": + if content_length > MAX_DEFAULTS_REQUEST_BYTES: + raise RequestError( + HTTPStatus.REQUEST_ENTITY_TOO_LARGE, + "The saved defaults request is too large.", + ) + if content_type.split(";", 1)[0].strip().lower() != "application/json": + raise RequestError( + HTTPStatus.BAD_REQUEST, + "Saved defaults must use JSON.", + ) + body = self.rfile.read(content_length) + if len(body) != content_length: + raise RequestError(HTTPStatus.BAD_REQUEST, "The request was incomplete.") + try: + payload = json.loads(body.decode("utf-8")) + except (UnicodeDecodeError, json.JSONDecodeError) as exc: + raise RequestError( + HTTPStatus.BAD_REQUEST, + "Saved defaults must contain valid JSON.", + ) from exc + if not isinstance(payload, dict): + raise RequestError( + HTTPStatus.BAD_REQUEST, + "Saved defaults must be a JSON object.", + ) + values = {str(name): str(value) for name, value in payload.items()} + settings = self.app.save_layout_defaults(values) + self._send_json( + HTTPStatus.OK, + { + "status": "saved", + "defaults": settings.as_form_values(), + }, + ) + return + + if content_length > self.app.max_request_bytes: + raise RequestError( + HTTPStatus.REQUEST_ENTITY_TOO_LARGE, + "The upload is too large.", + ) + if not content_type.lower().startswith("multipart/form-data"): + raise RequestError( + HTTPStatus.BAD_REQUEST, + "The upload must use multipart form data.", + ) + body = self.rfile.read(content_length) + if len(body) != content_length: + raise RequestError(HTTPStatus.BAD_REQUEST, "The upload was incomplete.") + + values, upload = parse_multipart(content_type, body) + png, filename, saved, removed = self.app.format_upload(upload, values) + if removed: + LOGGER.info("Retention removed: %s", ", ".join(removed)) + self._send_bytes( + HTTPStatus.OK, + png, + "image/png", + { + "Content-Disposition": f'attachment; filename="{filename}"', + "Cache-Control": "no-store", + "X-Roster-Saved": "true" if saved else "false", + }, + ) + except RequestError as exc: + self._send_json(exc.status, {"error": exc.message}) + except RosterFormatError as exc: + self._send_json(HTTPStatus.UNPROCESSABLE_ENTITY, {"error": str(exc)}) + except (BrokenPipeError, ConnectionResetError): + return + except Exception: + LOGGER.exception("POST %s failed", path) + message = ( + "The layout defaults could not be saved. Try again." + if path == "/api/layout-defaults" + else "The roster could not be formatted. Try again." + ) + self._send_json( + HTTPStatus.INTERNAL_SERVER_ERROR, + {"error": message}, + ) + + def log_message(self, format: str, *args: object) -> None: + LOGGER.info("%s - %s", self.address_string(), format % args) + + +def _environment_int(name: str, fallback: int) -> int: + raw = os.environ.get(name) + if raw is None: + return fallback + try: + return int(raw) + except ValueError as exc: + raise SystemExit(f"{name} must be a whole number") from exc + + +def _retention_maintenance(store: OutputStore, stop: Event) -> None: + while not stop.wait(RETENTION_CHECK_SECONDS): + try: + removed = store.prune() + if removed: + LOGGER.info("Scheduled retention removed: %s", ", ".join(removed)) + except OSError: + LOGGER.exception("Scheduled retention cleanup failed") + + +def build_parser() -> argparse.ArgumentParser: + parser = argparse.ArgumentParser(description="Run the local roster web app") + parser.add_argument("--host", default=os.environ.get("ROSTER_HOST", DEFAULT_HOST)) + parser.add_argument( + "--port", + type=int, + default=_environment_int("ROSTER_PORT", DEFAULT_PORT), + ) + parser.add_argument( + "--output-dir", + type=Path, + default=Path(os.environ.get("ROSTER_OUTPUT_DIR", BASE_DIR / "output")), + ) + parser.add_argument( + "--retention-months", + type=int, + default=_environment_int("ROSTER_RETENTION_MONTHS", DEFAULT_RETENTION_MONTHS), + help="delete roster PNGs more than this many calendar months old; 0 disables cleanup", + ) + parser.add_argument( + "--max-upload-mb", + type=int, + default=_environment_int("ROSTER_MAX_UPLOAD_MB", DEFAULT_MAX_UPLOAD_MB), + ) + return parser + + +def main() -> int: + args = build_parser().parse_args() + if not 1 <= args.port <= 65535: + raise SystemExit("port must be between 1 and 65535") + if args.retention_months < 0: + raise SystemExit("retention months cannot be negative") + if not 1 <= args.max_upload_mb <= 100: + raise SystemExit("max upload size must be between 1 and 100 MB") + + allowed_hosts = { + host.strip().lower().rstrip(".") + for host in os.environ.get("ROSTER_ALLOWED_HOSTS", "").split(",") + if host.strip() + } + if args.host not in {"0.0.0.0", "::"}: + allowed_hosts.add(args.host.lower().rstrip(".")) + + app = RosterWebApp( + output_dir=args.output_dir, + retention_months=args.retention_months, + max_upload_bytes=args.max_upload_mb * 1024 * 1024, + allowed_hosts=allowed_hosts, + ) + removed = app.store.prune() + if removed: + LOGGER.info("Startup retention removed: %s", ", ".join(removed)) + + server = RosterHTTPServer((args.host, args.port), app) + maintenance_stop = Event() + maintenance_thread: Thread | None = None + if args.retention_months > 0: + maintenance_thread = Thread( + target=_retention_maintenance, + args=(app.store, maintenance_stop), + name="roster-retention", + daemon=True, + ) + maintenance_thread.start() + LOGGER.info("Roster formatter available at http://%s:%s", args.host, args.port) + try: + server.serve_forever() + except KeyboardInterrupt: + LOGGER.info("Stopping roster formatter") + finally: + maintenance_stop.set() + if maintenance_thread is not None: + maintenance_thread.join(timeout=2) + server.server_close() + return 0 + + +if __name__ == "__main__": + logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s") + raise SystemExit(main()) diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..75efd30 --- /dev/null +++ b/tests/__init__.py @@ -0,0 +1 @@ +"""Roster formatter regression tests.""" diff --git a/tests/helpers.py b/tests/helpers.py new file mode 100644 index 0000000..078398a --- /dev/null +++ b/tests/helpers.py @@ -0,0 +1,38 @@ +from pathlib import Path + +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 diff --git a/tests/test_formatter.py b/tests/test_formatter.py new file mode 100644 index 0000000..0f92b59 --- /dev/null +++ b/tests/test_formatter.py @@ -0,0 +1,130 @@ +from datetime import date +from hashlib import sha256 +from pathlib import Path +from tempfile import TemporaryDirectory +import unittest + +import fitz # type: ignore +from PIL import Image + +from roster_formatter import ( + DEFAULT_LAYOUT, + PAGE_HEIGHT, + PAGE_WIDTH, + PNG_DPI, + PNG_HEIGHT, + PNG_WIDTH, + LayoutSettings, + RosterFormatError, + RosterPeriod, + format_roster, + validate_input_pdf, +) +from tests.helpers import make_geometry_pdf + + +LEGACY_GEOMETRY_SHA256 = "8b000127605f4fd78f9f39606de955eb02392ca113e8ddd808421d4f04c09c31" + + +class RosterPeriodTests(unittest.TestCase): + def test_original_month_abbreviation_rules_are_preserved(self) -> None: + expected = { + 1: "JAN 2026", + 2: "FEB 2026", + 3: "MARCH 2026", + 4: "APRIL 2026", + 5: "MAY 2026", + 6: "JUNE 2026", + 7: "JULY 2026", + 8: "AUG 2026", + 9: "SEP 2026", + 10: "OCT 2026", + 11: "NOV 2026", + 12: "DEC 2026", + } + self.assertEqual( + expected, + {month: RosterPeriod(2026, month).label for month in range(1, 13)}, + ) + + def test_suggested_period_changes_on_the_fifteenth(self) -> None: + self.assertEqual(RosterPeriod(2026, 7), RosterPeriod.suggested(date(2026, 7, 14))) + self.assertEqual(RosterPeriod(2026, 8), RosterPeriod.suggested(date(2026, 7, 15))) + self.assertEqual(RosterPeriod(2027, 1), RosterPeriod.suggested(date(2026, 12, 31))) + + def test_parse_accepts_browser_and_cli_formats(self) -> None: + self.assertEqual(RosterPeriod(2026, 9), RosterPeriod.parse("2026-09")) + self.assertEqual(RosterPeriod(2026, 9), RosterPeriod.parse("September 2026")) + self.assertEqual(RosterPeriod(2026, 9), RosterPeriod.parse("SEP 2026")) + + def test_parse_rejects_untrusted_filename_text(self) -> None: + with self.assertRaises(RosterFormatError): + RosterPeriod.parse("../../September 2026") + + +class LayoutRegressionTests(unittest.TestCase): + def test_production_defaults_are_explicit(self) -> None: + self.assertEqual(792, PAGE_WIDTH) + self.assertEqual(612, PAGE_HEIGHT) + self.assertEqual(150, PNG_DPI) + self.assertEqual(1650, PNG_WIDTH) + self.assertEqual(1275, PNG_HEIGHT) + self.assertEqual( + LayoutSettings( + content_shift=100, + bottom_margin=60, + logo_x=50, + logo_y=-10, + logo_scale=0.27, + date_x=460, + date_y=88, + date_font_size=48, + ), + DEFAULT_LAYOUT, + ) + + def test_legacy_default_is_byte_identical(self) -> None: + with TemporaryDirectory() as temp_dir: + root = Path(temp_dir) + source = make_geometry_pdf(root / "source.pdf") + output = root / "output.png" + format_roster(source, output, RosterPeriod(2026, 7)) + + self.assertEqual(LEGACY_GEOMETRY_SHA256, sha256(output.read_bytes()).hexdigest()) + with Image.open(output) as image: + self.assertEqual((PNG_WIDTH, PNG_HEIGHT), image.size) + self.assertEqual("RGB", image.mode) + + def test_explicit_adjustment_changes_pixels_but_not_canvas(self) -> None: + with TemporaryDirectory() as temp_dir: + root = Path(temp_dir) + source = make_geometry_pdf(root / "source.pdf") + default_output = root / "default.png" + adjusted_output = root / "adjusted.png" + format_roster(source, default_output, RosterPeriod(2026, 7)) + format_roster( + source, + adjusted_output, + RosterPeriod(2026, 7), + LayoutSettings(logo_x=55), + ) + + self.assertNotEqual(default_output.read_bytes(), adjusted_output.read_bytes()) + with Image.open(adjusted_output) as image: + self.assertEqual((PNG_WIDTH, PNG_HEIGHT), image.size) + + def test_input_geometry_is_validated(self) -> None: + with TemporaryDirectory() as temp_dir: + source = Path(temp_dir) / "portrait.pdf" + doc = fitz.open() + page = doc.new_page(width=612, height=792) + page.insert_text((20, 20), "not landscape") + doc.save(source) + doc.close() + + with self.assertRaisesRegex(RosterFormatError, "landscape"): + validate_input_pdf(source) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_server.py b/tests/test_server.py new file mode 100644 index 0000000..c4deb30 --- /dev/null +++ b/tests/test_server.py @@ -0,0 +1,406 @@ +from datetime import date, datetime +import json +import os +from pathlib import Path +import socket +from tempfile import TemporaryDirectory +from threading import Thread +import unittest +from urllib.error import HTTPError +from urllib.request import Request, urlopen + +from roster_formatter import DEFAULT_LAYOUT, LayoutSettings, RosterPeriod, format_roster +from server import OutputStore, RosterHTTPServer, RosterWebApp +from tests.helpers import make_geometry_pdf + + +def multipart_body(fields: dict[str, str], filename: str, file_data: bytes) -> tuple[str, bytes]: + boundary = "----RosterRegressionBoundary" + chunks: list[bytes] = [] + for name, value in fields.items(): + chunks.extend( + [ + f"--{boundary}\r\n".encode(), + f'Content-Disposition: form-data; name="{name}"\r\n\r\n'.encode(), + value.encode(), + b"\r\n", + ] + ) + chunks.extend( + [ + f"--{boundary}\r\n".encode(), + ( + 'Content-Disposition: form-data; name="roster"; ' + f'filename="{filename}"\r\n' + ).encode(), + b"Content-Type: application/pdf\r\n\r\n", + file_data, + b"\r\n", + f"--{boundary}--\r\n".encode(), + ] + ) + return f"multipart/form-data; boundary={boundary}", b"".join(chunks) + + +class OutputStoreTests(unittest.TestCase): + def test_layout_defaults_persist_across_store_restart_and_prune(self) -> None: + with TemporaryDirectory() as temp_dir: + root = Path(temp_dir) + settings = LayoutSettings( + content_shift=112, + bottom_margin=64, + logo_x=57, + logo_y=-8, + logo_scale=0.31, + date_x=472, + date_y=91, + date_font_size=52, + ) + store = OutputStore(root, retention_months=3) + + store.save_layout_defaults(settings) + + defaults_path = root / ".roster-layout-defaults.json" + self.assertTrue(defaults_path.is_file()) + self.assertEqual( + {"version": 1, "layout": settings.as_json_values()}, + json.loads(defaults_path.read_text(encoding="utf-8")), + ) + restarted_store = OutputStore(root, retention_months=3) + self.assertEqual(settings, restarted_store.load_layout_defaults()) + + os.utime(defaults_path, (datetime(2020, 1, 1).timestamp(),) * 2) + self.assertEqual([], restarted_store.prune(date(2026, 7, 25))) + self.assertTrue(defaults_path.is_file()) + self.assertEqual(settings, restarted_store.load_layout_defaults()) + + def test_invalid_layout_defaults_fall_back_to_factory_values(self) -> None: + with TemporaryDirectory() as temp_dir: + root = Path(temp_dir) + store = OutputStore(root, retention_months=3) + store.layout_defaults_path.write_text("{not valid json", encoding="utf-8") + + with self.assertLogs("roster.web", level="WARNING"): + loaded = store.load_layout_defaults() + + self.assertEqual(DEFAULT_LAYOUT, loaded) + + def test_retention_removes_only_matching_rosters_older_than_window(self) -> None: + with TemporaryDirectory() as temp_dir: + root = Path(temp_dir) + for filename in ( + "MARCH 2026 Roster.png", + "APRIL 2026 Roster.png", + "JULY 2026 Roster.png", + "JAN 2099 Roster.png", + "notes.png", + "shifted.pdf", + ): + (root / filename).write_bytes(b"test") + os.utime( + root / "JAN 2099 Roster.png", + (datetime(2026, 3, 31, 12).timestamp(),) * 2, + ) + + store = OutputStore(root, retention_months=3) + removed = store.prune(date(2026, 7, 25)) + + self.assertEqual( + ["JAN 2099 Roster.png", "MARCH 2026 Roster.png"], + removed, + ) + self.assertFalse((root / "MARCH 2026 Roster.png").exists()) + self.assertTrue((root / "APRIL 2026 Roster.png").exists()) + self.assertTrue((root / "notes.png").exists()) + self.assertTrue((root / "shifted.pdf").exists()) + + def test_symlink_is_never_listed_read_or_pruned(self) -> None: + with TemporaryDirectory() as temp_dir: + root = Path(temp_dir) + secret = root / "private.txt" + secret.write_bytes(b"private data") + link = root / "JAN 2020 Roster.png" + link.symlink_to(secret.name) + store = OutputStore(root, retention_months=3) + + self.assertIsNone(store.read(link.name)) + self.assertEqual([], store.list_items()) + self.assertEqual([], store.prune(date(2026, 7, 25))) + self.assertTrue(link.is_symlink()) + + def test_zero_retention_disables_cleanup(self) -> None: + with TemporaryDirectory() as temp_dir: + root = Path(temp_dir) + old = root / "JAN 2020 Roster.png" + old.write_bytes(b"test") + self.assertEqual([], OutputStore(root, retention_months=0).prune(date(2026, 7, 25))) + self.assertTrue(old.exists()) + + +class WebServerTests(unittest.TestCase): + def setUp(self) -> None: + self.temporary = TemporaryDirectory() + self.root = Path(self.temporary.name) + self.output_dir = self.root / "output" + self.source = make_geometry_pdf(self.root / "source.pdf") + self.app = RosterWebApp( + self.output_dir, + retention_months=0, + allowed_hosts={"roster.example.test"}, + ) + self.server = RosterHTTPServer(("127.0.0.1", 0), self.app) + self.thread = Thread(target=self.server.serve_forever, daemon=True) + self.thread.start() + host, port = self.server.server_address + self.base_url = f"http://{host}:{port}" + + def tearDown(self) -> None: + self.server.shutdown() + self.server.server_close() + self.thread.join(timeout=5) + self.temporary.cleanup() + + def test_health_and_index(self) -> None: + with urlopen(f"{self.base_url}/health", timeout=5) as response: + self.assertEqual({"status": "ok"}, json.loads(response.read())) + with urlopen(f"{self.base_url}/", timeout=5) as response: + html = response.read().decode() + self.assertIn("Roster Formatter", html) + self.assertNotIn("__DEFAULT_MONTH__", html) + self.assertNotIn("__LOGO_SCALE__", html) + self.assertIn('data-max-upload-mb="20"', html) + + def test_layout_defaults_endpoint_persists_canonical_values_in_index(self) -> None: + submitted = DEFAULT_LAYOUT.as_form_values() + submitted.update( + { + "content_shift": "123", + "bottom_margin": "65.5", + "logo_x": "58", + "logo_y": "-7", + "logo_scale": "0.310", + "date_x": "475", + "date_y": "92", + "date_font_size": "53", + } + ) + expected = LayoutSettings.from_mapping(submitted).as_form_values() + request = Request( + f"{self.base_url}/api/layout-defaults", + data=json.dumps(submitted).encode("utf-8"), + method="POST", + headers={"Content-Type": "application/json"}, + ) + + with urlopen(request, timeout=5) as response: + self.assertEqual( + {"status": "saved", "defaults": expected}, + json.loads(response.read()), + ) + + self.assertTrue((self.output_dir / ".roster-layout-defaults.json").is_file()) + restarted_store = OutputStore(self.output_dir, retention_months=0) + self.assertEqual(LayoutSettings.from_mapping(submitted), restarted_store.load_layout_defaults()) + with urlopen(f"{self.base_url}/", timeout=5) as response: + html = response.read().decode() + self.assertIn( + 'name="content_shift" type="number" value="123.0" ' + 'data-default="123.0" data-factory="100"', + html, + ) + self.assertIn( + 'name="logo_scale" type="number" value="0.31" ' + 'data-default="0.31" data-factory="0.27"', + html, + ) + self.assertIn( + 'name="date_font_size" type="number" value="53" ' + 'data-default="53" data-factory="48"', + html, + ) + self.assertNotIn("__FACTORY_", html) + + def test_layout_defaults_endpoint_requires_every_layout_field(self) -> None: + submitted = DEFAULT_LAYOUT.as_form_values() + submitted.pop("logo_scale") + request = Request( + f"{self.base_url}/api/layout-defaults", + data=json.dumps(submitted).encode("utf-8"), + method="POST", + headers={"Content-Type": "application/json"}, + ) + + with self.assertRaises(HTTPError) as caught: + urlopen(request, timeout=5) + + self.assertEqual(422, caught.exception.code) + self.assertEqual( + {"error": "Submit every layout setting before saving defaults."}, + json.loads(caught.exception.read()), + ) + self.assertFalse((self.output_dir / ".roster-layout-defaults.json").exists()) + + def test_theme_defaults_to_system_and_static_assets_expose_all_choices(self) -> None: + with urlopen(f"{self.base_url}/", timeout=5) as response: + html = response.read().decode() + self.assertIn('', html) + self.assertLess(html.index('/static/theme.js'), html.index('/static/styles.css')) + for choice in ("system", "light", "dark"): + self.assertIn(f'data-theme-choice="{choice}"', html) + + with urlopen(f"{self.base_url}/static/theme.js", timeout=5) as response: + self.assertTrue(response.headers["Content-Type"].startswith("text/javascript")) + theme_script = response.read().decode() + self.assertIn('new Set(["system", "light", "dark"])', theme_script) + self.assertIn('localStorage.getItem("roster-theme")', theme_script) + self.assertIn("document.documentElement.dataset.theme = theme", theme_script) + + with urlopen(f"{self.base_url}/static/styles.css", timeout=5) as response: + styles = response.read().decode() + self.assertIn(':root[data-theme="dark"]', styles) + self.assertIn("prefers-color-scheme: dark", styles) + + def test_untrusted_host_is_rejected(self) -> None: + request = Request( + f"{self.base_url}/api/history", + headers={"Host": "attacker.example"}, + ) + with self.assertRaises(HTTPError) as caught: + urlopen(request, timeout=5) + self.assertEqual(403, caught.exception.code) + self.assertEqual( + {"error": "Host is not allowed."}, + json.loads(caught.exception.read()), + ) + + def test_configured_caddy_host_is_allowed(self) -> None: + request = Request( + f"{self.base_url}/health", + headers={"Host": "roster.example.test"}, + ) + with urlopen(request, timeout=5) as response: + self.assertEqual({"status": "ok"}, json.loads(response.read())) + + def test_web_output_is_byte_identical_to_shared_renderer(self) -> None: + direct = self.root / "direct.png" + format_roster(self.source, direct, RosterPeriod(2026, 7)) + fields = DEFAULT_LAYOUT.as_form_values() + fields["month"] = "2026-07" + content_type, body = multipart_body( + fields, + "current-roster.pdf", + self.source.read_bytes(), + ) + request = Request( + f"{self.base_url}/format", + data=body, + method="POST", + headers={"Content-Type": content_type}, + ) + with urlopen(request, timeout=15) as response: + web_png = response.read() + self.assertEqual("true", response.headers["X-Roster-Saved"]) + self.assertIn("JULY 2026 Roster.png", response.headers["Content-Disposition"]) + + self.assertEqual(direct.read_bytes(), web_png) + self.assertEqual(web_png, (self.output_dir / "JULY 2026 Roster.png").read_bytes()) + + def test_format_missing_layout_fields_uses_saved_defaults(self) -> None: + settings = LayoutSettings( + content_shift=116, + bottom_margin=67, + logo_x=54, + logo_y=-6, + logo_scale=0.3, + date_x=468, + date_y=94, + date_font_size=51, + ) + self.app.store.save_layout_defaults(settings) + direct = self.root / "direct-saved-defaults.png" + format_roster(self.source, direct, RosterPeriod(2026, 8), settings) + content_type, body = multipart_body( + {"month": "2026-08"}, + "current-roster.pdf", + self.source.read_bytes(), + ) + request = Request( + f"{self.base_url}/format", + data=body, + method="POST", + headers={"Content-Type": content_type}, + ) + + with urlopen(request, timeout=15) as response: + web_png = response.read() + + self.assertEqual(direct.read_bytes(), web_png) + self.assertEqual(web_png, (self.output_dir / "AUG 2026 Roster.png").read_bytes()) + + def test_rejected_post_cannot_smuggle_a_second_request(self) -> None: + inner_content_type, inner_body = multipart_body( + {"month": "2026-07"}, + "smuggled.pdf", + self.source.read_bytes(), + ) + host, port = self.server.server_address + inner_request = ( + f"POST /format HTTP/1.1\r\n" + f"Host: {host}:{port}\r\n" + f"Content-Type: {inner_content_type}\r\n" + f"Content-Length: {len(inner_body)}\r\n" + "Connection: close\r\n" + "\r\n" + ).encode() + inner_body + outer_request = ( + f"POST /format HTTP/1.1\r\n" + f"Host: {host}:{port}\r\n" + "Origin: http://attacker.example\r\n" + "Content-Type: text/plain\r\n" + f"Content-Length: {len(inner_request)}\r\n" + "\r\n" + ).encode() + inner_request + + response_parts: list[bytes] = [] + with socket.create_connection((host, port), timeout=5) as connection: + connection.sendall(outer_request) + connection.shutdown(socket.SHUT_WR) + while True: + try: + chunk = connection.recv(65536) + except ConnectionResetError: + break + if not chunk: + break + response_parts.append(chunk) + + response = b"".join(response_parts) + self.assertEqual(1, response.count(b"HTTP/1.1")) + self.assertIn(b"403 Forbidden", response) + self.assertIn(b"Connection: close", response) + self.assertEqual([], list(self.output_dir.glob("*.png"))) + + def test_invalid_upload_gets_safe_error(self) -> None: + content_type, body = multipart_body( + {"month": "2026-07"}, + "not-a-roster.pdf", + b"this is not a pdf", + ) + request = Request( + f"{self.base_url}/format", + data=body, + method="POST", + headers={"Content-Type": content_type}, + ) + with self.assertRaises(HTTPError) as caught: + urlopen(request, timeout=5) + self.assertEqual(422, caught.exception.code) + self.assertEqual("close", caught.exception.headers["Connection"]) + self.assertEqual( + {"error": "The uploaded file is not a PDF."}, + json.loads(caught.exception.read()), + ) + + +if __name__ == "__main__": + unittest.main() diff --git a/web/app.js b/web/app.js new file mode 100644 index 0000000..7897fbf --- /dev/null +++ b/web/app.js @@ -0,0 +1,372 @@ +const body = document.body; +const form = document.querySelector("#roster-form"); +const fileInput = document.querySelector("#roster-file"); +const dropZone = document.querySelector("#drop-zone"); +const dropTitle = document.querySelector("#drop-title"); +const dropCopy = document.querySelector("#drop-copy"); +const monthInput = document.querySelector("#month"); +const suggestedMonthButton = document.querySelector("#suggested-month"); +const resetLayoutButton = document.querySelector("#reset-layout"); +const factoryLayoutButton = document.querySelector("#factory-layout"); +const saveLayoutDefaultsButton = document.querySelector("#save-layout-defaults"); +const layoutMessage = document.querySelector("#layout-message"); +const layoutInputs = [...document.querySelectorAll("[data-layout-input]")]; +const defaultsStatus = document.querySelector("#defaults-status"); +const themeChoiceButtons = [...document.querySelectorAll("[data-theme-choice]")]; +const formMessage = document.querySelector("#form-message"); +const formatButton = document.querySelector("#format-button"); +const buttonLabel = formatButton.querySelector(".button-label"); +const resultCard = document.querySelector("#result-card"); +const resultPreview = document.querySelector("#result-preview"); +const resultName = document.querySelector("#result-name"); +const downloadResult = document.querySelector("#download-result"); +const formatAnother = document.querySelector("#format-another"); +const historyList = document.querySelector("#history-list"); +const refreshHistoryButton = document.querySelector("#refresh-history"); +const retentionNote = document.querySelector("#retention-note"); + +const defaultMonth = body.dataset.defaultMonth; +const retentionMonths = Number(body.dataset.retentionMonths); +const maximumUploadMb = Number(body.dataset.maxUploadMb); +const maximumUploadBytes = maximumUploadMb * 1024 * 1024; +let selectedFile = null; +let resultUrl = null; + +const themeChoices = new Set(["system", "light", "dark"]); + +function setThemeChoice(choice, persist = true) { + const selected = themeChoices.has(choice) ? choice : "system"; + document.documentElement.dataset.theme = selected; + themeChoiceButtons.forEach((button) => { + button.setAttribute("aria-pressed", String(button.dataset.themeChoice === selected)); + }); + if (persist) { + try { + localStorage.setItem("roster-theme", selected); + } catch { + // The theme still works when browser storage is unavailable. + } + } +} + +function setFile(file) { + selectedFile = file || null; + if (!selectedFile) { + fileInput.value = ""; + dropZone.classList.remove("has-file"); + dropTitle.textContent = "Choose your roster PDF"; + dropCopy.textContent = `or drag it here · one-page landscape Letter · up to ${maximumUploadMb} MB`; + return; + } + + dropZone.classList.add("has-file"); + dropTitle.textContent = selectedFile.name; + dropCopy.textContent = `${formatFileSize(selectedFile.size)} · ready to format`; +} + +function formatFileSize(bytes) { + if (bytes < 1024 * 1024) { + return `${Math.max(1, Math.round(bytes / 1024))} KB`; + } + return `${(bytes / (1024 * 1024)).toFixed(1)} MB`; +} + +function showError(message) { + formMessage.textContent = message; + formMessage.hidden = false; +} + +function clearError() { + formMessage.textContent = ""; + formMessage.hidden = true; +} + +function showLayoutMessage(message, isError = false) { + layoutMessage.textContent = message; + layoutMessage.classList.toggle("is-error", isError); + layoutMessage.hidden = false; +} + +function clearLayoutMessage() { + layoutMessage.textContent = ""; + layoutMessage.classList.remove("is-error"); + layoutMessage.hidden = true; +} + +function setBusy(busy) { + body.classList.toggle("is-busy", busy); + form.setAttribute("aria-busy", String(busy)); + formatButton.disabled = busy; + buttonLabel.textContent = busy ? "Formatting…" : "Format roster"; +} + +function updateDefaultsStatus() { + const custom = layoutInputs.some((input) => { + if (input.value.trim() === "") { + return true; + } + return Number(input.value) !== Number(input.dataset.default); + }); + defaultsStatus.textContent = custom ? "Unsaved layout" : "Saved defaults"; + defaultsStatus.classList.toggle("is-custom", custom); +} + +async function saveLayoutDefaults() { + const invalidInput = layoutInputs.find((input) => !input.checkValidity()); + if (invalidInput) { + invalidInput.reportValidity(); + invalidInput.focus(); + return; + } + + const values = Object.fromEntries(layoutInputs.map((input) => [input.name, input.value])); + const originalLabel = saveLayoutDefaultsButton.textContent; + saveLayoutDefaultsButton.disabled = true; + saveLayoutDefaultsButton.textContent = "Saving…"; + clearLayoutMessage(); + + try { + const response = await fetch("/api/layout-defaults", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(values), + }); + let payload = {}; + try { + payload = await response.json(); + } catch { + // Use the safe fallback below if the server returns an unexpected response. + } + if (!response.ok) { + throw new Error(payload.error || "The layout defaults could not be saved."); + } + if (!payload.defaults || typeof payload.defaults !== "object") { + throw new Error("The server returned an invalid defaults response."); + } + + const canonicalValues = layoutInputs.map((input) => { + const savedValue = payload.defaults[input.name]; + if (savedValue === undefined) { + throw new Error("The server returned an incomplete defaults response."); + } + return String(savedValue); + }); + layoutInputs.forEach((input, index) => { + input.value = canonicalValues[index]; + input.dataset.default = canonicalValues[index]; + }); + updateDefaultsStatus(); + showLayoutMessage("Saved. These values will prefill future rosters."); + } catch (error) { + showLayoutMessage(error.message || "The layout defaults could not be saved.", true); + } finally { + saveLayoutDefaultsButton.disabled = false; + saveLayoutDefaultsButton.textContent = originalLabel; + } +} + +function responseFilename(response) { + const disposition = response.headers.get("Content-Disposition") || ""; + const match = disposition.match(/filename="([^"]+)"/i); + return match ? match[1] : "Formatted Roster.png"; +} + +function createHistoryItem(item) { + const link = document.createElement("a"); + link.className = "history-item"; + link.href = item.url; + link.download = item.filename; + + const file = document.createElement("span"); + file.className = "history-file"; + const name = document.createElement("strong"); + name.textContent = item.filename; + const details = document.createElement("small"); + details.textContent = `${formatFileSize(item.size)} · PNG`; + file.append(name, details); + + const icon = document.createElement("span"); + icon.className = "history-download"; + icon.setAttribute("aria-hidden", "true"); + icon.textContent = "↓"; + link.append(file, icon); + return link; +} + +async function loadHistory() { + refreshHistoryButton.disabled = true; + try { + const response = await fetch("/api/history", { cache: "no-store" }); + if (!response.ok) { + throw new Error("History could not be loaded."); + } + const payload = await response.json(); + historyList.replaceChildren(); + if (!payload.items.length) { + const empty = document.createElement("p"); + empty.className = "empty-state"; + empty.textContent = "Your formatted rosters will appear here."; + historyList.append(empty); + return; + } + payload.items.forEach((item) => historyList.append(createHistoryItem(item))); + } catch (error) { + const empty = document.createElement("p"); + empty.className = "empty-state"; + empty.textContent = error.message; + historyList.replaceChildren(empty); + } finally { + refreshHistoryButton.disabled = false; + } +} + +fileInput.addEventListener("change", () => { + setFile(fileInput.files[0] || null); + clearError(); +}); + +["dragenter", "dragover"].forEach((eventName) => { + dropZone.addEventListener(eventName, (event) => { + event.preventDefault(); + dropZone.classList.add("is-dragging"); + }); +}); + +["dragleave", "drop"].forEach((eventName) => { + dropZone.addEventListener(eventName, (event) => { + event.preventDefault(); + dropZone.classList.remove("is-dragging"); + }); +}); + +dropZone.addEventListener("drop", (event) => { + const file = [...event.dataTransfer.files].find( + (candidate) => candidate.type === "application/pdf" || candidate.name.toLowerCase().endsWith(".pdf"), + ); + if (!file) { + showError("Drop a PDF file here."); + return; + } + setFile(file); + clearError(); +}); + +window.addEventListener("dragover", (event) => event.preventDefault()); +window.addEventListener("drop", (event) => event.preventDefault()); + +suggestedMonthButton.addEventListener("click", () => { + monthInput.value = defaultMonth; +}); + +themeChoiceButtons.forEach((button) => { + button.addEventListener("click", () => setThemeChoice(button.dataset.themeChoice)); +}); + +layoutInputs.forEach((input) => { + input.addEventListener("input", () => { + updateDefaultsStatus(); + clearLayoutMessage(); + }); +}); + +resetLayoutButton.addEventListener("click", () => { + layoutInputs.forEach((input) => { + input.value = input.dataset.default; + }); + updateDefaultsStatus(); + showLayoutMessage("Restored the saved defaults."); +}); + +factoryLayoutButton.addEventListener("click", () => { + layoutInputs.forEach((input) => { + input.value = input.dataset.factory; + }); + updateDefaultsStatus(); + showLayoutMessage("Original production values loaded. Save them to make them the defaults."); +}); + +saveLayoutDefaultsButton.addEventListener("click", saveLayoutDefaults); + +form.addEventListener("submit", async (event) => { + event.preventDefault(); + clearError(); + + if (!selectedFile) { + showError("Choose a roster PDF first."); + fileInput.focus(); + return; + } + if (!selectedFile.name.toLowerCase().endsWith(".pdf")) { + showError("The roster filename must end in .pdf."); + return; + } + if (selectedFile.size > maximumUploadBytes) { + showError(`The roster PDF must be ${maximumUploadMb} MB or smaller.`); + return; + } + if (!form.reportValidity()) { + return; + } + + const formData = new FormData(form); + formData.delete("roster"); + formData.append("roster", selectedFile, selectedFile.name); + setBusy(true); + + try { + const response = await fetch("/format", { + method: "POST", + body: formData, + }); + if (!response.ok) { + let message = "The roster could not be formatted."; + try { + const payload = await response.json(); + message = payload.error || message; + } catch { + // Keep the safe fallback for an unexpected non-JSON response. + } + throw new Error(message); + } + + const blob = await response.blob(); + const filename = responseFilename(response); + const saved = response.headers.get("X-Roster-Saved") === "true"; + if (resultUrl) { + URL.revokeObjectURL(resultUrl); + } + resultUrl = URL.createObjectURL(blob); + resultPreview.src = resultUrl; + downloadResult.href = resultUrl; + downloadResult.download = filename; + resultName.textContent = saved + ? `${filename} · saved in output/` + : `${filename} · available for download (outside retention window)`; + resultCard.hidden = false; + await loadHistory(); + resultCard.focus({ preventScroll: true }); + resultCard.scrollIntoView({ behavior: "smooth", block: "start" }); + } catch (error) { + showError(error.message || "The roster could not be formatted."); + formMessage.scrollIntoView({ behavior: "smooth", block: "center" }); + } finally { + setBusy(false); + } +}); + +formatAnother.addEventListener("click", () => { + setFile(null); + resultCard.hidden = true; + clearError(); + dropZone.scrollIntoView({ behavior: "smooth", block: "center" }); +}); + +refreshHistoryButton.addEventListener("click", loadHistory); + +if (retentionMonths === 0) { + retentionNote.textContent = "Automatic roster cleanup is disabled."; +} + +setThemeChoice(document.documentElement.dataset.theme, false); +updateDefaultsStatus(); +loadHistory(); diff --git a/web/index.html b/web/index.html new file mode 100644 index 0000000..475b417 --- /dev/null +++ b/web/index.html @@ -0,0 +1,209 @@ + + + + + + + Roster Formatter + + + + + +

+ +
+
+

Roster formatter

+

From current roster to ready-to-share PNG.

+

+ Upload the one-page PDF, confirm its month, and download the formatted image. + The current layout is preserved unless you intentionally change an advanced value. +

+
+ PNG + 1650 × 1275 px + 150 DPI +
+
+ +
+
+
+
+

New export

+

Format a roster

+
+ Saved defaults +
+ +
+ + +
+ +
+ + +
+

This controls the label and downloaded filename.

+
+ +
+ + + Advanced adjustments + Use only when this month needs a nudge. + + + +
+
+

Values use PDF points. Saved defaults prefill every new roster.

+
+ + +
+
+ +
+ Roster content +
+ + +
+
+ +
+ Logo +
+ + + +
+
+ +
+ Date label +
+ + + +
+
+ +
+ + +
+ +

+ The page canvas and 150-DPI export stay fixed, even when these values change. +

+
+
+ + + +
+
+ + +
+
+ + + + diff --git a/web/styles.css b/web/styles.css new file mode 100644 index 0000000..61be793 --- /dev/null +++ b/web/styles.css @@ -0,0 +1,1074 @@ +:root { + --ink: #102d3d; + --ink-soft: #46606d; + --blue: #278fd0; + --blue-dark: #176fa7; + --blue-pale: #eaf6fc; + --paper: #fffdfa; + --canvas: #f2f0ea; + --canvas-top: #f8f7f2; + --canvas-glow: rgba(39, 143, 208, 0.12); + --line: #d9dedc; + --line-dark: #bdc9ca; + --border-subtle: rgba(16, 45, 61, 0.12); + --badge-bg: rgba(255, 255, 255, 0.62); + --fact-bg: rgba(255, 255, 255, 0.5); + --surface: rgba(255, 253, 250, 0.94); + --surface-solid: #fff; + --surface-muted: rgba(245, 247, 245, 0.66); + --surface-hover: #f7f8f6; + --preview-bg: #e8e8e5; + --focus-ring: rgba(39, 143, 208, 0.32); + --input-hover-border: #90a4a8; + --action-bg: #102d3d; + --action-hover: #17445c; + --action-ink: #fff; + --action-shadow: 0 8px 18px rgba(16, 45, 61, 0.2); + --brand-backdrop: transparent; + --theme-track: rgba(255, 255, 255, 0.56); + --theme-active: #fff; + --theme-active-shadow: 0 1px 5px rgba(16, 45, 61, 0.15); + --warning: #92610d; + --success: #23845f; + --success-ink: #fff; + --danger: #a33c37; + --shadow: 0 22px 60px rgba(16, 45, 61, 0.1); + color-scheme: light; + font-family: Inter, ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; +} + +:root[data-theme="dark"] { + --ink: #e7eff3; + --ink-soft: #a8bac3; + --blue: #55b7ee; + --blue-dark: #8bcff5; + --blue-pale: #143246; + --paper: #15252d; + --canvas: #0c151a; + --canvas-top: #111f26; + --canvas-glow: rgba(53, 166, 226, 0.16); + --line: #2b414c; + --line-dark: #405d69; + --border-subtle: rgba(198, 224, 235, 0.13); + --badge-bg: rgba(24, 39, 47, 0.8); + --fact-bg: rgba(25, 42, 51, 0.66); + --surface: rgba(20, 34, 41, 0.95); + --surface-solid: #14242c; + --surface-muted: rgba(15, 29, 36, 0.82); + --surface-hover: #1b303a; + --preview-bg: #25363e; + --focus-ring: rgba(85, 183, 238, 0.42); + --input-hover-border: #6f909e; + --action-bg: #3ba7df; + --action-hover: #62bcef; + --action-ink: #07151c; + --action-shadow: 0 8px 22px rgba(0, 0, 0, 0.32); + --brand-backdrop: rgba(255, 255, 255, 0.92); + --theme-track: rgba(7, 18, 23, 0.58); + --theme-active: #263d48; + --theme-active-shadow: 0 1px 7px rgba(0, 0, 0, 0.34); + --warning: #efbd64; + --success: #62cda3; + --success-ink: #082018; + --danger: #f1948e; + --shadow: 0 22px 60px rgba(0, 0, 0, 0.3); + color-scheme: dark; +} + +@media (prefers-color-scheme: dark) { + :root[data-theme="system"] { + --ink: #e7eff3; + --ink-soft: #a8bac3; + --blue: #55b7ee; + --blue-dark: #8bcff5; + --blue-pale: #143246; + --paper: #15252d; + --canvas: #0c151a; + --canvas-top: #111f26; + --canvas-glow: rgba(53, 166, 226, 0.16); + --line: #2b414c; + --line-dark: #405d69; + --border-subtle: rgba(198, 224, 235, 0.13); + --badge-bg: rgba(24, 39, 47, 0.8); + --fact-bg: rgba(25, 42, 51, 0.66); + --surface: rgba(20, 34, 41, 0.95); + --surface-solid: #14242c; + --surface-muted: rgba(15, 29, 36, 0.82); + --surface-hover: #1b303a; + --preview-bg: #25363e; + --focus-ring: rgba(85, 183, 238, 0.42); + --input-hover-border: #6f909e; + --action-bg: #3ba7df; + --action-hover: #62bcef; + --action-ink: #07151c; + --action-shadow: 0 8px 22px rgba(0, 0, 0, 0.32); + --brand-backdrop: rgba(255, 255, 255, 0.92); + --theme-track: rgba(7, 18, 23, 0.58); + --theme-active: #263d48; + --theme-active-shadow: 0 1px 7px rgba(0, 0, 0, 0.34); + --warning: #efbd64; + --success: #62cda3; + --success-ink: #082018; + --danger: #f1948e; + --shadow: 0 22px 60px rgba(0, 0, 0, 0.3); + color-scheme: dark; + } +} + +* { + box-sizing: border-box; +} + +html { + min-width: 320px; + background: var(--canvas); +} + +body { + min-height: 100vh; + margin: 0; + color: var(--ink); + background: + radial-gradient(circle at 84% 9%, var(--canvas-glow), transparent 25rem), + linear-gradient(180deg, var(--canvas-top) 0, var(--canvas) 42rem); +} + +button, +input { + font: inherit; +} + +button, +a { + -webkit-tap-highlight-color: transparent; +} + +button:focus-visible, +a:focus-visible, +input:focus-visible, +summary:focus-visible, +.drop-zone:focus-within { + outline: 3px solid var(--focus-ring); + outline-offset: 3px; +} + +[hidden] { + display: none !important; +} + +.site-header { + display: flex; + align-items: center; + justify-content: space-between; + width: min(1180px, calc(100% - 40px)); + min-height: 104px; + margin: 0 auto; + border-bottom: 1px solid var(--border-subtle); +} + +.brand { + display: inline-flex; + align-items: center; + padding: 6px 9px; + margin-left: -9px; + border-radius: 10px; + background: var(--brand-backdrop); +} + +.brand img { + display: block; + width: 218px; + height: auto; +} + +.header-actions { + display: flex; + align-items: center; + justify-content: flex-end; + gap: 12px; +} + +.theme-switch { + display: inline-flex; + align-items: center; + gap: 2px; + padding: 3px; + border: 1px solid var(--line); + border-radius: 999px; + background: var(--theme-track); +} + +.theme-option { + min-height: 31px; + padding: 5px 10px; + cursor: pointer; + color: var(--ink-soft); + border: 0; + border-radius: 999px; + background: transparent; + font-size: 0.7rem; + font-weight: 780; + line-height: 1; + transition: color 150ms ease, background 150ms ease, box-shadow 150ms ease; +} + +.theme-option:hover { + color: var(--ink); + background: var(--surface-hover); +} + +.theme-option[aria-pressed="true"], +.theme-option.is-active { + color: var(--ink); + background: var(--theme-active); + box-shadow: var(--theme-active-shadow); +} + +.local-badge, +.defaults-status { + display: inline-flex; + align-items: center; + gap: 8px; + padding: 8px 12px; + color: var(--ink-soft); + border: 1px solid var(--line); + border-radius: 999px; + background: var(--badge-bg); + font-size: 0.78rem; + font-weight: 700; + letter-spacing: 0.02em; +} + +.local-badge > span { + width: 8px; + height: 8px; + border-radius: 50%; + background: var(--success); + box-shadow: 0 0 0 4px rgba(35, 132, 95, 0.12); +} + +main { + width: min(1180px, calc(100% - 40px)); + margin: 0 auto; +} + +.intro { + max-width: 790px; + padding: 74px 0 52px; +} + +.eyebrow, +.step-label { + margin: 0 0 12px; + color: var(--blue-dark); + font-size: 0.73rem; + font-weight: 800; + letter-spacing: 0.16em; + text-transform: uppercase; +} + +h1, +h2, +p { + text-wrap: pretty; +} + +h1 { + max-width: 760px; + margin: 0; + font-family: Georgia, "Times New Roman", serif; + font-size: clamp(2.7rem, 6vw, 5.2rem); + font-weight: 500; + letter-spacing: -0.045em; + line-height: 0.98; +} + +.lede { + max-width: 660px; + margin: 26px 0 0; + color: var(--ink-soft); + font-size: 1.08rem; + line-height: 1.7; +} + +.format-facts { + display: flex; + flex-wrap: wrap; + gap: 8px; + margin-top: 28px; +} + +.format-facts span { + padding: 7px 11px; + border: 1px solid var(--border-subtle); + border-radius: 7px; + color: var(--ink-soft); + background: var(--fact-bg); + font-size: 0.78rem; + font-weight: 750; + letter-spacing: 0.025em; +} + +.workspace { + display: grid; + grid-template-columns: minmax(0, 1.45fr) minmax(310px, 0.75fr); + gap: 24px; + align-items: start; + padding-bottom: 80px; +} + +.side-column { + display: grid; + gap: 24px; +} + +.card { + border: 1px solid var(--border-subtle); + border-radius: 20px; + background: var(--surface); + box-shadow: var(--shadow); +} + +.form-card { + padding: clamp(24px, 5vw, 44px); +} + +.card-heading, +.result-heading, +.advanced-heading { + display: flex; + align-items: flex-start; + justify-content: space-between; + gap: 18px; +} + +.card-heading { + margin-bottom: 30px; +} + +.card-heading h2, +.result-heading h2 { + margin: 0; + font-size: 1.45rem; + letter-spacing: -0.025em; +} + +.card-heading .step-label, +.result-heading .step-label { + margin-bottom: 7px; +} + +.defaults-status { + flex: 0 0 auto; + color: var(--success); + border-color: rgba(35, 132, 95, 0.22); + background: rgba(35, 132, 95, 0.07); +} + +.defaults-status.is-custom { + color: var(--warning); + border-color: rgba(146, 97, 13, 0.24); + background: rgba(217, 151, 35, 0.09); +} + +.drop-zone { + position: relative; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + min-height: 228px; + padding: 32px 20px; + overflow: hidden; + cursor: pointer; + text-align: center; + border: 1.5px dashed var(--line-dark); + border-radius: 15px; + background: + linear-gradient(135deg, rgba(39, 143, 208, 0.035), rgba(39, 143, 208, 0.09)), + var(--paper); + transition: border-color 160ms ease, background 160ms ease, transform 160ms ease; +} + +.drop-zone::after { + position: absolute; + inset: auto -48px -68px auto; + width: 170px; + height: 170px; + content: ""; + border: 24px solid rgba(39, 143, 208, 0.055); + border-radius: 50%; +} + +.drop-zone:hover, +.drop-zone.is-dragging { + border-color: var(--blue); + background: + linear-gradient(135deg, rgba(39, 143, 208, 0.08), rgba(39, 143, 208, 0.14)), + var(--paper); +} + +.drop-zone.is-dragging { + transform: translateY(-2px); +} + +.drop-zone.has-file { + border-style: solid; + border-color: rgba(35, 132, 95, 0.36); + background: rgba(35, 132, 95, 0.055); +} + +.drop-zone input { + position: absolute; + width: 1px; + height: 1px; + opacity: 0; + pointer-events: none; +} + +.upload-mark { + display: grid; + place-items: center; + width: 50px; + height: 50px; + margin-bottom: 18px; + color: var(--action-ink); + border-radius: 14px; + background: var(--action-bg); + box-shadow: var(--action-shadow); + font-size: 1.45rem; + line-height: 1; +} + +.drop-title { + position: relative; + z-index: 1; + max-width: 90%; + overflow: hidden; + font-size: 1.02rem; + font-weight: 800; + text-overflow: ellipsis; + white-space: nowrap; +} + +.drop-copy { + position: relative; + z-index: 1; + margin-top: 8px; + color: var(--ink-soft); + font-size: 0.82rem; + line-height: 1.5; +} + +.field-block { + margin-top: 30px; +} + +.field-block > label, +.setting-grid label { + display: grid; + gap: 8px; + color: var(--ink); + font-size: 0.82rem; + font-weight: 760; +} + +.month-row { + display: flex; + align-items: center; + gap: 14px; + margin-top: 9px; +} + +input[type="month"], +input[type="number"] { + min-width: 0; + color: var(--ink); + border: 1px solid var(--line-dark); + border-radius: 10px; + background: var(--surface-solid); +} + +input[type="month"] { + width: min(260px, 100%); + min-height: 48px; + padding: 10px 13px; + font-weight: 680; +} + +input[type="number"] { + width: 100%; + min-height: 43px; + padding: 8px 10px; + font-variant-numeric: tabular-nums; +} + +input:hover { + border-color: var(--input-hover-border); +} + +.text-button, +.icon-button { + padding: 0; + cursor: pointer; + color: var(--blue-dark); + border: 0; + background: transparent; + font-size: 0.8rem; + font-weight: 800; +} + +.text-button:hover { + text-decoration: underline; + text-underline-offset: 3px; +} + +.field-help { + margin: 8px 0 0; + color: var(--ink-soft); + font-size: 0.78rem; +} + +.advanced { + margin-top: 30px; + border: 1px solid var(--line); + border-radius: 13px; + background: var(--surface-muted); +} + +.advanced summary { + display: flex; + align-items: center; + justify-content: space-between; + gap: 16px; + min-height: 72px; + padding: 16px 18px; + cursor: pointer; + list-style: none; +} + +.advanced summary::-webkit-details-marker { + display: none; +} + +.advanced summary > span:first-child { + display: grid; + gap: 4px; +} + +.advanced summary strong { + font-size: 0.87rem; +} + +.advanced summary small { + color: var(--ink-soft); + font-size: 0.74rem; + font-weight: 500; +} + +.chevron { + font-size: 1.3rem; + transition: transform 160ms ease; +} + +.advanced[open] .chevron { + transform: rotate(180deg); +} + +.advanced-body { + padding: 0 18px 20px; + border-top: 1px solid var(--line); +} + +.advanced-heading { + align-items: center; + padding: 16px 0 8px; +} + +.advanced-heading p { + margin: 0; + color: var(--ink-soft); + font-size: 0.75rem; + line-height: 1.45; +} + +.layout-actions { + display: flex; + flex: 0 0 auto; + flex-wrap: wrap; + justify-content: flex-end; + gap: 7px 14px; +} + +.layout-actions .text-button { + white-space: nowrap; +} + +fieldset { + min-width: 0; + margin: 15px 0 0; + padding: 0; + border: 0; +} + +legend { + margin-bottom: 10px; + font-size: 0.74rem; + font-weight: 850; + letter-spacing: 0.08em; + text-transform: uppercase; +} + +.setting-grid { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 11px; +} + +.setting-grid--three { + grid-template-columns: repeat(3, minmax(0, 1fr)); +} + +.setting-grid label { + color: var(--ink-soft); + font-size: 0.72rem; +} + +.canvas-lock { + margin: 18px 0 0; + padding: 11px 13px; + color: var(--ink-soft); + border-left: 3px solid var(--blue); + background: var(--blue-pale); + font-size: 0.73rem; + line-height: 1.5; +} + +.save-defaults-row { + display: flex; + align-items: center; + justify-content: flex-end; + gap: 14px; + margin-top: 18px; +} + +#layout-message { + flex: 1 1 auto; + margin: 0; + color: var(--success); + font-size: 0.74rem; + line-height: 1.45; +} + +#layout-message.is-error { + color: var(--danger); +} + +.save-defaults-button { + flex: 0 0 auto; + min-height: 42px; + padding: 9px 14px; + font-size: 0.78rem; +} + +.form-message { + margin-top: 22px; + padding: 12px 14px; + color: var(--danger); + border: 1px solid rgba(163, 60, 55, 0.23); + border-radius: 10px; + background: rgba(163, 60, 55, 0.07); + font-size: 0.82rem; + line-height: 1.5; +} + +.primary-button, +.secondary-button { + display: inline-flex; + align-items: center; + justify-content: center; + min-height: 51px; + padding: 13px 18px; + cursor: pointer; + border-radius: 10px; + font-size: 0.88rem; + font-weight: 820; + text-decoration: none; + transition: background 150ms ease, border-color 150ms ease, transform 150ms ease; +} + +#format-button { + justify-content: space-between; + width: 100%; + margin-top: 24px; +} + +.primary-button { + color: var(--action-ink); + border: 1px solid var(--action-bg); + background: var(--action-bg); +} + +.primary-button:hover { + border-color: var(--action-hover); + background: var(--action-hover); + transform: translateY(-1px); +} + +.primary-button:disabled { + cursor: wait; + opacity: 0.68; + transform: none; +} + +.button-arrow { + font-size: 1.3rem; + font-weight: 400; +} + +.secondary-button { + color: var(--ink); + border: 1px solid var(--line-dark); + background: var(--surface-solid); +} + +.secondary-button:hover { + border-color: var(--ink-soft); + background: var(--surface-hover); +} + +.secondary-button:disabled { + cursor: wait; + opacity: 0.65; +} + +.result-card, +.history-card { + padding: 26px; +} + +.result-card { + border-color: rgba(35, 132, 95, 0.22); +} + +.result-heading { + margin-bottom: 20px; +} + +.success-mark { + display: grid; + place-items: center; + width: 35px; + height: 35px; + color: var(--success-ink); + border-radius: 50%; + background: var(--success); + font-weight: 900; +} + +.preview-shell { + padding: 8px; + overflow: hidden; + border: 1px solid var(--line); + border-radius: 11px; + background: var(--preview-bg); +} + +.preview-shell img { + display: block; + width: 100%; + height: auto; + border-radius: 5px; + background: white; +} + +.result-name { + margin: 13px 0 0; + overflow-wrap: anywhere; + color: var(--ink-soft); + font-size: 0.78rem; + text-align: center; +} + +.result-actions { + display: grid; + grid-template-columns: 1fr; + gap: 9px; + margin-top: 18px; +} + +.compact-heading { + align-items: center; + margin-bottom: 18px; +} + +.icon-button { + display: grid; + place-items: center; + width: 34px; + height: 34px; + border: 1px solid var(--line); + border-radius: 50%; + font-size: 1.05rem; +} + +.icon-button:hover { + background: var(--blue-pale); +} + +.history-list { + display: grid; + gap: 8px; +} + +.history-item { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; + min-width: 0; + padding: 12px; + color: inherit; + border: 1px solid var(--line); + border-radius: 10px; + background: var(--surface-solid); + text-decoration: none; + transition: border-color 150ms ease, background 150ms ease; +} + +.history-item:hover { + border-color: rgba(39, 143, 208, 0.48); + background: var(--blue-pale); +} + +.history-file { + min-width: 0; +} + +.history-file strong, +.history-file small { + display: block; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.history-file strong { + font-size: 0.8rem; +} + +.history-file small { + margin-top: 3px; + color: var(--ink-soft); + font-size: 0.69rem; +} + +.history-download { + flex: 0 0 auto; + color: var(--blue-dark); + font-size: 1.05rem; +} + +.empty-state, +.retention-note { + margin: 0; + color: var(--ink-soft); + font-size: 0.74rem; + line-height: 1.55; +} + +.empty-state { + padding: 22px 12px; + border: 1px dashed var(--line-dark); + border-radius: 10px; + text-align: center; +} + +.retention-note { + margin-top: 15px; +} + +.privacy-note { + display: flex; + align-items: flex-start; + gap: 13px; + padding: 0 8px; + color: var(--ink-soft); +} + +.privacy-note > span { + display: grid; + place-items: center; + flex: 0 0 auto; + width: 28px; + height: 28px; + border: 1px solid var(--line-dark); + border-radius: 50%; + font-size: 0.82rem; +} + +.privacy-note p { + margin: 3px 0 0; + font-size: 0.73rem; + line-height: 1.6; +} + +footer { + display: flex; + justify-content: space-between; + gap: 20px; + width: min(1180px, calc(100% - 40px)); + margin: 0 auto; + padding: 25px 0 32px; + color: var(--ink-soft); + border-top: 1px solid var(--border-subtle); + font-size: 0.72rem; +} + +body.is-busy .drop-zone, +body.is-busy .advanced, +body.is-busy .field-block { + opacity: 0.66; + pointer-events: none; +} + +@media (max-width: 860px) { + .workspace { + grid-template-columns: 1fr; + } + + .side-column { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + + .result-card, + .privacy-note { + grid-column: 1 / -1; + } +} + +@media (max-width: 620px) { + .site-header, + main, + footer { + width: min(100% - 24px, 1180px); + } + + .site-header { + flex-wrap: wrap; + gap: 10px; + min-height: 82px; + padding: 14px 0; + } + + .brand img { + width: 165px; + } + + .header-actions { + flex: 1 1 100%; + justify-content: space-between; + gap: 8px; + } + + .theme-option { + min-height: 29px; + padding: 5px 8px; + font-size: 0.66rem; + } + + .local-badge { + padding: 7px 9px; + font-size: 0.68rem; + } + + .intro { + padding: 52px 4px 38px; + } + + h1 { + font-size: clamp(2.5rem, 13vw, 4rem); + } + + .lede { + font-size: 0.98rem; + } + + .form-card, + .result-card, + .history-card { + padding: 22px; + border-radius: 16px; + } + + .drop-zone { + min-height: 205px; + } + + .month-row { + align-items: flex-start; + flex-direction: column; + } + + input[type="month"] { + width: 100%; + } + + .setting-grid, + .setting-grid--three { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + + .advanced-heading { + align-items: flex-start; + flex-direction: column; + } + + .layout-actions { + justify-content: flex-start; + } + + .save-defaults-row { + align-items: stretch; + flex-direction: column; + } + + .side-column { + grid-template-columns: 1fr; + } + + .result-card, + .privacy-note { + grid-column: auto; + } + + footer { + flex-direction: column; + } +} + +@media (max-width: 420px) { + .card-heading { + align-items: flex-start; + flex-direction: column; + } + + .compact-heading { + align-items: center; + flex-direction: row; + } + + .setting-grid, + .setting-grid--three { + grid-template-columns: 1fr; + } +} + +@media (prefers-reduced-motion: reduce) { + *, + *::before, + *::after { + scroll-behavior: auto !important; + transition-duration: 0.01ms !important; + } +} diff --git a/web/theme.js b/web/theme.js new file mode 100644 index 0000000..2fc666e --- /dev/null +++ b/web/theme.js @@ -0,0 +1,15 @@ +(() => { + const allowedThemes = new Set(["system", "light", "dark"]); + let theme = "system"; + + try { + const savedTheme = window.localStorage.getItem("roster-theme"); + if (allowedThemes.has(savedTheme)) { + theme = savedTheme; + } + } catch { + // Storage can be unavailable in hardened or private browsing contexts. + } + + document.documentElement.dataset.theme = theme; +})();