From e85bebee124afef99fcf98f09c7199e6f5b84969 Mon Sep 17 00:00:00 2001
From: Chuck <33324927+ChuckBuilds@users.noreply.github.com>
Date: Thu, 24 Jul 2025 15:04:17 -0500
Subject: [PATCH] adjust music artist and album font programatically. Web ui
now includes all settings
---
src/music_manager.py | 2 +-
templates/index.html | 708 ++++++++++++++++++++++++++++++++++++++++++-
web_interface.py | 2 +
3 files changed, 700 insertions(+), 12 deletions(-)
diff --git a/src/music_manager.py b/src/music_manager.py
index e90b4d14..e353e7c7 100644
--- a/src/music_manager.py
+++ b/src/music_manager.py
@@ -775,7 +775,7 @@ class MusicManager:
self.title_scroll_tick = 0
# --- Artist ---
- y_pos_artist = y_pos_title + line_height_title + padding_between_lines - 5
+ y_pos_artist = y_pos_title + line_height_title + padding_between_lines
artist_width = self.display_manager.get_text_width(artist, font_artist_album)
current_artist_display_text = artist
if artist_width > text_area_width:
diff --git a/templates/index.html b/templates/index.html
index c2ae23a9..84e891b6 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -489,6 +489,71 @@
GPIO slowdown factor (0-5)
+
+
+
+
+
+
+
+
+
@@ -547,6 +612,170 @@
How long to show word of the day
+
+
+
+
+
+
+
+
@@ -654,6 +883,76 @@
Only display games involving your favorite teams
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1161,6 +1524,12 @@
How often to update weather data (300-3600 seconds)
+
+
@@ -1202,6 +1571,35 @@
How often to update stock data
+
+
+
+
+
+
+
+
@@ -1237,6 +1635,23 @@
How often to update crypto data
+
+
+
+
@@ -1316,6 +1731,30 @@
How often to update stock news
+
+
+
+
+
+
+
+
@@ -1342,6 +1781,99 @@
How often to update odds
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1400,6 +1932,53 @@
Custom text to display on the LED matrix
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1521,6 +2121,18 @@
Comma-separated calendar names
+
+
+
+
@@ -2187,11 +2799,20 @@
chain_length: parseInt(formData.get('chain_length')),
parallel: parseInt(formData.get('parallel')),
brightness: parseInt(formData.get('brightness')),
- hardware_mapping: formData.get('hardware_mapping')
+ hardware_mapping: formData.get('hardware_mapping'),
+ scan_mode: parseInt(formData.get('scan_mode')),
+ pwm_bits: parseInt(formData.get('pwm_bits')),
+ pwm_dither_bits: parseInt(formData.get('pwm_dither_bits')),
+ pwm_lsb_nanoseconds: parseInt(formData.get('pwm_lsb_nanoseconds')),
+ disable_hardware_pulsing: formData.get('disable_hardware_pulsing') === 'on',
+ inverse_colors: formData.get('inverse_colors') === 'on',
+ show_refresh_rate: formData.get('show_refresh_rate') === 'on',
+ limit_refresh_rate_hz: parseInt(formData.get('limit_refresh_rate_hz'))
},
runtime: {
gpio_slowdown: parseInt(formData.get('gpio_slowdown'))
- }
+ },
+ use_short_date_format: formData.get('use_short_date_format') === 'on'
}
};
@@ -2227,7 +2848,8 @@
weather: {
enabled: formData.get('weather_enabled') === 'on',
units: formData.get('weather_units'),
- update_interval: parseInt(formData.get('weather_update_interval'))
+ update_interval: parseInt(formData.get('weather_update_interval')),
+ display_format: formData.get('weather_display_format')
},
location: {
city: formData.get('weather_city'),
@@ -2268,7 +2890,11 @@
stocks: {
enabled: formData.get('stocks_enabled') === 'on',
symbols: symbols,
- update_interval: parseInt(formData.get('stocks_update_interval'))
+ update_interval: parseInt(formData.get('stocks_update_interval')),
+ scroll_speed: parseInt(formData.get('stocks_scroll_speed')),
+ scroll_delay: parseFloat(formData.get('stocks_scroll_delay')),
+ toggle_chart: formData.get('stocks_toggle_chart') === 'on',
+ display_format: formData.get('stocks_display_format')
}
};
@@ -2305,7 +2931,9 @@
crypto: {
enabled: formData.get('crypto_enabled') === 'on',
symbols: symbols,
- update_interval: parseInt(formData.get('crypto_update_interval'))
+ update_interval: parseInt(formData.get('crypto_update_interval')),
+ display_format: formData.get('crypto_display_format'),
+ toggle_chart: formData.get('crypto_toggle_chart') === 'on'
}
};
@@ -2380,7 +3008,9 @@
enabled: formData.get('calendar_enabled') === 'on',
max_events: parseInt(formData.get('calendar_max_events')),
update_interval: parseInt(formData.get('calendar_update_interval')),
- calendars: calendars
+ calendars: calendars,
+ credentials_file: formData.get('calendar_credentials_file'),
+ token_file: formData.get('calendar_token_file')
}
};
@@ -2465,7 +3095,38 @@
calendar: parseInt(formData.get('calendar_duration')),
youtube: parseInt(formData.get('youtube_duration')),
text_display: parseInt(formData.get('text_display_duration')),
- of_the_day: parseInt(formData.get('of_the_day_duration'))
+ of_the_day: parseInt(formData.get('of_the_day_duration')),
+ hourly_forecast: parseInt(formData.get('hourly_forecast_duration')),
+ daily_forecast: parseInt(formData.get('daily_forecast_duration')),
+ stock_news: parseInt(formData.get('stock_news_duration')),
+ odds_ticker: parseInt(formData.get('odds_ticker_duration')),
+ nhl_live: parseInt(formData.get('nhl_live_duration')),
+ nhl_recent: parseInt(formData.get('nhl_recent_duration')),
+ nhl_upcoming: parseInt(formData.get('nhl_upcoming_duration')),
+ nba_live: parseInt(formData.get('nba_live_duration')),
+ nba_recent: parseInt(formData.get('nba_recent_duration')),
+ nba_upcoming: parseInt(formData.get('nba_upcoming_duration')),
+ nfl_live: parseInt(formData.get('nfl_live_duration')),
+ nfl_recent: parseInt(formData.get('nfl_recent_duration')),
+ nfl_upcoming: parseInt(formData.get('nfl_upcoming_duration')),
+ ncaa_fb_live: parseInt(formData.get('ncaa_fb_live_duration')),
+ ncaa_fb_recent: parseInt(formData.get('ncaa_fb_recent_duration')),
+ ncaa_fb_upcoming: parseInt(formData.get('ncaa_fb_upcoming_duration')),
+ ncaa_baseball_live: parseInt(formData.get('ncaa_baseball_live_duration')),
+ ncaa_baseball_recent: parseInt(formData.get('ncaa_baseball_recent_duration')),
+ ncaa_baseball_upcoming: parseInt(formData.get('ncaa_baseball_upcoming_duration')),
+ mlb_live: parseInt(formData.get('mlb_live_duration')),
+ mlb_recent: parseInt(formData.get('mlb_recent_duration')),
+ mlb_upcoming: parseInt(formData.get('mlb_upcoming_duration')),
+ milb_live: parseInt(formData.get('milb_live_duration')),
+ milb_recent: parseInt(formData.get('milb_recent_duration')),
+ milb_upcoming: parseInt(formData.get('milb_upcoming_duration')),
+ soccer_live: parseInt(formData.get('soccer_live_duration')),
+ soccer_recent: parseInt(formData.get('soccer_recent_duration')),
+ soccer_upcoming: parseInt(formData.get('soccer_upcoming_duration')),
+ ncaam_basketball_live: parseInt(formData.get('ncaam_basketball_live_duration')),
+ ncaam_basketball_recent: parseInt(formData.get('ncaam_basketball_recent_duration')),
+ ncaam_basketball_upcoming: parseInt(formData.get('ncaam_basketball_upcoming_duration'))
}
}
};
@@ -2574,7 +3235,11 @@
const config = {
stock_news: {
enabled: formData.get('stock_news_enabled') === 'on',
- update_interval: parseInt(formData.get('stock_news_update_interval'))
+ update_interval: parseInt(formData.get('stock_news_update_interval')),
+ scroll_speed: parseInt(formData.get('stock_news_scroll_speed')),
+ scroll_delay: parseFloat(formData.get('stock_news_scroll_delay')),
+ max_headlines_per_symbol: parseInt(formData.get('stock_news_max_headlines_per_symbol')),
+ headlines_per_rotation: parseInt(formData.get('stock_news_headlines_per_rotation'))
}
};
@@ -2609,7 +3274,18 @@
const config = {
odds_ticker: {
enabled: formData.get('odds_ticker_enabled') === 'on',
- update_interval: parseInt(formData.get('odds_ticker_update_interval'))
+ update_interval: parseInt(formData.get('odds_ticker_update_interval')),
+ show_favorite_teams_only: formData.get('odds_ticker_show_favorite_teams_only') === 'on',
+ games_per_favorite_team: parseInt(formData.get('odds_ticker_games_per_favorite_team')),
+ max_games_per_league: parseInt(formData.get('odds_ticker_max_games_per_league')),
+ show_odds_only: formData.get('odds_ticker_show_odds_only') === 'on',
+ sort_order: formData.get('odds_ticker_sort_order'),
+ enabled_leagues: formData.get('odds_ticker_enabled_leagues').split(',').map(s => s.trim()).filter(s => s),
+ scroll_speed: parseInt(formData.get('odds_ticker_scroll_speed')),
+ scroll_delay: parseFloat(formData.get('odds_ticker_scroll_delay')),
+ loop: formData.get('odds_ticker_loop') === 'on',
+ future_fetch_days: parseInt(formData.get('odds_ticker_future_fetch_days')),
+ show_channel_logos: formData.get('odds_ticker_show_channel_logos') === 'on'
}
};
@@ -2680,7 +3356,14 @@
const config = {
text_display: {
enabled: formData.get('text_display_enabled') === 'on',
- text: formData.get('text_display_text')
+ text: formData.get('text_display_text'),
+ font_path: formData.get('text_display_font_path'),
+ font_size: parseInt(formData.get('text_display_font_size')),
+ scroll: formData.get('text_display_scroll') === 'on',
+ scroll_speed: parseInt(formData.get('text_display_scroll_speed')),
+ text_color: formData.get('text_display_text_color').split(',').map(s => parseInt(s.trim())),
+ background_color: formData.get('text_display_background_color').split(',').map(s => parseInt(s.trim())),
+ scroll_gap_width: parseInt(formData.get('text_display_scroll_gap_width'))
},
display: {
display_durations: {
@@ -2720,7 +3403,10 @@
const config = {
of_the_day: {
enabled: formData.get('of_the_day_enabled') === 'on',
- update_interval: parseInt(formData.get('of_the_day_update_interval'))
+ update_interval: parseInt(formData.get('of_the_day_update_interval')),
+ display_rotate_interval: parseInt(formData.get('of_the_day_display_rotate_interval')),
+ subtitle_rotate_interval: parseInt(formData.get('of_the_day_subtitle_rotate_interval')),
+ category_order: formData.get('of_the_day_category_order').split(',').map(s => s.trim()).filter(s => s)
}
};
diff --git a/web_interface.py b/web_interface.py
index 760282a8..2a51e688 100644
--- a/web_interface.py
+++ b/web_interface.py
@@ -95,6 +95,7 @@ def save_config_route():
symbols = request.form.get('stocks_symbols', '').split(',')
main_config['stocks']['symbols'] = [s.strip() for s in symbols if s.strip()]
main_config['stocks']['update_interval'] = int(request.form.get('stocks_update_interval', 600))
+ main_config['stocks']['toggle_chart'] = 'stocks_toggle_chart' in request.form
# Update crypto settings
if 'crypto_enabled' in request.form:
@@ -102,6 +103,7 @@ def save_config_route():
symbols = request.form.get('crypto_symbols', '').split(',')
main_config['crypto']['symbols'] = [s.strip() for s in symbols if s.strip()]
main_config['crypto']['update_interval'] = int(request.form.get('crypto_update_interval', 600))
+ main_config['crypto']['toggle_chart'] = 'crypto_toggle_chart' in request.form
# Update music settings
if 'music_enabled' in request.form: