sbcrumb ca796bdb58
Local Docker Build (Main) / build (push) Successful in 4s
Local Docker Build (Main) / deploy (push) Successful in 0s
Merge branch 'dev'
2025-10-22 08:37:51 -04:00
2025-10-20 19:49:01 -04:00
2025-10-20 14:15:14 -04:00
2025-09-29 09:23:48 -04:00
2025-09-27 13:00:08 -04:00
2025-10-17 10:32:25 -04:00
2025-10-20 19:49:01 -04:00

NFOGuard

Docker Pulls Docker Image Version Docker Image Size

Automated NFO file management for Radarr and Sonarr with intelligent date handling


🔌 Emby Plugin Included: The Emby companion plugin is now bundled directly into the Docker image — no extra steps required.

💬 Community Feedback: Join our Discord if you'd like to share feedback, test new features, or discuss improvements with other users:

Join Discord: https://discord.gg/ZykJRGt72b


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

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

  • Async I/O Operations - High-performance concurrent file processing
  • Batch Processing - Efficient handling of multiple files simultaneously
  • PostgreSQL Database - Production-ready database with optimized queries
  • Smart Skip Logic - Database-first checking eliminates expensive filesystem scans
  • 88% Scan Optimization - Subsequent scans reduced from hours to minutes via smart skip logic

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

Production Ready

  • Docker & Kubernetes - Health checks for orchestration platforms
  • Graceful Shutdown - Proper signal handling for container management
  • Configuration CLI - Validation tools for troubleshooting
  • Modular Architecture - Clean separation of concerns for maintainability

Quick Start

1. Download Configuration Files

wget https://raw.githubusercontent.com/sbcrumb/nfoguard/main/.env.template
wget https://raw.githubusercontent.com/sbcrumb/nfoguard/main/.env.secrets.template
wget https://raw.githubusercontent.com/sbcrumb/nfoguard/main/docker-compose.example.yml

2. Configure Environment

# Copy and edit main configuration
cp .env.template .env
nano .env

# Copy and edit secrets (API keys, passwords)
cp .env.secrets.template .env.secrets
nano .env.secrets
chmod 600 .env.secrets

# Copy and edit Docker Compose
cp docker-compose.example.yml docker-compose.yml
nano docker-compose.yml

3. Deploy

# Create data directory
mkdir -p ./data

# Start NFOGuard
docker-compose up -d

# Check logs
docker-compose logs -f nfoguard

# Verify health
curl http://localhost:8080/health

Configuration

Environment Files

File Purpose Contains
.env Main configuration Paths, behavior settings, non-sensitive options
.env.secrets Sensitive data API keys, passwords, database credentials

Key Configuration Options

Media Paths (Required):

# Container paths (what NFOGuard sees)
MOVIE_PATHS=/media/Movies/movies,/media/Movies/movies6
TV_PATHS=/media/TV/tv,/media/TV/tv6

# *arr application paths (what your apps see)
RADARR_ROOT_FOLDERS=/mnt/unionfs/Media/Movies/movies
SONARR_ROOT_FOLDERS=/mnt/unionfs/Media/TV/tv

Release Date Priority:

RELEASE_DATE_PRIORITY=digital,physical,theatrical

Debug Mode:

DEBUG=false                    # Clean production logs
SUPPRESS_TVDB_WARNINGS=true    # Hide non-critical API failures

Docker Images

Production (Stable)

image: sbcrumb/nfoguard:latest

Development (Latest Features)

image: sbcrumb/nfoguard:dev

Specific Version

image: sbcrumb/nfoguard:v2.6.7  # Latest with PostgreSQL & optimization

🚀 Version 2.6.7 includes major architecture improvements, PostgreSQL database migration, 88% scan optimization, async I/O performance enhancements, comprehensive monitoring, and configuration validation.

🔗 Webhook Setup

Configure these webhook URLs in your applications:

Radarr: http://nfoguard:8080/webhook/radarr
Sonarr: http://nfoguard:8080/webhook/sonarr

Triggers: On Import, On Upgrade, On Rename

🔄 Manual Operations

Manual Scanning

Trigger manual scans via API endpoints:

# Manual scan all media (movies and TV)
curl -X POST "http://localhost:8080/manual/scan?scan_type=both"

# Manual scan TV only
curl -X POST "http://localhost:8080/manual/scan?scan_type=tv"

# Manual scan movies only
curl -X POST "http://localhost:8080/manual/scan?scan_type=movies"

# Manual scan specific path
curl -X POST "http://localhost:8080/manual/scan?path=/media/movies"

# Bulk update all movies from Radarr database
curl -X POST "http://localhost:8080/bulk/update"

# Verify NFO files match database data
curl -X POST "http://localhost:8080/database/verify/nfo-sync?media_type=both"

# Fix NFO files that don't match database
curl -X POST "http://localhost:8080/database/fix/nfo-sync?media_type=both"

NFO Verification & Synchronization

NFOGuard includes comprehensive verification tools to ensure NFO files remain synchronized with database dates:

# Verify all NFO files (movies and episodes)
curl -X POST "http://localhost:8080/database/verify/nfo-sync?media_type=both"

# Verify only movies
curl -X POST "http://localhost:8080/database/verify/nfo-sync?media_type=movies"

# Verify only TV episodes  
curl -X POST "http://localhost:8080/database/verify/nfo-sync?media_type=episodes"

# Fix detected issues by regenerating NFO files
curl -X POST "http://localhost:8080/database/fix/nfo-sync?media_type=both"

Verification Checks:

  • Missing NFO files - Database entries without corresponding NFO files
  • Empty NFO files - NFO files that exist but contain no content
  • Date mismatches - Database dates don't match NFO file dates
  • Source mismatches - Database source doesn't match NFO source information

Fix Operations:

  • Regenerates NFO files from database data for any detected issues
  • Preserves existing metadata while updating NFOGuard date sections
  • Only operates when MANAGE_NFO=true is configured
  • Creates proper movie.nfo and episode S##E##.nfo files

API Endpoints

Core Operations

Endpoint Method Purpose
/webhook/radarr POST Radarr webhook handler
/webhook/sonarr POST Sonarr webhook handler
/manual/scan POST Manual media scanning
/bulk/update POST Bulk update from Radarr database

Health & Monitoring

Endpoint Method Purpose
/api/v1/health GET Comprehensive health status
/api/v1/health/ready GET Kubernetes readiness probe
/api/v1/health/live GET Kubernetes liveness probe
/api/v1/status GET Complete system status
/api/v1/status/brief GET Quick system overview

Metrics & Performance

Endpoint Method Purpose
/api/v1/metrics GET Prometheus metrics (text format)
/api/v1/metrics/json GET Metrics in JSON format
/api/v1/metrics/processing GET Processing-specific metrics
/api/v1/metrics/errors GET Error metrics and recent failures
/api/v1/metrics/system GET System resource metrics

Database Management

Endpoint Method Purpose
/database/backfill/movie-release-dates POST Backfill missing release dates for existing movies
/database/cleanup/orphaned-episodes POST Delete episodes without video files
/database/cleanup/orphaned-movies POST Delete movies without video files
/database/cleanup/orphaned-series POST Delete TV series without directories
/database/verify/nfo-sync POST Verify that database dates match NFO file contents
/database/fix/nfo-sync POST Fix NFO sync issues by regenerating NFO files from database data

Configuration & Debugging

Endpoint Method Purpose
/debug/movie/{imdb_id}/priority GET Debug movie priority logic
/debug/tmdb/{imdb_id} GET Debug TMDB lookup
/ping GET Simple connectivity test

Manual Scan Parameters

  • scan_type: both, movies, tv
  • path: Specific directory path to scan
  • Use for initial setup or fixing existing media

📁 Volume Mapping

Critical: Update docker-compose.yml with your actual paths:

volumes:
  - ./data:/app/data                           # NFOGuard data
  - /your/movies/path:/media/Movies/movies:rw  # Movie library
  - /your/tv/path:/media/TV/tv:rw              # TV library

Common Examples

Unraid:

- /mnt/user/Media/Movies:/media/Movies/movies:rw
- /mnt/user/Media/TV:/media/TV/tv:rw

Synology:

- /volume1/Media/Movies:/media/Movies/movies:rw
- /volume1/Media/TV:/media/TV/tv:rw

Standard Linux:

- /home/user/media/movies:/media/Movies/movies:rw
- /home/user/media/tv:/media/TV/tv:rw

Troubleshooting

Check Logs

docker-compose logs -f nfoguard

Enable Debug Mode

# In .env file
DEBUG=true
PATH_DEBUG=true

Health Check

curl http://localhost:8080/health

Monitoring & Observability

NFOGuard provides comprehensive monitoring capabilities for production deployments:

Health Checks

# Basic health status
curl http://localhost:8080/api/v1/health

# Kubernetes readiness probe  
curl http://localhost:8080/api/v1/health/ready

# Kubernetes liveness probe
curl http://localhost:8080/api/v1/health/live

# Quick system overview
curl http://localhost:8080/api/v1/status/brief

Metrics for Grafana/Prometheus

# Prometheus metrics format
curl http://localhost:8080/api/v1/metrics

# JSON metrics for dashboards
curl http://localhost:8080/api/v1/metrics/json

# Processing performance metrics
curl http://localhost:8080/api/v1/metrics/processing

# Error rates and recent failures
curl http://localhost:8080/api/v1/metrics/errors

# System resource usage
curl http://localhost:8080/api/v1/metrics/system

Configuration Validation

# Validate configuration before deployment
python config/validation_cli.py

# Include runtime tests (database, APIs, file access)
python config/validation_cli.py --runtime

# JSON output for automation
python config/validation_cli.py --runtime --json

Docker Health Checks

Add to your docker-compose.yml:

healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost:8080/api/v1/health/live"]
  interval: 30s
  timeout: 10s
  retries: 3
  start_period: 40s

Structured Logging

NFOGuard uses structured JSON logging with correlation IDs for request tracing:

# Enable structured logging
STRUCTURED_LOGGING=true

# Log level configuration  
LOG_LEVEL=INFO

# Example log output with correlation ID
{"timestamp": "2024-01-01T12:00:00Z", "level": "INFO", "correlation_id": "req_123", "message": "Webhook received", "context": {"webhook_type": "radarr", "media_type": "movie"}}

Common Issues

  1. Permission Errors: Ensure NFOGuard can write to mounted directories
  2. Path Mapping: Verify container paths match .env configuration
  3. Webhooks: Check URLs and ensure port 8080 is accessible
  4. Database: Verify PostgreSQL credentials in .env.secrets

What NFOGuard Does

Before

<movie>
  <title>Movie Title</title>
  <year>2023</year>
  <!-- Existing Radarr metadata -->
</movie>

After

<movie>
  <title>Movie Title</title>
  <year>2023</year>
  <!-- Existing Radarr metadata preserved -->
  
  <!-- NFOGuard additions at bottom -->
  <digital_release_date>2023-03-15</digital_release_date>
  <lockdata>true</lockdata>
  <!-- Manager: NFOGuard -->
</movie>

📋 Requirements

  • Docker and Docker Compose
  • Radarr and/or Sonarr
  • Media files in accessible directories
  • Network connectivity between services

📁 Directory Structure Requirements

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

Directory Structure:

/movies/
└── Movie Title (2024) [tt1234567]/
    ├── movie.mkv
    └── movie.nfo (created by NFOGuard)

Identification Methods:

  1. Primary: Directory name contains IMDb ID in brackets: [tt1234567] or [imdb-tt1234567]
  2. Fallback: NFO file with IMDb ID in movie.nfo file (see NFO format below)
  3. Video file required: .mkv, .mp4, .avi, .mov, .m4v
  4. Case insensitive - [TT1234567] works too

Examples:

✅ Action Film (2024) [tt1234567]/
✅ Drama Movie [imdb-tt7654321]/
✅ SciFi Thriller (2023) [TT9876543]/
❌ Missing IMDB Directory/

📺 TV Shows

Directory Structure:

/tv/
└── Series Title (2024) [tt1234567]/
    ├── Season 01/
    │   ├── Series S01E01.mkv
    │   ├── Series S01E02.mkv
    │   ├── S01E01.nfo (created by NFOGuard)
    │   └── S01E02.nfo (created by NFOGuard)
    ├── Season 02/
    └── tvshow.nfo (created by NFOGuard)

Identification Methods:

  1. Primary: Series directory contains IMDb ID: [tt1234567] or [imdb-tt1234567]
  2. Fallback: NFO file with IMDb ID in tvshow.nfo file (see NFO format below)
  3. Season directories must match pattern: Season 01, Season 1, season 01 etc.
  4. Episode files must contain season/episode info:
    • SxxExx format: S01E01, S1E1, s01e01
    • Dot format: 1.1, 01.01
  5. Video extensions: .mkv, .mp4, .avi, .mov, .m4v, .ts, .m2ts

Examples:

✅ Drama Series (2024) [tt1234567]/
    ├── Season 01/
    │   ├── Drama S01E01.mkv
    │   └── Drama S01E02.mkv
    └── Season 02/

✅ Comedy Show [tt7654321]/
    └── Season 1/
        ├── Comedy 1.1.mkv
        └── Comedy 1.2.mkv

❌ Series Without IMDB []/
❌ Series [tt1234567]/Episode01.mkv (no season directory)
❌ Series [tt1234567]/Season 1/RandomName.mkv (no episode pattern)

📄 NFO File Identification Format

NFOGuard can extract IMDb IDs from existing NFO files using these XML tags:

Movie NFO (movie.nfo):

<!-- Method 1: uniqueid tag (preferred) -->
<uniqueid type="imdb">tt1234567</uniqueid>

<!-- Method 2: imdbid tag -->
<imdbid>tt1234567</imdbid>

<!-- Method 3: imdb tag -->
<imdb>tt1234567</imdb>

TV Show NFO (tvshow.nfo):

<!-- Same format as movies -->
<uniqueid type="imdb">tt1234567</uniqueid>
<imdbid>tt1234567</imdbid>
<imdb>tt1234567</imdb>

Episode NFO Files: NFOGuard creates standardized episode NFO files using the pattern S##E##.nfo:

  • S01E01.nfo for Season 1, Episode 1
  • S02E05.nfo for Season 2, Episode 5
  • Always zero-padded format (S01E01, not S1E1)
  • Smart Rename: NFOGuard will find existing NFO files (created by Sonarr/other tools), extract their metadata, and rename them to the standard format

🚫 What Gets Skipped

NFOGuard will ignore:

  • Directories without IMDb IDs in brackets AND no NFO files with IMDb IDs
  • Directories without video files
  • TV episodes without recognizable season/episode patterns
  • Season directories that don't match "Season X" format

🆘 Support

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

Commercial licensing and enterprise features may be available separately. Contact us for more information.


NFOGuard - Keeping your media metadata clean and organized! 🎯

S
Description
No description provided
Readme MIT 19 MiB
Languages
Python 81%
JavaScript 11.3%
HTML 4.7%
CSS 2.8%
Dockerfile 0.2%