The downloaded lists are now taken from the user's liked lists, not defined in source anymore
MODIFY
plex.py
plex.py
import trakt.sync
import trakt.users
import trakt.core
-import trakt_show_progress
from dotenv import load_dotenv
from os import getenv
import logging
from time import time
-from plexapi.exceptions import BadRequest, NotFound
+
+
+import trakt_show_progress
+from trakt_list_util import TraktListUtil
import requests
import requests_cache
@@ -85,12 +87,10 @@ def process_single_movie(plex_movie, trakt_watched, trakt_ratings, trakt_collect
-def process_movie_section(s, watched_set, ratings_dict, watchlist, collection):
+def process_movie_section(s, watched_set, ratings_dict, listutil, collection):
# args: a section of plex movies, a set comprised of the slugs of all watched movies and a dict with key=slug and value=rating (1-10)
- # plex movies to be added to the watchlist
- # will be returned
- plex_watchlist = []
+
###############
# Sync movies with trakt
###############
@@ -159,15 +159,13 @@ def process_movie_section(s, watched_set, ratings_dict, watchlist, collection):
logging.info("Movie [{} ({})]: marking as watched in Plex...".format(movie.title, movie.year))
with requests_cache.disabled():
movie.markWatched()
- # add to plex watchlist
- if m.slug in watchlist:
- plex_watchlist.append(movie)
- logging.info('Movie [{} ({})]: added to watchlist'.format(movie.title, movie.year))
+ # add to plex lists
+ listutil.addPlexMovieToLists(m.slug, movie)
logging.info("Movie [{} ({})]: sync complete".format(movie.title, movie.year))
except trakt.errors.NotFoundException:
logging.error("Movie [{} ({})]: NOT FOUND on trakt - GUID: {}".format(movie.title, movie.year, guid))
- return plex_watchlist
+
def process_single_show(show):
guid = show.guid
@@ -305,16 +303,20 @@ def main():
start_time = time()
load_dotenv()
logging.basicConfig(format='%(asctime)s %(levelname)s:%(message)s', filename='last_update.log', filemode='w', level=logging.INFO)
+ listutil = TraktListUtil()
# do not use the cache for account specific stuff as this is subject to change
with requests_cache.disabled():
+ liked_lists = trakt_show_progress.get_liked_lists()
trakt_user = trakt.users.User(getenv('TRAKT_USERNAME'))
trakt_watched_movies = set(map(lambda m: m.slug, trakt_user.watched_movies))
logging.debug("Watched movies from trakt: {}".format(trakt_watched_movies))
trakt_movie_collection = set(map(lambda m: m.slug, trakt_user.movie_collection))
#logging.debug("Movie collection from trakt:", trakt_movie_collection)
- trakt_movie_watchlist = set(map(lambda m: m.slug, trakt_user.watchlist_movies))
+ listutil.addList(None, "Trakt Watchlist", list_set=set(map(lambda m: m.slug, trakt_user.watchlist_movies)))
#logging.debug("Movie watchlist from trakt:", trakt_movie_watchlist)
user_ratings = trakt_user.get_ratings(media_type='movies')
+ for lst in liked_lists:
+ listutil.addList(lst['username'], lst['listname'])
ratings = {}
for r in user_ratings:
ratings[r['movie']['ids']['slug']] = r['rating']
@@ -328,8 +330,7 @@ def main():
logging.info("Server version {} updated at: {}".format(plex.version, plex.updatedAt))
logging.info("Recently added: {}".format(plex.library.recentlyAdded()[:5]))
- # collect the watchlist items in loop, then recreate it afterwards
- plex_watchlist = []
+
with requests_cache.disabled():
sections = plex.library.sections()
for section in sections:
@@ -338,7 +339,7 @@ def main():
if type(section) is plexapi.library.MovieSection:
#clean_collections_in_section(section)
print("Processing section", section.title)
- plex_watchlist += process_movie_section(section, trakt_watched_movies, ratings, trakt_movie_watchlist, trakt_movie_collection)
+ process_movie_section(section, trakt_watched_movies, ratings, listutil, trakt_movie_collection)
# process show sections
elif type(section) is plexapi.library.ShowSection:
print("Processing section", section.title)
@@ -349,15 +350,7 @@ def main():
timedelta = time() - section_start_time
logging.warning("Completed section sync in {} s".format(timedelta))
- try:
- with requests_cache.disabled():
- plex.playlist('trakt_watchlist').delete()
- except (NotFound, BadRequest):
- with requests_cache.disabled():
- logging.error("Playlist 'trakt_watchlist' not found, so it could not be deleted. Actual playlists: %s" % plex.playlists())
- pass
- with requests_cache.disabled():
- plex.createPlaylist('trakt_watchlist', items=plex_watchlist)
+ listutil.updatePlexLists(plex)
logging.info("Updated plex watchlist")
timedelta = time() - start_time
logging.info("Completed full sync in {} seconds".format(timedelta))

ADD
trakt_list_util.py
+from trakt.users import UserList
+from trakt.errors import NotFoundException
+from trakt.movies import Movie
+import requests_cache
+import logging
+from plexapi.exceptions import BadRequest, NotFound
+
+class TraktList():
+ def __init__(self, username, listname):
+ self.name = listname
+ self.plex_movies = []
+ if username != None:
+ self.slugs = set(map(lambda m: m.slug, [elem for elem in UserList._get(listname, username).get_items() if type(elem) == Movie]))
+
+ @staticmethod
+ def from_set(listname, list_set):
+ l = TraktList(None, listname)
+ l.slugs = list_set
+ return l
+
+ def addPlexMovie(self, slug, plex_movie):
+ if slug in self.slugs:
+ self.plex_movies.append(plex_movie)
+ logging.info('Movie [{} ({})]: added to list {}'.format(plex_movie.title, plex_movie.year, self.name))
+
+ def updatePlexList(self, plex):
+ with requests_cache.disabled():
+ try:
+ plex.playlist(self.name).delete()
+ except (NotFound, BadRequest):
+ logging.error("Playlist %s not found, so it could not be deleted. Actual playlists: %s" % (self.name, plex.playlists()))
+ pass
+ plex.createPlaylist(self.name, items=self.plex_movies)
+
+
+class TraktListUtil():
+ def __init__(self):
+ self.lists = []
+
+ def addList(self, username, listname, list_set = None):
+ if list_set is not None:
+ self.lists.append(TraktList.from_set(listname, list_set))
+ logging.info("Downloaded List {}".format(listname))
+ return
+ try:
+ self.lists.append(TraktList(username, listname))
+ logging.info("Downloaded List {}".format(listname))
+ except NotFoundException:
+ logging.warning("Failed to get list {} by user {}".format(listname, username))
+
+ def addPlexMovieToLists(self, slug, plex_movie):
+ for l in self.lists:
+ l.addPlexMovie(slug, plex_movie)
+
+ def updatePlexLists(self, plex):
+ for l in self.lists:
+ l.updatePlexList(plex)

MODIFY
trakt_show_progress.py
trakt_show_progress.py
from trakt.core import get
from trakt.tv import TVEpisode
+@get
+def get_liked_lists():
+ data = yield 'users/likes/lists'
+ retVal = []
+ for lst in data:
+ thisList = {}
+ thisList['listname'] = lst['list']['name']
+ thisList['username'] = lst['list']['user']['ids']['slug']
+ retVal.append(thisList)
+ yield retVal
+
+
@get
def lookup_table(show):
# returns all seasons and episodes with one single call
@@ -102,5 +114,4 @@ def get_completed(self, season, episode):
if __name__ == "__main__":
- watched_got = all_episodes('game-of-thrones')
- print(watched_got.get_completed(8, 6))
\ No newline at end of file
+ print(get_liked_lists())
\ No newline at end of file

The downloaded lists are now taken from the user's liked lists, not defined in source anymore