GithubHelp home page GithubHelp logo

taxel / plextraktsync Goto Github PK

View Code? Open in Web Editor NEW
1.4K 25.0 95.0 2.89 MB

A python script that syncs the movies, shows and ratings between trakt and Plex (without needing a PlexPass or Trakt VIP subscription)

License: MIT License

Python 95.72% Shell 1.32% Dockerfile 1.19% Batchfile 1.77%

plextraktsync's Introduction

Plex-Trakt-Sync

Python Versions

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

Originally created by @Taxel, now maintained by 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?


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.8-3.12 versions.

Installation

pipx

Installation with 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.

Docker Compose

You can setup docker compose file like this:

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.

Windows Setup (optional alternative)

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

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

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"
  • Below the "#!/bin/bash" line add: docker start PlexTraktSync
  • 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.

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 section

  • 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 .envand .pytrakt.json files. Plex URL and token is stored in servers.yml.

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

  • 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 can also be used to run the script at set intervals.

A docker-compose example with a 6h interval:

version: "2"
services:
  scheduler:
    image: mcuadros/ofelia:latest
    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:

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.

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

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

$ 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.

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:

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:

services:
  plextraktsync:
    image: ghcr.io/taxel/plextraktsync
    command: sync
    container_name: plextraktsync
    profiles: ["schedule"]
    volumes:
      - /configs/mediarr/plextraktsync:/app/config
    environment:
      - PUID=1000
      - PGID=1000
    depends_on:
      - plex
  scheduler:
    image: mcuadros/ofelia:latest
    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". The PlexTraktSync container also has a docker compose profile called "schedule" which means that it won't run automatically when you run for example docker-compose up.

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 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.

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 [email protected]

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

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:

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:

[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:

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.

# [email protected]
[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/[email protected] for all users
  2. as your user: ~/.config/systemd/user/[email protected] 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"
  2. 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

Good practices

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 (answers). It's free for anyone to sign up and edit info at tmdb. Trakt will update from tmdb data.

I have many matching errors in logs

Make sure you use 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 are populated on tmdb.

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 (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.

How to sync multiple users ?

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

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

Yes using docker, check Discussions page.

I have another question

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

plextraktsync's People

Contributors

agneevx avatar chrillep avatar cosmincc avatar dennisvtang avatar dependabot[bot] avatar ericswpark avatar fabiomsnunes avatar fnwc avatar glensc avatar hawkeone avatar hollander-1908 avatar imjuzcy avatar jbalcorn avatar jberesford avatar jonnywong16 avatar ksya avatar matty666 avatar mcdallas avatar ngdm avatar pokeponz avatar rileyxx avatar scottrobertson avatar sebbejohansson avatar simonc56 avatar sirloinofbeef avatar stevietv avatar taxel avatar th3s4mur41 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

plextraktsync's Issues

How does the synchronisation of lists, watch lists and collections work?

So I have PlexTraktSync set up now and it works a charm to keep my two servers in sync. Thanks @twolaw for the help yesterday

I'm a little confused by the list syncing however as I'm not sure what the expected behaviour should be. Should lists I create in Trakt register as Collections in Plex and vice versa? Or is it something else?

I have collections already set up in Plex and I have lists and a watch list in Trakt, but they don't seem to be syncing anywhere.

Any suggestions?

Timeout

I think this should continue to next request :)



Processing section TV Shows
Traceback (most recent call last):
  File "C:\Program Files (x86)\Python38-32\lib\site-packages\urllib3\connectionpool.py", line 421, in _make_request
    six.raise_from(e, None)
  File "<string>", line 3, in raise_from
  File "C:\Program Files (x86)\Python38-32\lib\site-packages\urllib3\connectionpool.py", line 416, in _make_request
    httplib_response = conn.getresponse()
  File "C:\Program Files (x86)\Python38-32\lib\http\client.py", line 1322, in getresponse
    response.begin()
  File "C:\Program Files (x86)\Python38-32\lib\http\client.py", line 303, in begin
    version, status, reason = self._read_status()
  File "C:\Program Files (x86)\Python38-32\lib\http\client.py", line 264, in _read_status
    line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
  File "C:\Program Files (x86)\Python38-32\lib\socket.py", line 669, in readinto
    return self._sock.recv_into(b)
socket.timeout: timed out

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Program Files (x86)\Python38-32\lib\site-packages\requests\adapters.py", line 439, in send
    resp = conn.urlopen(
  File "C:\Program Files (x86)\Python38-32\lib\site-packages\urllib3\connectionpool.py", line 719, in urlopen
    retries = retries.increment(
  File "C:\Program Files (x86)\Python38-32\lib\site-packages\urllib3\util\retry.py", line 400, in increment
    raise six.reraise(type(error), error, _stacktrace)
  File "C:\Program Files (x86)\Python38-32\lib\site-packages\urllib3\packages\six.py", line 735, in reraise
    raise value
  File "C:\Program Files (x86)\Python38-32\lib\site-packages\urllib3\connectionpool.py", line 665, in urlopen
    httplib_response = self._make_request(
  File "C:\Program Files (x86)\Python38-32\lib\site-packages\urllib3\connectionpool.py", line 423, in _make_request
    self._raise_timeout(err=e, url=url, timeout_value=read_timeout)
  File "C:\Program Files (x86)\Python38-32\lib\site-packages\urllib3\connectionpool.py", line 330, in _raise_timeout
    raise ReadTimeoutError(
urllib3.exceptions.ReadTimeoutError: HTTPConnectionPool(host='148.251.159.246', port=42411): Read timed out. (read timeout=30)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:/Users/bradl/Desktop/PlexTraktSync-master/main.py", line 315, in <module>
    main()
  File "C:/Users/bradl/Desktop/PlexTraktSync-master/main.py", line 300, in main
    process_show_section(section)
  File "C:/Users/bradl/Desktop/PlexTraktSync-master/main.py", line 186, in process_show_section
    for episode in show.episodes():
  File "C:\Program Files (x86)\Python38-32\lib\site-packages\plexapi\video.py", line 352, in episodes
    return self.fetchItems(key, **kwargs)
  File "C:\Program Files (x86)\Python38-32\lib\site-packages\plexapi\base.py", line 147, in fetchItems
    data = self._server.query(ekey)
  File "C:\Program Files (x86)\Python38-32\lib\site-packages\plexapi\server.py", line 376, in query
    response = method(url, headers=headers, timeout=timeout, **kwargs)
  File "C:\Program Files (x86)\Python38-32\lib\site-packages\requests\sessions.py", line 546, in get
    return self.request('GET', url, **kwargs)
  File "C:\Program Files (x86)\Python38-32\lib\site-packages\requests\sessions.py", line 533, in request
    resp = self.send(prep, **send_kwargs)
  File "C:\Program Files (x86)\Python38-32\lib\site-packages\requests\sessions.py", line 646, in send
    r = adapter.send(request, **kwargs)
  File "C:\Program Files (x86)\Python38-32\lib\site-packages\requests\adapters.py", line 529, in send
    raise ReadTimeout(e, request=request)
requests.exceptions.ReadTimeout: HTTPConnectionPool(host='148.251.159.246', port=42411): Read timed out. (read timeout=30)

Process finished with exit code 1

Script Not Syncing TV Shows To Playlists (Only Movies)

This script is magically! But noticed it only imports movies into the Plex Playlists and seems to skip over TV show lists?
I have a couple of straight up TV lists, Archieverse is one of them, which it seems to miss.
As well as I have Marvel Rising List, which has a number of TV episodes as well as movies, but it's only adding the movies to the Plex Playlist.
Any future development in play to import all items from Trakt play lists?

Options to sync one way or the other

It would be nice to configure the syncing ways. Maybe I want to update track from one server but not pull the tracking down, etc. Also option to toggle TV or Movies

Crash every run. Data of git clone 8/27

Every time running after initial config throws these errors:

Starting sync Plex {{{{{Email}}}}}} and Trakt {{{{{username}}}}}
Traceback (most recent call last):
  File "./main.py", line 342, in <module>
    main()
  File "./main.py", line 285, in main
    trakt_watched_shows = pytrakt_extensions.allwatched()
  File "/usr/local/lib/python3.8/site-packages/trakt/core.py", line 539, in inner
    json_data = self._handle_request('get', url)
  File "/usr/local/lib/python3.8/site-packages/trakt/core.py", line 519, in _handle_request
    json_data = json.loads(response.content.decode('UTF-8', 'ignore'))
  File "/usr/lib64/python3.8/json/__init__.py", line 357, in loads
    return _default_decoder.decode(s)
  File "/usr/lib64/python3.8/json/decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib64/python3.8/json/decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

Instalation problem

I have a problem with the installation.
Unfortunately, during the first step I have problems:

[~] # pip3 /share/CACHEDEV1_DATA/.qpkg/PlexMediaServer/PlexTraktSync-master/requirements.txt
ERROR: unknown command "/share/CACHEDEV1_DATA/.qpkg/PlexMediaServer/PlexTraktSync-master/requirements.txt"
[~] # pip3 install -r /share/CACHEDEV1_DATA/.qpkg/PlexMediaServer/PlexTraktSync-master/requirements.txt
Collecting astroid==2.3.2
  Downloading astroid-2.3.2-py3-none-any.whl (205 kB)
     |████████████████████████████████| 205 kB 1.1 MB/s
Collecting certifi==2019.9.11
  Downloading certifi-2019.9.11-py2.py3-none-any.whl (154 kB)
     |████████████████████████████████| 154 kB 205 kB/s
Requirement already satisfied: chardet==3.0.4 in /share/CACHEDEV1_DATA/.qpkg/Entware/lib/python3.7/site-packages (from -r /share/CACHEDEV1_DATA/.qpkg/PlexMediaServer/PlexTraktSync-master/requirements.txt (line 3)) (3.0.4)
Requirement already satisfied: idna==2.8 in /share/CACHEDEV1_DATA/.qpkg/Entware/lib/python3.7/site-packages (from -r /share/CACHEDEV1_DATA/.qpkg/PlexMediaServer/PlexTraktSync-master/requirements.txt (line 4)) (2.8)
Collecting isort==4.3.21
  Downloading isort-4.3.21-py2.py3-none-any.whl (42 kB)
     |████████████████████████████████| 42 kB 1.5 MB/s
Requirement already satisfied: lazy-object-proxy==1.4.2 in /share/CACHEDEV1_DATA/.qpkg/Entware/lib/python3.7/site-packages (from -r /share/CACHEDEV1_DATA/.qpkg/PlexMediaServer/PlexTraktSync-master/requirements.txt (line 6)) (1.4.2)
Collecting mccabe==0.6.1
  Downloading mccabe-0.6.1-py2.py3-none-any.whl (8.6 kB)
Requirement already satisfied: oauthlib==3.1.0 in /share/CACHEDEV1_DATA/.qpkg/Entware/lib/python3.7/site-packages (from -r /share/CACHEDEV1_DATA/.qpkg/PlexMediaServer/PlexTraktSync-master/requirements.txt (line 8)) (3.1.0)
Collecting PlexAPI==3.2.0
  Downloading PlexAPI-3.2.0.tar.gz (73 kB)
     |████████████████████████████████| 73 kB 3.0 MB/s
Collecting pylint==2.4.3
  Downloading pylint-2.4.3-py3-none-any.whl (302 kB)
     |████████████████████████████████| 302 kB 1.7 MB/s
Collecting python-dotenv==0.10.3
  Downloading python_dotenv-0.10.3-py2.py3-none-any.whl (16 kB)
Requirement already satisfied: requests==2.22.0 in /share/CACHEDEV1_DATA/.qpkg/Entware/lib/python3.7/site-packages (from -r /share/CACHEDEV1_DATA/.qpkg/PlexMediaServer/PlexTraktSync-master/requirements.txt (line 12)) (2.22.0)
Requirement already satisfied: requests-cache==0.5.2 in /share/CACHEDEV1_DATA/.qpkg/Entware/lib/python3.7/site-packages (from -r /share/CACHEDEV1_DATA/.qpkg/PlexMediaServer/PlexTraktSync-master/requirements.txt (line 13)) (0.5.2)
Collecting requests-oauthlib==1.2.0
  Downloading requests_oauthlib-1.2.0-py2.py3-none-any.whl (22 kB)
Requirement already satisfied: six==1.12.0 in /share/CACHEDEV1_DATA/.qpkg/Entware/lib/python3.7/site-packages (from -r /share/CACHEDEV1_DATA/.qpkg/PlexMediaServer/PlexTraktSync-master/requirements.txt (line 15)) (1.12.0)
Collecting tqdm==4.36.1
  Downloading tqdm-4.36.1-py2.py3-none-any.whl (52 kB)
     |████████████████████████████████| 52 kB 1.8 MB/s
Collecting trakt==2.11.0
  Downloading trakt-2.11.0.tar.gz (31 kB)
Collecting typed-ast==1.4.0
  Downloading typed_ast-1.4.0.tar.gz (206 kB)
     |████████████████████████████████| 206 kB 1.7 MB/s
Collecting urllib3==1.25.6
  Downloading urllib3-1.25.6-py2.py3-none-any.whl (125 kB)
     |████████████████████████████████| 125 kB 1.7 MB/s
Collecting websocket-client==0.56.0
  Downloading websocket_client-0.56.0-py2.py3-none-any.whl (200 kB)
     |████████████████████████████████| 200 kB 3.0 MB/s
Requirement already satisfied: wrapt==1.11.2 in /share/CACHEDEV1_DATA/.qpkg/Entware/lib/python3.7/site-packages (from -r /share/CACHEDEV1_DATA/.qpkg/PlexMediaServer/PlexTraktSync-master/requirements.txt (line 21)) (1.11.2)
Installing collected packages: typed-ast, astroid, certifi, isort, mccabe, tqdm, websocket-client, PlexAPI, pylint, python-dotenv, requests-oauthlib, trakt, urllib3
    Running setup.py install for typed-ast ... error
    ERROR: Command errored out with exit status 1:
     command: /opt/bin/python3 -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/share/CACHEDEV1_DATA/.qpkg/Entware/tmp/pip-install-h89e36at/typed-ast/setup.py'"'"'; __file__='"'"'/share/CACHEDEV1_DATA/.qpkg/Entware/tmp/pip-install-h89e36at/typed-ast/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /share/CACHEDEV1_DATA/.qpkg/Entware/tmp/pip-record-3ya_66qz/install-record.txt --single-version-externally-managed --compile --install-headers /opt/include/python3.7/typed-ast
         cwd: /share/CACHEDEV1_DATA/.qpkg/Entware/tmp/pip-install-h89e36at/typed-ast/
    Complete output (25 lines):
    running install
    running build
    running build_py
    creating build
    creating build/lib.linux-x86_64-3.7
    creating build/lib.linux-x86_64-3.7/typed_ast
    copying typed_ast/__init__.py -> build/lib.linux-x86_64-3.7/typed_ast
    copying typed_ast/ast27.py -> build/lib.linux-x86_64-3.7/typed_ast
    copying typed_ast/ast3.py -> build/lib.linux-x86_64-3.7/typed_ast
    copying typed_ast/conversions.py -> build/lib.linux-x86_64-3.7/typed_ast
    package init file 'ast3/tests/__init__.py' not found (or not a regular file)
    creating build/lib.linux-x86_64-3.7/typed_ast/tests
    copying ast3/tests/test_basics.py -> build/lib.linux-x86_64-3.7/typed_ast/tests
    warning: build_py: byte-compiling is disabled, skipping.

    running build_ext
    building '_ast27' extension
    creating build/temp.linux-x86_64-3.7
    creating build/temp.linux-x86_64-3.7/ast27
    creating build/temp.linux-x86_64-3.7/ast27/Parser
    creating build/temp.linux-x86_64-3.7/ast27/Python
    creating build/temp.linux-x86_64-3.7/ast27/Custom
    x86_64-openwrt-linux-gnu-gcc -Wno-unused-result -Wsign-compare -DNDEBUG -O2 -pipe -fomit-frame-pointer -fno-caller-saves -fhonour-copts -Wno-error=unused-but-set-variable -Wno-error=unused-result -O2 -pipe -fomit-frame-pointer -fno-caller-saves -fhonour-copts -Wno-error=unused-but-set-variable -Wno-error=unused-result -DNDEBUG -fno-inline -O2 -pipe -fomit-frame-pointer -fno-caller-saves -fhonour-copts -Wno-error=unused-but-set-variable -Wno-error=unused-result -DNDEBUG -fno-inline -I/media/ware/Entware.2019.10/staging_dir/target-x86_64_glibc-2.27/opt/include -I/media/ware/Entware.2019.10/staging_dir/toolchain-x86_64_gcc-7.4.0_glibc-2.27/include -fPIC -Iast27/Include -I/opt/include/python3.7 -c ast27/Parser/acceler.c -o build/temp.linux-x86_64-3.7/ast27/Parser/acceler.o
    unable to execute 'x86_64-openwrt-linux-gnu-gcc': No such file or directory
    error: command 'x86_64-openwrt-linux-gnu-gcc' failed with exit status 1
    ----------------------------------------
ERROR: Command errored out with exit status 1: /opt/bin/python3 -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/share/CACHEDEV1_DATA/.qpkg/Entware/tmp/pip-install-h89e36at/typed-ast/setup.py'"'"'; __file__='"'"'/share/CACHEDEV1_DATA/.qpkg/Entware/tmp/pip-install-h89e36at/typed-ast/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /share/CACHEDEV1_DATA/.qpkg/Entware/tmp/pip-record-3ya_66qz/install-record.txt --single-version-externally-managed --compile --install-headers /opt/include/python3.7/typed-ast Check the logs for full command output.
[~] # pip instal urllib3
ERROR: unknown command "instal" - maybe you meant "install"
[~] # pip install urllib3
Requirement already satisfied: urllib3 in /share/CACHEDEV1_DATA/.qpkg/Entware/lib/python3.7/site-packages (1.25.8)
[~] # pip install websocket-client
Requirement already satisfied: websocket-client in /share/CACHEDEV1_DATA/.qpkg/Entware/lib/python3.7/site-packages (0.57.0)
Requirement already satisfied: six in /share/CACHEDEV1_DATA/.qpkg/Entware/lib/python3.7/site-packages (from websocket-client) (1.12.0)
[~] # pip install pip
Requirement already satisfied: pip in /share/CACHEDEV1_DATA/.qpkg/Entware/lib/python3.7/site-packages (20.0.2)
[~] # pip install wrapt
Requirement already satisfied: wrapt in /share/CACHEDEV1_DATA/.qpkg/Entware/lib/python3.7/site-packages (1.11.2)
[~] #

Give user indication what to do on error

I've updated to recent master (39c89b9) and now I get error:

root@acai:~/scm/mediaserver/plex/Plugins/PlexTraktSync # ./plex_trakt_sync.sh
Loading .env environment variables…
Starting sync Plex None and Trakt *censored*
Trakt authentication error: Unauthorized - OAuth must be provided

I did ran pip3 install -r requirements.txt to grab latest packages, the error is still there

I really would not wish to dig through merged pull requests to see what changed and how to log in again. I think the error should give me instructions on what to do next.

Inconsistency with config locations

It's very confusing that configuration is spewed around in multiple places:

  • config.json
  • .env
  • .pytrakt.json

and config.json is even committed to git, so must be careful when pushing changes.

multiuser

Is there a way to sync multiple users from one linux machine ?

my server was previously on windows, and I simply copied the directory and run the get_env several time.

Now I have migrated on ubuntu, and one user is working fine, but the other one are giving an error message
Traceback (most recent call last): File "main.py", line 322, in <module> main() File "main.py", line 263, in main map(lambda m: m.slug, trakt_user.watched_movies)) File "/home/greg/.local/lib/python3.6/site-packages/trakt/core.py", line 472, in inner json_data = self._handle_request('get', url) File "/home/greg/.local/lib/python3.6/site-packages/trakt/core.py", line 449, in _handle_request raise self.error_map[response.status_code]() trakt.errors.OAuthException: Unauthorized - OAuth must be provided

Syncing Wrong Shows

This is syncing wrong shows that I have never watched lol

2019-11-11 20:25:16,895 INFO:Show [Crazy Claws (1981)]: Marked as watched on plex: episode S01E01
2019-11-11 20:25:17,168 INFO:Show [Crazy Claws (1981)]: Marked as watched on plex: episode S01E02
2019-11-11 20:25:17,444 INFO:Show [Crazy Claws (1981)]: Marked as watched on plex: episode S01E03
2019-11-11 20:25:17,723 INFO:Show [Crazy Claws (1981)]: Marked as watched on plex: episode S01E04
2019-11-11 20:25:18,000 INFO:Show [Crazy Claws (1981)]: Marked as watched on plex: episode S01E05
2019-11-11 20:25:18,275 INFO:Show [Crazy Claws (1981)]: Marked as watched on plex: episode S01E06
2019-11-11 20:25:18,545 INFO:Show [Crazy Claws (1981)]: Marked as watched on plex: episode S01E07
2019-11-11 20:25:18,841 INFO:Show [Crazy Claws (1981)]: Marked as watched on plex: episode S01E08
2019-11-11 20:25:19,127 INFO:Show [Crazy Claws (1981)]: Marked as watched on plex: episode S01E09
2019-11-11 20:25:19,407 INFO:Show [Crazy Claws (1981)]: Marked as watched on plex: episode S01E10
2019-11-11 20:25:19,689 INFO:Show [Crazy Claws (1981)]: Marked as watched on plex: episode S01E11
2019-11-11 20:25:19,952 INFO:Show [Crazy Claws (1981)]: Marked as watched on plex: episode S01E12
2019-11-11 20:25:20,238 INFO:Show [Crazy Claws (1981)]: Marked as watched on plex: episode S01E13
2019-11-11 20:25:20,514 INFO:Show [Crazy Claws (1981)]: Marked as watched on plex: episode S01E14
2019-11-11 20:25:20,794 INFO:Show [Crazy Claws (1981)]: Marked as watched on plex: episode S01E15
2019-11-11 20:25:21,070 INFO:Show [Crazy Claws (1981)]: Marked as watched on plex: episode S01E16
2019-11-11 20:25:21,070 INFO:Show [Crazy Claws (1981)]: Finished sync

image

Add Configuration in a file instead of interactive first time setup

Hi,
I really like this project :)

I'm running this in a docker container, so that i can start the container when needed.
The only problem is that I can't figure out how to do the initial setup without the interactive part.

So my workaround is to do the first setup manually and then only copy the files to the image during the docker build.

I would open a pull request for the docker setup...but It needs manual work to get there.

TL;DR: Please add a config file with a non interactive setup in order to dockerize the project.

Extra option to not create collection in Trakt?

Hello,

I found this hidden gem and I am testing it out. I wanted to ask you if there is a way to not initially sync the whole Plex library to the Trakt Collection. Is that possible to be excluded? I could not find it in the json file.

I actually just want to create Plex collections out of Trakt Lists. If possible even with specify what Trakt list. I think that should be possible with this, but I can't get past the initial sync to Trakt Collection (does a lot of time-outs)

Thanks!

Watched dates from episodes not correctly synced from Plex to trakt

Hi, so I've got this strange issue that episodes watch dates from Plex are not synced correctly when the script is run. Meaning, that when I watched an episode on Plex, I expect the episode on trakt to have the same watched timestamp. Instead it seems to have the timestamp from the sync.

Strangely enough, the issue doesn't arise with movies, there the timestamp sync works without issues and as expected.

Getting 'bad response from trakt' for my entire TV library

I love this project, thank you so much for doing this.

The script had been working perfectly for me for months until yesterday. I thought maybe I broke something so I reinstalled and ran the setup again, authenticated fine, synced the movie library fine, but now I'm getting this for the whole TV library:

... 2020-09-22 07:57:09,307 WARNING:Completed section sync in 33 min 44.7 seconds 2020-09-22 07:57:09,815 INFO:Now working on show section TV Shows containing 737 elements 2020-09-22 07:57:11,381 ERROR:Show [The '80s: The Decade That Made Us (2013)]: bad response from trakt (GUID com.plexapp.agents.thetvdb://268450?lang=en) 2020-09-22 07:57:12,275 ERROR:Show [The 100 (2014)]: bad response from trakt (GUID com.plexapp.agents.thetvdb://268592?lang=en) 2020-09-22 07:57:13,425 ERROR:Show [2 Dope Queens (2018)]: bad response from trakt (GUID com.plexapp.agents.thetvdb://340151?lang=en) 2020-09-22 07:57:14,414 ERROR:Show [30 Rock (2005)]: bad response from trakt (GUID com.plexapp.agents.thetvdb://79488?lang=en) 2020-09-22 07:57:15,842 ERROR:Show [3rd Rock from the Sun (1996)]: bad response from trakt (GUID com.plexapp.agents.thetvdb://72389?lang=en) 2020-09-22 07:57:17,051 ERROR:Show [68 Whiskey (2020)]: bad response from trakt (GUID com.plexapp.agents.thetvdb://370053?lang=en) 2020-09-22 07:57:18,058 ERROR:Show [The A-Team (1983)]: bad response from trakt (GUID com.plexapp.agents.thetvdb://77904?lang=en) 2020-09-22 07:57:18,954 ERROR:Show [A.P. Bio (2018)]: bad response from trakt (GUID com.plexapp.agents.thetvdb://328534?lang=en) 2020-09-22 07:57:19,967 ERROR:Show [Abstract: The Art of Design (2017)]: bad response from trakt (GUID com.plexapp.agents.thetvdb://322890?lang=en) 2020-09-22 07:57:21,153 ERROR:Show [Adam Ruins Everything (2015)]: bad response from trakt (GUID com.plexapp.agents.thetvdb://300774?lang=en) 2020-09-22 07:57:22,119 ERROR:Show [Adventure Time (2010)]: bad response from trakt (GUID com.plexapp.agents.thetvdb://152831?lang=en) 2020-09-22 07:57:23,420 ERROR:Show [The Adventures of Brisco County, Jr. (1993)]: bad response from trakt (GUID com.plexapp.agents.thetvdb://72364?lang=en) 2020-09-22 07:57:24,298 ERROR:Show [The Adventures of Young Indiana Jones (1992)]: bad response from trakt (GUID com.plexapp.agents.thetvdb://82643?lang=en) ...

Is there any way I can fix this?

TypeError: '<' not supported between instances of 'Movie' and 'Movie'

Processing section TV Shows
Traceback (most recent call last):
  File "/home/glen/scm/mediaserver/plex/Plugins/PlexTraktSync/main.py", line 354, in <module>
    main()
  File "/home/glen/scm/mediaserver/plex/Plugins/PlexTraktSync/main.py", line 345, in main
    listutil.updatePlexLists(plex)
  File "/home/glen/scm/mediaserver/plex/Plugins/PlexTraktSync/trakt_list_util.py", line 61, in updatePlexLists
    l.updatePlexList(plex)
  File "/home/glen/scm/mediaserver/plex/Plugins/PlexTraktSync/trakt_list_util.py", line 36, in updatePlexList
    _, plex_movies_sorted = zip(*sorted(self.plex_movies))
TypeError: '<' not supported between instances of 'Movie' and 'Movie'

Sync does no more work with new Plex Movie agent

It seems like the script is no longer able to sync or scrobble anything related to movies after upgrading to the latest agent on Plex side. The new agent implementation does no more add the imdb ids to the metadata, but it does combine multiple sources (rottentomatoe, imdb, ...) to one single "plex://" item.

I'm not sure if this could be fixed on script side or whether we need to wait until Plex re-adds this imdb information. According to a Plex employee this is already in discussion: https://forums.plex.tv/t/new-plex-movie-agent-does-not-contain-imdb-info/618121/34

Until then: you guys need to switch back to "plex agent (legacy)" and re-match already matched movies again. Then you get back the guid="com.plexapp.agents.imdb://tt2140479?lang=de"metadata items.

image

Excluding a libray

Is there any way to exclude a library?

Also, when adding to cron, couldn't it just be "0 */2 * * * python main.py"?
I'm not even sure what the rest does, but I've noticed "plex_trakt_sync.sh" seems to set some PATH variables before running main.py

Trakt username with special character raises an error because PyTrakt doesn't use slug version as API expects

Upon running the script and setting everything up it seems to run into the error above. Having the log_debug_messages set to true and running the script outputs:

2020-08-13 18:09:27,728 INFO:Starting sync Plex {Username} and Trakt {user-name}
2020-08-13 18:09:27,729 DEBUG:get: https://api-v2launch.trakt.tv/users/{user-name}
2020-08-13 18:09:27,729 DEBUG:headers: {'Content-Type': 'application/json', 'trakt-api-version': '2', 'trakt-api-key': '{API-KEY}', 'Authorization': 'Bearer {Bearer}'}
2020-08-13 18:09:27,729 DEBUG:method, url :: get, https://api-v2launch.trakt.tv/users/{user-name}
2020-08-13 18:09:27,731 DEBUG:Starting new HTTPS connection (1): api-v2launch.trakt.tv:443
2020-08-13 18:09:27,885 DEBUG:https://api-v2launch.trakt.tv:443 "GET /users/{user-name} HTTP/1.1" 200 None
2020-08-13 18:09:27,886 DEBUG:RESPONSE [get] (https://api-v2launch.trakt.tv/users/{user-name}): <Response [200]>
2020-08-13 18:09:27,887 DEBUG:get: https://api-v2launch.trakt.tv/users/{User Name}/watched/movies
2020-08-13 18:09:27,887 DEBUG:headers: {'Content-Type': 'application/json', 'trakt-api-version': '2', 'trakt-api-key': '{API-KEY}', 'Authorization': 'Bearer {Bearer}'}
2020-08-13 18:09:27,887 DEBUG:method, url :: get, https://api-v2launch.trakt.tv/users/{User Name}/watched/movies
2020-08-13 18:09:27,888 DEBUG:Starting new HTTPS connection (1): api-v2launch.trakt.tv:443
2020-08-13 18:09:28,052 DEBUG:https://api-v2launch.trakt.tv:443 "GET /users/{User%20Name}/watched/movies HTTP/1.1" 404 None
2020-08-13 18:09:28,054 DEBUG:RESPONSE [get] (https://api-v2launch.trakt.tv/users/{User Name}/watched/movies): <Response [404]>

at the end it seems to be trying to put a space between my username instead of a - like in the first portion of the log and therefor failing because it reaches a 404 response since said url does not exist.

note: I replaced actual usernames with {whatever}. I put - where they was at in the log and spaces in the logs where they was at along with the %20 in the one bit where it was.

I've posted this issue over at moogar0880/PyTrakt#126 as well, just in case this is an issue with their package instead of the script.

Edit: It seems to be that it pulls the username from the settings page of trakt, so if there is a space in the username on the settings page of trakt it will pull it with the space..

unsupported format string passed to NoneType.__format__

Hello,

After lunching main.py, I've got this error :

Processing section Divertissement
Traceback (most recent call last):
  File "main.py", line 179, in process_show_section
    eps = lookup[episode.seasonNumber][episode.index]
KeyError: 2019

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "main.py", line 301, in <module>
    main()
  File "main.py", line 286, in main
    process_show_section(section)
  File "main.py", line 220, in process_show_section
    show.title, show.year, episode.seasonNumber, episode.index))
TypeError: unsupported format string passed to NoneType.__format__

Do you have any idea ?

Incorrect movie matched

Greetings,

I am attempting to sync movies from Trakt lists to Plex, and some didn't appear in the playlists. Here is one example where Adventures in Babysitting (1987) is in my Trakt list and my Plex library, but it matches the remake from 2016.

2020-07-11 08:14:49,970 DEBUG:get: https://api-v2launch.trakt.tv/movies/adventures-in-babysitting-1987?extended=full
2020-07-11 08:14:49,970 DEBUG:headers: {'Content-Type': 'application/json', 'trakt-api-version': '2', 'trakt-api-key': 'TRAKTKEY', 'Authorization': 'Bearer BEARER'}
2020-07-11 08:14:49,970 DEBUG:method, url :: get, https://api-v2launch.trakt.tv/movies/adventures-in-babysitting-1987?extended=full
2020-07-11 08:14:49,980 DEBUG:RESPONSE [get] (https://api-v2launch.trakt.tv/movies/adventures-in-babysitting-1987?extended=full): <Response [200]>

[later in the log...]

2020-07-11 08:15:38,015 DEBUG:get: https://api-v2launch.trakt.tv/search?id=360606&id_type=tmdb
2020-07-11 08:15:38,016 DEBUG:headers: {'Content-Type': 'application/json', 'trakt-api-version': '2', 'trakt-api-key': 'TRAKTKEY', 'Authorization': 'Bearer BEARER'}
2020-07-11 08:15:38,016 DEBUG:method, url :: get, https://api-v2launch.trakt.tv/search?id=360606&id_type=tmdb
2020-07-11 08:15:38,028 DEBUG:RESPONSE [get] (https://api-v2launch.trakt.tv/search?id=360606&id_type=tmdb): <Response [200]>
2020-07-11 08:15:38,029 INFO:Movie [Adventures In Babysitting (1987)]: sync complete

Another example is the movie L.A. Story, which gets matched to Toy Story 4. Let me know if you need further info

"Watched at"-date not correctly set when syncing from trakt to plex

Similar to issue #19 but this time, the sync order is switched and it's for both movies and tv shows.

Currently, when the script is run, when there's a episode or a movie watched on trakt, it gets marked as watched in Plex as well. At it's core, it works (it actually gets marked as watched in Plex) but the date is wrong.

I expected that the script would use the "watched at" timestamp to carry over from trakt to plex, but instead it uses the timestamp of the sync itself.

I think this is maybe a upstream issue as well because currently the script uses
movie.markWatched() and episode.markWatched() instead of passing through the "watched at" timestamp from trakt.

Error when processing a TV show

Hi, unsure what's going on here, but I think the show "The Bold Type" is making this script freak out.

This is what I get as an error in the console:

Traceback (most recent call last): File "main.py", line 247, in <module> main() File "main.py", line 233, in main process_show_section(section) File "main.py", line 125, in process_show_section logging.error("Show [{} ({})]: Unrecognized GUID {}".format(show.title, show .year)) IndexError: tuple index out of range

Syncing Managed Users

I am working on getting trakt and plex syncing again since the plugin stopped working. I got the script working and it imported all the watches and collected to trakt that I've missed in the past few months - so thats great. But, I have a separate library setup for Kids Movies, and the kids have a "managed user" that they watch their movies from. Naturally, most of those movies remain unwatched on my normal plex account, and watched on the Kids managed user.

I'd like to be able to sync the watch status from the managed user up to Trakt, so I can then sync down the watched status to my main account - so all the movies the kids have watched end up getting marked as watched on my normal account.

Can the script support this scenario?

trakt.errors.TraktInternalException: Internal Server Error

@twolaw After updating to the latest release of the master branch it is not working any more for me.

Currently on: 8be3a7e

PS C:\GitHub\PlexTraktSync> python .\main.py
Processing section Kids Movies
Traceback (most recent call last):
  File ".\main.py", line 324, in <module>
    main()
  File ".\main.py", line 305, in main
    section, trakt_watched_movies, ratings, listutil, trakt_movie_collection)
  File ".\main.py", line 65, in process_movie_section
    search = trakt.sync.search_by_id(x, id_type=provider)
  File "C:\Python37\lib\site-packages\trakt\core.py", line 472, in inner
    json_data = self._handle_request('get', url)
  File "C:\Python37\lib\site-packages\trakt\core.py", line 449, in _handle_request
    raise self.error_map[response.status_code]()
trakt.errors.TraktInternalException: Internal Server Error
PS C:\GitHub\PlexTraktSync>

last_update.txt

Is it possible to use PlexTraktSync when Plex is in a docker container?

Hi there,

I'm really interested in using PlexTraktSync but I'm not sure if I can make it work with my setup.

I have two Plex servers in two locations, one that is in a docker container and the other that is my Shield TV Pro, connected to a Raspberry Pi with an rclone mount.

Is there any for me to use PlexTraktSync, or am I out of luck?

Plex connection errors in log

I'm getting the below error in my last_update.log

2020-10-10 20:00:02,075 INFO:Starting sync Plex CraftyClown and Trakt CraftyClown
2020-10-10 20:00:05,489 INFO:Downloaded List Trakt Watchlist
2020-10-10 20:00:05,737 INFO:Downloaded List Steven Spielberg
2020-10-10 20:00:05,947 INFO:Downloaded List Oscar Winners
2020-10-10 20:00:05,972 INFO:Downloaded List Christopher Nolan
2020-10-10 20:00:05,972 INFO:Loaded Trakt lists.
2020-10-10 20:00:06,011 INFO:Plex connection error: HTTPSConnectionPool(host='redacted.plex.direct', port=32400): Max retries exceeded with url: / (Caused by NewConnectionError('<urllib3.connection.VerifiedHTTPSConnection object at 0x7f87f4b2f2e0>: Failed to establish a new connection: [Errno 111] Connection refused'))

Any idea what this error relates to?

Sync non-local Plex

I have access to friends' Plex where I'm just a user, not an admin.

Can I use this tool to sync with that plex instance? I can mark "Watched" in web UI, so, technically should be possible.

Install Script + cron on Synology NAS

Hello to the community.
My Plex Media Server is running on an unrooted Nvidia Shield Pro (2019). I've tired for a long time to install the trakt "Plex-Trakt-Scrobbler" plugin on the PMS without success.
This script seems a very good alternative to sync Plex and Trakt.

I would like to run the PlexTraktSync script on my Synology NAS.
Then I connected to my NAS in SSH, switch to Super User... At this stage, it is important to let you know that I am quite unfamiliar with SSH commands, Python... Such that all the commands I entered, well I don't really understand the meaning of that...
Any way I did :
cd ~ git clone https://github.com/Taxel/PlexTraktSync.git cd PlexTraktSync pip3 install -r requirements.txt cp .env_example .env python3 main.py

However when I entered python3 main.py, I got the following error:
root@Tonio-NAS:/volume1/GitProjects/PlexTraktSync# python3 main.py Traceback (most recent call last): File "main.py", line 11, in <module> from dotenv import load_dotenv File "/volume1/@appstore/py3k/usr/local/lib/python3.5/site-packages/dotenv/__init__.py", line 2, in <module> from .main import load_dotenv, get_key, set_key, unset_key, find_dotenv, dotenv_values File "/volume1/@appstore/py3k/usr/local/lib/python3.5/site-packages/dotenv/main.py", line 10, in <module> from typing import (Dict, Iterator, List, Match, Optional, # noqa ImportError: cannot import name 'TYPE_CHECKING'

From what I understand based on my web research, I has to do with the Python version available on my NAS. I tired to install all the python package I could find on the synology and community app store but no luck.

Did anyone succeed to install this script on a Synology NAS.
The next question will be on the way to set up a repetitive scheduled task to run automatically the script every day.

Many thanks to the community and to the script developper(s).

Odd repeated sync issue

For some reason, when I run the script automatically, it marks as watched a specific special of the show Letterkenny, this one: https://trakt.tv/shows/letterkenny/seasons/0/episodes/20

I currently have 66 plays, all accrued in the last couple of weeks. Obviously I am not this much of a fan of Letterkenny :)

My logs just say that it keeps marking it as watched on trakt. Any idea?

astimezone() cannot be applied to a naive client

When I run this sync I get this:

"Processing section Movies
Traceback (most recent call last):
File ".\main.py", line 324, in
main()
File ".\main.py", line 305, in main
section, trakt_watched_movies, ratings, listutil, trakt_movie_collection)
File ".\main.py", line 117, in process_movie_section
m.mark_as_seen(seen_date.astimezone(datetime.timezone.utc))
ValueError: astimezone() cannot be applied to a naive datetime"

Then the script stops. Any idea what these could mean?

trakt.errors.TraktInternalException: Internal Server Error

Updated to the latest git version and was able to run it once but after it fails with the following error

PS C:\GitHub\PlexTraktSync> python .\main.py
Starting sync Plex USERNAME and Trakt USERNAME
Processing section Kids Movies
Processing section Movies
Processing section TV Shows
Completed full sync in 6 min 24.3 seconds
PS C:\GitHub\PlexTraktSync> python .\main.py
Starting sync Plex USERNAME and Trakt USERNAME
Traceback (most recent call last):
  File ".\main.py", line 355, in <module>
    main()
  File ".\main.py", line 291, in main
    trakt_watched_shows = pytrakt_extensions.allwatched()
  File "C:\Python38\lib\site-packages\trakt\core.py", line 539, in inner
    json_data = self._handle_request('get', url)
  File "C:\Python38\lib\site-packages\trakt\core.py", line 516, in _handle_request
    raise self.error_map[response.status_code]()
trakt.errors.TraktInternalException: Internal Server Error
PS C:\GitHub\PlexTraktSync> python .\main.py
Starting sync Plex USERNAME and Trakt USERNAME
Traceback (most recent call last):
  File ".\main.py", line 355, in <module>
    main()
  File ".\main.py", line 291, in main
    trakt_watched_shows = pytrakt_extensions.allwatched()
  File "C:\Python38\lib\site-packages\trakt\core.py", line 539, in inner
    json_data = self._handle_request('get', url)
  File "C:\Python38\lib\site-packages\trakt\core.py", line 516, in _handle_request
    raise self.error_map[response.status_code]()
trakt.errors.TraktInternalException: Internal Server Error
PS C:\GitHub\PlexTraktSync> python .\main.py
Starting sync Plex USERNAME and Trakt USERNAME
Traceback (most recent call last):
  File ".\main.py", line 355, in <module>
    main()
  File ".\main.py", line 291, in main
    trakt_watched_shows = pytrakt_extensions.allwatched()
  File "C:\Python38\lib\site-packages\trakt\core.py", line 539, in inner
    json_data = self._handle_request('get', url)
  File "C:\Python38\lib\site-packages\trakt\core.py", line 516, in _handle_request
    raise self.error_map[response.status_code]()
trakt.errors.TraktInternalException: Internal Server Error
PS C:\GitHub\PlexTraktSync>

Debug log

2020-10-19 10:46:29,502 INFO:Starting sync Plex USERNAME and Trakt USERNAME
2020-10-19 10:46:29,502 DEBUG:get: https://api-v2launch.trakt.tv/users/me
2020-10-19 10:46:29,502 DEBUG:headers: {'Content-Type': 'application/json', 'trakt-api-version': '2', 'trakt-api-key': 'APIKEY', 'Authorization': 'Bearer BEARER'}
2020-10-19 10:46:29,502 DEBUG:method, url :: get, https://api-v2launch.trakt.tv/users/me
2020-10-19 10:46:29,502 DEBUG:Starting new HTTPS connection (1): api-v2launch.trakt.tv:443
2020-10-19 10:46:29,740 DEBUG:https://api-v2launch.trakt.tv:443 "GET /users/me HTTP/1.1" 200 94
2020-10-19 10:46:29,747 DEBUG:RESPONSE [get] (https://api-v2launch.trakt.tv/users/me): <Response [200]>
2020-10-19 10:46:29,747 DEBUG:get: https://api-v2launch.trakt.tv/users/USERNAME/watched/movies
2020-10-19 10:46:29,748 DEBUG:headers: {'Content-Type': 'application/json', 'trakt-api-version': '2', 'trakt-api-key': 'APIKEY', 'Authorization': 'Bearer BEARER'}
2020-10-19 10:46:29,748 DEBUG:method, url :: get, https://api-v2launch.trakt.tv/users/USERNAME/watched/movies
2020-10-19 10:46:29,752 DEBUG:Starting new HTTPS connection (1): api-v2launch.trakt.tv:443
2020-10-19 10:46:30,339 DEBUG:https://api-v2launch.trakt.tv:443 "GET /users/USERNAME/watched/movies HTTP/1.1" 200 51866
2020-10-19 10:46:30,346 DEBUG:RESPONSE [get] (https://api-v2launch.trakt.tv/users/USERNAME/watched/movies): <Response [200]>
2020-10-19 10:46:30,387 DEBUG:Watched movies from trakt: {139264, 7, 8, 9, 10, 8202, 14, 268305, 18, 19, 77846, 24602, 28, 29, 223262, 31, 253980, 34, 120866, 36, 149544, 96298, 43, 163882, 196651, 372779, 47, 34864, 48, 4146, 24627, 149556, 4149, 54, 4151, 56, 79928, 58, 59, 92214, 315447, 4158, 4159, 64, 77888, 92226, 66, 67, 69, 70, 92230, 92232, 72, 303178, 74, 75, 76, 36940, 243783, 213072, 2128, 80, 10322, 84, 86, 87, 88, 89, 90, 73817, 92252, 292956, 370774, 428130, 103, 6248, 34924, 239730, 209011, 157811, 313464, 120, 30842, 4219, 6268, 126, 108671, 127, 128, 130, 4225, 174212, 284803, 36998, 135, 149640, 202888, 268427, 141, 53390, 43151, 53392, 145, 4242, 16529, 30866, 149, 150, 151, 152, 239768, 190618, 387139, 157, 22685, 159, 160, 10401, 139432, 4267, 106668, 106667, 139438, 161967, 174, 176, 177, 317619, 161972, 229556, 4278, 30905, 264623, 24763, 360637, 235711, 370883, 196, 24772, 198, 377030, 57544, 313547, 6350, 12496, 212, 223444, 108758, 188631, 121049, 65754, 69850, 149723, 295134, 69855, 224, 225505, 133346, 196835, 228, 230, 231, 6375, 233, 234, 24811, 236, 4335, 239, 225520, 200946, 4339, 4340, 178423, 249, 251, 26876, 71938, 4355, 261, 190727, 51342, 139532, 273, 6418, 6419, 276, 277, 6422, 16662, 301334, 219417, 262425, 254235, 8476, 8477, 147742, 305444, 295, 4392, 219433, 57642, 57643, 300, 12589, 4398, 145711, 304, 190767, 219436, 358698, 308, 254263, 6456, 313, 12601, 119098, 57660, 57661, 268719, 57663, 8513, 371013, 326, 205127, 329, 330, 4428, 4429, 233805, 205135, 336, 337, 287057, 258387, 344, 346, 41309, 295265, 192866, 358, 166247, 2408, 59753, 76136, 51563, 14701, 4470, 268663, 4472, 268664, 2427, 100732, 6525, 254332, 383, 6527, 190847, 2434, 348923, 254340, 389, 390, 35207, 392, 65935, 400, 8594, 12693, 59799, 117143, 61849, 410, 188825, 413, 414, 415, 416, 417, 10655, 61856, 168349, 207269, 192932, 166311, 61864, 205219, 205222, 427, 61867, 4527, 432, 61873, 61874, 31151, 6580, 180661, 438, 439, 440, 442, 242107, 443, 444, 445, 2494, 448, 197050, 211394, 213443, 211396, 285120, 383430, 213447, 457, 55753, 451100, 460, 174540, 462, 25039, 464, 463, 322000, 340430, 469, 59861, 472, 4568, 475, 478, 479, 480, 6625, 481, 482, 483, 485, 486, 82405, 240099, 301543, 55786, 492, 47598, 495, 496, 47601, 98799, 8691, 149999, 503, 504, 505, 131577, 25084, 10752, 516, 517, 328196, 521, 33289, 59534, 102924, 256522, 4622, 527, 531, 532, 4629, 96790, 534, 4632, 4633, 4634, 191003, 35353, 541, 35355, 96797, 27168, 545, 546, 547, 548, 549, 55841, 270885, 338466, 553, 554, 371243, 203309, 236077, 31279, 334304, 242226, 10803, 21043, 565, 566, 8759, 119348, 193081, 242227, 4667, 276911, 178749, 168510, 4677, 589, 62030, 590, 592, 242257, 242258, 595, 293456, 597, 205398, 598, 599, 205401, 4697, 16981, 205404, 605, 4700, 16982, 16984, 16985, 610, 463454, 612, 614, 205415, 615, 6761, 616, 72297, 35436, 264821, 630, 2679, 307829, 401889, 635, 55894, 217731, 650, 651, 652, 653, 225931, 655, 172687, 438927, 295570, 659, 172692, 660, 661, 277139, 172700, 4765, 4767, 184992, 4771, 29348, 677, 4773, 273065, 4778, 293547, 41645, 6830, 4783, 297647, 283316, 4789, 98998, 305845, 697, 698, 4793, 700, 86717, 704, 705, 706, 4800, 219842, 221890, 277187, 361154, 498373, 4810, 23244, 722, 242386, 244436, 4821, 135898, 219867, 219869, 451298, 90856, 363240, 39659, 99062, 6904, 762, 174842, 90875, 2813, 23293, 23294, 201238, 769, 256765, 2819, 23299, 23300, 346883, 146185, 224010, 23308, 782, 783, 784, 785, 224015, 350990, 269076, 789, 790, 70421, 792, 351001, 793, 794, 795, 796, 4891, 353053, 39712, 357152, 13093, 2857, 54066, 9010, 170802, 9013, 226105, 4923, 123707, 41789, 226108, 4929, 52036, 6983, 6986, 396109, 127824, 2897, 217936, 851, 27476, 27477, 127828, 4951, 260951, 363355, 9055, 2913, 7010, 232291, 156518, 308070, 195432, 123759, 299887, 881, 4977, 303985, 884, 222071, 270869, 4989, 306046, 258947, 217987, 334724, 322439, 5001, 905, 906, 5003, 5004, 25482, 911, 199563, 5013, 299929, 330651, 31645, 7070, 56223, 11165, 84894, 224157, 226209, 234398, 933, 7077, 138149, 21418, 166828, 11181, 127923, 54196, 41908, 269236, 952, 154554, 7104, 5057, 5058, 27584, 35776, 5061, 3014, 5063, 158661, 5065, 222153, 293826, 385988, 222160, 50131, 7125, 981, 50134, 985, 50139, 7132, 50140, 50141, 7135, 3039, 50145, 84956, 5091, 293862, 271335, 7144, 328678, 7146, 3051, 93163, 340974, 168946, 5107, 82938, 363514, 242684, 1021, 203775, 1028, 1029, 1030, 164868, 1032, 1033, 5128, 27656, 177157, 181256, 222216, 1039, 72719, 209935, 336912, 1048, 103449, 117784, 1052, 7198, 35873, 320546, 107556, 300068, 56358, 56360, 5161, 310313, 375853, 222254, 109615, 1071, 80948, 5174, 7223, 1080, 1081, 5178, 1083, 7228, 7229, 238651, 181311, 181312, 181313, 3138, 293955, 277572, 3144, 183371, 293963, 363597, 308302, 5203, 1111, 277019, 5209, 29789, 83040, 5218, 5220, 25703, 25704, 222316, 255088, 5234, 5235, 1138, 25724, 5245, 23678, 273537, 435331, 1155, 1157, 179334, 304261, 1163, 302219, 171149, 343180, 78993, 1170, 304278, 294039, 230554, 29851, 23708, 23709, 230555, 324762, 337055, 429212, 97444, 101542, 40108, 56494, 1199, 56495, 298164, 81077, 1206, 23734, 1210, 31930, 62655, 283849, 66764, 304332, 68817, 5329, 359635, 140500, 1237, 87254, 310488, 156890, 1244, 9437, 169180, 296164, 238823, 238824, 238825, 5355, 349419, 1261, 5357, 91374, 5360, 29936, 1266, 1267, 1268, 1269, 1270, 5363, 193776, 265465, 277750, 167163, 226556, 265469, 113917, 265470, 107776, 269568, 337145, 369915, 214279, 269578, 52492, 11534, 34064, 257298, 343315, 5398, 195864, 34073, 410908, 5405, 5406, 5407, 5408, 29981, 220447, 5411, 36131, 56612, 5414, 1319, 1320, 11558, 214309, 1323, 329002, 34093, 34095, 410927, 130355, 87348, 191797, 191798, 226615, 237986, 44345, 193850, 290103, 333115, 1343, 156997, 417095, 449866, 36171, 1356, 1357, 99663, 212307, 15709, 42338, 296293, 296295, 224616, 171369, 212330, 46448, 7537, 175475, 394612, 374133, 128378, 148859, 1406, 318851, 1413, 56709, 1416, 222605, 214415, 220563, 13716, 1430, 234907, 118174, 364601, 5539, 157093, 146856, 353704, 193963, 322988, 7597, 1454, 325036, 193968, 1458, 5554, 38322, 243128, 7609, 1466, 347587, 89542, 89543, 5580, 347603, 241110, 241112, 159200, 355809, 167397, 216553, 271850, 314865, 396788, 5621, 374263, 216570, 189952, 165377, 81411, 181765, 241162, 204300, 77325, 241168, 75285, 13845, 81433, 77338, 81435, 249372, 13852, 382491, 169506, 77348, 77349, 177700, 54823, 296488, 77353, 247337, 22059, 292395, 114222, 163375, 7729, 5684, 355892, 149047, 3640, 3642, 132669, 1599, 7751, 194119, 5705, 5706, 5708, 1615, 7759, 77394, 1621, 5723, 46685, 36449, 56931, 5732, 13926, 44653, 71277, 5744, 13937, 13939, 196213, 24185, 134783, 34431, 5765, 3717, 34439, 44679, 44680, 44681, 216715, 46734, 24207, 13968, 46736, 239250, 99984, 300686, 331407, 216727, 114333, 24221, 83614, 114335, 360095, 175781, 24230, 138919, 3753, 93870, 439986, 405173, 333499, 7869, 3774, 218815, 298686, 222913, 3778, 1735, 52936, 34505, 1736, 1737, 14027, 34503, 34507, 73425, 34515, 34516, 34517, 3798, 7895, 5846, 24279, 91859, 91866, 5853, 93923, 57060, 370404, 5864, 22248, 7917, 243438, 311024, 3825, 24307, 349939, 3832, 225019, 1789, 5887, 220927, 16129, 159491, 30474, 53002, 102156, 235276, 53007, 30479, 112404, 286484, 147225, 65316, 3879, 268072, 165674, 3887, 10041, 1851, 112447, 356159, 102209, 3907, 30533, 1863, 94024, 1865, 3914, 22351, 14160, 300880, 14162, 108370, 3924, 3925, 30549, 225109, 57181, 186208, 3942, 292712, 5994, 3948, 30573, 73582, 266092, 153456, 225136, 307054, 210803, 3956, 10101, 307062, 128888, 225146, 40834, 126852, 6022, 231303, 159626, 159627, 42891, 42892, 202637, 40847, 382862, 42897, 53139, 225172, 8085, 348052, 6039, 352153, 130970, 14234, 14236, 92063, 6049, 313251, 294821, 1967, 8112, 221103, 235441, 24500, 57270, 24505, 202681, 225212, 266173, 12222, 4032, 292801, 303043, 196549, 75724, 4044, 6096, 301009, 10197, 432086, 75735, 12248, 6105, 34777, 301015, 190430, 4065, 223202, 65508, 100325, 8166, 192487, 301030, 315368, 2026, 12269, 172017, 4088, 210942}
2020-10-19 10:46:30,387 DEBUG:get: https://api-v2launch.trakt.tv/users/USERNAME/collection/movies?extended=metadata
2020-10-19 10:46:30,387 DEBUG:headers: {'Content-Type': 'application/json', 'trakt-api-version': '2', 'trakt-api-key': 'APIKEY', 'Authorization': 'Bearer BEARER'}
2020-10-19 10:46:30,388 DEBUG:method, url :: get, https://api-v2launch.trakt.tv/users/USERNAME/collection/movies?extended=metadata
2020-10-19 10:46:30,391 DEBUG:Starting new HTTPS connection (1): api-v2launch.trakt.tv:443
2020-10-19 10:46:30,624 DEBUG:https://api-v2launch.trakt.tv:443 "GET /users/USERNAME/collection/movies?extended=metadata HTTP/1.1" 200 16533
2020-10-19 10:46:30,633 DEBUG:RESPONSE [get] (https://api-v2launch.trakt.tv/users/USERNAME/collection/movies?extended=metadata): <Response [200]>
2020-10-19 10:46:30,643 DEBUG:get: https://api-v2launch.trakt.tv/sync/watched/shows
2020-10-19 10:46:30,643 DEBUG:headers: {'Content-Type': 'application/json', 'trakt-api-version': '2', 'trakt-api-key': 'APIKEY', 'Authorization': 'Bearer BEARER'}
2020-10-19 10:46:30,643 DEBUG:method, url :: get, https://api-v2launch.trakt.tv/sync/watched/shows
2020-10-19 10:46:30,645 DEBUG:Starting new HTTPS connection (1): api-v2launch.trakt.tv:443
2020-10-19 10:46:31,148 DEBUG:https://api-v2launch.trakt.tv:443 "GET /sync/watched/shows HTTP/1.1" 500 20
2020-10-19 10:46:31,154 DEBUG:RESPONSE [get] (https://api-v2launch.trakt.tv/sync/watched/shows): <Response [500]>

Error first run Plexapi

I tried to follow the install instruction and on the first run I get this:

~/PlexTraktSync$ python3 main.py

Traceback (most recent call last):
File "main.py", line 2, in
import plexapi.server
ImportError: No module named 'plexapi'

I already did pip install plexapi but I get the same error when I run python3 main.py

Episodes without air date: new Watch state each time script is run

When running the script it is setting episodes to watched in Trakt each time.
This is from shows in my Kids library.
For me I don't even want to sync this to Trakt but currently there is no way to exclude libraries when running.
Would prefer the ability to exclude a library from being synced as requested in: #22

When running the script it will add a new watched state to Trakt from Plex while I did not watch it in the time between running the scripts.
For these shows:

  • Woezel en Pip
  • Sprookjesboom

For example:
Woezel en Pip - S01E01

This is the play info from Plex:
image

This is now my Trakt history of that same episode (I've run the script 4 times).
image

2020-05-01 16:30:38,650 DEBUG:Show [Woezel en Pip (2010)]: Started sync
2020-05-01 16:30:38,650 DEBUG:get: https://api-v2launch.trakt.tv/search/tvdb/250127
2020-05-01 16:30:38,650 DEBUG:headers: {'Content-Type': 'application/json', 'trakt-api-version': '2', 'trakt-api-key': 'APIKEY', 'Authorization': 'Bearer KEY'}
2020-05-01 16:30:38,650 DEBUG:method, url :: get, https://api-v2launch.trakt.tv/search/tvdb/250127
2020-05-01 16:30:38,657 DEBUG:RESPONSE [get] (https://api-v2launch.trakt.tv/search/tvdb/250127): <Response [200]>
2020-05-01 16:30:38,657 DEBUG:get: https://api-v2launch.trakt.tv/shows/woezel-en-pip/progress/watched
2020-05-01 16:30:38,657 DEBUG:headers: {'Content-Type': 'application/json', 'trakt-api-version': '2', 'trakt-api-key': 'APIKEY', 'Authorization': 'Bearer KEY'}
2020-05-01 16:30:38,657 DEBUG:method, url :: get, https://api-v2launch.trakt.tv/shows/woezel-en-pip/progress/watched
2020-05-01 16:30:38,659 DEBUG:Starting new HTTPS connection (1): api-v2launch.trakt.tv:443
2020-05-01 16:30:39,062 DEBUG:https://api-v2launch.trakt.tv:443 "GET /shows/woezel-en-pip/progress/watched HTTP/1.1" 200 270
2020-05-01 16:30:39,067 DEBUG:RESPONSE [get] (https://api-v2launch.trakt.tv/shows/woezel-en-pip/progress/watched): <Response [200]>
2020-05-01 16:30:39,067 DEBUG:get: https://api-v2launch.trakt.tv/shows/woezel-en-pip/progress/collection
2020-05-01 16:30:39,068 DEBUG:headers: {'Content-Type': 'application/json', 'trakt-api-version': '2', 'trakt-api-key': 'APIKEY', 'Authorization': 'Bearer KEY'}
2020-05-01 16:30:39,068 DEBUG:method, url :: get, https://api-v2launch.trakt.tv/shows/woezel-en-pip/progress/collection
2020-05-01 16:30:39,071 DEBUG:Starting new HTTPS connection (1): api-v2launch.trakt.tv:443
2020-05-01 16:30:39,370 DEBUG:https://api-v2launch.trakt.tv:443 "GET /shows/woezel-en-pip/progress/collection HTTP/1.1" 200 265
2020-05-01 16:30:39,373 DEBUG:RESPONSE [get] (https://api-v2launch.trakt.tv/shows/woezel-en-pip/progress/collection): <Response [200]>
2020-05-01 16:30:39,373 DEBUG:get: https://api-v2launch.trakt.tv/shows/woezel-en-pip/seasons?extended=episodes
2020-05-01 16:30:39,373 DEBUG:headers: {'Content-Type': 'application/json', 'trakt-api-version': '2', 'trakt-api-key': 'APIKEY', 'Authorization': 'Bearer KEY'}
2020-05-01 16:30:39,373 DEBUG:method, url :: get, https://api-v2launch.trakt.tv/shows/woezel-en-pip/seasons?extended=episodes
2020-05-01 16:30:39,375 DEBUG:Starting new HTTPS connection (1): api-v2launch.trakt.tv:443
2020-05-01 16:30:40,169 DEBUG:https://api-v2launch.trakt.tv:443 "GET /shows/woezel-en-pip/seasons?extended=episodes HTTP/1.1" 200 1126
2020-05-01 16:30:40,173 DEBUG:RESPONSE [get] (https://api-v2launch.trakt.tv/shows/woezel-en-pip/seasons?extended=episodes): <Response [200]>
2020-05-01 16:30:40,175 DEBUG:Show [Woezel en Pip (2010)]: Generated LUT in 0.8026101589202881 seconds
2020-05-01 16:30:40,201 DEBUG:http://plex.home.lan:32400 "GET /library/metadata/118844/allLeaves HTTP/1.1" 200 3023
2020-05-01 16:30:40,220 DEBUG:post: https://api-v2launch.trakt.tv/sync/history
2020-05-01 16:30:40,220 DEBUG:headers: {'Content-Type': 'application/json', 'trakt-api-version': '2', 'trakt-api-key': 'APIKEY', 'Authorization': 'Bearer KEY'}
2020-05-01 16:30:40,220 DEBUG:method, url :: post, https://api-v2launch.trakt.tv/sync/history
2020-05-01 16:30:40,222 DEBUG:Starting new HTTPS connection (1): api-v2launch.trakt.tv:443
2020-05-01 16:30:40,559 DEBUG:https://api-v2launch.trakt.tv:443 "POST /sync/history HTTP/1.1" 201 100
2020-05-01 16:30:40,564 DEBUG:RESPONSE [post] (https://api-v2launch.trakt.tv/sync/history): <Response [201]>
2020-05-01 16:30:40,564 INFO:Show [Woezel en Pip (2010)]: Marked as watched on trakt: episode S01E01
2020-05-01 16:30:40,564 DEBUG:Show [Woezel en Pip (2010)]: Synced episode S01E01

The last debug log:
last_update.txt

I've looked through my Plex logs but don't see anything that corresponds with the run of the script.

JSONDecodeError when processing movies

When I run this script it does work for a while and then I get the following:

"Processing section Movies
Traceback (most recent call last):
  File "C:\PlexTraktSync\main.py", line 342, in <module>
    main()
  File "C:\PlexTraktSync\main.py", line 322, in main
    process_movie_section(
  File "C:\PlexTraktSync\main.py", line 65, in process_movie_section
    search = trakt.sync.search_by_id(x, id_type=provider)
  File "C:\Users\Monte\AppData\Local\Programs\Python\Python38-32\lib\site-packages\trakt\core.py", line 539, in inner
    json_data = self._handle_request('get', url)
  File "C:\Users\Monte\AppData\Local\Programs\Python\Python38-32\lib\site-packages\trakt\core.py", line 519, in _handle_request
    json_data = json.loads(response.content.decode('UTF-8', 'ignore'))
  File "C:\Users\Monte\AppData\Local\Programs\Python\Python38-32\lib\json\__init__.py", line 357, in loads
    return _default_decoder.decode(s)
  File "C:\Users\Monte\AppData\Local\Programs\Python\Python38-32\lib\json\decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "C:\Users\Monte\AppData\Local\Programs\Python\Python38-32\lib\json\decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)"

When this happens it stops and it never makes it to TV Shows or lists. It is making progress prior to getting this error because I see movies added to my collection in Trakt that are on my Plex server.

Anyone know what any of these errors mean, or more importantly, how to fix them?

JSONDecodeError

On my first run I got the following error. It sync'd up until a certain movie and stopped. When I ran it again it continued on. Just letting you know ;-)

Processing section Movies Traceback (most recent call last): File "main.py", line 315, in <module> main() File "main.py", line 296, in main section, trakt_watched_movies, ratings, listutil, trakt_movie_collection) File "main.py", line 80, in process_movie_section m.add_to_library() File "C:\Users\timli\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.7_qbz5n2kfra8p0\LocalCache\local-packages\Python37\site-packages\trakt\movies.py", line 261, in add_to_library add_to_collection(self) File "C:\Users\timli\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.7_qbz5n2kfra8p0\LocalCache\local-packages\Python37\site-packages\trakt\core.py", line 507, in inner json_data = self._handle_request('post', url, data=args) File "C:\Users\timli\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.7_qbz5n2kfra8p0\LocalCache\local-packages\Python37\site-packages\trakt\core.py", line 452, in _handle_request json_data = json.loads(response.content.decode('UTF-8', 'ignore')) File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.7_3.7.1776.0_x64__qbz5n2kfra8p0\lib\json\__init__.py", line 348, in loads return _default_decoder.decode(s) File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.7_3.7.1776.0_x64__qbz5n2kfra8p0\lib\json\decoder.py", line 337, in decode obj, end = self.raw_decode(s, idx=_w(s, 0).end()) File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.7_3.7.1776.0_x64__qbz5n2kfra8p0\lib\json\decoder.py", line 355, in raw_decode raise JSONDecodeError("Expecting value", s, err.value) from None json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

Bad Request 401

Been getting the following error when it comes to syncing playlists:

BadRequest (401) unauthorized http://plex.mydomain.com/library; <html><head><title>Unauthorized</title></head><body><h1>401 Unauthorized</h1></body></html>

For reference, I'm using Cloudbox install instance of Plex, etc.

Is there a setting I need to tinker with in order to get this to work?

Thanks so much!

Support for XBMCnfoMovies and XBMCnfoTV importer/agents

Hi,

I am using XBMCnfoMoviesImporter and XBMCnfoTVImporter bundles which are currently not supported - which depends on the given guid.

I have added support for that on my locale repor clone - but I am not sure if that always behaves the same. With me XBMCnfoMoviesImporter is similar to imdb and XBMCnfoTVImporter is similar to thetvdb (but that might depend on the source used to create the xbmc nfo files.

My additions are plain stupid 😁

elif 'imdb' in guid or 'xbmcnfo' in guid: (in line 42 of main.py) and
elif 'thetvdb' in guid or 'xbmcnfotv' in guid: (in line 125 of main.py)

Maybe someone has a better and more reliable idea how to add that support?!

Thanks for your effort and sharing!

can't open file 'main.py': [Errno 2] No such file or directory

User@----- MINGW64 ~
$ pipenv run python main.py
Creating a virtualenv for this project…
Pipfile: C:\Users\User\Pipfile
Using C:/Users/User/AppData/Local/Programs/Python/Python38/python.exe (3.8.1) to create virtualenv…
[=== ] Creating virtual environment...created virtual environment CPython3.8.1.final.0-64 in 15448ms
creator CPython3Windows(dest=C:\Users\User.virtualenvs\User-jBUq-HwN, clear=False, global=False)
seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=C:\Users\User\AppData\Local\pypa\virtualenv)
added seed packages: pip==20.2.2, setuptools==49.6.0, wheel==0.35.1
activators BashActivator,BatchActivator,FishActivator,PowerShellActivator,PythonActivator,XonshActivator

Successfully created virtual environment!
Virtualenv location: C:\Users\User.virtualenvs\User-jBUq-HwN
Creating a Pipfile for this project…
C:\Users\User.virtualenvs\User-jBUq-HwN\Scripts\python.exe: can't open file 'main.py': [Errno 2] No such file or directory

User@----- MINGW64 ~
$ python3 main.py
bash: python3: command not found

User@----- MINGW64 ~
$ sudo python3 main.py
bash: sudo: command not found

User@---- MINGW64 ~
$ pipenv run python main.py

C:\Users\User.virtualenvs\User-jBUq-HwN\Scripts\python.exe: can't open file 'main.py': [Errno 2] No such file or directory

User@---- MINGW64 ~

Stopped syncing TV Collection on 9/18

I have set this script to run on a schedule every night and the other day I checked it to see if it was still working. Seems to be working fine, for movies. None of my newly added TV episodes are being added to my Trakt collection. Any new movies it picks up. The last time it picked up a TV show and added it to my Trakt collection was on 9/18. There is no error message since the script seems to be running fine. It just doesn't actually add the TV episodes in Trakt. I have not changed Plex versions or anything else on the Plex server, not even rebooted since before 9/18. Any thoughts?

ValueError: astimezone() cannot be applied to a naive datetime

When I run synchronization, I get an error:

Traceback (most recent call last):
File "./main.py", line 324, in
main()
File "./main.py", line 309, in main
process_show_section(section, trakt_watched_shows)
File "./main.py", line 222, in process_show_section
eps.instance.mark_as_seen(seen_date.astimezone(datetime.timezone.utc))
ValueError: astimezone() cannot be applied to a naive datetime

Sync not considering rank

Hi,

This script was exactly what I was looking for. Nevertheless it does not consider the rank position on the list e.g. when I reorder my watchlist and sync again, the playlist in Plex does not update accordingly. I'm I doing something wrong or can this be added?

Sync cut short

For some reason the script isn't syncing all the media in TV show, it seems to finish in Movies. Is there any way to trouble shoot this further?

Does "Did not find on Trakt. Aborting" cause the script to stop processing further?

2019-11-11 15:52:00,361 INFO:Show [Marvel's Daredevil (2015)]: Finished sync
2019-11-11 15:52:00,838 INFO:Show [Marvel's Iron Fist (2017)]: Finished sync
2019-11-11 15:52:01,621 INFO:Show [Marvel's Jessica Jones (2015)]: Finished sync
2019-11-11 15:52:02,196 INFO:Show [Marvel's Luke Cage (2016)]: Finished sync
2019-11-11 15:52:02,920 INFO:Show [Marvel's Runaways (2017)]: Finished sync
2019-11-11 15:52:02,935 ERROR:Show [Marvel's Runaways (None)]: Did not find on Trakt. Aborting
2019-11-11 15:52:02,936 WARNING:Completed section sync in 14.192335367202759 s
2019-11-11 15:52:02,949 ERROR:Playlist Trakt Watchlist not found, so it could not be deleted. Actual playlists: []
2019-11-11 15:52:02,950 INFO:Updated plex watchlist
2019-11-11 15:52:02,950 INFO:Completed full sync in 64.80218029022217 seconds

Watched items

Hi
I am getting random missed watched seasons and episodes on Plex.
For example, The 100, I have watched all seasons which shows in trakt but in Plex the last season is marked unwatched.
There are also some shows with episodes not marked watched on Plex.
I have ran the script a few times but not seeing any errors.

improve get_env_data.py

Why do you have trakt.APPLICATION_ID = '65370' ?
It is only needed for pin auth method but you choose oauth method.

Then I have a suggestion : could get_env_data.py create .env file and write both TOKEN in it.
So the user would not have to copy-paste values, it would be automatic.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.