initial update
This commit is contained in:
+294
-1
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user