Files
Web-Line-Radio/config.py
2026-03-02 09:48:49 -05:00

118 lines
4.7 KiB
Python

#!/usr/bin/env python3
"""
Configuration Management for Chat Server
Supports both environment variables and .env files
"""
import os
from typing import Optional, Any, cast
from pathlib import Path
try:
from dotenv import load_dotenv # type: ignore
load_dotenv(override=True)
DOTENV_AVAILABLE = True
except ImportError:
DOTENV_AVAILABLE = False
class Config:
"""Configuration class with environment variable support"""
# Server Configuration
HOST: str = os.getenv('HOST', '127.0.0.1')
PORT: int = int(os.getenv('PORT', '8765'))
MAX_HISTORY: int = int(os.getenv('MAX_HISTORY', '100'))
# Admin Configuration
ADMIN_PASSWORD: str = os.getenv('ADMIN_PASSWORD', '') # Should be set in environment
# SSL Configuration
USE_SSL: bool = os.getenv('USE_SSL', 'false').lower() == 'true'
SSL_CERT_PATH: Optional[str] = os.getenv('SSL_CERT_PATH')
SSL_KEY_PATH: Optional[str] = os.getenv('SSL_KEY_PATH')
# Database Configuration
DB_PATH: str = os.getenv('DB_PATH', 'data/chat.db')
# Logging Configuration
LOG_LEVEL: str = os.getenv('LOG_LEVEL', 'INFO')
LOG_FILE: Optional[str] = os.getenv('LOG_FILE', 'logs/chat_server.log')
# Security Configuration
MAX_MESSAGE_LENGTH: int = int(os.getenv('MAX_MESSAGE_LENGTH', '4096'))
MAX_NICKNAME_LENGTH: int = int(os.getenv('MAX_NICKNAME_LENGTH', '32'))
RATE_LIMIT_MESSAGES: int = int(os.getenv('RATE_LIMIT_MESSAGES', '120'))
RATE_LIMIT_WINDOW: int = int(os.getenv('RATE_LIMIT_WINDOW', '60'))
# Session Configuration
SESSION_TIMEOUT: int = int(os.getenv('SESSION_TIMEOUT', '3600'))
KEEPALIVE_INTERVAL: int = int(os.getenv('KEEPALIVE_INTERVAL', '30'))
RECONNECT_TIMEOUT: int = int(os.getenv('RECONNECT_TIMEOUT', '300'))
# Backup Configuration
BACKUP_DIR: str = os.getenv('BACKUP_DIR', './backups')
AUTO_BACKUP_ENABLED: bool = os.getenv('AUTO_BACKUP_ENABLED', 'false').lower() == 'true'
AUTO_BACKUP_INTERVAL: int = int(os.getenv('AUTO_BACKUP_INTERVAL', '86400')) # 24 hours
# Room Configuration
ROOM_EXPIRATION_HOURS: int = int(os.getenv('ROOM_EXPIRATION_HOURS', '24'))
AUTO_HISTORY_CLEAR: bool = os.getenv('AUTO_HISTORY_CLEAR', 'false').lower() == 'true'
@classmethod
def validate(cls) -> bool:
"""Validate configuration"""
errors = []
# Validate port range
if not (1 <= cls.PORT <= 65535):
errors.append(f"Invalid PORT: {cls.PORT}. Must be between 1-65535")
# Validate SSL configuration
if cls.USE_SSL:
if not cls.SSL_CERT_PATH or not cls.SSL_KEY_PATH:
errors.append("SSL enabled but SSL_CERT_PATH or SSL_KEY_PATH not set")
elif not Path(cast(str, cls.SSL_CERT_PATH)).exists():
errors.append(f"SSL certificate not found: {cls.SSL_CERT_PATH}")
elif not Path(cast(str, cls.SSL_KEY_PATH)).exists():
errors.append(f"SSL key not found: {cls.SSL_KEY_PATH}")
# Validate positive integers
if cls.MAX_HISTORY < 1:
errors.append(f"MAX_HISTORY must be positive, got {cls.MAX_HISTORY}")
if cls.MAX_MESSAGE_LENGTH < 1:
errors.append(f"MAX_MESSAGE_LENGTH must be positive, got {cls.MAX_MESSAGE_LENGTH}")
if cls.MAX_NICKNAME_LENGTH < 1:
errors.append(f"MAX_NICKNAME_LENGTH must be positive, got {cls.MAX_NICKNAME_LENGTH}")
# Print errors
if errors:
print("[ERROR] Configuration errors:")
for error in errors:
print(f" - {error}")
return False
return True
@classmethod
def display(cls):
"""Display current configuration"""
print("\n" + "=" * 70)
print("CHAT SERVER CONFIGURATION")
print("=" * 70)
print(f"Server: {cls.HOST}:{cls.PORT}")
print(f"SSL: {'Enabled' if cls.USE_SSL else 'Disabled'}")
print(f"Database: {cls.DB_PATH}")
print(f"Log Level: {cls.LOG_LEVEL}")
print(f"Log File: {cls.LOG_FILE or 'Console only'}")
print(f"Max History: {cls.MAX_HISTORY} messages")
print(f"Rate Limit: {cls.RATE_LIMIT_MESSAGES} msg/{cls.RATE_LIMIT_WINDOW}s")
print(f"Auto Backup: {'Enabled' if cls.AUTO_BACKUP_ENABLED else 'Disabled'}")
print("=" * 70 + "\n")
# Validate configuration on import
if __name__ != "__main__":
if not Config.validate():
raise ValueError("Invalid configuration. Please check your environment variables or .env file")