feature: more omprovments phase 3
Build & Push DEV to DockerHub / docker (pull_request) Failing after 33s

This commit is contained in:
2025-09-27 12:53:20 -04:00
parent 03d9db9364
commit d7426281de
7 changed files with 1505 additions and 112 deletions
+17 -81
View File
@@ -3,7 +3,6 @@ TV Series Processor for NFOGuard
Handles TV series processing and episode management
"""
import os
import glob
import re
from pathlib import Path
from typing import Optional, Dict, List, Set, Tuple, Any
@@ -16,6 +15,11 @@ from clients.sonarr_client import SonarrClient
from clients.external_clients import ExternalClientManager
from config.settings import config
from utils.logging import _log
from utils.file_utils import (
find_media_path_by_imdb_and_title,
find_episodes_on_disk,
extract_title_from_directory_name
)
class TVProcessor:
@@ -32,36 +36,14 @@ class TVProcessor:
self.external_clients = ExternalClientManager()
def find_series_path(self, series_title: str, imdb_id: str, sonarr_path: str = None) -> Optional[Path]:
"""Find series directory path"""
# Try webhook path first
if sonarr_path:
container_path = self.path_mapper.sonarr_path_to_container_path(sonarr_path)
path_obj = Path(container_path)
if path_obj.exists():
return path_obj
# Search by IMDb ID or title
for media_path in config.tv_paths:
if not media_path.exists():
continue
# Search by IMDb ID
if imdb_id:
pattern = str(media_path / f"*[imdb-{imdb_id}]*")
matches = glob.glob(pattern)
if matches:
return Path(matches[0])
# Search by title
if series_title:
title_clean = series_title.lower().replace(" ", "").replace("-", "")
for item in media_path.iterdir():
if item.is_dir() and "[imdb-" in item.name.lower():
item_clean = item.name.lower().replace(" ", "").replace("-", "")
if title_clean in item_clean:
return item
return None
"""Find series directory path using unified file utilities"""
return find_media_path_by_imdb_and_title(
title=series_title,
imdb_id=imdb_id,
search_paths=config.tv_paths,
webhook_path=sonarr_path,
path_mapper=self.path_mapper
)
def process_series(self, series_path: Path) -> None:
"""Process a TV series directory"""
@@ -76,7 +58,7 @@ class TVProcessor:
self.db.upsert_series(imdb_id, str(series_path))
# Find video files
disk_episodes = self._find_disk_episodes(series_path)
disk_episodes = find_episodes_on_disk(series_path)
_log("INFO", f"Found {len(disk_episodes)} episodes on disk")
# Get episode dates
@@ -108,55 +90,9 @@ class TVProcessor:
_log("INFO", f"Completed processing TV series: {series_path.name}")
def _extract_series_title_from_path(self, series_path: Path) -> Optional[str]:
"""Extract series title from directory path, removing year and IMDb ID"""
name = series_path.name
# Remove IMDb ID part: [imdb-ttXXXXXX] or [ttXXXXXX]
name = re.sub(r'\s*\[imdb-?tt\d+\]', '', name, flags=re.IGNORECASE)
name = re.sub(r'\s*\[tt\d+\]', '', name, flags=re.IGNORECASE)
# Remove year in parentheses: (YYYY)
name = re.sub(r'\s*\(\d{4}\)', '', name)
# Clean up extra spaces
name = ' '.join(name.split())
return name.strip() if name.strip() else None
"""Extract series title from directory path using unified file utilities"""
return extract_title_from_directory_name(series_path.name)
def _find_disk_episodes(self, series_path: Path) -> Dict[Tuple[int, int], List[Path]]:
"""Find all episodes on disk and return mapping of (season, episode) -> [video_files]"""
episodes = {}
if not series_path.exists():
return episodes
video_extensions = {'.mkv', '.mp4', '.avi', '.m4v', '.mov', '.ts'}
# Define regex pattern for episode files
episode_pattern = re.compile(
r'.*[sS](\d{1,2})[eE](\d{1,3}).*|.*(\d{1,2})x(\d{1,3}).*'
)
for item in series_path.rglob('*'):
if item.is_file() and item.suffix.lower() in video_extensions:
# Try to extract season/episode from filename
match = episode_pattern.match(item.name)
if match:
if match.group(1) and match.group(2): # SxxExx format
season = int(match.group(1))
episode = int(match.group(2))
elif match.group(3) and match.group(4): # NxNN format
season = int(match.group(3))
episode = int(match.group(4))
else:
continue
key = (season, episode)
if key not in episodes:
episodes[key] = []
episodes[key].append(item)
return episodes
def _gather_episode_dates(self, series_path: Path, imdb_id: str, disk_episodes: Dict[Tuple[int, int], List[Path]]) -> Dict[Tuple[int, int], Tuple[Optional[str], Optional[str], str]]:
"""Gather episode air dates and date added information"""
@@ -251,7 +187,7 @@ class TVProcessor:
_log("INFO", f"Processing season {season_num} of series: {series_path_obj.name}")
# Find episodes in this season
disk_episodes = self._find_disk_episodes(series_path_obj)
disk_episodes = find_episodes_on_disk(series_path_obj)
season_episodes = {k: v for k, v in disk_episodes.items() if k[0] == season_num}
if not season_episodes: