No updates detected yet. GitHub releases will appear here.
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗Daily movie, TV, and book recommendations — movies and TV from your Plex library, books from your Goodreads want-to-read shelf — chosen by Gemini (on Vertex AI). This is an experiment in building an app with generative AI.
Stack: Go, Chi (routing), GORM (ORM), Postgres, Gemini on Vertex AI (google.golang.org/genai), zap + gutil/logging (JSON logs), OpenTelemetry (HTTP metrics on /metrics).
The home page shows one set of recommendations per calendar day:
ViewCount == 0).Each card shows poster, title, year, rating, genre, and runtime (movies), season count (TV), or author and page count (books). A tier's heading is omitted when it has no picks, so books simply don't appear unless Goodreads is configured.
Past days are listed at /dates (one row per distinct day, paginated).
rating and fall back to audienceRating, which is the only score Plex sets on TV shows/review/list_rss/{userID}), since the official API was retired in December 2020 and issues no new keysmetacritic.com/tv/<show>/season-N/| Method | Path | Description |
|---|---|---|
| GET | / | Today’s recommendations (UTC date) |
| GET | /date/YYYY-MM-DD | Recommendations for that day |
| GET | /dates | Paginated list of days (?page, ?size) |
| GET | /cron/recommend | Start recommendation generation (async; file lock) |
| GET | /cron/cache | Refresh Plex → Postgres cache (async; file lock) |
| GET | /stats | DB statistics |
| GET | /health | JSON health including DB ping |
| GET | /metrics | Prometheus exposition (otelhttp HTTP server metrics) |
| GET | /static/* | Embedded static files (e.g. favicon) |
| Variable | Required | Description |
|---|---|---|
DATABASE_URL | yes | Postgres connection string, e.g. postgres://user:pass@host:5432/recommender?sslmode=disable |
PLEX_URL | yes | Plex server base URL |
PLEX_TOKEN | yes | Plex token |
GOOGLE_CLOUD_PROJECT | yes | GCP project ID (Vertex AI API enabled) |
GOOGLE_CLOUD_LOCATION | yes | Vertex AI region, e.g. us-central1 |
GOOGLE_GENAI_USE_VERTEXAI | no | true to use Vertex AI (recommended); the SDK also supports the Gemini Developer API |
GEMINI_MODEL | no | Model ID (default gemini-2.5-flash) |
GEMINI_API_KEY | no | When set, call the Gemini API with this key instead of Vertex AI, e.g. through a LiteLLM proxy set by GOOGLE_GEMINI_BASE_URL |
GOOGLE_APPLICATION_CREDENTIALS | no | Path to a service-account key for local dev; production uses ambient ADC (workload identity) |
TRAKT_CLIENT_ID | no | Trakt API app client id; enables Trakt signals |
TRAKT_CLIENT_SECRET | no | Trakt API app client secret |
TRAKT_CONNECT_TOKEN | no | Shared secret required to call GET /trakt/connect?token=…; the endpoint is disabled when unset |
ANILIST_USERNAME | no | AniList username (public list); enables AniList signals |
OMDB_API_KEY | no | OMDb key; enables Metacritic Metascores |
OMDB_BATCH_SIZE | no | OMDb lookups per cache run (default 40, sized for OMDb's free 1000/day quota) |
GOODREADS_USER_ID | no | Goodreads numeric user id; enables the books tier |
Authentication to Vertex AI uses Application Default Credentials — no API key. Locally, run gcloud auth application-default login or set GOOGLE_APPLICATION_CREDENTIALS.
External sources only re-rank titles you already own in Plex — they never add new titles. Each is off unless configured, and all are synced during /cron/cache.
This is the beginning of the README. Read the rest at the original. Read the full README ↗
PORT | no | HTTP port (default 8080) |
POSTER_DIR | no | Directory for locally cached Plex posters (default posters; Docker Compose uses /data/posters) |