diff --git a/.env.example b/.env.example index 78ce602..7916a30 100644 --- a/.env.example +++ b/.env.example @@ -1,28 +1,142 @@ -# NFOGuard Environment Variables +# =========================================== +# NFOGuard Configuration - CORRECTED VERSION +# =========================================== +# Main configuration file - safe to share for debugging +# Sensitive data (API keys, passwords) are in .env.secrets -# User and Group IDs -PUID=1000 -PGID=1000 +# =========================================== +# MEDIA PATHS (REQUIRED) - FIXED +# =========================================== +# Container paths (what NFOGuard sees inside container) +MOVIE_PATHS=/media/Movies/movies,/media/Movies/movies6 +TV_PATHS=/media/TV/tv,/media/TV/tv6 -# Timezone -TZ=UTC +# Radarr paths (what Radarr sees on the host system) +RADARR_ROOT_FOLDERS=/mnt/unionfs/Media/Movies/movies,/mnt/unionfs/Media/Movies/movies6 -# Media path (for read-only access to scan NFO files) -MEDIA_PATH=/path/to/your/media +# Sonarr paths (what Sonarr sees on the host system) - FIXED VARIABLE NAME AND PATHS +SONARR_ROOT_FOLDERS=/mnt/unionfs/Media/TV/tv,/mnt/unionfs/Media/TV/tv6 -# Database settings (if using PostgreSQL) -# DB_USER=nfoguard -# DB_PASSWORD=your_secure_password +# Download detection paths (for identifying downloads vs existing files) +DOWNLOAD_PATH_INDICATORS=/downloads/,/nzbget/,/completed/,/sabnzbd/,/torrents/ -# Emby Plugin Deployment - Bind Mount Method (Recommended) -# Set this to the path where Emby plugins are installed on your host -# Common paths: -# - /var/lib/emby/plugins (native Emby install) -# - /path/to/emby/config/plugins (Docker Emby) -# - /config/plugins (linuxserver.io Emby) -EMBY_PLUGINS_PATH=/path/to/emby/plugins +# =========================================== +# DATABASE CONFIGURATION +# =========================================== +# NFOGuard Database Configuration (PostgreSQL - v2.6+) +# NOTE: For new installations, PostgreSQL is strongly recommended +# Set these values in .env.secrets for security: +# - DB_PASSWORD=your_secure_password +# - DB_USER=nfoguard (default) -# NFOGuard specific settings +# PostgreSQL Database Settings +DB_TYPE=postgresql +DB_HOST=nfoguard-db # Container name from docker-compose +DB_PORT=5432 +DB_NAME=nfoguard + +# Legacy SQLite Configuration (Deprecated in v2.6+) +# Only use for existing SQLite installations +# DB_PATH=/app/data/media_dates.db + +# Log file directory +LOG_DIR=/app/data/logs + +# =========================================== +# RADARR DATABASE CONNECTION (RECOMMENDED) +# =========================================== +# Direct database access for better performance +RADARR_DB_TYPE=postgresql +RADARR_DB_HOST=192.168.255.50 +RADARR_DB_PORT=5432 +RADARR_DB_NAME=radarr-main +RADARR_DB_USER=postgres + +# =========================================== +# API CONNECTIONS (OPTIONAL) +# =========================================== +# API keys are stored in .env.secrets for security +RADARR_URL=http://radarr:7878 +SONARR_URL=http://sonarr:8989 +JELLYSEERR_URL=http://jellyseerr:5055 + +# =========================================== +# RELEASE DATE PROCESSING +# =========================================== +# Priority order for release date fallbacks (digital, physical, theatrical) +RELEASE_DATE_PRIORITY=digital,physical,theatrical +#RELEASE_DATE_PRIORITY=digital,theatrical,physical +ENABLE_SMART_DATE_VALIDATION=true +MAX_RELEASE_DATE_GAP_YEARS=10 + +# Prefer API release dates over file modification dates for manual imports +PREFER_RELEASE_DATES_OVER_FILE_DATES=true + +# Disable file date fallback completely (recommended for clean imports) +ALLOW_FILE_DATE_FALLBACK=false + +# TMDB country for regional release date preferences +TMDB_COUNTRY=US + +# =========================================== +# NFO FILE MANAGEMENT +# =========================================== +# Create/update .nfo files +MANAGE_NFO=true + +# Update file modification times to match import dates +FIX_DIR_MTIMES=true + +# Add lockdata tags to prevent metadata overwrites +LOCK_METADATA=true + +# Brand name in NFO comments +MANAGER_BRAND=NFOGuard + +# =========================================== +# PROCESSING BEHAVIOR +# =========================================== +# Movie date update strategy +MOVIE_DATE_UPDATE_MODE=overwrite +MOVIE_PRESERVE_EXISTING=false + +# When to update existing dates (always, missing_only, never) +UPDATE_MODE=always + +# File modification time behavior (update, leave_alone) +MTIME_BEHAVIOR=update + +# Manual scan priority: use existing NFO dates for speed vs check APIs for accuracy +# false (default) = Check external APIs first, use NFO as fallback (slower but accurate) +# true = Use NFO dates immediately without API checks (faster but may use wrong dates) +MANUAL_SCAN_PRIORITIZE_NFO=false + +# =========================================== +# PERFORMANCE & BATCHING +# =========================================== +# Delay before processing batched events (seconds) +BATCH_DELAY=5.0 + +# Maximum concurrent series processing +MAX_CONCURRENT_SERIES=3 + +# API timeout in seconds +TIMEOUT_SECONDS=45 + +# =========================================== +# DEBUGGING +# =========================================== +# Enable verbose logging (true/false) DEBUG=false + +# Enable path mapping debug output (true/false) PATH_DEBUG=false -SUPPRESS_TVDB_WARNINGS=true \ No newline at end of file + +# Suppress TVDB API warnings (true/false) - TVDB failures are common and non-critical +SUPPRESS_TVDB_WARNINGS=true + +# =========================================== +# SERVER CONFIGURATION +# =========================================== +# Port for webhook server +PORT=8080 \ No newline at end of file diff --git a/.env.secrets.template b/.env.secrets.example similarity index 68% rename from .env.secrets.template rename to .env.secrets.example index 3efc95a..6653c39 100644 --- a/.env.secrets.template +++ b/.env.secrets.example @@ -4,9 +4,17 @@ # Add .env.secrets to your .gitignore # =========================================== -# RADARR DATABASE CREDENTIALS +# NFOGUARD DATABASE CREDENTIALS (REQUIRED) # =========================================== -# Database password for PostgreSQL connection +# NFOGuard PostgreSQL database password (REQUIRED for v2.6+) +DB_PASSWORD=your_secure_nfoguard_password +# Optional: Override default database user (defaults to 'nfoguard') +# DB_USER=nfoguard + +# =========================================== +# RADARR DATABASE CREDENTIALS (OPTIONAL) +# =========================================== +# Database password for external Radarr PostgreSQL connection (optional optimization) RADARR_DB_PASSWORD=your_radarr_db_password # =========================================== diff --git a/.env.template b/.env.template deleted file mode 100644 index 189dc67..0000000 --- a/.env.template +++ /dev/null @@ -1,129 +0,0 @@ -# =========================================== -# NFOGuard Configuration - CORRECTED VERSION -# =========================================== -# Main configuration file - safe to share for debugging -# Sensitive data (API keys, passwords) are in .env.secrets - -# =========================================== -# MEDIA PATHS (REQUIRED) - FIXED -# =========================================== -# Container paths (what NFOGuard sees inside container) -MOVIE_PATHS=/media/Movies/movies,/media/Movies/movies6 -TV_PATHS=/media/TV/tv,/media/TV/tv6 - -# Radarr paths (what Radarr sees on the host system) -RADARR_ROOT_FOLDERS=/mnt/unionfs/Media/Movies/movies,/mnt/unionfs/Media/Movies/movies6 - -# Sonarr paths (what Sonarr sees on the host system) - FIXED VARIABLE NAME AND PATHS -SONARR_ROOT_FOLDERS=/mnt/unionfs/Media/TV/tv,/mnt/unionfs/Media/TV/tv6 - -# Download detection paths (for identifying downloads vs existing files) -DOWNLOAD_PATH_INDICATORS=/downloads/,/nzbget/,/completed/,/sabnzbd/,/torrents/ - -# =========================================== -# DATABASE CONFIGURATION -# =========================================== -# NFOGuard SQLite database location -DB_PATH=/app/data/media_dates.db - -# Log file directory -LOG_DIR=/app/data/logs - -# =========================================== -# RADARR DATABASE CONNECTION (RECOMMENDED) -# =========================================== -# Direct database access for better performance -RADARR_DB_TYPE=postgresql -RADARR_DB_HOST=192.168.255.50 -RADARR_DB_PORT=5432 -RADARR_DB_NAME=radarr-main -RADARR_DB_USER=postgres - -# =========================================== -# API CONNECTIONS (OPTIONAL) -# =========================================== -# API keys are stored in .env.secrets for security -RADARR_URL=http://radarr:7878 -SONARR_URL=http://sonarr:8989 -JELLYSEERR_URL=http://jellyseerr:5055 - -# =========================================== -# RELEASE DATE PROCESSING -# =========================================== -# Priority order for release date fallbacks (digital, physical, theatrical) -RELEASE_DATE_PRIORITY=digital,physical,theatrical -#RELEASE_DATE_PRIORITY=digital,theatrical,physical -ENABLE_SMART_DATE_VALIDATION=true -MAX_RELEASE_DATE_GAP_YEARS=10 - -# Prefer API release dates over file modification dates for manual imports -PREFER_RELEASE_DATES_OVER_FILE_DATES=true - -# Disable file date fallback completely (recommended for clean imports) -ALLOW_FILE_DATE_FALLBACK=false - -# TMDB country for regional release date preferences -TMDB_COUNTRY=US - -# =========================================== -# NFO FILE MANAGEMENT -# =========================================== -# Create/update .nfo files -MANAGE_NFO=true - -# Update file modification times to match import dates -FIX_DIR_MTIMES=true - -# Add lockdata tags to prevent metadata overwrites -LOCK_METADATA=true - -# Brand name in NFO comments -MANAGER_BRAND=NFOGuard - -# =========================================== -# PROCESSING BEHAVIOR -# =========================================== -# Movie date update strategy -MOVIE_DATE_UPDATE_MODE=overwrite -MOVIE_PRESERVE_EXISTING=false - -# When to update existing dates (always, missing_only, never) -UPDATE_MODE=always - -# File modification time behavior (update, leave_alone) -MTIME_BEHAVIOR=update - -# Manual scan priority: use existing NFO dates for speed vs check APIs for accuracy -# false (default) = Check external APIs first, use NFO as fallback (slower but accurate) -# true = Use NFO dates immediately without API checks (faster but may use wrong dates) -MANUAL_SCAN_PRIORITIZE_NFO=false - -# =========================================== -# PERFORMANCE & BATCHING -# =========================================== -# Delay before processing batched events (seconds) -BATCH_DELAY=5.0 - -# Maximum concurrent series processing -MAX_CONCURRENT_SERIES=3 - -# API timeout in seconds -TIMEOUT_SECONDS=45 - -# =========================================== -# DEBUGGING -# =========================================== -# Enable verbose logging (true/false) -DEBUG=false - -# Enable path mapping debug output (true/false) -PATH_DEBUG=false - -# Suppress TVDB API warnings (true/false) - TVDB failures are common and non-critical -SUPPRESS_TVDB_WARNINGS=true - -# =========================================== -# SERVER CONFIGURATION -# =========================================== -# Port for webhook server -PORT=8080 \ No newline at end of file diff --git a/Emby-DLL/NFOGuard.Emby.Plugin.dll b/Emby-DLL/NFOGuard.Emby.Plugin.dll index 8369710..60fad74 100644 Binary files a/Emby-DLL/NFOGuard.Emby.Plugin.dll and b/Emby-DLL/NFOGuard.Emby.Plugin.dll differ diff --git a/README.md b/README.md index 15e613d..8f11aad 100644 --- a/README.md +++ b/README.md @@ -24,41 +24,42 @@ NFOGuard automatically updates movie and TV show NFO files with proper release dates and metadata when triggered by Radarr/Sonarr webhooks. It preserves existing metadata while adding clean, accurate date information at the bottom of NFO files. -## ✨ Features +## Features -### **🎬 Core Media Management** +### **Core Media Management** - **Movie & TV Support** - Works with both Radarr and Sonarr - **Smart Date Handling** - Prioritizes digital, physical, and theatrical release dates - **Webhook Integration** - Triggers automatically on import, upgrade, and rename - **NFO Preservation** - Maintains existing metadata, adds fields cleanly at bottom - **Metadata Locking** - Prevents overwrites with lockdata tags -### **⚡ Performance & Scalability** +### **Performance & Scalability** - **Async I/O Operations** - High-performance concurrent file processing - **Batch Processing** - Efficient handling of multiple files simultaneously -- **Database Integration** - Direct PostgreSQL/SQLite access for better performance -- **Smart Concurrency** - Controlled parallel processing with rate limiting +- **PostgreSQL Database** - Production-ready database with optimized queries +- **Smart Skip Logic** - Database-first checking eliminates expensive filesystem scans +- **88% Scan Optimization** - TV library scans reduced from hours to minutes -### **🔧 Configuration & Validation** +### **Web Interface & Management** +- **Complete Web UI** - Episode and movie management with filtering and search +- **Database Cleanup Tools** - Delete orphaned episodes with confirmation dialogs +- **Real-time Statistics** - Live episode counts and source mapping +- **Manual Scan Control** - Smart, full, and incomplete scan modes +- **Health Monitoring** - System status and performance metrics + +### **Configuration & Validation** - **Comprehensive Config Validation** - Validates all settings before startup - **Runtime Health Checks** - Monitors system health and dependencies - **Path Validation** - Ensures media directories are accessible - **Database Connectivity Tests** - Validates database connections -### **📊 Monitoring & Observability** -- **Health Check APIs** - `/api/v1/health`, `/api/v1/health/ready`, `/api/v1/health/live` -- **Prometheus Metrics** - `/api/v1/metrics` endpoint for monitoring integration -- **Performance Monitoring** - Operation timing, error rates, and bottleneck detection -- **Structured Logging** - JSON logs with correlation IDs for request tracing -- **System Status APIs** - Real-time performance and error metrics - -### **🐳 Production Ready** +### **Production Ready** - **Docker & Kubernetes** - Health checks for orchestration platforms -- **Grafana Compatible** - Metrics endpoints for dashboard integration +- **Graceful Shutdown** - Proper signal handling for container management - **Configuration CLI** - Validation tools for troubleshooting - **Modular Architecture** - Clean separation of concerns for maintainability -## 🚀 Quick Start +## Quick Start ### 1. Download Configuration Files @@ -101,7 +102,7 @@ docker-compose logs -f nfoguard curl http://localhost:8080/health ``` -## ⚙️ Configuration +## Configuration ### Environment Files @@ -134,7 +135,7 @@ DEBUG=false # Clean production logs SUPPRESS_TVDB_WARNINGS=true # Hide non-critical API failures ``` -## 🐳 Docker Images +## Docker Images ### Production (Stable) ```yaml @@ -257,7 +258,7 @@ volumes: - /home/user/media/tv:/media/TV/tv:rw ``` -## 🔧 Troubleshooting +## Troubleshooting ### Check Logs ```bash @@ -276,7 +277,7 @@ PATH_DEBUG=true curl http://localhost:8080/health ``` -## 📊 Monitoring & Observability +## Monitoring & Observability NFOGuard provides comprehensive monitoring capabilities for production deployments: @@ -356,7 +357,7 @@ LOG_LEVEL=INFO 3. **Webhooks**: Check URLs and ensure port 8080 is accessible 4. **Database**: Verify PostgreSQL credentials in `.env.secrets` -## 📊 What NFOGuard Does +## What NFOGuard Does ### Before ```xml @@ -392,7 +393,7 @@ LOG_LEVEL=INFO NFOGuard identifies movies and TV shows using two methods: directory names with IMDb IDs (primary) or NFO files with IMDb IDs (fallback). Your media should follow these conventions: -### 🎬 **Movies** +### **Movies** **Directory Structure:** ``` diff --git a/VERSION b/VERSION index 57cf282..338a5b5 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.6.5 +2.6.6 diff --git a/docker-compose.example b/docker-compose.example index 6f2ec80..ef6f168 100644 --- a/docker-compose.example +++ b/docker-compose.example @@ -6,13 +6,17 @@ services: image: sbcrumb/nfoguard:latest # Alternative: Use specific version - # image: sbcrumb/nfoguard:v1.5.5 + # image: sbcrumb/nfoguard:v2.6.5 # Alternative: Use development version # image: sbcrumb/nfoguard:dev container_name: nfoguard + # Database dependency + depends_on: + - nfoguard-postgres + # Restart policy restart: unless-stopped @@ -87,6 +91,54 @@ services: max-size: "10m" max-file: "3" + # PostgreSQL Database (Required for v2.6+) + nfoguard-postgres: + image: postgres:15-alpine + container_name: nfoguard-db + + # Restart policy + restart: unless-stopped + + # Environment variables for PostgreSQL + environment: + - POSTGRES_DB=nfoguard + - POSTGRES_USER=nfoguard + - POSTGRES_PASSWORD=${DB_PASSWORD} # Set in .env.secrets + - POSTGRES_INITDB_ARGS=--encoding=UTF-8 --lc-collate=C --lc-ctype=C + + # PostgreSQL data persistence + volumes: + - ./postgres-data:/var/lib/postgresql/data + + # PostgreSQL port (optional - only needed for external access) + # ports: + # - "5432:5432" + + # Health check for database + healthcheck: + test: ["CMD-SHELL", "pg_isready -U nfoguard -d nfoguard"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 60s + + # Resource limits for database + deploy: + resources: + limits: + memory: 256M + cpus: '0.3' + reservations: + memory: 128M + cpus: '0.1' + + # Logging configuration + logging: + driver: "json-file" + options: + max-size: "10m" + max-file: "3" + # Optional: Custom network for media services # networks: # media-network: @@ -97,12 +149,13 @@ services: # =========================================== # 1. Copy this file to docker-compose.yml # 2. Update volume mounts to match your actual media paths -# 3. Copy .env.template to .env and configure -# 4. Copy .env.secrets.template to .env.secrets and add credentials -# 5. Create data directory: mkdir -p ./data +# 3. Copy .env.example to .env and configure all settings +# 4. Copy .env.secrets.example to .env.secrets and add credentials (especially DB_PASSWORD) +# 5. Create directories: mkdir -p ./data ./postgres-data # 6. Run: docker-compose up -d -# 7. Check logs: docker-compose logs -f nfoguard -# 8. Access health check: curl http://localhost:8080/health +# 7. Check logs: docker-compose logs -f +# 8. Access web interface: http://localhost:8080 +# 9. Access health check: curl http://localhost:8080/health # =========================================== # VOLUME MAPPING EXAMPLES