from models import Player, Group, Content from extensions import db from utils.logger import log_group_created, log_group_edited, log_group_deleted from utils.logger import log_player_created, log_player_edited, log_player_deleted def create_group(name, player_ids): """ Create a new group with the given name and add selected players to it. Clears individual playlists of players and locks them to the group. """ new_group = Group(name=name) db.session.add(new_group) db.session.flush() # Get the group ID # Add players to the group and lock them for player_id in player_ids: player = Player.query.get(player_id) if player: # Add player to group new_group.players.append(player) # Delete player's individual playlist Content.query.filter_by(player_id=player.id).delete() # Lock player to this group player.locked_to_group_id = new_group.id db.session.commit() log_group_created(name) return new_group def edit_group(group_id, name, player_ids): """ Edit an existing group, updating its name and players. Handles locking/unlocking players appropriately. """ group = Group.query.get_or_404(group_id) group.name = name # Get current players in the group current_player_ids = [player.id for player in group.players] # Determine players to add and remove players_to_add = [pid for pid in player_ids if pid not in current_player_ids] players_to_remove = [pid for pid in current_player_ids if pid not in player_ids] # Handle players to add for player_id in players_to_add: player = Player.query.get(player_id) if player: # Add to group group.players.append(player) # Delete individual playlist Content.query.filter_by(player_id=player.id).delete() # Lock to group player.locked_to_group_id = group.id # Handle players to remove for player_id in players_to_remove: player = Player.query.get(player_id) if player: # Remove from group group.players.remove(player) # Unlock from group player.locked_to_group_id = None db.session.commit() log_group_edited(group.name) return group def delete_group(group_id): """ Delete a group and unlock all associated players. """ group = Group.query.get_or_404(group_id) group_name = group.name # Unlock all players in the group for player in group.players: player.locked_to_group_id = None db.session.delete(group) db.session.commit() log_group_deleted(group_name) def add_player(username, hostname, password, quickconnect_password): """ Add a new player with the given details. """ from flask_bcrypt import Bcrypt bcrypt = Bcrypt() hashed_password = bcrypt.generate_password_hash(password).decode('utf-8') hashed_quickconnect = bcrypt.generate_password_hash(quickconnect_password).decode('utf-8') new_player = Player( username=username, hostname=hostname, password=hashed_password, quickconnect_password=hashed_quickconnect ) db.session.add(new_player) db.session.commit() log_player_created(username, hostname) return new_player def edit_player(player_id, username, hostname, password=None, quickconnect_password=None): """ Edit an existing player's details. """ from flask_bcrypt import Bcrypt bcrypt = Bcrypt() player = Player.query.get_or_404(player_id) player.username = username player.hostname = hostname if password: player.password = bcrypt.generate_password_hash(password).decode('utf-8') if quickconnect_password: player.quickconnect_password = bcrypt.generate_password_hash(quickconnect_password).decode('utf-8') db.session.commit() log_player_edited(username) return player def delete_player(player_id): """ Delete a player and all its content. """ player = Player.query.get_or_404(player_id) username = player.username # Delete all media related to the player Content.query.filter_by(player_id=player_id).delete() # Delete the player db.session.delete(player) db.session.commit() log_player_deleted(username) def get_group_content(group_id): """ Get unique content for a group. """ group = Group.query.get_or_404(group_id) # Get unique media files for the group content = ( db.session.query(Content.id, Content.file_name, db.func.min(Content.duration).label('duration')) .filter(Content.player_id.in_([player.id for player in group.players])) .group_by(Content.file_name) .all() ) return content