223 lines
6.4 KiB
Python
223 lines
6.4 KiB
Python
"""
|
|
Player management utilities
|
|
"""
|
|
|
|
from app.extensions import db, bcrypt
|
|
from app.models.player import Player
|
|
from app.models.content import Content
|
|
from app.utils.logger import log_player_created, log_player_edited, log_player_deleted, log_content_reordered
|
|
|
|
def create_player(username, hostname, password, quickconnect_password=None):
|
|
"""
|
|
Create a new player
|
|
|
|
Args:
|
|
username (str): Player username
|
|
hostname (str): Player hostname
|
|
password (str): Player password
|
|
quickconnect_password (str): Quick connect password (optional)
|
|
|
|
Returns:
|
|
tuple: (success, player_or_error_message)
|
|
"""
|
|
try:
|
|
# Check if hostname already exists
|
|
if Player.query.filter_by(hostname=hostname).first():
|
|
return False, f"Player with hostname '{hostname}' already exists"
|
|
|
|
# Create new player
|
|
player = Player(
|
|
username=username,
|
|
hostname=hostname
|
|
)
|
|
|
|
# Set passwords
|
|
player.set_password(password)
|
|
if quickconnect_password:
|
|
player.set_quickconnect_password(quickconnect_password)
|
|
|
|
db.session.add(player)
|
|
db.session.commit()
|
|
|
|
log_player_created(username, hostname)
|
|
return True, player
|
|
|
|
except Exception as e:
|
|
db.session.rollback()
|
|
return False, str(e)
|
|
|
|
def edit_player(player_id, username=None, hostname=None, password=None, quickconnect_password=None):
|
|
"""
|
|
Edit an existing player
|
|
|
|
Args:
|
|
player_id (int): Player ID
|
|
username (str): New username (optional)
|
|
hostname (str): New hostname (optional)
|
|
password (str): New password (optional)
|
|
quickconnect_password (str): New quick connect password (optional)
|
|
|
|
Returns:
|
|
tuple: (success, player_or_error_message)
|
|
"""
|
|
try:
|
|
player = Player.query.get(player_id)
|
|
if not player:
|
|
return False, "Player not found"
|
|
|
|
# Check for hostname conflicts
|
|
if hostname and hostname != player.hostname:
|
|
existing = Player.query.filter_by(hostname=hostname).first()
|
|
if existing and existing.id != player_id:
|
|
return False, f"Player with hostname '{hostname}' already exists"
|
|
player.hostname = hostname
|
|
|
|
# Update fields
|
|
if username:
|
|
player.username = username
|
|
|
|
if password:
|
|
player.set_password(password)
|
|
|
|
if quickconnect_password:
|
|
player.set_quickconnect_password(quickconnect_password)
|
|
|
|
db.session.commit()
|
|
|
|
log_player_edited(player.username)
|
|
return True, player
|
|
|
|
except Exception as e:
|
|
db.session.rollback()
|
|
return False, str(e)
|
|
|
|
def delete_player(player_id):
|
|
"""
|
|
Delete a player and all its content
|
|
|
|
Args:
|
|
player_id (int): Player ID
|
|
|
|
Returns:
|
|
tuple: (success, error_message)
|
|
"""
|
|
try:
|
|
player = Player.query.get(player_id)
|
|
if not player:
|
|
return False, "Player not found"
|
|
|
|
username = player.username
|
|
|
|
# Delete all content files
|
|
import os
|
|
from flask import current_app
|
|
|
|
upload_folder = os.path.join(current_app.static_folder, 'uploads')
|
|
for content in player.content:
|
|
file_path = os.path.join(upload_folder, content.file_name)
|
|
if os.path.exists(file_path):
|
|
try:
|
|
os.remove(file_path)
|
|
except:
|
|
pass # File might be used by other content
|
|
|
|
# Remove from groups
|
|
for group in player.groups:
|
|
group.players.remove(player)
|
|
|
|
# Delete player (cascades to content)
|
|
db.session.delete(player)
|
|
db.session.commit()
|
|
|
|
log_player_deleted(username)
|
|
return True, None
|
|
|
|
except Exception as e:
|
|
db.session.rollback()
|
|
return False, str(e)
|
|
|
|
def get_player_content(player_id):
|
|
"""
|
|
Get all content for a player ordered by position
|
|
|
|
Args:
|
|
player_id (int): Player ID
|
|
|
|
Returns:
|
|
list: List of Content objects
|
|
"""
|
|
return Content.query.filter_by(player_id=player_id).order_by(Content.position).all()
|
|
|
|
def update_player_content_order(player_id, content_items):
|
|
"""
|
|
Update the order of content items for a player
|
|
|
|
Args:
|
|
player_id (int): Player ID
|
|
content_items (list): List of content items with new positions
|
|
|
|
Returns:
|
|
tuple: (success, error_message, new_playlist_version)
|
|
"""
|
|
try:
|
|
player = Player.query.get(player_id)
|
|
if not player:
|
|
return False, "Player not found", None
|
|
|
|
# Update positions
|
|
for i, item in enumerate(content_items):
|
|
content_id = item.get('id')
|
|
content = Content.query.filter_by(id=content_id, player_id=player_id).first()
|
|
if content:
|
|
content.position = i
|
|
|
|
# Increment playlist version
|
|
player.increment_playlist_version()
|
|
db.session.commit()
|
|
|
|
log_content_reordered('player', player.username)
|
|
return True, None, player.playlist_version
|
|
|
|
except Exception as e:
|
|
db.session.rollback()
|
|
return False, str(e), None
|
|
|
|
def get_player_by_hostname(hostname):
|
|
"""
|
|
Get player by hostname
|
|
|
|
Args:
|
|
hostname (str): Player hostname
|
|
|
|
Returns:
|
|
Player: Player object or None
|
|
"""
|
|
return Player.query.filter_by(hostname=hostname).first()
|
|
|
|
def verify_player_credentials(hostname, password, quickconnect_code=None):
|
|
"""
|
|
Verify player credentials
|
|
|
|
Args:
|
|
hostname (str): Player hostname
|
|
password (str): Player password
|
|
quickconnect_code (str): Quick connect code (optional)
|
|
|
|
Returns:
|
|
tuple: (success, player_or_error_message)
|
|
"""
|
|
player = get_player_by_hostname(hostname)
|
|
if not player:
|
|
return False, "Player not found"
|
|
|
|
if quickconnect_code:
|
|
if player.verify_quickconnect_code(quickconnect_code):
|
|
return True, player
|
|
else:
|
|
return False, "Invalid quick connect code"
|
|
else:
|
|
if player.check_password(password):
|
|
return True, player
|
|
else:
|
|
return False, "Invalid password"
|