#!/usr/bin/env python3 """ Test script to verify episode matching logic with mock data. """ import sys import os from pathlib import Path # Add src to path sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'src')) from Matcher.episode_renamer import EpisodeRenamer def create_mock_episodes(): """Create mock episode data to test the matching logic.""" return [ { 'path': Path('Disc 1_t01.mkv'), 'name': 'Disc 1_t01.mkv', 'size_bytes': 2 * 1024**3, # 2GB 'size_gb': 2.0, 'duration_minutes': 61.0, }, { 'path': Path('Disc 1_t02.mkv'), 'name': 'Disc 1_t02.mkv', 'size_bytes': 2.1 * 1024**3, # 2.1GB 'size_gb': 2.1, 'duration_minutes': 55.0, }, { 'path': Path('Disc 1_t03.mkv'), 'name': 'Disc 1_t03.mkv', 'size_bytes': 2.2 * 1024**3, # 2.2GB 'size_gb': 2.2, 'duration_minutes': 57.0, }, { 'path': Path('Disc 2_t01.mkv'), 'name': 'Disc 2_t01.mkv', 'size_bytes': 2.0 * 1024**3, # 2GB 'size_gb': 2.0, 'duration_minutes': 55.0, }, { 'path': Path('Disc 2_t02.mkv'), 'name': 'Disc 2_t02.mkv', 'size_bytes': 2.1 * 1024**3, # 2.1GB 'size_gb': 2.1, 'duration_minutes': 54.0, }, { 'path': Path('Disc 2_t03.mkv'), 'name': 'Disc 2_t03.mkv', 'size_bytes': 1.9 * 1024**3, # 1.9GB 'size_gb': 1.9, 'duration_minutes': 52.0, }, { 'path': Path('Disc 3_t01.mkv'), 'name': 'Disc 3_t01.mkv', 'size_bytes': 2.2 * 1024**3, # 2.2GB 'size_gb': 2.2, 'duration_minutes': 57.0, }, { 'path': Path('Disc 3_t02.mkv'), 'name': 'Disc 3_t02.mkv', 'size_bytes': 2.1 * 1024**3, # 2.1GB 'size_gb': 2.1, 'duration_minutes': 58.0, } ] def create_mock_tvdb_episodes(): """Create mock TVDB episode data.""" return [ {'episode_number': 1, 'name': 'Winter Is Coming', 'runtime': 61}, {'episode_number': 2, 'name': 'The Kingsroad', 'runtime': 55}, {'episode_number': 3, 'name': 'Lord Snow', 'runtime': 57}, {'episode_number': 4, 'name': 'Cripples, Bastards, and Broken Things', 'runtime': 55}, {'episode_number': 5, 'name': 'The Wolf and the Lion', 'runtime': 54}, {'episode_number': 6, 'name': 'A Golden Crown', 'runtime': 52}, {'episode_number': 7, 'name': 'You Win or You Die', 'runtime': 57}, {'episode_number': 8, 'name': 'The Pointy End', 'runtime': 58}, {'episode_number': 9, 'name': 'Baelor', 'runtime': 56}, {'episode_number': 10, 'name': 'Fire and Blood', 'runtime': 52}, ] def test_episode_matching(): """Test the episode matching logic.""" print("=== Testing Episode Matching Logic ===\n") # Create mock data episodes = create_mock_episodes() tvdb_episodes = create_mock_tvdb_episodes() print(f"Mock episode files ({len(episodes)}):") for ep in episodes: print(f" - {ep['name']} ({ep['duration_minutes']} min)") print(f"\nTVDB episodes ({len(tvdb_episodes)}):") for ep in tvdb_episodes: print(f" - Episode {ep['episode_number']}: {ep['name']} ({ep['runtime']} min)") # Initialize renamer renamer = EpisodeRenamer("/tmp/test", "Game of Thrones", 1) # Test the matching logic print("\n" + "="*80) print("TESTING EPISODE MATCHING") print("="*80) try: matched_episodes = renamer._match_episodes_by_duration(episodes, tvdb_episodes) print(f"\n=== MATCHING RESULTS ===") print(f"Successfully matched {len(matched_episodes)} episodes:") for match in matched_episodes: file_name = match['file_info']['path'].name episode_num = match['episode_number'] tvdb_name = match['tvdb_info']['name'] if match['tvdb_info'] else 'Unknown' duration_diff = match.get('duration_diff', 'N/A') print(f" {file_name} → Episode {episode_num}: {tvdb_name}") if duration_diff != 'N/A' and duration_diff is not None: print(f" Duration difference: {duration_diff:.1f} minutes") # Test validity of assignments print(f"\n=== ASSIGNMENT VALIDATION ===") episode_numbers = [m['episode_number'] for m in matched_episodes] if len(set(episode_numbers)) == len(episode_numbers): print("✓ All episodes assigned unique episode numbers") else: print("✗ Duplicate episode number assignments detected!") duplicates = [x for x in episode_numbers if episode_numbers.count(x) > 1] print(f" Duplicates: {set(duplicates)}") # Check disc order constraint disc_assignments = {} for match in matched_episodes: file_name = match['file_info']['path'].name episode_num = match['episode_number'] # Extract disc number if 'Disc 1' in file_name: disc = 1 elif 'Disc 2' in file_name: disc = 2 elif 'Disc 3' in file_name: disc = 3 else: disc = None if disc: if disc not in disc_assignments: disc_assignments[disc] = [] disc_assignments[disc].append(episode_num) print(f"\nDisc assignment validation:") for disc in sorted(disc_assignments.keys()): episodes = sorted(disc_assignments[disc]) print(f" Disc {disc}: Episodes {episodes}") # Check if episodes are in reasonable order (earlier discs should have earlier episodes) if disc == 1: expected_range = list(range(1, 4)) # Episodes 1-3 elif disc == 2: expected_range = list(range(4, 7)) # Episodes 4-6 elif disc == 3: expected_range = list(range(7, 9)) # Episodes 7-8 if set(episodes).issubset(set(expected_range)): print(f" ✓ Episodes {episodes} are within expected range {expected_range}") else: print(f" ⚠ Episodes {episodes} outside expected range {expected_range}") except Exception as e: print(f"Error during matching: {e}") import traceback traceback.print_exc() if __name__ == "__main__": test_episode_matching()