PlexTraktSync


NamePlexTraktSync JSON
Version 0.34.5 PyPI version JSON
download
home_pageNone
SummaryPlex-Trakt-Sync is a two-way-sync between trakt.tv and Plex Media Server
upload_time2025-03-09 13:06:33
maintainerNone
docs_urlNone
authorNone
requires_python>=3.9
licenseMIT License Copyright (c) 2019 Alexander Theimer Copyright (c) 2019-2024 twolaw Copyright (c) 2020-2025 Elan Ruusamäe Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
keywords
VCS
bugtrack_url
requirements apluggy attrs cattrs certifi charset-normalizer click decorator deprecated exceptiongroup humanize idna inquirerpy markdown-it-py mdurl oauthlib pfzy platformdirs plexapi pluggy prompt-toolkit pygments python-dotenv python-git-info pytimeparse pytrakt pyyaml requests requests-cache requests-oauthlib rich six tqdm types-decorator typing-extensions url-normalize urllib3 wcwidth websocket-client wrapt
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Plex-Trakt-Sync

![Python Versions][python-versions-badge]

This project adds a two-way-sync between trakt.tv and Plex Media Server. It
requires a trakt.tv account but no Plex premium and no Trakt VIP subscriptions,
unlike the Plex app provided by Trakt.

![image](https://raw.githubusercontent.com/twolaw/PlexTraktSync/img/plextraktsync_banner.png)

Originally created by [@Taxel][@taxel], now maintained by [contributors].

[@taxel]: https://github.com/Taxel
[contributors]: https://github.com/Taxel/PlexTraktSync/graphs/contributors

Note: The PyTrakt API keys are not stored securely, so if you do not want to
have a file containing those on your harddrive, you can not use this project.

## Contribute

**Looking for a way to contribute?**

- find issues with the [help-wanted] label
- improve documentation [docs-needed] label
- you can also just [create a pull request] to improve documentation
- ... more [developer contribution](CONTRIBUTING.md) docs

[help-wanted]: https://github.com/Taxel/PlexTraktSync/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22
[docs-needed]: https://github.com/Taxel/PlexTraktSync/issues?q=label%3A%22docs+needed%22+sort%3Aupdated-desc
[create a pull request]: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request

---

- [Plex-Trakt-Sync](#plex-trakt-sync)
  - [Features](#features)
  - [Pre-requisites](#pre-requisites)
  - [Installation](#installation)
    - [pipx](#pipx)
    - [Docker Compose](#docker-compose)
    - [Install code from Pull request](#install-code-from-pull-request), development
    - [Windows Setup (optional alternative)](#windows-setup-optional-alternative), unsupported
    - [Unraid setup](#unraid-setup), unsupported
    - [GitHub](#github), unsupported
  - [Setup](#setup)
  - [Configuration](#configuration)
    - [Libraries](#libraries)
    - [Per server configuration](#per-server-configuration)
    - [Logging](#logging)
  - [Commands](#commands)
    - [Sync](#sync)
    - [Unmatched](#unmatched)
    - [Info command](#info-command)
    - [Inspect](#inspect)
    - [Watch](#watch)
      - [Systemd setup](#systemd-setup)
      - [Systemd user setup](#systemd-user-setup)
  - [Good practices](#good-practices)
  - [Troubleshooting](#troubleshooting)

[python-versions-badge]: https://img.shields.io/badge/python-3.9%20%7C%203.10%20%7C%203.11%20%7C%203.12%20%7C%203.13-blue

## Features

- Media in Plex are added to Trakt collection
- Ratings are synced
- Watched status are synced (dates are not reported from Trakt to Plex)
- Liked lists in Trakt are downloaded and all movies in Plex belonging to that
  list are added
- Watchlists are synced
- You can edit the config file to choose what to sync
- None of the above requires a Plex Pass or Trakt VIP membership.
  Downside: Needs to be executed manually or via cronjob,
  can not use live data via webhooks.

## Pre-requisites

The script is known to work with Python 3.9-3.13 versions.

## Installation

### pipx

Installation with [pipx][install-pipx].

```
pipx install PlexTraktSync
```

or, to install specific version:

```
pipx install PlexTraktSync==0.15.2 --force
```

and to upgrade:

```
plextraktsync self-update
```

which just calls `pipx` with:

```
pipx upgrade PlexTraktSync
```

to run:

```
plextraktsync sync
```

NOTE: `pipx` install will use OS specific paths for Config, Logs, Cache, see
[platformdirs] documentation for details or check output of [info command](#info-command).

[platformdirs]: https://pypi.org/project/platformdirs
[install-pipx]: https://github.com/pypa/pipx#install-pipx

### Docker Compose

You can setup docker compose file like this:

```yaml
version: "2"
services:
  plextraktsync:
    image: ghcr.io/taxel/plextraktsync
    command: sync
    container_name: plextraktsync
    restart: on-failure:2
    volumes:
      - ./config:/app/config
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/Tallinn
```

You can use specific version `0.25.16`:

- `image: ghcr.io/taxel/plextraktsync:0.25.16`

or latest 0.25.x version:

- `image: ghcr.io/taxel/plextraktsync:0.25`

Note: `main` is development version and reporting bugs against development versions are not supported.

#### Run the Docker Container

To run sync:

```
docker compose run --rm plextraktsync sync
```

The container will stop after the sync is completed. Read Setup section to run
it automatically at set intervals.

### Install code from Pull request

This is to install development version to test if pull request would fix some problem.

See contributing guide how to [install code from pull request].

[install code from pull request]: CONTRIBUTING.md#install-code-from-pull-request

### Windows Setup (optional alternative)

NOTE: _This installation method is not supported. It's documented solely by user contribution._

- Download the latest `.zip` release from https://github.com/Taxel/PlexTraktSync/tags
- Run `setup.bat` to install requirements and create optional shortcuts and
  routines _(requires Windows 7sp1 - 11)_.

### Unraid setup

NOTE: _This installation method is not supported. It's documented solely by user contribution._

Option 1 for container creation:
Create a manual Unraid container of PlexTraktSync:

- Go to the Docker section, under "Docker Containers" and click "Add Container".
  - Click the advanced view to see all of the available parameters.
  - Leave the template blank/unselected.
  - Under Name: enter a name for the docker (e.g., PlexTraktSync).
  - Under Repository: enter `ghcr.io/taxel/plextraktsync:latest` (or whatever tag you want).
  - Under Extra Parameters: enter `-it` for interactive mode.
- Click "Apply".
- The container should start automatically. If not, start it.
- Enter the console for the container.
- Enter `plextraktsync` to start the credential process described above.

Option 2 for container creation:
Utilize the "Community Apps" Unraid Plugin.

- Go to the Plugins tab, paste the Community Apps URL in the URL area, and click "Install".

Once installed (or if already installed):

- Go to the (newly created) Apps tab and search "plextraktsync", and click on
  the App, and click "Install" (https://forums.unraid.net/topic/38582-plug-in-community-applications/)
- Take all the default settings (the -it switch as outlined elsewhere in the
  README is already present), and click "Apply".
- The container then installs, and will start.

Schedule (cron) the container to start at given intervals to process the sync

- Go to the Plugins tab, past the User Scripts URL in the URL area, and click "Install" (https://forums.unraid.net/topic/48286-plugin-ca-user-scripts/)

Once installed (or if already installed):

- Go to the Plugins tab, click on "User Scripts", and click the "Add New Script" button
- Name your script accordingly
- Click the "gear" icon next to the script name, and click "Edit Script"
- Remove the "#!/bin/bash" line and add:

```
#!/bin/bash

# Check if the container is running
if [ "$(docker ps -q -f name=PlexTraktSync)" ]; then
    echo "PlexTraktSync container is already running."
    exit 1
else
    echo "PlexTraktSync container is not running. Starting it now..."
    docker start PlexTraktSync
fi

# Run the sync command inside the container
docker exec PlexTraktSync plextraktsync sync
```

- The format of the script needs to be docker calling your container name (if you changed it from the default, ie to something like plex-trakt-sync), then issuing the command to sync.
- Click "Save Changes"
- Set the schedule accordingly using the dropdown menu next to the "Run in Background" button

### GitHub

NOTE: _This installation method is not supported._ You will not get support if you use this installation method.

Installing from GitHub is considered developer mode, and it's documented in
[CONTRIBUTING.md](CONTRIBUTING.md#checking-out-code).

## Setup

- You will need to create a Trakt API app if you do not already have one:

  - Visit https://trakt.tv/oauth/applications/new
  - Give it a meaningful name
  - Enter `urn:ietf:wg:oauth:2.0:oob` as the redirect url
  - You can leave Javascript origins and the Permissions checkboxes blank

- Run `plextraktsync login`, the script will ask for missing credentials

  > **Note**
  > To setup the credentials in the Docker Container, refer to the [Run the Docker Container](#run-the-docker-container) section

  > **Note2**
  > If you are not able to run a docker container from commandline, like on a Synology NAS,
  > run an instance of plextraktsync on a different device to create the necesary `.env`, `.pytrakt.json` and `servers.yml` files.
  > Move them to the mapped `/app/config` folder and rebuild the container.

- At first run you will be asked to setup Trakt and Plex access.

  Follow the instructions, your credentials and API keys will be stored in
  `.env`and `.pytrakt.json` files. Plex URL and token is stored in `servers.yml`.

  If you have [2 Factor Authentication enabled on Plex][two-factor-authentication], input the code when prompted. If you don't have 2FA enabled, just leave the prompt blank and press Enter.

[two-factor-authentication]: https://support.plex.tv/articles/two-factor-authentication/#toc-1:~:text=Old%20Third%2DParty%20Apps%20%26%20Tools

- Cronjobs can be optionally used on Linux or macOS to run the script at set intervals.

  For example, to run this script in a cronjob every two hours:

  ```
  $ crontab -e
  0 */2 * * * $HOME/.local/bin/plextraktsync sync
  ```

  - Note the command in the example above may not immediately work. Use the `which plextraktsync` command to locate your system's plextraktsync executable file and update it accordingly.

- Instead of cron, a docker scheduler like [Ofelia][ofelia] can also be used to
  run the script at set intervals.

[ofelia]: https://github.com/mcuadros/ofelia/

A docker compose example with a 6h interval:

```yaml
version: "2"
services:
  scheduler:
    image: mcuadros/ofelia:0.3
    container_name: scheduler
    depends_on:
      - plextraktsync
    command: daemon --docker
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
    labels:
      ofelia.job-run.plextraktsync.schedule: "@every 6h"
      ofelia.job-run.plextraktsync.container: "plextraktsync"
  plextraktsync:
    image: ghcr.io/taxel/plextraktsync:latest
    container_name: plextraktsync
    command: sync
    volumes:
      - ./config:/app/config
```

## Configuration

To disable parts of the functionality of this software, look no further than
`config.yml`. At first run, the script will create `config.yml` based on
`config.default.yml`. If you want to customize settings before first run (eg.
you don't want full sync) you can copy and edit `config.yml` before launching
the script. Here, in the sync section, you can disable the following things
by setting them from `true` to `false` in a text editor:

- Downloading liked lists from Trakt and adding them to Plex
- Syncing the watchlists between Plex and Trakt
- Syncing the watched status between Plex and Trakt
- Syncing the collected status between Plex and Trakt

The first execution of the script will (depending on your PMS library size)
take a long time. After that, movie details and Trakt lists are cached, so
it should run a lot quicker the second time. This does mean, however, that
Trakt lists are not updated dynamically (which is fine for lists like "2018
Academy Award Nominees" but might not be ideal for lists that are updated
often). Here are the execution times on my Plex server: First run - 1228
seconds, second run - 111 seconds

You can view sync progress in the `plextraktsync.log` file which will be
created.

You can use `--edit` or `--locate` flags to `config` command to open config
file in editor or in file browser.

### Libraries

By default, all libraries are processed. You can disable libraries by name by
changing `excluded-libraries` in `config.yml`.

You can also set `excluded-libraries` per server in `servers.yml`:

```yml
servers:
  Example1:
    token: ~
    urls:
      - http://localhost:32400
    config:
      excluded-libraries:
        - "Family Movies"
```

Additionally, you can list only libraries to be processed, in this case global
`excluded-libraries` will not be used for this server.

```yml
servers:
  Example1:
    token: ~
    urls:
      - http://localhost:32400
    config:
      libraries:
        - "Movies"
        - "TV Shows"
```

you can see the final list of libraries with info command:

```commandline
$ plextraktsync --server=Example1 info
Enabled 2 libraries in Plex Server:
 - 1: Movies
 - 2: TV Shows
```

### Per server configuration

If you want to specify your config per server you can do so inside of
`servers.yml`. Within the `config` part of the server configuration you can
specify how that specific server should work.

```yml
servers:
  Example1:
    token: ~
    urls:
      - http://localhost:32400
    config:
      sync:
        plex_to_trakt:
          collection: true
        trakt_to_plex:
          liked_lists: false
```

Using `sync` in a server config overrides the global sync-config in
`config.yml`.

This can also be used to have different configs between different libraries. To
be able to do this you specify the number of servers you need (most likely
equal to the number of different config setups you need). For example:

```yml
servers:
  Example1:
    token: ~
    urls:
      - http://localhost:32400
    config:
      libraries:
        - "Movies"
      sync:
        plex_to_trakt:
          ratings: true
          watched_status: true
        trakt_to_plex:
          ratings: true
          watched_status: true
  Example2:
    token: ~
    urls:
      - http://localhost:32400
    config:
      libraries:
        - "TV Shows"
      sync:
        plex_to_trakt:
          ratings: true
          watched_status: false
        trakt_to_plex:
          ratings: true
          watched_status: false
```

The above config would make it so that the "Movies" library syncs both ratings
and watched status, while the "TV Shows" library only syncs ratings. To then
run the sync you need to specify `--server Example1` or `--server Example2` to
run the sync for that specific server.

Running the sync command without `--server` will use default server from `.env`

If you want to run these jobs using `ofelia`, you can do so by running
something similar to this in your `docker-compose.yml`:

```yml
services:
  plextraktsync:
    image: ghcr.io/taxel/plextraktsync
    command: sync
    container_name: plextraktsync
    volumes:
      - ./config:/app/config
    environment:
      - PUID=1000
      - PGID=1000
    depends_on:
      - plex
  scheduler:
    image: mcuadros/ofelia:0.3
    container_name: scheduler
    command: daemon --docker
    restart: unless-stopped
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
    labels:
      ofelia.job-run.plextraktsync.schedule: "0 6,18 * * *"
      ofelia.job-run.plextraktsync.container: "plextraktsync"
      ofelia.job-run.plextraktsync.command: "--server 'Example1' sync"
      ofelia.job-run.plextraktsync2.schedule: "0 12,0 * * *"
      ofelia.job-run.plextraktsync2.container: "plextraktsync"
      ofelia.job-run.plextraktsync2.command: "--server 'Example2' sync"
```

If you are running only one PlexTraktSync container, you need to make sure that
the two jobs Ofelia jobs don't run at the same time. Ofelia skips scheduling a
new job run if the previous job is still running.

Depending on how long it takes for the job to run on your server you might have
to keep the schedule of the two jobs seperated with a few minutes or a few
hours. If you have two different PlexTraktSync containers in your docker
compose, you can run them at the same time.

The above config means that a job is running every 6 hours, alternating between
the two "servers".

### Logging

The logging level by default is `INFO`. This can be changed to DEBUG by editing
the "debug" variable in `config.yml` to `true`.

By default the logs will append, if you wish to maintain the log of only your
last run then edit the "append" variable in `config.yml` to `false`.

## Commands

Run `plextraktsync --help` to see available commands.
Run `plextraktsync COMMAND --help` to see help for `COMMAND`.

```
$ plextraktsync --help
Usage: plextraktsync [OPTIONS] COMMAND [ARGS]...

  Plex-Trakt-Sync is a two-way-sync between trakt.tv and Plex Media Server

Options:
  --version              Print version and exit
  --no-cache             Disable cache in for Trakt HTTP requests
  --no-progressbar       Disable progressbar
  --batch-delay INTEGER  Time in seconds between each collection batch submit
                         to Trakt  [default: 5]
  --server NAME          Plex Server name from servers.yml
  --help                 Show this message and exit.

Commands:
  bug-report         Create a pre-populated GitHub issue with information...
  cache              Manage and analyze Requests Cache.
  clear-collections  Clear Movies and Shows collections in Trakt
  config             Print user config for debugging and bug reports.
  download           Downloads movie or subtitles to a local directory
  imdb-import        Import IMDB ratings from CSV file.
  info               Print application and environment version info
  inspect            Inspect details of an object
  login              Log in to Plex and Trakt if needed
  plex-login         Log in to Plex Account to obtain Access Token.
  self-update        Update PlexTraktSync to the latest version using pipx
  sync               Perform sync between Plex and Trakt
  trakt-login        Log in to Trakt Account to obtain Access Token.
  unmatched          List media that has no match in Trakt or Plex
  watch              Listen to events from Plex
  watched-shows      Print a table of watched shows
```

You can [contribute](#contribute) yourself missing documentation.

### Sync

The `sync` subcommand supports `--sync=shows` and `--sync=movies` options,
so you can sync only specific library types.
Or only watchlist: `--sync=watchlist`.

```
➔ plextraktsync sync --help
Usage: plextraktsync sync [OPTIONS]

  Perform sync between Plex and Trakt

Options:
  --sync [all|movies|shows|watchlist]
                                  Specify what to sync  [default: all]
  --help                          Show this message and exit.
```

### Unmatched

You can use `unmatched` command to scan your library and display unmatched
movies.

Support for unmatched shows is not yet implemented.

`plextraktsync unmatched`

### Info command

The info command can be used to print package versions,
account information,
locations of Cache, Config and Logs directories

```
$ plextraktsync info
PlexTraktSync Version: 0.16.0
Python Version: 3.10.0 (default, Oct  6 2021, 01:11:32) [Clang 13.0.0 (clang-1300.0.29.3)]
Plex API Version: 4.7.2
Trakt API Version: 3.2.1
Cache Dir: /Users/glen/Library/Caches/PlexTraktSync
Config Dir: /Users/glen/Library/Application Support/PlexTraktSync
Log Dir: /Users/glen/Library/Logs/PlexTraktSync
Plex username: nobody
Trakt username: nobody
Plex Server version: 1.24.3.5033-757abe6b4, updated at: 2021-02-21 17:00:00
Server has 2 libraries: ['Movies', 'TV Shows']
```

### Inspect

Inspect command is used to get info about Plex Media Server items,
which is useful when debugging problems and reporting issues.

- Plex Web URL from your server:
  - https://app.plex.tv/desktop/#!/server/53aff62c4bb6027c1ada814d417e83ccdf4d5045/details?key=/library/metadata/123
- Plex Discover URL:
  - https://app.plex.tv/desktop/#!/provider/tv.plex.provider.discover/details?key=/library/metadata/5d7768258718ba001e311845
- Id from from your Plex Media Server:
  - `123`

```
plextraktsync inspect 123
plextraktsync inspect "https://app.plex.tv/desktop/#!/server/53aff62c4bb6027c1ada814d417e83ccdf4d5045/details?key=/library/metadata/123"
```

To avoid problems with various shells, put the value in double quotes.

### Watch

You can use the `watch` command to listen to events from Plex Media Server
and scrobble plays.

> What is scrobbling?
>
> _Scrobbling simply means automatically tracking what you’re watching. Instead
> of checking in from your phone of the website, this command runs in the
> background and automatically scrobbles back to Trakt while you enjoy watching
> your media_ - [Plex Scrobbler@blog.trakt.tv][plex-scrobbler]

[plex-scrobbler]: https://blog.trakt.tv/plex-scrobbler-52db9b016ead

To restrict scrobbling to your user **only** (recommended), set the following
in your `config.yml`:

```yaml
watch:
  username_filter: true
```

To run `watch` command:

`plextraktsync watch`

or

```
docker compose run --rm plextraktsync watch
```

or add `command: watch` to docker compose file, and `docker compose up -d
plextraktsync` to start the container detached:

```yaml
version: "2"
services:
  plextraktsync:
    image: ghcr.io/taxel/plextraktsync
    volumes:
      - ./config:/app/config
    command: watch
```

#### Systemd setup

Create a systemd unit so that it scrobbles automatically in the background:

```ini
[Unit]
Description=PlexTraktSync watch daemon
After=network-online.target

[Service]
ExecStart=plextraktsync watch
Restart=on-failure
RestartSec=10
User=user
Group=user

[Install]
WantedBy=multi-user.target
```

Note, depending on your install method you may need to set your ExecStart
command as follows:

```ini
ExecStart=/path/to/plextraktsync/plextraktsync.sh watch
```

Following that you will need to enable the service:

```
sudo systemctl daemon-reload
sudo systemctl start PlexTraktSync.service
sudo systemctl enable PlexTraktSync.service
```

#### Systemd user setup

You can also run as systemd user service.

This walkthough allows to use different servers with the same configuration.

This assumes `plextraktsync` is installed with `pipx` for your user.

```ini
# plextraktsync@.service
[Unit]
Description=PlexTraktSync watch daemon
After=network-online.target

[Service]
ExecSearchPath=%h/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ExecStart=plextraktsync watch --server=%i
Restart=on-failure
RestartSec=10

[Install]
WantedBy=default.target
```

Install the service template file:

1. as `root`: `/etc/xdg/systemd/user/plextraktsync@.service` for all users
1. as your user: `~/.config/systemd/user/plextraktsync@.service` for your user only

Next, you need to reload systemd:

1. if installed as `root`: `sudo systemctl daemon-reload`
2. if installed as user: `systemctl --user daemon-reload`

Now create instances based on server names from `servers.yml`, in this example `SERVER_NAME`.

1. `systemctl --user start "plextraktsync@SERVER_NAME.service"`
1. `systemctl --user status "plextraktsync@SERVER_NAME.service"`

for complete logs, you can use `journalctl` (add `-f` to follow logs):

1. `journalctl --user -u "plextraktsync@SERVER_NAME.service"`

If all works, enable it for auto-start on host reboot

1. `systemctl --user enable "plextraktsync@SERVER_NAME.service"`

For systemd --user session to start without having to log in you need to enable [systemd-linger]:

1. `loginctl enable-linger`

[systemd-linger]: https://wiki.archlinux.org/title/systemd/User#Automatic_start-up_of_systemd_user_instances

## Good practices

- Using default `Plex Movie` and `Plex TV Series` [metadata agents] improves
  script compatibility (for matching or for watchlist).
  It is recommended to [migrate to the new Plex TV Series agent][migrating-agent-scanner].
- Organize your shows folders and naming according to [Plex standard][naming-tv-show-files]
  and [theMovieDatabase][tmdb] (tmdb) order. If Plex doesn't properly identify your media,
  you can use the [Fix Match][fix-match] and the [Match Hinting][plexmatch].
  Also check the Episode Ordering preference (under Advanced) to correspond with your files.
- Use tmdb as source for TV Shows if possible,
  because it's the Trakt [primary data source][tv-show-metadata]
  ([switched from tvdb in Jan-2021][tmdb-transition]).

[fix-match]: https://support.plex.tv/articles/201018497-fix-match-match/
[metadata agents]: https://support.plex.tv/articles/200241558-agents/
[migrating-agent-scanner]: https://support.plex.tv/articles/migrating-a-tv-library-to-use-the-new-plex-tv-series-agent-scanner/
[naming-tv-show-files]: https://support.plex.tv/articles/naming-and-organizing-your-tv-show-files/
[plexmatch]: https://support.plex.tv/articles/plexmatch/
[tmdb-transition]: https://blog.trakt.tv/tmdb-transition-ef3d19a5cf24
[tmdb]: https://themoviedb.org/
[tv-show-metadata]: https://blog.trakt.tv/tv-show-metadata-e6e64ed4e6ef

## Troubleshooting

### I have duplicate watched episodes sent to Trakt at every sync

Check your Plex episodes ordering compared to Trakt ordering.
If episodes are in a different order, it should not be a problem because they
are identified with ids.
But if a season or an episode is missing on Trakt (and tmdb) it can't be synced.
You can fix it by [adding the missing episodes] or edit metadata (eg. missing
tvdb or imdb ids) on [tmdb] or [report a metadata issue on Trakt][how-to-report-metadata-issues] ([answers][reports]). It's free for anyone
to sign up and edit info at tmdb. Trakt will [update from tmdb][trakt-tvshow-update] data.

[adding the missing episodes]: https://support.trakt.tv/support/solutions/articles/70000264977
[tmdb]: https://themoviedb.org/
[trakt-tvshow-update]: https://support.trakt.tv/support/solutions/articles/70000260936-how-does-movie-tv-show-information-metadata-get-updated-how-can-i-refresh-or-sync-trakt-to-tmdb-
[how-to-report-metadata-issues]: https://support.trakt.tv/support/solutions/articles/70000627644-how-to-report-metadata-issues
[reports]: https://trakt.tv/settings/reports

### I have many matching errors in logs

Make sure you use [good practices](#good-practices) about Plex agent and files
organization as stated above.
Check if episodes are not missing on Trakt as explained in previous answer, and
check if [external ids][house-of-the-dragon] are populated on tmdb.

[house-of-the-dragon]: https://www.themoviedb.org/tv/94997-house-of-the-dragon/season/1/episode/1/edit?active_nav_item=external_ids

### I have season 0 matching errors

Season 0 folder must only contain episodes belonging to season 0, also named specials.
Trailers, deleted scenes, featurettes, interviews,... must be stored in a
separate [Extra folder][extra-folder] (not in season 0) according to Plex rules.
Keep in mind that seasons 0 aren't really official so datasources (tmdb, imdb
and tvdb) sometimes don't correspond. Check season 0 of shows on trakt.tv to identify those special episodes.
Use tmdb as Plex source as much as you can.

[extra-folder]: https://support.plex.tv/articles/local-files-for-tv-show-trailers-and-extras/

### How to sync multiple users ?

The easiest way is to use containers with custom config folder for each user:
[Multi-User docker-compose][discussions/997].

[discussions/997]: https://github.com/Taxel/PlexTraktSync/discussions/997

### Can this run on Synology, HomeAssistant, Portainer,... ?

Yes using docker, check [Discussions][discussions] page.

### I have another question

Check [Discussions][discussions], maybe someone already asked and found the answer.

[discussions]: https://github.com/Taxel/PlexTraktSync/discussions

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "PlexTraktSync",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": null,
    "keywords": null,
    "author": null,
    "author_email": null,
    "download_url": "https://files.pythonhosted.org/packages/98/2f/5c141037eb5fc543a8770f1a3b1f0276712c99451c0b3c321ab2fd5d29df/plextraktsync-0.34.5.tar.gz",
    "platform": null,
    "description": "# Plex-Trakt-Sync\n\n![Python Versions][python-versions-badge]\n\nThis project adds a two-way-sync between trakt.tv and Plex Media Server. It\nrequires a trakt.tv account but no Plex premium and no Trakt VIP subscriptions,\nunlike the Plex app provided by Trakt.\n\n![image](https://raw.githubusercontent.com/twolaw/PlexTraktSync/img/plextraktsync_banner.png)\n\nOriginally created by [@Taxel][@taxel], now maintained by [contributors].\n\n[@taxel]: https://github.com/Taxel\n[contributors]: https://github.com/Taxel/PlexTraktSync/graphs/contributors\n\nNote: The PyTrakt API keys are not stored securely, so if you do not want to\nhave a file containing those on your harddrive, you can not use this project.\n\n## Contribute\n\n**Looking for a way to contribute?**\n\n- find issues with the [help-wanted] label\n- improve documentation [docs-needed] label\n- you can also just [create a pull request] to improve documentation\n- ... more [developer contribution](CONTRIBUTING.md) docs\n\n[help-wanted]: https://github.com/Taxel/PlexTraktSync/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22\n[docs-needed]: https://github.com/Taxel/PlexTraktSync/issues?q=label%3A%22docs+needed%22+sort%3Aupdated-desc\n[create a pull request]: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request\n\n---\n\n- [Plex-Trakt-Sync](#plex-trakt-sync)\n  - [Features](#features)\n  - [Pre-requisites](#pre-requisites)\n  - [Installation](#installation)\n    - [pipx](#pipx)\n    - [Docker Compose](#docker-compose)\n    - [Install code from Pull request](#install-code-from-pull-request), development\n    - [Windows Setup (optional alternative)](#windows-setup-optional-alternative), unsupported\n    - [Unraid setup](#unraid-setup), unsupported\n    - [GitHub](#github), unsupported\n  - [Setup](#setup)\n  - [Configuration](#configuration)\n    - [Libraries](#libraries)\n    - [Per server configuration](#per-server-configuration)\n    - [Logging](#logging)\n  - [Commands](#commands)\n    - [Sync](#sync)\n    - [Unmatched](#unmatched)\n    - [Info command](#info-command)\n    - [Inspect](#inspect)\n    - [Watch](#watch)\n      - [Systemd setup](#systemd-setup)\n      - [Systemd user setup](#systemd-user-setup)\n  - [Good practices](#good-practices)\n  - [Troubleshooting](#troubleshooting)\n\n[python-versions-badge]: https://img.shields.io/badge/python-3.9%20%7C%203.10%20%7C%203.11%20%7C%203.12%20%7C%203.13-blue\n\n## Features\n\n- Media in Plex are added to Trakt collection\n- Ratings are synced\n- Watched status are synced (dates are not reported from Trakt to Plex)\n- Liked lists in Trakt are downloaded and all movies in Plex belonging to that\n  list are added\n- Watchlists are synced\n- You can edit the config file to choose what to sync\n- None of the above requires a Plex Pass or Trakt VIP membership.\n  Downside: Needs to be executed manually or via cronjob,\n  can not use live data via webhooks.\n\n## Pre-requisites\n\nThe script is known to work with Python 3.9-3.13 versions.\n\n## Installation\n\n### pipx\n\nInstallation with [pipx][install-pipx].\n\n```\npipx install PlexTraktSync\n```\n\nor, to install specific version:\n\n```\npipx install PlexTraktSync==0.15.2 --force\n```\n\nand to upgrade:\n\n```\nplextraktsync self-update\n```\n\nwhich just calls `pipx` with:\n\n```\npipx upgrade PlexTraktSync\n```\n\nto run:\n\n```\nplextraktsync sync\n```\n\nNOTE: `pipx` install will use OS specific paths for Config, Logs, Cache, see\n[platformdirs] documentation for details or check output of [info command](#info-command).\n\n[platformdirs]: https://pypi.org/project/platformdirs\n[install-pipx]: https://github.com/pypa/pipx#install-pipx\n\n### Docker Compose\n\nYou can setup docker compose file like this:\n\n```yaml\nversion: \"2\"\nservices:\n  plextraktsync:\n    image: ghcr.io/taxel/plextraktsync\n    command: sync\n    container_name: plextraktsync\n    restart: on-failure:2\n    volumes:\n      - ./config:/app/config\n    environment:\n      - PUID=1000\n      - PGID=1000\n      - TZ=Europe/Tallinn\n```\n\nYou can use specific version `0.25.16`:\n\n- `image: ghcr.io/taxel/plextraktsync:0.25.16`\n\nor latest 0.25.x version:\n\n- `image: ghcr.io/taxel/plextraktsync:0.25`\n\nNote: `main` is development version and reporting bugs against development versions are not supported.\n\n#### Run the Docker Container\n\nTo run sync:\n\n```\ndocker compose run --rm plextraktsync sync\n```\n\nThe container will stop after the sync is completed. Read Setup section to run\nit automatically at set intervals.\n\n### Install code from Pull request\n\nThis is to install development version to test if pull request would fix some problem.\n\nSee contributing guide how to [install code from pull request].\n\n[install code from pull request]: CONTRIBUTING.md#install-code-from-pull-request\n\n### Windows Setup (optional alternative)\n\nNOTE: _This installation method is not supported. It's documented solely by user contribution._\n\n- Download the latest `.zip` release from https://github.com/Taxel/PlexTraktSync/tags\n- Run `setup.bat` to install requirements and create optional shortcuts and\n  routines _(requires Windows 7sp1 - 11)_.\n\n### Unraid setup\n\nNOTE: _This installation method is not supported. It's documented solely by user contribution._\n\nOption 1 for container creation:\nCreate a manual Unraid container of PlexTraktSync:\n\n- Go to the Docker section, under \"Docker Containers\" and click \"Add Container\".\n  - Click the advanced view to see all of the available parameters.\n  - Leave the template blank/unselected.\n  - Under Name: enter a name for the docker (e.g., PlexTraktSync).\n  - Under Repository: enter `ghcr.io/taxel/plextraktsync:latest` (or whatever tag you want).\n  - Under Extra Parameters: enter `-it` for interactive mode.\n- Click \"Apply\".\n- The container should start automatically. If not, start it.\n- Enter the console for the container.\n- Enter `plextraktsync` to start the credential process described above.\n\nOption 2 for container creation:\nUtilize the \"Community Apps\" Unraid Plugin.\n\n- Go to the Plugins tab, paste the Community Apps URL in the URL area, and click \"Install\".\n\nOnce installed (or if already installed):\n\n- Go to the (newly created) Apps tab and search \"plextraktsync\", and click on\n  the App, and click \"Install\" (https://forums.unraid.net/topic/38582-plug-in-community-applications/)\n- Take all the default settings (the -it switch as outlined elsewhere in the\n  README is already present), and click \"Apply\".\n- The container then installs, and will start.\n\nSchedule (cron) the container to start at given intervals to process the sync\n\n- Go to the Plugins tab, past the User Scripts URL in the URL area, and click \"Install\" (https://forums.unraid.net/topic/48286-plugin-ca-user-scripts/)\n\nOnce installed (or if already installed):\n\n- Go to the Plugins tab, click on \"User Scripts\", and click the \"Add New Script\" button\n- Name your script accordingly\n- Click the \"gear\" icon next to the script name, and click \"Edit Script\"\n- Remove the \"#!/bin/bash\" line and add:\n\n```\n#!/bin/bash\n\n# Check if the container is running\nif [ \"$(docker ps -q -f name=PlexTraktSync)\" ]; then\n    echo \"PlexTraktSync container is already running.\"\n    exit 1\nelse\n    echo \"PlexTraktSync container is not running. Starting it now...\"\n    docker start PlexTraktSync\nfi\n\n# Run the sync command inside the container\ndocker exec PlexTraktSync plextraktsync sync\n```\n\n- The format of the script needs to be docker calling your container name (if you changed it from the default, ie to something like plex-trakt-sync), then issuing the command to sync.\n- Click \"Save Changes\"\n- Set the schedule accordingly using the dropdown menu next to the \"Run in Background\" button\n\n### GitHub\n\nNOTE: _This installation method is not supported._ You will not get support if you use this installation method.\n\nInstalling from GitHub is considered developer mode, and it's documented in\n[CONTRIBUTING.md](CONTRIBUTING.md#checking-out-code).\n\n## Setup\n\n- You will need to create a Trakt API app if you do not already have one:\n\n  - Visit https://trakt.tv/oauth/applications/new\n  - Give it a meaningful name\n  - Enter `urn:ietf:wg:oauth:2.0:oob` as the redirect url\n  - You can leave Javascript origins and the Permissions checkboxes blank\n\n- Run `plextraktsync login`, the script will ask for missing credentials\n\n  > **Note**\n  > To setup the credentials in the Docker Container, refer to the [Run the Docker Container](#run-the-docker-container) section\n\n  > **Note2**\n  > If you are not able to run a docker container from commandline, like on a Synology NAS,\n  > run an instance of plextraktsync on a different device to create the necesary `.env`, `.pytrakt.json` and `servers.yml` files.\n  > Move them to the mapped `/app/config` folder and rebuild the container.\n\n- At first run you will be asked to setup Trakt and Plex access.\n\n  Follow the instructions, your credentials and API keys will be stored in\n  `.env`and `.pytrakt.json` files. Plex URL and token is stored in `servers.yml`.\n\n  If you have [2 Factor Authentication enabled on Plex][two-factor-authentication], input the code when prompted. If you don't have 2FA enabled, just leave the prompt blank and press Enter.\n\n[two-factor-authentication]: https://support.plex.tv/articles/two-factor-authentication/#toc-1:~:text=Old%20Third%2DParty%20Apps%20%26%20Tools\n\n- Cronjobs can be optionally used on Linux or macOS to run the script at set intervals.\n\n  For example, to run this script in a cronjob every two hours:\n\n  ```\n  $ crontab -e\n  0 */2 * * * $HOME/.local/bin/plextraktsync sync\n  ```\n\n  - Note the command in the example above may not immediately work. Use the `which plextraktsync` command to locate your system's plextraktsync executable file and update it accordingly.\n\n- Instead of cron, a docker scheduler like [Ofelia][ofelia] can also be used to\n  run the script at set intervals.\n\n[ofelia]: https://github.com/mcuadros/ofelia/\n\nA docker compose example with a 6h interval:\n\n```yaml\nversion: \"2\"\nservices:\n  scheduler:\n    image: mcuadros/ofelia:0.3\n    container_name: scheduler\n    depends_on:\n      - plextraktsync\n    command: daemon --docker\n    volumes:\n      - /var/run/docker.sock:/var/run/docker.sock:ro\n    labels:\n      ofelia.job-run.plextraktsync.schedule: \"@every 6h\"\n      ofelia.job-run.plextraktsync.container: \"plextraktsync\"\n  plextraktsync:\n    image: ghcr.io/taxel/plextraktsync:latest\n    container_name: plextraktsync\n    command: sync\n    volumes:\n      - ./config:/app/config\n```\n\n## Configuration\n\nTo disable parts of the functionality of this software, look no further than\n`config.yml`. At first run, the script will create `config.yml` based on\n`config.default.yml`. If you want to customize settings before first run (eg.\nyou don't want full sync) you can copy and edit `config.yml` before launching\nthe script. Here, in the sync section, you can disable the following things\nby setting them from `true` to `false` in a text editor:\n\n- Downloading liked lists from Trakt and adding them to Plex\n- Syncing the watchlists between Plex and Trakt\n- Syncing the watched status between Plex and Trakt\n- Syncing the collected status between Plex and Trakt\n\nThe first execution of the script will (depending on your PMS library size)\ntake a long time. After that, movie details and Trakt lists are cached, so\nit should run a lot quicker the second time. This does mean, however, that\nTrakt lists are not updated dynamically (which is fine for lists like \"2018\nAcademy Award Nominees\" but might not be ideal for lists that are updated\noften). Here are the execution times on my Plex server: First run - 1228\nseconds, second run - 111 seconds\n\nYou can view sync progress in the `plextraktsync.log` file which will be\ncreated.\n\nYou can use `--edit` or `--locate` flags to `config` command to open config\nfile in editor or in file browser.\n\n### Libraries\n\nBy default, all libraries are processed. You can disable libraries by name by\nchanging `excluded-libraries` in `config.yml`.\n\nYou can also set `excluded-libraries` per server in `servers.yml`:\n\n```yml\nservers:\n  Example1:\n    token: ~\n    urls:\n      - http://localhost:32400\n    config:\n      excluded-libraries:\n        - \"Family Movies\"\n```\n\nAdditionally, you can list only libraries to be processed, in this case global\n`excluded-libraries` will not be used for this server.\n\n```yml\nservers:\n  Example1:\n    token: ~\n    urls:\n      - http://localhost:32400\n    config:\n      libraries:\n        - \"Movies\"\n        - \"TV Shows\"\n```\n\nyou can see the final list of libraries with info command:\n\n```commandline\n$ plextraktsync --server=Example1 info\nEnabled 2 libraries in Plex Server:\n - 1: Movies\n - 2: TV Shows\n```\n\n### Per server configuration\n\nIf you want to specify your config per server you can do so inside of\n`servers.yml`. Within the `config` part of the server configuration you can\nspecify how that specific server should work.\n\n```yml\nservers:\n  Example1:\n    token: ~\n    urls:\n      - http://localhost:32400\n    config:\n      sync:\n        plex_to_trakt:\n          collection: true\n        trakt_to_plex:\n          liked_lists: false\n```\n\nUsing `sync` in a server config overrides the global sync-config in\n`config.yml`.\n\nThis can also be used to have different configs between different libraries. To\nbe able to do this you specify the number of servers you need (most likely\nequal to the number of different config setups you need). For example:\n\n```yml\nservers:\n  Example1:\n    token: ~\n    urls:\n      - http://localhost:32400\n    config:\n      libraries:\n        - \"Movies\"\n      sync:\n        plex_to_trakt:\n          ratings: true\n          watched_status: true\n        trakt_to_plex:\n          ratings: true\n          watched_status: true\n  Example2:\n    token: ~\n    urls:\n      - http://localhost:32400\n    config:\n      libraries:\n        - \"TV Shows\"\n      sync:\n        plex_to_trakt:\n          ratings: true\n          watched_status: false\n        trakt_to_plex:\n          ratings: true\n          watched_status: false\n```\n\nThe above config would make it so that the \"Movies\" library syncs both ratings\nand watched status, while the \"TV Shows\" library only syncs ratings. To then\nrun the sync you need to specify `--server Example1` or `--server Example2` to\nrun the sync for that specific server.\n\nRunning the sync command without `--server` will use default server from `.env`\n\nIf you want to run these jobs using `ofelia`, you can do so by running\nsomething similar to this in your `docker-compose.yml`:\n\n```yml\nservices:\n  plextraktsync:\n    image: ghcr.io/taxel/plextraktsync\n    command: sync\n    container_name: plextraktsync\n    volumes:\n      - ./config:/app/config\n    environment:\n      - PUID=1000\n      - PGID=1000\n    depends_on:\n      - plex\n  scheduler:\n    image: mcuadros/ofelia:0.3\n    container_name: scheduler\n    command: daemon --docker\n    restart: unless-stopped\n    volumes:\n      - /var/run/docker.sock:/var/run/docker.sock:ro\n    labels:\n      ofelia.job-run.plextraktsync.schedule: \"0 6,18 * * *\"\n      ofelia.job-run.plextraktsync.container: \"plextraktsync\"\n      ofelia.job-run.plextraktsync.command: \"--server 'Example1' sync\"\n      ofelia.job-run.plextraktsync2.schedule: \"0 12,0 * * *\"\n      ofelia.job-run.plextraktsync2.container: \"plextraktsync\"\n      ofelia.job-run.plextraktsync2.command: \"--server 'Example2' sync\"\n```\n\nIf you are running only one PlexTraktSync container, you need to make sure that\nthe two jobs Ofelia jobs don't run at the same time. Ofelia skips scheduling a\nnew job run if the previous job is still running.\n\nDepending on how long it takes for the job to run on your server you might have\nto keep the schedule of the two jobs seperated with a few minutes or a few\nhours. If you have two different PlexTraktSync containers in your docker\ncompose, you can run them at the same time.\n\nThe above config means that a job is running every 6 hours, alternating between\nthe two \"servers\".\n\n### Logging\n\nThe logging level by default is `INFO`. This can be changed to DEBUG by editing\nthe \"debug\" variable in `config.yml` to `true`.\n\nBy default the logs will append, if you wish to maintain the log of only your\nlast run then edit the \"append\" variable in `config.yml` to `false`.\n\n## Commands\n\nRun `plextraktsync --help` to see available commands.\nRun `plextraktsync COMMAND --help` to see help for `COMMAND`.\n\n```\n$ plextraktsync --help\nUsage: plextraktsync [OPTIONS] COMMAND [ARGS]...\n\n  Plex-Trakt-Sync is a two-way-sync between trakt.tv and Plex Media Server\n\nOptions:\n  --version              Print version and exit\n  --no-cache             Disable cache in for Trakt HTTP requests\n  --no-progressbar       Disable progressbar\n  --batch-delay INTEGER  Time in seconds between each collection batch submit\n                         to Trakt  [default: 5]\n  --server NAME          Plex Server name from servers.yml\n  --help                 Show this message and exit.\n\nCommands:\n  bug-report         Create a pre-populated GitHub issue with information...\n  cache              Manage and analyze Requests Cache.\n  clear-collections  Clear Movies and Shows collections in Trakt\n  config             Print user config for debugging and bug reports.\n  download           Downloads movie or subtitles to a local directory\n  imdb-import        Import IMDB ratings from CSV file.\n  info               Print application and environment version info\n  inspect            Inspect details of an object\n  login              Log in to Plex and Trakt if needed\n  plex-login         Log in to Plex Account to obtain Access Token.\n  self-update        Update PlexTraktSync to the latest version using pipx\n  sync               Perform sync between Plex and Trakt\n  trakt-login        Log in to Trakt Account to obtain Access Token.\n  unmatched          List media that has no match in Trakt or Plex\n  watch              Listen to events from Plex\n  watched-shows      Print a table of watched shows\n```\n\nYou can [contribute](#contribute) yourself missing documentation.\n\n### Sync\n\nThe `sync` subcommand supports `--sync=shows` and `--sync=movies` options,\nso you can sync only specific library types.\nOr only watchlist: `--sync=watchlist`.\n\n```\n\u2794 plextraktsync sync --help\nUsage: plextraktsync sync [OPTIONS]\n\n  Perform sync between Plex and Trakt\n\nOptions:\n  --sync [all|movies|shows|watchlist]\n                                  Specify what to sync  [default: all]\n  --help                          Show this message and exit.\n```\n\n### Unmatched\n\nYou can use `unmatched` command to scan your library and display unmatched\nmovies.\n\nSupport for unmatched shows is not yet implemented.\n\n`plextraktsync unmatched`\n\n### Info command\n\nThe info command can be used to print package versions,\naccount information,\nlocations of Cache, Config and Logs directories\n\n```\n$ plextraktsync info\nPlexTraktSync Version: 0.16.0\nPython Version: 3.10.0 (default, Oct  6 2021, 01:11:32) [Clang 13.0.0 (clang-1300.0.29.3)]\nPlex API Version: 4.7.2\nTrakt API Version: 3.2.1\nCache Dir: /Users/glen/Library/Caches/PlexTraktSync\nConfig Dir: /Users/glen/Library/Application Support/PlexTraktSync\nLog Dir: /Users/glen/Library/Logs/PlexTraktSync\nPlex username: nobody\nTrakt username: nobody\nPlex Server version: 1.24.3.5033-757abe6b4, updated at: 2021-02-21 17:00:00\nServer has 2 libraries: ['Movies', 'TV Shows']\n```\n\n### Inspect\n\nInspect command is used to get info about Plex Media Server items,\nwhich is useful when debugging problems and reporting issues.\n\n- Plex Web URL from your server:\n  - https://app.plex.tv/desktop/#!/server/53aff62c4bb6027c1ada814d417e83ccdf4d5045/details?key=/library/metadata/123\n- Plex Discover URL:\n  - https://app.plex.tv/desktop/#!/provider/tv.plex.provider.discover/details?key=/library/metadata/5d7768258718ba001e311845\n- Id from from your Plex Media Server:\n  - `123`\n\n```\nplextraktsync inspect 123\nplextraktsync inspect \"https://app.plex.tv/desktop/#!/server/53aff62c4bb6027c1ada814d417e83ccdf4d5045/details?key=/library/metadata/123\"\n```\n\nTo avoid problems with various shells, put the value in double quotes.\n\n### Watch\n\nYou can use the `watch` command to listen to events from Plex Media Server\nand scrobble plays.\n\n> What is scrobbling?\n>\n> _Scrobbling simply means automatically tracking what you\u2019re watching. Instead\n> of checking in from your phone of the website, this command runs in the\n> background and automatically scrobbles back to Trakt while you enjoy watching\n> your media_ - [Plex Scrobbler@blog.trakt.tv][plex-scrobbler]\n\n[plex-scrobbler]: https://blog.trakt.tv/plex-scrobbler-52db9b016ead\n\nTo restrict scrobbling to your user **only** (recommended), set the following\nin your `config.yml`:\n\n```yaml\nwatch:\n  username_filter: true\n```\n\nTo run `watch` command:\n\n`plextraktsync watch`\n\nor\n\n```\ndocker compose run --rm plextraktsync watch\n```\n\nor add `command: watch` to docker compose file, and `docker compose up -d\nplextraktsync` to start the container detached:\n\n```yaml\nversion: \"2\"\nservices:\n  plextraktsync:\n    image: ghcr.io/taxel/plextraktsync\n    volumes:\n      - ./config:/app/config\n    command: watch\n```\n\n#### Systemd setup\n\nCreate a systemd unit so that it scrobbles automatically in the background:\n\n```ini\n[Unit]\nDescription=PlexTraktSync watch daemon\nAfter=network-online.target\n\n[Service]\nExecStart=plextraktsync watch\nRestart=on-failure\nRestartSec=10\nUser=user\nGroup=user\n\n[Install]\nWantedBy=multi-user.target\n```\n\nNote, depending on your install method you may need to set your ExecStart\ncommand as follows:\n\n```ini\nExecStart=/path/to/plextraktsync/plextraktsync.sh watch\n```\n\nFollowing that you will need to enable the service:\n\n```\nsudo systemctl daemon-reload\nsudo systemctl start PlexTraktSync.service\nsudo systemctl enable PlexTraktSync.service\n```\n\n#### Systemd user setup\n\nYou can also run as systemd user service.\n\nThis walkthough allows to use different servers with the same configuration.\n\nThis assumes `plextraktsync` is installed with `pipx` for your user.\n\n```ini\n# plextraktsync@.service\n[Unit]\nDescription=PlexTraktSync watch daemon\nAfter=network-online.target\n\n[Service]\nExecSearchPath=%h/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\nExecStart=plextraktsync watch --server=%i\nRestart=on-failure\nRestartSec=10\n\n[Install]\nWantedBy=default.target\n```\n\nInstall the service template file:\n\n1. as `root`: `/etc/xdg/systemd/user/plextraktsync@.service` for all users\n1. as your user: `~/.config/systemd/user/plextraktsync@.service` for your user only\n\nNext, you need to reload systemd:\n\n1. if installed as `root`: `sudo systemctl daemon-reload`\n2. if installed as user: `systemctl --user daemon-reload`\n\nNow create instances based on server names from `servers.yml`, in this example `SERVER_NAME`.\n\n1. `systemctl --user start \"plextraktsync@SERVER_NAME.service\"`\n1. `systemctl --user status \"plextraktsync@SERVER_NAME.service\"`\n\nfor complete logs, you can use `journalctl` (add `-f` to follow logs):\n\n1. `journalctl --user -u \"plextraktsync@SERVER_NAME.service\"`\n\nIf all works, enable it for auto-start on host reboot\n\n1. `systemctl --user enable \"plextraktsync@SERVER_NAME.service\"`\n\nFor systemd --user session to start without having to log in you need to enable [systemd-linger]:\n\n1. `loginctl enable-linger`\n\n[systemd-linger]: https://wiki.archlinux.org/title/systemd/User#Automatic_start-up_of_systemd_user_instances\n\n## Good practices\n\n- Using default `Plex Movie` and `Plex TV Series` [metadata agents] improves\n  script compatibility (for matching or for watchlist).\n  It is recommended to [migrate to the new Plex TV Series agent][migrating-agent-scanner].\n- Organize your shows folders and naming according to [Plex standard][naming-tv-show-files]\n  and [theMovieDatabase][tmdb] (tmdb) order. If Plex doesn't properly identify your media,\n  you can use the [Fix Match][fix-match] and the [Match Hinting][plexmatch].\n  Also check the Episode Ordering preference (under Advanced) to correspond with your files.\n- Use tmdb as source for TV Shows if possible,\n  because it's the Trakt [primary data source][tv-show-metadata]\n  ([switched from tvdb in Jan-2021][tmdb-transition]).\n\n[fix-match]: https://support.plex.tv/articles/201018497-fix-match-match/\n[metadata agents]: https://support.plex.tv/articles/200241558-agents/\n[migrating-agent-scanner]: https://support.plex.tv/articles/migrating-a-tv-library-to-use-the-new-plex-tv-series-agent-scanner/\n[naming-tv-show-files]: https://support.plex.tv/articles/naming-and-organizing-your-tv-show-files/\n[plexmatch]: https://support.plex.tv/articles/plexmatch/\n[tmdb-transition]: https://blog.trakt.tv/tmdb-transition-ef3d19a5cf24\n[tmdb]: https://themoviedb.org/\n[tv-show-metadata]: https://blog.trakt.tv/tv-show-metadata-e6e64ed4e6ef\n\n## Troubleshooting\n\n### I have duplicate watched episodes sent to Trakt at every sync\n\nCheck your Plex episodes ordering compared to Trakt ordering.\nIf episodes are in a different order, it should not be a problem because they\nare identified with ids.\nBut if a season or an episode is missing on Trakt (and tmdb) it can't be synced.\nYou can fix it by [adding the missing episodes] or edit metadata (eg. missing\ntvdb or imdb ids) on [tmdb] or [report a metadata issue on Trakt][how-to-report-metadata-issues] ([answers][reports]). It's free for anyone\nto sign up and edit info at tmdb. Trakt will [update from tmdb][trakt-tvshow-update] data.\n\n[adding the missing episodes]: https://support.trakt.tv/support/solutions/articles/70000264977\n[tmdb]: https://themoviedb.org/\n[trakt-tvshow-update]: https://support.trakt.tv/support/solutions/articles/70000260936-how-does-movie-tv-show-information-metadata-get-updated-how-can-i-refresh-or-sync-trakt-to-tmdb-\n[how-to-report-metadata-issues]: https://support.trakt.tv/support/solutions/articles/70000627644-how-to-report-metadata-issues\n[reports]: https://trakt.tv/settings/reports\n\n### I have many matching errors in logs\n\nMake sure you use [good practices](#good-practices) about Plex agent and files\norganization as stated above.\nCheck if episodes are not missing on Trakt as explained in previous answer, and\ncheck if [external ids][house-of-the-dragon] are populated on tmdb.\n\n[house-of-the-dragon]: https://www.themoviedb.org/tv/94997-house-of-the-dragon/season/1/episode/1/edit?active_nav_item=external_ids\n\n### I have season 0 matching errors\n\nSeason 0 folder must only contain episodes belonging to season 0, also named specials.\nTrailers, deleted scenes, featurettes, interviews,... must be stored in a\nseparate [Extra folder][extra-folder] (not in season 0) according to Plex rules.\nKeep in mind that seasons 0 aren't really official so datasources (tmdb, imdb\nand tvdb) sometimes don't correspond. Check season 0 of shows on trakt.tv to identify those special episodes.\nUse tmdb as Plex source as much as you can.\n\n[extra-folder]: https://support.plex.tv/articles/local-files-for-tv-show-trailers-and-extras/\n\n### How to sync multiple users ?\n\nThe easiest way is to use containers with custom config folder for each user:\n[Multi-User docker-compose][discussions/997].\n\n[discussions/997]: https://github.com/Taxel/PlexTraktSync/discussions/997\n\n### Can this run on Synology, HomeAssistant, Portainer,... ?\n\nYes using docker, check [Discussions][discussions] page.\n\n### I have another question\n\nCheck [Discussions][discussions], maybe someone already asked and found the answer.\n\n[discussions]: https://github.com/Taxel/PlexTraktSync/discussions\n",
    "bugtrack_url": null,
    "license": "MIT License\n        \n        Copyright (c) 2019 Alexander Theimer\n        Copyright (c) 2019-2024 twolaw\n        Copyright (c) 2020-2025 Elan Ruusam\u00e4e\n        \n        Permission is hereby granted, free of charge, to any person obtaining a copy\n        of this software and associated documentation files (the \"Software\"), to deal\n        in the Software without restriction, including without limitation the rights\n        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n        copies of the Software, and to permit persons to whom the Software is\n        furnished to do so, subject to the following conditions:\n        \n        The above copyright notice and this permission notice shall be included in all\n        copies or substantial portions of the Software.\n        \n        THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n        SOFTWARE.\n        ",
    "summary": "Plex-Trakt-Sync is a two-way-sync between trakt.tv and Plex Media Server",
    "version": "0.34.5",
    "project_urls": {
        "Homepage": "https://github.com/Taxel/PlexTraktSync",
        "Issues": "https://github.com/Taxel/PlexTraktSync/issues",
        "Repository": "https://github.com/Taxel/PlexTraktSync.git"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "75fc69a2dea2f64b499126496166bbdb15319738f62ab2288bc363ccb55176b4",
                "md5": "834ffacab8f4f06d8850a283e353d710",
                "sha256": "e9499e5f1560fb714b5a51dc4e43746d1b853f4086b04e30ff75f9e3174e5d12"
            },
            "downloads": -1,
            "filename": "plextraktsync-0.34.5-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "834ffacab8f4f06d8850a283e353d710",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9",
            "size": 126136,
            "upload_time": "2025-03-09T13:06:31",
            "upload_time_iso_8601": "2025-03-09T13:06:31.728301Z",
            "url": "https://files.pythonhosted.org/packages/75/fc/69a2dea2f64b499126496166bbdb15319738f62ab2288bc363ccb55176b4/plextraktsync-0.34.5-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "982f5c141037eb5fc543a8770f1a3b1f0276712c99451c0b3c321ab2fd5d29df",
                "md5": "3d70d905994e385b8ee30a034f0dc76c",
                "sha256": "38b811c1c5343e2cc92b3f3b3f4b17856d565f6b330c0d31b4c54fe79eed5d4b"
            },
            "downloads": -1,
            "filename": "plextraktsync-0.34.5.tar.gz",
            "has_sig": false,
            "md5_digest": "3d70d905994e385b8ee30a034f0dc76c",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 105063,
            "upload_time": "2025-03-09T13:06:33",
            "upload_time_iso_8601": "2025-03-09T13:06:33.232961Z",
            "url": "https://files.pythonhosted.org/packages/98/2f/5c141037eb5fc543a8770f1a3b1f0276712c99451c0b3c321ab2fd5d29df/plextraktsync-0.34.5.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-03-09 13:06:33",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "Taxel",
    "github_project": "PlexTraktSync",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [
        {
            "name": "apluggy",
            "specs": [
                [
                    "==",
                    "1.1.0"
                ]
            ]
        },
        {
            "name": "attrs",
            "specs": [
                [
                    "==",
                    "25.1.0"
                ]
            ]
        },
        {
            "name": "cattrs",
            "specs": [
                [
                    "==",
                    "24.1.2"
                ]
            ]
        },
        {
            "name": "certifi",
            "specs": [
                [
                    "==",
                    "2025.1.31"
                ]
            ]
        },
        {
            "name": "charset-normalizer",
            "specs": [
                [
                    "==",
                    "3.4.1"
                ]
            ]
        },
        {
            "name": "click",
            "specs": [
                [
                    "==",
                    "8.1.8"
                ]
            ]
        },
        {
            "name": "decorator",
            "specs": [
                [
                    "==",
                    "5.2.1"
                ]
            ]
        },
        {
            "name": "deprecated",
            "specs": [
                [
                    "==",
                    "1.2.18"
                ]
            ]
        },
        {
            "name": "exceptiongroup",
            "specs": [
                [
                    "==",
                    "1.2.2"
                ]
            ]
        },
        {
            "name": "humanize",
            "specs": [
                [
                    "==",
                    "4.12.1"
                ]
            ]
        },
        {
            "name": "idna",
            "specs": [
                [
                    "==",
                    "3.10"
                ]
            ]
        },
        {
            "name": "inquirerpy",
            "specs": [
                [
                    "==",
                    "0.3.4"
                ]
            ]
        },
        {
            "name": "markdown-it-py",
            "specs": [
                [
                    "==",
                    "3.0.0"
                ]
            ]
        },
        {
            "name": "mdurl",
            "specs": [
                [
                    "==",
                    "0.1.2"
                ]
            ]
        },
        {
            "name": "oauthlib",
            "specs": [
                [
                    "==",
                    "3.2.2"
                ]
            ]
        },
        {
            "name": "pfzy",
            "specs": [
                [
                    "==",
                    "0.3.4"
                ]
            ]
        },
        {
            "name": "platformdirs",
            "specs": [
                [
                    "==",
                    "4.3.6"
                ]
            ]
        },
        {
            "name": "plexapi",
            "specs": [
                [
                    "==",
                    "4.16.1"
                ]
            ]
        },
        {
            "name": "pluggy",
            "specs": [
                [
                    "==",
                    "1.5.0"
                ]
            ]
        },
        {
            "name": "prompt-toolkit",
            "specs": [
                [
                    "==",
                    "3.0.50"
                ]
            ]
        },
        {
            "name": "pygments",
            "specs": [
                [
                    "==",
                    "2.19.1"
                ]
            ]
        },
        {
            "name": "python-dotenv",
            "specs": [
                [
                    "==",
                    "1.0.1"
                ]
            ]
        },
        {
            "name": "python-git-info",
            "specs": [
                [
                    "==",
                    "0.8.3"
                ]
            ]
        },
        {
            "name": "pytimeparse",
            "specs": [
                [
                    "==",
                    "1.1.8"
                ]
            ]
        },
        {
            "name": "pytrakt",
            "specs": [
                [
                    "==",
                    "4.2.0"
                ]
            ]
        },
        {
            "name": "pyyaml",
            "specs": [
                [
                    "==",
                    "6.0.2"
                ]
            ]
        },
        {
            "name": "requests",
            "specs": [
                [
                    "==",
                    "2.32.3"
                ]
            ]
        },
        {
            "name": "requests-cache",
            "specs": [
                [
                    "==",
                    "1.2.1"
                ]
            ]
        },
        {
            "name": "requests-oauthlib",
            "specs": [
                [
                    "==",
                    "2.0.0"
                ]
            ]
        },
        {
            "name": "rich",
            "specs": [
                [
                    "==",
                    "13.9.4"
                ]
            ]
        },
        {
            "name": "six",
            "specs": [
                [
                    "==",
                    "1.17.0"
                ]
            ]
        },
        {
            "name": "tqdm",
            "specs": [
                [
                    "==",
                    "4.67.1"
                ]
            ]
        },
        {
            "name": "types-decorator",
            "specs": [
                [
                    "==",
                    "5.2.0.20250224"
                ]
            ]
        },
        {
            "name": "typing-extensions",
            "specs": [
                [
                    "==",
                    "4.12.2"
                ]
            ]
        },
        {
            "name": "url-normalize",
            "specs": [
                [
                    "==",
                    "1.4.3"
                ]
            ]
        },
        {
            "name": "urllib3",
            "specs": [
                [
                    "==",
                    "2.3.0"
                ]
            ]
        },
        {
            "name": "wcwidth",
            "specs": [
                [
                    "==",
                    "0.2.13"
                ]
            ]
        },
        {
            "name": "websocket-client",
            "specs": [
                [
                    "==",
                    "1.8.0"
                ]
            ]
        },
        {
            "name": "wrapt",
            "specs": [
                [
                    "==",
                    "1.17.2"
                ]
            ]
        }
    ],
    "lcname": "plextraktsync"
}
        
Elapsed time: 4.29526s