diff --git a/.env.sample b/.env.sample index 2519263..5a725fc 100644 --- a/.env.sample +++ b/.env.sample @@ -2,7 +2,8 @@ DRYRUN = "True" DEBUG = "True" SLEEP_DURATION = "3600" LOGFILE = "log.log" -#USER_MAPPING = { "test2": "test" } +#USER_MAPPING = { "testuser2": "testuser3" } +#LIBRARY_MAPPING = { "Shows": "TV Shows" } PLEX_BASEURL = "http://localhost:32400" PLEX_TOKEN = "SuperSecretToken" diff --git a/main.py b/main.py index 0fa4925..5d47dc8 100644 --- a/main.py +++ b/main.py @@ -8,63 +8,73 @@ from src.jellyfin import Jellyfin load_dotenv(override=True) -def cleanup_watched(watched_list_1, watched_list_2, user_mapping): +def cleanup_watched(watched_list_1, watched_list_2, user_mapping=None, library_mapping=None): modified_watched_list_1 = copy.deepcopy(watched_list_1) # remove entries from plex_watched that are in jellyfin_watched for user_1 in watched_list_1: - user_2 = search_mapping(user_mapping, user_1) + user_other = None + if user_mapping: + user_other = search_mapping(user_mapping, user_1) if user_1 in modified_watched_list_1: - for library in watched_list_1[user_1]: - if library in modified_watched_list_1[user_1]: - for item in watched_list_1[user_1][library]: - if item in modified_watched_list_1[user_1][library]: - if user_1 in watched_list_2: - user = user_1 - elif user_2 in watched_list_2: - user = user_2 - else: - logger(f"User {user_1} and {user_2} not found in watched list 2", 1) - user = None - - if user: - if library in watched_list_2[user]: - # Movies - if isinstance(watched_list_1[user_1][library], list): - for watch_list_1_key, watch_list_1_value in item.items(): - for watch_list_2_item in watched_list_2[user][library]: - for watch_list_2_item_key, watch_list_2_item_value in watch_list_2_item.items(): - if watch_list_1_key == watch_list_2_item_key and watch_list_1_value == watch_list_2_item_value: - if item in modified_watched_list_1[user_1][library]: - modified_watched_list_1[user_1][library].remove(item) - - # TV Shows - elif isinstance(watched_list_1[user_1][library], dict): - if item in watched_list_2[user][library]: - for season in watched_list_1[user_1][library][item]: - if season in watched_list_2[user][library][item]: - for episode in watched_list_1[user_1][library][item][season]: - for watch_list_1_episode_key, watch_list_1_episode_value in episode.items(): - for watch_list_2_episode in watched_list_2[user][library][item][season]: - for watch_list_2_episode_key, watch_list_2_episode_value in watch_list_2_episode.items(): - if watch_list_1_episode_key == watch_list_2_episode_key and watch_list_1_episode_value == watch_list_2_episode_value: - if episode in modified_watched_list_1[user_1][library][item][season]: - modified_watched_list_1[user_1][library][item][season].remove(episode) - - # If season is empty, remove season - if len(modified_watched_list_1[user_1][library][item][season]) == 0: - if season in modified_watched_list_1[user_1][library][item]: - del modified_watched_list_1[user_1][library][item][season] + if user_1 in watched_list_2: + user_2 = user_1 + elif user_other in watched_list_2: + user_2 = user_other + else: + logger(f"User {user_1} and {user_other} not found in watched list 2", 1) + continue - # If the show is empty, remove the show - if len(modified_watched_list_1[user_1][library][item]) == 0: - if item in modified_watched_list_1[user_1][library]: - del modified_watched_list_1[user_1][library][item] + for library_1 in watched_list_1[user_1]: + library_other = None + if library_mapping: + library_other = search_mapping(library_mapping, library_1) + if library_1 in modified_watched_list_1[user_1]: + if library_1 in watched_list_2[user_2]: + library_2 = library_1 + elif library_other in watched_list_2[user_2]: + library_2 = library_other + else: + logger(f"User {library_1} and {library_other} not found in watched list 2", 1) + continue + for item in watched_list_1[user_1][library_1]: + if item in modified_watched_list_1[user_1][library_1]: + # Movies + if isinstance(watched_list_1[user_1][library_1], list): + for watch_list_1_key, watch_list_1_value in item.items(): + for watch_list_2_item in watched_list_2[user_2][library_2]: + for watch_list_2_item_key, watch_list_2_item_value in watch_list_2_item.items(): + if watch_list_1_key == watch_list_2_item_key and watch_list_1_value == watch_list_2_item_value: + if item in modified_watched_list_1[user_1][library_1]: + modified_watched_list_1[user_1][library_1].remove(item) + + # TV Shows + elif isinstance(watched_list_1[user_1][library_1], dict): + if item in watched_list_2[user_2][library_2]: + for season in watched_list_1[user_1][library_1][item]: + if season in watched_list_2[user_2][library_2][item]: + for episode in watched_list_1[user_1][library_1][item][season]: + for watch_list_1_episode_key, watch_list_1_episode_value in episode.items(): + for watch_list_2_episode in watched_list_2[user_2][library_2][item][season]: + for watch_list_2_episode_key, watch_list_2_episode_value in watch_list_2_episode.items(): + if watch_list_1_episode_key == watch_list_2_episode_key and watch_list_1_episode_value == watch_list_2_episode_value: + if episode in modified_watched_list_1[user_1][library_1][item][season]: + modified_watched_list_1[user_1][library_1][item][season].remove(episode) + + # If season is empty, remove season + if len(modified_watched_list_1[user_1][library_1][item][season]) == 0: + if season in modified_watched_list_1[user_1][library_1][item]: + del modified_watched_list_1[user_1][library_1][item][season] + + # If the show is empty, remove the show + if len(modified_watched_list_1[user_1][library_1][item]) == 0: + if item in modified_watched_list_1[user_1][library_1]: + del modified_watched_list_1[user_1][library_1][item] # If library is empty then remove it - if len(modified_watched_list_1[user_1][library]) == 0: - if library in modified_watched_list_1[user_1]: - del modified_watched_list_1[user_1][library] + if len(modified_watched_list_1[user_1][library_1]) == 0: + if library_1 in modified_watched_list_1[user_1]: + del modified_watched_list_1[user_1][library_1] # If user is empty delete user if len(modified_watched_list_1[user_1]) == 0: @@ -72,21 +82,38 @@ def cleanup_watched(watched_list_1, watched_list_2, user_mapping): return modified_watched_list_1 -def setup_black_white_lists(): +def setup_black_white_lists(library_mapping=None): blacklist_library = os.getenv("BLACKLIST_LIBRARY") if blacklist_library: if len(blacklist_library) > 0: blacklist_library = blacklist_library.split(",") - blacklist_library = [x.lower().trim() for x in blacklist_library] + blacklist_library = [x.strip() for x in blacklist_library] + if library_mapping: + temp_library = [] + for library in blacklist_library: + library_other = search_mapping(library_mapping, library) + if library_other: + temp_library.append(library_other) + + blacklist_library = blacklist_library + temp_library else: blacklist_library = [] + logger(f"Blacklist Library: {blacklist_library}", 1) whitelist_library = os.getenv("WHITELIST_LIBRARY") if whitelist_library: if len(whitelist_library) > 0: whitelist_library = whitelist_library.split(",") - whitelist_library = [x.lower().strip() for x in whitelist_library] + whitelist_library = [x.strip() for x in whitelist_library] + if library_mapping: + temp_library = [] + for library in whitelist_library: + library_other = search_mapping(library_mapping, library) + if library_other: + temp_library.append(library_other) + + whitelist_library = whitelist_library + temp_library else: whitelist_library = [] logger(f"Whitelist Library: {whitelist_library}", 1) @@ -113,7 +140,7 @@ def setup_black_white_lists(): if blacklist_users: if len(blacklist_users) > 0: blacklist_users = blacklist_users.split(",") - blacklist_users = [x.lower().strip() for x in blacklist_users] + blacklist_users = [x.lower().strip() for x in blacklist_users] else: blacklist_users = [] logger(f"Blacklist Users: {blacklist_users}", 1) @@ -145,7 +172,7 @@ def setup_users(plex, jellyfin, blacklist_users, whitelist_users, user_mapping=N jellyfin_plex_mapped_user = search_mapping(user_mapping, plex_user) if jellyfin_plex_mapped_user: users[plex_user] = jellyfin_plex_mapped_user - break + continue if plex_user in jellyfin_users: users[plex_user] = plex_user @@ -155,7 +182,7 @@ def setup_users(plex, jellyfin, blacklist_users, whitelist_users, user_mapping=N plex_jellyfin_mapped_user = search_mapping(user_mapping, jellyfin_user) if plex_jellyfin_mapped_user: users[plex_jellyfin_mapped_user] = jellyfin_user - break + continue if jellyfin_user in plex_users: users[jellyfin_user] = jellyfin_user @@ -168,7 +195,7 @@ def setup_users(plex, jellyfin, blacklist_users, whitelist_users, user_mapping=N if len(whitelist_users) > 0: if user not in whitelist_users and users[user] not in whitelist_users: logger(f"{user} or {users[user]} is not in whitelist", 1) - break + continue if user not in blacklist_users and users[user] not in blacklist_users: users_filtered[user] = users[user] @@ -186,10 +213,10 @@ def setup_users(plex, jellyfin, blacklist_users, whitelist_users, user_mapping=N jellyfin_users[jellyfin_user] = jellyfin_id if len(plex_users) == 0: - raise Exception("No plex users found") + raise Exception(f"No plex users found, users found {users} filtered users {users_filtered}") if len(jellyfin_users) == 0: - raise Exception("No jellyfin users found") + raise Exception(f"No jellyfin users found, users found {users} filtered users {users_filtered}") logger(f"plex_users: {plex_users}", 1) logger(f"jellyfin_users: {jellyfin_users}", 1) @@ -209,32 +236,37 @@ def main(): if user_mapping: user_mapping = json.loads(user_mapping.lower()) logger(f"User Mapping: {user_mapping}", 1) - + + library_mapping = os.getenv("LIBRARY_MAPPING") + if library_mapping: + library_mapping = json.loads(library_mapping) + logger(f"Library Mapping: {library_mapping}", 1) + plex = Plex() jellyfin = Jellyfin() # Create (black/white)lists - blacklist_library, whitelist_library, blacklist_library_type, whitelist_library_type, blacklist_users, whitelist_users = setup_black_white_lists() + blacklist_library, whitelist_library, blacklist_library_type, whitelist_library_type, blacklist_users, whitelist_users = setup_black_white_lists(library_mapping) # Create users list plex_users, jellyfin_users = setup_users(plex, jellyfin, blacklist_users, whitelist_users, user_mapping) - plex_watched = plex.get_plex_watched(plex_users, blacklist_library, whitelist_library, blacklist_library_type, whitelist_library_type) - jellyfin_watched = jellyfin.get_jellyfin_watched(jellyfin_users, blacklist_library, whitelist_library, blacklist_library_type, whitelist_library_type) + plex_watched = plex.get_plex_watched(plex_users, blacklist_library, whitelist_library, blacklist_library_type, whitelist_library_type, library_mapping) + jellyfin_watched = jellyfin.get_jellyfin_watched(jellyfin_users, blacklist_library, whitelist_library, blacklist_library_type, whitelist_library_type, library_mapping) # clone watched so it isnt modified in the cleanup function so all duplicates are actually removed plex_watched_filtered = copy.deepcopy(plex_watched) jellyfin_watched_filtered = copy.deepcopy(jellyfin_watched) - plex_watched = cleanup_watched(plex_watched_filtered, jellyfin_watched_filtered, user_mapping) + plex_watched = cleanup_watched(plex_watched_filtered, jellyfin_watched_filtered, user_mapping, library_mapping) logger(f"plex_watched that needs to be synced to jellyfin:\n{plex_watched}", 1) - jellyfin_watched = cleanup_watched(jellyfin_watched_filtered, plex_watched_filtered, user_mapping) + jellyfin_watched = cleanup_watched(jellyfin_watched_filtered, plex_watched_filtered, user_mapping, library_mapping) logger(f"jellyfin_watched that needs to be synced to plex:\n{jellyfin_watched}", 1) # Update watched status - plex.update_watched(jellyfin_watched, user_mapping, dryrun) - jellyfin.update_watched(plex_watched, user_mapping, dryrun) + plex.update_watched(jellyfin_watched, user_mapping, library_mapping, dryrun) + jellyfin.update_watched(plex_watched, user_mapping, library_mapping, dryrun) if __name__ == "__main__": @@ -259,4 +291,4 @@ if __name__ == "__main__": logger("Exiting", log_type=0) os._exit(0) - sleep(sleep_timer) \ No newline at end of file + sleep(sleep_timer) diff --git a/src/jellyfin.py b/src/jellyfin.py index d502014..4b15fa5 100644 --- a/src/jellyfin.py +++ b/src/jellyfin.py @@ -1,6 +1,6 @@ import requests, os from dotenv import load_dotenv -from src.functions import logger, search_mapping +from src.functions import logger, search_mapping, str_to_bool load_dotenv(override=True) @@ -56,7 +56,7 @@ class Jellyfin(): return users - def get_jellyfin_watched(self, users, blacklist_library, whitelist_library, blacklist_library_type, whitelist_library_type): + def get_jellyfin_watched(self, users, blacklist_library, whitelist_library, blacklist_library_type, whitelist_library_type, library_mapping=None): users_watched = {} for user_name, user_id in users.items(): @@ -67,82 +67,105 @@ class Jellyfin(): for library in libraries: library_title = library["Name"] - library_id = library["Id"] - # if whitelist is not empty and library is not in whitelist - if len(whitelist_library) > 0 and library_title.lower() not in whitelist_library: - pass + watched = self.query(f"/Users/{user_id}/Items?SortBy=SortName&SortOrder=Ascending&Recursive=true&ParentId={library_id}&Filters=IsPlayed&limit=1", "get") + + if len(watched["Items"]) == 0: + logger(f"Jellyfin: No watched items found in library {library_title}", 1) + continue else: - logger(f"Jellyfin: Generating watched for {user_name} in library {library_title}", 0) + library_type = watched["Items"][0]["Type"] - if library_title.lower() not in blacklist_library: - watched = self.query(f"/Users/{user_id}/Items?SortBy=SortName&SortOrder=Ascending&Recursive=true&ParentId={library_id}&Filters=IsPlayed&limit=1", "get") - - if len(watched["Items"]) == 0: - pass - else: - library_type = watched["Items"][0]["Type"] + if library_type.lower() in blacklist_library_type: + logger(f"Jellyfin: Library type {library_type} is blacklist_library_type", 1) + continue - # if Type in blacklist_library_type then break - if library_type in blacklist_library_type or (len(whitelist_library_type) > 0 and library_type.lower() not in whitelist_library_type): - break - - # Movies - if library_type == "Movie": - watched = self.query(f"/Users/{user_id}/Items?SortBy=SortName&SortOrder=Ascending&Recursive=true&ParentId={library_id}&Filters=IsPlayed&Fields=ItemCounts,ProviderIds", "get") - for movie in watched["Items"]: - if movie["UserData"]["Played"] == True: - if movie["ProviderIds"]: - if user_name not in users_watched: - users_watched[user_name] = {} - if library_title not in users_watched[user_name]: - users_watched[user_name][library_title] = [] - # Lowercase movie["ProviderIds"] keys - movie["ProviderIds"] = {k.lower(): v for k, v in movie["ProviderIds"].items()} - users_watched[user_name][library_title].append(movie["ProviderIds"]) + if library_title.lower() in [x.lower() for x in blacklist_library]: + logger(f"Jellyfin: Library {library_title} is blacklist_library", 1) + continue - # TV Shows - if library_type == "Episode": - watched = self.query(f"/Users/{user_id}/Items?SortBy=SortName&SortOrder=Ascending&Recursive=true&ParentId={library_id}", "get") - watched_shows = [x for x in watched["Items"] if x["Type"] == "Series"] + library_other = None + if library_mapping: + library_other = search_mapping(library_mapping, library_title) + if library_other: + library_other.lower() + if library_other not in [x.lower() for x in blacklist_library]: + logger(f"Jellyfin: Library {library_other} is blacklist_library", 1) + continue - for show in watched_shows: - seasons = self.query(f"/Shows/{show['Id']}/Seasons?userId={user_id}&Fields=ItemCounts", "get") - if len(seasons["Items"]) > 0: - for season in seasons["Items"]: - episodes = self.query(f"/Shows/{show['Id']}/Episodes?seasonId={season['Id']}&userId={user_id}&Fields=ItemCounts,ProviderIds", "get") - if len(episodes["Items"]) > 0: - for episode in episodes["Items"]: - if episode["UserData"]["Played"] == True: - if episode["ProviderIds"]: - if user_name not in users_watched: - users_watched[user_name] = {} - if library_title not in users_watched[user_name]: - users_watched[user_name][library_title] = {} - if show["Name"] not in users_watched[user_name][library_title]: - users_watched[user_name][library_title][show["Name"]] = {} - if season["Name"] not in users_watched[user_name][library_title][show["Name"]]: - users_watched[user_name][library_title][show["Name"]][season["Name"]] = [] - - # Lowercase episode["ProviderIds"] keys - episode["ProviderIds"] = {k.lower(): v for k, v in episode["ProviderIds"].items()} - users_watched[user_name][library_title][show["Name"]][season["Name"]].append(episode["ProviderIds"]) + if len(whitelist_library_type) > 0: + if library_type.lower() not in whitelist_library_type: + logger(f"Jellyfin: Library type {library_type} is not whitelist_library_type", 1) + continue + + # if whitelist is not empty and library is not in whitelist + if len(whitelist_library) > 0: + if library_title.lower() not in [x.lower() for x in whitelist_library]: + logger(f"Jellyfin: Library {library_title} is not whitelist_library", 1) + continue + + if library_other: + if library_other not in [x.lower() for x in whitelist_library]: + logger(f"Jellyfin: Library {library_other} is not whitelist_library", 1) + continue + + logger(f"Jellyfin: Generating watched for {user_name} in library {library_title}", 0) + # Movies + if library_type == "Movie": + watched = self.query(f"/Users/{user_id}/Items?SortBy=SortName&SortOrder=Ascending&Recursive=true&ParentId={library_id}&Filters=IsPlayed&Fields=ItemCounts,ProviderIds", "get") + for movie in watched["Items"]: + if movie["UserData"]["Played"] == True: + if movie["ProviderIds"]: + if user_name not in users_watched: + users_watched[user_name] = {} + if library_title not in users_watched[user_name]: + users_watched[user_name][library_title] = [] + # Lowercase movie["ProviderIds"] keys + movie["ProviderIds"] = {k.lower(): v for k, v in movie["ProviderIds"].items()} + users_watched[user_name][library_title].append(movie["ProviderIds"]) + + # TV Shows + if library_type == "Episode": + watched = self.query(f"/Users/{user_id}/Items?SortBy=SortName&SortOrder=Ascending&Recursive=true&ParentId={library_id}", "get") + watched_shows = [x for x in watched["Items"] if x["Type"] == "Series"] + + for show in watched_shows: + seasons = self.query(f"/Shows/{show['Id']}/Seasons?userId={user_id}&Fields=ItemCounts", "get") + if len(seasons["Items"]) > 0: + for season in seasons["Items"]: + episodes = self.query(f"/Shows/{show['Id']}/Episodes?seasonId={season['Id']}&userId={user_id}&Fields=ItemCounts,ProviderIds", "get") + if len(episodes["Items"]) > 0: + for episode in episodes["Items"]: + if episode["UserData"]["Played"] == True: + if episode["ProviderIds"]: + if user_name not in users_watched: + users_watched[user_name] = {} + if library_title not in users_watched[user_name]: + users_watched[user_name][library_title] = {} + if show["Name"] not in users_watched[user_name][library_title]: + users_watched[user_name][library_title][show["Name"]] = {} + if season["Name"] not in users_watched[user_name][library_title][show["Name"]]: + users_watched[user_name][library_title][show["Name"]][season["Name"]] = [] + + # Lowercase episode["ProviderIds"] keys + episode["ProviderIds"] = {k.lower(): v for k, v in episode["ProviderIds"].items()} + users_watched[user_name][library_title][show["Name"]][season["Name"]].append(episode["ProviderIds"]) return users_watched - def update_watched(self, watched_list, user_mapping=None, dryrun=False): + def update_watched(self, watched_list, user_mapping=None, library_mapping=None, dryrun=False): for user, libraries in watched_list.items(): if user_mapping: - other = None + user_other = None if user in user_mapping.keys(): - other = user_mapping[user] + user_other = user_mapping[user] elif user in user_mapping.values(): - other = search_mapping(user_mapping, user) + user_other = search_mapping(user_mapping, user) - if other: - logger(f"Swapping user {user} with {other}", 1) - user = other + if user_other: + logger(f"Swapping user {user} with {user_other}", 1) + user = user_other user_id = None for key, value in self.users.items(): @@ -157,13 +180,30 @@ class Jellyfin(): jellyfin_libraries = self.query(f"/Users/{user_id}/Views", "get")["Items"] for library, videos in libraries.items(): + if library_mapping: + library_other = None + + if library in library_mapping.keys(): + library_other = library_mapping[library] + elif library in library_mapping.values(): + library_other = search_mapping(library_mapping, library) + + if library_other: + logger(f"Swapping library {library} with {library_other}", 1) + library = library_other + + if library not in [x["Name"] for x in jellyfin_libraries]: + logger(f"{library} not found in Jellyfin", 2) + continue + library_id = None for jellyfin_library in jellyfin_libraries: if jellyfin_library["Name"] == library: library_id = jellyfin_library["Id"] - break + continue if library_id: + logger(f"Jellyfin: Updating watched for {user} in library {library}", 1) library_search = self.query(f"/Users/{user_id}/Items?SortBy=SortName&SortOrder=Ascending&Recursive=true&ParentId={library_id}&limit=1", "get") library_type = library_search["Items"][0]["Type"] @@ -171,12 +211,12 @@ class Jellyfin(): if library_type == "Movie": jellyfin_search = self.query(f"/Users/{user_id}/Items?SortBy=SortName&SortOrder=Ascending&Recursive=true&ParentId={library_id}&isPlayed=false&Fields=ItemCounts,ProviderIds", "get") for jellyfin_video in jellyfin_search["Items"]: - if jellyfin_video["UserData"]["Played"] == False: + if str_to_bool(jellyfin_video["UserData"]["Played"]) == False: jellyfin_video_id = jellyfin_video["Id"] for video in videos: for key, value in jellyfin_video["ProviderIds"].items(): if key.lower() in video.keys() and value.lower() == video[key.lower()].lower(): - msg = f"{jellyfin_video['Name']} as watched for {user} in Jellyfin" + msg = f"{jellyfin_video['Name']} as watched for {user} in {library} for Jellyfin" if not dryrun: logger(f"Marking {msg}", 0) self.query(f"/Users/{user_id}/PlayedItems/{jellyfin_video_id}", "post") @@ -194,18 +234,17 @@ class Jellyfin(): jellyfin_show_id = jellyfin_show["Id"] jellyfin_episodes = self.query(f"/Shows/{jellyfin_show_id}/Episodes?userId={user_id}&Fields=ItemCounts,ProviderIds", "get") for jellyfin_episode in jellyfin_episodes["Items"]: - if jellyfin_episode["UserData"]["Played"] == False: + if str_to_bool(jellyfin_episode["UserData"]["Played"]) == False: jellyfin_episode_id = jellyfin_episode["Id"] for show in videos: for season in videos[show]: for episode in videos[show][season]: for key, value in jellyfin_episode["ProviderIds"].items(): if key.lower() in episode.keys() and value.lower() == episode[key.lower()].lower(): - msg = f"{jellyfin_episode['SeriesName']} {jellyfin_episode['SeasonName']} {jellyfin_episode['Name']} as watched for {user} in Jellyfin" + msg = f"{jellyfin_episode['SeriesName']} {jellyfin_episode['SeasonName']} {jellyfin_episode['Name']} as watched for {user} in {library} for Jellyfin" if not dryrun: logger(f"Marked {msg}", 0) self.query(f"/Users/{user_id}/PlayedItems/{jellyfin_episode_id}", "post") else: logger(f"Dryrun {msg}", 0) break - \ No newline at end of file diff --git a/src/plex.py b/src/plex.py index 8460826..9efb05d 100644 --- a/src/plex.py +++ b/src/plex.py @@ -93,7 +93,7 @@ class Plex: return watched - def get_plex_watched(self, users, blacklist_library, whitelist_library, blacklist_library_type, whitelist_library_type): + def get_plex_watched(self, users, blacklist_library, whitelist_library, blacklist_library_type, whitelist_library_type, library_mapping): # Get all libraries libraries = self.plex.library.sections() users_watched = {} @@ -101,37 +101,67 @@ class Plex: # for not in blacklist for library in libraries: library_title = library.title + library_type = library.type + + if library_type.lower() in blacklist_library_type: + logger(f"Plex: Library type {library_type} is blacklist_library_type", 1) + continue + + if library_title.lower() in [x.lower() for x in blacklist_library]: + logger(f"Plex: Library {library_title} is blacklist_library", 1) + continue + + library_other = None + if library_mapping: + library_other = search_mapping(library_mapping, library_title) + if library_other: + library_other.lower() + if library_other not in [x.lower() for x in blacklist_library]: + logger(f"Plex: Library {library_other} is blacklist_library", 1) + continue + + if len(whitelist_library_type) > 0: + if library_type.lower() not in whitelist_library_type: + logger(f"Plex: Library type {library_type} is not whitelist_library_type", 1) + continue + # if whitelist is not empty and library is not in whitelist - if (len(whitelist_library) > 0 and library_title.lower() not in [x.lower() for x in whitelist_library]) or (len(whitelist_library_type) > 0 and library_title.type() not in [x.lower() for x in whitelist_library_type]): - pass - else: - if library_title.lower() not in [x.lower() for x in blacklist_library] and library.type not in [x.lower() for x in blacklist_library_type]: - for user in users: - logger(f"Plex: Generating watched for {user.title} in library {library_title}", 0) - user_name = user.title.lower() - watched = self.get_plex_user_watched(user, library) - if watched: - if user_name not in users_watched: - users_watched[user_name] = {} - if library_title not in users_watched[user_name]: - users_watched[user_name][library_title] = [] - users_watched[user_name][library_title] = watched + if len(whitelist_library) > 0: + if library_title.lower() not in [x.lower() for x in whitelist_library]: + logger(f"Plex: Library {library_title} is not whitelist_library", 1) + continue + + if library_other: + if library_other not in [x.lower() for x in whitelist_library]: + logger(f"Plex: Library {library_other} is not whitelist_library", 1) + continue + + for user in users: + logger(f"Plex: Generating watched for {user.title} in library {library_title}", 0) + user_name = user.title.lower() + watched = self.get_plex_user_watched(user, library) + if watched: + if user_name not in users_watched: + users_watched[user_name] = {} + if library_title not in users_watched[user_name]: + users_watched[user_name][library_title] = [] + users_watched[user_name][library_title] = watched return users_watched - def update_watched(self, watched_list, user_mapping=None, dryrun=False): + def update_watched(self, watched_list, user_mapping=None, library_mapping=None, dryrun=False): for user, libraries in watched_list.items(): if user_mapping: - other = None + user_other = None if user in user_mapping.keys(): - other = user_mapping[user] + user_other = user_mapping[user] elif user in user_mapping.values(): - other = search_mapping(user_mapping, user) + user_other = search_mapping(user_mapping, user) - if other: - logger(f"Swapping user {user} with {other}", 1) - user = other + if user_other: + logger(f"Swapping user {user} with {user_other}", 1) + user = user_other for index, value in enumerate(self.users): if user.lower() == value.title.lower(): @@ -143,10 +173,28 @@ class Plex: else: user_plex = PlexServer(self.baseurl, user.get_token(self.plex.machineIdentifier)) - logger(f"Updating watched for {user.title}", 1) for library, videos in libraries.items(): + if library_mapping: + library_other = None + + if library in library_mapping.keys(): + library_other = library_mapping[library] + elif library in library_mapping.values(): + library_other = search_mapping(library_mapping, library) + + if library_other: + logger(f"Swapping library {library} with {library_other}", 1) + library = library_other + + # if library in plex library list + library_list = user_plex.library.sections() + if library.lower() not in [x.title.lower() for x in library_list]: + logger(f"Library {library} not found in Plex library list", 2) + continue + + logger(f"Plex: Updating watched for {user.title} in library {library}", 1) library_videos = user_plex.library.section(library) - + if library_videos.type == "movie": for movies_search in library_videos.search(unmatched=False, unwatched=True): for guid in movies_search.guids: @@ -156,12 +204,12 @@ class Plex: for video_keys, video_id in video.items(): if video_keys == guid_source and video_id == guid_id: if movies_search.viewCount == 0: - msg = f"{movies_search.title} as watched for {user.title} in Plex" + msg = f"{movies_search.title} as watched for {user.title} in {library} for Plex" if not dryrun: logger(f"Marked {msg}", 0) movies_search.markWatched() else: - logger(f"Dyrun {msg}", 0) + logger(f"Dryrun {msg}", 0) break elif library_videos.type == "show": @@ -178,7 +226,7 @@ class Plex: for episode_keys, episode_id in episode.items(): if episode_keys == guid_source and episode_id == guid_id: if episode_search.viewCount == 0: - msg = f"{show_search.title} {season_search.title} {episode_search.title} as watched for {user.title} in Plex" + msg = f"{show_search.title} {season_search.title} {episode_search.title} as watched for {user.title} in {library} for Plex" if not dryrun: logger(f"Marked {msg}", 0) episode_search.markWatched()