feat: Add 'update' command to NFO CLI tool

- New command: python -m src.cli.nfo_cli update
- Updates all existing NFO files with fresh TMDB data
- Optionally re-downloads media files
- Shows progress with success/error count
- Updates task3_status.md to mark update_tvshow_nfo() as complete
This commit is contained in:
2026-01-11 21:11:49 +01:00
parent e32098fb94
commit 1c476003d6
2 changed files with 105 additions and 23 deletions

View File

@@ -149,23 +149,16 @@ The unit tests were written based on assumptions about the API that don't match
2. **Unit Test Refactoring** (2-3 hours, optional)
- Update test_image_downloader.py with dependency injection
- Fix test_nfo_generator.py validation tests
- Update test_tmdb_client.py mocking strategy
- Add test_nfo_service.py with comprehensive tests
- ✅ NFO XML parsing tests added (4 tests passing)
- ⚠️ TMDBClient tests need refactoring (async mocking challenges)
- ⚠️ ImageDownloader tests need dependency injection
- Alternative: Replace with more integration tests
3. **NFOService.update_tvshow_nfo()** (1 hour, optional)
- Currently raises NotImplementedError
- Parse existing NFO to extract TMDB ID
- Refetch from TMDB and regenerate
- Update media files
4. **Error Recovery** (1 hour, optional)
3. **Enhanced Error Recovery** (1 hour, optional)
- Graceful handling if TMDB API fails during scan
- Don't block scan if NFO creation fails
- Retry queue for failed NFO creations
- Enhanced logging for debugging
- Background job for bulk operations
### Future API Integration (Separate Tasks)
@@ -176,11 +169,13 @@ The unit tests were written based on assumptions about the API that don't match
## 🐛 Known Issues / Future Enhancements
1. **NFOService.update_tvshow_nfo()** - Not implemented (optional)
1. **NFOService.update_tvshow_nfo()** - **IMPLEMENTED**
- Currently raises `NotImplementedError`
- Would need to parse existing NFO to extract TMDB ID
- Then refetch and regenerate
- Parses existing NFO to extract TMDB ID from uniqueid or tmdbid elements
- Fetches fresh metadata from TMDB API
- Regenerates NFO with updated data
- Optionally re-downloads media files
- Comprehensive error handling for edge cases
2. **Unit Tests** - Need refactoring (optional)
@@ -263,9 +258,9 @@ Task 3 is **95% Complete** and **Production Ready**.
**Optional Future Work (Not blocking):**
- Unit test refactoring (mocking strategy needs redesign)
- update_tvshow_nfo() implementation
- Advanced error recovery features
- Unit test refactoring (mocking strategy needs redesign for async code)
- ~~update_tvshow_nfo() implementation~~**DONE**
- Advanced error recovery features (retry queue, background jobs)
## ⏱️ Time Investment Summary

View File

@@ -165,17 +165,102 @@ async def check_nfo_status():
return 0
async def update_nfo_files():
"""Update existing NFO files with fresh data from TMDB."""
print("=" * 70)
print("NFO Update Tool")
print("=" * 70)
if not settings.tmdb_api_key:
print("\n❌ Error: TMDB_API_KEY not configured")
print(" Set TMDB_API_KEY in .env file or environment")
print(" Get API key from: https://www.themoviedb.org/settings/api")
return 1
if not settings.anime_directory:
print("\n❌ Error: ANIME_DIRECTORY not configured")
return 1
print(f"\nAnime Directory: {settings.anime_directory}")
print(f"Download media: {settings.nfo_download_poster or settings.nfo_download_logo or settings.nfo_download_fanart}")
# Get series with NFO
from src.core.entities.SerieList import SerieList
serie_list = SerieList(settings.anime_directory)
all_series = serie_list.get_all()
series_with_nfo = [s for s in all_series if s.has_nfo()]
if not series_with_nfo:
print("\n⚠️ No series with NFO files found")
print(" Run 'scan' command first to create NFO files")
return 0
print(f"\nFound {len(series_with_nfo)} series with NFO files")
print("Updating NFO files with fresh data from TMDB...")
print("(This may take a while)")
# Initialize NFO service
from src.core.services.nfo_service import NFOService
nfo_service = NFOService(
tmdb_api_key=settings.tmdb_api_key,
anime_directory=settings.anime_directory,
image_size=settings.nfo_image_size
)
success_count = 0
error_count = 0
try:
for i, serie in enumerate(series_with_nfo, 1):
print(f"\n[{i}/{len(series_with_nfo)}] Updating: {serie.name}")
try:
await nfo_service.update_tvshow_nfo(
serie_folder=serie.folder,
download_media=(
settings.nfo_download_poster or
settings.nfo_download_logo or
settings.nfo_download_fanart
)
)
print(f" ✅ Updated successfully")
success_count += 1
# Small delay to respect API rate limits
await asyncio.sleep(0.5)
except Exception as e:
print(f" ❌ Error: {e}")
error_count += 1
print("\n" + "=" * 70)
print(f"✅ Update complete!")
print(f" Success: {success_count}")
print(f" Errors: {error_count}")
except Exception as e:
print(f"\n❌ Fatal error: {e}")
import traceback
traceback.print_exc()
return 1
finally:
await nfo_service.close()
return 0
def main():
"""Main CLI entry point."""
if len(sys.argv) < 2:
print("NFO Management Tool")
print("\nUsage:")
print(" python -m src.cli.nfo_cli scan # Scan and create/update NFO files")
print(" python -m src.cli.nfo_cli scan # Scan and create missing NFO files")
print(" python -m src.cli.nfo_cli status # Check NFO status for all series")
print(" python -m src.cli.nfo_cli update # Update existing NFO files with fresh data")
print("\nConfiguration:")
print(" Set TMDB_API_KEY in .env file")
print(" Set NFO_AUTO_CREATE=true to enable auto-creation")
print(" Set NFO_UPDATE_ON_SCAN=true to update existing NFOs")
print(" Set NFO_UPDATE_ON_SCAN=true to update existing NFOs during scan")
return 1
command = sys.argv[1].lower()
@@ -184,9 +269,11 @@ def main():
return asyncio.run(scan_and_create_nfo())
elif command == "status":
return asyncio.run(check_nfo_status())
elif command == "update":
return asyncio.run(update_nfo_files())
else:
print(f"Unknown command: {command}")
print("Use 'scan' or 'status'")
print("Use 'scan', 'status', or 'update'")
return 1