fix: player connectivity and media download pipeline

- nginx: add /api/ shortcut block (no portal auth, X-Script-Name /digiserver,
  Host $http_host) so players can reach DigiServer API without /digiserver prefix
- nginx: use $http_host in /api/ block so Flask host_url includes port — fixes
  media download URLs missing :8080 (was http://ip/digiserver/... not http://ip:8080/...)
- player main.py: fix double-port bug when server_ip already contains a port
  (e.g. 192.168.0.230:8080 was producing http://192.168.0.230:8080:80)
- get_playlists_v2.py: force re-sync when server version differs OR local media
  files are missing on disk — fixes stale playlist after server reset
- digiserver api.py: playlist endpoint builds full media URLs using script_root
  from X-Script-Name header set by nginx
- weblink support, player build/deploy improvements, manage-playlist AJAX prefix fix
This commit is contained in:
ske087
2026-06-29 20:04:11 +03:00
parent f674330b93
commit 4f4e017ad2
16 changed files with 1222 additions and 38 deletions
+43 -4
View File
@@ -1,5 +1,5 @@
"""Players blueprint for player management and display."""
from flask import Blueprint, render_template, request, redirect, url_for, flash, jsonify
from flask import Blueprint, render_template, request, redirect, url_for, flash, jsonify, current_app
from flask_login import login_required
from werkzeug.security import generate_password_hash
import secrets
@@ -115,9 +115,45 @@ def add_player():
try:
from app.utils.background_tasks import background_player_deployment, run_background_task
# Get server URL for player configuration
# Determine the server address the player should contact.
# The player talks to the DigiServer API directly at
# {scheme}://{host}:{port}/api/... (no '/digiserver' path prefix),
# so prefer the address admins set on the "Build player files" page,
# then the configured HTTPS domain/IP, then the umbrella host.
from flask import request as flask_request
server_url = f"{flask_request.scheme}://{flask_request.host}/digiserver"
from app.models.https_config import HTTPSConfig
server_url = None
try:
import os
from app.utils.player_build import get_player_server_settings, BUILD_META_FILENAME
meta_path = os.path.join(current_app.instance_path, BUILD_META_FILENAME)
build_srv = get_player_server_settings(meta_path)
if build_srv:
scheme = 'https' if build_srv['use_https'] else 'http'
server_url = f"{scheme}://{build_srv['server_ip']}:{build_srv['port']}"
except Exception:
server_url = None
if not server_url:
https_cfg = HTTPSConfig.get_config()
if https_cfg and https_cfg.https_enabled and (https_cfg.domain or https_cfg.ip_address):
host = https_cfg.domain or https_cfg.ip_address
cfg_port = https_cfg.port or 443
server_url = f"https://{host}:{cfg_port}"
else:
# Fallback: derive from the current request host, but never
# ship 'localhost'/127.0.0.1 to a remote player — substitute
# this server's real LAN IP so the player can reach it.
host = flask_request.host
hostname_only = host.split(':')[0]
if hostname_only in ('localhost', '127.0.0.1', '') or hostname_only.startswith('127.'):
from app.utils.ssh_deploy import detect_server_ip
detected_ip = detect_server_ip()
if detected_ip:
port_part = host.split(':', 1)[1] if ':' in host else ''
host = f"{detected_ip}:{port_part}" if port_part else detected_ip
server_url = f"{flask_request.scheme}://{host}"
# Generate API key for player authentication
import hashlib
@@ -133,7 +169,10 @@ def add_player():
player_id=new_player.id,
port=ssh_port,
server_url=server_url,
server_api_key=api_key
server_api_key=api_key,
player_hostname=hostname,
quickconnect_code=quickconnect_code,
orientation=orientation
)
deployment_initiated = True
log_action('info', f'Background deployment initiated for player "{name}" on {ssh_hostname}')