Initial commit: DigiServer v2 with Blueprint Architecture
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
This commit is contained in:
123
app/config.py
Normal file
123
app/config.py
Normal file
@@ -0,0 +1,123 @@
|
||||
"""
|
||||
Configuration settings for DigiServer v2
|
||||
Environment-based configuration with sensible defaults
|
||||
"""
|
||||
import os
|
||||
from datetime import timedelta
|
||||
|
||||
|
||||
class Config:
|
||||
"""Base configuration"""
|
||||
|
||||
# Basic Flask config
|
||||
SECRET_KEY = os.getenv('SECRET_KEY', 'dev-secret-key-change-in-production')
|
||||
|
||||
# Database
|
||||
SQLALCHEMY_TRACK_MODIFICATIONS = False
|
||||
SQLALCHEMY_ECHO = False
|
||||
|
||||
# File Upload
|
||||
MAX_CONTENT_LENGTH = 2048 * 1024 * 1024 # 2GB
|
||||
UPLOAD_FOLDER = 'static/uploads'
|
||||
UPLOAD_FOLDERLOGO = 'static/resurse'
|
||||
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif', 'bmp', 'mp4', 'avi', 'mkv', 'mov', 'webm', 'pdf', 'ppt', 'pptx'}
|
||||
|
||||
# Session
|
||||
PERMANENT_SESSION_LIFETIME = timedelta(minutes=30)
|
||||
SESSION_COOKIE_SECURE = False # Set to True in production with HTTPS
|
||||
SESSION_COOKIE_HTTPONLY = True
|
||||
SESSION_COOKIE_SAMESITE = 'Lax'
|
||||
|
||||
# Cache
|
||||
SEND_FILE_MAX_AGE_DEFAULT = 300 # 5 minutes for static files
|
||||
|
||||
# Server Info
|
||||
SERVER_VERSION = "2.0.0"
|
||||
BUILD_DATE = "2025-11-12"
|
||||
|
||||
# Pagination
|
||||
ITEMS_PER_PAGE = 20
|
||||
|
||||
# Admin defaults
|
||||
DEFAULT_ADMIN_USER = os.getenv('ADMIN_USER', 'admin')
|
||||
DEFAULT_ADMIN_PASSWORD = os.getenv('ADMIN_PASSWORD', 'Initial01!')
|
||||
|
||||
|
||||
class DevelopmentConfig(Config):
|
||||
"""Development configuration"""
|
||||
|
||||
DEBUG = True
|
||||
TESTING = False
|
||||
|
||||
# Database
|
||||
SQLALCHEMY_DATABASE_URI = os.getenv(
|
||||
'DATABASE_URL',
|
||||
'sqlite:///instance/dev.db'
|
||||
)
|
||||
|
||||
# Cache (simple in-memory for development)
|
||||
CACHE_TYPE = 'simple'
|
||||
CACHE_DEFAULT_TIMEOUT = 60
|
||||
|
||||
# Security (relaxed for development)
|
||||
WTF_CSRF_ENABLED = True
|
||||
WTF_CSRF_TIME_LIMIT = None
|
||||
|
||||
|
||||
class ProductionConfig(Config):
|
||||
"""Production configuration"""
|
||||
|
||||
DEBUG = False
|
||||
TESTING = False
|
||||
|
||||
# Database
|
||||
SQLALCHEMY_DATABASE_URI = os.getenv(
|
||||
'DATABASE_URL',
|
||||
'sqlite:///instance/dashboard.db'
|
||||
)
|
||||
|
||||
# Redis Cache
|
||||
CACHE_TYPE = 'redis'
|
||||
CACHE_REDIS_HOST = os.getenv('REDIS_HOST', 'redis')
|
||||
CACHE_REDIS_PORT = int(os.getenv('REDIS_PORT', 6379))
|
||||
CACHE_REDIS_DB = 0
|
||||
CACHE_DEFAULT_TIMEOUT = 300
|
||||
|
||||
# Security
|
||||
SESSION_COOKIE_SECURE = True
|
||||
WTF_CSRF_ENABLED = True
|
||||
|
||||
# Rate Limiting
|
||||
RATELIMIT_STORAGE_URL = f"redis://{os.getenv('REDIS_HOST', 'redis')}:6379/1"
|
||||
|
||||
|
||||
class TestingConfig(Config):
|
||||
"""Testing configuration"""
|
||||
|
||||
DEBUG = True
|
||||
TESTING = True
|
||||
|
||||
# Database (in-memory for tests)
|
||||
SQLALCHEMY_DATABASE_URI = 'sqlite:///:memory:'
|
||||
|
||||
# Cache (simple for tests)
|
||||
CACHE_TYPE = 'simple'
|
||||
|
||||
# Security (disabled for tests)
|
||||
WTF_CSRF_ENABLED = False
|
||||
|
||||
|
||||
# Configuration dictionary
|
||||
config = {
|
||||
'development': DevelopmentConfig,
|
||||
'production': ProductionConfig,
|
||||
'testing': TestingConfig,
|
||||
'default': DevelopmentConfig
|
||||
}
|
||||
|
||||
|
||||
def get_config(env=None):
|
||||
"""Get configuration based on environment"""
|
||||
if env is None:
|
||||
env = os.getenv('FLASK_ENV', 'development')
|
||||
return config.get(env, config['default'])
|
||||
Reference in New Issue
Block a user