updated first commit
This commit is contained in:
324
app/utils/group_management.py
Normal file
324
app/utils/group_management.py
Normal file
@@ -0,0 +1,324 @@
|
||||
"""
|
||||
Group management utilities
|
||||
"""
|
||||
|
||||
from app.extensions import db
|
||||
from app.models.group import Group
|
||||
from app.models.player import Player
|
||||
from app.models.content import Content
|
||||
from app.utils.logger import log_group_created, log_group_edited, log_group_deleted, log_content_reordered
|
||||
|
||||
def create_group(name, player_ids=None, description=None):
|
||||
"""
|
||||
Create a new group
|
||||
|
||||
Args:
|
||||
name (str): Group name
|
||||
player_ids (list): List of player IDs to add to group (optional)
|
||||
description (str): Group description (optional)
|
||||
|
||||
Returns:
|
||||
tuple: (success, group_or_error_message)
|
||||
"""
|
||||
try:
|
||||
# Check if group name already exists
|
||||
if Group.query.filter_by(name=name).first():
|
||||
return False, f"Group with name '{name}' already exists"
|
||||
|
||||
# Create new group
|
||||
group = Group(
|
||||
name=name,
|
||||
description=description or ""
|
||||
)
|
||||
|
||||
# Add players to group
|
||||
if player_ids:
|
||||
players = Player.query.filter(Player.id.in_(player_ids)).all()
|
||||
for player in players:
|
||||
group.players.append(player)
|
||||
|
||||
db.session.add(group)
|
||||
db.session.commit()
|
||||
|
||||
log_group_created(name)
|
||||
return True, group
|
||||
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
return False, str(e)
|
||||
|
||||
def edit_group(group_id, name=None, player_ids=None, description=None):
|
||||
"""
|
||||
Edit an existing group
|
||||
|
||||
Args:
|
||||
group_id (int): Group ID
|
||||
name (str): New group name (optional)
|
||||
player_ids (list): New list of player IDs (optional)
|
||||
description (str): New description (optional)
|
||||
|
||||
Returns:
|
||||
tuple: (success, group_or_error_message)
|
||||
"""
|
||||
try:
|
||||
group = Group.query.get(group_id)
|
||||
if not group:
|
||||
return False, "Group not found"
|
||||
|
||||
# Check for name conflicts
|
||||
if name and name != group.name:
|
||||
existing = Group.query.filter_by(name=name).first()
|
||||
if existing and existing.id != group_id:
|
||||
return False, f"Group with name '{name}' already exists"
|
||||
group.name = name
|
||||
|
||||
# Update description
|
||||
if description is not None:
|
||||
group.description = description
|
||||
|
||||
# Update players
|
||||
if player_ids is not None:
|
||||
# Clear current players
|
||||
group.players.clear()
|
||||
|
||||
# Add new players
|
||||
if player_ids:
|
||||
players = Player.query.filter(Player.id.in_(player_ids)).all()
|
||||
for player in players:
|
||||
group.players.append(player)
|
||||
|
||||
db.session.commit()
|
||||
|
||||
log_group_edited(group.name)
|
||||
return True, group
|
||||
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
return False, str(e)
|
||||
|
||||
def delete_group(group_id):
|
||||
"""
|
||||
Delete a group (players remain, just removed from group)
|
||||
|
||||
Args:
|
||||
group_id (int): Group ID
|
||||
|
||||
Returns:
|
||||
tuple: (success, error_message)
|
||||
"""
|
||||
try:
|
||||
group = Group.query.get(group_id)
|
||||
if not group:
|
||||
return False, "Group not found"
|
||||
|
||||
group_name = group.name
|
||||
|
||||
# Remove all players from group
|
||||
group.players.clear()
|
||||
|
||||
# Delete group
|
||||
db.session.delete(group)
|
||||
db.session.commit()
|
||||
|
||||
log_group_deleted(group_name)
|
||||
return True, None
|
||||
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
return False, str(e)
|
||||
|
||||
def get_group_content(group_id):
|
||||
"""
|
||||
Get all unique content for players in a group
|
||||
|
||||
Args:
|
||||
group_id (int): Group ID
|
||||
|
||||
Returns:
|
||||
list: List of Content objects
|
||||
"""
|
||||
group = Group.query.get(group_id)
|
||||
if not group:
|
||||
return []
|
||||
|
||||
player_ids = [player.id for player in group.players]
|
||||
if not player_ids:
|
||||
return []
|
||||
|
||||
# Get unique content by filename, taking the first occurrence
|
||||
content_query = (
|
||||
db.session.query(
|
||||
Content.file_name,
|
||||
db.func.min(Content.id).label('id'),
|
||||
db.func.min(Content.duration).label('duration'),
|
||||
db.func.min(Content.position).label('position')
|
||||
)
|
||||
.filter(Content.player_id.in_(player_ids))
|
||||
.group_by(Content.file_name)
|
||||
)
|
||||
|
||||
# Get the actual content objects
|
||||
content_ids = [c.id for c in content_query.all()]
|
||||
content = Content.query.filter(Content.id.in_(content_ids)).order_by(Content.position).all()
|
||||
|
||||
return content
|
||||
|
||||
def update_group_content_order(group_id, content_items):
|
||||
"""
|
||||
Update the order of content items for all players in a group
|
||||
|
||||
Args:
|
||||
group_id (int): Group ID
|
||||
content_items (list): List of content items with new positions
|
||||
|
||||
Returns:
|
||||
tuple: (success, error_message)
|
||||
"""
|
||||
try:
|
||||
group = Group.query.get(group_id)
|
||||
if not group:
|
||||
return False, "Group not found"
|
||||
|
||||
player_ids = [player.id for player in group.players]
|
||||
if not player_ids:
|
||||
return True, None # No players in group
|
||||
|
||||
# Update positions for all matching content across all players
|
||||
for i, item in enumerate(content_items):
|
||||
file_name = item.get('file_name')
|
||||
if file_name:
|
||||
Content.query.filter(
|
||||
Content.player_id.in_(player_ids),
|
||||
Content.file_name == file_name
|
||||
).update({Content.position: i})
|
||||
|
||||
# Increment playlist version for all players and group
|
||||
group.increment_playlist_version()
|
||||
db.session.commit()
|
||||
|
||||
log_content_reordered('group', group.name)
|
||||
return True, None
|
||||
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
return False, str(e)
|
||||
|
||||
def add_player_to_group(group_id, player_id):
|
||||
"""
|
||||
Add a player to a group
|
||||
|
||||
Args:
|
||||
group_id (int): Group ID
|
||||
player_id (int): Player ID
|
||||
|
||||
Returns:
|
||||
tuple: (success, error_message)
|
||||
"""
|
||||
try:
|
||||
group = Group.query.get(group_id)
|
||||
player = Player.query.get(player_id)
|
||||
|
||||
if not group:
|
||||
return False, "Group not found"
|
||||
if not player:
|
||||
return False, "Player not found"
|
||||
|
||||
if player not in group.players:
|
||||
group.players.append(player)
|
||||
db.session.commit()
|
||||
|
||||
return True, None
|
||||
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
return False, str(e)
|
||||
|
||||
def remove_player_from_group(group_id, player_id):
|
||||
"""
|
||||
Remove a player from a group
|
||||
|
||||
Args:
|
||||
group_id (int): Group ID
|
||||
player_id (int): Player ID
|
||||
|
||||
Returns:
|
||||
tuple: (success, error_message)
|
||||
"""
|
||||
try:
|
||||
group = Group.query.get(group_id)
|
||||
player = Player.query.get(player_id)
|
||||
|
||||
if not group:
|
||||
return False, "Group not found"
|
||||
if not player:
|
||||
return False, "Player not found"
|
||||
|
||||
if player in group.players:
|
||||
group.players.remove(player)
|
||||
db.session.commit()
|
||||
|
||||
return True, None
|
||||
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
return False, str(e)
|
||||
|
||||
def get_available_players():
|
||||
"""
|
||||
Get all players that are not locked to any group
|
||||
|
||||
Returns:
|
||||
list: List of Player objects
|
||||
"""
|
||||
return Player.query.filter_by(locked_to_group_id=None).all()
|
||||
|
||||
def lock_players_to_group(group_id, player_ids):
|
||||
"""
|
||||
Lock specified players to a group (exclusive membership)
|
||||
|
||||
Args:
|
||||
group_id (int): Group ID
|
||||
player_ids (list): List of player IDs to lock
|
||||
|
||||
Returns:
|
||||
tuple: (success, error_message)
|
||||
"""
|
||||
try:
|
||||
group = Group.query.get(group_id)
|
||||
if not group:
|
||||
return False, "Group not found"
|
||||
|
||||
players = Player.query.filter(Player.id.in_(player_ids)).all()
|
||||
|
||||
for player in players:
|
||||
player.locked_to_group_id = group_id
|
||||
|
||||
db.session.commit()
|
||||
return True, None
|
||||
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
return False, str(e)
|
||||
|
||||
def unlock_players_from_group(group_id):
|
||||
"""
|
||||
Unlock all players from a group
|
||||
|
||||
Args:
|
||||
group_id (int): Group ID
|
||||
|
||||
Returns:
|
||||
tuple: (success, error_message)
|
||||
"""
|
||||
try:
|
||||
players = Player.query.filter_by(locked_to_group_id=group_id).all()
|
||||
|
||||
for player in players:
|
||||
player.locked_to_group_id = None
|
||||
|
||||
db.session.commit()
|
||||
return True, None
|
||||
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
return False, str(e)
|
||||
Reference in New Issue
Block a user