Files
gnula_grabber/app.md
T

63 lines
2.9 KiB
Markdown

---
name: gnula_grabber
lang: py
domain: infra
version: 0.1.0
description: "Pipeline 2-partes: detecta pelis en castellano en gnula (crawler→catálogo SQLite) y las descarga via Chrome+CDP+NordVPN (HLS streaming+descifrado AES) → manual/movies → Radarr/Jellyfin. Captcha=humano."
tags: [gnula, hls, scraping, cdp, nordvpn, media, popelis, navegator]
uses_functions:
- extract_hls_from_cdp_tab_py_pipelines
- start_nordvpn_socks_bridge_bash_infra
- popelis_import_media_drop_py_infra
uses_types: []
framework: ""
entry_point: "crawl.py"
dir_path: "apps/gnula_grabber"
repo_url: ""
---
## Propósito
Sistema 2-partes para poblar la biblioteca Jellyfin con pelis en **castellano** desde gnula
(gnularetro.cc), saltando el bloqueo del ISP (DPI Allot, vía NordVPN) y Cloudflare (navegador real).
## Parte 1 — Detector (`crawl.py`)
Crawler vía **FlareSolverr** (Chrome headless NordVPN+CF). Recorre listados/categorías,
parsea `<article class="item movies">`, filtra los que tienen bandera **es.png** (= "Español"
dentro de la página; el alt-text del listado está invertido — usar el nombre de imagen),
dedup vs catálogo + Radarr, y guarda en SQLite `~/.config/popelis/gnula_catalog.db`
(tabla `movies`: href, title, year, flags, lang_es, status, in_library).
```bash
python3 apps/gnula_grabber/crawl.py "peliculas/estrenos" 2
python3 apps/gnula_grabber/crawl.py "peliculas/accion" 2 # paginación rota -> recorrer categorías
```
## Parte 2 — Downloader (`download.py`)
Consume el catálogo (pelis `status=pending`). Por cada una: navega a su página en el Chrome
CDP, clica el server **Español** (luluvid/luluvdo, `li[data-nume]` del grupo es.png), quita el
overlay de ad (`div z-index>=1000`) + `jwplayer().play()` + trusted click, espera `master.m3u8`
(captcha=humano), y delega a `grab_stream.py`. Marca `downloaded`.
```bash
python3 apps/gnula_grabber/download.py 1 # baja 1 peli pending
```
## Núcleo — `grab_stream.py`
Descarga HLS **streaming a disco** (no blob → no peta Chrome): in-page fetchea cada segmento
crudo (sesión browser = pasa el 522 CF), lo manda por CDP, y LOCAL descifra AES-128-CBC
(key+IV de `#EXT-X-KEY`; IV=media-sequence) + append a `.ts` + remux `ffmpeg -c copy``.mkv`
directo a `F:\POPELIS\manual\movies`. El timer systemd `popelis-import.timer` lo importa
(metadata Radarr) → `media` → Jellyfin (realtime monitor).
```bash
python3 apps/gnula_grabber/grab_stream.py "Titulo (2025)" # con el player luluvdo reproduciendo
```
## Prerequisitos
- Bridge NordVPN (`start_nordvpn_socks_bridge --port 8889`).
- gluetun+FlareSolverr arriba (para el crawler).
- Chrome lanzado por CDP+NordVPN (ver README.md, lanzamiento canónico).
- venv con `pycryptodome` + `websocket-client` (vía `uv run --with`).
## Gotchas
- Ver `README.md` para el flujo completo + gotchas (overlay ad, --load-extension Chrome 148,
token efímero, 522 solo-externos, paginación gnula rota → categorías).