commit
b3175305bd
|
|
@ -53,7 +53,7 @@ jobs:
|
||||||
docker-compose -f JellyPlex-Watched-CI/plex/docker-compose.yml up -d
|
docker-compose -f JellyPlex-Watched-CI/plex/docker-compose.yml up -d
|
||||||
docker-compose -f JellyPlex-Watched-CI/jellyfin/docker-compose.yml up -d
|
docker-compose -f JellyPlex-Watched-CI/jellyfin/docker-compose.yml up -d
|
||||||
# Wait for containers to start
|
# Wait for containers to start
|
||||||
sleep 5
|
sleep 10
|
||||||
|
|
||||||
docker-compose -f JellyPlex-Watched-CI/plex/docker-compose.yml logs
|
docker-compose -f JellyPlex-Watched-CI/plex/docker-compose.yml logs
|
||||||
docker-compose -f JellyPlex-Watched-CI/jellyfin/docker-compose.yml logs
|
docker-compose -f JellyPlex-Watched-CI/jellyfin/docker-compose.yml logs
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
**.env
|
**.env*
|
||||||
*.prof
|
*.prof
|
||||||
|
|
||||||
# Byte-compiled / optimized / DLL files
|
# Byte-compiled / optimized / DLL files
|
||||||
|
|
|
||||||
|
|
@ -25,23 +25,34 @@ generate_locations = str_to_bool(os.getenv("GENERATE_LOCATIONS", "True"))
|
||||||
|
|
||||||
|
|
||||||
def get_guids(item):
|
def get_guids(item):
|
||||||
guids = {"title": item["Name"]}
|
if item.get("Name"):
|
||||||
|
guids = {"title": item.get("Name")}
|
||||||
|
else:
|
||||||
|
logger(f"Jellyfin: Name not found in {item.get('Id')}", 1)
|
||||||
|
guids = {"title": None}
|
||||||
|
|
||||||
if "ProviderIds" in item:
|
if "ProviderIds" in item:
|
||||||
guids.update({k.lower(): v for k, v in item["ProviderIds"].items()})
|
guids.update({k.lower(): v for k, v in item["ProviderIds"].items()})
|
||||||
|
else:
|
||||||
|
logger(f"Jellyfin: ProviderIds not found in {item.get('Name')}", 1)
|
||||||
|
|
||||||
if "MediaSources" in item:
|
if "MediaSources" in item:
|
||||||
guids["locations"] = tuple(
|
guids["locations"] = tuple(
|
||||||
[x["Path"].split("/")[-1] for x in item["MediaSources"] if "Path" in x]
|
[x["Path"].split("/")[-1] for x in item["MediaSources"] if "Path" in x]
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
|
logger(f"Jellyfin: MediaSources not found in {item.get('Name')}", 1)
|
||||||
guids["locations"] = tuple()
|
guids["locations"] = tuple()
|
||||||
|
|
||||||
|
if "UserData" in item:
|
||||||
guids["status"] = {
|
guids["status"] = {
|
||||||
"completed": item["UserData"]["Played"],
|
"completed": item["UserData"]["Played"],
|
||||||
# Convert ticks to milliseconds to match Plex
|
# Convert ticks to milliseconds to match Plex
|
||||||
"time": floor(item["UserData"]["PlaybackPositionTicks"] / 10000),
|
"time": floor(item["UserData"]["PlaybackPositionTicks"] / 10000),
|
||||||
}
|
}
|
||||||
|
else:
|
||||||
|
logger(f"Jellyfin: UserData not found in {item.get('Name')}", 1)
|
||||||
|
guids["status"] = {}
|
||||||
|
|
||||||
return guids
|
return guids
|
||||||
|
|
||||||
|
|
@ -132,7 +143,7 @@ class Jellyfin:
|
||||||
)
|
)
|
||||||
if response.status_code != 200:
|
if response.status_code != 200:
|
||||||
raise Exception(
|
raise Exception(
|
||||||
f"Query failed with status {response.status} {response.reason}"
|
f"Query failed with status {response.status_code} {response.reason}"
|
||||||
)
|
)
|
||||||
results = response.json()
|
results = response.json()
|
||||||
|
|
||||||
|
|
@ -142,7 +153,7 @@ class Jellyfin:
|
||||||
)
|
)
|
||||||
if response.status_code != 200:
|
if response.status_code != 200:
|
||||||
raise Exception(
|
raise Exception(
|
||||||
f"Query failed with status {response.status} {response.reason}"
|
f"Query failed with status {response.status_code} {response.reason}"
|
||||||
)
|
)
|
||||||
results = response.json()
|
results = response.json()
|
||||||
|
|
||||||
|
|
@ -221,6 +232,9 @@ class Jellyfin:
|
||||||
|
|
||||||
for movie in watched["Items"] + in_progress["Items"]:
|
for movie in watched["Items"] + in_progress["Items"]:
|
||||||
if "MediaSources" in movie and movie["MediaSources"] != {}:
|
if "MediaSources" in movie and movie["MediaSources"] != {}:
|
||||||
|
if "UserData" not in movie:
|
||||||
|
continue
|
||||||
|
|
||||||
# Skip if not watched or watched less than a minute
|
# Skip if not watched or watched less than a minute
|
||||||
if (
|
if (
|
||||||
movie["UserData"]["Played"] == True
|
movie["UserData"]["Played"] == True
|
||||||
|
|
@ -256,6 +270,9 @@ class Jellyfin:
|
||||||
# Filter the list of shows to only include those that have been partially or fully watched
|
# 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 not "UserData" in show:
|
||||||
|
continue
|
||||||
|
|
||||||
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)
|
||||||
|
|
@ -613,7 +630,7 @@ class Jellyfin:
|
||||||
else:
|
else:
|
||||||
logger(
|
logger(
|
||||||
f"Jellyfin: Skipping movie {jellyfin_video.get('Name')} as it is not in mark list for {user_name}",
|
f"Jellyfin: Skipping movie {jellyfin_video.get('Name')} as it is not in mark list for {user_name}",
|
||||||
1,
|
3,
|
||||||
)
|
)
|
||||||
|
|
||||||
# TV Shows
|
# TV Shows
|
||||||
|
|
|
||||||
26
src/plex.py
26
src/plex.py
|
|
@ -64,11 +64,25 @@ def extract_guids_from_item(item: Union[Movie, Show, Episode]) -> Dict[str, str]
|
||||||
|
|
||||||
|
|
||||||
def get_guids(item: Union[Movie, Episode], completed=True):
|
def get_guids(item: Union[Movie, Episode], completed=True):
|
||||||
|
if not item.locations:
|
||||||
|
logger(
|
||||||
|
f"Plex: {item.title} has no locations",
|
||||||
|
1,
|
||||||
|
)
|
||||||
|
|
||||||
|
if not item.guids:
|
||||||
|
logger(
|
||||||
|
f"Plex: {item.title} has no guids",
|
||||||
|
1,
|
||||||
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"title": item.title,
|
"title": item.title,
|
||||||
"locations": tuple([location.split("/")[-1] for location in item.locations])
|
"locations": (
|
||||||
|
tuple([location.split("/")[-1] for location in item.locations])
|
||||||
if generate_locations
|
if generate_locations
|
||||||
else tuple(),
|
else tuple()
|
||||||
|
),
|
||||||
"status": {
|
"status": {
|
||||||
"completed": completed,
|
"completed": completed,
|
||||||
"time": item.viewOffset,
|
"time": item.viewOffset,
|
||||||
|
|
@ -84,11 +98,11 @@ def get_user_library_watched_show(show, process_episodes, threads=None):
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
"title": show.title,
|
"title": show.title,
|
||||||
"locations": tuple(
|
"locations": (
|
||||||
[location.split("/")[-1] for location in show.locations]
|
tuple([location.split("/")[-1] for location in show.locations])
|
||||||
)
|
|
||||||
if generate_locations
|
if generate_locations
|
||||||
else tuple(),
|
else tuple()
|
||||||
|
),
|
||||||
}
|
}
|
||||||
| extract_guids_from_item(show)
|
| extract_guids_from_item(show)
|
||||||
).items() # Merge the metadata and guid dictionaries
|
).items() # Merge the metadata and guid dictionaries
|
||||||
|
|
|
||||||
|
|
@ -248,7 +248,7 @@ def filter_episode_watched_list_2_keys_dict(
|
||||||
|
|
||||||
# Iterate through episode_watched_list_2_keys_dict["season"] and find the indecies that match season
|
# Iterate through episode_watched_list_2_keys_dict["season"] and find the indecies that match season
|
||||||
for season_index, season_value in enumerate(
|
for season_index, season_value in enumerate(
|
||||||
episode_watched_list_2_keys_dict["season"]
|
episode_watched_list_2_keys_dict.get("season")
|
||||||
):
|
):
|
||||||
if season_value == season:
|
if season_value == season:
|
||||||
season_indecies.append(season_index)
|
season_indecies.append(season_index)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue