Landscape orientation, redesigned web UI, rotation on/off + minutes, weather by city name
- Panel is mounted sideways: render landscape (600x400), rotate to the panel's native portrait orientation right before writing to hardware. - Web UI: card-based layout, dark mode, active nav highlighting, save confirmation toasts, error banners. - Rotation: separate enabled/disabled toggle (off pins to the first screen in the list) and the interval is now in minutes instead of raw seconds. Migrates existing config.json from the old interval_seconds field. - Weather: type a city name instead of hunting down coordinates, resolved via Open-Meteo's free geocoding API. Manual lat/long still available as a fallback.
This commit is contained in:
1 parent
7c197e20a5
commit
61348be674
11 files changed
+393
-104
No files matched your search
+34
-12
@@ -1,5 +1,6 @@
|
||||
"""Flask app: status/preview page + one settings form per screen + rotation settings."""
|
||||
|
||||
import requests
|
||||
from flask import Flask, redirect, render_template, request, url_for
|
||||
|
||||
|
||||
@@ -42,30 +43,51 @@ def create_app(config, screens: dict, scheduler) -> Flask:
|
||||
"boost_cover": "boost_cover" in request.form,
|
||||
"grayscale_cover": "grayscale_cover" in request.form,
|
||||
})
|
||||
return redirect(url_for("settings_navidrome"))
|
||||
return redirect(url_for("settings_navidrome", saved=1))
|
||||
return render_template("settings_navidrome.html", settings=config.get_screen_settings("navidrome"))
|
||||
|
||||
@app.route("/settings/weather", methods=["GET", "POST"])
|
||||
def settings_weather():
|
||||
error = None
|
||||
if request.method == "POST":
|
||||
lat = request.form.get("latitude", "").strip()
|
||||
lon = request.form.get("longitude", "").strip()
|
||||
config.update_screen_settings("weather", {
|
||||
"latitude": float(lat) if lat else None,
|
||||
"longitude": float(lon) if lon else None,
|
||||
})
|
||||
return redirect(url_for("settings_weather"))
|
||||
return render_template("settings_weather.html", settings=config.get_screen_settings("weather"))
|
||||
city = request.form.get("city", "").strip()
|
||||
lat_raw = request.form.get("latitude", "").strip()
|
||||
lon_raw = request.form.get("longitude", "").strip()
|
||||
|
||||
if city:
|
||||
try:
|
||||
result = screens["weather"].geocode(city)
|
||||
except requests.exceptions.RequestException:
|
||||
result = None
|
||||
if result is None:
|
||||
error = f'Could not find "{city}" -- try a different spelling, or fill in coordinates manually below instead.'
|
||||
else:
|
||||
config.update_screen_settings("weather", {
|
||||
"city": result["label"],
|
||||
"latitude": result["latitude"],
|
||||
"longitude": result["longitude"],
|
||||
})
|
||||
return redirect(url_for("settings_weather", saved=1))
|
||||
else:
|
||||
config.update_screen_settings("weather", {
|
||||
"city": "",
|
||||
"latitude": float(lat_raw) if lat_raw else None,
|
||||
"longitude": float(lon_raw) if lon_raw else None,
|
||||
})
|
||||
return redirect(url_for("settings_weather", saved=1))
|
||||
|
||||
return render_template("settings_weather.html", settings=config.get_screen_settings("weather"), error=error)
|
||||
|
||||
@app.route("/settings/rotation", methods=["GET", "POST"])
|
||||
def settings_rotation():
|
||||
if request.method == "POST":
|
||||
raw = request.form.get("screens", "")
|
||||
selected = [s.strip() for s in raw.split(",") if s.strip() in screens]
|
||||
interval = int(request.form.get("interval_seconds", 300) or 300)
|
||||
config.set_rotation(selected, interval)
|
||||
interval_minutes = int(request.form.get("interval_minutes", 5) or 5)
|
||||
enabled = "rotation_enabled" in request.form
|
||||
config.set_rotation(selected, interval_minutes, enabled)
|
||||
config.set_navidrome_priority("navidrome_priority" in request.form)
|
||||
return redirect(url_for("settings_rotation"))
|
||||
return redirect(url_for("settings_rotation", saved=1))
|
||||
return render_template(
|
||||
"settings_rotation.html",
|
||||
screens=screens,
|
||||
|
||||
Reference in new issue
Block a user