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

Feature request: Clear_collected should remove episodes from Trakt Collection that were collected in the first place

NGDM opened this issue · comments

commented

Feature description

The clear_collected feature should clear the items that were present in your collection but aren't anymore.
Now it is seemingly bulk-clearing all episodes of a show that aren't present in the Plex library.
This generates a lot of unnecessary API calls as well as messages in the log.

Use case

This would make the script more efficient/performant and make health-checking and debugging using the logs easier.

Current behaviour in logs

2023-04-06 10:49:57,137 INFO[PlexTraktSync]:Remove from Trakt collection (1/3190): <TVEpisode>: Malcolm in the Middle S0E1 A Stroke of Genius
2023-04-06 10:49:57,183 INFO[PlexTraktSync]:Remove from Trakt collection (2/3190): <TVEpisode>: Malcolm in the Middle S0E2 Outtakes
2023-04-06 10:49:57,189 INFO[PlexTraktSync]:Remove from Trakt collection (3/3190): <TVEpisode>: Malcolm in the Middle S0E3 Gag Reel
2023-04-06 10:49:57,193 INFO[PlexTraktSync]:Remove from Trakt collection (4/3190): <TVEpisode>: Malcolm in the Middle S0E4 Malcolm Vision
2023-04-06 10:49:57,196 INFO[PlexTraktSync]:Remove from Trakt collection (5/3190): <TVEpisode>: Malcolm in the Middle S0E5 DS Deals And Sellouts
2023-04-06 10:49:57,199 INFO[PlexTraktSync]:Remove from Trakt collection (6/3190): <TVEpisode>: Malcolm in the Middle S0E6 Cold Opens
2023-04-06 10:49:57,202 INFO[PlexTraktSync]:Remove from Trakt collection (7/3190): <TVEpisode>: Malcolm in the Middle S0E7 Season One Promos
2023-04-06 10:49:57,205 INFO[PlexTraktSync]:Remove from Trakt collection (8/3190): <TVEpisode>: Malcolm in the Middle S0E8 Malcolm: Behind the Middle
2023-04-06 10:49:57,209 INFO[PlexTraktSync]:Remove from Trakt collection (9/3190): <TVEpisode>: Malcolm in the Middle S0E9 Dewey's Day Job: A Portrait of Erik Per Sullivan
2023-04-06 10:49:57,213 INFO[PlexTraktSync]:Remove from Trakt collection (10/3190): <TVEpisode>: Malcolm in the Middle S0E10 Pilot Extended
2023-04-06 10:49:57,240 INFO[PlexTraktSync]:Remove from Trakt collection (11/3190): <TVEpisode>: Malcolm in the Middle S0E11 None
2023-04-06 10:49:57,243 INFO[PlexTraktSync]:Remove from Trakt collection (12/3190): <TVEpisode>: Malcolm in the Middle S0E12 Company Picnic 1: Director's cut (Season 3, episode 11)
2023-04-06 10:49:57,247 INFO[PlexTraktSync]:Remove from Trakt collection (13/3190): <TVEpisode>: Malcolm in the Middle S0E13 Quarantunes Reunion
2023-04-06 10:49:57,251 INFO[PlexTraktSync]:Remove from Trakt collection (14/3190): <TVEpisode>: The Mandalorian S3E7 Chapter 23
2023-04-06 10:49:57,256 INFO[PlexTraktSync]:Remove from Trakt collection (15/3190): <TVEpisode>: The Mandalorian S3E8 Chapter 24
2023-04-06 10:49:57,260 INFO[PlexTraktSync]:Remove from Trakt collection (16/3190): <TVEpisode>: Ted Lasso S0E1 The Missing Christmas Mustache
2023-04-06 10:49:57,263 INFO[PlexTraktSync]:Remove from Trakt collection (17/3190): <TVEpisode>: Ted Lasso S3E5 Signs
2023-04-06 10:49:57,266 INFO[PlexTraktSync]:Remove from Trakt collection (18/3190): <TVEpisode>: Ted Lasso S3E6 Every Disadvantage Has Its Advantage
2023-04-06 10:49:57,269 INFO[PlexTraktSync]:Remove from Trakt collection (19/3190): <TVEpisode>: Ted Lasso S3E7 Ola's
2023-04-06 10:49:57,272 INFO[PlexTraktSync]:Remove from Trakt collection (20/3190): <TVEpisode>: Ted Lasso S3E8 We'll Never Have Paris
2023-04-06 10:49:57,275 INFO[PlexTraktSync]:Remove from Trakt collection (21/3190): <TVEpisode>: Ted Lasso S3E9 The Omission Attrition
2023-04-06 10:49:57,278 INFO[PlexTraktSync]:Remove from Trakt collection (22/3190): <TVEpisode>: Ted Lasso S3E10 Episode 10
2023-04-06 10:49:57,282 INFO[PlexTraktSync]:Remove from Trakt collection (23/3190): <TVEpisode>: Ted Lasso S3E11 Episode 11
2023-04-06 10:49:57,284 INFO[PlexTraktSync]:Remove from Trakt collection (24/3190): <TVEpisode>: Ted Lasso S3E12 Episode 12

Plan to implement

No, little python experience

I do not see how this could not work, because the logic is:

  1. take all trakt_ids from trakt
  2. walk all items in plex, save their trakt id to plex_trakt_ids list
  3. subtract from trakt_ids plex_trakt_ids
  4. the remaining ids -> delete from trakt

code:

so, the input list to delete comes from trakt.

you should see the delete of those 3190 items once, and never again. do you report this behaving otherwise?

commented

Yes, this happens every time.

I'm wondering if Trakt is just returning all episodes as collected if you have all regular, existing episodes collected (so no Specials or unaired episodes). On the regular Trakt UI it also shows the show as 100% collected…

I can't get Postman working with the Trakt API to check it out… the authorizing part is tricky.
Could you maybe confirm this?

You can enable debug logging, then request urls get logged to the log.

From my logs, I think this is the request for shows

you can probably make requests with trakt apiary:

I myself use this script:

$ cat curl.sh
#!/bin/sh

curl \
     --header "Content-Type: application/json" \
     --header "trakt-api-version: 2" \
     --header "trakt-api-key: $CLIENT_ID" \
     --header "Authorization: Bearer $OAUTH_TOKEN" \
	"$@"
./curl.sh "https://api-v2launch.trakt.tv/users/me/collection/shows?extended=metadata" | jq -C | less

And it happens only for shows?

commented

Succeeded with the Apiary requests. The returned list of episodes is correct, it only returns actually collected episodes.

I've checked the code as well (even PyTrakt) and I think it must be failing when retrieving the seasons of the show from the collection:

  1. show_collection is called and afterwards iterates over shows and seasons:
    for show in self.show_collection:
    for season in show.seasons:
    yield from season.episodes
  2. show_collection executes API call and extracts JSON data. I think here the seasons/episodes aren't being populated as they should be:
    https://github.com/moogar0880/PyTrakt/blob/8a6d4f168a858447014fb4c2c0efceb47b30ebb7/trakt/users.py#L375
  3. When retrieving seasons from the TVShow class it checks if it already contains seasons, else it will call the API for ALL seasons: https://github.com/moogar0880/PyTrakt/blob/8a6d4f168a858447014fb4c2c0efceb47b30ebb7/trakt/tv.py#L382
    (I see calls for Season and Episode data in the DEBUG logs, right before the collection removal logs; although I just noticed after writing all this that the "extended" parameter isn't the same as in this method...)
2023-04-12 12:03:57,965 DEBUG[trakt.core]:get: https://api-v2launch.trakt.tv/shows/33089/seasons?extended=episodes
2023-04-12 12:03:57,966 DEBUG[trakt.core]:method, url :: get, https://api-v2launch.trakt.tv/shows/33089/seasons?extended=episodes
2023-04-12 12:03:57,968 DEBUG[requests_cache.policy.actions]:Cache directives from request headers: CacheDirectives()
2023-04-12 12:03:57,968 DEBUG[requests_cache.policy.expiration]:URL https://api-v2launch.trakt.tv/shows/33089/seasons?extended=episodes matched pattern "*.trakt.tv/shows/*/seasons": 3674576450094852
2023-04-12 12:03:57,968 DEBUG[requests_cache.policy.actions]:Pre-read cache checks: disabled by expiration
2023-04-12 12:03:57,969 DEBUG[requests_cache.policy.actions]:Post-read cache actions: CacheActions(expire_after=3674576450094852, send_request=True, skip_read=True)
2023-04-12 12:03:57,993 DEBUG[urllib3.connectionpool]:https://api-v2launch.trakt.tv:443 "GET /shows/33089/seasons?extended=episodes HTTP/1.1" 200 None
2023-04-12 12:03:57,996 DEBUG[requests_cache.policy.actions]:Pre-write cache checks: disabled by expiration
2023-04-12 12:03:57,996 DEBUG[requests_cache.session]:Skipping cache write for URL: https://api-v2launch.trakt.tv/shows/33089/seasons?extended=episodes
2023-04-12 12:03:57,996 DEBUG[trakt.core]:RESPONSE [get] (https://api-v2launch.trakt.tv/shows/33089/seasons?extended=episodes): <Response [200]>
2023-04-12 12:03:57,997 DEBUG[trakt.core]:get: https://api-v2launch.trakt.tv/shows/614/seasons?extended=episodes
2023-04-12 12:03:57,997 DEBUG[trakt.core]:method, url :: get, https://api-v2launch.trakt.tv/shows/614/seasons?extended=episodes
2023-04-12 12:03:58,000 DEBUG[requests_cache.policy.actions]:Cache directives from request headers: CacheDirectives()
2023-04-12 12:03:58,000 DEBUG[requests_cache.policy.expiration]:URL https://api-v2launch.trakt.tv/shows/614/seasons?extended=episodes matched pattern "*.trakt.tv/shows/*/seasons": 3674576450094852
2023-04-12 12:03:58,000 DEBUG[requests_cache.policy.actions]:Pre-read cache checks: disabled by expiration
2023-04-12 12:03:58,000 DEBUG[requests_cache.policy.actions]:Post-read cache actions: CacheActions(expire_after=3674576450094852, send_request=True, skip_read=True)
2023-04-12 12:03:58,026 DEBUG[urllib3.connectionpool]:https://api-v2launch.trakt.tv:443 "GET /shows/614/seasons?extended=episodes HTTP/1.1" 200 None
2023-04-12 12:03:58,028 DEBUG[requests_cache.policy.actions]:Pre-write cache checks: disabled by expiration
2023-04-12 12:03:58,028 DEBUG[requests_cache.session]:Skipping cache write for URL: https://api-v2launch.trakt.tv/shows/614/seasons?extended=episodes
2023-04-12 12:03:58,028 DEBUG[trakt.core]:RESPONSE [get] (https://api-v2launch.trakt.tv/shows/614/seasons?extended=episodes): <Response [200]>
2023-04-12 12:03:58,042 INFO[PlexTraktSync]:Remove from Trakt collection (1/3188): <TVEpisode>: The Mandalorian S3E8 Chapter 24
2023-04-12 12:03:58,054 INFO[PlexTraktSync]:Remove from Trakt collection (2/3188): <TVEpisode>: Ted Lasso S0E1 The Missing Christmas Mustache
2023-04-12 12:03:58,057 INFO[PlexTraktSync]:Remove from Trakt collection (3/3188): <TVEpisode>: Ted Lasso S3E6 Every Disadvantage Has Its Advantage
2023-04-12 12:03:58,061 INFO[PlexTraktSync]:Remove from Trakt collection (4/3188): <TVEpisode>: Ted Lasso S3E7 Ola's
2023-04-12 12:03:58,065 INFO[PlexTraktSync]:Remove from Trakt collection (5/3188): <TVEpisode>: Ted Lasso S3E8 We'll Never Have Paris

I have a feeling the extraction of collected seasons and episodes doesn't work as expected in PyTrakt, but I can't understand python enough to deduct:

  • Not sure how the Season Number is being assigned. I don't see how it is retrieved from the "number" key/value in the JSON.
  • Maybe JSON-extraction just fails and _seasons remains None, which results in retrieval of ALL seasons.

JSON example structure:
afbeelding

The bug appeared in pytrakt 3.4.19 with PR glensc/python-pytrakt#24
Lines 376 to 379 have been removed, they should be restored :

https://github.com/glensc/python-pytrakt/blob/ab5ea09eae1fc37c252958472e1df7c93a645d1c/trakt/users.py#L369-L381

Fixed with 0.26.2