video-master-adapt/config.py
nickviljoen 891c36bbfb Add standalone desktop application with web interface
Major Features:
- 🖥️ Standalone desktop app (VideoMatcher.app) - double-click to run
- 🎨 Black & gold branded UI (Montserrat font, #FFC407 accent)
- 📁 Local file browser for master/adaptation folders
-  Fast mode processing (10-20x faster, disables AKAZE/AI Vision)
- 🤖 Smart AI Vision fallback (auto-retry when no matches found)
- 📊 Real-time progress bars (fingerprinting & matching)
- 💾 Local processing (no cloud, no authentication)
- 📤 CSV export with master filenames

Web Application (Enterprise):
- 🌐 Flask web app with Azure AD authentication
- 📦 Box.com integration for cloud storage
- 🐳 Docker support for deployment
- 🔐 JWT validation with httpOnly cookies
- 🎯 REST API endpoints

Enhancements:
- Fixed master filename lookup (was showing "Unknown")
- Automatic fingerprint recovery (detects missing files)
- Improved CSV format (master file next to adaptation)
- Port conflict handling (auto-finds available port)
- Environment variable fixes for standalone mode

Documentation:
- Updated README with standalone app section
- Added 10+ guide documents (UI improvements, fingerprint recovery, etc.)
- Build instructions with PyInstaller
- Comprehensive troubleshooting guide

Technical:
- PyInstaller build configuration (video_matcher.spec)
- Launcher with environment setup (launcher.py)
- Mock authentication for standalone mode
- Video matcher service layer
- Metadata parser and AKAZE video matching

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 09:49:04 +02:00

90 lines
3.5 KiB
Python

"""
Configuration module for Video Master Detection web application.
Handles environment-based configuration for development and production.
"""
import os
from dotenv import load_dotenv
load_dotenv()
class Config:
"""Configuration class for Flask application."""
# Flask Core Settings
SECRET_KEY = os.environ.get('SECRET_KEY', 'dev-secret-key-change-in-production')
# Azure AD Authentication (SAME as reference app)
AZURE_TENANT_ID = os.environ.get('AZURE_TENANT_ID', 'e519c2e6-bc6d-4fdf-8d9c-923c2f002385')
AZURE_CLIENT_ID = os.environ.get('AZURE_CLIENT_ID', '9079054c-9620-4757-a256-23413042f1ef')
# Box.com Configuration
BOX_CONFIG_PATH = os.environ.get('BOX_CONFIG_PATH', 'config/box_config.json')
BOX_ROOT_FOLDER_ID = os.environ.get('BOX_ROOT_FOLDER_ID', '') # To be provided
# Video Processing Settings
VIDEO_TEMP_DIR = os.environ.get('VIDEO_TEMP_DIR', 'tmp/video_downloads')
MAX_VIDEOS_PER_JOB = int(os.environ.get('MAX_VIDEOS_PER_JOB', '20'))
# File Size Limits (in bytes)
MAX_FILE_SIZE = int(os.environ.get('MAX_FILE_SIZE', str(2 * 1024 * 1024 * 1024))) # 2GB per file
MAX_JOB_SIZE = int(os.environ.get('MAX_JOB_SIZE', str(10 * 1024 * 1024 * 1024))) # 10GB total per job
WARNING_FILE_SIZE = int(os.environ.get('WARNING_FILE_SIZE', str(500 * 1024 * 1024))) # 500MB warning threshold
MIN_DISK_SPACE_GB = int(os.environ.get('MIN_DISK_SPACE_GB', '10')) # Minimum 10GB free space required
# Video Format Settings
ALLOWED_FORMATS = ['.mp4', '.webm', '.m4v'] # Recommended formats
WARNING_FORMATS = ['.mov', '.avi', '.mkv'] # Large format warning
BLOCKED_FORMATS = ['.mxf', '.ari', '.r3d', '.dpx'] # Raw/uncompressed formats blocked
# Cleanup Settings
CLEANUP_AGE_HOURS = int(os.environ.get('CLEANUP_AGE_HOURS', '24')) # Delete temp files older than 24 hours
AUTO_CLEANUP = os.environ.get('AUTO_CLEANUP', 'true').lower() == 'true' # Automatic cleanup after jobs
# Video Matcher Settings
DATA_DIR = os.environ.get('DATA_DIR', 'data')
ENABLE_AI_VISION = os.environ.get('ENABLE_AI_VISION', 'true').lower() == 'true'
ENABLE_AKAZE = os.environ.get('ENABLE_AKAZE', 'true').lower() == 'true'
ENABLE_METADATA_FILTER = os.environ.get('ENABLE_METADATA_FILTER', 'true').lower() == 'true'
# OpenAI Configuration (for AI Vision matching)
OPENAI_API_KEY = os.environ.get('OPENAI_API_KEY', '')
# Server Configuration
HOST = os.environ.get('HOST', '0.0.0.0')
PORT = int(os.environ.get('PORT', '5000'))
# Logging Configuration
LOG_LEVEL = os.environ.get('LOG_LEVEL', 'INFO')
ACCESS_LOG = os.environ.get('ACCESS_LOG', 'logs/access.log')
ERROR_LOG = os.environ.get('ERROR_LOG', 'logs/error.log')
# Flask Environment
FLASK_ENV = os.environ.get('FLASK_ENV', 'development')
DEBUG = os.environ.get('DEBUG', 'False').lower() == 'true'
class DevelopmentConfig(Config):
"""Development-specific configuration."""
DEBUG = True
PORT = 7183 # Match reference app port for consistency
class ProductionConfig(Config):
"""Production-specific configuration."""
DEBUG = False
# Ensure critical settings are set in production
def __init__(self):
super().__init__()
if self.SECRET_KEY == 'dev-secret-key-change-in-production':
raise ValueError('SECRET_KEY must be set in production environment')
# Configuration dictionary
config = {
'development': DevelopmentConfig,
'production': ProductionConfig,
'default': Config
}