Phase 3: HTMX & Alpine.js integration, router refactoring, and UI modernization
CI / Test (Python 3.11) (push) Has been cancelled
CI / Test (Python 3.12) (push) Has been cancelled
CI / Lint (push) Has been cancelled
CI / Type Check (push) Has been cancelled
CI / Summary (push) Has been cancelled

- Modernized the frontend with HTMX for server-driven UI and Alpine.js for client state.
- Refactored anime, player, and recommendation logic into modular routers.
- Updated README.md to reflect the latest project state and technologies (v2.4).
- Added Plyr.io for an improved streaming experience.
- Improved project structure with componentized templates.
- Added Playwright and Vitest configuration for frontend testing.
This commit is contained in:
root
2026-03-26 10:34:26 +00:00
parent a684237725
commit 9f85908ff3
31 changed files with 3413 additions and 2201 deletions
+46 -3
View File
@@ -20,10 +20,53 @@ def get_download_manager():
return download_manager
def get_templates():
from main import templates
from app.downloaders import get_downloader
return templates
@router.get("/api/player/embed")
async def get_player_embed(request: Request, url: str):
"""
Get an embedded video player for a given episode URL.
This route extracts the direct video link and returns an HTML fragment.
"""
from main import templates
try:
# 1. Get the downloader for the anime site (e.g. Anime-Sama)
downloader = get_downloader(url)
if not downloader:
raise HTTPException(status_code=400, detail="No downloader found for this URL")
# 2. Get the video player URL (embed URL like VidMoly, DoodStream, etc.)
video_url, _ = await downloader.get_download_link(url)
# 3. Get the direct video file link from the player
player_handler = get_downloader(video_url)
if not player_handler:
# If no direct extractor, we might have to use an iframe
return templates.TemplateResponse(
"components/player_embed.html",
{
"request": request,
"video_url": video_url,
"is_iframe": True
}
)
direct_url, filename = await player_handler.get_download_link(video_url)
return templates.TemplateResponse(
"components/player_embed.html",
{
"request": request,
"video_url": direct_url,
"filename": filename,
"is_iframe": False
}
)
except Exception as e:
import logging
logging.getLogger(__name__).error(f"Embed error: {e}", exc_info=True)
return f"<div class='error-msg'>Erreur lors de l'extraction de la vidéo : {str(e)}</div>"
@router.get("/video/{task_id}")