{"id":46682496,"url":"https://github.com/gioxx/trakt-multi-scrobbler","last_synced_at":"2026-04-28T22:01:11.008Z","repository":{"id":329021590,"uuid":"1117795311","full_name":"gioxx/trakt-multi-scrobbler","owner":"gioxx","description":"Web dashboard to map Jellyfin watches to one or more Trakt accounts.","archived":false,"fork":false,"pushed_at":"2026-04-28T20:23:26.000Z","size":1419,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-04-28T21:26:17.991Z","etag":null,"topics":["docker-image","jellyfin","trakt","trakt-tv"],"latest_commit_sha":null,"homepage":"https://hub.docker.com/r/gfsolone/trakt-multi-scrobbler","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gioxx.png","metadata":{"files":{"readme":"README.IT.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"gioxx","ko_fi":"gioxx","buy_me_a_coffee":"gioxx"}},"created_at":"2025-12-16T20:33:34.000Z","updated_at":"2026-04-28T20:17:47.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/gioxx/trakt-multi-scrobbler","commit_stats":null,"previous_names":["gioxx/trakt-multi-scrobbler"],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/gioxx/trakt-multi-scrobbler","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gioxx%2Ftrakt-multi-scrobbler","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gioxx%2Ftrakt-multi-scrobbler/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gioxx%2Ftrakt-multi-scrobbler/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gioxx%2Ftrakt-multi-scrobbler/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gioxx","download_url":"https://codeload.github.com/gioxx/trakt-multi-scrobbler/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gioxx%2Ftrakt-multi-scrobbler/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32400873,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-28T19:38:08.556Z","status":"ssl_error","status_checked_at":"2026-04-28T19:37:55.688Z","response_time":56,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docker-image","jellyfin","trakt","trakt-tv"],"created_at":"2026-03-09T00:35:16.146Z","updated_at":"2026-04-28T22:01:10.965Z","avatar_url":"https://github.com/gioxx.png","language":"HTML","funding_links":["https://github.com/sponsors/gioxx","https://ko-fi.com/gioxx","https://buymeacoffee.com/gioxx"],"categories":[],"sub_categories":[],"readme":"# Trakt Multi-Scrobbler (Jellyfin → Trakt)\n\n[English version](README.md)\n\n\u003cimg src=\"static/scrobbler_icon.webp\" alt=\"Trakt Multi-Scrobbler Logo\" width=\"256\" /\u003e\n\nDashboard web per scegliere quali utenti Jellyfin scrobblano verso quali account Trakt. Supporta più utenti per entrambi i servizi, regole per serie/film, tema chiaro/scuro e gestione account Trakt via device flow.\n\n## Funzionalità principali\n- Lettura libreria Jellyfin (film/episodi) con ID TMDB/IMDB/TVDB e locandine.\n- Scelta degli utenti Jellyfin che fungono da “fonte” (persistita).\n- Regole per contenuto: per ogni film/serie decidi a quali account Trakt inviare gli scrobble.\n- Sync automatica/su richiesta verso Trakt, con filtri per nuovi titoli e “Unassigned”.\n- Aggiunta/rimozione account Trakt dalla UI (device flow) e toggle per abilitarli.\n- Pagina dedicata per ogni account Trakt per vedere cosa sincronizza.\n- Backup/ripristino della configurazione (token JSON + db SQLite) dalla UI.\n- Tema chiaro/scuro e localizzazione (en/it).\n\n## Requisiti\n- Jellyfin con API key.\n- App Trakt con `client_id` e `client_secret` (https://trakt.tv/oauth/applications).\n- Python 3.11+ oppure Docker.\n- Node.js 18+ (opzionale, solo per rigenerare gli asset CSS della UI).\n\n## Configurazione rapida\n1) **Clona il repo**\n   ```bash\n   git clone https://github.com/gioxx/trakt-multi-scrobbler.git\n   cd trakt-multi-scrobbler\n   ```\n\nAggiornamento opzionale dello stylesheet UI (Tailwind, build locale):\n   ```bash\n   npm install\n   npm run build:css\n   ```\n   Per sviluppo continuo:\n   ```bash\n   npm run watch:css\n   ```\n\nI metadati nel footer (nome/versione/repo) vengono letti da `static/app_meta.json`.\n\n2) **Variabili d’ambiente minime**\n   ```bash\n   export JELLYFIN_URL=\"https://il-tuo-jellyfin\"\n   export JELLYFIN_APIKEY=\"API_KEY_JELLYFIN\"\n   export TRAKT_CLIENT_ID=\"CLIENT_ID_TRAKT\"\n   export TRAKT_CLIENT_SECRET=\"CLIENT_SECRET_TRAKT\"\n   ```\n   Opzionali:\n   ```bash\n   export TRAKT_STATE_PATH=\"trakt_accounts.json\"     # percorso stato account Trakt\n   export TRAKT_DB_PATH=\"trakt_sync.db\"              # facoltativo; SQLite con regole di sync (di default accanto a TRAKT_STATE_PATH)\n   export JELLYFIN_STATE_PATH=\"jellyfin_state.json\"  # facoltativo; di default usa la stessa cartella di TRAKT_STATE_PATH\n   export THUMB_CACHE_DIR=\"/data/thumb_cache\"        # facoltativo; cache locale poster (default accanto a TRAKT_STATE_PATH)\n   export THUMB_CACHE_TTL_HOURS=\"72\"                 # facoltativo; aggiorna la cache poster ogni N ore\n   export PROXY_IMAGES=\"true\"                        # facoltativo; proxy delle immagini Jellyfin tramite l'app (utile con HTTPS/CDN)\n   export IMAGE_CACHE_SECONDS=\"86400\"                # facoltativo; cache-control per le immagini proxate\n   export JELLYFIN_TIMEOUT=\"5\"                       # facoltativo; timeout (secondi) per le chiamate a Jellyfin\n   export THUMB_FETCH_TIMEOUT=\"5\"                    # facoltativo; timeout per il download delle locandine\n   export THUMB_MAX_HEIGHT=\"500\"                     # facoltativo; altezza massima poster richiesta a Jellyfin (px), larghezza auto-adattata\n   export INTERNAL_HTTP_BASE=\"http://127.0.0.1:8089\" # facoltativo; base interna usata per cache poster quando PROXY_IMAGES=true\n   export WATCH_THRESHOLD=\"0.95\"                     # soglia completamento (0-1)\n   export REFRESH_MINUTES=\"30\"                       # polling Jellyfin\n   ```\n\n3) **Avvio locale (Python)**\n   ```bash\n   pip install -r requirements.txt\n   uvicorn app.main:app --reload --host 0.0.0.0 --port 8089\n   ```\n   Apri http://localhost:8089.\n\n4) **Avvio con Docker (immagine già pronta)**\n   - GitHub Container Registry  \n     ```bash\n     docker run -d --name trakt-multi-scrobbler \\\n       -p 8089:8089 \\\n       -e JELLYFIN_URL=\"https://il-tuo-jellyfin\" \\\n       -e JELLYFIN_APIKEY=\"API_KEY_JELLYFIN\" \\\n       -e TRAKT_CLIENT_ID=\"CLIENT_ID_TRAKT\" \\\n       -e TRAKT_CLIENT_SECRET=\"CLIENT_SECRET_TRAKT\" \\\n       -e TRAKT_STATE_PATH=\"/data/trakt_accounts.json\" \\\n       -e JELLYFIN_STATE_PATH=\"/data/jellyfin_state.json\" \\\n       -v tms-data:/data \\\n       ghcr.io/gioxx/trakt-multi-scrobbler:latest\n     ```\n   - Docker Hub  \n     ```bash\n     docker run -d --name trakt-multi-scrobbler \\\n       -p 8089:8089 \\\n       -e JELLYFIN_URL=\"https://il-tuo-jellyfin\" \\\n       -e JELLYFIN_APIKEY=\"API_KEY_JELLYFIN\" \\\n       -e TRAKT_CLIENT_ID=\"CLIENT_ID_TRAKT\" \\\n       -e TRAKT_CLIENT_SECRET=\"CLIENT_SECRET_TRAKT\" \\\n       -e TRAKT_STATE_PATH=\"/data/trakt_accounts.json\" \\\n       -e JELLYFIN_STATE_PATH=\"/data/jellyfin_state.json\" \\\n       -v tms-data:/data \\\n       gfsolone/trakt-multi-scrobbler:latest\n     ```\n\n5) **Avvio con Docker Compose (file del repo)**\n   ```bash\n   docker compose up --build\n   ```\n   Usa il volume nominato previsto in `docker-compose.yml` (`/data`). Se vuoi inizializzarlo:\n   ```bash\n   docker compose run --rm trakt-multi-scrobbler sh -c 'cat \u003e /data/trakt_accounts.json \u003c\u003cEOF\\n{ \\\"accounts\\\": [], \\\"last_synced\\\": {} }\\nEOF'\n   ```\n\n## Collegare account Trakt (device flow)\n- Dalla UI clicca “Add Trakt account”, copia il codice, apri il link, autorizza: i token vengono salvati in `TRAKT_STATE_PATH` (JSON); regole di sync e timestamp sono nel file SQLite `TRAKT_DB_PATH`.\n- In alternativa, via curl:\n  1. `POST https://api.trakt.tv/oauth/device/code` con `client_id`.\n  2. Autorizza via `verification_url` con `user_code`.\n  3. `POST https://api.trakt.tv/oauth/device/token` con `client_id`, `client_secret`, `code` per ottenere `access_token`/`refresh_token`/`expires_in`.\n  4. Calcola `expires_at = now + expires_in` (secondi) e inserisci nel JSON.\n\n## Come usare la UI\n- **Jellyfin User(s)**: scegli quali utenti Jellyfin sono monitorati (checkbox nel modale). Persistenza in `JELLYFIN_STATE_PATH`.\n- **Trakt User(s)**: aggiungi/rimuovi account via device flow, attiva/disattiva con la checkbox. I token stanno in `TRAKT_STATE_PATH`; regole e stato sync sono nel database SQLite `TRAKT_DB_PATH`. Ogni scheda apre la pagina dedicata dell'account.\n- **Backup \u0026 restore**: dalla UI principale puoi scaricare uno ZIP con token JSON + db SQLite (e stato Jellyfin); carica lo ZIP per ripristinare su un'altra installazione.\n- **Content filters**: ricerca, filtro tipo (film/serie), filtro alfabetico e filtro per account Trakt; assegna le regole per film/serie (checkbox per account). “Unassigned” mostra i titoli senza destinazione.\n- **Sync to Trakt**: invia subito gli eventi completati; la sync gira anche in automatico ogni `REFRESH_MINUTES`.\n- **Refresh Jellyfin**: forza l’aggiornamento di libreria/utenti/cache.\n- **Recently watched**: ultimi 6 titoli visti dagli utenti Jellyfin selezionati.\n\n## Note e limiti\n- Vengono scrobblati solo i titoli con ID TMDB/IMDB/TVDB.\n- I timestamp inviati a Trakt sono quelli originali di Jellyfin.\n- I token Trakt vengono refreshati automaticamente.\n- Localizzazione: i file sono in `static/locales/en.json` e `static/locales/it.json`. Per aggiungere una lingua crea `static/locales/\u003ccodice\u003e.json` e aggiungi l’opzione al select lingua in `static/index.html`.\n- Se usi Plex come principale ma hai anche Jellyfin, puoi abbinarlo a `luigi311/jellyplex-watched` (https://github.com/luigi311/JellyPlex-Watched) per tenere allineati Jellyfin e Plex.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgioxx%2Ftrakt-multi-scrobbler","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgioxx%2Ftrakt-multi-scrobbler","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgioxx%2Ftrakt-multi-scrobbler/lists"}