Skip to content

Commit 2c702bd

Browse files
committed
docs: update DOCKER.md and README.md, and add README in spanish
1 parent 9fb7f0d commit 2c702bd

3 files changed

Lines changed: 451 additions & 154 deletions

File tree

DOCKER.md

Lines changed: 98 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,45 +4,117 @@ Requirements: Docker and Docker Compose installed.
44

55
How to build the image
66

7+
# Docker Guide
8+
9+
## Requirements
10+
11+
- Docker
12+
- Docker Compose
13+
14+
## Build image
15+
716
```bash
817
docker build -t filmaffinity-scores .
918
```
1019

11-
How to run with docker-compose
20+
## Run with Docker Compose
1221

13-
1. Copy `.env.example` to `.env` and edit values if needed.
14-
2. Start the app:
22+
1. Copy `.env.example` to `.env` and configure values.
23+
2. Start services.
24+
25+
Full stack (API + scheduler):
1526

1627
```bash
17-
docker compose up --build
28+
docker compose up -d --build
1829
```
1930

20-
This mounts the local `data/` folder into the container to persist cache between runs.
21-
31+
API only:
2232

23-
Environment variables reference
24-
25-
- `PORT` : port in container and host mapping (default `8085`).
26-
- `CACHE_TTL` : cache TTL seconds (default `86400`).
27-
- `JELLYFIN_BASE_URL`: your Jellyfin base URL (e.g. `http://192.168.1.31:8096`).
28-
- `JELLYFIN_API_KEY`: your Jellyfin API key.
29-
- `JELLYFIN_AUTH_MODE`: auth mode for Jellyfin client (`auto`|`header`|`query`).
30-
- `ENABLE_POSTER_BADGES`: enable FilmAffinity badge overlay and poster upload (`true`/`false`, default `false`).
31-
- `POSTER_BADGE_POSITION`: badge position (`top-right` default, also `top-left`, `bottom-right`, `bottom-left`).
32-
- `POSTER_BADGE_SIZE`: badge width ratio relative to poster width (default `0.2`).
33-
- `PUPPETEER_EXECUTABLE_PATH` : optional — set only if you want to use a system-installed Chromium.
34-
- `DEBUG_SCREENSHOTS` : set to `true` to persist debug screenshots under the `data/` folder inside the container (disabled by default).
33+
```bash
34+
docker compose up -d app
35+
```
3536

36-
Sync script specific variables (see `.env.example`):
37+
Scheduler only:
3738

38-
- `SYNC_JELLYFIN_DRY_RUN`, `SYNC_JELLYFIN_LIMIT`, `SYNC_JELLYFIN_BATCH_SIZE`, `SYNC_JELLYFIN_DELAY_MS`, `SYNC_JELLYFIN_RETRIES`, `SYNC_JELLYFIN_RETRY_DELAY`, `SYNC_JELLYFIN_SET_CRITIC`, `SYNC_JELLYFIN_FORCE`, `SYNC_JELLYFIN_PAGE_SIZE`, `SYNC_JELLYFIN_INCLUDE_ITEM_TYPES`.
39+
```bash
40+
docker compose up -d scheduler
41+
```
3942

40-
Notes on Puppeteer
43+
## Defined services
44+
45+
- `app`:
46+
- Runs `npm start`
47+
- Exposes port `8085` in the container
48+
- Maps `${PORT:-8085}:8085` on the host
49+
- `scheduler`:
50+
- Runs `node scripts/scheduler.js`
51+
- Executes recurring `update-cache` + `sync-jellyfin` cycles
52+
53+
## Data persistence
54+
55+
Both services mount:
56+
57+
- `./data:/app/data`
58+
59+
This persists:
60+
61+
- SQLite database (default `data/ratings.db`)
62+
- Original poster backups (default `data/poster-originals`)
63+
- Debug screenshots when `DEBUG_SCREENSHOTS=true`
64+
65+
## Key environment variables (summary)
66+
67+
See `.env.example` for full details.
68+
69+
- General:
70+
- `PORT` (default `8085`)
71+
- `LOG_LEVEL` (`debug|info|warn|error`)
72+
- `DB_PATH` (default `data/ratings.db`)
73+
- `CACHE_TTL` (seconds)
74+
- Jellyfin:
75+
- `JELLYFIN_BASE_URL`
76+
- `JELLYFIN_API_KEY`
77+
- `JELLYFIN_AUTH_MODE` (`auto|header|query`)
78+
- `JELLYFIN_TIMEOUT`
79+
- Sync:
80+
- `SYNC_JELLYFIN_DRY_RUN`
81+
- `SYNC_JELLYFIN_LIMIT`
82+
- `SYNC_JELLYFIN_BATCH_SIZE`
83+
- `SYNC_JELLYFIN_DELAY_MS`
84+
- `SYNC_JELLYFIN_RETRIES`
85+
- `SYNC_JELLYFIN_RETRY_DELAY`
86+
- `SYNC_JELLYFIN_SET_CRITIC`
87+
- `SYNC_JELLYFIN_FORCE`
88+
- `SYNC_JELLYFIN_PAGE_SIZE`
89+
- `SYNC_JELLYFIN_INCLUDE_ITEM_TYPES`
90+
- Poster processing:
91+
- `ENABLE_POSTER_BADGES`
92+
- `POSTER_BADGE_POSITION`
93+
- `POSTER_BADGE_SIZE`
94+
- `POSTER_PRESERVE_ORIGINAL`
95+
- `POSTER_ORIGINALS_DIR`
96+
- Scraping:
97+
- `REQUEST_DELAY_MS`
98+
- `DEBUG_SCREENSHOTS`
99+
- `PUPPETEER_EXECUTABLE_PATH` (optional)
100+
101+
## Puppeteer notes for containers
102+
103+
- The `Dockerfile` installs required system packages for Chromium.
104+
- A compatible Chromium is installed during `npm ci`.
105+
- If sandbox issues appear, consider launching Puppeteer with `--no-sandbox --disable-setuid-sandbox` or set `PUPPETEER_EXECUTABLE_PATH` to a system Chromium binary.
106+
107+
## Quick validation
108+
109+
Check the API health endpoint:
41110

42-
- The image installs runtime libraries required by Chromium; Puppeteer will download a compatible Chromium during `npm install` inside the image.
43-
- If you encounter Chromium sandbox issues, try launching Puppeteer with `--no-sandbox --disable-setuid-sandbox` flags or set `PUPPETEER_EXECUTABLE_PATH` to a system Chromium binary.
111+
```bash
112+
curl "http://localhost:${PORT:-8085}/health"
113+
```
44114

45-
Validation
115+
View logs:
46116

47-
- The compose service exposes the app on `http://localhost:PORT`.
48-
- Data is persisted in `./data/ratings.json`.
117+
```bash
118+
docker compose logs -f app
119+
docker compose logs -f scheduler
120+
```

README-ES.md

Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
# FilmAffinity Scores (API + Jellyfin Sync)
2+
3+
![Node.js](https://img.shields.io/badge/Node.js-20.x-brightgreen?logo=node.js)
4+
![Docker](https://img.shields.io/badge/Docker-ready-blue?logo=docker)
5+
![License](https://img.shields.io/badge/license-MIT-lightgrey)
6+
7+
## ES
8+
9+
Servicio Node.js para:
10+
11+
1. Consultar valoraciones de FilmAffinity (scraping con Puppeteer).
12+
2. Exponerlas vía API REST.
13+
3. Guardarlas en caché persistente (SQLite).
14+
4. Sincronizar ratings en Jellyfin.
15+
5. Opcionalmente reescribir pósters en Jellyfin con badge visual de nota.
16+
17+
No es solo una API: también incluye un flujo batch y un scheduler para mantener la librería actualizada.
18+
19+
### Qué hace hoy el proyecto
20+
21+
- API HTTP para consultar una película por título/año.
22+
- Caché en memoria (node-cache) + caché persistente (data/ratings.db).
23+
- Scraper con puppeteer-extra + stealth plugin.
24+
- Sincronización de metadatos en Jellyfin (CommunityRating, opcional CriticRating).
25+
- Procesamiento de póster y subida de imagen a Jellyfin.
26+
- Scheduler para ejecutar ciclos automáticos de actualización.
27+
28+
### Arquitectura rápida
29+
30+
- npm start: levanta la API (src/index.js).
31+
- npm run update-cache: recorre la librería de Jellyfin y refresca caché en SQLite.
32+
- npm run sync-jellyfin: sincroniza ratings FilmAffinity -> Jellyfin.
33+
- npm run scheduler: bucle continuo que ejecuta update-cache + sync-jellyfin en cada ciclo.
34+
35+
### Requisitos
36+
37+
- Node.js 20+
38+
- Acceso a una instancia de Jellyfin (si vas a usar sync/scheduler)
39+
- JELLYFIN_API_KEY con permisos para leer y actualizar metadata
40+
41+
### Instalación
42+
43+
```bash
44+
git clone https://github.com/Cruzadera/filmaffinity-scores.git
45+
cd filmaffinity-scores
46+
npm install
47+
cp .env.example .env
48+
```
49+
50+
Edita .env con tus valores reales antes de ejecutar sincronizaciones.
51+
52+
### Modo API (REST)
53+
54+
Arranque:
55+
56+
```bash
57+
npm start
58+
```
59+
60+
Por defecto expone en http://localhost:8085
61+
62+
Endpoints:
63+
64+
- GET /movie?title=...&year=...
65+
- title obligatorio
66+
- year obligatorio (4 dígitos)
67+
- Devuelve 400/404/502 según validación, no encontrado o fallo de scraping
68+
- GET /rating?title=...&year=...
69+
- title obligatorio
70+
- year opcional
71+
- GET /health
72+
73+
Ejemplo:
74+
75+
```bash
76+
curl "http://localhost:8085/movie?title=Alien&year=1979"
77+
```
78+
79+
Respuesta típica:
80+
81+
```json
82+
{
83+
"title": "Alien",
84+
"year": "1979",
85+
"rating": 8.1,
86+
"votes": "123456",
87+
"url": "https://www.filmaffinity.com/es/film123456.html"
88+
}
89+
```
90+
91+
### Sincronización con Jellyfin
92+
93+
Script recomendado:
94+
95+
```bash
96+
npm run sync-jellyfin
97+
```
98+
99+
Por defecto corre en dry-run (SYNC_JELLYFIN_DRY_RUN=true): calcula cambios pero no los aplica.
100+
101+
Prueba controlada:
102+
103+
```bash
104+
LOG_LEVEL=debug \
105+
SYNC_JELLYFIN_DRY_RUN=true \
106+
node scripts/sync-jellyfin.js --limit=5 --batch-size=2
107+
```
108+
109+
Aplicar cambios reales:
110+
111+
```bash
112+
LOG_LEVEL=debug \
113+
SYNC_JELLYFIN_DRY_RUN=false \
114+
node scripts/sync-jellyfin.js --limit=20 --batch-size=2
115+
```
116+
117+
Sincronizar también pósters con badge:
118+
119+
```bash
120+
LOG_LEVEL=debug \
121+
SYNC_JELLYFIN_DRY_RUN=false \
122+
ENABLE_POSTER_BADGES=true \
123+
POSTER_BADGE_POSITION=top-right \
124+
POSTER_BADGE_SIZE=0.2 \
125+
node scripts/sync-jellyfin.js --limit=20 --batch-size=2
126+
```
127+
128+
### Scheduler automático
129+
130+
```bash
131+
npm run scheduler
132+
```
133+
134+
Ciclo:
135+
136+
1. Ejecuta update-cache
137+
2. Ejecuta sync-jellyfin
138+
3. Espera SLEEP_SECONDS (default 86400)
139+
4. Repite en bucle
140+
141+
SYNC_JELLYFIN_FORCE_ON_STARTUP=true permite forzar la primera pasada.
142+
143+
### Variables de entorno (resumen)
144+
145+
Consulta .env.example para lista completa.
146+
147+
- Generales:
148+
- PORT (default 8085)
149+
- LOG_LEVEL (debug|info|warn|error, default info)
150+
- DB_PATH (default data/ratings.db)
151+
- CACHE_TTL en segundos (default 86400)
152+
- Jellyfin:
153+
- JELLYFIN_BASE_URL
154+
- JELLYFIN_API_KEY
155+
- JELLYFIN_AUTH_MODE (auto|header|query)
156+
- JELLYFIN_TIMEOUT
157+
- Sync:
158+
- SYNC_JELLYFIN_DRY_RUN, SYNC_JELLYFIN_LIMIT, SYNC_JELLYFIN_BATCH_SIZE
159+
- SYNC_JELLYFIN_DELAY_MS, SYNC_JELLYFIN_RETRIES, SYNC_JELLYFIN_RETRY_DELAY
160+
- SYNC_JELLYFIN_SET_CRITIC, SYNC_JELLYFIN_FORCE, SYNC_JELLYFIN_PAGE_SIZE
161+
- SYNC_JELLYFIN_INCLUDE_ITEM_TYPES
162+
- Pósters:
163+
- ENABLE_POSTER_BADGES
164+
- POSTER_BADGE_POSITION
165+
- POSTER_BADGE_SIZE
166+
- POSTER_PRESERVE_ORIGINAL
167+
- POSTER_ORIGINALS_DIR
168+
- POSTER_BADGE_DRY_RUN / POSTER_BADGE_FORCE
169+
- Scraping/cache incremental:
170+
- REQUEST_DELAY_MS
171+
- RECENT_TTL_DAYS
172+
- RECENT_YEARS
173+
- DEBUG_SCREENSHOTS
174+
175+
### Docker
176+
177+
En docker-compose.yml hay dos servicios:
178+
179+
- app: API REST
180+
- scheduler: ciclo automático cache + sync
181+
182+
Arrancar stack completo:
183+
184+
```bash
185+
docker compose up -d --build
186+
```
187+
188+
Solo scheduler:
189+
190+
```bash
191+
docker compose up -d scheduler
192+
```
193+
194+
El volumen ./data:/app/data persiste SQLite y backups de pósters.
195+
196+
### Tests
197+
198+
```bash
199+
npm test
200+
```
201+
202+
### Notas
203+
204+
- El scraping puede romperse si FilmAffinity cambia HTML o anti-bot.
205+
- Las actualizaciones en Jellyfin dependen de permisos del API key.
206+
- En producción, empezar en dry-run y luego pasar a modo escritura.
207+
208+
## Disclaimer
209+
210+
Proyecto orientado a uso personal/autoalojado y fines educativos. Respeta los términos de uso de servicios externos.
211+
212+
## License
213+
214+
Ver LICENSE.

0 commit comments

Comments
 (0)