Sign inSign up

cplieger/tautulli-remap

By cplieger

Updated 5 minutes ago

Fix broken Tautulli watch history after reorganizing your Plex libraries

Image
Developer tools
Databases & storage
0

10K+

cplieger/tautulli-remap repository overview

tautulli-remap

Fix broken Tautulli watch history after reorganizing your Plex libraries.

What it does

When you reorganize your Plex libraries (move files, re-add content, change folder structure), Plex assigns new internal IDs to your media. This breaks Tautulli's watch history: it can no longer link history entries to the right items. This tool automatically finds the correct new IDs and updates Tautulli's database, preserving your watch history and statistics.

For each stale entry, it finds the correct current rating key in Plex using a chain of strategies, most precise first:

  1. Episode-GUID resolution (TV shows): resolves a show through one of its watched episodes' stable Plex GUIDs, which map directly to the show's current key. Exact and collision-free, and it restores the show's full watch history (all seasons and episodes).
  2. GUID match: Plex's globally unique identifier; covers movies and shows whose history still carries a show-level GUID, for example from the legacy thetvdb agent.
  3. Title+year match (fallback): matches by title and release year when no GUID resolves.
  4. Title-only with media type guard (optional): last resort matching by title alone, restricted to the same media type to reduce false positives.
Why this design
  • Three run modes: REMAP_INTERVAL set to a Go duration like 24h for a built-in timer, REMAP_INTERVAL=off for resident-idle (stays healthy, awaits docker exec ... tautulli-remap trigger), or tautulli-remap trigger for a one-shot pass that reports its outcome via its exit code.
  • Dry-run by default for safety: no changes are applied until you explicitly set DRY_RUN=false, so you can always preview first.
  • Matching strategies with increasing aggressiveness: starts with the exact ones (episode-GUID resolution for shows, GUID match for movies), falls back to title+year, and optionally title-only, giving you control over the risk/coverage tradeoff.
  • Stdlib-first, minimal dependencies: pure Go on the standard library plus a first-party shared-lib set (health, httpx, plexapi, scheduler, envx, slogx, runesafe, keyenc) and golang.org/x/sync, minimizing supply-chain risk.
  • Distroless and rootless: runs as nonroot on gcr.io/distroless/static-debian13 with no shell or package manager.

Pull

docker pull cplieger/tautulli-remap:latest

Also published to ghcr.io/cplieger/tautulli-remap with identical images and tags. Release versions are tagged vX.Y.Z alongside latest.

Quick start

# Example compose for tautulli-remap. See the README for all configuration options and hardening.
services:
  tautulli-remap:
    image: ghcr.io/cplieger/tautulli-remap:latest
    container_name: tautulli-remap
    restart: unless-stopped

    environment:
      TAUTULLI_URL: "http://tautulli:8181"
      TAUTULLI_API_KEY: "your-tautulli-api-key"  # required
      PLEX_URL: "http://plex:32400"
      PLEX_TOKEN: "your-plex-token"  # required
      REMAP_INTERVAL: "24h"  # Go duration; "off" = resident-idle
      DRY_RUN: "true"  # set to false to apply changes

Documentation

License

GPL-3.0-or-later. See LICENSE. The image carries the license text of every bundled component under /usr/share/licenses/.

Tag summary

Content type

Image

Digest

sha256:5730d3321

Size

3.7 MB

Last updated

7 minutes ago

docker pull cplieger/tautulli-remap