Simplify get watched process. Only get watched for syncing libraries
Signed-off-by: Luis Garcia <git@luigi311.com>
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -223,13 +223,54 @@ class JellyfinEmby:
|
||||
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}",
|
||||
@@ -238,7 +279,7 @@ class JellyfinEmby:
|
||||
|
||||
# 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",
|
||||
@@ -274,7 +315,7 @@ class JellyfinEmby:
|
||||
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,
|
||||
@@ -283,7 +324,7 @@ class JellyfinEmby:
|
||||
# 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(
|
||||
@@ -352,10 +393,10 @@ class JellyfinEmby:
|
||||
|
||||
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:
|
||||
@@ -368,9 +409,9 @@ class JellyfinEmby:
|
||||
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
|
||||
@@ -383,130 +424,68 @@ class JellyfinEmby:
|
||||
logger(traceback.format_exc(), 2)
|
||||
return {}
|
||||
|
||||
def get_users_watched(
|
||||
self,
|
||||
user_name,
|
||||
user_id,
|
||||
blacklist_library,
|
||||
whitelist_library,
|
||||
blacklist_library_type,
|
||||
whitelist_library_type,
|
||||
library_mapping,
|
||||
):
|
||||
try:
|
||||
# Get all libraries
|
||||
user_name = user_name.lower()
|
||||
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 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"]
|
||||
]
|
||||
)
|
||||
|
||||
skip_reason = check_skip_logic(
|
||||
library_title,
|
||||
types,
|
||||
blacklist_library,
|
||||
whitelist_library,
|
||||
blacklist_library_type,
|
||||
whitelist_library_type,
|
||||
library_mapping,
|
||||
)
|
||||
|
||||
if skip_reason:
|
||||
logger(
|
||||
f"{self.server_type}: Skipping library {library_title}: {skip_reason}",
|
||||
1,
|
||||
)
|
||||
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,
|
||||
)
|
||||
continue
|
||||
|
||||
for library_type in types:
|
||||
# Get watched for user
|
||||
watched.append(
|
||||
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,
|
||||
sync_libraries
|
||||
):
|
||||
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,
|
||||
)
|
||||
)
|
||||
libraries = []
|
||||
|
||||
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)
|
||||
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"]
|
||||
|
||||
if library_title not in sync_libraries:
|
||||
continue
|
||||
|
||||
# Get all library types excluding "Folder"
|
||||
types = set(
|
||||
[
|
||||
x["Type"]
|
||||
for x in library["Items"]
|
||||
if x["Type"] in ["Movie", "Series", "Episode"]
|
||||
]
|
||||
)
|
||||
|
||||
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,
|
||||
)
|
||||
|
||||
|
||||
if user_name.lower() not in users_watched:
|
||||
users_watched[user_name.lower()] = {}
|
||||
users_watched[user_name.lower()].update(watched)
|
||||
|
||||
return users_watched
|
||||
except Exception as e:
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
from src.functions import (
|
||||
logger,
|
||||
match_list,
|
||||
search_mapping,
|
||||
)
|
||||
|
||||
@@ -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:
|
||||
|
||||
17
src/main.py
17
src/main.py
@@ -2,6 +2,7 @@ import os, traceback, json
|
||||
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,
|
||||
@@ -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)
|
||||
|
||||
|
||||
42
src/plex.py
42
src/plex.py
@@ -466,14 +466,28 @@ class Plex:
|
||||
logger(f"Plex: Failed to get users, Error: {e}", 2)
|
||||
raise Exception(e)
|
||||
|
||||
def get_libraries(self):
|
||||
try:
|
||||
output = {}
|
||||
|
||||
libraries = self.plex.library.sections()
|
||||
|
||||
for library in libraries:
|
||||
library_title = library.title
|
||||
library_type = library.type
|
||||
|
||||
output[library_title] = library_type
|
||||
|
||||
return output
|
||||
except Exception as e:
|
||||
logger(f"Plex: Failed to get libraries, Error: {e}", 2)
|
||||
raise Exception(e)
|
||||
|
||||
|
||||
def get_watched(
|
||||
self,
|
||||
users,
|
||||
blacklist_library,
|
||||
whitelist_library,
|
||||
blacklist_library_type,
|
||||
whitelist_library_type,
|
||||
library_mapping,
|
||||
sync_libraries
|
||||
):
|
||||
try:
|
||||
# Get all libraries
|
||||
@@ -500,23 +514,7 @@ class Plex:
|
||||
libraries = user_plex.library.sections()
|
||||
|
||||
for library in libraries:
|
||||
library_title = library.title
|
||||
library_type = library.type
|
||||
|
||||
skip_reason = check_skip_logic(
|
||||
library_title,
|
||||
library_type,
|
||||
blacklist_library,
|
||||
whitelist_library,
|
||||
blacklist_library_type,
|
||||
whitelist_library_type,
|
||||
library_mapping,
|
||||
)
|
||||
|
||||
if skip_reason:
|
||||
logger(
|
||||
f"Plex: Skipping library {library_title}: {skip_reason}", 1
|
||||
)
|
||||
if library.title not in sync_libraries:
|
||||
continue
|
||||
|
||||
user_watched = get_user_library_watched(user, user_plex, library)
|
||||
|
||||
Reference in New Issue
Block a user