Fix NFO plot fallback by using en-US search overview when German result is empty
This commit is contained in:
@@ -174,6 +174,32 @@ class NFOService:
|
||||
# Enrich with fallback languages for empty overview/tagline
|
||||
# Pass search result overview as last resort fallback
|
||||
search_overview = tv_show.get("overview") or None
|
||||
if not search_overview:
|
||||
try:
|
||||
logger.debug(
|
||||
"No overview in German search result, trying en-US search fallback for: %s",
|
||||
search_name,
|
||||
)
|
||||
en_search_results = await self.tmdb_client.search_tv_show(
|
||||
search_name,
|
||||
language="en-US",
|
||||
)
|
||||
if en_search_results.get("results"):
|
||||
en_match = self._find_best_match(
|
||||
en_search_results["results"], search_name, year
|
||||
)
|
||||
search_overview = en_match.get("overview") or None
|
||||
if search_overview:
|
||||
logger.info(
|
||||
"Using en-US search overview fallback for %s",
|
||||
search_name,
|
||||
)
|
||||
except (TMDBAPIError, Exception) as exc:
|
||||
logger.warning(
|
||||
"Failed en-US search fallback for overview: %s",
|
||||
exc,
|
||||
)
|
||||
|
||||
details = await self._enrich_details_with_fallback(
|
||||
details, search_overview=search_overview
|
||||
)
|
||||
|
||||
@@ -424,7 +424,14 @@ class TestCreateTVShowNFO:
|
||||
patch.object(nfo_service.tmdb_client, 'get_tv_show_content_ratings', new_callable=AsyncMock) as mock_ratings, \
|
||||
patch.object(nfo_service, '_download_media_files', new_callable=AsyncMock):
|
||||
|
||||
mock_search.return_value = {"results": [{"id": 1429, "name": "Attack on Titan", "first_air_date": "2013-04-07"}]}
|
||||
mock_search.return_value = {
|
||||
"results": [{
|
||||
"id": 1429,
|
||||
"name": "Attack on Titan",
|
||||
"first_air_date": "2013-04-07",
|
||||
"overview": "Several hundred years ago, humans were nearly...",
|
||||
}]
|
||||
}
|
||||
mock_details.return_value = mock_tmdb_data
|
||||
mock_ratings.return_value = mock_content_ratings_de
|
||||
|
||||
@@ -463,7 +470,14 @@ class TestCreateTVShowNFO:
|
||||
patch.object(nfo_service.tmdb_client, 'get_tv_show_content_ratings', new_callable=AsyncMock) as mock_ratings, \
|
||||
patch.object(nfo_service, '_download_media_files', new_callable=AsyncMock):
|
||||
|
||||
mock_search.return_value = {"results": [{"id": 1429, "name": "Attack on Titan", "first_air_date": "2013-04-07"}]}
|
||||
mock_search.return_value = {
|
||||
"results": [{
|
||||
"id": 1429,
|
||||
"name": "Attack on Titan",
|
||||
"first_air_date": "2013-04-07",
|
||||
"overview": "Several hundred years ago, humans were nearly...",
|
||||
}]
|
||||
}
|
||||
mock_details.return_value = mock_tmdb_data
|
||||
mock_ratings.return_value = mock_content_ratings_no_de
|
||||
|
||||
@@ -749,7 +763,14 @@ class TestNFOServiceEdgeCases:
|
||||
"poster_path": None, "backdrop_path": None
|
||||
}
|
||||
|
||||
mock_search.return_value = {"results": [{"id": 1, "name": "Series", "first_air_date": "2020-01-01"}]}
|
||||
mock_search.return_value = {
|
||||
"results": [{
|
||||
"id": 1,
|
||||
"name": "Series",
|
||||
"first_air_date": "2020-01-01",
|
||||
"overview": "Test overview.",
|
||||
}]
|
||||
}
|
||||
mock_details.return_value = tmdb_data
|
||||
mock_ratings.return_value = {"results": []}
|
||||
|
||||
@@ -1486,6 +1507,67 @@ class TestEnrichFallbackLanguages:
|
||||
content = nfo_path.read_text(encoding="utf-8")
|
||||
assert "<plot>Search result overview text.</plot>" in content
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_en_us_search_fallback_when_german_search_overview_empty(
|
||||
self, nfo_service, tmp_path
|
||||
):
|
||||
"""When the German search overview is empty, fallback to en-US search overview."""
|
||||
series_folder = tmp_path / "Rare Anime"
|
||||
series_folder.mkdir()
|
||||
|
||||
empty_data = {
|
||||
"id": 77777, "name": "Rare Anime",
|
||||
"original_name": "新しいアニメ", "first_air_date": "2025-01-01",
|
||||
"overview": "",
|
||||
"vote_average": 0, "vote_count": 0,
|
||||
"status": "Continuing", "episode_run_time": [],
|
||||
"genres": [], "networks": [], "production_countries": [],
|
||||
"poster_path": None, "backdrop_path": None,
|
||||
"external_ids": {}, "credits": {"cast": []},
|
||||
"images": {"logos": []},
|
||||
}
|
||||
|
||||
async def search_side_effect(query, language="de-DE", page=1):
|
||||
if language == "en-US":
|
||||
return {
|
||||
"results": [{
|
||||
"id": 77777,
|
||||
"name": "Rare Anime",
|
||||
"first_air_date": "2025-01-01",
|
||||
"overview": "English search overview text.",
|
||||
}],
|
||||
}
|
||||
return {
|
||||
"results": [{
|
||||
"id": 77777,
|
||||
"name": "Rare Anime",
|
||||
"first_air_date": "2025-01-01",
|
||||
"overview": "",
|
||||
}],
|
||||
}
|
||||
|
||||
async def details_side_effect(tv_id, **kwargs):
|
||||
return empty_data
|
||||
|
||||
with patch.object(nfo_service.tmdb_client, 'search_tv_show', new_callable=AsyncMock) as mock_search, \
|
||||
patch.object(nfo_service.tmdb_client, 'get_tv_show_details', new_callable=AsyncMock) as mock_details, \
|
||||
patch.object(nfo_service.tmdb_client, 'get_tv_show_content_ratings', new_callable=AsyncMock) as mock_ratings, \
|
||||
patch.object(nfo_service, '_download_media_files', new_callable=AsyncMock):
|
||||
|
||||
mock_search.side_effect = search_side_effect
|
||||
mock_details.side_effect = details_side_effect
|
||||
mock_ratings.return_value = {"results": []}
|
||||
|
||||
nfo_path = await nfo_service.create_tvshow_nfo(
|
||||
"Rare Anime", "Rare Anime",
|
||||
download_poster=False, download_logo=False, download_fanart=False,
|
||||
)
|
||||
|
||||
content = nfo_path.read_text(encoding="utf-8")
|
||||
assert "<plot>English search overview text.</plot>" in content
|
||||
assert mock_search.call_count == 2
|
||||
assert mock_search.call_args_list[1].kwargs['language'] == 'en-US'
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_no_japanese_fallback_when_english_succeeds(
|
||||
self, nfo_service, tmp_path,
|
||||
|
||||
Reference in New Issue
Block a user