Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions plugins.json
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@
"last_updated": "2026-09-02",
"verified": true,
"screenshot": "",
"latest_version": "1.29.1"
"latest_version": "1.29.2"
},
{
"id": "calendar",
Expand Down Expand Up @@ -240,7 +240,7 @@
"last_updated": "2026-09-02",
"verified": true,
"screenshot": "",
"latest_version": "3.4.1"
"latest_version": "3.4.2"
},
{
"id": "geochron",
Expand Down Expand Up @@ -335,7 +335,7 @@
"last_updated": "2026-09-02",
"verified": true,
"screenshot": "",
"latest_version": "1.25.1",
"latest_version": "1.25.2",
"icon": "fas fa-hockey-puck"
},
{
Expand All @@ -359,7 +359,7 @@
"last_updated": "2026-09-02",
"verified": true,
"screenshot": "",
"latest_version": "1.24.1",
"latest_version": "1.24.2",
"icon": "fas fa-baseball-ball"
},
{
Expand Down Expand Up @@ -760,7 +760,7 @@
"last_updated": "2026-09-02",
"verified": true,
"screenshot": "",
"latest_version": "2.24.1"
"latest_version": "2.24.2"
},
{
"id": "static-image",
Expand Down Expand Up @@ -1048,7 +1048,7 @@
"downloads": 0,
"verified": true,
"screenshot": "",
"latest_version": "1.22.1",
"latest_version": "1.22.2",
"last_updated": "2026-09-02"
},
{
Expand Down Expand Up @@ -1095,7 +1095,7 @@
"last_updated": "2026-09-02",
"verified": true,
"screenshot": "",
"latest_version": "1.21.1"
"latest_version": "1.21.2"
},
{
"id": "jellyfin-now-playing",
Expand Down
2 changes: 1 addition & 1 deletion plugins/afl-scoreboard/game_renderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ def _load_fonts(self) -> Dict[str, ImageFont.FreeTypeFont]:
fonts["score"] = self._load_custom_font(score_config, default_size=10, element_key='score_text')
fonts["time"] = self._load_custom_font(period_config, default_size=8, element_key='period_text')
fonts["team"] = self._load_custom_font(team_config, default_size=8, element_key='team_name')
fonts["status"] = self._load_custom_font(status_config, default_size=6, element_key='status_text')
fonts["status"] = self._load_custom_font(status_config, default_size=6, element_key='status_text', default_font='4x6-font.ttf')
fonts["detail"] = self._load_custom_font(detail_config, default_size=6, default_font='4x6-font.ttf', element_key='detail_text')
fonts["odds"] = self._load_custom_font(odds_config, default_size=6, default_font='4x6-font.ttf', element_key='odds_text')
fonts["rank"] = self._load_custom_font(rank_config, default_size=10, element_key='rank_text')
Expand Down
9 changes: 8 additions & 1 deletion plugins/afl-scoreboard/manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "afl-scoreboard",
"name": "AFL Scoreboard",
"version": "1.22.1",
"version": "1.22.2",
"author": "ChuckBuilds",
"description": "Live, recent, and upcoming AFL (Australian Football League) games with real-time scores and game status.",
"category": "sports",
Expand All @@ -18,6 +18,13 @@
"afl_upcoming"
],
"versions": [
{
"version": "1.22.2",
"released": "2026-09-02",
"ledmatrix_min_version": "3.3.0",
"notes": "Render the font the settings page advertises. Each text element's schema names a default font, but several elements never passed it to the loader, so the loader used its own fallback instead: the status text -- and on hockey the detail and odds text too -- advertised the 4x6 font while actually drawing in PressStart2P. Choosing the font the picker already showed as active therefore changed the display, which looked like the picker was broken. Each element now renders what its schema declares. This affects panels 128 pixels wide and narrower, on upcoming screens only; wider panels draw that header in the time font and are unchanged. It also fixes a knock-on problem: \"Next Game\" needed 72px in the wrong font and had to shorten to \"Next\" on a 64px panel, where it now fits whole at 41px.",
"changelog": "Documentation only, no behaviour change. Rewrites the README around real rendered screenshots of the 2026 finals series and documents every configuration option. Writes down the game-selection logic in full: the three selection paths, and that upcoming_games_to_show/recent_games_to_show mean a per-team budget under show_favorite_teams_only but a total otherwise. Records four verified dead ends so they stop costing people time: show_odds is a no-op for AFL because ESPN publishes no odds block for the league (though it still issues one odds request per selected game), show_ranking has no poll to draw, dynamic_duration.min_duration_seconds is never read, and background_service.max_workers is ignored in favour of a single worker. Also corrects README defaults that had drifted from the schema (show_favorite_teams_only, display_duration, show_odds)."
},
{
"version": "1.22.1",
"released": "2026-09-02",
Expand Down
2 changes: 1 addition & 1 deletion plugins/afl-scoreboard/sports.py
Original file line number Diff line number Diff line change
Expand Up @@ -867,7 +867,7 @@ def _load_fonts(self):
fonts["score"] = self._load_custom_font_from_element_config(score_config, default_size=10, element_key='score_text')
fonts["time"] = self._load_custom_font_from_element_config(period_config, default_size=8, element_key='period_text')
fonts["team"] = self._load_custom_font_from_element_config(team_config, default_size=8, element_key='team_name')
fonts["status"] = self._load_custom_font_from_element_config(status_config, default_size=6, element_key='status_text')
fonts["status"] = self._load_custom_font_from_element_config(status_config, default_size=6, element_key='status_text', default_font='4x6-font.ttf')
fonts["detail"] = self._load_custom_font_from_element_config(detail_config, default_size=6, element_key='detail_text', default_font='4x6-font.ttf')
fonts["odds"] = self._load_custom_font_from_element_config(odds_config, default_size=6, element_key='odds_text', default_font='4x6-font.ttf')
fonts["rank"] = self._load_custom_font_from_element_config(rank_config, default_size=10, element_key='rank_text')
Expand Down
2 changes: 1 addition & 1 deletion plugins/baseball-scoreboard/game_renderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ def _load_fonts(self) -> Dict[str, ImageFont.FreeTypeFont]:
fonts["score"] = self._load_custom_font(score_config, default_size=10, element_key='score_text')
fonts["time"] = self._load_custom_font(period_config, default_size=8, element_key='period_text')
fonts["team"] = self._load_custom_font(team_config, default_size=8, element_key='team_name')
fonts["status"] = self._load_custom_font(status_config, default_size=6, element_key='status_text')
fonts["status"] = self._load_custom_font(status_config, default_size=6, element_key='status_text', default_font='PressStart2P-Regular.ttf')
fonts["detail"] = self._load_custom_font(detail_config, default_size=6, default_font='4x6-font.ttf', element_key='detail_text')
fonts["odds"] = self._load_custom_font(odds_config, default_size=6, default_font='4x6-font.ttf', element_key='odds_text')
fonts["rank"] = self._load_custom_font(rank_config, default_size=10, element_key='rank_text')
Expand Down
2 changes: 1 addition & 1 deletion plugins/baseball-scoreboard/sports.py
Original file line number Diff line number Diff line change
Expand Up @@ -809,7 +809,7 @@ def _load_fonts(self):
fonts["score"] = self._load_custom_font_from_element_config(score_config, default_size=10, element_key='score_text')
fonts["time"] = self._load_custom_font_from_element_config(period_config, default_size=8, element_key='period_text')
fonts["team"] = self._load_custom_font_from_element_config(team_config, default_size=8, element_key='team_name')
fonts["status"] = self._load_custom_font_from_element_config(status_config, default_size=6, element_key='status_text')
fonts["status"] = self._load_custom_font_from_element_config(status_config, default_size=6, element_key='status_text', default_font='PressStart2P-Regular.ttf')
fonts["detail"] = self._load_custom_font_from_element_config(detail_config, default_size=6, element_key='detail_text', default_font='4x6-font.ttf')
fonts["odds"] = self._load_custom_font_from_element_config(odds_config, default_size=6, element_key='odds_text', default_font='4x6-font.ttf')
fonts["rank"] = self._load_custom_font_from_element_config(rank_config, default_size=10, element_key='rank_text')
Expand Down
2 changes: 1 addition & 1 deletion plugins/basketball-scoreboard/game_renderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ def _load_fonts(self) -> Dict[str, ImageFont.FreeTypeFont]:
fonts["score"] = self._load_custom_font(score_config, default_size=10, element_key='score_text')
fonts["time"] = self._load_custom_font(period_config, default_size=8, element_key='period_text')
fonts["team"] = self._load_custom_font(team_config, default_size=8, element_key='team_name')
fonts["status"] = self._load_custom_font(status_config, default_size=6, element_key='status_text')
fonts["status"] = self._load_custom_font(status_config, default_size=6, element_key='status_text', default_font='4x6-font.ttf')
fonts["detail"] = self._load_custom_font(detail_config, default_size=6, default_font='4x6-font.ttf', element_key='detail_text')
fonts["odds"] = self._load_custom_font(odds_config, default_size=6, default_font='4x6-font.ttf', element_key='odds_text')
fonts["rank"] = self._load_custom_font(rank_config, default_size=10, element_key='rank_text')
Expand Down
9 changes: 8 additions & 1 deletion plugins/basketball-scoreboard/manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "basketball-scoreboard",
"name": "Basketball Scoreboard",
"version": "1.29.1",
"version": "1.29.2",
"update_interval": 60,
"description": "Live, recent, and upcoming basketball games across NBA, NCAA Men's, NCAA Women's, and WNBA with real-time scores, schedules, and March Madness tournament support",
"author": "ChuckBuilds",
Expand All @@ -19,6 +19,13 @@
"branch": "main",
"plugin_path": "plugins/basketball-scoreboard",
"versions": [
{
"version": "1.29.2",
"released": "2026-09-02",
"ledmatrix_min_version": "3.3.0",
"notes": "Render the font the settings page advertises. Each text element's schema names a default font, but several elements never passed it to the loader, so the loader used its own fallback instead: the status text -- and on hockey the detail and odds text too -- advertised the 4x6 font while actually drawing in PressStart2P. Choosing the font the picker already showed as active therefore changed the display, which looked like the picker was broken. Each element now renders what its schema declares. This affects panels 128 pixels wide and narrower, on upcoming screens only; wider panels draw that header in the time font and are unchanged. It also fixes a knock-on problem: \"Next Game\" needed 72px in the wrong font and had to shorten to \"Next\" on a 64px panel, where it now fits whole at 41px.",
"changelog": "Retry a team logo whose previous download failed, instead of showing a grey box forever. A failed download is cached by the core as a placeholder wearing the real logo's filename; the logo loader scans filename variations, found that stub, and so never called the downloader again. The loader now skips a placeholder that is stale enough to be worth retrying and lets the download run, which also picks up stubs already on disk. The retry is rate-limited by the core (6h), so this does not trade a permanent grey box for a request every frame. Needs a core carrying src.logo_downloader.is_placeholder_logo; against an older core the check is skipped and behaviour is unchanged. Ported byte-identically across every sports lineage."
},
{
"version": "1.29.1",
"released": "2026-09-02",
Expand Down
2 changes: 1 addition & 1 deletion plugins/basketball-scoreboard/sports.py
Original file line number Diff line number Diff line change
Expand Up @@ -670,7 +670,7 @@ def _load_fonts(self):
fonts["score"] = self._load_custom_font_from_element_config(score_config, default_size=10, element_key='score_text')
fonts["time"] = self._load_custom_font_from_element_config(period_config, default_size=8, element_key='period_text')
fonts["team"] = self._load_custom_font_from_element_config(team_config, default_size=8, element_key='team_name')
fonts["status"] = self._load_custom_font_from_element_config(status_config, default_size=6, element_key='status_text')
fonts["status"] = self._load_custom_font_from_element_config(status_config, default_size=6, element_key='status_text', default_font='4x6-font.ttf')
fonts["detail"] = self._load_custom_font_from_element_config(detail_config, default_size=6, default_font='4x6-font.ttf', element_key='detail_text')
fonts["odds"] = self._load_custom_font_from_element_config(odds_config, default_size=6, default_font='4x6-font.ttf', element_key='odds_text')
fonts["rank"] = self._load_custom_font_from_element_config(rank_config, default_size=10, element_key='rank_text')
Expand Down
4 changes: 2 additions & 2 deletions plugins/football-scoreboard/game_renderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,7 @@ def _load_fonts(self) -> Dict[str, Union[ImageFont.FreeTypeFont, Any]]:
fonts["team"] = self._load_custom_font(
team_config, default_size=team_size, element_key='team_name')
fonts["status"] = self._load_custom_font(
status_config, default_size=status_size, element_key='status_text')
status_config, default_size=status_size, element_key='status_text', default_font='4x6-font.ttf')
fonts["detail"] = self._load_custom_font(
detail_config,
default_size=self._detail_font_size(), element_key='detail_text',
Expand Down Expand Up @@ -900,7 +900,7 @@ def render_game_card(
'score': ('PressStart2P-Regular.ttf', 10),
'time': ('PressStart2P-Regular.ttf', 8),
'team': ('PressStart2P-Regular.ttf', 8),
'status': ('PressStart2P-Regular.ttf', 6),
'status': ('4x6-font.ttf', 6),
'detail': ('4x6-font.ttf', 6),
# Same default as detail: odds rendered with the detail font until
# this setting existed, and the default must not change that.
Expand Down
9 changes: 8 additions & 1 deletion plugins/football-scoreboard/manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "football-scoreboard",
"name": "Football Scoreboard",
"version": "3.4.1",
"version": "3.4.2",
"update_interval": 60,
"author": "ChuckBuilds",
"class_name": "FootballScoreboardPlugin",
Expand All @@ -25,6 +25,13 @@
"ncaa_fb_live"
],
"versions": [
{
"version": "3.4.2",
"released": "2026-09-02",
"ledmatrix_min_version": "3.3.0",
"notes": "Render the font the settings page advertises. Each text element's schema names a default font, but several elements never passed it to the loader, so the loader used its own fallback instead: the status text -- and on hockey the detail and odds text too -- advertised the 4x6 font while actually drawing in PressStart2P. Choosing the font the picker already showed as active therefore changed the display, which looked like the picker was broken. Each element now renders what its schema declares. This affects panels 128 pixels wide and narrower, on upcoming screens only; wider panels draw that header in the time font and are unchanged. It also fixes a knock-on problem: \"Next Game\" needed 72px in the wrong font and had to shorten to \"Next\" on a 64px panel, where it now fits whole at 41px.",
"changelog": "Retry a team logo whose previous download failed, instead of showing a grey box forever. A failed download is cached by the core as a placeholder wearing the real logo's filename; the logo loader scans filename variations, found that stub, and so never called the downloader again. The loader now skips a placeholder that is stale enough to be worth retrying and lets the download run, which also picks up stubs already on disk. The retry is rate-limited by the core (6h), so this does not trade a permanent grey box for a request every frame. Needs a core carrying src.logo_downloader.is_placeholder_logo; against an older core the check is skipped and behaviour is unchanged. Ported byte-identically across every sports lineage."
},
{
"version": "3.4.1",
"released": "2026-09-02",
Expand Down
2 changes: 1 addition & 1 deletion plugins/football-scoreboard/sports.py
Original file line number Diff line number Diff line change
Expand Up @@ -821,7 +821,7 @@ def _load_fonts(self):
fonts["score"] = self._load_custom_font_from_element_config(score_config, default_size=10, element_key='score_text')
fonts["time"] = self._load_custom_font_from_element_config(period_config, default_size=8, element_key='period_text')
fonts["team"] = self._load_custom_font_from_element_config(team_config, default_size=8, element_key='team_name')
fonts["status"] = self._load_custom_font_from_element_config(status_config, default_size=6, element_key='status_text')
fonts["status"] = self._load_custom_font_from_element_config(status_config, default_size=6, element_key='status_text', default_font='4x6-font.ttf')
fonts["detail"] = self._load_custom_font_from_element_config(detail_config, default_size=6, element_key='detail_text', default_font='4x6-font.ttf')
fonts["odds"] = self._load_custom_font_from_element_config(odds_config, default_size=6, element_key='odds_text', default_font='4x6-font.ttf')
fonts["rank"] = self._load_custom_font_from_element_config(rank_config, default_size=10, element_key='rank_text')
Expand Down
21 changes: 15 additions & 6 deletions plugins/football-scoreboard/test_fonts_render_crisply.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,13 +123,22 @@ def main():
# Loading "without raising" proves nothing on its own: _load_fonts wraps
# the whole block in try/except and drops to hardcoded emergency defaults,
# which are crisp as well -- so a broken call in the config path is
# invisible unless the two paths can be told apart. They can: the config
# path gives status PressStart2P (the loader's own default face), while
# the emergency fallback hardcodes 4x6-font for it.
status_face = os.path.basename(str(getattr(local.get("status"), "path", "")))
# invisible unless the two paths can be told apart.
#
# The status FACE used to be that discriminator: the config path gave
# PressStart2P (the loader's own fallback face) while the emergency block
# hardcodes 4x6-font. That stopped discriminating when the config path was
# corrected to pass the font its schema declares, which is 4x6-font -- both
# paths now agree on status, so the old check could not tell them apart.
#
# The odds slot replaces it: only the config path builds one. The emergency
# block predates the setting and never gained it, which is safe at runtime
# (_draw_dynamic_odds falls back to fonts["detail"]) and is exactly the
# asymmetry this check needs. If the emergency block ever gains an odds
# entry, pick another: rank is 10px on the config path and 8px here.
check("the no-resolver path used the config loader, not the emergency "
"fallback (status face %s)" % (status_face or "none"),
status_face == "PressStart2P-Regular.ttf")
"fallback (odds slot %s)" % ("present" if "odds" in local else "absent"),
"odds" in local)
for key, font in sorted(local.items()):
size = getattr(font, "size", None)
if size:
Expand Down
Loading
Loading