refactor: migrate main.py to modular routers and add project roadmap
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

- Migrated monolithic main.py to feature-scoped routers in app/routers/
- Added GEMINI.md for project context and AI instructional guidelines
- Updated README.md with a comprehensive modernization plan (SQL migration, robust scraping DSL, frontend modernization)
- Improved authentication with cookie support and modular JS
- Updated test suite and documentation
This commit is contained in:
root
2026-03-24 10:12:04 +00:00
parent 1b5d7f9238
commit d4d8d8a3b6
42 changed files with 4518 additions and 2426 deletions
+37
View File
@@ -0,0 +1,37 @@
# Video Players (app/downloaders/video_players)
## OVERVIEW
File hosting extractors that extract direct download links from video player pages (Doodstream, Sibnet, VidMoly, etc.).
## WHERE TO LOOK
| Need | File |
|------|------|
| Base class | `base.py` - `BaseVideoPlayer` abstract class |
| Add new player | Create new `.py` file, inherit `BaseVideoPlayer`, add to `__init__.py` |
| URL detection logic | Each player's `can_handle()` method |
| Extract download link | Each player's `get_download_link()` method |
## CONVENTIONS
**Class naming**: `{Provider}Downloader` (e.g., `DoodStreamDownloader`)
**Required methods**:
```python
def can_handle(self, url: str) -> bool: ...
async def get_download_link(self, url: str, target_filename: str = None) -> tuple[str, str]: ...
```
**File operation**: Always use `sanitize_filename()` on extracted filenames.
**HTTP client**: Use `self.client` (AsyncClient from base class). Always close via `await self.close()` when done.
**Return format**: `(download_url, filename)` tuple.
## ANTI-PATTERNS
- Do NOT hardcode User-Agent in each player (use base class headers)
- Do NOT forget to call `await self.close()` after extraction
- Do NOT return None for missing URLs, raise an exception
- Do NOT use sync `requests`, use async `httpx`
- Do NOT skip the `target_filename` parameter, even if unused
@@ -12,6 +12,7 @@ from .rapidfile import RapidFileDownloader
from .vidzy import VidzyDownloader
from .luluv import LuLuvidDownloader
from .uqload import UqloadDownloader
from .smoothpre import SmoothpreDownloader
__all__ = [
"BaseVideoPlayer",
@@ -26,6 +27,7 @@ __all__ = [
"VidzyDownloader",
"LuLuvidDownloader",
"UqloadDownloader",
"SmoothpreDownloader",
]
@@ -43,6 +45,7 @@ def get_video_player(url: str) -> BaseVideoPlayer:
VidzyDownloader(),
LuLuvidDownloader(),
UqloadDownloader(),
SmoothpreDownloader(),
]
for player in players: