Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove seasons from watch list #174

Merged
merged 3 commits into from
Jun 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
213 changes: 75 additions & 138 deletions src/jellyfin_emby.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ def info(self) -> str:
response = self.query(query_string, "get")

if response:
return f"{response['ServerName']}: {response['Version']}"
return f"{self.server_type} {response['ServerName']}: {response['Version']}"
else:
return None

Expand Down Expand Up @@ -229,38 +229,42 @@ def get_user_library_watched(
f"/Users/{user_id}/Items"
+ f"?ParentId={library_id}&Filters=IsPlayed&IncludeItemTypes=Movie&Recursive=True&Fields=ItemCounts,ProviderIds,MediaSources",
"get",
)
).get("Items", [])

in_progress = self.query(
f"/Users/{user_id}/Items"
+ f"?ParentId={library_id}&Filters=IsResumable&IncludeItemTypes=Movie&Recursive=True&Fields=ItemCounts,ProviderIds,MediaSources",
"get",
)
).get("Items", [])

for movie in watched["Items"] + in_progress["Items"]:
if "MediaSources" in movie and movie["MediaSources"] != {}:
if "UserData" not in movie:
continue
for movie in watched + in_progress:
# Skip if theres no user data which means the movie has not been watched
if "UserData" not in movie:
continue

# Skip if not watched or watched less than a minute
if (
movie["UserData"]["Played"] == True
or movie["UserData"]["PlaybackPositionTicks"] > 600000000
):
logger(
f"{self.server_type}: Adding {movie.get('Name')} to {user_name} watched list",
3,
)
# Skip if theres no media tied to the movie
if "MediaSources" not in movie or movie["MediaSources"] == {}:
continue

# Get the movie's GUIDs
movie_guids = get_guids(self.server_type, movie)
# Skip if not watched or watched less than a minute
if (
movie["UserData"]["Played"] == True
or movie["UserData"]["PlaybackPositionTicks"] > 600000000
):
logger(
f"{self.server_type}: Adding {movie.get('Name')} to {user_name} watched list",
3,
)

# Append the movie dictionary to the list for the given user and library
user_watched[user_name][library_title].append(movie_guids)
logger(
f"{self.server_type}: Added {movie_guids} to {user_name} watched list",
3,
)
# Get the movie's GUIDs
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)
logger(
f"{self.server_type}: Added {movie_guids} to {user_name} watched list",
3,
)

# TV Shows
if library_type in ["Series", "Episode"]:
Expand All @@ -272,20 +276,19 @@ def get_user_library_watched(
f"/Users/{user_id}/Items"
+ f"?ParentId={library_id}&isPlaceHolder=false&IncludeItemTypes=Series&Recursive=True&Fields=ProviderIds,Path,RecursiveItemCount",
"get",
)
).get("Items", [])

# Filter the list of shows to only include those that have been partially or fully watched
watched_shows_filtered = []
for show in watched_shows["Items"]:
if not "UserData" in show:
for show in watched_shows:
if "UserData" not in show:
continue

if "PlayedPercentage" in show["UserData"]:
if show["UserData"]["PlayedPercentage"] > 0:
watched_shows_filtered.append(show)

# Retrieve the seasons of each watched show
seasons_watched = []
# Retrieve the watched/partially watched list of episodes of each watched show
for show in watched_shows_filtered:
logger(
f"{self.server_type}: Adding {show.get('Name')} to {user_name} watched list",
Expand All @@ -298,118 +301,54 @@ def get_user_library_watched(
if "Path" in show
else tuple()
)
show_guids = frozenset(show_guids.items())
show_identifiers = {
"show_guids": show_guids,
"show_id": show["Id"],
}

seasons_watched.append(
self.query(
f"/Shows/{show['Id']}/Seasons"
+ f"?userId={user_id}&isPlaceHolder=false&Fields=ProviderIds,RecursiveItemCount",
"get",
identifiers=frozenset(show_identifiers.items()),
)
show_display_name = (
show_guids["title"]
if show_guids["title"]
else show_guids["locations"]
)

# Filter the list of seasons to only include those that have been partially or fully watched
seasons_watched_filtered = []
for seasons in seasons_watched:
seasons_watched_filtered_dict = {}
seasons_watched_filtered_dict["Identifiers"] = seasons[
"Identifiers"
]
seasons_watched_filtered_dict["Items"] = []
for season in seasons["Items"]:
if "PlayedPercentage" in season["UserData"]:
if season["UserData"]["PlayedPercentage"] > 0:
seasons_watched_filtered_dict["Items"].append(season)

if seasons_watched_filtered_dict["Items"]:
seasons_watched_filtered.append(seasons_watched_filtered_dict)

# Create a list of tasks to retrieve the episodes of each watched season
watched_episodes = []
for seasons in seasons_watched_filtered:
if len(seasons["Items"]) > 0:
for season in seasons["Items"]:
if "IndexNumber" not in season:
logger(
f"Jellyfin: Skipping show {season.get('SeriesName')} season {season.get('Name')} as it has no index number",
3,
)
show_guids = frozenset(show_guids.items())

continue
season_identifiers = dict(seasons["Identifiers"])
season_identifiers["season_index"] = season["IndexNumber"]
watched_task = self.query(
f"/Shows/{season_identifiers['show_id']}/Episodes"
+ f"?seasonId={season['Id']}&userId={user_id}&isPlaceHolder=false&Filters=IsPlayed&Fields=ProviderIds,MediaSources",
"get",
identifiers=frozenset(season_identifiers.items()),
)
show_episodes = self.query(
f"/Shows/{show['Id']}/Episodes"
+ f"?userId={user_id}&isPlaceHolder=false&Fields=ProviderIds,MediaSources",
"get",
).get("Items", [])

# Iterate through the episodes
# Create a list to store the episodes
mark_episodes_list = []
for episode in show_episodes:
if "UserData" not in episode:
continue

in_progress_task = self.query(
f"/Shows/{season_identifiers['show_id']}/Episodes"
+ f"?seasonId={season['Id']}&userId={user_id}&isPlaceHolder=false&Filters=IsResumable&Fields=ProviderIds,MediaSources",
"get",
identifiers=frozenset(season_identifiers.items()),
)
watched_episodes.append(watched_task)
watched_episodes.append(in_progress_task)

# Iterate through the watched episodes
for episodes in watched_episodes:
# If the season has any watched episodes
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"]:
if (
"MediaSources" in episode
and episode["MediaSources"] != {}
):
# If watched or watched more than a minute
if (
episode["UserData"]["Played"] == True
or episode["UserData"]["PlaybackPositionTicks"]
> 600000000
):
episode_dict = get_guids(self.server_type, episode)
# Add the episode dictionary to the season's list of episodes
season_dict["Episodes"].append(episode_dict)

# Add the season dictionary to the show's list of seasons
if (
season_dict["Identifiers"]["show_guids"]
not in user_watched[user_name][library_title]
"MediaSources" not in episode
or episode["MediaSources"] == {}
):
user_watched[user_name][library_title][
season_dict["Identifiers"]["show_guids"]
] = {}
continue

# If watched or watched more than a minute
if (
season_dict["Identifiers"]["season_index"]
not in user_watched[user_name][library_title][
season_dict["Identifiers"]["show_guids"]
]
episode["UserData"]["Played"] == True
or episode["UserData"]["PlaybackPositionTicks"] > 600000000
):
user_watched[user_name][library_title][
season_dict["Identifiers"]["show_guids"]
][season_dict["Identifiers"]["season_index"]] = []
episode_guids = get_guids(self.server_type, episode)
mark_episodes_list.append(episode_guids)

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] = []

user_watched[user_name][library_title][
season_dict["Identifiers"]["show_guids"]
][season_dict["Identifiers"]["season_index"]] = season_dict[
"Episodes"
]
logger(
f"{self.server_type}: Added {season_dict['Episodes']} to {user_name} {season_dict['Identifiers']['show_guids']} watched list",
1,
)
show_guids
] = mark_episodes_list
for episode in mark_episodes_list:
logger(
f"{self.server_type}: Added {episode} to {user_name} {show_display_name} watched list",
1,
)

logger(
f"{self.server_type}: Got watched for {user_name} in library {library_title}",
Expand Down Expand Up @@ -674,7 +613,7 @@ def update_user_watched(
is not None
):
show_found = True
for shows, seasons in videos.items():
for shows, episodes in videos.items():
show = {k: v for k, v in shows}
if (
contains_nested(
Expand All @@ -683,9 +622,8 @@ def update_user_watched(
)
is not None
):
for season in seasons.values():
for episode in season:
episode_videos.append(episode)
for episode in episodes:
episode_videos.append(episode)

break

Expand All @@ -702,14 +640,13 @@ def update_user_watched(
]
):
show_found = True
for show, seasons in videos.items():
for show, episodes in videos.items():
show = {k: v for k, v in show}
if show_provider_id.lower() in show.get(
show_provider_source.lower(), []
):
for season in seasons.values():
for episode in season:
episode_videos.append(episode)
for episode in episodes:
episode_videos.append(episode)

break

Expand Down
Loading