Do not mark shows/movies that do not exist
This commit is contained in:
@@ -170,7 +170,9 @@ def combine_watched_dicts(dicts: list):
|
|||||||
# If the subkey already exists in the combined dictionary,
|
# If the subkey already exists in the combined dictionary,
|
||||||
# check if the values are different and raise an exception if they are
|
# check if the values are different and raise an exception if they are
|
||||||
if combined_dict[key][subkey] != subvalue:
|
if combined_dict[key][subkey] != subvalue:
|
||||||
raise ValueError(f"Conflicting values for subkey '{subkey}' under key '{key}'")
|
raise ValueError(
|
||||||
|
f"Conflicting values for subkey '{subkey}' under key '{key}'"
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
# If the subkey does not exist in the combined dictionary, add it
|
# If the subkey does not exist in the combined dictionary, add it
|
||||||
combined_dict[key][subkey] = subvalue
|
combined_dict[key][subkey] = subvalue
|
||||||
@@ -218,22 +220,56 @@ def cleanup_watched(
|
|||||||
for show_key_1 in watched_list_1[user_1][library_1].keys():
|
for show_key_1 in watched_list_1[user_1][library_1].keys():
|
||||||
show_key_dict = dict(show_key_1)
|
show_key_dict = dict(show_key_1)
|
||||||
for season in watched_list_1[user_1][library_1][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]:
|
for episode in watched_list_1[user_1][library_1][show_key_1][
|
||||||
if is_episode_in_dict(episode, episode_watched_list_2_keys_dict):
|
season
|
||||||
if episode in modified_watched_list_1[user_1][library_1][show_key_1][season]:
|
]:
|
||||||
logger(f"Removing {episode} from {show_key_dict['title']}", 3)
|
if is_episode_in_dict(
|
||||||
modified_watched_list_1[user_1][library_1][show_key_1][season].remove(episode)
|
episode, episode_watched_list_2_keys_dict
|
||||||
|
):
|
||||||
|
if (
|
||||||
|
episode
|
||||||
|
in modified_watched_list_1[user_1][library_1][
|
||||||
|
show_key_1
|
||||||
|
][season]
|
||||||
|
):
|
||||||
|
logger(
|
||||||
|
f"Removing {episode} from {show_key_dict['title']}",
|
||||||
|
3,
|
||||||
|
)
|
||||||
|
modified_watched_list_1[user_1][library_1][
|
||||||
|
show_key_1
|
||||||
|
][season].remove(episode)
|
||||||
|
|
||||||
# Remove empty seasons
|
# Remove empty seasons
|
||||||
if len(modified_watched_list_1[user_1][library_1][show_key_1][season]) == 0:
|
if (
|
||||||
if season in modified_watched_list_1[user_1][library_1][show_key_1]:
|
len(
|
||||||
logger(f"Removing {season} from {show_key_dict['title']} because it is empty", 3)
|
modified_watched_list_1[user_1][library_1][show_key_1][
|
||||||
del modified_watched_list_1[user_1][library_1][show_key_1][season]
|
season
|
||||||
|
]
|
||||||
|
)
|
||||||
|
== 0
|
||||||
|
):
|
||||||
|
if (
|
||||||
|
season
|
||||||
|
in modified_watched_list_1[user_1][library_1][
|
||||||
|
show_key_1
|
||||||
|
]
|
||||||
|
):
|
||||||
|
logger(
|
||||||
|
f"Removing {season} from {show_key_dict['title']} because it is empty",
|
||||||
|
3,
|
||||||
|
)
|
||||||
|
del modified_watched_list_1[user_1][library_1][
|
||||||
|
show_key_1
|
||||||
|
][season]
|
||||||
|
|
||||||
# Remove empty shows
|
# Remove empty shows
|
||||||
if len(modified_watched_list_1[user_1][library_1][show_key_1]) == 0:
|
if len(modified_watched_list_1[user_1][library_1][show_key_1]) == 0:
|
||||||
if show_key_1 in modified_watched_list_1[user_1][library_1]:
|
if show_key_1 in modified_watched_list_1[user_1][library_1]:
|
||||||
logger(f"Removing {show_key_dict['title']} because it is empty", 3)
|
logger(
|
||||||
|
f"Removing {show_key_dict['title']} because it is empty",
|
||||||
|
3,
|
||||||
|
)
|
||||||
del modified_watched_list_1[user_1][library_1][show_key_1]
|
del modified_watched_list_1[user_1][library_1][show_key_1]
|
||||||
|
|
||||||
for user_1 in watched_list_1:
|
for user_1 in watched_list_1:
|
||||||
@@ -306,6 +342,7 @@ def is_episode_in_dict(episode, episode_watched_list_2_keys_dict):
|
|||||||
# If the loop completes without finding a match, return False
|
# If the loop completes without finding a match, return False
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def future_thread_executor(args: list, workers: int = -1):
|
def future_thread_executor(args: list, workers: int = -1):
|
||||||
futures_list = []
|
futures_list = []
|
||||||
results = []
|
results = []
|
||||||
|
|||||||
160
src/jellyfin.py
160
src/jellyfin.py
@@ -85,8 +85,9 @@ class Jellyfin:
|
|||||||
f"Jellyfin: Generating watched for {user_name} in library {library_title}",
|
f"Jellyfin: Generating watched for {user_name} in library {library_title}",
|
||||||
0,
|
0,
|
||||||
)
|
)
|
||||||
# Movies
|
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
|
# Movies
|
||||||
if library_type == "Movie":
|
if library_type == "Movie":
|
||||||
user_watched[user_name][library_title] = []
|
user_watched[user_name][library_title] = []
|
||||||
watched = await self.query(
|
watched = await self.query(
|
||||||
@@ -95,16 +96,27 @@ class Jellyfin:
|
|||||||
"get",
|
"get",
|
||||||
session,
|
session,
|
||||||
)
|
)
|
||||||
|
|
||||||
for movie in watched["Items"]:
|
for movie in watched["Items"]:
|
||||||
if movie["UserData"]["Played"] is True:
|
# Check if the movie has been played
|
||||||
movie_guids = {}
|
if (
|
||||||
movie_guids["title"] = movie["Name"]
|
movie["UserData"]["Played"] is True
|
||||||
|
and "MediaSources" in movie
|
||||||
|
and movie["MediaSources"] is not {}
|
||||||
|
):
|
||||||
|
# Create a dictionary for the movie with its title
|
||||||
|
movie_guids = {"title": movie["Name"]}
|
||||||
|
|
||||||
|
# If the movie has provider IDs, add them to the dictionary
|
||||||
if "ProviderIds" in movie:
|
if "ProviderIds" in movie:
|
||||||
# Lowercase movie["ProviderIds"] keys
|
movie_guids.update(
|
||||||
movie_guids = {
|
{
|
||||||
k.lower(): v
|
k.lower(): v
|
||||||
for k, v in movie["ProviderIds"].items()
|
for k, v in movie["ProviderIds"].items()
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
# If the movie has media sources, add them to the dictionary
|
||||||
if "MediaSources" in movie:
|
if "MediaSources" in movie:
|
||||||
movie_guids["locations"] = tuple(
|
movie_guids["locations"] = tuple(
|
||||||
[
|
[
|
||||||
@@ -112,22 +124,31 @@ class Jellyfin:
|
|||||||
for x in movie["MediaSources"]
|
for x in movie["MediaSources"]
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Append the movie dictionary to the list for the given user and library
|
||||||
user_watched[user_name][library_title].append(movie_guids)
|
user_watched[user_name][library_title].append(movie_guids)
|
||||||
|
|
||||||
# TV Shows
|
# TV Shows
|
||||||
if library_type == "Series":
|
if library_type == "Series":
|
||||||
|
# Initialize an empty dictionary for the given user and library
|
||||||
user_watched[user_name][library_title] = {}
|
user_watched[user_name][library_title] = {}
|
||||||
|
|
||||||
|
# Retrieve a list of watched TV shows
|
||||||
watched_shows = await self.query(
|
watched_shows = await self.query(
|
||||||
f"/Users/{user_id}/Items"
|
f"/Users/{user_id}/Items"
|
||||||
+ f"?ParentId={library_id}&isPlaceHolder=false&Fields=ProviderIds,Path,RecursiveItemCount",
|
+ f"?ParentId={library_id}&isPlaceHolder=false&Fields=ProviderIds,Path,RecursiveItemCount",
|
||||||
"get",
|
"get",
|
||||||
session,
|
session,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Filter the list of shows to only include those that have been partially or fully watched
|
||||||
watched_shows_filtered = []
|
watched_shows_filtered = []
|
||||||
for show in watched_shows["Items"]:
|
for show in watched_shows["Items"]:
|
||||||
if "PlayedPercentage" in show["UserData"]:
|
if "PlayedPercentage" in show["UserData"]:
|
||||||
if show["UserData"]["PlayedPercentage"] > 0:
|
if show["UserData"]["PlayedPercentage"] > 0:
|
||||||
watched_shows_filtered.append(show)
|
watched_shows_filtered.append(show)
|
||||||
|
|
||||||
|
# Create a list of tasks to retrieve the seasons of each watched show
|
||||||
seasons_tasks = []
|
seasons_tasks = []
|
||||||
for show in watched_shows_filtered:
|
for show in watched_shows_filtered:
|
||||||
show_guids = {
|
show_guids = {
|
||||||
@@ -136,21 +157,26 @@ class Jellyfin:
|
|||||||
show_guids["title"] = show["Name"]
|
show_guids["title"] = show["Name"]
|
||||||
show_guids["locations"] = tuple([show["Path"].split("/")[-1]])
|
show_guids["locations"] = tuple([show["Path"].split("/")[-1]])
|
||||||
show_guids = frozenset(show_guids.items())
|
show_guids = frozenset(show_guids.items())
|
||||||
identifiers = {"show_guids": show_guids, "show_id": show["Id"]}
|
show_identifiers = {
|
||||||
task = asyncio.ensure_future(
|
"show_guids": show_guids,
|
||||||
|
"show_id": show["Id"],
|
||||||
|
}
|
||||||
|
season_task = asyncio.ensure_future(
|
||||||
self.query(
|
self.query(
|
||||||
f"/Shows/{show['Id']}/Seasons"
|
f"/Shows/{show['Id']}/Seasons"
|
||||||
+ f"?userId={user_id}&isPlaceHolder=false&Fields=ProviderIds,RecursiveItemCount",
|
+ f"?userId={user_id}&isPlaceHolder=false&Fields=ProviderIds,RecursiveItemCount",
|
||||||
"get",
|
"get",
|
||||||
session,
|
session,
|
||||||
frozenset(identifiers.items()),
|
frozenset(show_identifiers.items()),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
seasons_tasks.append(task)
|
seasons_tasks.append(season_task)
|
||||||
|
|
||||||
|
# Retrieve the seasons for each watched show
|
||||||
seasons_watched = await asyncio.gather(*seasons_tasks)
|
seasons_watched = await asyncio.gather(*seasons_tasks)
|
||||||
seasons_watched_filtered = []
|
|
||||||
|
|
||||||
|
# Filter the list of seasons to only include those that have been partially or fully watched
|
||||||
|
seasons_watched_filtered = []
|
||||||
for seasons in seasons_watched:
|
for seasons in seasons_watched:
|
||||||
seasons_watched_filtered_dict = {}
|
seasons_watched_filtered_dict = {}
|
||||||
seasons_watched_filtered_dict["Identifiers"] = seasons[
|
seasons_watched_filtered_dict["Identifiers"] = seasons[
|
||||||
@@ -169,6 +195,7 @@ class Jellyfin:
|
|||||||
seasons_watched_filtered_dict
|
seasons_watched_filtered_dict
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Create a list of tasks to retrieve the episodes of each watched season
|
||||||
episodes_tasks = []
|
episodes_tasks = []
|
||||||
for seasons in seasons_watched_filtered:
|
for seasons in seasons_watched_filtered:
|
||||||
if len(seasons["Items"]) > 0:
|
if len(seasons["Items"]) > 0:
|
||||||
@@ -176,7 +203,7 @@ class Jellyfin:
|
|||||||
season_identifiers = dict(seasons["Identifiers"])
|
season_identifiers = dict(seasons["Identifiers"])
|
||||||
season_identifiers["season_id"] = season["Id"]
|
season_identifiers["season_id"] = season["Id"]
|
||||||
season_identifiers["season_name"] = season["Name"]
|
season_identifiers["season_name"] = season["Name"]
|
||||||
task = asyncio.ensure_future(
|
episode_task = asyncio.ensure_future(
|
||||||
self.query(
|
self.query(
|
||||||
f"/Shows/{season_identifiers['show_id']}/Episodes"
|
f"/Shows/{season_identifiers['show_id']}/Episodes"
|
||||||
+ f"?seasonId={season['Id']}&userId={user_id}&isPlaceHolder=false&isPlayed=true&Fields=ProviderIds,MediaSources",
|
+ f"?seasonId={season['Id']}&userId={user_id}&isPlaceHolder=false&isPlayed=true&Fields=ProviderIds,MediaSources",
|
||||||
@@ -185,62 +212,67 @@ class Jellyfin:
|
|||||||
frozenset(season_identifiers.items()),
|
frozenset(season_identifiers.items()),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
episodes_tasks.append(task)
|
episodes_tasks.append(episode_task)
|
||||||
|
|
||||||
|
# Retrieve the episodes for each watched season
|
||||||
watched_episodes = await asyncio.gather(*episodes_tasks)
|
watched_episodes = await asyncio.gather(*episodes_tasks)
|
||||||
|
|
||||||
|
# Iterate through the watched episodes
|
||||||
for episodes in watched_episodes:
|
for episodes in watched_episodes:
|
||||||
|
# If the season has any watched episodes
|
||||||
if len(episodes["Items"]) > 0:
|
if len(episodes["Items"]) > 0:
|
||||||
|
# Create a dictionary for the season with its identifier and episodes
|
||||||
|
season_dict = {}
|
||||||
|
season_dict["Identifiers"] = dict(episodes["Identifiers"])
|
||||||
|
season_dict["Episodes"] = []
|
||||||
for episode in episodes["Items"]:
|
for episode in episodes["Items"]:
|
||||||
if episode["UserData"]["Played"] is True:
|
if (
|
||||||
if (
|
episode["UserData"]["Played"] is True
|
||||||
"ProviderIds" in episode
|
and "MediaSources" in episode
|
||||||
or "MediaSources" in episode
|
and episode["MediaSources"] is not {}
|
||||||
):
|
):
|
||||||
episode_identifiers = dict(
|
# Create a dictionary for the episode with its provider IDs and media sources
|
||||||
episodes["Identifiers"]
|
episode_dict = {
|
||||||
)
|
k.lower(): v
|
||||||
show_guids = episode_identifiers["show_guids"]
|
for k, v in episode["ProviderIds"].items()
|
||||||
if (
|
}
|
||||||
show_guids
|
episode_dict["title"] = episode["Name"]
|
||||||
not in user_watched[user_name][
|
episode_dict["locations"] = tuple(
|
||||||
library_title
|
[
|
||||||
]
|
x["Path"].split("/")[-1]
|
||||||
):
|
for x in episode["MediaSources"]
|
||||||
user_watched[user_name][library_title][
|
]
|
||||||
show_guids
|
)
|
||||||
] = {}
|
# Add the episode dictionary to the season's list of episodes
|
||||||
if (
|
season_dict["Episodes"].append(episode_dict)
|
||||||
episode_identifiers["season_name"]
|
# Add the season dictionary to the show's list of seasons
|
||||||
not in user_watched[user_name][
|
if (
|
||||||
library_title
|
season_dict["Identifiers"]["show_guids"]
|
||||||
][show_guids]
|
not in user_watched[user_name][library_title]
|
||||||
):
|
):
|
||||||
user_watched[user_name][library_title][
|
user_watched[user_name][library_title][
|
||||||
show_guids
|
season_dict["Identifiers"]["show_guids"]
|
||||||
][episode_identifiers["season_name"]] = []
|
] = {}
|
||||||
|
|
||||||
episode_guids = {}
|
if (
|
||||||
if "ProviderIds" in episode:
|
season_dict["Identifiers"]["season_name"]
|
||||||
episode_guids = {
|
not in user_watched[user_name][library_title][
|
||||||
k.lower(): v
|
season_dict["Identifiers"]["show_guids"]
|
||||||
for k, v in episode[
|
]
|
||||||
"ProviderIds"
|
):
|
||||||
].items()
|
user_watched[user_name][library_title][
|
||||||
}
|
season_dict["Identifiers"]["show_guids"]
|
||||||
if "MediaSources" in episode:
|
][season_dict["Identifiers"]["season_name"]] = []
|
||||||
episode_guids["locations"] = tuple(
|
|
||||||
[
|
|
||||||
x["Path"].split("/")[-1]
|
|
||||||
for x in episode["MediaSources"]
|
|
||||||
]
|
|
||||||
)
|
|
||||||
user_watched[user_name][library_title][
|
|
||||||
show_guids
|
|
||||||
][episode_identifiers["season_name"]].append(
|
|
||||||
episode_guids
|
|
||||||
)
|
|
||||||
|
|
||||||
logger(f"Jellyfin: Got watched for {user_name} in library {library_title}")
|
user_watched[user_name][library_title][
|
||||||
|
season_dict["Identifiers"]["show_guids"]
|
||||||
|
][season_dict["Identifiers"]["season_name"]] = season_dict[
|
||||||
|
"Episodes"
|
||||||
|
]
|
||||||
|
|
||||||
|
logger(
|
||||||
|
f"Jellyfin: Got watched for {user_name} in library {library_title}", 1
|
||||||
|
)
|
||||||
return user_watched
|
return user_watched
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger(
|
logger(
|
||||||
|
|||||||
63
src/main.py
63
src/main.py
@@ -13,6 +13,7 @@ from src.jellyfin import Jellyfin
|
|||||||
|
|
||||||
load_dotenv(override=True)
|
load_dotenv(override=True)
|
||||||
|
|
||||||
|
|
||||||
def setup_black_white_lists(
|
def setup_black_white_lists(
|
||||||
blacklist_library: str,
|
blacklist_library: str,
|
||||||
whitelist_library: str,
|
whitelist_library: str,
|
||||||
@@ -310,9 +311,28 @@ def generate_server_connections():
|
|||||||
|
|
||||||
return servers
|
return servers
|
||||||
|
|
||||||
def get_server_watched(server_connection: list, users: dict, blacklist_library: list, whitelist_library: list, blacklist_library_type: list, whitelist_library_type: list, library_mapping: dict):
|
|
||||||
|
def get_server_watched(
|
||||||
|
server_connection: list,
|
||||||
|
users: dict,
|
||||||
|
blacklist_library: list,
|
||||||
|
whitelist_library: list,
|
||||||
|
blacklist_library_type: list,
|
||||||
|
whitelist_library_type: list,
|
||||||
|
library_mapping: dict,
|
||||||
|
):
|
||||||
if server_connection[0] == "plex":
|
if server_connection[0] == "plex":
|
||||||
return server_connection[1].get_watched(
|
return server_connection[1].get_watched(
|
||||||
|
users,
|
||||||
|
blacklist_library,
|
||||||
|
whitelist_library,
|
||||||
|
blacklist_library_type,
|
||||||
|
whitelist_library_type,
|
||||||
|
library_mapping,
|
||||||
|
)
|
||||||
|
elif server_connection[0] == "jellyfin":
|
||||||
|
return asyncio.run(
|
||||||
|
server_connection[1].get_watched(
|
||||||
users,
|
users,
|
||||||
blacklist_library,
|
blacklist_library,
|
||||||
whitelist_library,
|
whitelist_library,
|
||||||
@@ -320,22 +340,27 @@ def get_server_watched(server_connection: list, users: dict, blacklist_library:
|
|||||||
whitelist_library_type,
|
whitelist_library_type,
|
||||||
library_mapping,
|
library_mapping,
|
||||||
)
|
)
|
||||||
elif server_connection[0] == "jellyfin":
|
)
|
||||||
return asyncio.run(server_connection[1].get_watched(
|
|
||||||
users,
|
|
||||||
blacklist_library,
|
|
||||||
whitelist_library,
|
|
||||||
blacklist_library_type,
|
|
||||||
whitelist_library_type,
|
|
||||||
library_mapping,
|
|
||||||
))
|
|
||||||
|
|
||||||
|
|
||||||
def update_server_watched(server_connection: list, server_watched_filtered: dict, user_mapping: dict, library_mapping: dict, dryrun: bool):
|
def update_server_watched(
|
||||||
|
server_connection: list,
|
||||||
|
server_watched_filtered: dict,
|
||||||
|
user_mapping: dict,
|
||||||
|
library_mapping: dict,
|
||||||
|
dryrun: bool,
|
||||||
|
):
|
||||||
if server_connection[0] == "plex":
|
if server_connection[0] == "plex":
|
||||||
server_connection[1].update_watched(server_watched_filtered, user_mapping, library_mapping, dryrun)
|
server_connection[1].update_watched(
|
||||||
|
server_watched_filtered, user_mapping, library_mapping, dryrun
|
||||||
|
)
|
||||||
elif server_connection[0] == "jellyfin":
|
elif server_connection[0] == "jellyfin":
|
||||||
asyncio.run(server_connection[1].update_watched(server_watched_filtered, user_mapping, library_mapping, dryrun))
|
asyncio.run(
|
||||||
|
server_connection[1].update_watched(
|
||||||
|
server_watched_filtered, user_mapping, library_mapping, dryrun
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def main_loop():
|
def main_loop():
|
||||||
logfile = os.getenv("LOGFILE", "log.log")
|
logfile = os.getenv("LOGFILE", "log.log")
|
||||||
@@ -448,11 +473,19 @@ def main_loop():
|
|||||||
)
|
)
|
||||||
|
|
||||||
update_server_watched(
|
update_server_watched(
|
||||||
server_1, server_2_watched_filtered, user_mapping, library_mapping, dryrun
|
server_1,
|
||||||
|
server_2_watched_filtered,
|
||||||
|
user_mapping,
|
||||||
|
library_mapping,
|
||||||
|
dryrun,
|
||||||
)
|
)
|
||||||
|
|
||||||
update_server_watched(
|
update_server_watched(
|
||||||
server_2, server_1_watched_filtered, user_mapping, library_mapping, dryrun
|
server_2,
|
||||||
|
server_1_watched_filtered,
|
||||||
|
user_mapping,
|
||||||
|
library_mapping,
|
||||||
|
dryrun,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
24
src/plex.py
24
src/plex.py
@@ -15,11 +15,14 @@ from src.functions import (
|
|||||||
# Bypass hostname validation for ssl. Taken from https://github.com/pkkid/python-plexapi/issues/143#issuecomment-775485186
|
# Bypass hostname validation for ssl. Taken from https://github.com/pkkid/python-plexapi/issues/143#issuecomment-775485186
|
||||||
class HostNameIgnoringAdapter(requests.adapters.HTTPAdapter):
|
class HostNameIgnoringAdapter(requests.adapters.HTTPAdapter):
|
||||||
def init_poolmanager(self, connections, maxsize, block=..., **pool_kwargs):
|
def init_poolmanager(self, connections, maxsize, block=..., **pool_kwargs):
|
||||||
self.poolmanager = PoolManager(num_pools=connections,
|
self.poolmanager = PoolManager(
|
||||||
maxsize=maxsize,
|
num_pools=connections,
|
||||||
block=block,
|
maxsize=maxsize,
|
||||||
assert_hostname=False,
|
block=block,
|
||||||
**pool_kwargs)
|
assert_hostname=False,
|
||||||
|
**pool_kwargs,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_user_library_watched(user, user_plex, library):
|
def get_user_library_watched(user, user_plex, library):
|
||||||
try:
|
try:
|
||||||
@@ -39,8 +42,9 @@ def get_user_library_watched(user, user_plex, library):
|
|||||||
for video in library_videos.search(unwatched=False):
|
for video in library_videos.search(unwatched=False):
|
||||||
movie_guids = {}
|
movie_guids = {}
|
||||||
for guid in video.guids:
|
for guid in video.guids:
|
||||||
guid_source = re.search(r"(.*)://", guid.id).group(1).lower()
|
# Extract source and id from guid.id
|
||||||
guid_id = re.search(r"://(.*)", guid.id).group(1)
|
m = re.match(r"(.*)://(.*)", guid.id)
|
||||||
|
guid_source, guid_id = m.group(1).lower(), m.group(2)
|
||||||
movie_guids[guid_source] = guid_id
|
movie_guids[guid_source] = guid_id
|
||||||
|
|
||||||
movie_guids["title"] = video.title
|
movie_guids["title"] = video.title
|
||||||
@@ -94,7 +98,7 @@ def get_user_library_watched(user, user_plex, library):
|
|||||||
|
|
||||||
user_watched[user_name][library.title][show_guids] = episode_guids
|
user_watched[user_name][library.title][show_guids] = episode_guids
|
||||||
|
|
||||||
logger(f"Plex: Got watched for {user_name} in library {library.title}", 0)
|
logger(f"Plex: Got watched for {user_name} in library {library.title}", 1)
|
||||||
return user_watched
|
return user_watched
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger(
|
logger(
|
||||||
@@ -316,7 +320,9 @@ class Plex:
|
|||||||
user_plex = self.plex
|
user_plex = self.plex
|
||||||
else:
|
else:
|
||||||
user_plex = self.login(
|
user_plex = self.login(
|
||||||
self.plex._baseurl, user.get_token(self.plex.machineIdentifier), self.ssl_bypass
|
self.plex._baseurl,
|
||||||
|
user.get_token(self.plex.machineIdentifier),
|
||||||
|
self.ssl_bypass,
|
||||||
)
|
)
|
||||||
|
|
||||||
libraries = user_plex.library.sections()
|
libraries = user_plex.library.sections()
|
||||||
|
|||||||
Reference in New Issue
Block a user