feat: Add SendVid downloader support
Add complete support for SendVid video hosting service used by Anime-Sama for anime series like Hell's Paradise. Changes: - Create SendVidDownloader class with proper headers to avoid 403 errors - Add SendVid detection and handling in AnimeSamaDownloader - Update download_manager to include SendVid-specific headers - Support custom episode naming (e.g., "Hells Paradise - Episode 01.mp4") Technical details: - SendVid embed pages require User-Agent and Referer headers - Direct MP4 URLs extracted from <source> tags with IP/time-based parameters - Tested with Hell's Paradise Episode 01 (7MB, 24min, 1280x720) 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:
@@ -0,0 +1,113 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Project Overview
|
||||
|
||||
Ohm Stream Downloader is a FastAPI-based web application for downloading media files from various file hosting services (1fichier, Doodstream, Rapidfile, etc.). It features a web interface, parallel downloads, pause/resume support, and direct file serving.
|
||||
|
||||
## Development Commands
|
||||
|
||||
```bash
|
||||
# Create and activate virtual environment
|
||||
python3 -m venv venv
|
||||
source venv/bin/activate # On Windows: venv\Scripts\activate
|
||||
|
||||
# Install dependencies
|
||||
pip install -r requirements.txt
|
||||
|
||||
# Run development server (auto-reload)
|
||||
uvicorn main:app --reload --host 0.0.0.0 --port 8000
|
||||
|
||||
# Access web interface
|
||||
# Open http://localhost:8000/web in browser
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
**Directory Structure:**
|
||||
```
|
||||
Ohm_streaming/
|
||||
├── main.py # FastAPI application & API endpoints
|
||||
├── app/
|
||||
│ ├── models/ # Pydantic models (DownloadTask, DownloadStatus, etc.)
|
||||
│ ├── downloaders/ # Host-specific downloaders
|
||||
│ │ ├── base.py # BaseDownloader abstract class
|
||||
│ │ ├── unfichier.py # 1fichier.com handler
|
||||
│ │ ├── doodstream.py # Doodstream handler
|
||||
│ │ └── rapidfile.py # Rapidfile handler
|
||||
│ └── download_manager.py # Manages download queue, progress, parallel downloads
|
||||
├── downloads/ # Downloaded files storage
|
||||
├── templates/
|
||||
│ └── index.html # Web interface (single-page app)
|
||||
└── static/ # Static assets (CSS, JS, images)
|
||||
```
|
||||
|
||||
**Core Components:**
|
||||
|
||||
1. **DownloadManager** (`app/download_manager.py`)
|
||||
- Manages all download tasks with parallel download limit (default: 3 concurrent)
|
||||
- Handles pause/resume/cancel operations
|
||||
- Tracks progress, speed, and file chunks for resume support
|
||||
- Uses semaphore to limit concurrent downloads
|
||||
|
||||
2. **Downloaders** (`app/downloaders/`)
|
||||
- Each host has its own downloader class inheriting from `BaseDownloader`
|
||||
- `can_handle(url)` - Checks if downloader supports the URL
|
||||
- `get_download_link(url)` - Extracts direct download link and filename from host page
|
||||
- Uses httpx for async HTTP requests and BeautifulSoup for HTML parsing
|
||||
|
||||
3. **Download Task Flow:**
|
||||
- Client sends URL via POST `/api/download`
|
||||
- DownloadManager creates task with unique ID
|
||||
- Appropriate downloader extracts direct link
|
||||
- File downloaded in chunks (1MB) to `downloads/` directory
|
||||
- Progress tracked in real-time (bytes, speed, percentage)
|
||||
- Resume uses HTTP Range headers to continue from last byte
|
||||
|
||||
**API Endpoints:**
|
||||
- `POST /api/download` - Create new download task (starts automatically)
|
||||
- `GET /api/downloads` - List all download tasks with status
|
||||
- `GET /api/download/{task_id}` - Get specific task details
|
||||
- `POST /api/download/{task_id}/pause` - Pause active download
|
||||
- `POST /api/download/{task_id}/resume` - Resume paused download
|
||||
- `DELETE /api/download/{task_id}` - Cancel/delete download
|
||||
- `GET /api/download/{task_id}/file` - Download completed file
|
||||
- `GET /web` - Web interface
|
||||
|
||||
**Web Interface:**
|
||||
- Single-page app at `/web` (templates/index.html)
|
||||
- Auto-refreshes every second to show progress
|
||||
- Shows progress bar, speed, file size
|
||||
- Controls: Pause, Resume, Cancel, Download completed file
|
||||
|
||||
## Adding New Host Support
|
||||
|
||||
To add support for a new file hosting service:
|
||||
|
||||
1. Create new file in `app/downloaders/` (e.g., `myhost.py`)
|
||||
2. Inherit from `BaseDownloader`
|
||||
3. Implement `can_handle(url)` to detect your host URLs
|
||||
4. Implement `get_download_link(url)` to extract direct download link
|
||||
5. Import and add to `downloaders` list in `app/downloaders/__init__.py`
|
||||
|
||||
Example:
|
||||
```python
|
||||
from .base import BaseDownloader
|
||||
|
||||
class MyHostDownloader(BaseDownloader):
|
||||
def can_handle(self, url: str) -> bool:
|
||||
return "myhost.com" in url.lower()
|
||||
|
||||
async def get_download_link(self, url: str) -> tuple[str, str]:
|
||||
# Fetch page, parse HTML, extract download URL
|
||||
soup = BeautifulSoup(await self._fetch_page(url), 'lxml')
|
||||
# ... extraction logic ...
|
||||
return download_url, filename
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
Edit `main.py` to configure:
|
||||
- `max_parallel` - Maximum concurrent downloads (default: 3)
|
||||
- `download_dir` - Storage location (default: "downloads")
|
||||
Reference in New Issue
Block a user