refactor: Restructure downloaders with clear separation

This commit implements a complete reorganization of the downloader system
with a clear distinction between anime streaming sites and video hosting services.

## Structure Changes

**New Organization:**
- `app/downloaders/anime_sites/` - Anime streaming sites (catalogs + metadata)
- `app/downloaders/video_players/` - Video hosting services (file downloads)

**Base Classes:**
- `BaseAnimeSite` - For anime providers (search, episodes, metadata)
- `BaseVideoPlayer` - For video players (download link extraction)

**Migrated Downloaders:**
Anime Sites (4):
- AnimeSama, NekoSama, AnimeUltime, Vostfree

Video Players (8):
- Doodstream, Sibnet, VidMoly, SendVid, Lpayer, 1fichier, Uptobox, Rapidfile

## Key Improvements

1. **Clear Separation**: Distinct base classes for different use cases
2. **Preserved Functionality**: All existing features maintained
   - VidMoly: M3U8 support, Playwright, multi-domains, target_filename param
   - SendVid: target_filename parameter support
   - All others: No behavioral changes

3. **Better Organization**:
   - Anime sites: search_anime(), get_episodes(), get_anime_metadata()
   - Video players: get_download_link(url, target_filename=None)

4. **Fixed Imports**: Updated cross-imports in AnimeSama
   - from ..video_players.vidmoly import
   - from ..video_players.sendvid import
   - from ..video_players.sibnet import
   - from ..video_players.lpayer import

5. **Updated Tests**: All test imports use new structure
6. **Updated Providers**: Added 4 missing file hosts to providers.py

## Backward Compatibility

 Main API unchanged: get_downloader() works identically
 All 23 tests passing
 Frontend fully functional
 No breaking changes for users

## Documentation

- RESTRUCTURATION_SUMMARY.md - Technical details
- FIX_IMPORT_ERROR.md - Import error resolution
- IMPORT_VERIFICATION_REPORT.md - Complete import verification
- FRONTEND_VERIFICATION_FINAL.md - Frontend validation

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
This commit is contained in:
root
2026-01-24 22:13:20 +00:00
parent 1fe7392063
commit 3afad41d46
25 changed files with 1001 additions and 83 deletions
+38 -32
View File
@@ -1,40 +1,46 @@
from .base import BaseDownloader
from .unfichier import UnFichierDownloader
from .doodstream import DoodStreamDownloader
from .rapidfile import RapidFileDownloader
from .uptobox import UptoboxDownloader
from .animesama import AnimeSamaDownloader
from .animeultime import AnimeUltimeDownloader
from .nekosama import NekoSamaDownloader
from .vostfree import VostfreeDownloader
from .vidmoly import VidMolyDownloader
from .sendvid import SendVidDownloader
from .sibnet import SibnetDownloader
from .lpayer import LpayerDownloader
# Import from new organized structure
from .video_players import (
BaseVideoPlayer,
get_video_player,
DoodStreamDownloader,
SibnetDownloader,
VidMolyDownloader,
SendVidDownloader,
LpayerDownloader,
UnFichierDownloader,
UptoboxDownloader,
RapidFileDownloader
)
from .anime_sites import (
BaseAnimeSite,
get_anime_site,
AnimeSamaDownloader,
NekoSamaDownloader,
AnimeUltimeDownloader,
VostfreeDownloader
)
def get_downloader(url: str) -> BaseDownloader:
"""Factory function to get the appropriate downloader for a URL"""
downloaders = [
# Anime sites
AnimeSamaDownloader(),
AnimeUltimeDownloader(),
NekoSamaDownloader(),
VostfreeDownloader(),
# File hosts
UnFichierDownloader(),
UptoboxDownloader(),
DoodStreamDownloader(),
RapidFileDownloader(),
VidMolyDownloader(),
SendVidDownloader(),
SibnetDownloader(),
LpayerDownloader(),
]
"""
Factory function to get the appropriate downloader for a URL.
for downloader in downloaders:
if downloader.can_handle(url):
return downloader
This function now uses the organized structure:
- Checks anime sites first (for catalogs/search)
- Then checks video players (for direct download links)
- Falls back to generic downloader if no match
"""
# Try anime sites first
anime_site = get_anime_site(url)
if anime_site:
return anime_site
# Then try video players
video_player = get_video_player(url)
if video_player:
return video_player
# Return generic downloader if no match
return GenericDownloader()