Initial import
This commit is contained in:
@@ -15,6 +15,16 @@ MAX_ACTIVE_SESSIONS_PER_DISPLAY = 3
|
||||
SESSION_TTL_SECONDS = 90
|
||||
|
||||
|
||||
def _is_playlist_active_now(p: Playlist, now_utc: datetime) -> bool:
|
||||
"""Return True if playlist is active based on its optional schedule window."""
|
||||
|
||||
if p.schedule_start and now_utc < p.schedule_start:
|
||||
return False
|
||||
if p.schedule_end and now_utc > p.schedule_end:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def _enforce_and_touch_display_session(display: Display, sid: str | None):
|
||||
"""Enforce concurrent display viewer limit and touch last_seen.
|
||||
|
||||
@@ -103,6 +113,18 @@ def _playlist_signature(display: Display) -> tuple[int | None, str]:
|
||||
raw = "no-playlist"
|
||||
return None, hashlib.sha1(raw.encode("utf-8")).hexdigest()
|
||||
|
||||
# Apply scheduling + priority rule so a schedule change triggers a player refresh.
|
||||
playlists = Playlist.query.filter(Playlist.id.in_(active_ids)).all()
|
||||
now_utc = datetime.utcnow()
|
||||
scheduled = [p for p in playlists if _is_playlist_active_now(p, now_utc)]
|
||||
if any(p.is_priority for p in scheduled):
|
||||
scheduled = [p for p in scheduled if p.is_priority]
|
||||
active_ids = [x for x in active_ids if any(p.id == x for p in scheduled)]
|
||||
|
||||
if not active_ids:
|
||||
raw = "no-active-playlist"
|
||||
return None, hashlib.sha1(raw.encode("utf-8")).hexdigest()
|
||||
|
||||
# Pull items in a stable order so reordering affects signature.
|
||||
if use_mapping:
|
||||
items = (
|
||||
@@ -174,11 +196,30 @@ def display_playlist(token: str):
|
||||
use_mapping = False
|
||||
|
||||
if not active_ids:
|
||||
return jsonify({"display": display.name, "playlists": [], "items": []})
|
||||
return jsonify(
|
||||
{
|
||||
"display": display.name,
|
||||
"transition": display.transition or "none",
|
||||
"playlists": [],
|
||||
"items": [],
|
||||
}
|
||||
)
|
||||
|
||||
playlists = Playlist.query.filter(Playlist.id.in_(active_ids)).all()
|
||||
pl_by_id = {p.id: p for p in playlists}
|
||||
ordered_playlists = [pl_by_id[x] for x in active_ids if x in pl_by_id]
|
||||
|
||||
# Filter playlists by schedule
|
||||
now_utc = datetime.utcnow()
|
||||
scheduled = [p for p in playlists if _is_playlist_active_now(p, now_utc)]
|
||||
|
||||
# Priority rule:
|
||||
# If any active (scheduled) playlist is marked priority, only play priority playlists.
|
||||
any_priority = any(p.is_priority for p in scheduled)
|
||||
if any_priority:
|
||||
scheduled = [p for p in scheduled if p.is_priority]
|
||||
|
||||
pl_by_id = {p.id: p for p in scheduled}
|
||||
scheduled_ids = [x for x in active_ids if x in pl_by_id]
|
||||
ordered_playlists = [pl_by_id[x] for x in scheduled_ids]
|
||||
|
||||
# Merge items across active playlists.
|
||||
if use_mapping:
|
||||
@@ -186,17 +227,21 @@ def display_playlist(token: str):
|
||||
PlaylistItem.query.join(DisplayPlaylist, DisplayPlaylist.playlist_id == PlaylistItem.playlist_id)
|
||||
.filter(
|
||||
DisplayPlaylist.display_id == display.id,
|
||||
PlaylistItem.playlist_id.in_(active_ids),
|
||||
PlaylistItem.playlist_id.in_(scheduled_ids),
|
||||
)
|
||||
.order_by(DisplayPlaylist.position.asc(), PlaylistItem.position.asc())
|
||||
.all()
|
||||
)
|
||||
else:
|
||||
merged = (
|
||||
PlaylistItem.query.filter(PlaylistItem.playlist_id == active_ids[0])
|
||||
.order_by(PlaylistItem.position.asc())
|
||||
.all()
|
||||
)
|
||||
# single-playlist fallback; apply schedule filter too.
|
||||
if scheduled_ids:
|
||||
merged = (
|
||||
PlaylistItem.query.filter(PlaylistItem.playlist_id == scheduled_ids[0])
|
||||
.order_by(PlaylistItem.position.asc())
|
||||
.all()
|
||||
)
|
||||
else:
|
||||
merged = []
|
||||
|
||||
items = []
|
||||
for item in merged:
|
||||
@@ -217,6 +262,7 @@ def display_playlist(token: str):
|
||||
return jsonify(
|
||||
{
|
||||
"display": display.name,
|
||||
"transition": display.transition or "none",
|
||||
"playlists": [{"id": p.id, "name": p.name} for p in ordered_playlists],
|
||||
"items": items,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user