goon/scripts/clips_backfill_redgifs.py
goon-foss 4f5de92bfc feat(clips): tabele klipow do feedu Swipe + ingest RedGifs (etap 2)
Nowy wertykal krotkich pionowych klipow tworcow, osobno od scen: inne kolumny
(tworca, audio, lajki, nisze), inny cykl zycia, inna taksonomia, brak filtra
60 s. Tabele `clips` (unikalne source+source_id) i `clip_tags` z indeksem
(tag, clip_id) pod skan po tagu od losowego uuid w przyszlym feedzie.

Zrodlo nr 1: RedGifs, oficjalne API v2 z tokenem tymczasowym (zwiazany z IP
i UA, na 401 odnowienie). Globalne `order=latest` bez search_text daje ~100
na strone, kazde zapytanie widzi maks. 10 000 wynikow, wiec katalog chodzi
sie po niszach (skrypt backfillu). Pliki media.redgifs.com sa publiczne i bez
podpisu (206 z VPS-a i z telefonu), do bazy wchodzi gotowy adres.

Scheduler: job clips-latest co godzine (5 stron), zatrzymuje sie na stronie
bez nowych. Reaper (HEAD, 403/404/410 -> dead_at) jako skrypt, upsert
odzywia klip, ktory zrodlo znow podaje. API: GET /clips i /clips/stats do
pilota; wlasciwy feed, pamiec widzianych i telemetria to etap 3.

Sprawdzone tego dnia i odlozone: nsfwswipe (lustro v.redd.it, bez audio,
stoi od 19.08), Pornhub Shorties (zrodlo nr 2, HLS z tokenem 2 h, Referer
na segmentach, 0/110 performerow z kanonu).
2026-09-14 16:32:57 +02:00

37 lines
1.7 KiB
Python

"""Backfill klipów RedGifs po niszach (społecznościach). Do uruchamiania ręcznego.
Scheduler bierze tylko globalne „najnowsze" (co godzinę). Głębszy katalog chodzi się tu:
lista nisz z API jest posortowana od najpopularniejszych, dla każdej bierzemy N stron
po 100 gifów w wybranym porządku (`latest` = świeże, `top28` = najlepsze z miesiąca).
Jedno zapytanie RedGifs widzi maks. 10 000 wyników, więc `--per-niche-pages` ≤ 100.
Długi przebieg odpalaj przez `docker compose run -d --rm worker python -m scripts...`
(nie `exec`, patrz notatka o restarcie workera), z pliku, nie z heredoca.
python -m scripts.clips_backfill_redgifs --niche-pages 1 --per-niche-pages 1 # ~10k
python -m scripts.clips_backfill_redgifs --niche-pages 19 --per-niche-pages 5 --order top28
"""
from __future__ import annotations
import argparse
import logging
from app.scheduler.clips_ingest import run_redgifs_niches
def main() -> None:
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(message)s")
ap = argparse.ArgumentParser()
ap.add_argument("--niche-pages", type=int, default=1, help="stron listy nisz (100 nisz/strona)")
ap.add_argument("--per-niche-pages", type=int, default=1, help="stron gifów na niszę (100/strona)")
ap.add_argument("--order", default="latest", choices=["latest", "top", "top7", "top28", "trending", "score"])
ap.add_argument("--skip", type=int, default=0, help="pomiń pierwsze N nisz (wznowienie)")
a = ap.parse_args()
out = run_redgifs_niches(
niche_pages=a.niche_pages, per_niche_pages=a.per_niche_pages, order=a.order, skip=a.skip
)
print(out)
if __name__ == "__main__":
main()