fix(reap): dodaj brakujacy modul sondy do repo
`.gitignore` ma regule na `_*.py` (pliki robocze), przez co wspolny modul sondy wypadl z poprzedniego commita i zostaly w nim dwa skrypty importujace nieistniejacy modul.
This commit is contained in:
parent
f10d999410
commit
4df82b0bbe
1 changed files with 127 additions and 0 deletions
127
scripts/_reap_probe.py
Normal file
127
scripts/_reap_probe.py
Normal file
|
|
@ -0,0 +1,127 @@
|
||||||
|
"""Wspolna sonda dla pomiaru i przemialu martwych zrodel.
|
||||||
|
|
||||||
|
Trzymamy to w jednym miejscu, zeby bramka w `tube_reap_dead.py` sprawdzala DOKLADNIE ta
|
||||||
|
sama sonde, ktora potem mieli baze. Gdyby to byly dwie kopie, bramka moglaby przepuscic
|
||||||
|
przemial oparty na innym zachowaniu niz to, ktore przetestowala.
|
||||||
|
"""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import re
|
||||||
|
import time
|
||||||
|
from urllib.parse import urlsplit, urlunsplit
|
||||||
|
|
||||||
|
from app.extractors import try_extract
|
||||||
|
from app.extractors._models import HosterDead, TubePageError
|
||||||
|
|
||||||
|
ALIVE, DEAD, UNKNOWN = "alive", "dead", "unknown"
|
||||||
|
|
||||||
|
_SPACING_SEC = 0.4
|
||||||
|
|
||||||
|
# Ciag cyfr dosc dlugi, zeby byl numerem sceny, a nie fragmentem tytulu.
|
||||||
|
_NUM_RE = re.compile(r"\d{4,}")
|
||||||
|
# Segment wygladajacy na identyfikator, a nie na tytul: bez mysinikow i dosc dlugi,
|
||||||
|
# za to z cyframi (np. eporner `000goU7Teov`, xnxx `video-10003hb8`).
|
||||||
|
_ID_SEG_RE = re.compile(r"^[A-Za-z0-9_.-]{6,}$")
|
||||||
|
_ZNACZNIK = "99899989"
|
||||||
|
|
||||||
|
|
||||||
|
def bogus_url(url: str) -> str | None:
|
||||||
|
"""Prawdziwy adres -> adres sceny, ktora na pewno nie istnieje.
|
||||||
|
|
||||||
|
Sluzy do kontroli negatywnej: jesli taki adres wraca ZYWY, to znaczy, ze dla tego
|
||||||
|
tuba w ogole nie widzimy smierci i jego wynik trzeba odrzucic, a nie czytac jako
|
||||||
|
"brak trupow".
|
||||||
|
|
||||||
|
Pierwsza wersja podmieniala po prostu ostatni ciag cyfr, przez co nie budowala nic
|
||||||
|
dla tubow BEZ numeru sceny w adresie (`hentaigasm.com/1-funkan-dake-.../`,
|
||||||
|
`mypornerleak.com/1st-double-vag-.../`). Takie tuby wychodzily w raporcie jako "0/0",
|
||||||
|
czyli niezmierzone, a bylo ich okolo 950 tys. zrodel. Dlatego kolejno:
|
||||||
|
|
||||||
|
1. numer w parametrach zapytania (`siska.video/video.php?videoID=100007`),
|
||||||
|
2. segment sciezki bedacy identyfikatorem (`/video/39776/`, `/386900.html`,
|
||||||
|
`/hd-porn/000goU7Teov/`, `/video-10003hb8/`),
|
||||||
|
3. gdy identyfikatora nie ma, tub routuje po samym slugu, wiec psujemy slug.
|
||||||
|
|
||||||
|
Kolejnosc ma znaczenie: slug psujemy DOPIERO na koncu, bo czesc tubow routuje po
|
||||||
|
samym numerze i sluga nie sprawdza, wiec zepsuty slug oddalby 200 i falszywie
|
||||||
|
wygladal na slepote sondy.
|
||||||
|
"""
|
||||||
|
parts = urlsplit(url)
|
||||||
|
|
||||||
|
if parts.query and _NUM_RE.search(parts.query):
|
||||||
|
q = _NUM_RE.sub(_ZNACZNIK, parts.query, count=1)
|
||||||
|
return urlunsplit((parts.scheme, parts.netloc, parts.path, q, parts.fragment))
|
||||||
|
|
||||||
|
segs = parts.path.split("/")
|
||||||
|
idx = [i for i, s in enumerate(segs) if s]
|
||||||
|
if not idx:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def _rozbij(seg: str) -> tuple[str, str]:
|
||||||
|
rdzen, _, ext = seg.rpartition(".")
|
||||||
|
return (rdzen, ext) if rdzen else (seg, "")
|
||||||
|
|
||||||
|
def _zloz(i: int, nowy: str, ext: str) -> str:
|
||||||
|
segs[i] = f"{nowy}.{ext}" if ext else nowy
|
||||||
|
return urlunsplit(
|
||||||
|
(parts.scheme, parts.netloc, "/".join(segs), parts.query, parts.fragment)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Przebieg 1: segment bedacy CALY identyfikatorem (`/video/39776/`, `/386900.html`,
|
||||||
|
# `/hd-porn/000goU7Teov/`). Segmenty czysto literowe pomijamy, bo to nazwa trasy
|
||||||
|
# (`videos`, `episodes`, `watch`). Podmiana trasy sprawdzalaby, czy tub obsluguje
|
||||||
|
# dany adres, a nie czy istnieje scena, wiec tub oddajacy 404 na zla trase i 200 na
|
||||||
|
# nieistniejaca scene FALSZYWIE zdalby bramke. To jedyny kierunek bledu, ktory boli.
|
||||||
|
for i in reversed(idx):
|
||||||
|
rdzen, ext = _rozbij(segs[i])
|
||||||
|
if "-" in rdzen or not _ID_SEG_RE.match(rdzen):
|
||||||
|
continue
|
||||||
|
if rdzen.isdigit() or (rdzen.isalnum() and any(c.isdigit() for c in rdzen)):
|
||||||
|
nowy = (
|
||||||
|
_NUM_RE.sub(_ZNACZNIK, rdzen, count=1)
|
||||||
|
if _NUM_RE.search(rdzen)
|
||||||
|
else rdzen[:-2] + "zq"
|
||||||
|
)
|
||||||
|
return _zloz(i, nowy, ext)
|
||||||
|
|
||||||
|
# Przebieg 2: identyfikator wtopiony w slug (`/video-10003hb8/`,
|
||||||
|
# `/videos/01082023-a-bj-to-remember/`, `..._17800085.html`).
|
||||||
|
for i in reversed(idx):
|
||||||
|
rdzen, ext = _rozbij(segs[i])
|
||||||
|
if _NUM_RE.search(rdzen):
|
||||||
|
return _zloz(i, _NUM_RE.sub(_ZNACZNIK, rdzen, count=1), ext)
|
||||||
|
|
||||||
|
# Przebieg 3: identyfikatora nie ma, tub routuje po samym slugu, wiec psujemy slug.
|
||||||
|
last = idx[-1]
|
||||||
|
rdzen, _, ext = segs[last].rpartition(".")
|
||||||
|
if rdzen:
|
||||||
|
segs[last] = f"{rdzen}-zqx9nieistnieje.{ext}"
|
||||||
|
else:
|
||||||
|
segs[last] = f"{segs[last]}-zqx9nieistnieje"
|
||||||
|
return urlunsplit((parts.scheme, parts.netloc, "/".join(segs), parts.query, parts.fragment))
|
||||||
|
|
||||||
|
|
||||||
|
def probe(sitetag: str, url: str) -> tuple[str, str]:
|
||||||
|
"""(werdykt, szczegol) dla jednego adresu. Szczegol sluzy tylko do raportu.
|
||||||
|
|
||||||
|
Idzie przez `try_extract`, czyli ten sam kod, ktorego uzywa aplikacja przy
|
||||||
|
odtwarzaniu, wiec sonda nie moze "widziec" czegos innego niz user.
|
||||||
|
|
||||||
|
DEAD pada TYLKO na twardych sygnalach: HTTP 404/410 albo `HosterDead` (soft-404, np.
|
||||||
|
sxyprn "Post Not Found"). Wszystko inne, lacznie z pustym wynikiem ekstraktora, to
|
||||||
|
UNKNOWN i zrodla nikt nie rusza. Odwrotne ustawienie schowaloby zywe sceny po cichej
|
||||||
|
zmianie markupu, tak jak przy porntrex (6479 scen).
|
||||||
|
"""
|
||||||
|
time.sleep(_SPACING_SEC)
|
||||||
|
try:
|
||||||
|
out = try_extract(sitetag, url)
|
||||||
|
except TubePageError as e:
|
||||||
|
if e.status_code in (404, 410):
|
||||||
|
return DEAD, f"HTTP {e.status_code}"
|
||||||
|
# 403, 5xx, rate limit: NIE jest dowodem na nic.
|
||||||
|
return UNKNOWN, f"HTTP {e.status_code}"
|
||||||
|
except HosterDead:
|
||||||
|
return DEAD, "soft-404"
|
||||||
|
except Exception as e:
|
||||||
|
return UNKNOWN, type(e).__name__
|
||||||
|
return (ALIVE, "") if out else (UNKNOWN, "ekstraktor zwrocil pusto")
|
||||||
Loading…
Add table
Reference in a new issue