Compare commits

..

2 Commits

Author SHA1 Message Date
e02d65778f chore: bump version 2026-06-05 20:25:20 +02:00
45d259bab2 fix(setup): resolve series key from search link field
- Fix _resolve_key_via_search to use 'title' instead of 'name'
- Extract key from 'link' field URL (e.g., /anime/stream/naruto -> naruto)
- Skip folders with unresolved keys instead of crashing with 'Series key cannot be empty'
- Update tests to use correct field names (title/link)
2026-06-05 20:24:24 +02:00
4 changed files with 18 additions and 9 deletions

View File

@@ -1 +1 @@
v1.4.0 v1.4.1

View File

@@ -1,6 +1,6 @@
{ {
"name": "aniworld-web", "name": "aniworld-web",
"version": "1.4.0", "version": "1.4.1",
"description": "Aniworld Anime Download Manager - Web Frontend", "description": "Aniworld Anime Download Manager - Web Frontend",
"type": "module", "type": "module",
"scripts": { "scripts": {

View File

@@ -93,9 +93,11 @@ class SetupService:
results = await series_app.search(title) results = await series_app.search(title)
if len(results) == 1: if len(results) == 1:
result_name = results[0].get('name', '').lower() result_name = results[0].get('title', '').lower()
if result_name == title.lower(): if result_name == title.lower():
return results[0].get('key', '') link = results[0].get('link', '')
if link and '/anime/stream/' in link:
return link.split('/anime/stream/')[-1].split('/')[0]
except Exception as e: except Exception as e:
logger.warning( logger.warning(
"Provider search failed for folder", "Provider search failed for folder",
@@ -236,6 +238,13 @@ class SetupService:
# Resolve key via provider search # Resolve key via provider search
resolved_key = await cls._resolve_key_via_search(title) resolved_key = await cls._resolve_key_via_search(title)
if not resolved_key:
logger.warning(
"Could not resolve series key for folder, skipping: %s",
folder_name
)
continue
# Check filesystem properties # Check filesystem properties
props = cls._get_series_properties(folder) props = cls._get_series_properties(folder)

View File

@@ -67,7 +67,7 @@ class TestResolveKeyViaSearch:
"""Search returns 1 result with same name → returns key.""" """Search returns 1 result with same name → returns key."""
mock_series_app = AsyncMock() mock_series_app = AsyncMock()
mock_series_app.search.return_value = [ mock_series_app.search.return_value = [
{'key': 'attack-on-titan', 'name': 'Attack on Titan'} {'title': 'Attack on Titan', 'link': '/anime/stream/attack-on-titan'}
] ]
with patch( with patch(
@@ -97,8 +97,8 @@ class TestResolveKeyViaSearch:
"""Search returns >1 results → returns empty string.""" """Search returns >1 results → returns empty string."""
mock_series_app = AsyncMock() mock_series_app = AsyncMock()
mock_series_app.search.return_value = [ mock_series_app.search.return_value = [
{'key': 'attack-on-titan', 'name': 'Attack on Titan'}, {'title': 'Attack on Titan', 'link': '/anime/stream/attack-on-titan'},
{'key': 'attack-on-titan-ova', 'name': 'Attack on Titan OVA'} {'title': 'Attack on Titan OVA', 'link': '/anime/stream/attack-on-titan-ova'}
] ]
with patch( with patch(
@@ -114,7 +114,7 @@ class TestResolveKeyViaSearch:
"""Search returns 1 result but name differs (case-insensitive) → returns empty string.""" """Search returns 1 result but name differs (case-insensitive) → returns empty string."""
mock_series_app = AsyncMock() mock_series_app = AsyncMock()
mock_series_app.search.return_value = [ mock_series_app.search.return_value = [
{'key': 'attack-on-titan', 'name': 'Attack on Titan'} {'title': 'Attack on Titan', 'link': '/anime/stream/attack-on-titan'}
] ]
with patch( with patch(
@@ -243,7 +243,7 @@ class TestSetupServiceRun:
mock_series_app = AsyncMock() mock_series_app = AsyncMock()
mock_series_app.search.return_value = [ mock_series_app.search.return_value = [
{'key': 'attack-on-titan', 'name': 'Attack on Titan'} {'title': 'Attack on Titan', 'link': '/anime/stream/attack-on-titan'}
] ]
mock_db = AsyncMock() mock_db = AsyncMock()