diff --git a/api/routes.py b/api/routes.py index e5c25c9..c5435c7 100644 --- a/api/routes.py +++ b/api/routes.py @@ -2391,7 +2391,7 @@ def register_routes(app, dependencies: dict): imdb_id = "unknown" try: - # Parse the NFO file we already know exists (since grep found it missing dateadded) + # Try to parse the NFO file we already know exists (since grep found it missing dateadded) tree = ET.parse(nfo_file) root = tree.getroot() @@ -2418,26 +2418,43 @@ def register_routes(app, dependencies: dict): imdb_text = content_match.group(1) print(f"✅ Found IMDb {imdb_text} in NFO content: {os.path.basename(nfo_file)}") return imdb_text - - # Method 4: Fallback - check folder structure for episodes - if is_episode: - series_folder = os.path.dirname(os.path.dirname(nfo_file)) - folder_name = os.path.basename(series_folder) - folder_match = re.search(r'\[imdb-(tt\d+)\]', folder_name, re.IGNORECASE) - if folder_match: - print(f"✅ Found IMDb {folder_match.group(1)} in folder: {folder_name}") - return folder_match.group(1) - else: - # For movies, check movie folder - movie_folder = os.path.dirname(nfo_file) - folder_name = os.path.basename(movie_folder) - folder_match = re.search(r'\[imdb-(tt\d+)\]', folder_name, re.IGNORECASE) - if folder_match: - print(f"✅ Found IMDb {folder_match.group(1)} in folder: {folder_name}") - return folder_match.group(1) + except ET.ParseError as e: + # Handle malformed XML by trying text-based search + print(f"⚠️ NFO XML parse error in {os.path.basename(nfo_file)}: {e}") + try: + # Fallback: Read as text and search for IMDb patterns + with open(nfo_file, 'r', encoding='utf-8', errors='ignore') as f: + nfo_text = f.read() + + # Search for IMDb patterns in raw text + text_match = re.search(r'(tt\d{7,})', nfo_text) + if text_match: + imdb_text = text_match.group(1) + print(f"✅ Found IMDb {imdb_text} in NFO text content: {os.path.basename(nfo_file)}") + return imdb_text + except Exception as text_error: + print(f"⚠️ Error reading NFO as text {nfo_file}: {text_error}") + except Exception as e: - print(f"⚠️ Error parsing NFO for IMDb in {nfo_file}: {e}") + print(f"⚠️ Unexpected error parsing NFO {nfo_file}: {e}") + + # Method 4: Fallback - check folder structure + if is_episode: + series_folder = os.path.dirname(os.path.dirname(nfo_file)) + folder_name = os.path.basename(series_folder) + folder_match = re.search(r'\[imdb-(tt\d+)\]', folder_name, re.IGNORECASE) + if folder_match: + print(f"✅ Found IMDb {folder_match.group(1)} in folder: {folder_name}") + return folder_match.group(1) + else: + # For movies, check movie folder + movie_folder = os.path.dirname(nfo_file) + folder_name = os.path.basename(movie_folder) + folder_match = re.search(r'\[imdb-(tt\d+)\]', folder_name, re.IGNORECASE) + if folder_match: + print(f"✅ Found IMDb {folder_match.group(1)} in folder: {folder_name}") + return folder_match.group(1) print(f"❌ No IMDb ID found in {os.path.basename(nfo_file)}") return "unknown" @@ -2568,7 +2585,7 @@ def register_routes(app, dependencies: dict): with db.get_connection() as conn: cursor = conn.cursor() cursor.execute(""" - SELECT dateadded, source, added_by + SELECT dateadded, source FROM episodes WHERE imdb_id = %s AND season = %s AND episode = %s LIMIT 1 @@ -2578,7 +2595,6 @@ def register_routes(app, dependencies: dict): if result: episode["dateadded"] = result["dateadded"] episode["source"] = result.get("source", "database") - episode["added_by"] = result.get("added_by", "unknown") else: print(f"⚠️ No database entry for {episode['imdb_id']} S{episode['season']:02d}E{episode['episode']:02d}") except Exception as e: @@ -2591,7 +2607,7 @@ def register_routes(app, dependencies: dict): with db.get_connection() as conn: cursor = conn.cursor() cursor.execute(""" - SELECT dateadded, source, added_by + SELECT dateadded, source FROM movies WHERE imdb_id = %s LIMIT 1 @@ -2601,7 +2617,6 @@ def register_routes(app, dependencies: dict): if result: movie["dateadded"] = result["dateadded"] movie["source"] = result.get("source", "database") - movie["added_by"] = result.get("added_by", "unknown") else: print(f"⚠️ No database entry for movie {movie['imdb_id']}") except Exception as e: diff --git a/nfoguard-web/static/css/styles.css b/nfoguard-web/static/css/styles.css index 0c06736..42e54f1 100644 --- a/nfoguard-web/static/css/styles.css +++ b/nfoguard-web/static/css/styles.css @@ -958,6 +958,97 @@ body { border-radius: 0.375rem; } +/* NFO Repair Table Styling */ +.nfo-repair-table-container { + background: white; + border-radius: 0.5rem; + box-shadow: var(--shadow); + overflow-x: auto; + overflow-y: auto; + max-height: 600px; + margin-bottom: 1rem; + border: 1px solid var(--border-color); +} + +.nfo-repair-table { + width: 100%; + min-width: 800px; + border-collapse: collapse; + font-size: 0.875rem; + background: white; +} + +.nfo-repair-table th { + background-color: var(--dark-color); + color: white; + padding: 0.75rem 0.5rem; + text-align: left; + font-weight: 600; + position: sticky; + top: 0; + z-index: 10; +} + +.nfo-repair-table td { + padding: 0.75rem 0.5rem; + border-bottom: 1px solid var(--border-color); + vertical-align: top; +} + +.nfo-repair-table tr:hover { + background-color: #f8f9fa; +} + +.media-type-badge { + padding: 0.25rem 0.5rem; + border-radius: 0.25rem; + font-size: 0.75rem; + font-weight: 600; + text-transform: uppercase; +} + +.media-type-badge.episode { + background-color: #e3f2fd; + color: #1976d2; +} + +.media-type-badge.movie { + background-color: #f3e5f5; + color: #7b1fa2; +} + +.status-ready { + color: #2e7d32; + font-weight: 600; + font-size: 0.75rem; +} + +.status-missing { + color: #d32f2f; + font-weight: 600; + font-size: 0.75rem; +} + +.text-center { + text-align: center; +} + +.text-muted { + color: #6c757d; +} + +.nfo-fix-actions { + margin-top: 1rem; + padding: 1rem; + background-color: #f8f9fa; + border-radius: 0.5rem; + text-align: center; +} + +.nfo-fix-actions .btn { + margin-bottom: 0.5rem; +} + .admin-tools { display: flex; flex-direction: column; diff --git a/nfoguard-web/static/index.html b/nfoguard-web/static/index.html index d4860b9..fbbbcd6 100644 --- a/nfoguard-web/static/index.html +++ b/nfoguard-web/static/index.html @@ -4,7 +4,7 @@