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:
|
else:
|
||||||
return None
|
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(
|
def future_thread_executor(
|
||||||
args: list, threads: int = None, override_threads: bool = False
|
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)
|
logger(f"{self.server_type}: Get users failed {e}", 2)
|
||||||
raise Exception(e)
|
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(
|
def get_user_library_watched(
|
||||||
self, user_name, user_id, library_type, library_id, library_title
|
self, user_name, user_id, library_type, library_id, library_title
|
||||||
):
|
):
|
||||||
try:
|
try:
|
||||||
user_name = user_name.lower()
|
user_name = user_name.lower()
|
||||||
user_watched = {}
|
user_watched = {}
|
||||||
user_watched[user_name] = {}
|
|
||||||
|
|
||||||
logger(
|
logger(
|
||||||
f"{self.server_type}: Generating watched for {user_name} in library {library_title}",
|
f"{self.server_type}: Generating watched for {user_name} in library {library_title}",
|
||||||
@@ -238,7 +279,7 @@ class JellyfinEmby:
|
|||||||
|
|
||||||
# Movies
|
# Movies
|
||||||
if library_type == "Movie":
|
if library_type == "Movie":
|
||||||
user_watched[user_name][library_title] = []
|
user_watched[library_title] = []
|
||||||
watched = self.query(
|
watched = self.query(
|
||||||
f"/Users/{user_id}/Items"
|
f"/Users/{user_id}/Items"
|
||||||
+ f"?ParentId={library_id}&Filters=IsPlayed&IncludeItemTypes=Movie&Recursive=True&Fields=ItemCounts,ProviderIds,MediaSources",
|
+ 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)
|
movie_guids = get_guids(self.server_type, movie)
|
||||||
|
|
||||||
# Append the movie dictionary to the list for the given user and library
|
# 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(
|
logger(
|
||||||
f"{self.server_type}: Added {movie_guids} to {user_name} watched list",
|
f"{self.server_type}: Added {movie_guids} to {user_name} watched list",
|
||||||
3,
|
3,
|
||||||
@@ -283,7 +324,7 @@ class JellyfinEmby:
|
|||||||
# TV Shows
|
# TV Shows
|
||||||
if library_type in ["Series", "Episode"]:
|
if library_type in ["Series", "Episode"]:
|
||||||
# Initialize an empty dictionary for the given user and library
|
# 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
|
# Retrieve a list of watched TV shows
|
||||||
watched_shows = self.query(
|
watched_shows = self.query(
|
||||||
@@ -352,10 +393,10 @@ class JellyfinEmby:
|
|||||||
|
|
||||||
if mark_episodes_list:
|
if mark_episodes_list:
|
||||||
# Add the show dictionary to the user's watched list
|
# Add the show dictionary to the user's watched list
|
||||||
if show_guids not in user_watched[user_name][library_title]:
|
if show_guids not in user_watched[library_title]:
|
||||||
user_watched[user_name][library_title][show_guids] = []
|
user_watched[library_title][show_guids] = []
|
||||||
|
|
||||||
user_watched[user_name][library_title][
|
user_watched[library_title][
|
||||||
show_guids
|
show_guids
|
||||||
] = mark_episodes_list
|
] = mark_episodes_list
|
||||||
for episode in 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}",
|
f"{self.server_type}: Got watched for {user_name} in library {library_title}",
|
||||||
1,
|
1,
|
||||||
)
|
)
|
||||||
if library_title in user_watched[user_name]:
|
if library_title in user_watched:
|
||||||
logger(
|
logger(
|
||||||
f"{self.server_type}: {user_watched[user_name][library_title]}", 3
|
f"{self.server_type}: {user_watched[library_title]}", 3
|
||||||
)
|
)
|
||||||
|
|
||||||
return user_watched
|
return user_watched
|
||||||
@@ -383,130 +424,68 @@ class JellyfinEmby:
|
|||||||
logger(traceback.format_exc(), 2)
|
logger(traceback.format_exc(), 2)
|
||||||
return {}
|
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(
|
def get_watched(
|
||||||
self,
|
self,
|
||||||
users,
|
users,
|
||||||
blacklist_library,
|
sync_libraries
|
||||||
whitelist_library,
|
|
||||||
blacklist_library_type,
|
|
||||||
whitelist_library_type,
|
|
||||||
library_mapping=None,
|
|
||||||
):
|
):
|
||||||
try:
|
try:
|
||||||
users_watched = {}
|
users_watched = {}
|
||||||
watched = []
|
watched = []
|
||||||
|
|
||||||
for user_name, user_id in users.items():
|
for user_name, user_id in users.items():
|
||||||
watched.append(
|
libraries = []
|
||||||
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:
|
all_libraries = self.query(f"/Users/{user_id}/Views", "get")
|
||||||
user_watched_combine = combine_watched_dicts(user_watched)
|
for library in all_libraries["Items"]:
|
||||||
for user, user_watched_temp in user_watched_combine.items():
|
library_id = library["Id"]
|
||||||
if user not in users_watched:
|
library_title = library["Name"]
|
||||||
users_watched[user] = {}
|
identifiers = {
|
||||||
users_watched[user].update(user_watched_temp)
|
"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
|
return users_watched
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
from src.functions import (
|
from src.functions import (
|
||||||
logger,
|
logger,
|
||||||
|
match_list,
|
||||||
search_mapping,
|
search_mapping,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -128,6 +129,49 @@ def check_whitelist_logic(
|
|||||||
|
|
||||||
return skip_reason
|
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):
|
def show_title_dict(user_list: dict):
|
||||||
try:
|
try:
|
||||||
|
|||||||
17
src/main.py
17
src/main.py
@@ -2,6 +2,7 @@ import os, traceback, json
|
|||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
from time import sleep, perf_counter
|
from time import sleep, perf_counter
|
||||||
|
|
||||||
|
from src.library import setup_libraries
|
||||||
from src.functions import (
|
from src.functions import (
|
||||||
logger,
|
logger,
|
||||||
str_to_bool,
|
str_to_bool,
|
||||||
@@ -153,24 +154,20 @@ def main_loop():
|
|||||||
server_1, server_2, blacklist_users, whitelist_users, user_mapping
|
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)
|
logger("Creating watched lists", 1)
|
||||||
server_1_watched = server_1[1].get_watched(
|
server_1_watched = server_1[1].get_watched(
|
||||||
server_1_users,
|
server_1_users,
|
||||||
blacklist_library,
|
server_1_libraries
|
||||||
whitelist_library,
|
|
||||||
blacklist_library_type,
|
|
||||||
whitelist_library_type,
|
|
||||||
library_mapping,
|
|
||||||
)
|
)
|
||||||
logger("Finished creating watched list server 1", 1)
|
logger("Finished creating watched list server 1", 1)
|
||||||
|
|
||||||
server_2_watched = server_2[1].get_watched(
|
server_2_watched = server_2[1].get_watched(
|
||||||
server_2_users,
|
server_2_users,
|
||||||
blacklist_library,
|
server_2_libraries
|
||||||
whitelist_library,
|
|
||||||
blacklist_library_type,
|
|
||||||
whitelist_library_type,
|
|
||||||
library_mapping,
|
|
||||||
)
|
)
|
||||||
logger("Finished creating watched list server 2", 1)
|
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)
|
logger(f"Plex: Failed to get users, Error: {e}", 2)
|
||||||
raise Exception(e)
|
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(
|
def get_watched(
|
||||||
self,
|
self,
|
||||||
users,
|
users,
|
||||||
blacklist_library,
|
sync_libraries
|
||||||
whitelist_library,
|
|
||||||
blacklist_library_type,
|
|
||||||
whitelist_library_type,
|
|
||||||
library_mapping,
|
|
||||||
):
|
):
|
||||||
try:
|
try:
|
||||||
# Get all libraries
|
# Get all libraries
|
||||||
@@ -500,23 +514,7 @@ class Plex:
|
|||||||
libraries = user_plex.library.sections()
|
libraries = user_plex.library.sections()
|
||||||
|
|
||||||
for library in libraries:
|
for library in libraries:
|
||||||
library_title = library.title
|
if library.title not in sync_libraries:
|
||||||
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
|
|
||||||
)
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
user_watched = get_user_library_watched(user, user_plex, library)
|
user_watched = get_user_library_watched(user, user_plex, library)
|
||||||
|
|||||||
Reference in New Issue
Block a user