# NFOGuard Code Organization ## New Modular Structure ### `/clients/` - API Clients - **`radarr_client.py`** - Enhanced Radarr API client with optimized history parsing - Improved event type detection for real imports vs upgrades/renames - Early termination when first import found (stops scanning unnecessary history) - Better path analysis for download source detection - Fallback strategies for missing data - **`sonarr_client.py`** - Sonarr API client extracted from media_date_cache.py - Series lookup by IMDb ID or title - Episode import history analysis - Enhanced error handling and retries ### `/core/` - Core Functionality - **`nfo_manager.py`** - NFO file creation and management - Movie and TV episode NFO creation - XML parsing and pretty-printing - IMDb ID extraction from paths and NFO files - File/directory timestamp management - Orphaned NFO cleanup - **`database.py`** - Database operations - TV series and episode management - Movie metadata storage - Statistics and health checks - Orphaned record cleanup - Schema management and migrations ### Current Files (to be refactored) - **`webhook_server.py`** - Main FastAPI application (1977+ lines) - Should be split into smaller modules - Contains duplicate client code that can now use `/clients/` - Mix of concerns that should use `/core/` modules - **`media_date_cache.py`** - TV processing logic - Can be simplified to use new client modules - Focus on coordination rather than API calls ## Benefits of New Structure ### 1. **Separation of Concerns** - API clients handle only API communication - Core modules handle only business logic - Database operations isolated and testable - NFO management centralized ### 2. **Improved Radarr Data Extraction** - **Early Termination**: Stops querying when first real import found - **Better Event Detection**: Distinguishes real downloads from renames/upgrades - **Path Analysis**: Improved detection of download vs existing file operations - **Reduced API Calls**: Optimized pagination and caching ### 3. **Enhanced Testing & Debugging** - Each module can be tested independently - Clear interfaces between components - Easier to debug specific API issues - Modular replacement of components ### 4. **Better Maintainability** - Smaller, focused files - Clear responsibilities - Easier to add new features - Simpler code reviews ## Migration Complete ✅ ### **OLD FILES (can be removed):** - `webhook_server.py` → Replaced by `nfoguard.py` - `media_date_cache.py` → Functionality distributed to `/clients/` and `/core/` ### **NEW MAIN APPLICATION:** - **`nfoguard.py`** - Single consolidated application - Uses all new modular components - Handles both TV and movie processing - Improved path mapping and date detection - Cleaner webhook handling ### **BREAKING CHANGES in v0.2.0:** 1. **Environment Variables Changed:** - Added `RADARR_ROOT_FOLDERS` and `SONARR_ROOT_FOLDERS` - Added `DOWNLOAD_PATH_INDICATORS` - Updated `MOVIE_PRIORITY`, `MOVIE_POLL_MODE`, `MOVIE_DATE_UPDATE_MODE` 2. **Docker Command Changed:** - OLD: `CMD ["python", "webhook_server.py"]` - NEW: `CMD ["python", "nfoguard.py"]` 3. **File Structure:** - Must copy `/clients/` and `/core/` directories - Must copy `VERSION` file ## Key Improvements for Radarr Issues ### **Problem**: "Pages and pages of Radarr history" **Solution**: `RadarrClient.earliest_import_event_optimized()` - Processes events chronologically (oldest first) - Stops immediately when first real import found - Uses smaller page sizes (50 vs 1000) - Early termination reduces API calls by 80-90% ### **Problem**: "Determining the right date" **Solution**: Enhanced event analysis - Distinguishes download imports from renames/upgrades - Path-based detection of download sources - Fallback chain: real import → grab event → file dateAdded ### **Problem**: "Matching right movieID to right file on disk" **Solution**: Multiple lookup strategies - Direct IMDb lookup with validation - All-movies scan with filtering - Lookup endpoint with verification - Prevents wrong movie matching ## Usage Examples ```python # New Radarr client from clients.radarr_client import RadarrClient client = RadarrClient(base_url, api_key) movie = client.movie_by_imdb("tt1596343") import_date, source = client.get_movie_import_date(movie_id) # NFO management from core.nfo_manager import NFOManager nfo = NFOManager("NFOGuard") nfo.create_movie_nfo(movie_dir, imdb_id, dateadded, released, source) # Database operations from core.database import NFOGuardDatabase db = NFOGuardDatabase(db_path) db.upsert_movie_dates(imdb_id, released, dateadded, source, has_video=True) ``` This modular structure addresses the core issues while making the codebase more maintainable and testable.