From 40fcd1ed9faf22bba769da563cdac8e7964d56ea Mon Sep 17 00:00:00 2001 From: Chuck Date: Tue, 7 Apr 2026 14:07:39 -0400 Subject: [PATCH] docs: fix README_NBA_LOGOS and PLUGIN_CONFIGURATION_GUIDE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit scripts/README_NBA_LOGOS.md - "python download_nba_logos.py" — wrong on two counts. The script is at scripts/download_nba_logos.py (not the project root), and "python" is Python 2 on most systems. Replaced all 4 occurrences with "python3 scripts/download_nba_logos.py". - The doc framed itself as the way to set up "the NBA leaderboard". The basketball/leaderboard functionality is now in the basketball-scoreboard and ledmatrix-leaderboard plugins (in the ledmatrix-plugins repo), which auto-download logos on first run. Reframed the script as a pre-population utility for offline / dev use cases. - Bumped the documented Python minimum from 3.7 to 3.9 to match the rest of the project. docs/PLUGIN_CONFIGURATION_GUIDE.md - The "Plugin Manifest" example was missing 3 fields the plugin loader actually requires: id, entry_point, and class_name. A contributor copying this manifest verbatim would get PluginError("No class_name in manifest") at load time — the same loader bug already found in stock-news. Added all three. - The same example showed config_schema as an inline object. The loader expects config_schema to be a file path string (e.g. "config_schema.json") with the actual schema in a separate JSON file — verified earlier in this audit. Fixed. - Added a paragraph explaining the loader's required fields and the case-sensitivity rule on class_name (the bug that broke hello-world's manifest before this PR fixed it). - "Plugin Manager Class" example had the wrong constructor signature: (config, display_manager, cache_manager, font_manager). The real BasePlugin.__init__ at base_plugin.py:53-60 takes (plugin_id, config, display_manager, cache_manager, plugin_manager). A copy-pasted example would TypeError on instantiation. Fixed, including a comment noting which attributes BasePlugin sets up. - Renamed the example class from MyPluginManager to MyPlugin to match the project convention (XxxPlugin / XxxScoreboardPlugin in actual plugins). Co-Authored-By: Claude Opus 4.6 (1M context) --- docs/PLUGIN_CONFIGURATION_GUIDE.md | 38 ++++++++++++++++++------------ scripts/README_NBA_LOGOS.md | 37 +++++++++++++++++++---------- 2 files changed, 48 insertions(+), 27 deletions(-) diff --git a/docs/PLUGIN_CONFIGURATION_GUIDE.md b/docs/PLUGIN_CONFIGURATION_GUIDE.md index e8f8cb13..7471130a 100644 --- a/docs/PLUGIN_CONFIGURATION_GUIDE.md +++ b/docs/PLUGIN_CONFIGURATION_GUIDE.md @@ -184,37 +184,45 @@ plugin-repos/ ```json { + "id": "my-plugin", "name": "My Plugin", "version": "1.0.0", "description": "Plugin description", "author": "Your Name", + "entry_point": "manager.py", + "class_name": "MyPlugin", "display_modes": ["my_plugin"], - "config_schema": { - "type": "object", - "properties": { - "enabled": {"type": "boolean", "default": false}, - "update_interval": {"type": "integer", "default": 3600} - } - } + "config_schema": "config_schema.json" } ``` +The required fields the plugin loader will check for are `id`, +`name`, `version`, `class_name`, and `display_modes`. `entry_point` +defaults to `manager.py` if omitted. `config_schema` must be a +**file path** (relative to the plugin directory) — the schema itself +lives in a separate JSON file, not inline in the manifest. The +`class_name` value must match the actual class defined in the entry +point file **exactly** (case-sensitive, no spaces); otherwise the +loader fails with `AttributeError` at load time. + ### Plugin Manager Class ```python from src.plugin_system.base_plugin import BasePlugin -class MyPluginManager(BasePlugin): - def __init__(self, config, display_manager, cache_manager, font_manager): - super().__init__(config, display_manager, cache_manager, font_manager) - self.enabled = config.get('enabled', False) - +class MyPlugin(BasePlugin): + def __init__(self, plugin_id, config, display_manager, cache_manager, plugin_manager): + super().__init__(plugin_id, config, display_manager, cache_manager, plugin_manager) + # self.config, self.display_manager, self.cache_manager, + # self.plugin_manager, self.logger, and self.enabled are + # all set up by BasePlugin.__init__. + def update(self): - """Update plugin data""" + """Fetch/update data. Called based on update_interval.""" pass - + def display(self, force_clear=False): - """Display plugin content""" + """Render plugin content to the LED matrix.""" pass def get_duration(self): diff --git a/scripts/README_NBA_LOGOS.md b/scripts/README_NBA_LOGOS.md index 1a025cd5..8ae9b496 100644 --- a/scripts/README_NBA_LOGOS.md +++ b/scripts/README_NBA_LOGOS.md @@ -1,29 +1,40 @@ # NBA Logo Downloader -This script downloads all NBA team logos from the ESPN API and saves them in the `assets/sports/nba_logos/` directory for use with the NBA leaderboard. +This script downloads all NBA team logos from the ESPN API and saves +them in the `assets/sports/nba_logos/` directory. + +> **Heads up:** the NBA leaderboard and basketball scoreboards now +> live as plugins in the +> [`ledmatrix-plugins`](https://github.com/ChuckBuilds/ledmatrix-plugins) +> repo (`basketball-scoreboard`, `ledmatrix-leaderboard`). Those +> plugins download the logos they need automatically on first display. +> This standalone script is mainly useful when you want to pre-populate +> the assets directory ahead of time, or for development/debugging. + +All commands below should be run from the LEDMatrix project root. ## Usage ### Basic Usage ```bash -python download_nba_logos.py +python3 scripts/download_nba_logos.py ``` ### Force Re-download If you want to re-download all logos (even if they already exist): ```bash -python download_nba_logos.py --force +python3 scripts/download_nba_logos.py --force ``` ### Quiet Mode Reduce logging output: ```bash -python download_nba_logos.py --quiet +python3 scripts/download_nba_logos.py --quiet ``` ### Combined Options ```bash -python download_nba_logos.py --force --quiet +python3 scripts/download_nba_logos.py --force --quiet ``` ## What It Does @@ -82,12 +93,14 @@ assets/sports/nba_logos/ └── WAS.png # Washington Wizards ``` -## Integration with NBA Leaderboard +## Integration with NBA plugins -Once the logos are downloaded, the NBA leaderboard will: -- ✅ Use local logos instantly (no download delays) -- ✅ Display team logos in the scrolling leaderboard -- ✅ Show proper team branding for all 30 NBA teams +Once the logos are in `assets/sports/nba_logos/`, both the +`basketball-scoreboard` and `ledmatrix-leaderboard` plugins will pick +them up automatically and skip their own first-run download. This is +useful if you want to deploy a Pi without internet access to ESPN, or +if you want to preview the display on your dev machine without +waiting for downloads. ## Troubleshooting @@ -102,6 +115,6 @@ This is normal - some teams might have temporary API issues or the ESPN API migh ## Requirements -- Python 3.7+ -- `requests` library (should be installed with the project) +- Python 3.9+ (matches the project's overall minimum) +- `requests` library (already in `requirements.txt`) - Write access to `assets/sports/nba_logos/` directory