Git Product home page Git Product logo

jellyplex-watched's Introduction

JellyPlex-Watched

Codacy Badge

Sync watched between jellyfin, plex and emby locally

Description

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

Features

Plex

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

Jellyfin

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

Emby

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

Configuration

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

Installation

Baremetal

  • Setup virtualenv of your choice

  • Install dependencies

      pip install -r requirements.txt
  • Create a .env file similar to .env.sample, uncomment whitelist and blacklist if needed, fill in baseurls and tokens

  • Run

    python main.py

Docker

  • Build docker image

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

    docker pull luigi311/jellyplex-watched:latest

With variables

  • Run

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

With .env

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

  • Run

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

Troubleshooting/Issues

  • Jellyfin

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

    • Do not use quotes around variables in docker compose

Contributing

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

License

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

jellyplex-watched's People

Contributors

agustinmorantes avatar dependabot[bot] avatar janw avatar jchris246 avatar jianglai avatar lgtm-migrator avatar luigi311 avatar neofright avatar nicba1010 avatar remos 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

jellyplex-watched's Issues

[QUESTION] DryRun - Looping in 3600.0

I just came across your tool to sync between Plex and Jellyfin(and Emby is on the list I see). First of all awesome, thank you for sharing this!

I do have a question, I am doing a dry run and using docker/podman with the example you gave
docker run --rm -it -v "$(pwd)/.env:/app/.env" luigi311/jellyplex-watched:latest
Now I see a bunch of output about "Dryrun" in it and shows the items it would change but now it's stuck at "Looping in 3600.0". I'm guess it will actually exit at some point until it's done what it's currently doing so I'm waiting for that before I do a real run. So I would guess it would depend on how big your library is and how many users you are syncing for, but what does that indicate where it's currently stuck at during execution?

Reasoning behind using user.title

Hi,

a question. Why are user titles used instead of usernames to identify plex users? Aren't usernames much less likely to change?

[bug] Can't dry run sync, `Unexpected mimetype: text/html`

Trying to test syncing with a dry run first, but the docker container keeps throwing python errors about not being able to connect to the Jellyfin Server. The server running Docker is not the same server as the one running Plex and Jellyfin, but it can connect using other docker containers without issue. Below is my sanitized .env file and the error.

.env
## Do not mark any shows/movies as played and instead just output to log if they would of been marked.
DRYRUN = "True"
## Additional logging information
DEBUG = "True"
## Debugging level, "info" is default, "debug" is more verbose
DEBUG_LEVEL = "debug"
## How often to run the script in seconds
SLEEP_DURATION = "3600"
## Log file where all output will be written to
LOGFILE = "log.log"
## Map usernames between plex and jellyfin in the event that they are different, order does not matter
#USER_MAPPING = { "testuser2": "testuser3" }
## Map libraries between plex and jellyfin in the even that they are different, order does not matter
#LIBRARY_MAPPING = { "Shows": "TV Shows" }


## Recommended to use token as it is faster to connect as it is direct to the server instead of going through the plex servers
## URL of the plex server, use hostname or IP address if the hostname is not resolving correctly
## Comma seperated list for multiple servers
PLEX_BASEURL = "http://10.0.0.11:32400"
## Plex token https://support.plex.tv/articles/204059436-finding-an-authentication-token-x-plex-token/
PLEX_TOKEN = "*****"
## If not using plex token then use username and password of the server admin along with the servername
#PLEX_USERNAME = ""
#PLEX_PASSWORD = ""
#PLEX_SERVERNAME = "Plex Server"
## Skip hostname validation for ssl certificates.
SSL_BYPASS = "True"

## Jellyfin server URL, use hostname or IP address if the hostname is not resolving correctly
## Comma seperated list for multiple servers
JELLYFIN_BASEURL = "http://10.0.0.11:8096/"
## Jellyfin api token, created manually by logging in to the jellyfin server admin dashboard and creating an api key
JELLYFIN_TOKEN = "*****"


## Blacklisting/Whitelisting libraries, library types such as Movies/TV Shows, and users. Mappings apply so if the mapping for the user or library exist then both will be excluded.
#BLACKLIST_LIBRARY = ""
#WHITELIST_LIBRARY = ""
#BLACKLIST_LIBRARY_TYPE = "" 
#WHITELIST_LIBRARY_TYPE = ""
#BLACKLIST_USERS = ""
#WHITELIST_USERS = "testuser1,testuser2"
log.log
[INFO]: Dryrun: True

[INFO]: User Mapping: {'user test': 'user test2'}

[INFO]: Library Mapping: {'Shows Test': 'TV Shows Test'}

[INFO]: Creating (black/white)lists

[INFO]: Blacklist Library: []

[INFO]: Whitelist Library: []

[INFO]: Blacklist Library Type: []

[INFO]: Whitelist Library Type: []

[INFO]: Blacklist Users: []

[INFO]: Whitelist Users: []

[INFO]: Creating server connections

[ERROR]: Jellyfin: Query failed 0, message='Attempt to decode JSON with unexpected mimetype: text/html', url=URL('http://10.0.0.11:8096/jellyfin/web/index.html')

[ERROR]: Jellyfin: Get users failed 0, message='Attempt to decode JSON with unexpected mimetype: text/html', url=URL('http://10.0.0.11:8096/jellyfin/web/index.html')

[ERROR]: 0, message='Attempt to decode JSON with unexpected mimetype: text/html', url=URL('http://10.0.0.11:8096/jellyfin/web/index.html')

[ERROR]: Traceback (most recent call last):

  File "/app/src/jellyfin.py", line 41, in query

    results = await response.json()

              ^^^^^^^^^^^^^^^^^^^^^

  File "/usr/local/lib/python3.11/site-packages/aiohttp/client_reqrep.py", line 1104, in json

    raise ContentTypeError(

aiohttp.client_exceptions.ContentTypeError: 0, message='Attempt to decode JSON with unexpected mimetype: text/html', url=URL('http://10.0.0.11:8096/jellyfin/web/index.html')

During handling of the above exception, another exception occurred:

Traceback (most recent call last):

  File "/app/src/jellyfin.py", line 64, in get_users

    response = await self.query(query_string, "get", session)

               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  File "/app/src/jellyfin.py", line 56, in query

    raise Exception(e)

Exception: 0, message='Attempt to decode JSON with unexpected mimetype: text/html', url=URL('http://10.0.0.11:8096/jellyfin/web/index.html')

During handling of the above exception, another exception occurred:

Traceback (most recent call last):

  File "/app/src/main.py", line 639, in main

    main_loop()

  File "/app/src/main.py", line 561, in main_loop

    servers = generate_server_connections()

              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  File "/app/src/main.py", line 506, in generate_server_connections

    Jellyfin(baseurl=baseurl.strip(), token=jellyfin_token[i].strip()),

    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  File "/app/src/jellyfin.py", line 22, in __init__

    self.users = asyncio.run(self.get_users())

                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  File "/usr/local/lib/python3.11/asyncio/runners.py", line 190, in run

    return runner.run(main)

           ^^^^^^^^^^^^^^^^

  File "/usr/local/lib/python3.11/asyncio/runners.py", line 118, in run

    return self._loop.run_until_complete(task)

           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  File "/usr/local/lib/python3.11/asyncio/base_events.py", line 650, in run_until_complete

    return future.result()

           ^^^^^^^^^^^^^^^

  File "/app/src/jellyfin.py", line 74, in get_users

    raise Exception(e)

Exception: 0, message='Attempt to decode JSON with unexpected mimetype: text/html', url=URL('http://10.0.0.11:8096/jellyfin/web/index.html')

Retrying in 3600.0

Error getting watched TV Shows in Jellyfin

This is the log in debug true with debug level set to debug not sure what exactly is going on.
I'm running in a docker container

today at 06:23:10Server 1: plex <src.plex.Plex object at 0x1480727e21a0>
today at 06:23:10Server 2: jellyfin <src.jellyfin.Jellyfin object at 0x148071ef5000>
today at 06:23:10Plex: Generating watched for deanosim in library Movies
today at 06:23:10Plex: Generating watched for deanosim in library Anime
today at 06:23:10Plex: Generating watched for deanosim in library TV Shows
today at 06:24:21Jellyfin: Generating watched for deanosim in library TV Shows
today at 06:24:21Jellyfin: Generating watched for deanosim in library Movies
today at 06:24:21Jellyfin: Generating watched for deanosim in library Anime
today at 06:27:53[ERROR]: Jellyfin: Failed to get watched for deanosim in library TV Shows, Error: 'Path'
today at 06:27:53[ERROR]: Jellyfin: Failed to get watched, Error: 'Exception' object has no attribute 'items'
today at 06:27:53[ERROR]: 'Exception' object has no attribute 'items'
today at 06:27:53[ERROR]: Traceback (most recent call last):
today at 06:27:53  File "/app/src/jellyfin.py", line 357, in get_watched
today at 06:27:53    user_watched_temp = combine_watched_dicts(user_watched)
today at 06:27:53  File "/app/src/functions.py", line 161, in combine_watched_dicts
today at 06:27:53    for key, value in single_dict.items():
today at 06:27:53AttributeError: 'Exception' object has no attribute 'items'
today at 06:27:53
today at 06:27:53During handling of the above exception, another exception occurred:
today at 06:27:53
today at 06:27:53Traceback (most recent call last):
today at 06:27:53  File "/app/src/main.py", line 639, in main
today at 06:27:53    main_loop()
today at 06:27:53  File "/app/src/main.py", line 590, in main_loop
today at 06:27:53    server_2_watched = asyncio.run(
today at 06:27:53  File "/usr/local/lib/python3.10/asyncio/runners.py", line 44, in run
today at 06:27:53    return loop.run_until_complete(main)
today at 06:27:53  File "/usr/local/lib/python3.10/asyncio/base_events.py", line 646, in run_until_complete
today at 06:27:53    return future.result()
today at 06:27:53  File "/app/src/jellyfin.py", line 366, in get_watched
today at 06:27:53    raise Exception(e)
today at 06:27:53Exception: 'Exception' object has no attribute 'items'
today at 06:27:53
today at 06:27:53Retrying in 3600.0

I could wonder if the debug level isn't working for some reason.

[Feature Request] Github actions changes

Is your feature request related to a problem? Please describe.

  • Integration testing
  • Scheduled releases

Describe the solution you'd like
We can create a integration step where it will run a dryrun on my plex and jellyfin servers with 2 test users to validate that it is outputting what i would expect it to output. We might need to add in a new logging variable so it only spits out things like what it is marking so we can do a comparison with what we would expect without all the other fluff since it will just complicate the validation. We might need to add in a python script for actually testing and checking that the items that should be in the log are there. The ordering might be random due to the marking being threaded/async so we can not do a simple text comparison and would instead have to be for line checks and only be successful if all the lines are in it.

We might also want to do weekly releases so the base image can be updated regularly even if there are no commits to the project to prevent any security issues in the images lingering.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

[BUG] Error updating watched for

Describe the bug
I'm experiencing an issue with the script (running on my Ubuntu 22.04 VM where I host both plex and jellyfin right now). I've only whitelisted my own username and most tv shows and anime seems to work but none of my movies watched status is synced and I'm getting the following error.

Logs

Plex: Generating watched for tscibilia in library Anime
Plex: Generating watched for tscibilia in library Movies
Plex: Generating watched for tscibilia in library TV Shows
Jellyfin: Generating watched for tscibilia in library Anime
...
Marked Sailor Moon Season 1 Episode 36 Usagi's Confusion: Is Tuxedo Mask Evil? as watched for tscibilia in Anime for Jellyfin
Marked Sailor Moon Season 1 Episode 37 Let's Become a Princess: Usagi's Bizarre Training as watched for tscibilia in Anime for Jellyfin
Marked Sailor Moon Season 1 Episode 38 The Snow, the Mountains, Friendship and Monsters as watched for tscibilia in Anime for Jellyfin
[ERROR]: Jellyfin: Query get /Users/d41fe7314bad48f4aad689213aaf3ffd/Items?SortBy=SortName&SortOrder=Ascending&Recursive=True&ParentId=767bffe4f11c93ef34b805451a696a4e&isPlayed=false&Fields=ItemCounts,ProviderIds,Path&IncludeItemTypes=Series
Results None

[ERROR]: Jellyfin: Query get /Users/d41fe7314bad48f4aad689213aaf3ffd/Items?SortBy=SortName&SortOrder=Ascending&Recursive=True&ParentId=f137a2dd21bbc1b99aa5c0f6bf02a805&isPlayed=false&Fields=ItemCounts,ProviderIds,MediaSources&IncludeItemTypes=Movie
Results None

[ERROR]: Jellyfin: Error updating watched for tscibilia in library TV Shows, 
[ERROR]: Traceback (most recent call last):
  File "/home/plex/JellyPlex-Watched/src/jellyfin.py", line 94, in query
    async with session.get(
  File "/home/plex/JellyPlex-Watched/venv/lib/python3.10/site-packages/aiohttp/client.py", line 1141, in __aenter__
    self._resp = await self._coro
  File "/home/plex/JellyPlex-Watched/venv/lib/python3.10/site-packages/aiohttp/client.py", line 560, in _request
    await resp.start(conn)
  File "/home/plex/JellyPlex-Watched/venv/lib/python3.10/site-packages/aiohttp/client_reqrep.py", line 894, in start
    with self._timer:
  File "/home/plex/JellyPlex-Watched/venv/lib/python3.10/site-packages/aiohttp/helpers.py", line 721, in __exit__
    raise asyncio.TimeoutError from None
asyncio.exceptions.TimeoutError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/plex/JellyPlex-Watched/src/jellyfin.py", line 632, in update_user_watched
    jellyfin_search = await self.query(
  File "/home/plex/JellyPlex-Watched/src/jellyfin.py", line 124, in query
    raise Exception(e)
Exception

[ERROR]: Jellyfin: Error updating watched for tscibilia in library Movies, 
[ERROR]: Traceback (most recent call last):
  File "/home/plex/JellyPlex-Watched/src/jellyfin.py", line 94, in query
    async with session.get(
  File "/home/plex/JellyPlex-Watched/venv/lib/python3.10/site-packages/aiohttp/client.py", line 1141, in __aenter__
    self._resp = await self._coro
  File "/home/plex/JellyPlex-Watched/venv/lib/python3.10/site-packages/aiohttp/client.py", line 560, in _request
    await resp.start(conn)
  File "/home/plex/JellyPlex-Watched/venv/lib/python3.10/site-packages/aiohttp/client_reqrep.py", line 894, in start
    with self._timer:
  File "/home/plex/JellyPlex-Watched/venv/lib/python3.10/site-packages/aiohttp/helpers.py", line 721, in __exit__
    raise asyncio.TimeoutError from None
asyncio.exceptions.TimeoutError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/plex/JellyPlex-Watched/src/jellyfin.py", line 548, in update_user_watched
    jellyfin_search = await self.query(
  File "/home/plex/JellyPlex-Watched/src/jellyfin.py", line 124, in query
    raise Exception(e)
Exception

Marked Sailor Moon Season 1 Episode 39 Paired with a Monster: Mako, the Ice Skating Queen as watched for tscibilia in Anime for Jellyfin
Marked Sailor Moon Season 1 Episode 40 The Legendary Lake Yokai: The Bond of Usagi's Family as watched for tscibilia in Anime for Jellyfin
...
Average time: 960.8917050190503
Looping in 3600.0

Type:

  • Docker
  • Native

Additional context
I didn't include the entire log, please let me know if you need additional information.

Allow n many jellyfin/plex servers

Allow the user to specify multiple jellyfin or plex servers and use all of those to sync.

Ex 2 jellyfin servers to sync across each other
Ex 2 jellyfin servers and 2 plex servers to sync from each server to the other 3 servers.

Everything in main function needs to be redesigned to handle this as all the functions are already able to handle any combination of two servers. Remove duplicate function calls in main will need the most redesign.

[ERROR]: No users found for server 1 plex

I am running your docker template via unraid and get the following error, I've removed personal names etc for obvious reasons.

[INFO]: Dryrun: True
[INFO]: Creating (black/white)lists
[INFO]: Blacklist Library: []
[INFO]: Blacklist Library Type: []
[INFO]: Blacklist Users: []
[INFO]: Whitelist Library: []
[INFO]: Whitelist Library Type: []
[INFO]: Whitelist Users: []
[INFO]: Creating server connections
[INFO]: Creating users list
[INFO]: User list that exist on both servers {}
[INFO]: Filtered user list {}
[ERROR]: No users found for server 1 plex, users found {}, filtered users {}, server 1 users [<MyPlexUser:123456:Guest>, <MyPlexUser:123456:User1>, <MyPlexAccount:123456:User2>]
[ERROR]: Traceback (most recent call last):
  File "/app/src/main.py", line 374, in main
    main_loop()
  File "/app/src/main.py", line 301, in main_loop
    server_1_users, server_2_users = setup_users(
                                     ^^^^^^^^^^^^
  File "/app/src/main.py", line 43, in setup_users
    raise Exception(
Exception: No users found for server 1 plex, users found {}, filtered users {}, server 1 users [<MyPlexUser:123456:Guest>, <MyPlexUser:123456:User1>, <MyPlexUser:123456:User2>]

Not sure why it says No users found for server 1 plex but then proceeds to list all the users anyway?

The above is running the template with just URLs and Tokens added, no user mappings, if I add user mappings as so...

-e 'USER_MAPPING'='{ "plex-user": "jelly-user" }'

It seems to accept the user mapping but I just get the same error message...any ideas?

To confirm also, container is set to DEBUG, see below.

image

Let me know if you need anything else :)

[BUG] Timeouts may be too low in `aiohttp.ClientSession`

Describe the bug
Timeouts are too low for large libraries.

To Reproduce
Steps to reproduce the behavior:
Run on a rather large library.

Expected behavior
The application moves watch history in its entirety, has a configurable timeout for aiohttp.ClientSession.

Logs
If applicable, add logs to help explain your problem ideally with DEBUG set to true, be sure to remove sensitive information

Jellyfin: Generating watched for username in library TV (Sports)
[ERROR]: Jellyfin: Query get /Users/ID/Items?ParentId=ID&isPlaceHolder=false&IncludeItemTypes=Series&Recursive=True&Fields=ProviderIds,Path,RecursiveItemCount
Results None

[ERROR]: Jellyfin: Failed to get watched for username in library TV, Error: 
[ERROR]: Traceback (most recent call last):
  File "/opt/jf-watched/JellyPlex-Watched/src/jellyfin.py", line 96, in query
    async with session.get(
  File "/opt/jf-watched/.venv/lib/python3.11/site-packages/aiohttp/client.py", line 1141, in __aenter__
    self._resp = await self._coro
                 ^^^^^^^^^^^^^^^^
  File "/opt/jf-watched/.venv/lib/python3.11/site-packages/aiohttp/client.py", line 560, in _request
    await resp.start(conn)
  File "/opt/jf-watched/.venv/lib/python3.11/site-packages/aiohttp/client_reqrep.py", line 894, in start
    with self._timer:
  File "/opt/jf-watched/.venv/lib/python3.11/site-packages/aiohttp/helpers.py", line 721, in __exit__
    raise asyncio.TimeoutError from None
TimeoutError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/opt/jf-watched/JellyPlex-Watched/src/jellyfin.py", line 221, in get_user_library_watched
    watched_shows = await self.query(
                    ^^^^^^^^^^^^^^^^^
  File "/opt/jf-watched/JellyPlex-Watched/src/jellyfin.py", line 126, in query
    raise Exception(e)
Exception

[ERROR]: Jellyfin: Query get /Users/ID/Items?ParentId=ID&isPlaceHolder=false&IncludeItemTypes=Series&Recursive=True&Fields=ProviderIds,Path,RecursiveItemCount
Results None

[ERROR]: Jellyfin: Failed to get watched for username in library TV (Foreign), Error: 
[ERROR]: Traceback (most recent call last):
  File "/opt/jf-watched/JellyPlex-Watched/src/jellyfin.py", line 96, in query
    async with session.get(
  File "/opt/jf-watched/.venv/lib/python3.11/site-packages/aiohttp/client.py", line 1141, in __aenter__
    self._resp = await self._coro
                 ^^^^^^^^^^^^^^^^
  File "/opt/jf-watched/.venv/lib/python3.11/site-packages/aiohttp/client.py", line 560, in _request
    await resp.start(conn)
  File "/opt/jf-watched/.venv/lib/python3.11/site-packages/aiohttp/client_reqrep.py", line 894, in start
    with self._timer:
  File "/opt/jf-watched/.venv/lib/python3.11/site-packages/aiohttp/helpers.py", line 721, in __exit__
    raise asyncio.TimeoutError from None
TimeoutError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/opt/jf-watched/JellyPlex-Watched/src/jellyfin.py", line 221, in get_user_library_watched
    watched_shows = await self.query(
                    ^^^^^^^^^^^^^^^^^
  File "/opt/jf-watched/JellyPlex-Watched/src/jellyfin.py", line 126, in query
    raise Exception(e)
Exception

[ERROR]: Jellyfin: Query get /Users/ID/Items?ParentId=ID&isPlaceHolder=false&IncludeItemTypes=Series&Recursive=True&Fields=ProviderIds,Path,RecursiveItemCount
Results None

[ERROR]: Jellyfin: Failed to get watched for username in library TV, Error: 
[ERROR]: Traceback (most recent call last):
  File "/opt/jf-watched/JellyPlex-Watched/src/jellyfin.py", line 96, in query
    async with session.get(
  File "/opt/jf-watched/.venv/lib/python3.11/site-packages/aiohttp/client.py", line 1141, in __aenter__
    self._resp = await self._coro
                 ^^^^^^^^^^^^^^^^
  File "/opt/jf-watched/.venv/lib/python3.11/site-packages/aiohttp/client.py", line 560, in _request
    await resp.start(conn)
  File "/opt/jf-watched/.venv/lib/python3.11/site-packages/aiohttp/client_reqrep.py", line 894, in start
    with self._timer:
  File "/opt/jf-watched/.venv/lib/python3.11/site-packages/aiohttp/helpers.py", line 721, in __exit__
    raise asyncio.TimeoutError from None
TimeoutError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/opt/jf-watched/JellyPlex-Watched/src/jellyfin.py", line 221, in get_user_library_watched
    watched_shows = await self.query(
                    ^^^^^^^^^^^^^^^^^
  File "/opt/jf-watched/JellyPlex-Watched/src/jellyfin.py", line 126, in query
    raise Exception(e)
Exception

Type:

  • Docker
  • Native

Additional context
Add any other context about the problem here.

[BUG] [ERROR]: Jellyfin: Error updating watched

Describe the bug
The script breaks after some minutes with the error message shown.

To Reproduce
Steps to reproduce the behavior:
Every run.

Expected behavior
A clear and concise description of what you expected to happen.

Logs
[ERROR]: Jellyfin: Error updating watched for peppo-online in library 4. KIDS: Shows, 'imdb'
[ERROR]: Traceback (most recent call last):
File "E:\JellyPlex-Watched-5.0.0\src\jellyfin.py", line 741, in update_user_watched
in episode[
KeyError: 'imdb'

Type:

  • [x ] Docker

[ERROR]: Jellyfin: Error updating watched for peppo-online in library 4. KIDS: Shows, 'imdb'
[ERROR]: Traceback (most recent call last):
File "E:\JellyPlex-Watched-5.0.0\src\jellyfin.py", line 741, in update_user_watched
in episode[
KeyError: 'imdb'
Additional context
Add any other context about the problem here.

I didn't find another issue report with the same error, that's why I posted it.
It's an unraid docker hosted plex to jellyfin.

TV Shows syncs, Movies do not

Attempting to sync from Jellyfin to Plex and have no issues with TV Shows but the script seems to ignore the Movies sync. I've run a number of variations including explicitly whitelisting Movies and doing a manual mapping of the libraries (Movies:Movies) to no avail. Are there any other adjustments I should be looking at or other ways to debug?

[INFO]: Dryrun: False
[INFO]: User Mapping: {'usernameredacted': 'usernameredacted'}
[INFO]: Library Mapping: {'movies': 'Movies'}
[INFO]: Creating (black/white)lists
[INFO]: Blacklist Library: []
[INFO]: Whitelist Library: ['Movies', 'Movies']
[INFO]: Blacklist Library Type: ['tv shows']
[INFO]: Whitelist Library Type: []
[INFO]: Blacklist Users: []
[INFO]: Whitelist Users: []
[INFO]: Creating server connections
[INFO]: Creating users list
Server 1: plex <src.plex.Plex object at 0x7f32feb76050>
Server 2: jellyfin <src.jellyfin.Jellyfin object at 0x7f32feb75e10>
[INFO]: User list that exist on both servers {'usernameredacted': 'usernameredacted'}
[INFO]: Filtered user list {'usernameredacted': 'usernameredacted'}
[INFO]: Server 1 users: [<MyPlexAccount:usernameredacted:usernameredacted>]
[INFO]: Server 2 users: {'usernameredacted': 'usernameredacted'}
[INFO]: Creating watched lists
[INFO]: Plex: Skipping library TV Shows is not whitelist_library
Plex: Generating watched for usernameredacted in library Movies
[INFO]: Finished creating watched list server 1
[INFO]: Jellyfin: Skipping library Shows is not whitelist_library
[INFO]: Jellyfin: Skipping library Collections is not whitelist_library
Jellyfin: Generating watched for usernameredacted in library Movies
[INFO]: Finished creating watched list server 2
[INFO]: Cleaning Server 1 Watched
[INFO]: library Movies and Movies not found in watched list 2
[INFO]: Removing Movies from usernameredacted because it is empty
[INFO]: Removing usernameredacted from watched list 1 because it is empty
[INFO]: Cleaning Server 2 Watched
[INFO]: Removing usernameredacted from watched list 1 because it is empty
[INFO]: server 1 watched that needs to be synced to server 2:
{}
[INFO]: server 2 watched that needs to be synced to server 1:
{}
Average time: 1.2631806570570916
Looping in 3600.

docker run --rm -it -e LOGFILE="log.log" -e LIBRARY_MAPPING='{ "movies": "Movies" }' -e WHITELIST_LIBRARY="Movies" -e BLACKLIST_LIBRARY_TYPE="TV Shows" -e USER_MAPPING='{ "redacted": "redacted" }' -e SLEEP_DURATION="3600" -e DEBUG_LEVEL="info" -e DRYRUN="False" -e PLEX_TOKEN="redacted" -e PLEX_BASEURL="http://10.10.0.128:32400" -e JELLYFIN_TOKEN="redacted" -e JELLYFIN_BASEURL="https://jellyfin.redacted.com" luigi311/jellyplex-watched:latest

Config not finding User ID 1

I have 3 users in both plex and Jellyfin.

Names/ID numbers in the logs have been changed for privacy.

GET https://plexurl/accounts returns this in PostMan:

<?xml version="1.0" encoding="UTF-8"?>
<MediaContainer size="16" identifier="com.plexapp.system.accounts">
    <Account id="0" key="/accounts/0" name="" defaultAudioLanguage="en" autoSelectAudio="1" defaultSubtitleLanguage="en" subtitleMode="1" thumb="" />
<Account id="1" key="/accounts/1" name="YYY1" defaultAudioLanguage="en" autoSelectAudio="1" defaultSubtitleLanguage="en" subtitleMode="0" thumb="" />
<Account id="1234" key="/accounts/1234" name="XXX1" defaultAudioLanguage="en" autoSelectAudio="1" defaultSubtitleLanguage="en" subtitleMode="1" thumb="" />
<Account id="2345" key="/accounts/2345" name="ZZZ" defaultAudioLanguage="en" autoSelectAudio="1" defaultSubtitleLanguage="en" subtitleMode="1" thumb="" />

Linked users with an ID other than 1 are being returned and found according to the logs.

LOG:

[INFO]: User list that exist on both servers {'XXX1': 'XXX2', 'ZZZ`: 'ZZZ', 'YYY1': 'YYY2'}
[INFO]: Filtered user list {'XXX': 'amber', 'XXX1': 'XXX2', 'YYY1': 'YYY2'}
[INFO]: Server 1 users: [<MyPlexUser:1234:XXX1>, <MyPlexUser:2345:YYY1>]`
...
`[ERROR]: Plex: Failed to update watched, Error: 'str' object has no attribute 'get_token'
[ERROR]: 'str' object has no attribute 'get_token'
[ERROR]: Traceback (most recent call last):
  File "/app/src/plex.py", line 401, in update_watched
    self.plex._baseurl, user.get_token(self.plex.machineIdentifier)
                        ^^^^^^^^^^^^^^
AttributeError: 'str' object has no attribute 'get_token'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "/app/src/main.py", line 396, in main
    main_loop()
  File "/app/src/main.py", line 373, in main_loop
    update_server_watched(
  File "/app/src/main.py", line 256, in update_server_watched
    server_connection[1].update_watched(
  File "/app/src/plex.py", line 451, in update_watched
    raise Exception(e)
Exception: 'str' object has no attribute 'get_token'
Retrying in 3600.0

[SOLVED] Plex wouldn't sync with Jellyfin

I ran into a problem where Plex and Jellyfin wouldn't sync because I had grouped together my Anime and TV folder in Jellyfin under User > Settings > Home > Library Folders. Once they where separated it would sync without a problem.
Just thought I would let people know if they run into the same problem as I did

TV Shows not Syncing

Hi :)

I setup the script yesterday through Docker and I've noticed that Movies are working fine but, TV Shows are not syncing. There is the following messages present in the logs:

[INFO]: Jellyfin: Skipping Library TV Shows not a single type: set()
[INFO]: TV shows and None not found in watched list 2
[INFO]: Generating show_output_dict failed, skipping
[INFO]: Generating episode_output_dict failed, skipping

I tried to look for any solution in the closed issues but unfortunately was not able to find anything.

I am running the latest docker container.

Please let me know if you require any further information. Any help is appreciated

Thanks :)

[Feature Request] - Sync unplayed status

Is your feature request related to a problem? Please describe.
No my feature request is not related to a problem

Describe the solution you'd like
I would like to the sync also to be able to sync unplayed status, so that if you mark a movie to status unplayed on Plex it will also sync it to unplayed status on Jellyfin/Emby and vice-versa.

Describe alternatives you've considered
I haven't considered any alternative solutions because I only found one other script that does the same and yours is easier to user and has multi-user support.

Additional context
I just came across this script today and I just wanted to say thank your the work you do on this script!! I also wanted to let you know I run Plex, Emby and Jellfyin. I also tested the sync from Plex to Emby since issue 56 the person hadn't test it yet since they hadn't responded since their last reply. I just wanted to let you know the watched sync play status from Plex to Emby and vice-versa works as well even though it's not officially supported yet.

[BUG] JellyPlex does not complete

Describe the bug
Jellyplex does not complete the process. It marks movies successfully and starts on the TV library. It gets through A-D in the list and then errors out. The same error with debug and info log levels.

[ERROR]: Traceback (most recent call last): [ERROR]: Jellyfin: Error updating watched for johimself in library TV, 'imdb' File "/app/src/jellyfin.py", line 739, in update_user_watched in episode[ ^^^^^^^^ KeyError: 'imdb' Average time: 87.78911246974894 Looping in 3600.0

To Reproduce
Steps to reproduce the behavior:

  1. Start container
  2. View logs

Expected behavior
Expect the process to complete for all items in the library

Logs
[ERROR]: Traceback (most recent call last): [ERROR]: Jellyfin: Error updating watched for johimself in library TV, 'imdb' File "/app/src/jellyfin.py", line 739, in update_user_watched in episode[ ^^^^^^^^ KeyError: 'imdb' Average time: 87.78911246974894 Looping in 3600.0

Type:

  • Docker
  • Native

Sync progress to Jellyfin?

First of all, thank you for this project. It is exactly what I have been looking for.

I'm curious on how watch progress sync works with Jellyfin. I know in the README file the "Sync inprogross" checkbox is unchecked for Jellyfin. I did some experiments and what I observed is that Jellyfin watch progress (e.g. minutes watched) syncs to Plex, but not vice versa. Is that working as intended? If so, are there plans to allow two-way progress sync works between Jellyfin and Plex?

Also, as far as the watched/unwatched status goes, it looks like the app itself does not keep track of the latest status, but rather only syncs whichever is the furthest to other servers. So for example if I had finished watching a movie on Plex, it will sync to Jellyfin and both will be marked as watched. But if I mark the same movie as unwatched again on Plex, the next the app runs, it does not know that the "unwatched" status is the latest, but rather thinks the "watched" status on Jellyfin is the furthest, so it syncs the status on Plex back to "watched". Is that correct?

[BUG]Plex: Skipping show <show> as it is not in mark list for <user>

Describe the bug
I'm trying to sync from jellyfin to Plex, logs say that a watched episode to be synced is found but plex isn't updated.
Logs say "[DEBUG]: Plex: Skipping episode as it is not in mark list for userplex"

To Reproduce
Steps to reproduce the behavior:
configured container with following .env

DRYRUN = "False"
DEBUG = "True"
DEBUG_LEVEL = "debug"
RUN_ONLY_ONCE = "False"
SLEEP_DURATION = "3600"
LOGFILE = "log.log"
USER_MAPPING = { "userjelly": "userplex" }
BLACKLIST_LIBRARY = "Film,Musica,Foto,Musica Classica,Concerti"
WHITELIST_LIBRARY = ""
BLACKLIST_LIBRARY_TYPE = ""
WHITELIST_LIBRARY_TYPE = ""
BLACKLIST_USERS = "xxx"
WHITELIST_USERS = ""
PLEX_BASEURL = "http://plexip:32400"
PLEX_TOKEN = "plextoken"
SSL_BYPASS = "True"
SYNC_FROM_JELLYFIN_TO_PLEX = "True"
JELLYFIN_BASEURL = "http://jellyip:8096"
JELLYFIN_TOKEN = "jellytoken"

Expected behavior
Episode watched status to be synced in plex

Logs
[INFO]: server 2 watched that needs to be synced to server 1:
{'userjelly': {'Serie TV': {frozenset({('title', 'Omicidio a Easttown'), ('locations', ('Mare of Easttown (2021)',)), ('tvdb', '370112'), ('imdb', 'tt10155688'), ('tmdb', '115004')}): {'Season 1': [{'tvdb': '8197081', 'imdb': 'tt11033898', 'title': 'Miss Lady Hawk in persona', 'locations': (), 'status': {'completed': True, 'time': 0}}]}}}}
[INFO]: Plex: Updating watched for userplex in library Serie TV
[INFO]: Generating movies_output_dict failed, skipping
[INFO]: Plex: mark list
Shows: {'locations': [('Mare of Easttown (2021)',)], 'tvdb': ['370112'], 'imdb': ['tt10155688'], 'tmdb': ['115004']}
Episodes: {'completed': [True], 'time': [0], 'locations': [()], 'tvdb': ['8197081'], 'imdb': ['tt11033898'], 'title': ['miss lady hawk in persona']}
Movies: {}
[DEBUG]: Plex: Skipping show Black Mirror as it is not in mark list for userplex
[DEBUG]: Plex: Skipping episode Miss Lady Hawk in persona as it is not in mark list for userplex
[DEBUG]: Plex: Skipping episode Padri as it is not in mark list for userplex
[DEBUG]: Plex: Skipping episode Inserire il numero due as it is not in mark list for userplex
[DEBUG]: Plex: Skipping episode Povero Sisifo as it is not in mark list for userplex
[DEBUG]: Plex: Skipping episode Illusioni as it is not in mark list for userplex
[DEBUG]: Plex: Skipping episode Ben aspra dev'esser la tempesta as it is not in mark list for userplex
[DEBUG]: Plex: Skipping episode Sacramento as it is not in mark list for userplex

Type:

  • [ X] Docker
  • Native

Additional context
Sync the other way (from Plex to jellyfin) works correctly.
I'm I missing something? What's the "mark list"?

Ignore SSLCertificate

Please add an option to ignore non-matching SSL certificates from plex-direct.domain and your local instance.

It is possible to use http when setting "Secure connections:" to “preferred” instead of “always”, but I would rather leave my server on “always”.

Thanks you!

User Mapping Error

Describe the bug
A clear and concise description of what the bug is.
I'm trying to map users together from jellyfin/plex. When I try to map the users I get a error
image
I'm trying to map the users from plex/jellyfin
To Reproduce
Steps to reproduce the behavior:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

Expected behavior
A clear and concise description of what you expected to happen.

Logs
If applicable, add logs to help explain your problem ideally with DEBUG set to true, be sure to remove sensitive information

Type:

  • [yes ] Docker
  • Native

Additional context
Add any other context about the problem here.

Dry Run does not do anything

I have followed the instructions, filled out the env, started the container, but all I get is the below:

[INFO]: Dryrun: True [INFO]: Creating (black/white)lists [INFO]: Blacklist Library: [] [INFO]: Whitelist Library: [] [INFO]: Blacklist Library Type: [] [INFO]: Whitelist Library Type: [] [INFO]: Blacklist Users: [] [INFO]: Whitelist Users: [] [INFO]: Creating server connections Average time: 0.0012488549982663244 Looping in 3600.0

I have updated the logging to debug, but still, nothing else is printed out for any errors that may be occurring

Syntax error main.py line 25

I'm getting a syntax error when trying to run main.py
File "main.py", line 25 logger(f"User {user_1} and {user_other} not found in watched list 2", 1) ^ SyntaxError: invalid syntax

I'm sorry if I'm missing something obvious.

Failed to log into plex

I have been using JellyPlex-Watched as a docker successfully for several months but recently it seems to have stopped working. I dont believe i have changed in my configuration of plex or this app. Below are the errors i see in the logs. Any idea what is going wrong?

[ERROR]: Plex: Failed to login, Failed to login via plex account xxxxxxxx, Error: (429) too_many_requests; https://plex.tv/users/sign_in.xml
[ERROR]: (429) too_many_requests; https://plex.tv/users/sign_in.xml
[ERROR]: Traceback (most recent call last):

[BUG] Unable to run if WHITELIST_USERS not specified

Describe the bug
The process is unable to run if WHITELIST_USERS variable doesn't have anything in it

To Reproduce
Steps to reproduce the behavior:

  1. Deploy docker with req'd env vars
  2. Do not provide the WHITELIST_USERS var

Expected behavior
A clear and concise description of what you expected to happen.

Logs

[INFO]: Dryrun: False
[INFO]: Creating (black/white)lists
[INFO]: Blacklist Library: []
[INFO]: Blacklist Library Type: []
[INFO]: Blacklist Users: []
[INFO]: Whitelist Library: []
[INFO]: Whitelist Library Type: []
[INFO]: Whitelist Users: []
[INFO]: Creating server connections
[INFO]: Creating users list
[INFO]: User list that exist on both servers { <REMOVED> }
[INFO]: Filtered user list {<REMOVED>}
[INFO]: Server 1 users: [<REMOVED - but was many MyPlexUser: and a single MyPlexAccount: >]
[INFO]: Creating watched lists
[ERROR]: Plex: Failed to login, Error: No complete plex credentials provided
[ERROR]: Plex: Failed to get watched, Error: No complete plex credentials provided
[ERROR]: No complete plex credentials provided
[ERROR]: Traceback (most recent call last):
  File "/app/src/plex.py", line 269, in login
    raise Exception("No complete plex credentials provided")
Exception: No complete plex credentials provided
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "/app/src/plex.py", line 310, in get_watched
    user_plex = self.login(
                ^^^^^^^^^^^
  File "/app/src/plex.py", line 278, in login
    raise Exception(e)
Exception: No complete plex credentials provided
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "/app/src/main.py", line 373, in main
    main_loop()
  File "/app/src/main.py", line 306, in main_loop
    server_1_watched = get_server_watched(
                       ^^^^^^^^^^^^^^^^^^^
  File "/app/src/main.py", line 155, in get_server_watched
    return server_connection[1].get_watched(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/src/plex.py", line 348, in get_watched
    raise Exception(e)
Exception: No complete plex credentials provided
Retrying in 3600.0

Type:

  • Docker
  • Native

Additional context
Works perfectly fine if I provide users in the WHITELIST_USERS variable. I tried both my account in the WHITELIST_USERS, as well as just a user's account and there was no difference, successful run every time.

Not syncing TV Shows

My TV Shows are not being synced, I set log level to debug, but no error messages.

plex = user1
jellyfin = user2

Users are mapped and working for Movies. The Libraries share the same name, so not mapping necessary.


[INFO]: server 1 watched that needs to be synced to server 2:
{'user1': {'TV Shows': ...... log list of watched episodes .......
....


[INFO]: server 2 watched that needs to be synced to server 1:
{}
[INFO]: Jellyfin: Updating watched for user1 in library TV Shows
Looping in 3600.0

This is all I see in the log.

Should "Jellyfin: Updating watched for user1" not be using user2?

If I restart the docker, the same log is output again.

Thank you!

[BUG] KeyError: 'tmdb' in jellyfin.py

Describe the bug
Traceback when syncing a Plex server to a Jellyfin server.

To Reproduce
Steps to reproduce the behavior:

  1. Follow baremetal install with venv (python 3.11)
  2. Add plex token and jellyfin token to .env
  3. Run python main.py

Expected behavior
No traceback

Logs

[DEBUG]: Jellyfin: Skipping episode La Bande masquée as it is not in mark list for jean
[DEBUG]: Jellyfin: Skipping episode Minuit moins une as it is not in mark list for jean
Dryrun Roblochon : La Série Season 1 Episode 22 Chiche Donne tout as watched for jean in Séries for Jellyfin
[ERROR]: Jellyfin: Error updating watched for jean in library Séries, 'tmdb'
[ERROR]: Traceback (most recent call last):
  File "/home/jean/scm/JellyPlex-Watched/src/jellyfin.py", line 676, in update_user_watched
    in show[show_provider_source.lower()]
       ~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
KeyError: 'tmdb'

Average time: 140.85019239597023

Type:

  • Docker
  • Native

Additional context

I'm able to reproduce against 5.0.0, 4.5.0 and main.

[BUG] SSL: CERTIFICATE_VERIFY_FAILED when SSL_BYPASS = "True"

Describe the bug
I cannot see anything in my continue watching section on either plex or jellyfin

I just get the following errors output when I run the "docker logs jellyplex" command

I have SSL_BYPASS = "True" in the config (I have attached my full config)

`During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/app/src/main.py", line 382, in main
main_loop()
File "/app/src/main.py", line 298, in main_loop
servers = generate_server_connections()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/app/src/main.py", line 89, in generate_server_connections
Plex(
File "/app/src/plex.py", line 393, in init
self.plex = self.login(self.baseurl, self.token)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/app/src/plex.py", line 415, in login
raise Exception(e)
Exception: HTTPSConnectionPool(host='localhost', port=32400): Max retries exceeded with url: / (Caused by SSLError(SSLCertVerificationError(1, "[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: Hostname mismatch, certificate is not valid for 'localhost'. (_ssl.c:1002)")))`

Type:
Docker

Additional context
config.txt

Can't sync history of mine

Hi, thank you for this, it's amazing. If I run script I don't see my account there. Don't know where is a problem. History of every users are now synced. My history is not synced.

No errors while running. I login to plex with email/password. If I open plex web, in settings I see nickname "Renecek"
Any idea what to do please?

Plex: Generating watched for juraj obšitník in library Filmy
Plex: Generating watched for juraj obšitník in library TV Seriály
Plex: Generating watched for kilasqo in library Filmy
Plex: Generating watched for kilasqo in library TV Seriály
Plex: Generating watched for leomatthi in library Filmy
Plex: Generating watched for leomatthi in library TV Seriály
Plex: Generating watched for novot63 in library FilmyPlex: Generating watched for novot63 in library TV Seriály

Plex: Generating watched for pepob962 in library Filmy
Plex: Generating watched for pepob962 in library TV Seriály
Plex: Generating watched for stanislavka1 in library Filmy
Plex: Generating watched for stanislavka1 in library TV Seriály
Jellyfin: Generating watched for juraj library Filmy
Jellyfin: Generating watched for juraj library TV Seriály
Jellyfin: Generating watched for kilasqo in library Filmy
Jellyfin: Generating watched for pepob962 in library Filmy
Jellyfin: Generating watched for pepob962 in library TV Seriály
Jellyfin: Generating watched for stanislavka1 in library Filmy
Jellyfin: Generating watched for stanislavka1 in library TV Seriály
Jellyfin: Generating watched for leomatthi in library Filmy
Jellyfin: Generating watched for leomatthi in library TV Seriály
Average time: 6.956052200001068
Looping in 3600.0

Failed attribute guids in Plex

I am having this issue:
[ERROR]: Plex: Failed to get watched for matin in library Movies, Error: 'Movie' object has no attribute 'guids'
I didn't have it before, but suddenly when restarting the plugin I got it and I don't understand what it is or how it occured.

[BUG] KeyError: 'IndexNumber' in jellyfin.py

Describe the bug
Traceback when syncing a Plex server to a Jellyfin server.

To Reproduce
Steps to reproduce the behavior:

  1. Follow baremetal install with venv (python 3.11)
  2. Add plex token and jellyfin token to .env
  3. Run python main.py

Expected behavior
No traceback

Logs

[ERROR]: Jellyfin: Error updating watched for paul in library Séries, 'IndexNumber'
[ERROR]: Traceback (most recent call last):
  File "/home/paul/scm/JellyPlex-Watched/src/jellyfin.py", line 755, in update_user_watched
    f"{jellyfin_episode['SeriesName']} {jellyfin_episode['SeasonName']} Episode {jellyfin_episode['IndexNumber']} {jellyfin_episode['Name']}"
                                                                                 ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^
KeyError: 'IndexNumber'

Average time: 102.91429637104739

Type:

  • Docker
  • Native

Additional context

I'm able to reproduce against main.

[Feature Request] Sync playback offset

It would be nice to also, in addition to syncing whether an item has been watched, have the playback state of an item synced. For example, if I start a movie in plex and complete an hour (1:00:00) out of the hour and forty five mins (1:45:00) total duration, that state could be sync to jellyfin and I can resume the movie there.

It may not be possible to mutate the viewOffset plex uses to keep track of watch position for an item, due to the closed source nature of plex. A workaround could be to use a PlexClient to seekTo the position. Similarly for jellyfin, using the Playstate endpoints could be helpful.

matching users

I'm not finding information on matching users between Plex and Jellyfin. I'd like to ensure manual assignment for syncing. How can I do this to be sure each user is properly synced? Happy to beer tip.

[Feature Request] Mark Unwatched

Hello,

I was wondering if it would be possible to be able to mark things unwatched as well as watched?

I like to use this to have my Plex server as the master watchlist that will sync to my jellyfin server.

It works perfectly when something is watched on Plex to sync to watched on jellyfin, but there are times where I mark things as unwatched in Plex.

When I do that it stays marked watched in jellyfin. Is there a way to implement JellyPlex-Watched to mark those as unwatched to match Plex?

Thank you!

[BUG] Permission denied log.log

Describe the bug
The container does not work with the error log reporting permission denied to log.log from the function main.py. I tried changing the log file to "/var/log/jellyplex.log" but that had no effect either.

To Reproduce
Steps to reproduce the behavior:

  1. Compose file with all the variables on the README.
  2. Try to run the container.

Expected behavior
For it to run without problems?

Logs
PermissionError: [Errno 13] Permission denied: 'log.log'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):

File "/app/main.py", line 11, in

main()

File "/app/src/main.py", line 392, in main

logger(error, log_type=2)

File "/app/src/functions.py", line 30, in logger

file = open(logfile, "a", encoding="utf-8")

Type:

  • [* ] Docker
  • Native

Additional context
docker on debian, tried both latest and 4.2 tags.

How to use compose file in portainer?

Hello,
scripts works perfect. Want to create stack in my portainer, how to do that please?

version: "3"
services:
  jellyplex:
    image: luigi311/jellyplex-watched:latest
    container_name: jellyplex
    env_file:
    - /home/user/data/jellyplex/.env:/app/.env
    restart: unless-stopped

Still getting this error

Deployment error
open /home/user/data/jellyplex/.env:/app/.env: no such file or directory 

[BUG] 'Path' error getting/updating Jellyfin watched

Describe the bug
I get an issue that seems related to #36 , #31 , #25 and #28 with only my Jellyfin Shows library(that spans through multiple directories) and my main user only.
Another Jellyfin library (Anime, which also spans through multiple directories) syncs successfully.
I've tried changing merge settings and even select only one folder to be included in the library in question, no luck.
I feel like it depends on some Jellyfin setting rather than being a bug but I don't know what exactly.

Logs

[ERROR]: Jellyfin: Failed to get watched for user in library Shows, Error: 'Path'
[ERROR]: Traceback (most recent call last):
  File "/app/src/jellyfin.py", line 333, in get_user_library_watched
    episode_dict = get_episode_guids(episode)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/src/jellyfin.py", line 53, in get_episode_guids
    [x["Path"].split("/")[-1] for x in episode["MediaSources"]]
  File "/app/src/jellyfin.py", line 53, in <listcomp>
    [x["Path"].split("/")[-1] for x in episode["MediaSources"]]
     ~^^^^^^^^
KeyError: 'Path'

...

[ERROR]: Jellyfin: Error updating watched for user in library Shows, 'Path'
[ERROR]: Traceback (most recent call last):
  File "/app/src/jellyfin.py", line 702, in update_user_watched
    episode_location["Path"].split("/")[-1],
    ~~~~~~~~~~~~~~~~^^^^^^^^
KeyError: 'Path'

Type:

  • Docker

Additional context
Add any other context about the problem here.

Replicated #31 - Not syncing movies

Just posted this under the closed ticket, and wasn't sure if you'd see it. #31
So I think I have the same problem that @daveonkels had previously - and it appears to be due to having multiple folders in each library (as for me, I had the issue with TV Shows as well). I have two folders for Movies (4k and non-4k) and same for TV. And when it does the search, it only returns the top level. When I modify the query for jellyfin_search to include recursive folders, but filtered for either Movie or Series, it seems to work ok (I think)

jellyfin_search = await self.query( f"/Users/{user_id}/Items" + f"?SortBy=SortName&SortOrder=Ascending&Recursive=true&ParentId={library_id}" + "&isPlayed=false&Fields=ItemCounts,ProviderIds,MediaSources" + f"&IncludeItemTypes=Movie",

jellyfin_search = await self.query( f"/Users/{user_id}/Items" + f"?SortBy=SortName&SortOrder=Ascending&Recursive=true**&ParentId={library_id}" + "&isPlayed=false&Fields=ItemCounts,ProviderIds,Path" + f"&IncludeItemTypes=Series",

Allow using filename or provider tags

Allow using the filenames of the video files instead of using the provider tags as this will allow matching of unmatched items. Filenames should be ok even when using different mappings in docker containers as we can use the Folder name of the show and the name of the episode as our checks instead of full paths as everything is already separated by library so this should also avoid any collisions with having the same show/episode/movie in multiple libraries.

TV Shows not syncing to jellyfin

Running in docker trying to sync plex watched to jellyfin, I was able to successfully sync my movies, movies 4k, and tv shows 4k libraries but my main tv shows library doesn't seem to work. There is no errors logged with debug enabled. It shows the list of changes and says its syncing to jellyfin but nothing seems to happen on the jellyfin side and it immediately goes to looping. Watched status is successfully synced from jellyfin to plex.

I've attached a log from a run with a test user

log.log

[BUG] I get: [ERROR]: Jellyfin: Error updating watched for matin in library Anime, 'Name'

I don't understand why this error pops up, it wasn't there before, but I'm not sure for how long it has been there, since I was on a trip.

This is the console log:
Plex: Generating watched for mikail121 in library Movies
Plex: Generating watched for mikail121 in library Anime
Plex: Generating watched for mikail121 in library Cartoons
Plex: Generating watched for black_speedy in library Movies
Plex: Generating watched for black_speedy in library Anime
Plex: Generating watched for black_speedy in library Cartoons
Jellyfin: Generating watched for matin in library Anime
Jellyfin: Generating watched for matin in library Cartoons
Jellyfin: Generating watched for matin in library Movies
Jellyfin: Generating watched for miko in library Anime
[ERROR]: Jellyfin: Error updating watched for matin in library Anime, 'Name'
[ERROR]: Traceback (most recent call last):
File "C:\Plugins For Video\JellyPlex-Watched\src\jellyfin.py", line 800, in update_user_watched
f"Jellyfin: Skipping episode {jellyfin_episode['Name']} as it is not in mark list for {user_name}",
KeyError: 'Name'

Average time: 50.37688530000014
Looping in 3600.0

I'm not sure if it might be some show that it doesn't recognize or what it might be.

This is my config:

# Global Settings

## Do not mark any shows/movies as played and instead just output to log if they would of been marked.
DRYRUN = "False"

## Additional logging information
DEBUG = "False"

## Debugging level, "info" is default, "debug" is more verbose
DEBUG_LEVEL = "info"

## If set to true then the script will only run once and then exit
RUN_ONLY_ONCE = "False"

## How often to run the script in seconds
SLEEP_DURATION = "3600"

## Log file where all output will be written to
LOGFILE = "log.log"

## Map usernames between servers in the event that they are different, order does not matter
## Comma separated for multiple options
USER_MAPPING = { "black_speedy": "matin", "mikail121":"Miko" }

## Map libraries between servers in the even that they are different, order does not matter
## Comma separated for multiple options
#LIBRARY_MAPPING = { "Shows": "TV Shows", "Movie": "Movies" }

## Blacklisting/Whitelisting libraries, library types such as Movies/TV Shows, and users. Mappings apply so if the mapping for the user or library exist then both will be excluded.
## Comma separated for multiple options
#BLACKLIST_LIBRARY = ""
#WHITELIST_LIBRARY = ""
#BLACKLIST_LIBRARY_TYPE = ""
#WHITELIST_LIBRARY_TYPE = ""
#BLACKLIST_USERS = ""
WHITELIST_USERS = "black_speedy,matin,mikail121,Miko"

# Plex

## Recommended to use token as it is faster to connect as it is direct to the server instead of going through the plex servers
## URL of the plex server, use hostname or IP address if the hostname is not resolving correctly
## Comma separated list for multiple servers
PLEX_BASEURL = "http://localhost:32400"

## Plex token https://support.plex.tv/articles/204059436-finding-an-authentication-token-x-plex-token/
## Comma separated list for multiple servers
PLEX_TOKEN = ""

## If not using plex token then use username and password of the server admin along with the servername
## Comma separated for multiple options
#PLEX_USERNAME = ""
#PLEX_PASSWORD = ""
#PLEX_SERVERNAME = "MediaPC"

## Skip hostname validation for ssl certificates.
## Set to True if running into ssl certificate errors
SSL_BYPASS = "False"

## control the direction of syncing. e.g. SYNC_FROM_PLEX_TO_JELLYFIN set to true will cause the updates from plex
## to be updated in jellyfin. SYNC_FROM_PLEX_TO_PLEX set to true will sync updates between multiple plex servers
SYNC_FROM_PLEX_TO_JELLYFIN = "True"
SYNC_FROM_JELLYFIN_TO_PLEX = "True"
SYNC_FROM_PLEX_TO_PLEX = "True"
SYNC_FROM_JELLYFIN_TO_JELLYFIN = "True"

# Jellyfin

## Jellyfin server URL, use hostname or IP address if the hostname is not resolving correctly
## Comma separated list for multiple servers
JELLYFIN_BASEURL = "http://localhost:8096"

## Jellyfin api token, created manually by logging in to the jellyfin server admin dashboard and creating an api key
## Comma separated list for multiple servers
JELLYFIN_TOKEN = ""

[BUG] Cannot decode JSON on Jellyfin Users

Cannot decode JSON
Unable to use the tool, as it fails in opening the URI to Jellyfin.

To Reproduce
Steps to reproduce the behavior:

  1. Configure .env or docker runtime vars
  2. Start container
  3. See error

Expected behavior
I expect it to sync the way it's described (and the way I've used it before)

Logs

During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "/app/src/main.py", line 382, in main
    main_loop()
  File "/app/src/main.py", line 298, in main_loop
    servers = generate_server_connections()
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/src/main.py", line 146, in generate_server_connections
    Jellyfin(baseurl=baseurl, token=jellyfin_token[i].strip()),
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/src/jellyfin.py", line 80, in __init__
    self.users = asyncio.run(self.get_users())
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/asyncio/runners.py", line 190, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/asyncio/runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/asyncio/base_events.py", line 653, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "/app/src/jellyfin.py", line 144, in get_users
    raise Exception(e)
Exception: 0, message='Attempt to decode JSON with unexpected mimetype: ', url=URL('http://10.0.1.150:8096/Users')

Type:

  • Docker

[Need Help] Attempt to decode JSON with unexpected mimetype: text/html', url=URL('....')

Hey!

I'm getting this error when using your lovely software:

Output from the log.log:
https://paste.ec/paste/jmH-GoOH#qetLghapEmczdLcCZ1uFzeSBaAQ8T7xaa7yHzjxjfFT

I'm running it in docker.

My docker-compose.yml setup:

version: "3.9"

services:
  jellyplexwatched:
    container_name: jellyplexwatched
    image: luigi311/jellyplex-watched:latest
    labels:
     - "org.hotio.pullio.notify=true"
     - "org.hotio.pullio.update=true"
     - "org.hotio.pullio.generic.webhook=https://notifiarr.com/api/v1/notification/pullio/xxxxx-xxxx-xxxx-xxxx-xxxxxxxxx"
     - "autoheal=true"
    volumes:
      - /opt/docker-all/jellyplexwatched/config.env:/app/.env
      - /etc/localtime:/etc/localtime:ro
    restart: unless-stopped

My config.env (with URLs etc redacted):
https://paste.ec/paste/V0p7h0Fa#4QWxivibZG60U8eM1EDRLyn8j5QEC7KC17+j44upsfi

My NGINX file for my jellyfin.domain.com, if that matters at all. I'm just using the official nginx reverse proxy from the jellyfin docs:
https://paste.ec/paste/mLYMPSIM#vUgW46tgSt59ACOIffnI9arMq8OjKoGZ7TTnXHxje9k

[ERROR]: string indices must be integers

Hello, I'm getting this error when I try to sync two Jellyfin 10.8.0 servers:

[ERROR]: string indices must be integers
[ERROR]: Traceback (most recent call last):
  File "/app/src/jellyfin.py", line 140, in get_watched
    if len(watched["Items"]) == 0:
TypeError: string indices must be integers
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "/app/src/functions.py", line 145, in future_thread_executor
    result = future.result()
  File "/usr/local/lib/python3.10/concurrent/futures/_base.py", line 446, in result
    return self.__get_result()
  File "/usr/local/lib/python3.10/concurrent/futures/_base.py", line 391, in __get_result
    raise self._exception
  File "/usr/local/lib/python3.10/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/app/src/jellyfin.py", line 163, in get_watched
    raise Exception(e)
Exception: string indices must be integers
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "/app/src/main.py", line 424, in main
    main_loop()
  File "/app/src/main.py", line 395, in main_loop
    results = future_thread_executor(args)
  File "/app/src/functions.py", line 148, in future_thread_executor
    raise Exception(e)
Exception: string indices must be integers
Retrying in 120.0```

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.