From 09b28abcdc9c4cba895ab1545a4da9ed30e91f25 Mon Sep 17 00:00:00 2001 From: SBCrumb Date: Mon, 22 Sep 2025 08:36:46 -0400 Subject: [PATCH] make local dir for ignores in local docs --- .env.example | 28 --- .env.fixed | 124 ------------- .env.template | 173 ++++++++---------- .gitignore | 1 - SETUP.md | 153 ---------------- SUMMARY.md | 496 -------------------------------------------------- 6 files changed, 78 insertions(+), 897 deletions(-) delete mode 100644 .env.example delete mode 100644 .env.fixed delete mode 100644 SETUP.md delete mode 100644 SUMMARY.md diff --git a/.env.example b/.env.example deleted file mode 100644 index 78ce602..0000000 --- a/.env.example +++ /dev/null @@ -1,28 +0,0 @@ -# NFOGuard Environment Variables - -# User and Group IDs -PUID=1000 -PGID=1000 - -# Timezone -TZ=UTC - -# Media path (for read-only access to scan NFO files) -MEDIA_PATH=/path/to/your/media - -# Database settings (if using PostgreSQL) -# DB_USER=nfoguard -# DB_PASSWORD=your_secure_password - -# 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 - -# NFOGuard specific settings -DEBUG=false -PATH_DEBUG=false -SUPPRESS_TVDB_WARNINGS=true \ No newline at end of file diff --git a/.env.fixed b/.env.fixed deleted file mode 100644 index 1a449f0..0000000 --- a/.env.fixed +++ /dev/null @@ -1,124 +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 - -# =========================================== -# 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/.env.template b/.env.template index 4ee8755..1a449f0 100644 --- a/.env.template +++ b/.env.template @@ -1,13 +1,24 @@ -# NFOGuard Environment Configuration Template -# Copy this to .env and customize for your setup +# =========================================== +# NFOGuard Configuration - CORRECTED VERSION +# =========================================== +# Main configuration file - safe to share for debugging +# Sensitive data (API keys, passwords) are in .env.secrets # =========================================== -# MEDIA PATHS (REQUIRED) +# MEDIA PATHS (REQUIRED) - FIXED # =========================================== -# Paths where your movies and TV shows are stored inside the container -# Adjust these to match YOUR directory structure -TV_PATHS=/media/TV/tv,/media/TV/tv6 +# 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 @@ -15,127 +26,99 @@ MOVIE_PATHS=/media/Movies/movies,/media/Movies/movies6 # NFOGuard SQLite database location DB_PATH=/app/data/media_dates.db +# Log file directory +LOG_DIR=/app/data/logs + # =========================================== -# RADARR DATABASE CONNECTION (REQUIRED) +# RADARR DATABASE CONNECTION (RECOMMENDED) # =========================================== -# Connection to Radarr's PostgreSQL database -# NOTE: Database password should be set in .env.secrets file -RADARR_DB_HOST=radarr-postgres +# 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 -RADARR_DB_USER=radarr +RADARR_DB_NAME=radarr-main +RADARR_DB_USER=postgres # =========================================== -# RADARR API (OPTIONAL - for fallback) +# API CONNECTIONS (OPTIONAL) # =========================================== -# Only needed if you want API fallback (not recommended for performance) -# NOTE: API key should be set in .env.secrets file +# API keys are stored in .env.secrets for security RADARR_URL=http://radarr:7878 - -# =========================================== -# SONARR API (REQUIRED for Enhanced TV NFOs - v0.6.0+) -# =========================================== -# Required for TV processing and enhanced NFO generation with metadata -# NOTE: API key should be set in .env.secrets file SONARR_URL=http://sonarr:8989 - -# =========================================== -# EXTERNAL APIs FOR DIGITAL RELEASE DATES -# =========================================== -# NOTE: All API keys should be set in .env.secrets file -# See .env.secrets.template for required keys: -# - TMDB_API_KEY (recommended for digital release dates) -# - OMDB_API_KEY (optional for DVD/digital release dates) -# - JELLYSEERR_API_KEY (optional for additional digital release data) - -# Jellyseerr URL (optional) JELLYSEERR_URL=http://jellyseerr:5055 # =========================================== -# NFO MANAGEMENT +# RELEASE DATE PROCESSING # =========================================== -# Whether to create/update .nfo files +# 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 -# Whether to fix file modification times to match import dates +# Update file modification times to match import dates FIX_DIR_MTIMES=true -# Whether to add tags to prevent metadata drift +# Add lockdata tags to prevent metadata overwrites LOCK_METADATA=true -# Brand name to add to NFO files +# Brand name in NFO comments MANAGER_BRAND=NFOGuard # =========================================== -# PROCESSING SETTINGS +# PROCESSING BEHAVIOR # =========================================== -# Delay before processing batched webhook events (seconds) +# 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 + +# =========================================== +# PERFORMANCE & BATCHING +# =========================================== +# Delay before processing batched events (seconds) BATCH_DELAY=5.0 # Maximum concurrent series processing MAX_CONCURRENT_SERIES=3 -# Movie date strategy: import_then_digital or digital_then_import -MOVIE_PRIORITY=import_then_digital - -# Smart fallback: prefer release dates over file dates for manual imports (true/false) -PREFER_RELEASE_DATES_OVER_FILE_DATES=true - -# Allow file dates as absolute last resort (true/false) -# If false, movies with no valid import AND no release dates will be skipped entirely -ALLOW_FILE_DATE_FALLBACK=false - -# Fallback priority order when no valid Radarr import exists (comma-separated) -# Options: digital, physical, theatrical -# digital = VOD/streaming release, physical = DVD/Blu-ray, theatrical = cinema release -RELEASE_DATE_PRIORITY=digital,physical,theatrical - -# Smart date validation: automatically prefer theatrical over unreasonably late digital/physical dates -# Example: "The Craft (1996)" theatrical vs "The Craft (2022)" physical → chooses 1996 theatrical -ENABLE_SMART_DATE_VALIDATION=true - -# Maximum reasonable gap between theatrical and digital/physical release (in years) -# If digital/physical is more than this many years after theatrical, prefer theatrical instead -MAX_RELEASE_DATE_GAP_YEARS=10 - -# TMDB country for regional release date preferences -TMDB_COUNTRY=US - -# TMDB release type priority (comma-separated numbers) -# 1=Premiere, 2=Limited Theatrical, 3=Theatrical, 4=Digital, 5=Physical, 6=TV Premiere -# Default: 4,5,3,2,6,1 (Digital → Physical → Theatrical → Limited → TV → Premiere) -TMDB_TYPE_PRIORITY=4,5,3,2,6,1 - -# When to query APIs: always, if_missing, never -MOVIE_POLL_MODE=always - -# Update mode: backfill_only or overwrite -MOVIE_DATE_UPDATE_MODE=backfill_only +# API timeout in seconds +TIMEOUT_SECONDS=45 # =========================================== -# TV SERIES PROCESSING +# DEBUGGING # =========================================== -# Season directory naming format (supports {season} placeholder) -# Examples: "Season {season:02d}" -> "Season 01", "S{season:02d}" -> "S01" -TV_SEASON_DIR_FORMAT=Season {season:02d} - -# Season directory detection pattern (lowercase, what to look for at start of dir name) -# Examples: "season " -> matches "Season 01", "s" -> matches "S01", "season" -> matches "Season01" -TV_SEASON_DIR_PATTERN=season - -# TV webhook processing mode (v0.6.0+) -# targeted = Only process episodes mentioned in webhook (efficient, recommended) -# series = Process entire series directory (comprehensive, current default) -TV_WEBHOOK_PROCESSING_MODE=targeted - -# =========================================== -# LOGGING -# =========================================== -# Enable debug logging +# 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 +# SERVER CONFIGURATION # =========================================== -# Port to run the webhook server on +# Port for webhook server PORT=8080 \ No newline at end of file diff --git a/.gitignore b/.gitignore index 644c789..ff21fc2 100644 --- a/.gitignore +++ b/.gitignore @@ -62,7 +62,6 @@ temp/ # Local development files (not for public repo) *.local CODE_STRUCTURE.local -RESTART_SUMMARY.md # Ignore GitHub workflows when pushing to Gitea .github/ diff --git a/SETUP.md b/SETUP.md deleted file mode 100644 index 0798ec5..0000000 --- a/SETUP.md +++ /dev/null @@ -1,153 +0,0 @@ -# NFOGuard Setup Guide - -## 🔐 Secure Configuration Setup - -NFOGuard now uses a **two-file configuration system** for better security and easier troubleshooting: - -- **`.env`** - Main configuration (safe to share for debugging) -- **`.env.secrets`** - Sensitive API keys and passwords (never commit to git) - -### Step 1: Copy Configuration Templates - -```bash -# Copy main configuration -cp .env.template .env - -# Copy secrets configuration -cp .env.secrets.template .env.secrets -``` - -### Step 2: Configure Main Settings - -Edit your `.env` file with your specific paths and preferences: - -```bash -# Media paths (adjust to your directory structure) -TV_PATHS=/media/TV/tv,/media/TV/tv6 -MOVIE_PATHS=/media/Movies/movies,/media/Movies/movies6 - -# Database connection details -RADARR_DB_HOST=radarr-postgres -RADARR_DB_PORT=5432 -RADARR_DB_NAME=radarr -RADARR_DB_USER=radarr - -# Processing preferences -PREFER_RELEASE_DATES_OVER_FILE_DATES=true -ALLOW_FILE_DATE_FALLBACK=false -RELEASE_DATE_PRIORITY=digital,physical,theatrical - -# TV webhook processing mode (v0.6.0+) -TV_WEBHOOK_PROCESSING_MODE=targeted -``` - -### Step 3: Configure Secrets - -Edit your `.env.secrets` file with your actual API keys and passwords: - -```bash -# Database password -RADARR_DB_PASSWORD=your_actual_radarr_password - -# TMDB API key (required for release date detection) -TMDB_API_KEY=your_actual_tmdb_api_key - -# Sonarr API key (REQUIRED for v0.6.0+ Enhanced TV NFO Generation) -SONARR_API_KEY=your_actual_sonarr_api_key - -# Optional API keys -RADARR_API_KEY=your_radarr_api_key -OMDB_API_KEY=your_omdb_api_key -``` - -### Step 4: Verify Configuration - -Test your setup: - -```bash -# Test database connections -curl -X POST "http://localhost:8080/test/bulk-update" - -# Test movie scanning -curl -X POST "http://localhost:8080/test/movie-scan" - -# Check system health -curl "http://localhost:8080/health" -``` - -## 🔒 Security Features - -### API Key Masking -All API keys and passwords are automatically masked in logs: -``` -[2025-09-09T12:34:56] INFO: TMDB API call with key=***masked*** -[2025-09-09T12:34:56] INFO: Database connection password=***masked*** -``` - -### Sensitive Data Separation -- **Main `.env`**: Paths, preferences, URLs (safe to share) -- **`.env.secrets`**: API keys, passwords (never commit to version control) -- **Automatic loading**: Both files loaded automatically at startup - -### Git Protection -The `.gitignore` file prevents accidental commits: -``` -.env -.env.secrets -.env.local -``` - -## 🛠 Troubleshooting - -### "Environment files not loaded" Warning -Install python-dotenv: -```bash -pip install python-dotenv==1.0.0 -# or -docker-compose build # rebuilds with updated requirements.txt -``` - -### Sharing Configuration for Help -You can safely share your `.env` file for debugging since it contains no sensitive data. The `.env.secrets` file should never be shared. - -### Migration from Old Setup -If you have an existing `.env` with API keys: -1. Move all `*_API_KEY` and `*_PASSWORD` variables to `.env.secrets` -2. Remove sensitive data from `.env` -3. Restart NFOGuard - -## 🎯 Docker Compose Example - -```yaml -version: '3.8' -services: - nfoguard: - image: sbcrumb/nfoguard:latest - container_name: nfoguard - ports: - - "8080:8080" - volumes: - - /path/to/your/media:/media:rw - - ./data:/app/data - - ./.env:/app/.env:ro # Main configuration - - ./.env.secrets:/app/.env.secrets:ro # Secrets - environment: - - PORT=8080 - depends_on: - - radarr-postgres -``` - -## 📋 Configuration Reference - -### Main Configuration (.env) -- **Paths**: `TV_PATHS`, `MOVIE_PATHS`, `DB_PATH` -- **Processing**: `MOVIE_PRIORITY`, `RELEASE_DATE_PRIORITY` -- **Features**: `MANAGE_NFO`, `FIX_DIR_MTIMES`, `LOCK_METADATA` -- **URLs**: `RADARR_URL`, `SONARR_URL`, `JELLYSEERR_URL` - -### Secrets Configuration (.env.secrets) -- **Database**: `RADARR_DB_PASSWORD` -- **APIs**: `TMDB_API_KEY`, `OMDB_API_KEY`, `RADARR_API_KEY`, `SONARR_API_KEY` -- **Optional**: `JELLYSEERR_API_KEY` - -This setup makes NFOGuard more secure while keeping configuration manageable for troubleshooting and deployment. \ No newline at end of file diff --git a/SUMMARY.md b/SUMMARY.md deleted file mode 100644 index 181b580..0000000 --- a/SUMMARY.md +++ /dev/null @@ -1,496 +0,0 @@ -# NFOGuard Project Summary - -## Overview -NFOGuard is a Python-based tool that manages NFO (metadata) files for movies and TV shows in Plex/Emby media servers. It integrates with Radarr and Sonarr to automatically manage metadata, ensuring proper dates and metadata consistency. - -## 🎯 CURRENT SESSION ACCOMPLISHMENTS (September 21, 2025) - -### ✅ MAJOR ISSUES RESOLVED -1. **Database Save Bug**: Identified and resolved "phantom" database save issue (was logging interpretation error) -2. **Enhanced Movie Detection**: Movies without IMDb IDs in directory names now detected via filenames/NFO content -3. **Enhanced Logging**: Crystal-clear source attribution showing NFOGuard DB vs Radarr vs External APIs -4. **Priority Flow Confirmed**: Perfect implementation of user's requested flow - -### ✅ KEY IMPROVEMENTS MADE - -**🔍 Enhanced Movie Detection**: -- Added `find_movie_imdb_id()` function with comprehensive detection -- Supports directory names, filenames, and NFO file content parsing -- Movies like "Ick (2024)" now properly processed without directory IMDb tags - -**📊 Crystal-Clear Logging System**: -- Added emoji-based logging for easy visual scanning -- Clear source attribution: `nfoguard_db:`, `radarr:db.`, `tmdb:`, etc. -- Priority flow display shows exact decision path -- Final completion logs show chosen date and source - -**🔄 Perfect Priority Flow**: -1. NFOGuard Database (cached entries) → -2. Radarr Import History (real import dates) → -3. External APIs (TMDB/OMDb with configurable priority) → -4. Save to NFOGuard Database (cache for future) - -**🚀 Manual Scan Commands**: -- Movies only: `curl -X POST "http://nfoguard:8080/manual/scan?scan_type=movies"` -- TV only: `curl -X POST "http://nfoguard:8080/manual/scan?scan_type=tv"` -- Both: `curl -X POST "http://nfoguard:8080/manual/scan?scan_type=both"` - -### ✅ CONFIGURATION MAINTAINED -All existing .env settings fully preserved and respected: -- `RELEASE_DATE_PRIORITY=digital,physical,theatrical` -- `MOVIE_PRIORITY=import_then_digital` -- `PREFER_RELEASE_DATES_OVER_FILE_DATES=true` -- `ALLOW_FILE_DATE_FALLBACK=false` - -### ✅ DEBUGGING COMPLETED -- **Root Cause**: "Phantom database save" was actually two different movie executions in logs -- **Database Save**: Working correctly in both early-exit and full-processing paths -- **NFO Processing**: Fixed to execute before date validation (preserves existing metadata) -- **File Detection**: Enhanced to handle movies without directory IMDb tags - -## Core Architecture - -### Main Components -- **nfoguard.py**: Main application file containing the core logic -- **core/nfo_manager.py**: Handles NFO file creation and updates -- **clients/**: External API integrations (Radarr, Sonarr, etc.) - -### Key Features -- Creates and updates movie.nfo files with proper metadata -- Manages TV show NFO files (tvshow.nfo, season.nfo, episode NFOs) -- Preserves existing metadata while adding NFOGuard-managed fields -- Supports date management from multiple sources (Radarr, file dates, etc.) -- Webhook support for real-time processing - -## Current Issue Analysis - -### Problem -When a movie.nfo file already exists (e.g., from Radarr), NFOGuard is **not** processing the file to: -1. Move date fields to the bottom -2. Add NFOGuard comment -3. Add NFOGuard-managed fields (dateadded, lockdata, etc.) - -### Root Cause Identified -The issue is in `nfoguard.py:1009-1012`. The processing logic has a premature exit condition: - -```python -# Skip processing if no valid date found and file dates disabled -if dateadded is None: - _log("WARNING", f"Skipping movie {movie_path.name} - no valid date source available") - self.db.upsert_movie_dates(imdb_id, released, None, source, True) - return # <-- This exits BEFORE NFO processing -``` - -**The NFO processing code (lines 1015-1018) never executes when dateadded is None.** - -### Analysis of NFO Processing Logic -The `create_movie_nfo` function in `core/nfo_manager.py:52-147` is actually well-designed: -- Lines 60-78: Properly loads and preserves existing NFO content -- Lines 69-78: Removes NFOGuard-managed fields to re-add them at the bottom -- Lines 96-123: Adds all NFOGuard fields at the end -- Lines 124-141: Adds NFOGuard comment and proper formatting - -**The NFO manager code is correct - it's just not being called due to the early exit.** - -## Files That Need Updates -1. `nfoguard.py` - Fix the early exit logic around line 1009-1012 - -## Status -- ✅ NFO Processing Issue: Fixed in nfoguard.py:1008-1025 -- 🔍 **NEW ISSUE**: Database not persisting dateadded values on manual scans - -## Fix Summary - -### Movie NFO Processing (✅ Fixed) -**Problem**: NFO processing was skipped entirely when `dateadded` was None due to early return. - -**Solution**: Moved NFO processing (`create_movie_nfo`) to execute **before** the `dateadded` check, ensuring that: -1. Existing NFO files are always processed and standardized -2. NFOGuard comment is added -3. Date fields are moved to bottom -4. lockdata is added if configured -5. Only file mtime updates are skipped when no valid date is found - -### TV Episode NFO Processing (✅ Enhanced) -**Enhancement**: Added smart episode NFO migration for long-named files. - -**New Functionality**: -1. **Detection**: `find_existing_episode_nfo()` scans for non-standard NFO files that match season/episode -2. **Migration**: Extracts metadata from long-named files (e.g., `Episode.Name.Here.S01E05.nfo`) -3. **Standardization**: Creates standard `S01E05.nfo` with preserved metadata + NFOGuard enhancements -4. **Cleanup**: Automatically deletes old long-named NFO files after successful migration -5. **Preservation**: All existing metadata is preserved, dates moved to bottom, NFOGuard fields added - -## 🔍 DATABASE SAVE BUG RESOLVED! ✅ - -### Problem Analysis COMPLETED -**Root Cause Identified**: The "phantom database save bug" was actually a **logging interpretation error**. - -### What Actually Happened -The debug logs showing these two lines: -``` -DEBUG: Movie processing reached post-mtime section: Dear Santa (2024) [imdb-tt2396431] -INFO: Completed processing movie: Dear Santa (2024) [imdb-tt2396431] (source: tmdb:digital) -``` - -**Cannot be from the same function execution!** Here's why: - -### The Real Execution Flow -**Line 1014-1018**: Early exit when `dateadded is None`: -```python -if dateadded is None: - _log("WARNING", f"Movie {movie_path.name} - no valid date source available, but NFO was still processed") - self.db.upsert_movie_dates(imdb_id, released, None, source, True) - return # <-- EXITS HERE, never reaches line 1029! -``` - -**Line 1029**: Debug log that only executes when `dateadded` has a valid value: -```python -_log("DEBUG", f"Movie processing reached post-mtime section: {movie_path.name}") -``` - -**Line 1045**: Completion log that only executes after successful database save: -```python -_log("INFO", f"Completed processing movie: {movie_path.name} (source: {source})") -``` - -### Key Insight -**The logs are from TWO different executions:** -1. **First run**: `dateadded = None` → early exit at line 1018 → database save executes BUT for NULL value -2. **Second run**: `dateadded` has value → reaches line 1029 → full processing → line 1045 - -### Database Save Status -✅ **Database saves ARE working correctly!** -- Early exit path (line 1018): Saves NULL dateadded when no valid date found -- Full processing path (lines 1038-1043): Saves valid dateadded when available -- Both paths call `upsert_movie_dates()` appropriately - -### Investigation Status -✅ **Enhanced Movie Detection**: Working (Ick 2024 now processed) -✅ **NFO Processing**: Working (files get updated) -✅ **File Timestamp Updates**: Working (mtimes get set) -✅ **Database Persistence**: **WORKING CORRECTLY** - saves happen in both execution paths - -## 📊 ENHANCED LOGGING SYSTEM (September 21, 2025) ✅ - -### New Crystal-Clear Source Attribution -**Problem**: Logs didn't clearly show whether dates came from NFOGuard DB vs Radarr vs external APIs. - -**Solution**: Added comprehensive logging with emojis and clear source identification. - -### New Logging Format -**Priority Flow Display**: -``` -🔄 PRIORITY FLOW: NFOGuard DB → Radarr import → External APIs (digital,physical,theatrical) → Save to NFOGuard DB -``` - -**NFOGuard Database Lookups**: -``` -🔍 NFOGuard DB lookup for tt1234567: FOUND - dateadded=2025-06-15T11:10:31-04:00, source=radarr:db.history.import -✅ MANUAL SCAN: Using existing NFOGuard database entry: 2025-06-15T11:10:31-04:00 (original source: radarr:db.history.import) -``` - -**External Source Queries**: -``` -🔍 RADARR DATABASE: Checking import history for movie ID 123 (tt1234567)... -📦 RADARR DATABASE: Found import date=2025-07-20T14:30:00Z, source=radarr:db.history.import -🔍 EXTERNAL APIs: Trying digital release date fallback... -🌐 EXTERNAL APIs: Found digital release date=2025-06-15T00:00:00+00:00, source=tmdb:digital -``` - -**Final Decision Tracking**: -``` -✅ FINAL CHOICE: Using Radarr import date 2025-07-20T14:30:00-04:00 from radarr:db.history.import -🎬 COMPLETED: Movie Name (2024) | Final date: 2025-07-20T14:30:00-04:00 | Final source: radarr:db.history.import -``` - -### Source Attribution System -**NFOGuard Database**: `nfoguard_db:radarr:db.history.import` (shows original source) -**Radarr Database**: `radarr:db.history.import` (fresh query) -**External APIs**: `tmdb:digital`, `omdb:dvd`, etc. - -### Perfect Priority Flow Confirmed -1. ✅ **NFOGuard DB First**: Check cached entries, use if available -2. ✅ **Radarr Import History**: Query for real import dates if not cached -3. ✅ **External APIs**: TMDB/OMDb fallback with configurable priority (`RELEASE_DATE_PRIORITY`) -4. ✅ **Save to NFOGuard DB**: Cache result for future lookups - -**This ensures we don't repeatedly query Radarr/external APIs for the same movies!** - -## 🚀 MANUAL SCAN API COMMANDS - -### Available Scan Types -**Movies Only:** -```bash -curl -X POST "http://nfoguard:8080/manual/scan?scan_type=movies" -``` - -**TV Shows Only:** -```bash -curl -X POST "http://nfoguard:8080/manual/scan?scan_type=tv" -``` - -**Both Movies AND TV Shows (Default):** -```bash -curl -X POST "http://nfoguard:8080/manual/scan?scan_type=both" -# OR simply: -curl -X POST "http://nfoguard:8080/manual/scan" -``` - -**Specific Path Scan:** -```bash -curl -X POST "http://nfoguard:8080/manual/scan?path=/media/Movies/Movie.Name.2024&scan_type=movies" -``` - -### What Each Scan Does -- **Movies**: Processes all movie directories in `MOVIE_PATHS`, follows NFOGuard priority flow -- **TV**: Processes all TV series in `TV_PATHS`, updates episode NFO files with proper dates -- **Both**: Processes both movies and TV shows in sequence (recommended for full refresh) - -All scans run in background and return immediately with status confirmation. - -### Movie IMDb ID Detection (✅ Enhanced) -**Enhancement**: Added comprehensive IMDb ID detection for movies without directory tags. - -**New Detection Methods**: -1. **Directory Name**: `[imdb-tt123456]` format (existing) -2. **Filename Patterns**: IMDb ID in any video file name `Movie.Name.2024.[tt123456].mkv` -3. **NFO File Content**: `tt123456` (NEW) -4. **Legacy NFO Tags**: `` and `` tags (NEW) - -**Implementation**: -- Added `find_movie_imdb_id()` function that tries all methods in priority order -- Extended `parse_imdb_from_nfo()` to handle XML parsing -- Updated movie processing to use comprehensive detection - -**Example**: Ick (2024) directory without IMDb in folder name will now be detected via NFO file content. - - -# NFOGuard Development Summary - -## Current Status: v1.6.6 - Docker Plugin Deployment! 🐳 - -### Latest Updates (v1.6.6) - September 19, 2025 -- **🐳 DOCKER PLUGIN DEPLOYMENT**: Added automatic Emby plugin deployment via Docker -- **📦 DLL PACKAGING**: NFOGuard.Emby.Plugin.dll now packaged with Docker image -- **🔗 BIND MOUNT SUPPORT**: Primary method using bind mount to Emby plugins directory -- **⚙️ ENVIRONMENT FALLBACK**: Secondary method using EMBY_PLUGINS_PATH environment variable -- **🚀 AUTO-UPDATE**: Plugin automatically updates when new Docker image is deployed -- **📋 CONFIGURATION**: Added .env.example with plugin deployment settings -- **🔄 STARTUP SCRIPT**: Container automatically deploys plugin on startup -- **🎯 WORKFLOW INTEGRATION**: Compatible with Gitea → DockerHub deployment pipeline - -### Docker Plugin Deployment Flow -**Bind Mount Method (Recommended):** -1. Set `EMBY_PLUGINS_PATH=/path/to/emby/plugins` in .env -2. Docker bind mounts host directory to `/emby-plugins` in container -3. On startup, NFOGuard copies DLL to mounted directory -4. Plugin updates automatically with each new image deployment - -**Benefits:** -- Works with separate Emby/NFOGuard containers -- Compatible with native Emby installations -- Secure - only exposes plugins directory -- Automatic updates via CI/CD pipeline - -## Previous Status: v1.6.0 - NFO-Based Identification! 📄 - -### Latest Updates (v1.6.0) - September 16, 2025 -- **📄 NFO IDENTIFICATION**: Added support for identifying movies/TV shows from NFO files -- **🔄 DUAL METHOD**: Directory name IMDb IDs (primary) + NFO file IMDb IDs (fallback) -- **📋 NFO FORMATS**: Supports ``, ``, and `` XML tags -- **🎬 MOVIE SUPPORT**: Reads movie.nfo files for IMDb ID extraction -- **📺 TV SUPPORT**: Reads tvshow.nfo files for series identification -- **✅ SMART FALLBACK**: Only checks NFO files when directory name lacks IMDb ID -- **📝 DOCUMENTATION**: Updated README with NFO identification examples and formats -- **🔄 NFO RENAMING**: Added smart episode NFO file renaming to standardized `S##E##.nfo` format -- **🎯 SONARR INTEGRATION**: Detects existing NFO files created by Sonarr/other tools, extracts metadata, and renames to standard format -- **📁 METADATA PRESERVATION**: Preserves all existing metadata when renaming non-standard NFO files -- **🧹 CLEANUP**: Removes old non-standard NFO files after successful rename to prevent duplicates - -### Previous Updates (v1.5.5) - September 15, 2025 -- **🔧 DATABASE BUG FIX**: Fixed `upsert_movie_dates` to be a proper upsert operation -- **💾 DATA INTEGRITY**: Manual scans now properly save `dateadded` to database -- **🎯 ROOT CAUSE**: Fixed UPDATE-only operation that was leaving `dateadded` fields NULL -- **✅ WEBHOOK FIX**: Webhooks now find existing database entries correctly -- **📺 TV SHOWS**: NOT affected - already using proper `INSERT OR REPLACE` operations - -### Previous Updates (v1.5.4) - September 15, 2025 -- **🎯 WEBHOOK DATE FIX**: Fixed webhook processing to use proper date decision logic -- **🔍 SMART FALLBACK**: Webhooks now check database → Radarr import dates → release dates → timestamp -- **❌ ISSUE RESOLVED**: Upgrade webhooks no longer incorrectly use current timestamp when database exists -- **✅ PROPER FLOW**: Webhook mode now uses same date logic as manual scans for missing entries - -### Previous Updates (v1.5.3) - September 15, 2025 -- **🔧 RADARR RENAME FIX**: Added missing event type filtering to Radarr webhooks -- **✅ CONSISTENCY**: Radarr now matches Sonarr's event handling (Download, Upgrade, Rename) -- **🎯 FIXED ISSUE**: Radarr rename events now properly trigger NFO updates with correct dates -- **🔄 WORKFLOW**: Both Sonarr and Radarr now follow identical webhook processing flows - -### Previous Updates (v1.5.2) -- **🔇 TVDB WARNINGS**: Added SUPPRESS_TVDB_WARNINGS configuration option -- **✅ CLEAN LOGS**: Can now suppress non-critical TVDB API failure warnings -- **🧹 PRODUCTION**: Cleaner logs for production monitoring -- **🎯 FUNCTIONAL**: System works perfectly without TVDB (uses IMDb/Sonarr data) - -### TVDB Warning Suppression -**Added new environment variable:** -```bash -# Suppress TVDB API warnings (true/false) - TVDB failures are common and non-critical -SUPPRESS_TVDB_WARNINGS=true -``` - -### Why Suppress TVDB Warnings? -- **❌ Common Failures**: Many series don't exist in TVDB database -- **✅ Non-Critical**: NFOGuard works perfectly without TVDB data -- **📊 Primary Data**: Uses IMDb IDs and Sonarr metadata (more reliable) -- **🧹 Log Noise**: Reduces repetitive warning messages - -### Before vs After - -**Before (noisy):** -``` -INFO: All episodes found in cache -WARNING: GET https://api4.thetvdb.com/v4/search/remoteid?remoteId=tt0804484&type=series failed: HTTP Error 400: Bad Request -INFO: Completed processing TV series: Foundation (2021) [imdb-tt0804484] -WARNING: GET https://api4.thetvdb.com/v4/search/remoteid?remoteId=tt9737326&type=series failed: HTTP Error 400: Bad Request -``` - -**After (clean):** -``` -INFO: All episodes found in cache -INFO: Completed processing TV series: Foundation (2021) [imdb-tt0804484] -INFO: Completed processing TV series: Invasion (2021) [imdb-tt9737326] -``` - -### Your Configuration -```bash -DEBUG=false # Clean production logging -PATH_DEBUG=false # No path mapping debug -SUPPRESS_TVDB_WARNINGS=true # Hide non-critical TVDB failures -``` - -### System Status -- ✅ **Processing**: All TV series processing successfully -- ✅ **Episodes**: All episodes found and processed -- ✅ **NFO Files**: Being created/updated with proper metadata -- ✅ **Functionality**: TVDB failures don't affect operation - -## 🔇 NFOGuard v1.5.2 - Ultra-clean production logs! 🔇 - -### Copy SUPPRESS_TVDB_WARNINGS=true to your server .env file and restart! - ---- - -## 🔧 FIXED: Database Upsert Bug (September 15, 2025) - **CRITICAL** - -### Issue Discovery -**The Real Root Cause**: Manual scans were NOT actually saving `dateadded` to database due to faulty upsert operation! - -### Problem Details -**Database Method Bug** in `core/database.py:173-182`: -- `upsert_movie_dates()` was doing UPDATE-only, not proper upsert -- If movie row didn't exist properly, UPDATE would affect 0 rows -- `dateadded` field remained NULL even after manual scan -- Webhooks found database entries but with NULL `dateadded` → fell back to current timestamp - -### 🔧 **Fix Applied** -- **Location**: `core/database.py:173-186` -- **Changed**: UPDATE-only → proper `INSERT OR REPLACE` upsert -- **Result**: Manual scans now properly save `dateadded` to database -- **Webhook Impact**: Now finds existing dates correctly, no more false timestamps - -### Before vs After Database Operations -**Before (BROKEN):** -```sql -UPDATE movies SET dateadded = '2025-06-15...' WHERE imdb_id = 'tt123'; --- If row doesn't exist properly: 0 rows affected, dateadded stays NULL -``` - -**After (FIXED):** -```sql -INSERT OR REPLACE INTO movies (...) VALUES (...); --- Always works: Creates row OR replaces with all data including dateadded -``` - ---- - -## 🎯 FIXED: Webhook Date Logic Issue (September 15, 2025) - -### Issue Discovery -Upgrade webhooks were incorrectly using current timestamp (`webhook:first_seen`) instead of checking Radarr for proper import dates when no database entry existed. - -**Example Problem:** -- Database populated via manual scan: `2025-06-15T11:10:31-04:00` (radarr:db.history.import) -- Upgrade webhook comes in: `2025-09-15T12:04:23-04:00` (webhook:first_seen) ❌ **WRONG!** - -### Root Cause -Webhook mode was bypassing the full date decision logic (`_decide_movie_dates`) and jumping straight to current timestamp as fallback. - -### ✅ **Fix Applied** -- **Location**: `nfoguard.py:975-990` -- **Logic**: Webhook mode now uses same date priority as manual scans: - 1. **Database first** (if exists) - 2. **Full date logic** (Radarr import → release dates → fallbacks) - 3. **Current timestamp** (only as absolute last resort) - -### Result -Webhook upgrades now properly find and use existing Radarr import dates instead of creating false "first seen" timestamps. - ---- - -## 🔧 FIXED: Radarr Rename Event Issue (September 15, 2025) - -### Issue Resolution -**COMPLETED**: Fixed missing Radarr rename event handling by adding proper event type filtering. - -### ✅ **Both Sonarr & Radarr Webhook Handling** - **NOW WORKING CORRECTLY** -- **Sonarr Location**: `nfoguard.py:1429` -- **Radarr Location**: `nfoguard.py:1479` **(FIXED)** -- **Event Filtering**: `if event_type not in ["Download", "Upgrade", "Rename"]:` -- **✅ STATUS**: **Rename events ARE processed for both systems** -- **✅ BEHAVIOR**: Both systems now update NFO files with proper date metadata on rename - -### What Was Fixed -1. **Added Event Type Filtering**: Radarr webhooks now explicitly filter for supported events -2. **Consistent Processing**: Both Sonarr and Radarr now follow identical webhook workflows -3. **Proper Rename Handling**: Rename events trigger full NFO processing pipeline - ---- - -## 📋 NFOGuard Webhook Workflow Documentation - -### 🎬 **Radarr Webhook Workflow** -1. **Import Event**: - - Check database - if not seen before, current timestamp = truth of first import - - Update movie.nfo with proper date metadata - -2. **Rename Event**: - - Check database - if we have the date, use existing date - - Update movie.nfo file as always (preserving original import date) - -3. **Rename Event (No Database Entry)**: - - Check Radarr database for earliest import date - - If found, use earliest import date → update database + movie.nfo - - If no import date found, use digital/theatrical release date (fallback logic) - -### 📺 **Sonarr Webhook Workflow** -1. **Import Event**: - - Check database - if not seen before, current timestamp = truth of first import - - Update episode.nfo with proper date metadata - -2. **Rename Event**: - - Check database - if we have the date, use existing date - - Update episode.nfo file as always (preserving original import date) - -3. **Rename Event (No Database Entry)**: - - Check Sonarr API for earliest import date - - If found, use earliest import date → update database + episode.nfo - - If no import date found, use air date (fallback logic) - -### 🔄 **Key Processing Logic** -- **Database First**: Always check NFOGuard database for existing dates -- **Import Truth**: Webhook import events establish "source of truth" timestamps -- **Date Preservation**: Rename events preserve original import dates, never overwrite -- **Smart Fallbacks**: API queries → Release dates → Air dates → File dates (configurable) -- **Batch Processing**: All webhooks go through batching system with configurable delays \ No newline at end of file