Files
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

3.5 KiB

name, lang, domain, version, description, tags, uses_functions, uses_types, framework, entry_point, dir_path, repo_url
name lang domain version description tags uses_functions uses_types framework entry_point dir_path repo_url
gnula_grabber py infra 0.1.0 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.
gnula
hls
scraping
cdp
nordvpn
media
popelis
navegator
extract_hls_from_cdp_tab_py_pipelines
start_nordvpn_socks_bridge_bash_infra
popelis_import_media_drop_py_infra
chrome_load_extensions_bash_browser
crawl.py apps/gnula_grabber

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).

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.

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).

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):
    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).