feat: download latest season only + fix lpayer CDN + HLS support
- Watchlist 'Suivre' now downloads only the latest season instead of all episodes - Fix lpayer CDN 403 errors by adding proper Referer header for IP ranges - Add HLS/m3u8 stream download support using ffmpeg - Improve episode filename format: 'Anime - SX - Episode XX.mp4' - Add CDN detection for lpayer IPs (185.237.x.x, 203.188.x.x, /mik/ path)
This commit is contained in:
@@ -2094,9 +2094,12 @@ async def check_watchlist_item(
|
||||
@app.post("/api/watchlist/{item_id}/download-all", tags=["Watchlist"])
|
||||
async def download_all_episodes(
|
||||
item_id: str,
|
||||
background_tasks: BackgroundTasks,
|
||||
current_user: User = Depends(get_current_user_from_token)
|
||||
):
|
||||
"""Download ALL episodes for a watchlist item (used when first following an anime)"""
|
||||
"""Download the LATEST SEASON episodes for a watchlist item (used when first following an anime)"""
|
||||
from app.downloaders import get_downloader
|
||||
|
||||
try:
|
||||
item = watchlist_manager.get_by_id(item_id)
|
||||
if not item:
|
||||
@@ -2105,18 +2108,64 @@ async def download_all_episodes(
|
||||
if item.user_id != current_user.id:
|
||||
raise HTTPException(status_code=403, detail="Access denied")
|
||||
|
||||
# Temporarily set last_episode_downloaded to 0 to trigger download of ALL episodes
|
||||
watchlist_manager.update(item_id, {"last_episode_downloaded": 0})
|
||||
downloader = get_downloader(item.anime_url)
|
||||
latest_season_url = item.anime_url # Default to current URL
|
||||
|
||||
result = await episode_checker.manual_check(item_id)
|
||||
# Try to get the latest season if provider supports it
|
||||
if hasattr(downloader, 'get_seasons'):
|
||||
try:
|
||||
seasons = await downloader.get_seasons(item.anime_url)
|
||||
if seasons and len(seasons) > 0:
|
||||
# Get the last season (most recent)
|
||||
latest_season = seasons[-1]
|
||||
latest_season_url = latest_season.get('url', item.anime_url)
|
||||
logger.info(f"Found {len(seasons)} seasons, using latest: {latest_season.get('title', 'unknown')}")
|
||||
except Exception as e:
|
||||
logger.warning(f"Could not fetch seasons, using default URL: {e}")
|
||||
|
||||
# Note: download_new_episodes already updates last_episode_downloaded via update_check_time
|
||||
# So we don't restore the original value - the new value reflects what was actually downloaded
|
||||
# Get episodes from the latest season
|
||||
episodes = await downloader.get_episodes(latest_season_url, item.lang)
|
||||
|
||||
if not episodes:
|
||||
return {
|
||||
"status": "warning",
|
||||
"message": f"No episodes found for {item.anime_title}",
|
||||
"result": {"new_episodes_found": 0, "episodes_downloaded": []}
|
||||
}
|
||||
|
||||
# Create download tasks for all episodes of the latest season
|
||||
task_ids = []
|
||||
|
||||
# Extract season number from URL for filename
|
||||
import re
|
||||
season_match = re.search(r'saison(\d+)', latest_season_url, re.IGNORECASE)
|
||||
season_num = season_match.group(1) if season_match else "1"
|
||||
|
||||
# Clean anime title for filename
|
||||
anime_title_clean = item.anime_title.replace('/', '-').replace('\\', '-').strip()
|
||||
|
||||
for episode in episodes:
|
||||
# Build a nice filename: "Anime Title - S1 - Episode 01.mp4"
|
||||
ep_num = episode.get('episode', '01')
|
||||
filename = f"{anime_title_clean} - S{season_num} - Episode {ep_num}.mp4"
|
||||
|
||||
request = DownloadRequest(url=episode['url'], filename=filename)
|
||||
task = download_manager.create_task(request)
|
||||
task_ids.append(task.id)
|
||||
background_tasks.add_task(download_manager.start_download, task.id)
|
||||
|
||||
# Update watchlist with total episodes count
|
||||
watchlist_manager.update(item_id, {
|
||||
"last_episode_downloaded": len(episodes),
|
||||
"total_episodes": len(episodes)
|
||||
})
|
||||
|
||||
return {
|
||||
"status": "success",
|
||||
"message": f"Downloading all episodes for {item.anime_title}",
|
||||
"result": result
|
||||
"message": f"Downloading {len(task_ids)} episodes from latest season for {item.anime_title}",
|
||||
"task_ids": task_ids,
|
||||
"total_episodes": len(episodes),
|
||||
"season_url": latest_season_url
|
||||
}
|
||||
except HTTPException:
|
||||
raise
|
||||
|
||||
Reference in New Issue
Block a user