From 3889d3a31cc67392e4f7ef8414de353d444e64be Mon Sep 17 00:00:00 2001 From: SBCrumb Date: Wed, 24 Sep 2025 11:21:38 -0400 Subject: [PATCH] feat: Add three-tier optimization for maximum performance Implemented smart caching system that dramatically reduces processing time: TIER 1 (Fastest): NFO File Check - If NFO already has NFOGuard dateadded + lockdata, use it directly - Skips both database queries AND API calls - Perfect for movies already processed by NFOGuard TIER 2 (Fast): Database Check - If database has complete dateadded data, use it - Skips expensive API calls to TMDB/OMDB/Radarr - Creates NFO from cached data TIER 3 (Slowest): Full Processing - Only when neither NFO nor database have data - Queries all APIs, processes dates, saves to database This should dramatically improve full scan performance, especially on subsequent runs where most movies already have NFOGuard data. Expected speedup: 90%+ reduction in processing time for warm scans. --- core/nfo_manager.py | 35 +++++++++++++++++++++++++++++++++++ nfoguard.py | 18 +++++++++++++++++- 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/core/nfo_manager.py b/core/nfo_manager.py index a632fd5..753b5b6 100644 --- a/core/nfo_manager.py +++ b/core/nfo_manager.py @@ -114,6 +114,41 @@ class NFOManager: print(f"❌ No IMDb ID found in directory, filenames, or NFO for: {movie_dir.name}") return None + def extract_nfoguard_dates_from_nfo(self, nfo_path: Path) -> Optional[Dict[str, str]]: + """Extract NFOGuard-managed dates from existing NFO file""" + if not nfo_path.exists(): + return None + + try: + tree = ET.parse(nfo_path) + root = tree.getroot() + + # Look for NFOGuard fields + dateadded_elem = root.find('.//dateadded') + premiered_elem = root.find('.//premiered') + lockdata_elem = root.find('.//lockdata') + + # Only consider it NFOGuard-managed if it has dateadded and lockdata + if (dateadded_elem is not None and dateadded_elem.text and + lockdata_elem is not None and lockdata_elem.text == "true"): + + result = { + "dateadded": dateadded_elem.text.strip(), + "source": "nfo_file_existing" + } + + if premiered_elem is not None and premiered_elem.text: + result["released"] = premiered_elem.text.strip() + + print(f"✅ Found NFOGuard data in NFO: dateadded={result['dateadded']}, released={result.get('released', 'None')}") + return result + + except (ET.ParseError, Exception) as e: + print(f"⚠️ Error parsing NFO for NFOGuard data: {e}") + pass + + return None + def _parse_nfo_with_tolerance(self, nfo_path: Path): """Parse NFO file with tolerance for URLs appended after XML""" try: diff --git a/nfoguard.py b/nfoguard.py index 16369a9..31f1b55 100644 --- a/nfoguard.py +++ b/nfoguard.py @@ -970,7 +970,23 @@ class MovieProcessor: self.db.upsert_movie_dates(imdb_id, None, None, None, False) return - # Get existing dates + # TIER 1: Check if NFO file already has NFOGuard data (fastest - no DB or API calls) + nfo_path = movie_path / "movie.nfo" + nfo_data = self.nfo_manager.extract_nfoguard_dates_from_nfo(nfo_path) + if nfo_data: + _log("INFO", f"🚀 Using existing NFOGuard data from NFO file: {nfo_data['dateadded']} (source: {nfo_data['source']})") + dateadded = nfo_data["dateadded"] + source = nfo_data["source"] + released = nfo_data.get("released") + + # Update file mtimes if enabled (NFO is already correct) + if config.fix_dir_mtimes and dateadded: + self.nfo_manager.update_movie_files_mtime(movie_path, dateadded) + + _log("INFO", f"Completed processing movie: {movie_path.name} (source: {source}) [nfo-only]") + return + + # TIER 2: Check database for existing data existing = self.db.get_movie_dates(imdb_id) _log("DEBUG", f"Database lookup for {imdb_id}: {existing}")