mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-10-04 14:25:08 +00:00
chore: mark skins unsupported, fix stale docs and preview size, prepare 3.4.0 (#580)
* chore: mark skins unsupported, fix stale docs and preview size, prepare 3.4.0
Skins: no current scoreboard plugin builds on src.base_classes, so the only
skin hook (SportsCore._render_game) never runs. The plugin schema endpoint no
longer injects the Visual Skin dropdown, the store hides and refuses
"type": "skin" registry entries, and GET /api/v3/skins reports
supported: false with a message. Stored skin config still loads and saves.
src/skin_system/ and its tests are unchanged apart from the support flag.
Docs: check_plugin.py/render_plugin.py examples use --plugin; document
BasePlugin.get_update_interval() and its interaction with the manifest
update_interval; CLAUDE.md drops the stale template line number and
recommends display_manager.width/height.
Preview size: new src/display_geometry.py holds the size computation and
defaults DisplayManager uses (double-sided applied, chain_length default 2).
The web preview, /display/current, Starlark magnify default, sync handshake
and two dev scripts use it.
Release: __version__ 3.4.0, CHANGELOG 3.4.0 section plus a 3.3.0 tag note.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix: address CodeRabbit review on #580
- Preview fallbacks (SSE stream and /display/current) use logical_size({})
(128x32, the shared default) instead of a hard-coded 128x64.
- display_geometry treats a non-mapping display/hardware block as missing,
so a malformed config.json falls back to defaults instead of raising
AttributeError (which turned the Starlark render into an HTTP 500).
- Docs: the static update interval falls back manifest -> plugin config
-> 60s, in both the API reference and the architecture spec.
Not taken: validating double_sided copies against chain_length/parallel.
An orientation Rotate: or U-mapper pixel mapper decides which axis panels
lie on, so the counts would reject working setups (the existing
vertical-split test is one).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix(display_geometry): a non-finite hardware size raises ValueError, not OverflowError
CodeRabbit flagged the Starlark magnify default in
_standalone_render_starlark_app for truthy non-mapping display values. That
case was already handled by a9e1bd0b (_display/_hardware treat a non-mapping
block as missing, covered by test_non_mapping_display_config_uses_the_defaults),
and the magnify it produces from the 128x32 defaults is the same as from 64x32.
Checking the same path found one input that still escaped: Python's JSON
parser accepts Infinity, and int(inf) raises OverflowError, which neither the
Starlark path (TypeError, ValueError) nor the preview stream in app.py caught,
so a hand-edited "rows": Infinity returned HTTP 500. physical_size now raises
ValueError for it, matching its documented contract, so every caller's
existing fallback applies. DisplayManager already caught Exception.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1256,6 +1256,16 @@ def install_plugin():
|
||||
plugin_id = data['plugin_id']
|
||||
branch = data.get('branch') # Optional branch parameter
|
||||
|
||||
# A registry skin would install but never render with the current
|
||||
# scoreboards; refuse it with the reason rather than a generic failure
|
||||
try:
|
||||
registry_entry = api_v3.plugin_store_manager.get_registry_info(plugin_id)
|
||||
except Exception:
|
||||
registry_entry = None
|
||||
if isinstance(registry_entry, dict) and (registry_entry.get('type') or 'plugin') == 'skin':
|
||||
from src.skin_system import SKINS_UNSUPPORTED_MESSAGE
|
||||
return jsonify({'status': 'error', 'message': SKINS_UNSUPPORTED_MESSAGE}), 400
|
||||
|
||||
# Install the plugin
|
||||
# Log the plugins directory being used for debugging
|
||||
plugins_dir = api_v3.plugin_store_manager.plugins_dir
|
||||
@@ -1456,9 +1466,13 @@ def get_registry_from_url():
|
||||
registry = api_v3.plugin_store_manager.fetch_registry_from_url(repo_url)
|
||||
|
||||
if registry:
|
||||
# Skins aren't offered: current scoreboards don't render them
|
||||
return jsonify({
|
||||
'status': 'success',
|
||||
'plugins': registry.get('plugins', []),
|
||||
'plugins': [
|
||||
p for p in registry.get('plugins', [])
|
||||
if not (isinstance(p, dict) and (p.get('type') or 'plugin') == 'skin')
|
||||
],
|
||||
'registry_url': repo_url
|
||||
})
|
||||
else:
|
||||
@@ -1573,6 +1587,10 @@ def list_plugin_store():
|
||||
# Format plugins for the web interface
|
||||
formatted_plugins = []
|
||||
for plugin in plugins:
|
||||
# Registry skins install but never render with the current
|
||||
# scoreboards, so the store doesn't offer them
|
||||
if (plugin.get('type') or 'plugin') == 'skin':
|
||||
continue
|
||||
formatted_plugins.append({
|
||||
'id': plugin.get('id'),
|
||||
'name': plugin.get('name'),
|
||||
@@ -2649,18 +2667,11 @@ def get_plugin_schema():
|
||||
schema = schema_mgr.load_schema(plugin_id, use_cache=True)
|
||||
|
||||
if schema:
|
||||
# Offer installed visual skins as a dropdown (returns a copy;
|
||||
# the cached schema and validation are never enum-restricted)
|
||||
try:
|
||||
current_skin = None
|
||||
if api_v3.config_manager:
|
||||
config = api_v3.config_manager.load_config()
|
||||
current_skin = config.get(plugin_id, {}).get('skin')
|
||||
injected = schema_mgr.inject_skin_selector(schema, plugin_id, current_skin)
|
||||
if isinstance(injected, dict):
|
||||
schema = injected
|
||||
except Exception:
|
||||
logger.debug('Skin selector injection failed for %s', plugin_id, exc_info=True)
|
||||
# No "Visual Skin" dropdown: the current scoreboard plugins don't
|
||||
# render skins (src.skin_system.SKINS_UNSUPPORTED_MESSAGE), so
|
||||
# schema_mgr.inject_skin_selector is deliberately not called. A
|
||||
# stored "skin" value is unaffected: validation still allows it
|
||||
# and a form save deep-merges over the stored section, keeping it.
|
||||
return jsonify({'status': 'success', 'data': {'schema': schema}})
|
||||
|
||||
# Return a simple default schema if file not found
|
||||
|
||||
Reference in New Issue
Block a user