Files
ohm_streaming/app/scrapers/hosters/vidmoly.py
T
Roman 41566ab5fb v0.1.0 — Réécriture complète de OhmStreaming
Nouvelle version réécrite de zéro : recherche multi-sources (Vostfree,
French-Manga), extraction 2 niveaux, proxy vidéo intégré, streaming/téléchargement
HLS, métadonnées Kitsu, bibliothèque locale, comptes JWT + administration,
découverte fusionnée, indexeur Torznab (Sonarr/Prowlarr).
2026-09-22 10:05:47 +00:00

45 lines
1.7 KiB
Python

"""Extracteur VidMoly (vidmoly.to / vidmoly.me) — page embed → mp4/m3u8.
Le lecteur jwplayer est configuré dans du JS parfois packé (p,a,c,k,e,d) :
`sources: [{file: "...m3u8"}]`. On dépacke si besoin puis on extrait par regex.
"""
import logging
import re
from app.scrapers.base import HosterExtractor, ScrapeError, VideoLink, register_hoster
from app.scrapers.hosters._packer import unpack_packed_js
from app.scrapers.http import fetch
logger = logging.getLogger(__name__)
_PATTERNS = (
re.compile(r'sources\s*:\s*\[\s*\{[^}]*?file\s*:\s*["\'](?P<url>[^"\']+)["\']'),
re.compile(r'file\s*:\s*["\'](?P<url>https?://[^"\']+?\.(?:m3u8|mp4)[^"\']*)["\']'),
re.compile(r'["\'](?P<url>https?://[^"\']*?\.(?:m3u8|mp4)(?:\?[^"\']*)?)["\']'),
)
@register_hoster
class VidmolyExtractor(HosterExtractor):
name = "vidmoly"
domains = ("vidmoly.to", "vidmoly.me", "vidmoly.biz", "vidmoly.com")
async def extract(self, embed_url: str) -> VideoLink:
html = await fetch(embed_url)
candidates: list[str] = []
for content in (html, unpack_packed_js(html) or ""):
for pattern in _PATTERNS:
for match in pattern.finditer(content):
candidates.append(match.group("url"))
video = [u for u in candidates if re.search(r"\.(mp4|m3u8)(\?|$)", u)]
url = next((u for u in video if ".mp4" in u), None) or (video[0] if video else None)
if not url:
raise ScrapeError(f"vidmoly : URL vidéo introuvable dans {embed_url}")
return VideoLink(
url=url,
hoster=self.name,
headers={"Referer": embed_url},
is_hls=".m3u8" in url,
)