Taxel / PlexTraktSync

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

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Sync and unmatched error on 0.30.7

AndreiArdelean1 opened this issue · comments

Confirmation

  • I have read the README.md on the project homepage
  • I have checked if identical issue already exists
  • I have tried downgrading to find version that can be used as a workaround

The problem

Running the following commands fails when running version 0.30.7:

python3 -m plextraktsync --no-progressbar unmatched
python3 -m plextraktsync --no-progressbar sync --sync=shows
python3 -m plextraktsync --no-progressbar sync --sync=movies

Steps to reproduce the behavior

Have version 0.30.7 installed in docker

Run commands:
python3 -m plextraktsync --no-progressbar unmatched
python3 -m plextraktsync --no-progressbar sync --sync=shows
python3 -m plextraktsync --no-progressbar sync --sync=movies

Error trace / logs

`python3 -m plextraktsync --no-progressbar unmatched`:

         ╭───────────────── 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 term │
         │       connected: {e}")                                              │
         │    29 │   │   │   except ClickException as e:                       │
         │                                                                     │
         │ /app/plextraktsync/commands/unmatched.py:23 in unmatched            │
         │                                                                     │
         │   20 │   │   │   if all(guid.local for guid in pm.guids):           │
         │   21 │   │   │   │   failed.append(pm)                              │
         │   22 │   else:                                                      │
         │ ❱ 23 │   │   for pm in walker.get_plex_movies():                    │
         │   24 │   │   │   movie = mf.resolve_any(pm)                         │
         │   25 │   │   │   if not movie:                                      │
         │   26 │   │   │   │   failed.append(pm)                              │
         ╰─────────────────────────────────────────────────────────────────────╯
         TypeError: 'async_generator' object is not iterable                    
Error: Error running unmatched command: 'async_generator' object is not iterable



`python3 -m plextraktsync --no-progressbar sync --sync=shows`:
INFO     PlexTraktSync [0.30.7]                                                 
INFO     Connecting with url: http://plex:32400, timeout 30 seconds             
INFO     Sync Show sections: ['TV Shows']                                       
INFO     Enable sync plugin 'AddCollectionPlugin': False                        
INFO     Enable sync plugin 'ClearCollectedPlugin': False                       
INFO     Enable sync plugin 'LikedListsPlugin': False                           
INFO     Enable sync plugin 'SyncRatingsPlugin': False                          
INFO     Enable sync plugin 'SyncWatchedPlugin': True                           
INFO     Enable sync plugin 'TraktListsPlugin': False                           
INFO     Enable sync plugin 'WatchListPlugin': False                            
INFO     Enable sync plugin 'WatchProgressPlugin': False                        
INFO     Preload shows data                                                     
ERROR    'async for' requires an object with __aiter__ method, got              
         PlexSectionPager                                                       
         ╭───────────────── 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 term │
         │       connected: {e}")                                              │
         │    29 │   │   │   except ClickException as e:                       │
         │                                                                     │
         │ /app/plextraktsync/commands/sync.py:76 in sync                      │
         │                                                                     │
         │   73 │   │   │   w.print_plan(print=logger.info)                    │
         │   74 │   │   if dry_run:                                            │
         │   75 │   │   │   logger.info("Enabled dry-run mode: not making actu │
         │ ❱ 76 │   │   run_async(runner, walker=w, dry_run=config.dry_run)    │
         │   77                                                                │
         │                                                                     │
         │ /app/plextraktsync/decorators/coro.py:13 in wrapper                 │
         │                                                                     │
         │   10 │   """                                                        │
         │   11 │   @wraps(f)                                                  │
         │   12 │   def wrapper(*args, **kwargs):                              │
         │ ❱ 13 │   │   return asyncio.run(f(*args, **kwargs))                 │
         │   14 │                                                              │
         │   15 │   return wrapper                                             │
         │   16                                                                │
         │                                                                     │
         │ /usr/local/lib/python3.12/asyncio/runners.py:194 in run             │
         │                                                                     │
         │   191 │   │   │   "asyncio.run() cannot be called from a running ev │
         │   192 │                                                             │
         │   193 │   with Runner(debug=debug, loop_factory=loop_factory) as ru │
         │ ❱ 194 │   │   return runner.run(main)                               │
         │   195                                                               │
         │   196                                                               │
         │   197 def _cancel_all_tasks(loop):                                  │
         │                                                                     │
         │ /usr/local/lib/python3.12/asyncio/runners.py:118 in run             │
         │                                                                     │
         │   115 │   │                                                         │
         │   116 │   │   self._interrupt_count = 0                             │
         │   117 │   │   try:                                                  │
         │ ❱ 118 │   │   │   return self._loop.run_until_complete(task)        │
         │   119 │   │   except exceptions.CancelledError:                     │
         │   120 │   │   │   if self._interrupt_count > 0:                     │
         │   121 │   │   │   │   uncancel = getattr(task, "uncancel", None)    │
         │                                                                     │
         │ /usr/local/lib/python3.12/asyncio/base_events.py:687 in             │
         │ run_until_complete                                                  │
         │                                                                     │
         │    684 │   │   if not future.done():                                │
         │    685 │   │   │   raise RuntimeError('Event loop stopped before Fu │
         │    686 │   │                                                        │
         │ ❱  687 │   │   return future.result()                               │
         │    688 │                                                            │
         │    689 │   def stop(self):                                          │
         │    690 │   │   """Stop running the event loop.                      │
         │                                                                     │
         │ /app/plextraktsync/commands/sync.py:13 in run_async                 │
         │                                                                     │
         │   10                                                                │
         │   11 @coro                                                          │
         │   12 async def run_async(runner, **kwargs):                         │
         │ ❱ 13 │   await runner.sync(**kwargs)                                │
         │   14                                                                │
         │   15                                                                │
         │   16 def sync(                                                      │
         │                                                                     │
         │ /app/plextraktsync/sync/Sync.py:49 in sync                          │
         │                                                                     │
         │   46 │   │   │   async for movie in walker.find_movies():           │
         │   47 │   │   │   │   await pm.ahook.walk_movie(movie=movie, dry_run │
         │   48 │   │   │                                                      │
         │ ❱ 49 │   │   │   async for episode in walker.find_episodes():       │
         │   50 │   │   │   │   await pm.ahook.walk_episode(episode=episode, d │
         │   51 │   │                                                          │
         │   52 │   │   await pm.ahook.fini(walker=walker, dry_run=dry_run)    │
         │                                                                     │
         │ /app/plextraktsync/plan/Walker.py:114 in find_episodes              │
         │                                                                     │
         │   111 │   │   # Preload plex shows                                  │
         │   112 │   │   plex_shows: dict[int, PlexLibraryItem] = {}           │
         │   113 │   │   self.logger.info("Preload shows data")                │
         │ ❱ 114 │   │   async for show in self.get_plex_shows():              │
         │   115 │   │   │   plex_shows[show.key] = show                       │
         │   116 │   │   self.logger.info(f"Preloaded shows data ({len(plex_sh │
         │   117                                                               │
         │                                                                     │
         │ /app/plextraktsync/plan/Walker.py:103 in get_plex_shows             │
         │                                                                     │
         │   100 │   │   else:                                                 │
         │   101 │   │   │   return                                            │
         │   102 │   │                                                         │
         │ ❱ 103 │   │   async for m in it:                                    │
         │   104 │   │   │   yield m                                           │
         │   105 │                                                             │
         │   106 │   async def find_episodes(self):                            │
         │                                                                     │
         │ /app/plextraktsync/plan/Walker.py:166 in media_from_sections        │
         │                                                                     │
         │   163 │   │   │   │   │   section.pager(),                          │
         │   164 │   │   │   │   │   desc=f"Processing {section.title_link}",  │
         │   165 │   │   │   │   )                                             │
         │ ❱ 166 │   │   │   │   async for m in it:                            │
         │   167 │   │   │   │   │   yield m                                   │
         │   168 │                                                             │
         │   169 │   async def episodes_from_sections(self, sections: list[Ple │
         │       Generator[PlexLibraryItem, Any, None]:                        │
         │                                                                     │
         │ /app/plextraktsync/plan/Walker.py:201 in progressbar                │
         │                                                                     │
         │   198 │   │   │   │   async for m in it:                            │
         │   199 │   │   │   │   │   yield m                                   │
         │   200 │   │   else:                                                 │
         │ ❱ 201 │   │   │   async for m in iterable:                          │
         │   202 │   │   │   │   yield m                                       │
         │   203 │                                                             │
         │   204 │   async def media_from_traktlist(self, items: TraktWatchLis │
         │       -> Generator[Media, Any, None]:                               │
         ╰─────────────────────────────────────────────────────────────────────╯
         TypeError: 'async for' requires an object with __aiter__ method, got   
         PlexSectionPager                                                       
Error: Error running sync command: 'async for' requires an object with __aiter__ method, got PlexSectionPager


`python3 -m plextraktsync --no-progressbar sync --sync=movies`:
INFO     PlexTraktSync [0.30.7]                                                 
INFO     Connecting with url: http://plex:32400, timeout 30 seconds             
INFO     Sync Movie sections: ['Movies']                                        
INFO     Enable sync plugin 'AddCollectionPlugin': False                        
INFO     Enable sync plugin 'ClearCollectedPlugin': False                       
INFO     Enable sync plugin 'LikedListsPlugin': False                           
INFO     Enable sync plugin 'SyncRatingsPlugin': False                          
INFO     Enable sync plugin 'SyncWatchedPlugin': True                           
INFO     Enable sync plugin 'TraktListsPlugin': False                           
INFO     Enable sync plugin 'WatchListPlugin': False                            
INFO     Enable sync plugin 'WatchProgressPlugin': False                        
ERROR    'async for' requires an object with __aiter__ method, got              
         PlexSectionPager                                                       
         ╭───────────────── 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 term │
         │       connected: {e}")                                              │
         │    29 │   │   │   except ClickException as e:                       │
         │                                                                     │
         │ /app/plextraktsync/commands/sync.py:76 in sync                      │
         │                                                                     │
         │   73 │   │   │   w.print_plan(print=logger.info)                    │
         │   74 │   │   if dry_run:                                            │
         │   75 │   │   │   logger.info("Enabled dry-run mode: not making actu │
         │ ❱ 76 │   │   run_async(runner, walker=w, dry_run=config.dry_run)    │
         │   77                                                                │
         │                                                                     │
         │ /app/plextraktsync/decorators/coro.py:13 in wrapper                 │
         │                                                                     │
         │   10 │   """                                                        │
         │   11 │   @wraps(f)                                                  │
         │   12 │   def wrapper(*args, **kwargs):                              │
         │ ❱ 13 │   │   return asyncio.run(f(*args, **kwargs))                 │
         │   14 │                                                              │
         │   15 │   return wrapper                                             │
         │   16                                                                │
         │                                                                     │
         │ /usr/local/lib/python3.12/asyncio/runners.py:194 in run             │
         │                                                                     │
         │   191 │   │   │   "asyncio.run() cannot be called from a running ev │
         │   192 │                                                             │
         │   193 │   with Runner(debug=debug, loop_factory=loop_factory) as ru │
         │ ❱ 194 │   │   return runner.run(main)                               │
         │   195                                                               │
         │   196                                                               │
         │   197 def _cancel_all_tasks(loop):                                  │
         │                                                                     │
         │ /usr/local/lib/python3.12/asyncio/runners.py:118 in run             │
         │                                                                     │
         │   115 │   │                                                         │
         │   116 │   │   self._interrupt_count = 0                             │
         │   117 │   │   try:                                                  │
         │ ❱ 118 │   │   │   return self._loop.run_until_complete(task)        │
         │   119 │   │   except exceptions.CancelledError:                     │
         │   120 │   │   │   if self._interrupt_count > 0:                     │
         │   121 │   │   │   │   uncancel = getattr(task, "uncancel", None)    │
         │                                                                     │
         │ /usr/local/lib/python3.12/asyncio/base_events.py:687 in             │
         │ run_until_complete                                                  │
         │                                                                     │
         │    684 │   │   if not future.done():                                │
         │    685 │   │   │   raise RuntimeError('Event loop stopped before Fu │
         │    686 │   │                                                        │
         │ ❱  687 │   │   return future.result()                               │
         │    688 │                                                            │
         │    689 │   def stop(self):                                          │
         │    690 │   │   """Stop running the event loop.                      │
         │                                                                     │
         │ /app/plextraktsync/commands/sync.py:13 in run_async                 │
         │                                                                     │
         │   10                                                                │
         │   11 @coro                                                          │
         │   12 async def run_async(runner, **kwargs):                         │
         │ ❱ 13 │   await runner.sync(**kwargs)                                │
         │   14                                                                │
         │   15                                                                │
         │   16 def sync(                                                      │
         │                                                                     │
         │ /app/plextraktsync/sync/Sync.py:46 in sync                          │
         │                                                                     │
         │   43 │   │   pm.hook.init(sync=self, pm=pm, is_partial=is_partial,  │
         │   44 │   │                                                          │
         │   45 │   │   if self.config.need_library_walk:                      │
         │ ❱ 46 │   │   │   async for movie in walker.find_movies():           │
         │   47 │   │   │   │   await pm.ahook.walk_movie(movie=movie, dry_run │
         │   48 │   │   │                                                      │
         │   49 │   │   │   async for episode in walker.find_episodes():       │
         │                                                                     │
         │ /app/plextraktsync/plan/Walker.py:89 in find_movies                 │
         │                                                                     │
         │    86 │   │   │   yield m                                           │
         │    87 │                                                             │
         │    88 │   async def find_movies(self) -> Generator[Media, Any, None │
         │ ❱  89 │   │   async for plex in self.get_plex_movies():             │
         │    90 │   │   │   movie = self.mf.resolve_any(plex)                 │
         │    91 │   │   │   if not movie:                                     │
         │    92 │   │   │   │   continue                                      │
         │                                                                     │
         │ /app/plextraktsync/plan/Walker.py:85 in get_plex_movies             │
         │                                                                     │
         │    82 │   │   else:                                                 │
         │    83 │   │   │   return                                            │
         │    84 │   │                                                         │
         │ ❱  85 │   │   async for m in movies:                                │
         │    86 │   │   │   yield m                                           │
         │    87 │                                                             │
         │    88 │   async def find_movies(self) -> Generator[Media, Any, None │
         │                                                                     │
         │ /app/plextraktsync/plan/Walker.py:166 in media_from_sections        │
         │                                                                     │
         │   163 │   │   │   │   │   section.pager(),                          │
         │   164 │   │   │   │   │   desc=f"Processing {section.title_link}",  │
         │   165 │   │   │   │   )                                             │
         │ ❱ 166 │   │   │   │   async for m in it:                            │
         │   167 │   │   │   │   │   yield m                                   │
         │   168 │                                                             │
         │   169 │   async def episodes_from_sections(self, sections: list[Ple │
         │       Generator[PlexLibraryItem, Any, None]:                        │
         │                                                                     │
         │ /app/plextraktsync/plan/Walker.py:201 in progressbar                │
         │                                                                     │
         │   198 │   │   │   │   async for m in it:                            │
         │   199 │   │   │   │   │   yield m                                   │
         │   200 │   │   else:                                                 │
         │ ❱ 201 │   │   │   async for m in iterable:                          │
         │   202 │   │   │   │   yield m                                       │
         │   203 │                                                             │
         │   204 │   async def media_from_traktlist(self, items: TraktWatchLis │
         │       -> Generator[Media, Any, None]:                               │
         ╰─────────────────────────────────────────────────────────────────────╯
         TypeError: 'async for' requires an object with __aiter__ method, got   
         PlexSectionPager                                                       
Error: Error running sync command: 'async for' requires an object with __aiter__ method, got PlexSectionPager

Expected behavior

Have no errors

Inspect of problematic items

No response

Workarounds

Run docker with tag 0.30.6

Config file contents

# Config File: /app/config/config.yml
cache:
  path: /app/cache/trakt_cache
excluded-libraries:
- Personal
- Private
config:
  dotenv_override: true
plex:
  timeout: 30
logging:
  append: false
  console_time: false
  debug: false
  filename: plextraktsync.log
  filter_loggers: null
  filter: null
sync:
  rating_priority: plex
  plex_to_trakt:
    collection: false
    clear_collected: false
    ratings: false
    watched_status: true
    watchlist: false
  trakt_to_plex:
    liked_lists: false
    ratings: false
    watched_status: true
    watchlist: false
    watchlist_as_playlist: false
    playback_status: false
watch:
  add_collection: false
  remove_collection: false
  scrobble_threshold: 80
  username_filter: true
  media_progressbar: true
  ignore_clients: null
xbmc-providers:
  movies: imdb
  shows: tvdb

Install method

pipx

Version

0.30.7

Python Version

3.12.3 (main, Apr 10 2024, 04:12:22) [GCC 13.2.1 20231014]

Plex Server Version

1.40.2.8395-c67dce28e, updated at: 2024-05-16 05:31:20

Operating System and Version

Docker - Ubuntu

Ok, problem is --no-progressbar, omitting it at least sync command works