Taxel / PlexTraktSync

A python script that syncs the movies, shows and ratings between trakt and Plex (without needing a PlexPass or Trakt VIP subscription)
MIT License
1.58k stars 102 forks source link

ERROR: Unable to find user #1838

Closed jjscaria closed 7 months ago

jjscaria commented 7 months ago

Confirmation

The problem

Sync run is not finishing successfully. I can see my history is updated on Trakt but, the docker run is exiting with error.

Steps to reproduce the behavior

Executed the docker run command docker-compose run --rm plextraktsync sync

Redacted my username from the logs below

Error trace / logs

Processing TV Shows 100% ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1,484/1,484  [ 0:05:02 < 0:00:00 , 25 it/s ]INFO     TV Shows processed in 5 min 2.6 seconds
Syncing show ratings 100% ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 54/54  [ 0:00:00 < 0:00:00 , 576 it/s ]INFO     Updated liked list in 0.0 seconds
ERROR    Unable to find user [username]
         ╭───────────────────────────────────────────────────────────────────────────────── Traceback (most recent call last) ──────────────────────────────────────────────────────────────────────────────────╮         │ /app/plextraktsync/cli.py:26 in wrap                                                                                                                                                                 │         │                                                                                                                                                                                                      │         │    23 │   │   │   cmd = getattr(module, name)                                                                                                                                                        │         │    24 │   │   │                                                                                                                                                                                      │         │    25 │   │   │   try:                                                                                                                                                                               │         │ ❱  26 │   │   │   │   cmd(*args, **kwargs)                                                                                                                                                           │         │    27 │   │   │   except EOFError as e:                                                                                                                                                              │         │    28 │   │   │   │   raise ClickException(f"Program requested terminal, No terminal is                                                                                                              │         │       connected: {e}")                                                                                                                                                                               │         │    29 │   │   │   except ClickException as e:                                                                                                                                                        │         │                                                                                                                                                                                                      │         │ /app/plextraktsync/commands/sync.py:68 in sync                                                                                                                                                       │         │                                                                                                                                                                                                      │         │   65 │   │   │   w.print_plan(print=logger.info)                                                                                                                                                     │         │   66 │   │   if dry_run:                                                                                                                                                                             │         │   67 │   │   │   logger.info("Enabled dry-run mode: not making actual changes")                                                                                                                      │         │ ❱ 68 │   │   runner.sync(walker=w, dry_run=config.dry_run)                                                                                                                                           │         │   69                                                                                                                                                                                                 │         │                                                                                                                                                                                                      │         │ /app/plextraktsync/sync/Sync.py:105 in sync                                                                                                                                                          │         │                                                                                                                                                                                                      │         │   102 │   │   │   │   │   with measure_time("Updated liked list"):                                                                                                                                   │         │   103 │   │   │   │   │   │   trakt_lists.sync()                                                                                                                                                     │         │   104 │   │                                                                                                                                                                                          │         │ ❱ 105 │   │   if walker.config.walk_watchlist and self.sync_wl:                                                                                                                                      │         │   106 │   │   │   with measure_time("Updated watchlist"):                                                                                                                                            │         │   107 │   │   │   │   self.sync_watchlist(walker, dry_run=dry_run)                                                                                                                                   │         │   108                                                                                                                                                                                                │         │                                                                                                                                                                                                      │         │ /usr/local/lib/python3.12/functools.py:995 in __get__                                                                                                                                                │         │                                                                                                                                                                                                      │         │    992 │   │   │   raise TypeError(msg) from None                                                                                                                                                    │         │    993 │   │   val = cache.get(self.attrname, _NOT_FOUND)                                                                                                                                            │         │    994 │   │   if val is _NOT_FOUND:                                                                                                                                                                 │         │ ❱  995 │   │   │   val = self.func(instance)                                                                                                                                                         │         │    996 │   │   │   try:                                                                                                                                                                              │         │    997 │   │   │   │   cache[self.attrname] = val                                                                                                                                                    │         │    998 │   │   │   except TypeError:                                                                                                                                                                 │         │                                                                                                                                                                                                      │         │ /app/plextraktsync/sync/Sync.py:35 in sync_wl                                                                                                                                                        │         │                                                                                                                                                                                                      │         │    32 │                                                                                                                                                                                              │         │    33 │   @cached_property                                                                                                                                                                           │         │    34 │   def sync_wl(self):                                                                                                                                                                         │         │ ❱  35 │   │   return self.config.sync_wl and len(self.plex_wl) > 0                                                                                                                                   │         │    36 │                                                                                                                                                                                              │         │    37 │   @cached_property                                                                                                                                                                           │         │    38 │   def trakt_wl(self):                                                                                                                                                                        │         │                                                                                                                                                                                                      │         │ /usr/local/lib/python3.12/functools.py:995 in __get__                                                                                                                                                │         │                                                                                                                                                                                                      │         │    992 │   │   │   raise TypeError(msg) from None                                                                                                                                                    │         │    993 │   │   val = cache.get(self.attrname, _NOT_FOUND)                                                                                                                                            │         │    994 │   │   if val is _NOT_FOUND:                                                                                                                                                                 │         │ ❱  995 │   │   │   val = self.func(instance)                                                                                                                                                         │         │    996 │   │   │   try:                                                                                                                                                                              │         │    997 │   │   │   │   cache[self.attrname] = val                                                                                                                                                    │         │    998 │   │   │   except TypeError:                                                                                                                                                                 │         │                                                                                                                                                                                                      │         │ /app/plextraktsync/sync/Sync.py:31 in plex_wl                                                                                                                                                        │         │                                                                                                                                                                                                      │         │    28 │   def plex_wl(self):                                                                                                                                                                         │         │    29 │   │   from plextraktsync.plex.PlexWatchList import PlexWatchList                                                                                                                             │         │    30 │   │                                                                                                                                                                                          │         │ ❱  31 │   │   return PlexWatchList(self.plex.watchlist())                                                                                                                                            │         │    32 │                                                                                                                                                                                              │         │    33 │   @cached_property                                                                                                                                                                           │         │    34 │   def sync_wl(self):                                                                                                                                                                         │         │                                                                                                                                                                                                      │         │ /app/plextraktsync/plex/PlexApi.py:217 in watchlist                                                                                                                                                  │         │                                                                                                                                                                                                      │         │   214 │   │   return None                                                                                                                                                                            │         │   215 │                                                                                                                                                                                              │         │   216 │   def watchlist(self, libtype=None) -> list[Movie | Show] | None:                                                                                                                            │         │ ❱ 217 │   │   if not self.account:                                                                                                                                                                   │         │   218 │   │   │   return None                                                                                                                                                                        │         │   219 │   │                                                                                                                                                                                          │         │   220 │   │   params = {                                                                                                                                                                             │         │                                                                                                                                                                                                      │         │ /usr/local/lib/python3.12/functools.py:995 in __get__                                                                                                                                                │         │                                                                                                                                                                                                      │         │    992 │   │   │   raise TypeError(msg) from None                                                                                                                                                    │         │    993 │   │   val = cache.get(self.attrname, _NOT_FOUND)                                                                                                                                            │         │    994 │   │   if val is _NOT_FOUND:                                                                                                                                                                 │         │ ❱  995 │   │   │   val = self.func(instance)                                                                                                                                                         │         │    996 │   │   │   try:                                                                                                                                                                              │         │    997 │   │   │   │   cache[self.attrname] = val                                                                                                                                                    │         │    998 │   │   │   except TypeError:                                                                                                                                                                 │         │                                                                                                                                                                                                      │         │ /app/plextraktsync/plex/PlexApi.py:201 in account                                                                                                                                                    │         │                                                                                                                                                                                                      │         │   198 │   │   if plex_owner_token:                                                                                                                                                                   │         │   199 │   │   │   try:                                                                                                                                                                               │         │   200 │   │   │   │   plex_owner_account = MyPlexAccount(token=plex_owner_token,                                                                                                                     │         │       session=factory.session)                                                                                                                                                                       │         │ ❱ 201 │   │   │   │   return plex_owner_account.switchHomeUser(plex_username)                                                                                                                        │         │   202 │   │   │   except BadRequest as e:                                                                                                                                                            │         │   203 │   │   │   │   logger.error(f"Error during {plex_username} account access: {e}")                                                                                                              │         │   204 │   │   elif plex_account_token:                                                                                                                                                               │         │                                                                                                                                                                                                      │         │ /usr/local/lib/python3.12/site-packages/plexapi/myplex.py:499 in switchHomeUser                                                                                                                      │         │                                                                                                                                                                                                      │         │    496 │   │   │   │   │   userAccount = account.switchHomeUser('Username')                                                                                                                          │         │    497 │   │                                                                                                                                                                                         │         │    498 │   │   """                                                                                                                                                                                   │         │ ❱  499 │   │   user = user if isinstance(user, MyPlexUser) else self.user(user)                                                                                                                      │         │    500 │   │   url = f'{self.HOMEUSERS}/{user.id}/switch'                                                                                                                                            │         │    501 │   │   params = {}                                                                                                                                                                           │         │    502 │   │   if pin:                                                                                                                                                                               │         │                                                                                                                                                                                                      │         │ /usr/local/lib/python3.12/site-packages/plexapi/myplex.py:671 in user                                                                                                                                │         │                                                                                                                                                                                                      │         │    668 │   │   │   │   │   (user.username.lower(), user.email.lower(), str(user.id))):                                                                                                               │         │    669 │   │   │   │   return user                                                                                                                                                                   │         │    670 │   │                                                                                                                                                                                         │         │ ❱  671 │   │   raise NotFound(f'Unable to find user {username}')                                                                                                                                     │         │    672 │                                                                                                                                                                                             │         │    673 │   def users(self):                                                                                                                                                                          │         │    674 │   │   """ Returns a list of all :class:`~plexapi.myplex.MyPlexUser` objects connected                                                                                                       │         │        to your account.                                                                                                                                                                              │         ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯         NotFound: Unable to find user [username]
Error: Error running sync command: Unable to find user [username]

In case the error log is messed up, here is the screenshot: 1 2 3

Expected behavior

Complete sync and exit successfully

Inspect of problematic items

No response

Workarounds

No response

Install method

docker-compose

Config file contents

cache:
  path: $PTS_CACHE_DIR/trakt_cache

# You may want to use per server libraries config instead:
# - https://github.com/Taxel/PlexTraktSync#libraries
excluded-libraries:
  - Private

config:
  dotenv_override: true

plex:
  timeout: 30

logging:
  append: true
  # Whether to show timestamps in console messages
  console_time: false
  debug: false
  filename: plextraktsync.log
  # Additional logger names to apply filtering
  filter_loggers:
#    - plexapi
#    - requests_cache.backends
#    - requests_cache.backends.base
#    - requests_cache.backends.sqlite
#    - requests_cache.policy.actions
#    - requests_cache.session
#    - trakt.core
#    - urllib3.connectionpool
  filter:
#    # Filter out all messages with level WARNING
#    - level: WARNING
#    # Filter out message with level WARNING and containing a text
#    - level: WARNING
#      message: "not found on Trakt"
#    - message: "because provider local has no external Id"
#    - message: "because provider none has no external Id"
#    - message: "Retry using search for specific Plex Episode"
#    # Filter out messages by requests_cache
#    - name: requests_cache.backends
#    - name: requests_cache.backends.base
#    - name: requests_cache.backends.sqlite
#    - name: requests_cache.policy.actions
#    - name: requests_cache.session

# settings for 'sync' command
sync:
  # Setting for whether ratings from one platform should have priority.
  # Valid values are trakt, plex or none. (default: plex)
  # none - No rating priority. Existing ratings are not overwritten.
  # trakt - Trakt ratings have priority. Existing Plex ratings are overwritten.
  # plex - Plex ratings have priority. Existing Trakt ratings are overwritten.
  rating_priority: plex

  plex_to_trakt:
    collection: true
    # Clear collected state of items not present in Plex
    clear_collected: false
    ratings: true
    watched_status: true
    # If plex_to_trakt watchlist=false and trakt_to_plex watchlist=true
    # the Plex watchlist will be overwritten by Trakt watchlist
    watchlist: true
  trakt_to_plex:
    liked_lists: true
    ratings: true
    watched_status: true
    # If trakt_to_plex watchlist=false and plex_to_trakt watchlist=true
    # the Trakt watchlist will be overwritten by Plex watchlist
    watchlist: true
    # If you prefer to fetch trakt watchlist as a playlist instead of
    # plex watchlist, toggle this to true (is read only if watchlist=true)
    watchlist_as_playlist: false

# settings for 'watch' command
watch:
  add_collection: false
  remove_collection: false
  # what video watched percentage (0 to 100) triggers the watched status
  scrobble_threshold: 80
  # true to scrobble only what's watched by you, false for all your PMS users
  username_filter: true
  # Show the progress bar of played media in terminal
  media_progressbar: true

xbmc-providers:
  movies: imdb
  shows: tvdb

##### Advanced settings below this line, don't edit unless you know what you're doing #####
#http_cache:
  # https://requests-cache.readthedocs.io/en/main/user_guide/expiration.html#url-patterns
  # https://requests-cache.readthedocs.io/en/main/user_guide/expiration.html#expiration-values
  #
  # The value is seconds to cache.
  # Or one of the following special values:
  # - DO_NOT_CACHE: Skip both reading from and writing to the cache
  # - EXPIRE_IMMEDIATELY: Consider the response already expired, but potentially usable
  # - NEVER_EXPIRE: Store responses indefinitely
  #
  # The value can be also suffixed with a time unit:
  # - 5m, 1h, 3d
  # See full documentation at:
  # - https://github.com/wroberts/pytimeparse#pytimeparse-time-expression-parser
  #
  # NOTE: If there is more than one match, the first match will be used in the order they are defined
#  policy:
#    "*.trakt.tv/users/me": 1d
#    "*.trakt.tv/users/likes/lists": DO_NOT_CACHE

# vim:ts=2:sw=2:et

Version

0.29.2

Python Version

3.12.2

Plex Server Version

1.40.0.7998-c29d4c0c8

Operating System and Version

Debian 12

glensc commented 7 months ago

screenshots unreadable. share traces as text.

try disabling features from sync section to isolate the problem

jjscaria commented 7 months ago

screenshots unreadable. share traces as text.

You should be able to click on each image to view it maximized in a new tab. I posted the screenshots because the trace I posted is not formatted correctly.

try disabling features from sync section to isolate the problem

I tried variations of enabling and disabling features in the sync section under trakt_to_plex since plex_to_trakt seems to be working. I even tried commenting out that whole trakt_to_plex block and its still failing with the same error.

jjscaria commented 7 months ago

I did complete reinstall and that seems to have fixed the issue 🤷🏽

Thank you!

glensc commented 7 months ago

so, likely you made error in your config!

glensc commented 7 months ago

I even tried commenting out that whole trakt_to_plex block and its still failing with the same error.

doing so will enable default config, which has most things enabled