Skip to content

Commit

Permalink
Simplify get watched process. Only get watched for syncing libraries
Browse files Browse the repository at this point in the history
  • Loading branch information
luigi311 committed Oct 27, 2024
1 parent 8428be9 commit 92d84d3
Show file tree
Hide file tree
Showing 5 changed files with 176 additions and 146 deletions.
12 changes: 12 additions & 0 deletions src/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,18 @@ def search_mapping(dictionary: dict, key_value: str):
else:
return None

# Return list of objects that exist in both lists including mappings
def match_list(list1, list2, list_mapping=None):
output = []
for element in list1:
if element in list2:
output.append(element)
elif list_mapping:
element_other = search_mapping(list_mapping, element)
if element_other in list2:
output.append(element)

return output

def future_thread_executor(
args: list, threads: int = None, override_threads: bool = False
Expand Down
207 changes: 93 additions & 114 deletions src/jellyfin_emby.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,13 +223,54 @@ def get_users(self):
logger(f"{self.server_type}: Get users failed {e}", 2)
raise Exception(e)

def get_libraries(self):
try:
libraries = {}

# Theres no way to get all libraries so individually get list of libraries from all users
users = self.get_users()

for _, user_id in users.items():
user_libraries = self.query(f"/Users/{user_id}/Views", "get")
for library in user_libraries["Items"]:
library_id = library["Id"]
library_title = library["Name"]

# Get library items to check the type
media_info = self.query(
f"/Users/{user_id}/Items"
+ f"?ParentId={library_id}&Filters=IsPlayed&Recursive=True&excludeItemTypes=Folder&limit=100",
"get",
)

types = set(
[
x["Type"]
for x in media_info["Items"]
if x["Type"] in ["Movie", "Series", "Episode"]
]
)
all_types = set([x["Type"] for x in media_info["Items"]])

if not types:
logger(
f"{self.server_type}: Skipping Library {library_title} found wanted types: {all_types}",
1,
)
else:
libraries[library_title] = str(types)

return libraries
except Exception as e:
logger(f"{self.server_type}: Get libraries failed {e}", 2)
raise Exception(e)

def get_user_library_watched(
self, user_name, user_id, library_type, library_id, library_title
):
try:
user_name = user_name.lower()
user_watched = {}
user_watched[user_name] = {}

logger(
f"{self.server_type}: Generating watched for {user_name} in library {library_title}",
Expand All @@ -238,7 +279,7 @@ def get_user_library_watched(

# Movies
if library_type == "Movie":
user_watched[user_name][library_title] = []
user_watched[library_title] = []
watched = self.query(
f"/Users/{user_id}/Items"
+ f"?ParentId={library_id}&Filters=IsPlayed&IncludeItemTypes=Movie&Recursive=True&Fields=ItemCounts,ProviderIds,MediaSources",
Expand Down Expand Up @@ -274,7 +315,7 @@ def get_user_library_watched(
movie_guids = get_guids(self.server_type, movie)

# Append the movie dictionary to the list for the given user and library
user_watched[user_name][library_title].append(movie_guids)
user_watched[library_title].append(movie_guids)
logger(
f"{self.server_type}: Added {movie_guids} to {user_name} watched list",
3,
Expand All @@ -283,7 +324,7 @@ def get_user_library_watched(
# TV Shows
if library_type in ["Series", "Episode"]:
# Initialize an empty dictionary for the given user and library
user_watched[user_name][library_title] = {}
user_watched[library_title] = {}

# Retrieve a list of watched TV shows
watched_shows = self.query(
Expand Down Expand Up @@ -352,10 +393,10 @@ def get_user_library_watched(

if mark_episodes_list:
# Add the show dictionary to the user's watched list
if show_guids not in user_watched[user_name][library_title]:
user_watched[user_name][library_title][show_guids] = []
if show_guids not in user_watched[library_title]:
user_watched[library_title][show_guids] = []

user_watched[user_name][library_title][
user_watched[library_title][
show_guids
] = mark_episodes_list
for episode in mark_episodes_list:
Expand All @@ -368,9 +409,9 @@ def get_user_library_watched(
f"{self.server_type}: Got watched for {user_name} in library {library_title}",
1,
)
if library_title in user_watched[user_name]:
if library_title in user_watched:
logger(
f"{self.server_type}: {user_watched[user_name][library_title]}", 3
f"{self.server_type}: {user_watched[library_title]}", 3
)

return user_watched
Expand All @@ -383,130 +424,68 @@ def get_user_library_watched(
logger(traceback.format_exc(), 2)
return {}

def get_users_watched(
def get_watched(
self,
user_name,
user_id,
blacklist_library,
whitelist_library,
blacklist_library_type,
whitelist_library_type,
library_mapping,
users,
sync_libraries
):
try:
# Get all libraries
user_name = user_name.lower()
users_watched = {}
watched = []

libraries = []

all_libraries = self.query(f"/Users/{user_id}/Views", "get")
for library in all_libraries["Items"]:
library_id = library["Id"]
library_title = library["Name"]
identifiers = {
"library_id": library_id,
"library_title": library_title,
}
libraries.append(
self.query(
f"/Users/{user_id}/Items"
+ f"?ParentId={library_id}&Filters=IsPlayed&Recursive=True&excludeItemTypes=Folder&limit=100",
"get",
identifiers=identifiers,
for user_name, user_id in users.items():
libraries = []

all_libraries = self.query(f"/Users/{user_id}/Views", "get")
for library in all_libraries["Items"]:
library_id = library["Id"]
library_title = library["Name"]
identifiers = {
"library_id": library_id,
"library_title": library_title,
}
libraries.append(
self.query(
f"/Users/{user_id}/Items"
+ f"?ParentId={library_id}&Filters=IsPlayed&Recursive=True&excludeItemTypes=Folder&limit=100",
"get",
identifiers=identifiers,
)
)
)

for library in libraries:
if len(library["Items"]) == 0:
continue

library_id = library["Identifiers"]["library_id"]
library_title = library["Identifiers"]["library_title"]
# Get all library types excluding "Folder"
types = set(
[
x["Type"]
for x in library["Items"]
if x["Type"] in ["Movie", "Series", "Episode"]
]
)
for library in libraries:
if len(library["Items"]) == 0:
continue

skip_reason = check_skip_logic(
library_title,
types,
blacklist_library,
whitelist_library,
blacklist_library_type,
whitelist_library_type,
library_mapping,
)
library_id = library["Identifiers"]["library_id"]
library_title = library["Identifiers"]["library_title"]

if skip_reason:
logger(
f"{self.server_type}: Skipping library {library_title}: {skip_reason}",
1,
)
continue
if library_title not in sync_libraries:
continue

# If there are multiple types in library raise error
if types is None or len(types) < 1:
all_types = set([x["Type"] for x in library["Items"]])
logger(
f"{self.server_type}: Skipping Library {library_title} found types: {types}, all types: {all_types}",
1,
# Get all library types excluding "Folder"
types = set(
[
x["Type"]
for x in library["Items"]
if x["Type"] in ["Movie", "Series", "Episode"]
]
)
continue

for library_type in types:
# Get watched for user
watched.append(
self.get_user_library_watched(
for library_type in types:
# Get watched for user
watched = self.get_user_library_watched(
user_name,
user_id,
library_type,
library_id,
library_title,
)
)

return watched
except Exception as e:
logger(f"{self.server_type}: Failed to get users watched, Error: {e}", 2)
raise Exception(e)

def get_watched(
self,
users,
blacklist_library,
whitelist_library,
blacklist_library_type,
whitelist_library_type,
library_mapping=None,
):
try:
users_watched = {}
watched = []

for user_name, user_id in users.items():
watched.append(
self.get_users_watched(
user_name,
user_id,
blacklist_library,
whitelist_library,
blacklist_library_type,
whitelist_library_type,
library_mapping,
)
)

for user_watched in watched:
user_watched_combine = combine_watched_dicts(user_watched)
for user, user_watched_temp in user_watched_combine.items():
if user not in users_watched:
users_watched[user] = {}
users_watched[user].update(user_watched_temp)

if user_name not in users_watched:
users_watched[user_name] = {}
users_watched[user_name].update(watched)

return users_watched
except Exception as e:
Expand Down
44 changes: 44 additions & 0 deletions src/library.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from src.functions import (
logger,
match_list,
search_mapping,
)

Expand Down Expand Up @@ -128,6 +129,49 @@ def check_whitelist_logic(

return skip_reason

def filter_libaries(
server_libraries, blacklist_library, blacklist_library_type, whitelist_library, whitelist_library_type, library_mapping=None
):
filtered_libaries = []
for library in server_libraries:
skip_reason = check_skip_logic(
library,
server_libraries[library],
blacklist_library,
whitelist_library,
blacklist_library_type,
whitelist_library_type,
library_mapping,
)

if skip_reason:
logger(
f"Skipping library {library}: {skip_reason}", 1
)
continue

filtered_libaries.append(library)

return filtered_libaries


def setup_libraries(
server_1, server_2, blacklist_library, blacklist_library_type, whitelist_library, whitelist_library_type, library_mapping=None
):
server_1_libraries = server_1.get_libraries()
server_2_libraries = server_2.get_libraries()
logger(f"Server 1 libraries: {server_1_libraries}", 1)
logger(f"Server 2 libraries: {server_2_libraries}", 1)

# Filter out all blacklist, whitelist libaries
filtered_server_1_libraries = filter_libaries(server_1_libraries, blacklist_library, blacklist_library_type, whitelist_library, whitelist_library_type, library_mapping)
filtered_server_2_libraries = filter_libaries(server_2_libraries, blacklist_library, blacklist_library_type, whitelist_library, whitelist_library_type, library_mapping)

output_server_1_libaries = match_list(filtered_server_1_libraries, filtered_server_2_libraries, library_mapping)
output_server_2_libaries = match_list(filtered_server_2_libraries, filtered_server_1_libraries, library_mapping)

return output_server_1_libaries, output_server_2_libaries


def show_title_dict(user_list: dict):
try:
Expand Down
17 changes: 7 additions & 10 deletions src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from dotenv import load_dotenv
from time import sleep, perf_counter

from src.library import setup_libraries
from src.functions import (
logger,
str_to_bool,
Expand Down Expand Up @@ -153,24 +154,20 @@ def main_loop():
server_1, server_2, blacklist_users, whitelist_users, user_mapping
)

server_1_libraries, server_2_libraries = setup_libraries(
server_1[1], server_2[1], blacklist_library, blacklist_library_type, whitelist_library, whitelist_library_type, library_mapping
)

logger("Creating watched lists", 1)
server_1_watched = server_1[1].get_watched(
server_1_users,
blacklist_library,
whitelist_library,
blacklist_library_type,
whitelist_library_type,
library_mapping,
server_1_libraries
)
logger("Finished creating watched list server 1", 1)

server_2_watched = server_2[1].get_watched(
server_2_users,
blacklist_library,
whitelist_library,
blacklist_library_type,
whitelist_library_type,
library_mapping,
server_2_libraries
)
logger("Finished creating watched list server 2", 1)

Expand Down
Loading

0 comments on commit 92d84d3

Please sign in to comment.