Features implemented: - Application factory pattern with environment-based config - 7 modular blueprints (main, auth, admin, players, groups, content, api) - Flask-Caching with Redis support for production - Flask-Login authentication with bcrypt password hashing - API endpoints with rate limiting and Bearer token auth - Comprehensive error handling and logging - CLI commands (init-db, create-admin, seed-db) Blueprint Structure: - main: Dashboard with caching, health check endpoint - auth: Login, register, logout, password change - admin: User management, system settings, theme, logo upload - players: Full CRUD, fullscreen view, bulk operations, playlist management - groups: Group management, player assignments, content management - content: Upload with progress tracking, file management, preview/download - api: RESTful endpoints with authentication, rate limiting, player feedback Performance Optimizations: - Dashboard caching (60s timeout) - Playlist caching (5min timeout) - Redis caching for production - Memoized functions for expensive operations - Cache clearing on data changes Security Features: - Bcrypt password hashing - Flask-Login session management - admin_required decorator for authorization - Player authentication via auth codes - API Bearer token authentication - Rate limiting on API endpoints (60 req/min default) - Input validation and sanitization Documentation: - README.md: Full project documentation with quick start - PROGRESS.md: Detailed progress tracking and roadmap - BLUEPRINT_GUIDE.md: Quick reference for blueprint architecture Pending work: - Models migration from v1 with database indexes - Utils migration from v1 with type hints - Templates migration with updated route references - Docker multi-stage build configuration - Unit tests for all blueprints Ready for models and utils migration from digiserver v1
64 lines
1.6 KiB
Python
64 lines
1.6 KiB
Python
"""
|
|
Main Blueprint - Dashboard and Home Routes
|
|
"""
|
|
from flask import Blueprint, render_template, redirect, url_for
|
|
from flask_login import login_required, current_user
|
|
from extensions import db, cache
|
|
from models.player import Player
|
|
from models.group import Group
|
|
from utils.logger import get_recent_logs
|
|
|
|
main_bp = Blueprint('main', __name__)
|
|
|
|
|
|
@main_bp.route('/')
|
|
@login_required
|
|
@cache.cached(timeout=60, unless=lambda: current_user.role != 'viewer')
|
|
def dashboard():
|
|
"""Main dashboard page"""
|
|
players = Player.query.all()
|
|
groups = Group.query.all()
|
|
server_logs = get_recent_logs(20)
|
|
|
|
return render_template(
|
|
'dashboard.html',
|
|
players=players,
|
|
groups=groups,
|
|
server_logs=server_logs
|
|
)
|
|
|
|
|
|
@main_bp.route('/health')
|
|
def health():
|
|
"""Health check endpoint"""
|
|
from flask import jsonify
|
|
import os
|
|
|
|
try:
|
|
# Check database
|
|
db.session.execute(db.text('SELECT 1'))
|
|
|
|
# Check disk space
|
|
upload_folder = os.path.join(
|
|
main_bp.root_path or '.',
|
|
'static/uploads'
|
|
)
|
|
|
|
if os.path.exists(upload_folder):
|
|
stat = os.statvfs(upload_folder)
|
|
free_space_gb = (stat.f_bavail * stat.f_frsize) / (1024**3)
|
|
else:
|
|
free_space_gb = 0
|
|
|
|
return jsonify({
|
|
'status': 'healthy',
|
|
'database': 'ok',
|
|
'disk_space_gb': round(free_space_gb, 2)
|
|
}), 200
|
|
|
|
except Exception as e:
|
|
return jsonify({
|
|
'status': 'unhealthy',
|
|
'error': str(e)
|
|
}), 500
|