- app.md Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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. |
|
|
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-extensionestá MUERTO en Chrome stable 148, verchrome_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íauv run --with).
Gotchas
- Ver
README.mdpara el flujo completo + gotchas (overlay ad, --load-extension Chrome 148, token efímero, 522 solo-externos, paginación gnula rota → categorías).