feat: Implement NFOService.update_tvshow_nfo()
- Parse existing NFO to extract TMDB ID from uniqueid or tmdbid element - Fetch fresh metadata from TMDB API - Regenerate NFO with updated data - Optionally re-download media files - Add comprehensive error handling (missing NFO, no TMDB ID, invalid XML) - Add unit tests for XML parsing logic (4 tests, all passing) - Add integration test script (requires TMDB API key)
This commit is contained in:
183
scripts/test_nfo_update.py
Normal file
183
scripts/test_nfo_update.py
Normal file
@@ -0,0 +1,183 @@
|
||||
"""Test script for NFOService.update_tvshow_nfo() functionality.
|
||||
|
||||
This script tests the update functionality by:
|
||||
1. Creating a test NFO file with TMDB ID
|
||||
2. Updating it with fresh data from TMDB
|
||||
3. Verifying the update worked correctly
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import logging
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
# Add src to path
|
||||
sys.path.insert(0, str(Path(__file__).parent.parent))
|
||||
|
||||
from src.config.settings import settings
|
||||
from src.core.services.nfo_service import NFOService
|
||||
from src.core.services.tmdb_client import TMDBAPIError
|
||||
|
||||
# Configure logging
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
||||
)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def test_update_nfo():
|
||||
"""Test NFO update functionality."""
|
||||
|
||||
# Check if TMDB API key is configured
|
||||
if not settings.tmdb_api_key:
|
||||
logger.error("TMDB_API_KEY not configured in environment")
|
||||
logger.error("Set TMDB_API_KEY in .env file or environment variables")
|
||||
return False
|
||||
|
||||
# Test series: Attack on Titan (TMDB ID: 1429)
|
||||
test_serie_name = "Attack on Titan"
|
||||
test_serie_folder = "test_update_nfo"
|
||||
test_tmdb_id = 1429
|
||||
|
||||
# Create test folder
|
||||
test_folder = Path(settings.anime_directory) / test_serie_folder
|
||||
test_folder.mkdir(parents=True, exist_ok=True)
|
||||
logger.info(f"Created test folder: {test_folder}")
|
||||
|
||||
# Initialize NFO service
|
||||
nfo_service = NFOService(
|
||||
tmdb_api_key=settings.tmdb_api_key,
|
||||
anime_directory=settings.anime_directory,
|
||||
image_size=settings.nfo_image_size
|
||||
)
|
||||
|
||||
try:
|
||||
# Step 1: Create initial NFO
|
||||
logger.info("=" * 60)
|
||||
logger.info("STEP 1: Creating initial NFO")
|
||||
logger.info("=" * 60)
|
||||
|
||||
nfo_path = await nfo_service.create_tvshow_nfo(
|
||||
serie_name=test_serie_name,
|
||||
serie_folder=test_serie_folder,
|
||||
year=2013,
|
||||
download_poster=False, # Skip downloads for faster testing
|
||||
download_logo=False,
|
||||
download_fanart=False
|
||||
)
|
||||
|
||||
logger.info(f"✓ Initial NFO created: {nfo_path}")
|
||||
|
||||
# Read initial NFO content
|
||||
initial_content = nfo_path.read_text(encoding="utf-8")
|
||||
logger.info(f"Initial NFO size: {len(initial_content)} bytes")
|
||||
|
||||
# Verify TMDB ID is in the file
|
||||
if str(test_tmdb_id) not in initial_content:
|
||||
logger.error(f"TMDB ID {test_tmdb_id} not found in NFO!")
|
||||
return False
|
||||
logger.info(f"✓ TMDB ID {test_tmdb_id} found in NFO")
|
||||
|
||||
# Step 2: Update the NFO
|
||||
logger.info("")
|
||||
logger.info("=" * 60)
|
||||
logger.info("STEP 2: Updating NFO with fresh data")
|
||||
logger.info("=" * 60)
|
||||
|
||||
updated_path = await nfo_service.update_tvshow_nfo(
|
||||
serie_folder=test_serie_folder,
|
||||
download_media=False # Skip downloads
|
||||
)
|
||||
|
||||
logger.info(f"✓ NFO updated: {updated_path}")
|
||||
|
||||
# Read updated content
|
||||
updated_content = updated_path.read_text(encoding="utf-8")
|
||||
logger.info(f"Updated NFO size: {len(updated_content)} bytes")
|
||||
|
||||
# Verify TMDB ID is still in the file
|
||||
if str(test_tmdb_id) not in updated_content:
|
||||
logger.error(f"TMDB ID {test_tmdb_id} not found after update!")
|
||||
return False
|
||||
logger.info(f"✓ TMDB ID {test_tmdb_id} still present after update")
|
||||
|
||||
# Step 3: Test update on non-existent NFO (should fail)
|
||||
logger.info("")
|
||||
logger.info("=" * 60)
|
||||
logger.info("STEP 3: Testing error handling")
|
||||
logger.info("=" * 60)
|
||||
|
||||
try:
|
||||
await nfo_service.update_tvshow_nfo(
|
||||
serie_folder="non_existent_folder",
|
||||
download_media=False
|
||||
)
|
||||
logger.error("✗ Should have raised FileNotFoundError!")
|
||||
return False
|
||||
except FileNotFoundError as e:
|
||||
logger.info(f"✓ Correctly raised FileNotFoundError: {e}")
|
||||
|
||||
# Step 4: Test update on NFO without TMDB ID
|
||||
logger.info("")
|
||||
logger.info("STEP 4: Testing NFO without TMDB ID")
|
||||
|
||||
# Create a minimal NFO without TMDB ID
|
||||
no_id_folder = test_folder.parent / "test_no_tmdb_id"
|
||||
no_id_folder.mkdir(parents=True, exist_ok=True)
|
||||
no_id_nfo = no_id_folder / "tvshow.nfo"
|
||||
no_id_nfo.write_text(
|
||||
'<?xml version="1.0" encoding="UTF-8"?>\n'
|
||||
'<tvshow>\n'
|
||||
' <title>Test Show</title>\n'
|
||||
'</tvshow>',
|
||||
encoding="utf-8"
|
||||
)
|
||||
|
||||
try:
|
||||
await nfo_service.update_tvshow_nfo(
|
||||
serie_folder="test_no_tmdb_id",
|
||||
download_media=False
|
||||
)
|
||||
logger.error("✗ Should have raised TMDBAPIError!")
|
||||
return False
|
||||
except TMDBAPIError as e:
|
||||
logger.info(f"✓ Correctly raised TMDBAPIError: {e}")
|
||||
|
||||
logger.info("")
|
||||
logger.info("=" * 60)
|
||||
logger.info("✓ ALL TESTS PASSED")
|
||||
logger.info("=" * 60)
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"✗ Test failed with error: {e}", exc_info=True)
|
||||
return False
|
||||
|
||||
finally:
|
||||
await nfo_service.close()
|
||||
|
||||
# Cleanup test folders
|
||||
logger.info("\nCleaning up test folders...")
|
||||
import shutil
|
||||
try:
|
||||
if test_folder.exists():
|
||||
shutil.rmtree(test_folder)
|
||||
logger.info(f"Removed: {test_folder}")
|
||||
|
||||
no_id_folder = test_folder.parent / "test_no_tmdb_id"
|
||||
if no_id_folder.exists():
|
||||
shutil.rmtree(no_id_folder)
|
||||
logger.info(f"Removed: {no_id_folder}")
|
||||
except Exception as e:
|
||||
logger.warning(f"Cleanup error: {e}")
|
||||
|
||||
|
||||
async def main():
|
||||
"""Main entry point."""
|
||||
success = await test_update_nfo()
|
||||
sys.exit(0 if success else 1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
Reference in New Issue
Block a user