Files
gnula_grabber/app.md
T
egutierrez b45bc9bbad chore: auto-commit (1 archivos)
- app.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-30 17:28:47 +02:00

74 lines
3.5 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
- chrome_load_extensions_bash_browser
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 CDP+NordVPN con perfil **`gnula_popelis`** (cookies de gnula/luluvdo + uBlock
Origin Lite ya instalado vía Web Store — persiste en el perfil, no se pasan flags de ext;
`--load-extension` está MUERTO en Chrome stable 148, ver `chrome_load_extensions_bash_browser`):
```bash
CHROME="/mnt/c/Program Files/Google/Chrome/Application/chrome.exe"
setsid "$CHROME" --remote-debugging-port=9222 --remote-debugging-address=0.0.0.0 \
'--remote-allow-origins=*' \
'--user-data-dir=C:\Users\lucas\AppData\Local\gnula_popelis' \
--proxy-server=http://127.0.0.1:8889 --no-first-run --no-default-browser-check \
'https://www.gnularetro.cc/' </dev/null >/tmp/chrome_gnula.log 2>&1 &
```
- 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).