Version 3 mit URL und Newsticker
Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
123
app.py
123
app.py
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user