Files
Ske_Signage/app/routes/player.py
2025-07-16 08:03:57 +03:00

168 lines
5.9 KiB
Python

"""
Player management routes
"""
from flask import Blueprint, render_template, request, redirect, url_for, flash, jsonify
from flask_login import login_required, current_user
from app.models.player import Player
from app.models.content import Content
from app.utils.player_management import (
create_player, edit_player, delete_player,
get_player_content, update_player_content_order,
verify_player_credentials
)
from app.routes.admin import admin_required
bp = Blueprint('player', __name__)
@bp.route('/')
@login_required
@admin_required
def index():
"""List all players"""
players = Player.query.order_by(Player.username).all()
return render_template('player/index.html', players=players)
@bp.route('/add', methods=['GET', 'POST'])
@login_required
@admin_required
def add():
"""Add new player"""
if request.method == 'POST':
username = request.form.get('username', '').strip()
hostname = request.form.get('hostname', '').strip()
password = request.form.get('password', '')
quickconnect_password = request.form.get('quickconnect_password', '')
# Validation
if not username or not hostname or not password:
flash('Username, hostname, and password are required.', 'danger')
return render_template('player/add.html')
# Create player
success, result = create_player(
username=username,
hostname=hostname,
password=password,
quickconnect_password=quickconnect_password if quickconnect_password else None
)
if success:
flash(f'Player "{username}" created successfully.', 'success')
return redirect(url_for('player.view', player_id=result.id))
else:
flash(f'Error creating player: {result}', 'danger')
return render_template('player/add.html')
@bp.route('/<int:player_id>')
@login_required
def view(player_id):
"""View player details and content"""
player = Player.query.get_or_404(player_id)
content = get_player_content(player_id)
return render_template('player/view.html', player=player, content=content)
@bp.route('/<int:player_id>/edit', methods=['GET', 'POST'])
@login_required
@admin_required
def edit(player_id):
"""Edit player"""
player = Player.query.get_or_404(player_id)
if request.method == 'POST':
username = request.form.get('username', '').strip()
hostname = request.form.get('hostname', '').strip()
password = request.form.get('password', '')
quickconnect_password = request.form.get('quickconnect_password', '')
# Update player
success, result = edit_player(
player_id=player_id,
username=username if username else None,
hostname=hostname if hostname else None,
password=password if password else None,
quickconnect_password=quickconnect_password if quickconnect_password else None
)
if success:
flash(f'Player "{result.username}" updated successfully.', 'success')
return redirect(url_for('player.view', player_id=player_id))
else:
flash(f'Error updating player: {result}', 'danger')
return_url = request.args.get('return_url', url_for('player.view', player_id=player_id))
return render_template('player/edit.html', player=player, return_url=return_url)
@bp.route('/<int:player_id>/delete', methods=['POST'])
@login_required
@admin_required
def delete(player_id):
"""Delete player"""
player = Player.query.get_or_404(player_id)
username = player.username
success, error = delete_player(player_id)
if success:
flash(f'Player "{username}" deleted successfully.', 'success')
else:
flash(f'Error deleting player: {error}', 'danger')
return redirect(url_for('dashboard.index'))
@bp.route('/<int:player_id>/fullscreen', methods=['GET', 'POST'])
def fullscreen(player_id):
"""Player fullscreen view with authentication"""
player = Player.query.get_or_404(player_id)
if request.method == 'POST':
hostname = request.form.get('hostname', '')
password = request.form.get('password', '')
quickconnect_code = request.form.get('quickconnect_password', '')
# Verify credentials
if quickconnect_code:
success, result = verify_player_credentials(hostname, None, quickconnect_code)
else:
success, result = verify_player_credentials(hostname, password)
if success and result.id == player_id:
authenticated = True
else:
authenticated = False
flash('Invalid credentials.', 'danger')
else:
authenticated = current_user.is_authenticated
if authenticated:
content = get_player_content(player_id)
return render_template('player/fullscreen.html', player=player, content=content)
else:
return render_template('player/auth.html', player=player)
@bp.route('/<int:player_id>/update_order', methods=['POST'])
@login_required
def update_order(player_id):
"""Update content order for player"""
if not request.is_json:
return jsonify({'success': False, 'error': 'Invalid request format'}), 400
player = Player.query.get_or_404(player_id)
# Check if player is locked to a group (only admin can reorder)
if player.is_locked_to_group and not current_user.is_admin:
return jsonify({
'success': False,
'error': 'Cannot reorder playlist for players locked to groups'
}), 403
items = request.json.get('items', [])
success, error, new_version = update_player_content_order(player_id, items)
if success:
return jsonify({'success': True, 'new_version': new_version})
else:
return jsonify({'success': False, 'error': error}), 500