Version 3 mit URL und Newsticker

Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
Erik Thiele
2026-04-25 19:26:35 +02:00
parent 5ac9dee8fc
commit 742f993a73
5 changed files with 373 additions and 74 deletions

123
app.py
View File

@@ -23,7 +23,7 @@ BASE_DIR = os.path.dirname(os.path.abspath(__file__))
MEDIA_DIR = os.path.join(BASE_DIR, "media")
CONFIG_FILE = os.path.join(BASE_DIR, "config.json")
APP_VERSION = "2.1.0"
APP_VERSION = "3.1.0"
UPLOAD_EXTENSIONS = {".jpg", ".jpeg", ".png", ".mp4"}
app = Flask(__name__)
@@ -48,6 +48,14 @@ def save_config(cfg):
os.fsync(f.fileno())
print("✅ config.json gespeichert")
def is_url(value):
return (
isinstance(value, str)
and value.lower().startswith(("http://", "https://"))
)
# -------------------------------------------------
# Auth / Benutzer
# -------------------------------------------------
@@ -64,6 +72,7 @@ def load_user(user_id):
@app.route("/login", methods=["GET", "POST"])
def login():
config = load_config()
error = None
if request.method == "POST":
if (
@@ -72,8 +81,9 @@ def login():
):
login_user(Admin())
return redirect("/admin")
error = "Ungültige Zugangsdaten"
return render_template("login.html")
return render_template("login.html", error=error)
@app.route("/logout")
def logout():
@@ -124,13 +134,23 @@ def player(screen):
# 1. Playlist-Reihenfolge
for name in playlist:
if is_url(name):
normal_files.append({"kind": "url", "url": name})
continue
if os.path.exists(os.path.join(folder, name)) and allowed_file(name):
normal_files.append(name)
normal_files.append({"kind": "file", "name": name})
existing_file_names = {
item["name"] for item in normal_files if item["kind"] == "file"
}
# 2. Neue Dateien hintendran
for f in sorted(os.listdir(folder)):
if f not in normal_files and allowed_file(f):
normal_files.append(f)
if f in existing_file_names or f.startswith("._"):
continue
if allowed_file(f):
normal_files.append({"kind": "file", "name": f})
# ------------------------------
# Priority-Playlist (global)
@@ -139,7 +159,15 @@ def player(screen):
priority_cfg = config.get("priority", {})
if priority_cfg.get("enabled", False):
prio_files = priority_cfg.get("playlist", [])
prio_files = []
for name in priority_cfg.get("playlist", []):
if is_url(name):
prio_files.append({"kind": "url", "url": name})
continue
file_path = os.path.join(MEDIA_DIR, "priority", name)
if os.path.exists(file_path):
prio_files.append({"kind": "file", "name": name})
else:
prio_files = []
@@ -148,7 +176,9 @@ def player(screen):
screen=screen,
normal_files=normal_files, # ✅ explizit
prio_files=prio_files, # ✅ IMMER Liste
interval=screen_cfg.get("interval", 10)
interval=screen_cfg.get("interval", 10),
newsticker_text=screen_cfg.get("newsticker_text", ""),
newsticker_enabled=screen_cfg.get("newsticker_enabled", False)
)
@@ -193,10 +223,26 @@ def admin():
continue
files = []
playlist = cfg["screens"][screen].get("playlist", [])
screen_cfg = cfg.setdefault("screens", {}).setdefault(screen, {
"interval": 10,
"show_images": True,
"show_videos": True,
"playlist": []
})
playlist = screen_cfg.get("playlist", [])
screen_cfg["newsticker_text"] = screen_cfg.get("newsticker_text", "")
screen_cfg["newsticker_enabled"] = screen_cfg.get("newsticker_enabled", False)
# 1⃣ Playlist-Reihenfolge
for name in playlist:
if is_url(name):
files.append({
"name": name,
"type": "url",
"size": "URL"
})
continue
file_path = os.path.join(path, name)
if not os.path.exists(file_path):
continue
@@ -227,7 +273,7 @@ def admin():
"size": size
})
screens[screen] = cfg["screens"][screen]
screens[screen] = screen_cfg
media_files[screen] = files
screen_status[screen] = "active" if files else "empty"
@@ -241,7 +287,15 @@ def admin():
# 1⃣ Playlist-Reihenfolge
for name in prio_playlist:
file_path = os.path.join(MEDIA_DIR, "priority")
if is_url(name):
priority_files.append({
"name": name,
"type": "url",
"size": "URL"
})
continue
file_path = os.path.join(prio_dir, name)
if not os.path.exists(file_path):
continue
@@ -291,11 +345,18 @@ def admin():
@login_required
def update_screen(screen):
config = load_config()
cfg = config["screens"][screen]
cfg = config.setdefault("screens", {}).setdefault(screen, {
"interval": 10,
"show_images": True,
"show_videos": True,
"playlist": []
})
cfg["interval"] = int(request.form.get("interval", 10))
cfg["show_images"] = "show_images" in request.form
cfg["show_videos"] = "show_videos" in request.form
cfg["newsticker_text"] = request.form.get("newsticker_text", "")
cfg["newsticker_enabled"] = "newsticker_enabled" in request.form
save_config(config)
return redirect("/admin")
@@ -319,11 +380,38 @@ def upload(screen):
return redirect("/admin")
# -------------------------------------------------
# Admin: URL hinzufügen
# -------------------------------------------------
@app.route("/admin/add-url/<screen>", methods=["POST"])
@login_required
def add_url(screen):
url = request.form.get("url", "").strip()
if not is_url(url):
return redirect("/admin")
config = load_config()
if screen == "priority":
config.setdefault("priority", {}).setdefault("playlist", []).append(url)
else:
screen_cfg = config.setdefault("screens", {}).setdefault(screen, {
"interval": 10,
"show_images": True,
"show_videos": True,
"playlist": []
})
screen_cfg.setdefault("playlist", []).append(url)
save_config(config)
return redirect("/admin")
# -------------------------------------------------
# Admin: Datei löschen
# -------------------------------------------------
@app.route("/admin/delete/<screen>/<filename>", methods=["POST"])
@app.route("/admin/delete/<screen>/<path:filename>", methods=["POST"])
@login_required
def delete_file(screen, filename):
cfg = load_config()
@@ -358,9 +446,18 @@ def save_playlist(screen):
data = request.get_json()
if screen == "priority":
cfg.setdefault("priority", {}).setdefault("playlist", [])
cfg["priority"]["playlist"] = data["playlist"]
else:
cfg["screens"][screen]["playlist"] = data["playlist"]
screen_cfg = cfg.setdefault("screens", {}).setdefault(screen, {
"interval": 10,
"show_images": True,
"show_videos": True,
"playlist": [],
"newsticker_text": "",
"newsticker_enabled": False
})
screen_cfg["playlist"] = data["playlist"]
save_config(cfg)
return "", 204