Skip to content

feat(masters): phase-aware Vegas scroll, crisp countdown rendering, stale-date guard (v2.5.0)#105

Open
sarjent wants to merge 4 commits intoChuckBuilds:mainfrom
sarjent:feat/masters-post-tournament-improvements
Open

feat(masters): phase-aware Vegas scroll, crisp countdown rendering, stale-date guard (v2.5.0)#105
sarjent wants to merge 4 commits intoChuckBuilds:mainfrom
sarjent:feat/masters-post-tournament-improvements

Conversation

@sarjent
Copy link
Copy Markdown
Contributor

@sarjent sarjent commented Apr 21, 2026

Summary

  • Vegas scroll phase-awareget_vegas_content() previously rendered the full leaderboard and course cards regardless of tournament phase. Off-season and pre-tournament now show a countdown card only; practice/tournament/post-tournament show the full leaderboard + hole + fun-fact strip.
  • Countdown card drawn at scroll sizerender_countdown() now accepts optional card_width/card_height params (matching render_player_card/render_hole_card), so Vegas scroll draws the card at the target dimensions directly instead of post-scaling a full-panel render with LANCZOS (which blurred pixel fonts).
  • Larger countdown font on wide-short displays — Added a dedicated font_countdown so the countdown number uses a large font independently of the compact leaderboard font override applied on wide-short panels like 192×32.
  • Narrow-panel font guardfont_countdown now gates "xl" (10px PressStart2P) on tier == "large" (width > 64). Narrow-tall panels (e.g. 32×64, 64×64) previously selected xl and overflowed on long strings like "364d 12h"; they now get "medium" (8px).
  • ESPN endDate cap — ESPN keeps the Masters event active post-tournament and extends endDate well past Sunday, causing the plugin to stay in tournament phase and never transition to countdown. Fixed by capping parsed endDate to start_date + 3 days 23:59:59 in _parse_leaderboard_event(), preventing an annual stale-cache bug.
  • Off-season countdown weightingPHASE_MODES["off-season"] now lists masters_countdown 3× (out of 10 entries) so it gets ~30% of screen time during the off-season rotation.
  • _computed_fallback_meta() microseconds — Fixed thu_midnight_edt to zero microseconds to avoid sub-second drift in phase boundary calculations.
  • Non-ASCII character — Replaced × (U+00D7) with x in an inline comment to satisfy RUF003 linter.
  • Narrowed broad exceptget_player_headshot() download path now catches only (requests.exceptions.RequestException, UnidentifiedImageError, OSError) instead of bare Exception.

Files changed

File Change
manager.py Phase-aware get_vegas_content(), countdown called with card_width/card_height, off-season countdown weighting
masters_renderer.py render_countdown() card_width/card_height params, font_countdown with tier+height guard
masters_data.py ESPN endDate cap, _computed_fallback_meta() microsecond fix
masters_helpers.py Non-ASCII comment fix
logo_loader.py Narrowed broad except in headshot download
manifest.json Version bumps 2.4.3 → 2.4.6

Test plan

  • Off-season: Vegas scroll shows countdown card only (no leaderboard or hole cards)
  • Pre-tournament: same countdown-only behavior
  • During tournament: Vegas scroll shows leaderboard + holes + fun facts
  • Post-tournament (within configured days): leaderboard cards visible
  • Post-tournament (beyond configured days): transitions to countdown
  • 192×32 display: countdown number renders at 10px, crisp (no blur)
  • 32×64 or 64×64 display: countdown text fits without overflow
  • Confirm endDate cap prevents stale phase after tournament Sunday

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Masters Tournament plugin now shows phase-aware content: countdown-only cards in off-season/pre-tournament and full leaderboard/cards during active phases.
  • Bug Fixes

    • Tournament end date clamped to the expected tournament week to avoid extended displays.
  • Chores

    • Masters Tournament plugin bumped to 2.5.0; global plugin metadata updated (including lacrosse-scoreboard to 1.2.1) and overall plugins list timestamp refreshed.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 21, 2026

Warning

Rate limit exceeded

@sarjent has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 31 minutes and 9 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 31 minutes and 9 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1c51a0bd-8cc8-4f6a-94a2-84ef0649920e

📥 Commits

Reviewing files that changed from the base of the PR and between df91c7b and d351b79.

📒 Files selected for processing (5)
  • plugins.json
  • plugins/masters-tournament/manager.py
  • plugins/masters-tournament/manifest.json
  • plugins/masters-tournament/masters_data.py
  • plugins/masters-tournament/masters_renderer.py
📝 Walkthrough

Walkthrough

Updates masters-tournament metadata to v2.5.0 and makes Vegas rendering phase-aware: off-season/pre-tournament can return a countdown-only card; clamps parsed tournament end_date to the expected Sunday; and adds per-card sizing & dedicated countdown font to the renderer.

Changes

Cohort / File(s) Summary
Metadata & Registry
plugins.json, plugins/masters-tournament/manifest.json
Bumped plugin manifest to 2.5.0 and updated plugins.json last_updated. Added new version entries (2.5.0, 2.4.6, 2.4.5, 2.4.4) and adjusted timestamps.
Manager — Phase-aware Vegas logic
plugins/masters-tournament/manager.py
get_vegas_content() now computes phase via _meta_dates()/get_detailed_phase() and returns a countdown-only card for off-season/pre-tournament when enabled (uses fallback start_date when needed); preserves multi-card flow for practice/tournament/post-tournament.
Data — End-date clamping
plugins/masters-tournament/masters_data.py
_parse_tournament_meta() now clamps end_date to the tournament-week Sunday boundary (start_date + 3 days, 23:59:59) after day-end normalization.
Renderer — Countdown sizing & fonts
plugins/masters-tournament/masters_renderer.py
Added font_countdown selection and updated render_countdown(...) signature to accept optional card_width/card_height. Layout, sizing, and shadow/text measurements use derived w/h when overrides provided.

Sequence Diagram

sequenceDiagram
    participant Manager as Manager<br/>(get_vegas_content)
    participant Data as MastersData<br/>(_meta_dates / _parse_tournament_meta)
    participant Phase as PhaseDetect<br/>(get_detailed_phase)
    participant Renderer as MastersRenderer<br/>(render_countdown)

    Manager->>Data: Request tournament meta dates
    Data-->>Manager: Return meta_start/meta_end (end_date clamped)
    Manager->>Phase: Determine detailed phase from dates
    Phase-->>Manager: Return phase (off-season, pre-tournament, etc.)

    alt Off-Season or Pre-Tournament
        Manager->>Renderer: render_countdown(days,hours,minutes, card_width, card_height)
        Renderer->>Renderer: Select font_countdown based on tier/height
        Renderer->>Renderer: Compute layout using derived w/h
        Renderer-->>Manager: Return countdown card
        Manager-->>Client: Return single countdown card
    else Practice/Tournament/Post-Tournament
        Manager->>Renderer: render_leaderboard_cards() / render_hole_cards()
        Renderer-->>Manager: Return multi-card composition
        Manager-->>Client: Return leaderboard + hole cards (+ fun-facts)
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly and specifically summarizes the main changes: phase-aware Vegas scroll behavior, countdown rendering improvements (crispness via card dimension parameters), and stale-date guard logic, with version bump to v2.5.0. All primary features are reflected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
plugins/masters-tournament/manager.py (1)

710-715: Avoid reaching into _computed_fallback_meta from outside the data source.

fetch_tournament_meta() already falls back to _computed_fallback_meta() when cache + live fetch both fail, so the two-step meta or _computed_fallback_meta() dance here duplicates that logic and leaks a private helper across module boundaries. A single call is clearer and keeps the data-source encapsulation intact:

♻️ Suggested cleanup
-            meta = self._tournament_meta or {}
-            target = meta.get("start_date")
-            if target is None:
-                target = self.data_source._computed_fallback_meta().get("start_date")
+            meta = self._tournament_meta or self.data_source.fetch_tournament_meta() or {}
+            target = meta.get("start_date")
             if not target:
                 return None
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugins/masters-tournament/manager.py` around lines 710 - 715, This code
reaches into data_source._computed_fallback_meta() and duplicates fallback
logic; replace the meta resolution with a single call to fetch_tournament_meta()
(or use self.fetch_tournament_meta() / the public data-source method that
already applies cache+live+fallback) instead of inspecting self._tournament_meta
or calling the private _computed_fallback_meta(), then extract target =
meta.get("start_date") and return None if not target; remove any direct
references to _computed_fallback_meta() to preserve encapsulation (keep
references to self._tournament_meta only if fetch_tournament_meta() is
unavailable but prefer the public fetch).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@plugins/masters-tournament/manager.py`:
- Around line 716-724: The countdown card is being resized with
Image.Resampling.LANCZOS which blurs bitmap/pixel fonts from render_countdown;
update the code so render_countdown can produce the card at the target size (add
optional card_width/card_height parameters to render_countdown and call it with
(cw,ch) matching render_player_card/render_hole_card), and if you cannot change
render_countdown immediately, change the resize call that currently uses
Image.Resampling.LANCZOS to use Image.Resampling.NEAREST so pixel glyphs remain
crisp when cw != self.display_width; ensure references include
calculate_tournament_countdown, render_countdown, cw, ch, and
Image.Resampling.NEAREST.

In `@plugins/masters-tournament/masters_renderer.py`:
- Around line 343-352: The countdown font selection currently picks
self.font_countdown via _load_font("xl"/"medium"/"small") purely on self.height,
which causes overflow on narrow tall panels; change the logic in the
font-selection block so it also considers horizontal budget (self.width or
self.tier) before choosing "xl" or "medium" — e.g., only pick "xl" when
self.height >= 20 AND self.width is wide enough (or tier != "small"), otherwise
fall back to the more compact self.font_score or a smaller _load_font size;
adjust references to font_countdown and ensure render_countdown uses that
smaller font to prevent overflow.

---

Nitpick comments:
In `@plugins/masters-tournament/manager.py`:
- Around line 710-715: This code reaches into
data_source._computed_fallback_meta() and duplicates fallback logic; replace the
meta resolution with a single call to fetch_tournament_meta() (or use
self.fetch_tournament_meta() / the public data-source method that already
applies cache+live+fallback) instead of inspecting self._tournament_meta or
calling the private _computed_fallback_meta(), then extract target =
meta.get("start_date") and return None if not target; remove any direct
references to _computed_fallback_meta() to preserve encapsulation (keep
references to self._tournament_meta only if fetch_tournament_meta() is
unavailable but prefer the public fetch).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3eba7dc4-c310-4790-801d-00fef2a37b03

📥 Commits

Reviewing files that changed from the base of the PR and between 13517ea and d82f15a.

📒 Files selected for processing (6)
  • plugins.json
  • plugins/masters-tournament/logo_loader.py
  • plugins/masters-tournament/manager.py
  • plugins/masters-tournament/manifest.json
  • plugins/masters-tournament/masters_data.py
  • plugins/masters-tournament/masters_renderer.py

Comment thread plugins/masters-tournament/manager.py
Comment thread plugins/masters-tournament/masters_renderer.py Outdated
@sarjent sarjent force-pushed the feat/masters-post-tournament-improvements branch from c38942d to f34fd91 Compare April 21, 2026 20:43
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@plugins/masters-tournament/manager.py`:
- Around line 689-691: The manifest/plugin version was increased only from
2.4.3→2.4.6 but this PR adds new phase-aware display functionality so you must
bump the MINOR version (not a patch); update the plugin manifest/version
constant to 2.5.0 (look for symbols like MANIFEST["version"], PLUGIN_VERSION, or
any VERSION constant in manager.py and the plugin manifest object) and ensure
any published metadata that references 2.4.x is updated to 2.5.0 so the release
reflects a new feature.
- Around line 710-716: get_vegas_content currently uses self._tournament_meta or
falls back to self.data_source._computed_fallback_meta() only when start_date is
None; change it to treat a start_date that is already past as stale and fall
back as well: retrieve meta via self._tournament_meta (or computed fallback),
parse the candidate start_date, call calculate_tournament_countdown(target) only
if the countdown indicates a non-zero future time (or if target > now),
otherwise reassign target =
self.data_source._computed_fallback_meta().get("start_date") and re-evaluate;
update the logic around variables meta, target and the call to
calculate_tournament_countdown to ensure stale/past start_date from cached
_tournament_meta does not produce an all-zero countdown.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: dc193474-d30b-4516-bfe9-14fee467e8c5

📥 Commits

Reviewing files that changed from the base of the PR and between d82f15a and f34fd91.

📒 Files selected for processing (5)
  • plugins.json
  • plugins/masters-tournament/manager.py
  • plugins/masters-tournament/manifest.json
  • plugins/masters-tournament/masters_data.py
  • plugins/masters-tournament/masters_renderer.py
✅ Files skipped from review due to trivial changes (2)
  • plugins.json
  • plugins/masters-tournament/manifest.json
🚧 Files skipped from review as they are similar to previous changes (2)
  • plugins/masters-tournament/masters_data.py
  • plugins/masters-tournament/masters_renderer.py

Comment on lines +689 to +691
Content is phase-aware:
off-season / pre-tournament → countdown card only
practice / tournament / post → leaderboard + holes + fun facts
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Use a minor version bump for the new phase-aware Vegas behavior.

This changes display functionality, but the PR summary says the manifest moved from 2.4.3 to 2.4.6. Please bump the plugin to the next minor version instead, e.g. 2.5.0, if this ships as new functionality. As per coding guidelines, “Bump MINOR version (1.x.0) for new features added, new config options (backward compatible), or new display modes/functionality”.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugins/masters-tournament/manager.py` around lines 689 - 691, The
manifest/plugin version was increased only from 2.4.3→2.4.6 but this PR adds new
phase-aware display functionality so you must bump the MINOR version (not a
patch); update the plugin manifest/version constant to 2.5.0 (look for symbols
like MANIFEST["version"], PLUGIN_VERSION, or any VERSION constant in manager.py
and the plugin manifest object) and ensure any published metadata that
references 2.4.x is updated to 2.5.0 so the release reflects a new feature.

Comment thread plugins/masters-tournament/manager.py
@sarjent sarjent changed the title fix(masters): Vegas scroll phase-awareness, countdown font, ESPN endDate cap (v2.4.3–2.4.5) feat(masters): phase-aware Vegas scroll, crisp countdown rendering, stale-date guard (v2.5.0) Apr 21, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
plugins/masters-tournament/manager.py (1)

710-721: Same stale-start_date guard is missing in _display_countdown.

The new guard here correctly falls back to _computed_fallback_meta() when cached start_date is in the past. However, _display_countdown (lines 648–667) still only falls back when start_date is falsy — if self._tournament_meta holds a completed tournament's start_date (truthy but stale), calculate_tournament_countdown() will return all zeros there too. Consider extracting a shared helper (e.g. _resolve_countdown_target()) so both paths stay consistent.

♻️ Suggested refactor
+    def _resolve_countdown_target(self):
+        """Return a future start_date for the countdown, falling back when
+        cached meta is missing or stale (past)."""
+        meta = self._tournament_meta or {}
+        target = meta.get("start_date")
+        if target is not None:
+            t_aware = target if target.tzinfo else target.replace(tzinfo=timezone.utc)
+            if t_aware <= datetime.now(timezone.utc):
+                target = None
+        if target is None:
+            target = self.data_source._computed_fallback_meta().get("start_date")
+        return target

Then reuse it in both _display_countdown and the new get_vegas_content branch.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugins/masters-tournament/manager.py` around lines 710 - 721, Extract a
single helper (e.g. _resolve_countdown_target) that encapsulates the stale
start_date check currently in get_vegas_content: it should read
self._tournament_meta.get("start_date"), if present make it timezone-aware
(default UTC) and if <= datetime.now(timezone.utc) treat it as None, then
fallback to self.data_source._computed_fallback_meta().get("start_date") and
return the final target or None. Replace the direct start_date handling in
_display_countdown (and the new branch in get_vegas_content) to call
_resolve_countdown_target so both paths use the same logic before invoking
calculate_tournament_countdown or returning None.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@plugins/masters-tournament/manager.py`:
- Around line 710-721: Extract a single helper (e.g. _resolve_countdown_target)
that encapsulates the stale start_date check currently in get_vegas_content: it
should read self._tournament_meta.get("start_date"), if present make it
timezone-aware (default UTC) and if <= datetime.now(timezone.utc) treat it as
None, then fallback to
self.data_source._computed_fallback_meta().get("start_date") and return the
final target or None. Replace the direct start_date handling in
_display_countdown (and the new branch in get_vegas_content) to call
_resolve_countdown_target so both paths use the same logic before invoking
calculate_tournament_countdown or returning None.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3d5b5a41-bd41-4203-95a2-8caf198218ea

📥 Commits

Reviewing files that changed from the base of the PR and between f34fd91 and df91c7b.

📒 Files selected for processing (3)
  • plugins.json
  • plugins/masters-tournament/manager.py
  • plugins/masters-tournament/manifest.json
✅ Files skipped from review due to trivial changes (2)
  • plugins.json
  • plugins/masters-tournament/manifest.json

@ChuckBuilds
Copy link
Copy Markdown
Owner

@sarjent I'm a bit confused on this one. Claude says it's empty and changes have already been merged. It's got a conflict with the lacrosse PR I just merged but I am not sure if we need to resolve and re-merge or just ignore. Open to suggestions

@sarjent
Copy link
Copy Markdown
Contributor Author

sarjent commented Apr 22, 2026

@sarjent I'm a bit confused on this one. Claude says it's empty and changes have already been merged. It's got a conflict with the lacrosse PR I just merged but I am not sure if we need to resolve and re-merge or just ignore. Open to suggestions

All sync'd. I was a bit behind on the branch.

sarjent and others added 4 commits April 22, 2026 08:53
- get_vegas_content() now checks tournament phase: off-season and
  pre-tournament return a single countdown card only; practice/
  tournament/post-tournament return the full leaderboard+holes+facts
  rotation. Fixes Vegas scroll always showing stale leaderboard data
  in off-season regardless of phase.
- Cap ESPN endDate to start_date+3d in _parse_leaderboard_event so
  ESPN's extended post-tournament API window can never push end_date
  beyond Sunday, preventing annual stale-cache phase detection bugs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add font_countdown that always uses the largest font fitting the display
height (xl=10px for height>=20, medium=8px for height>=14, else small).
Bypasses the wide-short override that was reducing font_score to 6px on
192x32 and similar panels, making the countdown number very small.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…v2.4.6)

Add card_width/card_height params to render_countdown so Vegas scroll
draws the card at the target size directly instead of LANCZOS-scaling
a full-panel render (which blurs pixel fonts). Also gate font_countdown
xl selection on tier=="large" so narrow-tall panels (e.g. 32x64, 64x64)
don't overflow with the 10px PressStart2P countdown string.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
….5.0

Bump MINOR version to 2.5.0: phase-aware Vegas scroll is new user-visible
functionality (off-season/pre-tournament show countdown only; active phases
show leaderboard+holes+fun facts), not a bug fix.

Also guard against stale cached start_date in get_vegas_content: if
_tournament_meta holds a past start_date (e.g. prior year cached value),
treat it as missing and fall back to _computed_fallback_meta() so the
countdown never shows all-zero from an expired date.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@sarjent sarjent force-pushed the feat/masters-post-tournament-improvements branch from df91c7b to d351b79 Compare April 22, 2026 13:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants