46602f1933
Remove dead code identified in docs/SANITIZATION-REVIEW.md:
- app/blueprints/content_old.py and app/blueprints/playlist.py
- app/models/group.py, app/utils/nginx_config_reader.py
- orphaned templates (content_list, edit_content, upload_content,
player_page) and the related group/Template references
Result: 6 blueprints, 82 routes, no dead modules or orphan templates.
Add files that deploy.sh and docker-entrypoint.sh already require but
which were never tracked:
- https_manager.py (referenced by deploy.sh, migrate_network.sh,
docker-entrypoint.sh)
- Caddyfile.example (seeded by deploy.sh; its absence aborts deploy)
Relocate generated Graphify artifacts from graphify-out/ to
docs/graphify-out/ (110 files, no content change) and archive the
superseded docs under docs/.
Ignore hygiene:
- ignore ad-hoc .env backups (.env.bak*) — they contain live secrets
- keep the pre-sanitization snapshots (docs/legacy code/,
docs/old_code_documentation/) on disk but out of the repo
Fix .env.example: drop a duplicated config block, genericize the
hardcoded host IP, and document HOSTNAME_INTERNAL.
77 lines
2.2 KiB
Python
77 lines
2.2 KiB
Python
"""Player status utilities.
|
|
|
|
Note: the group-management helpers that used to live here were removed along
|
|
with the deprecated Group subsystem (the ``group`` table had no rows and the
|
|
``/api/groups`` endpoint had already been archived).
|
|
"""
|
|
from typing import Dict
|
|
from datetime import datetime
|
|
|
|
from app.models import Player, PlayerFeedback
|
|
|
|
|
|
def get_player_status_info(player_id: int) -> Dict:
|
|
"""Get comprehensive status information for a player.
|
|
|
|
Args:
|
|
player_id: Player ID to query
|
|
|
|
Returns:
|
|
Dictionary with status information
|
|
"""
|
|
player = Player.query.get(player_id)
|
|
|
|
if not player:
|
|
return {
|
|
'online': False,
|
|
'status': 'unknown',
|
|
'last_seen': None,
|
|
'latest_feedback': None
|
|
}
|
|
|
|
# Check if player is online (seen in last 5 minutes)
|
|
is_online = False
|
|
if player.last_seen:
|
|
delta = datetime.utcnow() - player.last_seen
|
|
is_online = delta.total_seconds() < 300
|
|
|
|
# Get latest feedback
|
|
latest_feedback = PlayerFeedback.query.filter_by(player_id=player_id)\
|
|
.order_by(PlayerFeedback.timestamp.desc())\
|
|
.first()
|
|
|
|
return {
|
|
'online': is_online,
|
|
'status': player.status,
|
|
'last_seen': player.last_seen.isoformat() if player.last_seen else None,
|
|
'last_seen_ago': _format_time_ago(player.last_seen) if player.last_seen else 'Never',
|
|
'latest_feedback': {
|
|
'status': latest_feedback.status,
|
|
'message': latest_feedback.message,
|
|
'error': latest_feedback.error,
|
|
'timestamp': latest_feedback.timestamp.isoformat()
|
|
} if latest_feedback else None
|
|
}
|
|
|
|
|
|
def _format_time_ago(dt: datetime) -> str:
|
|
"""Format datetime as 'time ago' string.
|
|
|
|
Args:
|
|
dt: Datetime to format
|
|
|
|
Returns:
|
|
Formatted string like '5 minutes ago'
|
|
"""
|
|
delta = datetime.utcnow() - dt
|
|
seconds = delta.total_seconds()
|
|
|
|
if seconds < 60:
|
|
return f'{int(seconds)} seconds ago'
|
|
elif seconds < 3600:
|
|
return f'{int(seconds / 60)} minutes ago'
|
|
elif seconds < 86400:
|
|
return f'{int(seconds / 3600)} hours ago'
|
|
else:
|
|
return f'{int(seconds / 86400)} days ago'
|