goon/tests/test_redgifs_mapping.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

54 lines
1.8 KiB
Python

from datetime import UTC, datetime
from app.connectors.clips.redgifs import map_gif, tag_slug
SAMPLE = {
"id": "unusualequalaxolotl",
"type": 1,
"createDate": 1789393316,
"contentType": "Solo Female",
"duration": 9.4,
"hasAudio": True,
"height": 1920,
"width": 1080,
"hls": True,
"likes": 12,
"views": 340,
"niches": ["just-boobs"],
"tags": ["Femdom", "Pegging", "Strap On", "Strap On"],
"urls": {
"sd": "https://media.redgifs.com/UnusualEqualAxolotl-mobile.mp4",
"hd": "https://media.redgifs.com/UnusualEqualAxolotl.mp4",
"poster": "https://media.redgifs.com/UnusualEqualAxolotl-poster.jpg",
"thumbnail": "https://media.redgifs.com/UnusualEqualAxolotl-mobile.jpg",
},
"userName": "kitsuneroth",
"verified": True,
}
def test_map_gif_basic():
c = map_gif(SAMPLE)
assert c is not None
assert c.source == "redgifs" and c.source_id == "unusualequalaxolotl"
assert c.creator == "kitsuneroth" and c.creator_verified is True
assert c.has_audio is True and c.duration_sec == 9.4
assert c.width == 1080 and c.height == 1920
assert c.hd_url.endswith("UnusualEqualAxolotl.mp4")
assert c.published_at == datetime.fromtimestamp(1789393316, tz=UTC)
# slugi, bez duplikatow, kolejnosc zachowana
assert c.tags == ["femdom", "pegging", "strap-on"]
assert c.niches == ["just-boobs"]
assert c.likes == 12 and c.views == 340
def test_map_gif_skips_images_and_fileless():
assert map_gif({**SAMPLE, "type": 2}) is None
assert map_gif({**SAMPLE, "urls": {}}) is None
assert map_gif({**SAMPLE, "id": ""}) is None
def test_tag_slug():
assert tag_slug("Big Tits") == "big-tits"
assert tag_slug(" 18 Years Old!! ") == "18-years-old"
assert tag_slug("") == ""