diff --git a/src/functions.py b/src/functions.py index 5f5ffcd..2e7529b 100644 --- a/src/functions.py +++ b/src/functions.py @@ -39,6 +39,14 @@ def str_to_bool(value: any) -> bool: return str(value).lower() in ("y", "yes", "t", "true", "on", "1") +# Search for nested element in list +def contains_nested(element, lst): + for i, item in enumerate(lst): + if element in item: + return i + return None + + # Get mapped value def search_mapping(dictionary: dict, key_value: str): if key_value in dictionary.keys(): diff --git a/src/jellyfin.py b/src/jellyfin.py index 70520b4..b3d84c6 100644 --- a/src/jellyfin.py +++ b/src/jellyfin.py @@ -1,10 +1,7 @@ import asyncio, aiohttp, traceback from math import floor -from src.functions import ( - logger, - search_mapping, -) +from src.functions import logger, search_mapping, contains_nested from src.library import ( check_skip_logic, generate_library_guids_dict, @@ -554,13 +551,19 @@ class Jellyfin: if "MediaSources" in jellyfin_video: for movie_location in jellyfin_video["MediaSources"]: if ( - movie_location["Path"].split("/")[-1] - in videos_movies_ids["locations"] + contains_nested( + movie_location["Path"].split("/")[-1], + videos_movies_ids["locations"], + ) + is not None ): for video in videos: if ( - movie_location["Path"].split("/")[-1] - in video["locations"] + contains_nested( + movie_location["Path"].split("/")[-1], + video["locations"], + ) + is not None ): movie_status = video["status"] break @@ -632,8 +635,11 @@ class Jellyfin: if "Path" in jellyfin_show: if ( - jellyfin_show["Path"].split("/")[-1] - in videos_shows_ids["locations"] + contains_nested( + jellyfin_show["Path"].split("/")[-1], + videos_shows_ids["locations"], + ) + is not None ): show_found = True episode_videos = [] @@ -641,8 +647,11 @@ class Jellyfin: for show, seasons in videos.items(): show = {k: v for k, v in show} if ( - jellyfin_show["Path"].split("/")[-1] - in show["locations"] + contains_nested( + jellyfin_show["Path"].split("/")[-1], + show["locations"], + ) + is not None ): for season in seasons.values(): for episode in season: @@ -692,15 +701,21 @@ class Jellyfin: "MediaSources" ]: if ( - episode_location["Path"].split("/")[-1] - in videos_episodes_ids["locations"] + contains_nested( + episode_location["Path"].split("/")[-1], + videos_episodes_ids["locations"], + ) + is not None ): for episode in episode_videos: if ( - episode_location["Path"].split("/")[ - -1 - ] - in episode["locations"] + contains_nested( + episode_location["Path"].split( + "/" + )[-1], + episode["locations"], + ) + is not None ): episode_status = episode["status"] break diff --git a/src/library.py b/src/library.py index 36d5060..20792bc 100644 --- a/src/library.py +++ b/src/library.py @@ -132,6 +132,8 @@ def check_whitelist_logic( def show_title_dict(user_list: dict): try: show_output_dict = {} + show_output_dict["locations"] = [] + show_counter = 0 # Initialize a counter for the current show position show_output_keys = user_list.keys() show_output_keys = [dict(x) for x in list(show_output_keys)] @@ -141,15 +143,19 @@ def show_title_dict(user_list: dict): if provider_key.lower() == "title": continue if provider_key.lower() not in show_output_dict: - show_output_dict[provider_key.lower()] = [] + show_output_dict[provider_key.lower()] = [None] * show_counter if provider_key.lower() == "locations": - for show_location in provider_value: - show_output_dict[provider_key.lower()].append(show_location) + show_output_dict[provider_key.lower()].append(provider_value) else: show_output_dict[provider_key.lower()].append( provider_value.lower() ) + show_counter += 1 + for key in show_output_dict: + if len(show_output_dict[key]) < show_counter: + show_output_dict[key].append(None) + return show_output_dict except Exception: logger("Generating show_output_dict failed, skipping", 1) @@ -159,34 +165,54 @@ def show_title_dict(user_list: dict): def episode_title_dict(user_list: dict): try: episode_output_dict = {} + episode_output_dict["completed"] = [] + episode_output_dict["time"] = [] + episode_output_dict["locations"] = [] + episode_counter = 0 # Initialize a counter for the current episode position + + # Iterate through the shows, seasons, and episodes in user_list for show in user_list: for season in user_list[show]: for episode in user_list[show][season]: + + # Iterate through the keys and values in each episode for episode_key, episode_value in episode.items(): + + # If the key is not "status", add the key to episode_output_dict if it doesn't exist if episode_key != "status": if episode_key.lower() not in episode_output_dict: - episode_output_dict[episode_key.lower()] = [] - - if "completed" not in episode_output_dict: - episode_output_dict["completed"] = [] - if "time" not in episode_output_dict: - episode_output_dict["time"] = [] + # Initialize the list with None values up to the current episode position + episode_output_dict[episode_key.lower()] = [ + None + ] * episode_counter + # If the key is "locations", append each location to the list if episode_key == "locations": - for episode_location in episode_value: - episode_output_dict[episode_key.lower()].append( - episode_location - ) + episode_output_dict[episode_key.lower()].append( + episode_value + ) + + # If the key is "status", append the "completed" and "time" values elif episode_key == "status": episode_output_dict["completed"].append( episode_value["completed"] ) episode_output_dict["time"].append(episode_value["time"]) + + # For other keys, append the value to the list else: episode_output_dict[episode_key.lower()].append( episode_value.lower() ) + # Increment the episode_counter + episode_counter += 1 + + # Extend the lists in episode_output_dict with None values to match the current episode_counter + for key in episode_output_dict: + if len(episode_output_dict[key]) < episode_counter: + episode_output_dict[key].append(None) + return episode_output_dict except Exception: logger("Generating episode_output_dict failed, skipping", 1) @@ -196,26 +222,30 @@ def episode_title_dict(user_list: dict): def movies_title_dict(user_list: dict): try: movies_output_dict = {} + movies_output_dict["completed"] = [] + movies_output_dict["time"] = [] + movies_output_dict["locations"] = [] + movie_counter = 0 # Initialize a counter for the current movie position + for movie in user_list: for movie_key, movie_value in movie.items(): if movie_key != "status": if movie_key.lower() not in movies_output_dict: movies_output_dict[movie_key.lower()] = [] - if "completed" not in movies_output_dict: - movies_output_dict["completed"] = [] - if "time" not in movies_output_dict: - movies_output_dict["time"] = [] - if movie_key == "locations": - for movie_location in movie_value: - movies_output_dict[movie_key.lower()].append(movie_location) + movies_output_dict[movie_key.lower()].append(movie_value) elif movie_key == "status": movies_output_dict["completed"].append(movie_value["completed"]) movies_output_dict["time"].append(movie_value["time"]) else: movies_output_dict[movie_key.lower()].append(movie_value.lower()) + movie_counter += 1 + for key in movies_output_dict: + if len(movies_output_dict[key]) < movie_counter: + movies_output_dict[key].append(None) + return movies_output_dict except Exception: logger("Generating movies_output_dict failed, skipping", 1) diff --git a/src/plex.py b/src/plex.py index 0f1e8f0..889078d 100644 --- a/src/plex.py +++ b/src/plex.py @@ -9,6 +9,7 @@ from src.functions import ( logger, search_mapping, future_thread_executor, + contains_nested, ) from src.library import ( check_skip_logic, @@ -202,12 +203,18 @@ def get_user_library_watched(user, user_plex, library): def find_video(plex_search, video_ids, videos=None): try: for location in plex_search.locations: - if location.split("/")[-1] in video_ids["locations"]: + if ( + contains_nested(location.split("/")[-1], video_ids["locations"]) + is not None + ): episode_videos = [] if videos: for show, seasons in videos.items(): show = {k: v for k, v in show} - if location.split("/")[-1] in show["locations"]: + if ( + contains_nested(location.split("/")[-1], show["locations"]) + is not None + ): for season in seasons.values(): for episode in season: episode_videos.append(episode) @@ -241,9 +248,15 @@ def find_video(plex_search, video_ids, videos=None): def get_video_status(plex_search, video_ids, videos): try: for location in plex_search.locations: - if location.split("/")[-1] in video_ids["locations"]: + if ( + contains_nested(location.split("/")[-1], video_ids["locations"]) + is not None + ): for video in videos: - if location.split("/")[-1] in video["locations"]: + if ( + contains_nested(location.split("/")[-1], video["locations"]) + is not None + ): return video["status"] for guid in plex_search.guids: diff --git a/src/watched.py b/src/watched.py index 28d2cc8..2498eae 100644 --- a/src/watched.py +++ b/src/watched.py @@ -1,9 +1,6 @@ import copy -from src.functions import ( - logger, - search_mapping, -) +from src.functions import logger, search_mapping, contains_nested from src.library import generate_library_guids_dict @@ -118,6 +115,7 @@ def cleanup_watched( elif isinstance(watched_list_1[user_1][library_1], dict): for show_key_1 in watched_list_1[user_1][library_1].keys(): show_key_dict = dict(show_key_1) + for season in watched_list_1[user_1][library_1][show_key_1]: for episode in watched_list_1[user_1][library_1][show_key_1][ season @@ -204,10 +202,9 @@ def get_movie_index_in_dict(movie, movies_watched_list_2_keys_dict): # Iterate through the locations in the movie dictionary for location in movie_value: # If the location is in the movies_watched_list_2_keys_dict dictionary, return index of the key - if location in movies_watched_list_2_keys_dict["locations"]: - return movies_watched_list_2_keys_dict["locations"].index( - location - ) + return contains_nested( + location, movies_watched_list_2_keys_dict["locations"] + ) # If the key is not "locations", check if the movie_key is present in the movies_watched_list_2_keys_dict dictionary else: @@ -223,19 +220,16 @@ def get_movie_index_in_dict(movie, movies_watched_list_2_keys_dict): def get_episode_index_in_dict(episode, episode_watched_list_2_keys_dict): # Iterate through the keys and values of the episode dictionary for episode_key, episode_value in episode.items(): - # If the key is "locations", check if the "locations" key is present in the episode_watched_list_2_keys_dict dictionary - if episode_key == "locations": - if "locations" in episode_watched_list_2_keys_dict.keys(): + if episode_key in episode_watched_list_2_keys_dict.keys(): + if episode_key == "locations": # Iterate through the locations in the episode dictionary for location in episode_value: # If the location is in the episode_watched_list_2_keys_dict dictionary, return index of the key - if location in episode_watched_list_2_keys_dict["locations"]: - return episode_watched_list_2_keys_dict["locations"].index( - location - ) - # If the key is not "locations", check if the episode_key is present in the episode_watched_list_2_keys_dict dictionary - else: - if episode_key in episode_watched_list_2_keys_dict.keys(): + return contains_nested( + location, episode_watched_list_2_keys_dict["locations"] + ) + + else: # If the episode_value is in the episode_watched_list_2_keys_dict dictionary, return True if episode_value in episode_watched_list_2_keys_dict[episode_key]: return episode_watched_list_2_keys_dict[episode_key].index( diff --git a/test/test_library.py b/test/test_library.py index e9fd02e..3111f91 100644 --- a/test/test_library.py +++ b/test/test_library.py @@ -49,7 +49,9 @@ show_list = { "tmdb": "2181581", "tvdb": "8444132", "locations": ( - "The Last of Us - S01E01 - When You're Lost in the Darkness WEBDL-1080p.mkv", + ( + "The Last of Us - S01E01 - When You're Lost in the Darkness WEBDL-1080p.mkv", + ) ), "status": {"completed": True, "time": 0}, } @@ -61,21 +63,21 @@ movie_list = [ "title": "Coco", "imdb": "tt2380307", "tmdb": "354912", - "locations": ("Coco (2017) Remux-2160p.mkv", "Coco (2017) Remux-1080p.mkv"), + "locations": [("Coco (2017) Remux-2160p.mkv", "Coco (2017) Remux-1080p.mkv")], "status": {"completed": True, "time": 0}, } ] show_titles = { "imdb": ["tt3581920"], - "locations": ["The Last of Us"], + "locations": [("The Last of Us",)], "tmdb": ["100088"], "tvdb": ["392256"], } episode_titles = { "imdb": ["tt11957006"], "locations": [ - "The Last of Us - S01E01 - When You're Lost in the Darkness WEBDL-1080p.mkv" + ("The Last of Us - S01E01 - When You're Lost in the Darkness WEBDL-1080p.mkv",) ], "tmdb": ["2181581"], "tvdb": ["8444132"], @@ -84,7 +86,14 @@ episode_titles = { } movie_titles = { "imdb": ["tt2380307"], - "locations": ["Coco (2017) Remux-2160p.mkv", "Coco (2017) Remux-1080p.mkv"], + "locations": [ + [ + ( + "Coco (2017) Remux-2160p.mkv", + "Coco (2017) Remux-1080p.mkv", + ) + ] + ], "title": ["coco"], "tmdb": ["354912"], "completed": [True],