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).
41 lines
1.3 KiB
Python
41 lines
1.3 KiB
Python
"""Décompresseur pour le JavaScript packé « p,a,c,k,e,d » (Dean Edwards).
|
|
|
|
Utilisé par plusieurs hébergeurs vidéo (Uqload, VidMoly…) pour masquer
|
|
l'URL du lecteur : le HTML contient `eval(function(p,a,c,k,e,d){...}(...))`.
|
|
"""
|
|
|
|
import re
|
|
|
|
_DIGITS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
|
|
_PACKED_RE = re.compile(
|
|
r"\}\('(?P<payload>.*?)',(?P<a>\d+),(?P<c>\d+),'(?P<keys>.*?)'\.split\('\|'\)",
|
|
re.DOTALL,
|
|
)
|
|
|
|
|
|
def _base_n(number: int, base: int) -> str:
|
|
if number == 0:
|
|
return "0"
|
|
chars = []
|
|
while number:
|
|
number, rest = divmod(number, base)
|
|
chars.append(_DIGITS[rest])
|
|
return "".join(reversed(chars))
|
|
|
|
|
|
def unpack_packed_js(text: str) -> str | None:
|
|
"""Retourne le JS dépacké si `text` contient un bloc packé, sinon None."""
|
|
match = _PACKED_RE.search(text)
|
|
if not match:
|
|
return None
|
|
payload = match.group("payload").replace("\\\\", "\\").replace("\\'", "'")
|
|
base, count = int(match.group("a")), int(match.group("c"))
|
|
keys = match.group("keys").split("|")
|
|
for index in range(count - 1, -1, -1):
|
|
token = _base_n(index, base)
|
|
if keys[index]:
|
|
replacement = keys[index].replace("\\", "\\\\")
|
|
payload = re.sub(rf"\b{re.escape(token)}\b", replacement, payload)
|
|
return payload
|