From f3ce1520848cbb36dd5c5875c25907d1af337787 Mon Sep 17 00:00:00 2001 From: Luigi311 Date: Sat, 11 Jun 2022 13:41:03 -0600 Subject: [PATCH] Simplify plex marking logic --- main.py | 42 +++++++++++++++++++++--------------------- src/functions.py | 2 +- src/jellyfin.py | 30 +++++++++++++++--------------- src/plex.py | 42 +++++++++++++++++++++--------------------- 4 files changed, 58 insertions(+), 58 deletions(-) diff --git a/main.py b/main.py index 5d47dc8..fe32e40 100644 --- a/main.py +++ b/main.py @@ -10,7 +10,7 @@ load_dotenv(override=True) 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_other = None @@ -47,7 +47,7 @@ def cleanup_watched(watched_list_1, watched_list_2, user_mapping=None, library_m 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]: @@ -60,22 +60,22 @@ def cleanup_watched(watched_list_1, watched_list_2, user_mapping=None, library_m 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 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_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: del modified_watched_list_1[user_1] @@ -95,10 +95,10 @@ def setup_black_white_lists(library_mapping=None): if library_other: temp_library.append(library_other) - blacklist_library = blacklist_library + temp_library + blacklist_library = blacklist_library + temp_library else: blacklist_library = [] - + logger(f"Blacklist Library: {blacklist_library}", 1) whitelist_library = os.getenv("WHITELIST_LIBRARY") @@ -140,11 +140,11 @@ def setup_black_white_lists(library_mapping=None): 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) - + whitelist_users = os.getenv("WHITELIST_USERS") if whitelist_users: if len(whitelist_users) > 0: @@ -159,11 +159,11 @@ def setup_black_white_lists(library_mapping=None): return blacklist_library, whitelist_library, blacklist_library_type, whitelist_library_type, blacklist_users, whitelist_users def setup_users(plex, jellyfin, blacklist_users, whitelist_users, user_mapping=None): - + # generate list of users from plex.users plex_users = [ x.title.lower() for x in plex.users ] jellyfin_users = [ key.lower() for key in jellyfin.users.keys() ] - + # combined list of overlapping users from plex and jellyfin users = {} @@ -173,10 +173,10 @@ def setup_users(plex, jellyfin, blacklist_users, whitelist_users, user_mapping=N if jellyfin_plex_mapped_user: users[plex_user] = jellyfin_plex_mapped_user continue - + if plex_user in jellyfin_users: users[plex_user] = plex_user - + for jellyfin_user in jellyfin_users: if user_mapping: plex_jellyfin_mapped_user = search_mapping(user_mapping, jellyfin_user) @@ -186,9 +186,9 @@ def setup_users(plex, jellyfin, blacklist_users, whitelist_users, user_mapping=N if jellyfin_user in plex_users: users[jellyfin_user] = jellyfin_user - + logger(f"User list that exist on both servers {users}", 1) - + users_filtered = {} for user in users: # whitelist_user is not empty and user lowercase is not in whitelist lowercase @@ -196,17 +196,17 @@ def setup_users(plex, jellyfin, blacklist_users, whitelist_users, user_mapping=N if user not in whitelist_users and users[user] not in whitelist_users: logger(f"{user} or {users[user]} is not in whitelist", 1) continue - + if user not in blacklist_users and users[user] not in blacklist_users: users_filtered[user] = users[user] logger(f"Filtered user list {users_filtered}", 1) - + plex_users = [] for plex_user in plex.users: if plex_user.title.lower() in users_filtered.keys() or plex_user.title.lower() in users_filtered.values(): plex_users.append(plex_user) - + jellyfin_users = {} for jellyfin_user, jellyfin_id in jellyfin.users.items(): if jellyfin_user.lower() in users_filtered.keys() or jellyfin_user.lower() in users_filtered.values(): @@ -267,11 +267,11 @@ def main(): # Update watched status plex.update_watched(jellyfin_watched, user_mapping, library_mapping, dryrun) jellyfin.update_watched(plex_watched, user_mapping, library_mapping, dryrun) - + if __name__ == "__main__": sleep_timer = float(os.getenv("SLEEP_TIMER", "3600")) - + while(True): try: main() diff --git a/src/functions.py b/src/functions.py index f3e3de8..b371212 100644 --- a/src/functions.py +++ b/src/functions.py @@ -67,7 +67,7 @@ def check_skip_logic(library_title, library_type, blacklist_library, whitelist_l if len(whitelist_library) > 0: if library_title.lower() not in [x.lower() for x in whitelist_library]: skip_reason = "is not whitelist_library" - + if library_other: if library_other.lower() not in [x.lower() for x in whitelist_library]: skip_reason = "is not whitelist_library" diff --git a/src/jellyfin.py b/src/jellyfin.py index 7bcbbce..5cd0a9c 100644 --- a/src/jellyfin.py +++ b/src/jellyfin.py @@ -14,7 +14,7 @@ class Jellyfin(): if not self.baseurl: raise Exception("Jellyfin baseurl not set") - + if not self.token: raise Exception("Jellyfin token not set") @@ -27,7 +27,7 @@ class Jellyfin(): if query_type == "get": response = requests.get(self.baseurl + query, headers={"accept":"application/json", "X-Emby-Token": self.token}) - + elif query_type == "post": authorization = ( 'MediaBrowser , ' @@ -42,19 +42,19 @@ class Jellyfin(): except Exception as e: logger(e, 2) logger(response, 2) - + def get_users(self): users = {} query = "/Users" response = self.query(query, "get") - + # If reponse is not empty if response: for user in response: users[user["Name"]] = user["Id"] - return users + return users def get_jellyfin_watched(self, users, blacklist_library, whitelist_library, blacklist_library_type, whitelist_library_type, library_mapping=None): users_watched = {} @@ -64,12 +64,12 @@ class Jellyfin(): user_name = user_name.lower() libraries = self.query(f"/Users/{user_id}/Views", "get")["Items"] - + for library in libraries: library_title = library["Name"] library_id = library["Id"] 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 @@ -123,7 +123,7 @@ class Jellyfin(): # 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, library_mapping=None, dryrun=False): @@ -135,7 +135,7 @@ class Jellyfin(): user_other = user_mapping[user] elif user in user_mapping.values(): user_other = search_mapping(user_mapping, user) - + if user_other: logger(f"Swapping user {user} with {user_other}", 1) user = user_other @@ -145,13 +145,13 @@ class Jellyfin(): if user.lower() == key.lower(): user_id = self.users[key] break - + if not user_id: logger(f"{user} not found in Jellyfin", 2) break - + jellyfin_libraries = self.query(f"/Users/{user_id}/Views", "get")["Items"] - + for library, videos in libraries.items(): if library_mapping: library_other = None @@ -160,7 +160,7 @@ class Jellyfin(): 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 @@ -174,7 +174,7 @@ class Jellyfin(): if jellyfin_library["Name"] == library: library_id = jellyfin_library["Id"] 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") @@ -196,7 +196,7 @@ class Jellyfin(): else: logger(f"Dryrun {msg}", 0) break - + # TV Shows if library_type == "Episode": jellyfin_search = self.query(f"/Users/{user_id}/Items?SortBy=SortName&SortOrder=Ascending&Recursive=true&ParentId={library_id}&isPlayed=false", "get") diff --git a/src/plex.py b/src/plex.py index 9ab9aa7..e8b0350 100644 --- a/src/plex.py +++ b/src/plex.py @@ -36,7 +36,7 @@ class Plex: plex = account.resource(self.servername).connect() else: raise Exception("No complete plex credentials provided") - + return plex except Exception as e: if self.username or self.password: @@ -45,14 +45,14 @@ class Plex: else: logger(f"Plex: Failed to login, Error: {e}", 2) return None - + def get_plex_users(self): users = self.plex.myPlexAccount().users() - + # append self to users users.append(self.plex.myPlexAccount()) - + return users def get_plex_user_watched(self, user, library): @@ -60,9 +60,9 @@ class Plex: user_plex = self.plex else: user_plex = PlexServer(self.baseurl, user.get_token(self.plex.machineIdentifier)) - + watched = None - + if library.type == "movie": watched = [] library_videos = user_plex.library.section(library.title) @@ -81,22 +81,22 @@ class Plex: for season in show.seasons(): guids = [] for episode in season.episodes(): - if episode.viewCount > 0: - guids_temp = {} + if episode.viewCount > 0: + guids_temp = {} for guid in episode.guids: # Extract after :// from guid.id guid_source = re.search(r'(.*)://', guid.id).group(1).lower() guid_id = re.search(r'://(.*)', guid.id).group(1) guids_temp[guid_source] = guid_id - - guids.append(guids_temp) - + + guids.append(guids_temp) + if guids: # append show, season, episode if show.title not in watched: watched[show.title] = {} if season.title not in watched[show.title]: - watched[show.title][season.title] = {} + watched[show.title][season.title] = {} watched[show.title][season.title] = guids return watched @@ -116,7 +116,7 @@ class Plex: if skip_reason: logger(f"Plex: Skipping library {library_title} {skip_reason}", 1) continue - + for user in users: logger(f"Plex: Generating watched for {user.title} in library {library_title}", 0) user_name = user.title.lower() @@ -127,9 +127,9 @@ class Plex: 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, library_mapping=None, dryrun=False): for user, libraries in watched_list.items(): if user_mapping: @@ -139,7 +139,7 @@ class Plex: user_other = user_mapping[user] elif user in user_mapping.values(): user_other = search_mapping(user_mapping, user) - + if user_other: logger(f"Swapping user {user} with {user_other}", 1) user = user_other @@ -162,7 +162,7 @@ class Plex: 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 @@ -192,7 +192,7 @@ class Plex: else: logger(f"Dryrun {msg}", 0) break - + elif library_videos.type == "show": for show_search in library_videos.search(unmatched=False, unwatched=True): if show_search.title in videos: @@ -201,9 +201,9 @@ class Plex: for guid in episode_search.guids: guid_source = re.search(r'(.*)://', guid.id).group(1).lower() guid_id = re.search(r'://(.*)', guid.id).group(1) - for show, seasons in videos.items(): - for season, episodes in seasons.items(): - for episode in episodes: + for show in videos: + for season in videos[show]: + for episode in videos[show][season]: for episode_keys, episode_id in episode.items(): if episode_keys == guid_source and episode_id == guid_id: if episode_search.viewCount == 0: