mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-08-01 08:48:05 +00:00
Add skin system: user-installable visual overlays for sports scoreboards (#419)
* Add skin system: user-installable visual overlays for sports scoreboards Skins restyle a scoreboard's live/recent/upcoming rendering while the host plugin keeps doing data fetching, scheduling, caching, live priority, and vegas mode — the anti-fork alternative for users who only want a different layout. - src/skin_system/: ScoreboardSkin API, SkinContext (canvas + adaptive layout + logo/font helpers), discovery/loading runtime with API major version gating and per-skin module namespacing - src/base_classes/sports.py: _render_game() seam at the three _draw_scorebug_layout call sites; skin-first with built-in fallback, 3-strikes session disable, slow-render warning; per-mode skin config - scripts/validate_skin.py: headless multi-mode/multi-size validator with bundled per-sport fixtures (no hardware or network needed) - skins/example-classic-baseball/: working reference skin - Web UI: served-schema Visual Skin dropdown (validation never enum-restricted, so uninstalled skins can't invalidate configs) and GET /api/v3/skins - Store: registry entries with type "skin" install to skins/ - docs/SKIN_SYSTEM.md (architecture), docs/CREATING_SKINS.md (author guide incl. Claude Code prompt), view-model contract locked by tests Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LrCusPasy1qeUN5anK3aA1 * Address review feedback on skin system - skin_runtime: cache the entry module so the 2nd/3rd load of the same skin (live/recent/upcoming hosts) doesn't re-execute it with unbound sibling aliases; rebind cached sibling modules to their bare names around entry import and restore prior bindings after; include per- manifest mtimes in the discovery cache fingerprint so in-place skin updates are picked up - sports.py: count render_skin_card exceptions toward the 3-strike session disable - store_manager: validate skin ids (pattern + resolved-path containment in skins/), reject registry/manifest id mismatches, and stage+validate downloads in a temp sibling before replacing an existing skin - schema_manager: leave the schema untouched when the configured skin value is a per-mode mapping (a string dropdown could overwrite it) - validate_skin.py: reject non-positive sizes and non-object --options at parse time; support --output-dir outside the repo; type annotations - example skin: validate accent_color once at load with logged fallback - fixtures: pregame 0-0 scores in football/hockey upcoming fixtures - api /skins: rely on the self-invalidating discovery cache instead of force_refresh - docs: valid JSON manifest example, load_logo caching semantics spelled out, language ids on fenced blocks - tests: view-model contract test now exercises the real extractor; regression test for repeated same-skin loads with sibling modules Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LrCusPasy1qeUN5anK3aA1 --------- Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"id": "401570001",
|
||||
"game_time": "7:05PM",
|
||||
"game_date": "Jul 16th",
|
||||
"start_time_utc": "2026-07-16T23:05:00+00:00",
|
||||
"status_text": "Final",
|
||||
"is_live": false,
|
||||
"is_final": true,
|
||||
"is_upcoming": false,
|
||||
"is_halftime": false,
|
||||
"is_period_break": false,
|
||||
"home_abbr": "LAD",
|
||||
"home_id": "19",
|
||||
"home_score": "5",
|
||||
"home_logo_path": "src/skin_system/fixtures/placeholder_home.png",
|
||||
"home_logo_url": null,
|
||||
"home_record": "58-33",
|
||||
"away_abbr": "SF",
|
||||
"away_id": "26",
|
||||
"away_score": "3",
|
||||
"away_logo_path": "src/skin_system/fixtures/placeholder_away.png",
|
||||
"away_logo_url": null,
|
||||
"away_record": "49-42",
|
||||
"is_within_window": true,
|
||||
"status": "STATUS_FINAL",
|
||||
"status_state": "post",
|
||||
"inning": 9,
|
||||
"inning_half": "top",
|
||||
"balls": 0,
|
||||
"strikes": 0,
|
||||
"outs": 3,
|
||||
"bases_occupied": [
|
||||
false,
|
||||
false,
|
||||
false
|
||||
],
|
||||
"start_time": "2026-07-16T23:05:00Z",
|
||||
"series_summary": "Series tied 2-2"
|
||||
}
|
||||
Reference in New Issue
Block a user