Models (6 + 1 association table): - User: Authentication with bcrypt, admin role check, last_login tracking - Player: Digital signage devices with auth codes, status tracking, online detection - Group: Player/content organization with statistics properties - Content: Media files with type detection, file size helpers, position ordering - ServerLog: Audit trail with class methods for logging levels - PlayerFeedback: Player status updates with error tracking - group_content: Many-to-many association table for groups and content Model improvements: - Added type hints to all methods and properties - Added database indexes on frequently queried columns (username, auth_code, group_id, player_id, position, level, timestamp, status) - Added comprehensive docstrings - Added helper properties (is_online, is_admin, file_size_mb, etc.) - Added relationship back_populates for bidirectional navigation - Added timestamps (created_at, updated_at, last_seen, uploaded_at) Utils (4 modules): - logger.py: Logging utility with level-based functions (info, warning, error) - uploads.py: File upload handling with progress tracking, video optimization - group_player_management.py: Player/group status tracking and bulk operations - pptx_converter.py: PowerPoint to PDF conversion using LibreOffice Utils improvements: - Full type hints on all functions - Comprehensive error handling - Progress tracking for long-running operations - Video optimization (H.264, 30fps, max 1080p, 8Mbps) - Helper functions for time formatting and statistics - Proper logging of all operations Performance optimizations: - Database indexes on all foreign keys and frequently filtered columns - Lazy loading for relationships where appropriate - Efficient queries with proper ordering - Helper properties to avoid repeated calculations Ready for template migration and testing
65 lines
2.3 KiB
Python
65 lines
2.3 KiB
Python
"""Player feedback model for tracking player status and errors."""
|
|
from datetime import datetime
|
|
from typing import Optional
|
|
|
|
from app.extensions import db
|
|
|
|
|
|
class PlayerFeedback(db.Model):
|
|
"""Player feedback model for tracking player status updates.
|
|
|
|
Attributes:
|
|
id: Primary key
|
|
player_id: Foreign key to player
|
|
status: Current status (playing, paused, error, unknown)
|
|
current_content_id: ID of currently playing content
|
|
message: Optional status message
|
|
error: Optional error message
|
|
timestamp: Feedback timestamp
|
|
"""
|
|
__tablename__ = 'player_feedback'
|
|
|
|
id = db.Column(db.Integer, primary_key=True)
|
|
player_id = db.Column(db.Integer, db.ForeignKey('player.id'),
|
|
nullable=False, index=True)
|
|
status = db.Column(db.String(50), nullable=False, default='unknown')
|
|
current_content_id = db.Column(db.Integer, db.ForeignKey('content.id'),
|
|
nullable=True)
|
|
message = db.Column(db.Text, nullable=True)
|
|
error = db.Column(db.Text, nullable=True)
|
|
timestamp = db.Column(db.DateTime, default=datetime.utcnow,
|
|
nullable=False, index=True)
|
|
|
|
# Relationships
|
|
player = db.relationship('Player', back_populates='feedback')
|
|
content = db.relationship('Content', backref='feedback_entries')
|
|
|
|
def __repr__(self) -> str:
|
|
"""String representation of PlayerFeedback."""
|
|
return f'<PlayerFeedback Player={self.player_id} Status={self.status}>'
|
|
|
|
@property
|
|
def is_error(self) -> bool:
|
|
"""Check if feedback indicates an error."""
|
|
return self.status == 'error' or self.error is not None
|
|
|
|
@property
|
|
def age_seconds(self) -> float:
|
|
"""Get age of feedback in seconds."""
|
|
delta = datetime.utcnow() - self.timestamp
|
|
return delta.total_seconds()
|
|
|
|
@classmethod
|
|
def get_latest_for_player(cls, player_id: int) -> Optional['PlayerFeedback']:
|
|
"""Get most recent feedback for a player.
|
|
|
|
Args:
|
|
player_id: Player ID to query
|
|
|
|
Returns:
|
|
Latest PlayerFeedback instance or None
|
|
"""
|
|
return cls.query.filter_by(player_id=player_id)\
|
|
.order_by(cls.timestamp.desc())\
|
|
.first()
|