Skip to content

Fix odds-ticker baseball gap and stock-ticker logo spacing#178

Merged
ChuckBuilds merged 3 commits into
mainfrom
claude/odds-stock-ticker-spacing
Jul 10, 2026
Merged

Fix odds-ticker baseball gap and stock-ticker logo spacing#178
ChuckBuilds merged 3 commits into
mainfrom
claude/odds-stock-ticker-spacing

Conversation

@ChuckBuilds

Copy link
Copy Markdown
Owner

Summary

  • odds-ticker: for live baseball games, the odds column width was sized to the away/home odds text ("Bases: 1B2B3B", "Count: 3-2" — up to 104px at 8px font), even though that text is never drawn for baseball; only a 24px bases-diamond graphic is drawn, left-aligned in that column. The next column (inning info) started after the full unused text width, leaving up to ~80px of dead space between the bases graphic and the inning text. Now the column is sized to the actual 24px graphic when it's a live baseball game.
  • ledmatrix-stocks: logo_x (2px) and logo_gap (4px between the logo's right edge and the symbol/price text) were too tight for a ~26px-tall logo on the 32px-tall display, making the logo look cramped against the edge and the text. Bumped to 4px and 8px respectively.

Found via code + browser/font analysis while investigating a user report of visible spacing issues on a running display (ledpi); root causes confirmed by computing actual text widths with the real font (PressStart2P-Regular.ttf) rather than guessing.

Test plan

  • python3 -m py_compile on both changed files
  • Verified via the real font that the baseball odds column shrinks from up to 104px to 24px
  • Visual confirmation on a physical LED matrix (no local hardware to render against from this environment)

🤖 Generated with Claude Code

odds-ticker: for live baseball games, odds_width was sized from the
away/home odds text ("Bases: 1B2B3B", "Count: 3-2" - up to 104px at
8px font) even though that text is never drawn; a 24px bases-diamond
graphic is drawn instead, left-aligned in that column. The next
column (inning info) started after the full odds_width, leaving up
to ~80px of dead space between the bases graphic and the inning
text. Detect the live-baseball case before sizing the column and use
the actual 24px graphic width instead of maxing against the unused
placeholder text.

ledmatrix-stocks: logo_x (2px) and logo_gap (4px, between the logo's
right edge and the symbol/price text) were too tight for a ~26px-tall
logo on a 32px-tall display. Bumped to 4px and 8px.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@ChuckBuilds, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 50 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 48b1627f-0066-4593-9297-61408e2bbb88

📥 Commits

Reviewing files that changed from the base of the PR and between ddbe970 and 201e85e.

📒 Files selected for processing (5)
  • plugins.json
  • plugins/ledmatrix-stocks/display_renderer.py
  • plugins/ledmatrix-stocks/manifest.json
  • plugins/odds-ticker/manager.py
  • plugins/odds-ticker/manifest.json
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/odds-stock-ticker-spacing

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.

@codacy-production

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 0 complexity

Metric Results
Complexity 0

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@ChuckBuilds

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

CI's version-bump enforcement failed because this PR's code changes to
display_renderer.py and manager.py weren't matched by manifest version
bumps. Branch was 5 commits behind main (missing #177's GPL/hasattr-guard
work, which had already taken ledmatrix-stocks to 2.3.1) — merged main
in first so this bumps from the real current version instead of colliding
with an already-published one.

- ledmatrix-stocks: 2.3.1 -> 2.3.2 (logo_x/logo_gap spacing fix)
- odds-ticker: 1.1.4 -> 1.1.5 (baseball odds-column sizing fix), and
  dropped its dependencies.managers object — same schema shape as the
  bug fixed in stock-news (PR #174): manifest_schema.json types
  `dependencies` as a flat array of pip package names, and nothing in
  core reads a `managers` key. It was never touched before because CI
  only validates changed plugins, but editing this manifest for the
  version bump means the schema check now runs against it for real.

New versions[] entries use ledmatrix_min_version (not the deprecated
ledmatrix_min flagged by core's store_manager.py validator).

plugins.json synced via update_registry.py.
@ChuckBuilds ChuckBuilds merged commit f391d72 into main Jul 10, 2026
3 checks passed
@ChuckBuilds ChuckBuilds deleted the claude/odds-stock-ticker-spacing branch July 10, 2026 17:28
ChuckBuilds added a commit that referenced this pull request Jul 10, 2026
Same recurring issue as PRs #175/#177/#178: the core's store_manager.py
validator flags ledmatrix_min as deprecated and expects
ledmatrix_min_version. This PR's new 1.19.0 changelog entry used the
deprecated name; corrected to match the non-deprecated field (older
entries below 1.6.2 already have this same pre-existing issue but are
untouched by this PR, so left as-is -- out of scope here).
ChuckBuilds added a commit that referenced this pull request Jul 10, 2026
…ayer card (v1.19.0) (#180)

* feat(baseball-scoreboard): team-color grid, clearer at-bat labels, player card (v1.19.0)

Three enhancements to the baseball plugin:

1. Traditional scoreboard: subtle team-color row tint (~12% brightness
   wash) plus a solid left-edge accent strip per team, reusing the
   already-fetched away/home ESPN colors. Gated by a new
   show_team_color_backgrounds toggle (default on; requires
   use_team_colors). Text stays legible via its black outline.

2. Pitcher/Batter screen: labels spelled out ("Pitcher:" / "Batter:")
   so "B" is no longer ambiguous with the grid's Balls indicator.

3. New Player Card screen (show_player_card, MLB & NCAA): rotates in a
   masters-style card for the current batter/pitcher with headshot,
   jersey number, position, bat/throw, and season stats (AVG/HR/RBI for
   hitters, ERA/W-L/K for pitchers). Bio + headshot fetched from ESPN's
   athlete API and cached (memory + disk); the headshot hides on tiny
   panels and the card degrades to text-only when unavailable. Skipped
   for MiLB (no ESPN player data).

All new code lives in existing files (no new bare-name modules, per the
cross-plugin collision rule). Adds config schema (grid toggle, per-league
show_player_card, player_card customization block), manager plumbing,
docs, and tests (test_player_card.py + grid-tint tests).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R1z28MrGx56x6eiJvibDg9

* fix(baseball-scoreboard): harden headshot cache path + download URL

Address a Codacy medium security finding on the new player-card headshot
loader:
- Sanitize the ESPN-provided player_id and league before using them as
  filesystem path segments (_safe_filename strips to [A-Za-z0-9_-]) so an
  unexpected id can't escape the headshot cache directory via '..' or path
  separators.
- Only fetch headshots over http(s), refusing file://, ftp://, etc.

Adds a unit test for the filename sanitization.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R1z28MrGx56x6eiJvibDg9

* fix(baseball-scoreboard): log player-bio cache errors instead of silent pass

Resolve the Codacy/Bandit B110 (try/except/pass) medium finding in
_fetch_player_bio: the two cache_manager get/set guards swallowed
exceptions with a bare `pass`. Log them at debug level instead so
cache issues are diagnosable, matching how the rest of the plugin
handles non-fatal cache errors.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R1z28MrGx56x6eiJvibDg9

* fix(baseball-scoreboard): harden + de-block headshot fetch (CodeRabbit review)

Address two CodeRabbit review findings on the player-card headshot loader:

1. SSRF + unbounded response (security): the ESPN-supplied headshot URL was
   fetched with only a scheme check. Now restrict the host to ESPN domains
   (*.espncdn.com / *.espn.com) via an allowlist, and stream the download
   with a hard 5 MB size cap (Content-Length check + bounded iter_content)
   to prevent memory exhaustion.

2. Render-path blocking (stability): load_headshot() previously did a
   synchronous requests.get on a cache miss straight from
   _draw_player_card_screen, freezing the display up to 5s when a new
   batter/pitcher rotated in. The render path is now cache-only
   (allow_download=False); BaseballLive.update() prefetches headshot bytes
   off-thread (daemon thread, throttled) to warm the disk cache, mirroring
   the existing _fetch_player_bio pattern. A cold cache degrades to a
   text-only card until the prefetch completes.

Adds tests for the host allowlist (incl. metadata-IP and look-alike-host
rejection) and for the render path never downloading.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R1z28MrGx56x6eiJvibDg9

* fix(baseball-scoreboard): use ledmatrix_min_version in new 1.19.0 entry

Same recurring issue as PRs #175/#177/#178: the core's store_manager.py
validator flags ledmatrix_min as deprecated and expects
ledmatrix_min_version. This PR's new 1.19.0 changelog entry used the
deprecated name; corrected to match the non-deprecated field (older
entries below 1.6.2 already have this same pre-existing issue but are
untouched by this PR, so left as-is -- out of scope here).

---------

Co-authored-by: Claude <noreply@anthropic.com>
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.

1 participant