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