initial update

This commit is contained in:
2025-09-21 09:25:36 -04:00
parent f5fd954ebb
commit 22483717c4
11 changed files with 994 additions and 613 deletions
+294 -1
View File
@@ -1,6 +1,299 @@
# 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**: `<uniqueid type="imdb">tt123456</uniqueid>` (NEW)
4. **Legacy NFO Tags**: `<imdbid>` and `<imdb>` 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.0 - NFO-Based Identification! 📄
## 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