jellyplex-watched

Docker app from Luigi311's Repository

Overview

Sync watched state between Plex, Jellyfin, and Emby

JellyPlex-Watched

Codacy Badge

Sync watched between jellyfin, plex and emby locally

Description

Keep in sync all your users watched history between jellyfin, plex and emby servers locally. This uses file names and provider ids to find the correct episode/movie between the two. This is not perfect but it works for most cases. You can use this for as many servers as you want by entering multiple options in the .env plex/jellyfin section separated by commas.

Features

Plex

  • [x] Match via filenames
  • [x] Match via provider ids
  • [x] Map usernames
  • [x] Use single login
  • [x] One way/multi way sync
  • [x] Sync watched
  • [x] Sync in progress
  • [ ] Sync view dates

Jellyfin

  • [x] Match via filenames
  • [x] Match via provider ids
  • [x] Map usernames
  • [x] Use single login
  • [x] One way/multi way sync
  • [x] Sync watched
  • [x] Sync in progress
  • [x] Sync view dates

Emby

  • [x] Match via filenames
  • [x] Match via provider ids
  • [x] Map usernames
  • [x] Use single login
  • [x] One way/multi way sync
  • [x] Sync watched
  • [x] Sync in progress
  • [x] Sync view dates

Configuration

Full list of configuration options can be found in the .env.sample

Installation

Baremetal

  • Install uv

  • Create a .env file similar to .env.sample; fill in baseurls and tokens, remember to uncomment anything you wish to use (e.g., user mapping, library mapping, black/whitelist, etc.). If you want to store your .env file anywhere else or under a different name you can use ENV_FILE variable to specify the location.

  • Run

    uv run main.py
    
    ENV_FILE="Test.env" uv run main.py
    

Docker

  • Build docker image

    docker build -t jellyplex-watched .
    
  • or use pre-built image

    docker pull luigi311/jellyplex-watched:latest
    

With variables

  • Run

    docker run --rm -it -e PLEX_TOKEN='SuperSecretToken' luigi311/jellyplex-watched:latest
    

With .env

  • Create a .env file similar to .env.sample and set the variables to match your setup

  • Run

     docker run --rm -it -v "$(pwd)/.env:/app/.env" luigi311/jellyplex-watched:latest
    

Troubleshooting/Issues

  • Jellyfin

    • Attempt to decode JSON with unexpected mimetype, make sure you enable remote access or add your docker subnet to lan networks in jellyfin settings
  • Configuration

    • Do not use quotes around variables in docker compose
    • If you are not running all 3 supported servers, that is, Plex, Jellyfin, and Emby simultaneously, make sure to comment out the server url and token of the server you aren't using.

Contributing

I am open to receiving pull requests. If you are submitting a pull request, please make sure run it locally for a day or two to make sure it is working as expected and stable.

License

This is currently under the GNU General Public License v3.0.

Install jellyplex-watched on Unraid in a few clicks.

Find jellyplex-watched in Community Apps on your Unraid server, review the template, and click Install. Unraid handles the Docker app or plugin setup from the published template.

Open the Apps tab on your Unraid server Search Community Apps for jellyplex-watched Review the template variables and paths Click Install

Download Statistics

870,581
Total Downloads
49,371
This Month
49,511
Avg / Month

Total Downloads Over Time

Loading chart...

Related apps

Explore more like this

Explore all

Details

Repository
luigi311/jellyplex-watched:latest
Last Updated2026-06-04
First Seen2023-03-18

Runtime arguments

Network
bridge
Shell
sh
Privileged
false

Template configuration

DRYRUNVariable

Do not mark any shows/movies as played and instead just output to log if they would of been marked. Change this to False after confirming that everything works as expected.

Default
True
DEBUGVariable

Print additional logging information

Default
False
DEBUG_LEVELVariable

Debugging level, 'info' is default, 'debug' is more verbose

Default
INFO
RUN_ONLY_ONCEVariable

If set to True then the script will only run once and then exit

Default
False
SLEEP_DURATIONVariable

How often to run the script in seconds

Default
3600
LOG_FILEVariable

Log file where all output will be written to

Default
/tmp/log.log
MARK_FILEVariable

Mark file where all shows/movies that have been marked as played will be written to

Default
/tmp/mark.log
REQUEST_TIMEOUTVariable

Timeout for requests for Jellyfin and Emby in seconds

Default
300
GENERATE_GUIDSVariable

Generating guids is a slow process, so setting this to False is a way to speed up the process by using the location only, useful when using same files on multiple servers

Default
True
GENERATE_LOCATIONSVariable

Generating locations is a slow process, so setting this to False is a way to speed up the process by using the guid only, useful when using different files on multiple servers

Default
True
MAX_THREADSVariable

Max threads for processing

Default
2
USER_MAPPINGVariable

Map usernames between servers in the event that they are different. Syntax: JSON map.

LIBRARY_MAPPINGVariable

Map libraries between servers in the event that they are different. Syntax: JSON map.

BLACKLIST_LIBRARYVariable

Blacklist libraries that should be excluded from processing. Lists are applied individually, in an OR relationship. Syntax: comma separated values for multiple options

WHITELIST_LIBRARYVariable

Whitelist libraries, everything not listed will be excluded from processing. Lists are applied individually, in an OR relationship. Syntax: comma separated values for multiple options

BLACKLIST_LIBRARY_TYPEVariable

Blacklist library types such as Movies/TV Shows that should be excluded from processing. Lists are applied individually, in an OR relationship. Syntax: comma separated values for multiple options

WHITELIST_LIBRARY_TYPEVariable

Whitelist library types such as Movies/TV Shows, everything not listed will be excluded from processing. Lists are applied individually, in an OR relationship. Syntax: comma separated values for multiple options

BLACKLIST_USERSVariable

Blacklist users that should be excluded from processing. Lists are applied individually, in an OR relationship. Syntax: comma separated values for multiple options

WHITELIST_USERSVariable

Whitelist users, each user not listed will be excluded from processing. Lists are applied individually, in an OR relationship. Syntax: comma separated values for multiple options

SYNC_FROM_PLEX_TO_PLEXVariable
Default
True
SYNC_FROM_PLEX_TO_JELLYFINVariable
Default
True
SYNC_FROM_PLEX_TO_EMBYVariable
Default
True
SYNC_FROM_JELLYFIN_TO_PLEXVariable
Default
True
SYNC_FROM_JELLYFIN_TO_JELLYFINVariable
Default
True
SYNC_FROM_JELLYFIN_TO_EMBYVariable
Default
True
SYNC_FROM_EMBY_TO_PLEXVariable
Default
True
SYNC_FROM_EMBY_TO_JELLYFINVariable
Default
True
SYNC_FROM_EMBY_TO_EMBYVariable
Default
True
PLEX_BASEURLVariable

URL of the plex server, use hostname or IP address if the hostname is not resolving correctly. Syntax: comma separated values for multiple servers

Default
https://localhost:32400
PLEX_TOKENVariable

Recommended over username/password. Token is faster to connect as it is direct to the server instead of going through the plex servers. See: https://support.plex.tv/articles/204059436-finding-an-authentication-token-x-plex-token/ Syntax: comma separated values for multiple servers

PLEX_SERVERNAMEVariable

Recommend using PLEX_TOKEN instead. If not using plex token then use username and password of the server admin along with the servername. Syntax: comma separated values for multiple servers

PLEX_USERNAMEVariable

Recommend using PLEX_TOKEN instead. Syntax: comma separated values for multiple servers

PLEX_PASSWORDVariable

Recommend using PLEX_TOKEN instead. Syntax: comma separated values for multiple servers

Plex: SSL_BYPASSVariable

Skip hostname validation for ssl certificates. Set to True if running into ssl certificate errors. Currently only applies to Plex.

Target
SSL_BYPASS
Default
False
JELLYFIN_BASEURLVariable

Jellyfin server URL, use hostname or IP address if the hostname is not resolving correctly. Syntax: comma separated values for multiple servers

Default
http://localhost:8096
JELLYFIN_TOKENVariable

Jellyfin api token, created manually by logging in to the jellyfin server admin dashboard and creating an api key. Syntax: comma separated values for multiple servers

EMBY_BASEURLVariable

Emby server URL, use hostname or IP address if the hostname is not resolving correctly. Syntax: comma separated values for multiple servers

Default
http://localhost:8097
EMBY_TOKENVariable

Emby api token, created manually by logging in to the Emby server admin dashboard and creating an api key. Syntax: comma separated values for multiple servers