168 lines
5.9 KiB
Python
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
|