Remove Shikimori API, use AnimeThemes only, switch to WebM format

- Remove ShikimoriService, use AnimeThemes API for search
- Replace shikimori_id with animethemes_slug as primary identifier
- Remove FFmpeg MP3 conversion, download WebM directly
- Add .webm support in storage and upload endpoints
- Update frontend to use animethemes_slug

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-01-12 11:22:46 +03:00
parent 333de65fbd
commit cc11f0b773
12 changed files with 138 additions and 263 deletions

View File

@@ -21,7 +21,6 @@ from .schemas import (
StorageStatsResponse,
)
from .db_models import Anime, AnimeTheme, DownloadTask, DownloadStatus
from .services.shikimori import ShikimoriService
from .services.animethemes import AnimeThemesService
from .services.downloader import DownloadService
from .services.storage_tracker import StorageTrackerService
@@ -34,30 +33,29 @@ router = APIRouter(prefix="/downloader", tags=["openings-downloader"])
@router.get("/search", response_model=SearchResponse)
async def search_anime(
query: str = Query(..., min_length=1, description="Search query"),
year: Optional[int] = Query(None, description="Filter by year"),
status: Optional[str] = Query(None, description="Filter by status (ongoing, released, announced)"),
limit: int = Query(20, ge=1, le=50, description="Maximum results"),
db: AsyncSession = Depends(get_db),
):
"""Search anime via Shikimori API."""
service = ShikimoriService()
results = await service.search(query, year=year, status=status, limit=limit)
"""Search anime via AnimeThemes API."""
service = AnimeThemesService()
results = await service.search(query, limit=limit)
return SearchResponse(results=results, total=len(results))
# ============== Anime Detail ==============
@router.get("/anime/{shikimori_id}", response_model=AnimeDetailResponse)
@router.get("/anime/{slug:path}", response_model=AnimeDetailResponse)
async def get_anime_detail(
shikimori_id: int,
slug: str,
db: AsyncSession = Depends(get_db),
):
"""Get anime details with available themes from AnimeThemes."""
shikimori_service = ShikimoriService()
animethemes_service = AnimeThemesService()
# Get or create anime record
anime = await shikimori_service.get_or_create_anime(db, shikimori_id)
anime = await animethemes_service.get_or_create_anime(db, slug)
if not anime:
raise HTTPException(status_code=404, detail=f"Anime not found: {slug}")
# Fetch themes from AnimeThemes API
themes = await animethemes_service.fetch_themes(db, anime)
@@ -92,10 +90,8 @@ async def get_anime_detail(
return AnimeDetailResponse(
id=anime.id,
shikimori_id=anime.shikimori_id,
title_russian=anime.title_russian,
animethemes_slug=anime.animethemes_slug,
title_english=anime.title_english,
title_japanese=anime.title_japanese,
year=anime.year,
poster_url=anime.poster_url,
themes=theme_infos,