Update app

This commit is contained in:
2026-01-25 12:03:08 +01:00
parent 4df004c18a
commit a5fe0f73a0
10 changed files with 611 additions and 54 deletions

View File

@@ -18,7 +18,7 @@ from ..uploads import (
get_company_upload_bytes,
is_valid_upload_relpath,
)
from ..models import AppSettings, Company, Display, DisplaySession, Playlist, PlaylistItem, User
from ..models import AppSettings, Company, Display, DisplayPlaylist, DisplaySession, Playlist, PlaylistItem, User
from ..email_utils import send_email
from ..auth_tokens import make_password_reset_token
@@ -343,7 +343,13 @@ def dashboard():
company_user_required()
playlists = Playlist.query.filter_by(company_id=current_user.company_id).order_by(Playlist.name.asc()).all()
displays = Display.query.filter_by(company_id=current_user.company_id).order_by(Display.name.asc()).all()
return render_template("company/dashboard.html", playlists=playlists, displays=displays)
playlists_json = [{"id": p.id, "name": p.name} for p in playlists]
return render_template(
"company/dashboard.html",
playlists=playlists,
playlists_json=playlists_json,
displays=displays,
)
@bp.post("/playlists")
@@ -412,6 +418,15 @@ def delete_playlist(playlist_id: int):
{"assigned_playlist_id": None}
)
# Remove from any display multi-playlist mappings in this company.
# Use a subquery to avoid a JOIN-based DELETE which is not supported on SQLite.
display_ids = [d.id for d in Display.query.filter_by(company_id=current_user.company_id).all()]
if display_ids:
DisplayPlaylist.query.filter(
DisplayPlaylist.display_id.in_(display_ids),
DisplayPlaylist.playlist_id == playlist.id,
).delete(synchronize_session=False)
# cleanup uploaded files for image/video items
for it in list(playlist.items):
if it.item_type in ("image", "video"):
@@ -900,3 +915,87 @@ def update_display(display_id: int):
flash("Display updated", "success")
return redirect(url_for("company.dashboard"))
@bp.post("/displays/<int:display_id>/playlists")
@login_required
def update_display_playlists(display_id: int):
"""Set active playlists for a display.
Expects JSON: { playlist_ids: [1,2,3] }
Returns JSON with the updated assigned playlist ids.
Note: if playlist_ids is empty, the display will have no active playlists.
For backwards compatibility, this does NOT modify Display.assigned_playlist_id.
"""
company_user_required()
display = db.session.get(Display, display_id)
if not display or display.company_id != current_user.company_id:
abort(404)
if not request.is_json:
abort(400)
payload = request.get_json(silent=True) or {}
raw_ids = payload.get("playlist_ids")
if raw_ids is None:
return jsonify({"ok": False, "error": "playlist_ids is required"}), 400
if not isinstance(raw_ids, list):
return jsonify({"ok": False, "error": "playlist_ids must be a list"}), 400
playlist_ids: list[int] = []
try:
for x in raw_ids:
if x in (None, ""):
continue
playlist_ids.append(int(x))
except (TypeError, ValueError):
return jsonify({"ok": False, "error": "Invalid playlist id"}), 400
# Ensure playlists belong to this company.
if playlist_ids:
allowed = {
p.id
for p in Playlist.query.filter(
Playlist.company_id == current_user.company_id,
Playlist.id.in_(playlist_ids),
).all()
}
if len(allowed) != len(set(playlist_ids)):
return jsonify({"ok": False, "error": "One or more playlists are invalid"}), 400
# Replace mapping rows.
DisplayPlaylist.query.filter_by(display_id=display.id).delete(synchronize_session=False)
now = datetime.utcnow()
for pos, pid in enumerate(dict.fromkeys(playlist_ids), start=1):
db.session.add(
DisplayPlaylist(
display_id=display.id,
playlist_id=pid,
position=pos,
created_at=now,
)
)
db.session.commit()
active_ids = [
r[0]
for r in db.session.query(DisplayPlaylist.playlist_id)
.filter(DisplayPlaylist.display_id == display.id)
.order_by(DisplayPlaylist.position.asc(), DisplayPlaylist.playlist_id.asc())
.all()
]
return jsonify(
{
"ok": True,
"display": {
"id": display.id,
"active_playlist_ids": active_ids,
},
}
)