Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
629f50ecdc | ||
|
|
3e2450b5fd | ||
|
|
0de5e86837 | ||
|
|
33a719f693 | ||
|
|
9ff985a848 | ||
|
|
5501e21aa8 | ||
|
|
2208d91d07 | ||
|
|
75f7f576ac |
@@ -19,6 +19,7 @@ Keep in sync all your users watched history between jellyfin, plex and emby serv
|
|||||||
- \[x] One way/multi way sync
|
- \[x] One way/multi way sync
|
||||||
- \[x] Sync watched
|
- \[x] Sync watched
|
||||||
- \[x] Sync in progress
|
- \[x] Sync in progress
|
||||||
|
- \[ ] Sync view dates
|
||||||
|
|
||||||
### Jellyfin
|
### Jellyfin
|
||||||
|
|
||||||
@@ -29,6 +30,8 @@ Keep in sync all your users watched history between jellyfin, plex and emby serv
|
|||||||
- \[x] One way/multi way sync
|
- \[x] One way/multi way sync
|
||||||
- \[x] Sync watched
|
- \[x] Sync watched
|
||||||
- \[x] Sync in progress
|
- \[x] Sync in progress
|
||||||
|
- \[x] Sync view dates
|
||||||
|
|
||||||
|
|
||||||
### Emby
|
### Emby
|
||||||
|
|
||||||
@@ -39,6 +42,8 @@ Keep in sync all your users watched history between jellyfin, plex and emby serv
|
|||||||
- \[x] One way/multi way sync
|
- \[x] One way/multi way sync
|
||||||
- \[x] Sync watched
|
- \[x] Sync watched
|
||||||
- \[x] Sync in progress
|
- \[x] Sync in progress
|
||||||
|
- \[x] Sync view dates
|
||||||
|
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "jellyplex-watched"
|
name = "jellyplex-watched"
|
||||||
version = "8.0.0"
|
version = "8.2.0"
|
||||||
description = "Sync watched between media servers locally"
|
description = "Sync watched between media servers locally"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = ">=3.12"
|
requires-python = ">=3.12"
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
# Functions for Jellyfin and Emby
|
# Functions for Jellyfin and Emby
|
||||||
|
|
||||||
|
from datetime import datetime
|
||||||
import requests
|
import requests
|
||||||
import traceback
|
import traceback
|
||||||
import os
|
|
||||||
from math import floor
|
from math import floor
|
||||||
from typing import Any, Literal
|
from typing import Any, Literal
|
||||||
from packaging.version import parse, Version
|
from packaging.version import parse, Version
|
||||||
@@ -76,15 +76,21 @@ def get_mediaitem(
|
|||||||
generate_guids: bool,
|
generate_guids: bool,
|
||||||
generate_locations: bool,
|
generate_locations: bool,
|
||||||
) -> MediaItem:
|
) -> MediaItem:
|
||||||
|
user_data = item.get("UserData", {})
|
||||||
|
last_played_date = user_data.get("LastPlayedDate")
|
||||||
|
|
||||||
|
viewed_date = datetime.today()
|
||||||
|
if last_played_date:
|
||||||
|
viewed_date = datetime.fromisoformat(last_played_date.replace("Z", "+00:00"))
|
||||||
|
|
||||||
return MediaItem(
|
return MediaItem(
|
||||||
identifiers=extract_identifiers_from_item(
|
identifiers=extract_identifiers_from_item(
|
||||||
server_type, item, generate_guids, generate_locations
|
server_type, item, generate_guids, generate_locations
|
||||||
),
|
),
|
||||||
status=WatchedStatus(
|
status=WatchedStatus(
|
||||||
completed=item.get("UserData", {}).get("Played"),
|
completed=user_data.get("Played"),
|
||||||
time=floor(
|
time=floor(user_data.get("PlaybackPositionTicks", 0) / 10000),
|
||||||
item.get("UserData", {}).get("PlaybackPositionTicks", 0) / 10000
|
viewed_date=viewed_date,
|
||||||
),
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -311,7 +317,7 @@ class JellyfinEmby:
|
|||||||
movie_items = []
|
movie_items = []
|
||||||
watched_items = self.query(
|
watched_items = 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,UserDataLastPlayedDate",
|
||||||
"get",
|
"get",
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -320,7 +326,7 @@ class JellyfinEmby:
|
|||||||
|
|
||||||
in_progress_items = self.query(
|
in_progress_items = self.query(
|
||||||
f"/Users/{user_id}/Items"
|
f"/Users/{user_id}/Items"
|
||||||
+ f"?ParentId={library_id}&Filters=IsResumable&IncludeItemTypes=Movie&Recursive=True&Fields=ItemCounts,ProviderIds,MediaSources",
|
+ f"?ParentId={library_id}&Filters=IsResumable&IncludeItemTypes=Movie&Recursive=True&Fields=ItemCounts,ProviderIds,MediaSources,UserDataLastPlayedDate",
|
||||||
"get",
|
"get",
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -371,8 +377,24 @@ class JellyfinEmby:
|
|||||||
if not show.get("UserData"):
|
if not show.get("UserData"):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if show["UserData"].get("PlayedPercentage", 0) > 0:
|
played_percentage = show["UserData"].get("PlayedPercentage")
|
||||||
watched_shows_filtered.append(show)
|
if played_percentage is None:
|
||||||
|
# Emby no longer shows PlayedPercentage
|
||||||
|
total_episodes = show.get("RecursiveItemCount")
|
||||||
|
unplayed_episodes = show["UserData"].get("UnplayedItemCount")
|
||||||
|
|
||||||
|
if total_episodes is None:
|
||||||
|
# Failed to get total count of episodes
|
||||||
|
continue
|
||||||
|
|
||||||
|
if (
|
||||||
|
unplayed_episodes is not None
|
||||||
|
and unplayed_episodes < total_episodes
|
||||||
|
):
|
||||||
|
watched_shows_filtered.append(show)
|
||||||
|
else:
|
||||||
|
if played_percentage > 0:
|
||||||
|
watched_shows_filtered.append(show)
|
||||||
|
|
||||||
# Retrieve the watched/partially watched list of episodes of each watched show
|
# Retrieve the watched/partially watched list of episodes of each watched show
|
||||||
for show in watched_shows_filtered:
|
for show in watched_shows_filtered:
|
||||||
@@ -388,7 +410,7 @@ class JellyfinEmby:
|
|||||||
|
|
||||||
show_episodes = self.query(
|
show_episodes = self.query(
|
||||||
f"/Shows/{show.get('Id')}/Episodes"
|
f"/Shows/{show.get('Id')}/Episodes"
|
||||||
+ f"?userId={user_id}&isPlaceHolder=false&Fields=ProviderIds,MediaSources",
|
+ f"?userId={user_id}&isPlaceHolder=false&Fields=ProviderIds,MediaSources,UserDataLastPlayedDate",
|
||||||
"get",
|
"get",
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -558,12 +580,28 @@ class JellyfinEmby:
|
|||||||
jelly_identifiers, stored_movie.identifiers
|
jelly_identifiers, stored_movie.identifiers
|
||||||
):
|
):
|
||||||
jellyfin_video_id = jellyfin_video.get("Id")
|
jellyfin_video_id = jellyfin_video.get("Id")
|
||||||
|
|
||||||
|
viewed_date: str = (
|
||||||
|
stored_movie.status.viewed_date.isoformat(
|
||||||
|
timespec="milliseconds"
|
||||||
|
).replace("+00:00", "Z")
|
||||||
|
)
|
||||||
|
|
||||||
if stored_movie.status.completed:
|
if stored_movie.status.completed:
|
||||||
msg = f"{self.server_type}: {jellyfin_video.get('Name')} as watched for {user_name} in {library_name}"
|
msg = f"{self.server_type}: {jellyfin_video.get('Name')} as watched for {user_name} in {library_name}"
|
||||||
if not dryrun:
|
if not dryrun:
|
||||||
|
user_data_payload: dict[
|
||||||
|
str, float | bool | datetime
|
||||||
|
] = {
|
||||||
|
"PlayCount": 1,
|
||||||
|
"Played": True,
|
||||||
|
"PlaybackPositionTicks": 0,
|
||||||
|
"LastPlayedDate": viewed_date,
|
||||||
|
}
|
||||||
self.query(
|
self.query(
|
||||||
f"/Users/{user_id}/PlayedItems/{jellyfin_video_id}",
|
f"/Users/{user_id}/Items/{jellyfin_video_id}/UserData",
|
||||||
"post",
|
"post",
|
||||||
|
json=user_data_payload,
|
||||||
)
|
)
|
||||||
|
|
||||||
logger.success(f"{'[DRYRUN] ' if dryrun else ''}{msg}")
|
logger.success(f"{'[DRYRUN] ' if dryrun else ''}{msg}")
|
||||||
@@ -581,14 +619,19 @@ class JellyfinEmby:
|
|||||||
msg = f"{self.server_type}: {jellyfin_video.get('Name')} as partially watched for {floor(stored_movie.status.time / 60_000)} minutes for {user_name} in {library_name}"
|
msg = f"{self.server_type}: {jellyfin_video.get('Name')} as partially watched for {floor(stored_movie.status.time / 60_000)} minutes for {user_name} in {library_name}"
|
||||||
|
|
||||||
if not dryrun:
|
if not dryrun:
|
||||||
playback_position_payload: dict[str, float] = {
|
user_data_payload: dict[
|
||||||
|
str, float | bool | datetime
|
||||||
|
] = {
|
||||||
|
"PlayCount": 0,
|
||||||
|
"Played": False,
|
||||||
"PlaybackPositionTicks": stored_movie.status.time
|
"PlaybackPositionTicks": stored_movie.status.time
|
||||||
* 10_000,
|
* 10_000,
|
||||||
|
"LastPlayedDate": viewed_date,
|
||||||
}
|
}
|
||||||
self.query(
|
self.query(
|
||||||
f"/Users/{user_id}/Items/{jellyfin_video_id}/UserData",
|
f"/Users/{user_id}/Items/{jellyfin_video_id}/UserData",
|
||||||
"post",
|
"post",
|
||||||
json=playback_position_payload,
|
json=user_data_payload,
|
||||||
)
|
)
|
||||||
|
|
||||||
logger.success(f"{'[DRYRUN] ' if dryrun else ''}{msg}")
|
logger.success(f"{'[DRYRUN] ' if dryrun else ''}{msg}")
|
||||||
@@ -671,15 +714,31 @@ class JellyfinEmby:
|
|||||||
stored_ep.identifiers,
|
stored_ep.identifiers,
|
||||||
):
|
):
|
||||||
jellyfin_episode_id = jellyfin_episode.get("Id")
|
jellyfin_episode_id = jellyfin_episode.get("Id")
|
||||||
|
|
||||||
|
viewed_date: str = (
|
||||||
|
stored_ep.status.viewed_date.isoformat(
|
||||||
|
timespec="milliseconds"
|
||||||
|
).replace("+00:00", "Z")
|
||||||
|
)
|
||||||
|
|
||||||
if stored_ep.status.completed:
|
if stored_ep.status.completed:
|
||||||
msg = (
|
msg = (
|
||||||
f"{self.server_type}: {jellyfin_episode.get('SeriesName')} {jellyfin_episode.get('SeasonName')} Episode {jellyfin_episode.get('IndexNumber')} {jellyfin_episode.get('Name')}"
|
f"{self.server_type}: {jellyfin_episode.get('SeriesName')} {jellyfin_episode.get('SeasonName')} Episode {jellyfin_episode.get('IndexNumber')} {jellyfin_episode.get('Name')}"
|
||||||
+ f" as watched for {user_name} in {library_name}"
|
+ f" as watched for {user_name} in {library_name}"
|
||||||
)
|
)
|
||||||
if not dryrun:
|
if not dryrun:
|
||||||
|
user_data_payload: dict[
|
||||||
|
str, float | bool | datetime
|
||||||
|
] = {
|
||||||
|
"PlayCount": 1,
|
||||||
|
"Played": True,
|
||||||
|
"PlaybackPositionTicks": 0,
|
||||||
|
"LastPlayedDate": viewed_date,
|
||||||
|
}
|
||||||
self.query(
|
self.query(
|
||||||
f"/Users/{user_id}/PlayedItems/{jellyfin_episode_id}",
|
f"/Users/{user_id}/Items/{jellyfin_episode_id}/UserData",
|
||||||
"post",
|
"post",
|
||||||
|
json=user_data_payload,
|
||||||
)
|
)
|
||||||
|
|
||||||
logger.success(
|
logger.success(
|
||||||
@@ -703,14 +762,19 @@ class JellyfinEmby:
|
|||||||
)
|
)
|
||||||
|
|
||||||
if not dryrun:
|
if not dryrun:
|
||||||
playback_position_payload = {
|
user_data_payload: dict[
|
||||||
|
str, float | bool | datetime
|
||||||
|
] = {
|
||||||
|
"PlayCount": 0,
|
||||||
|
"Played": False,
|
||||||
"PlaybackPositionTicks": stored_ep.status.time
|
"PlaybackPositionTicks": stored_ep.status.time
|
||||||
* 10_000,
|
* 10_000,
|
||||||
|
"LastPlayedDate": viewed_date,
|
||||||
}
|
}
|
||||||
self.query(
|
self.query(
|
||||||
f"/Users/{user_id}/Items/{jellyfin_episode_id}/UserData",
|
f"/Users/{user_id}/Items/{jellyfin_episode_id}/UserData",
|
||||||
"post",
|
"post",
|
||||||
json=playback_position_payload,
|
json=user_data_payload,
|
||||||
)
|
)
|
||||||
|
|
||||||
logger.success(
|
logger.success(
|
||||||
|
|||||||
11
src/plex.py
11
src/plex.py
@@ -1,3 +1,4 @@
|
|||||||
|
from datetime import datetime, timezone
|
||||||
import requests
|
import requests
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
|
|
||||||
@@ -83,11 +84,19 @@ def get_mediaitem(
|
|||||||
generate_guids: bool = True,
|
generate_guids: bool = True,
|
||||||
generate_locations: bool = True,
|
generate_locations: bool = True,
|
||||||
) -> MediaItem:
|
) -> MediaItem:
|
||||||
|
last_viewed_at = item.lastViewedAt
|
||||||
|
viewed_date = datetime.today()
|
||||||
|
|
||||||
|
if last_viewed_at:
|
||||||
|
viewed_date = last_viewed_at.replace(tzinfo=timezone.utc)
|
||||||
|
|
||||||
return MediaItem(
|
return MediaItem(
|
||||||
identifiers=extract_identifiers_from_item(
|
identifiers=extract_identifiers_from_item(
|
||||||
item, generate_guids, generate_locations
|
item, generate_guids, generate_locations
|
||||||
),
|
),
|
||||||
status=WatchedStatus(completed=completed, time=item.viewOffset),
|
status=WatchedStatus(
|
||||||
|
completed=completed, time=item.viewOffset, viewed_date=viewed_date
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import copy
|
import copy
|
||||||
|
from datetime import datetime
|
||||||
from pydantic import BaseModel, Field
|
from pydantic import BaseModel, Field
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
from typing import Any
|
from typing import Any
|
||||||
@@ -21,6 +22,7 @@ class MediaIdentifiers(BaseModel):
|
|||||||
class WatchedStatus(BaseModel):
|
class WatchedStatus(BaseModel):
|
||||||
completed: bool
|
completed: bool
|
||||||
time: int
|
time: int
|
||||||
|
viewed_date: datetime
|
||||||
|
|
||||||
|
|
||||||
class MediaItem(BaseModel):
|
class MediaItem(BaseModel):
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
from datetime import datetime
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
|
||||||
@@ -23,6 +24,8 @@ from src.watched import (
|
|||||||
cleanup_watched,
|
cleanup_watched,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
viewed_date = datetime.today()
|
||||||
|
|
||||||
tv_shows_watched_list_1: list[Series] = [
|
tv_shows_watched_list_1: list[Series] = [
|
||||||
Series(
|
Series(
|
||||||
identifiers=MediaIdentifiers(
|
identifiers=MediaIdentifiers(
|
||||||
@@ -41,7 +44,7 @@ tv_shows_watched_list_1: list[Series] = [
|
|||||||
tmdb_id="968589",
|
tmdb_id="968589",
|
||||||
tvdb_id="295296",
|
tvdb_id="295296",
|
||||||
),
|
),
|
||||||
status=WatchedStatus(completed=True, time=0),
|
status=WatchedStatus(completed=True, time=0, viewed_date=viewed_date),
|
||||||
),
|
),
|
||||||
MediaItem(
|
MediaItem(
|
||||||
identifiers=MediaIdentifiers(
|
identifiers=MediaIdentifiers(
|
||||||
@@ -51,7 +54,9 @@ tv_shows_watched_list_1: list[Series] = [
|
|||||||
tmdb_id="968590",
|
tmdb_id="968590",
|
||||||
tvdb_id="295297",
|
tvdb_id="295297",
|
||||||
),
|
),
|
||||||
status=WatchedStatus(completed=False, time=240000),
|
status=WatchedStatus(
|
||||||
|
completed=False, time=240000, viewed_date=viewed_date
|
||||||
|
),
|
||||||
),
|
),
|
||||||
MediaItem(
|
MediaItem(
|
||||||
identifiers=MediaIdentifiers(
|
identifiers=MediaIdentifiers(
|
||||||
@@ -61,7 +66,7 @@ tv_shows_watched_list_1: list[Series] = [
|
|||||||
tmdb_id="968592",
|
tmdb_id="968592",
|
||||||
tvdb_id="295298",
|
tvdb_id="295298",
|
||||||
),
|
),
|
||||||
status=WatchedStatus(completed=True, time=0),
|
status=WatchedStatus(completed=True, time=0, viewed_date=viewed_date),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -82,7 +87,7 @@ tv_shows_watched_list_1: list[Series] = [
|
|||||||
tmdb_id="4661246",
|
tmdb_id="4661246",
|
||||||
tvdb_id="10009418",
|
tvdb_id="10009418",
|
||||||
),
|
),
|
||||||
status=WatchedStatus(completed=True, time=0),
|
status=WatchedStatus(completed=True, time=0, viewed_date=viewed_date),
|
||||||
),
|
),
|
||||||
MediaItem(
|
MediaItem(
|
||||||
identifiers=MediaIdentifiers(
|
identifiers=MediaIdentifiers(
|
||||||
@@ -92,7 +97,9 @@ tv_shows_watched_list_1: list[Series] = [
|
|||||||
tmdb_id="4712059",
|
tmdb_id="4712059",
|
||||||
tvdb_id="10009419",
|
tvdb_id="10009419",
|
||||||
),
|
),
|
||||||
status=WatchedStatus(completed=False, time=240000),
|
status=WatchedStatus(
|
||||||
|
completed=False, time=240000, viewed_date=viewed_date
|
||||||
|
),
|
||||||
),
|
),
|
||||||
MediaItem(
|
MediaItem(
|
||||||
identifiers=MediaIdentifiers(
|
identifiers=MediaIdentifiers(
|
||||||
@@ -102,7 +109,7 @@ tv_shows_watched_list_1: list[Series] = [
|
|||||||
tmdb_id="4712061",
|
tmdb_id="4712061",
|
||||||
tvdb_id="10009420",
|
tvdb_id="10009420",
|
||||||
),
|
),
|
||||||
status=WatchedStatus(completed=True, time=0),
|
status=WatchedStatus(completed=True, time=0, viewed_date=viewed_date),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -123,7 +130,7 @@ tv_shows_watched_list_1: list[Series] = [
|
|||||||
tmdb_id="3070048",
|
tmdb_id="3070048",
|
||||||
tvdb_id="8438181",
|
tvdb_id="8438181",
|
||||||
),
|
),
|
||||||
status=WatchedStatus(completed=True, time=0),
|
status=WatchedStatus(completed=True, time=0, viewed_date=viewed_date),
|
||||||
),
|
),
|
||||||
MediaItem(
|
MediaItem(
|
||||||
identifiers=MediaIdentifiers(
|
identifiers=MediaIdentifiers(
|
||||||
@@ -133,7 +140,7 @@ tv_shows_watched_list_1: list[Series] = [
|
|||||||
tmdb_id="4568681",
|
tmdb_id="4568681",
|
||||||
tvdb_id="9829910",
|
tvdb_id="9829910",
|
||||||
),
|
),
|
||||||
status=WatchedStatus(completed=True, time=0),
|
status=WatchedStatus(completed=True, time=0, viewed_date=viewed_date),
|
||||||
),
|
),
|
||||||
MediaItem(
|
MediaItem(
|
||||||
identifiers=MediaIdentifiers(
|
identifiers=MediaIdentifiers(
|
||||||
@@ -143,7 +150,7 @@ tv_shows_watched_list_1: list[Series] = [
|
|||||||
tmdb_id="4497012",
|
tmdb_id="4497012",
|
||||||
tvdb_id="9870382",
|
tvdb_id="9870382",
|
||||||
),
|
),
|
||||||
status=WatchedStatus(completed=True, time=0),
|
status=WatchedStatus(completed=True, time=0, viewed_date=viewed_date),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -170,7 +177,7 @@ tv_shows_watched_list_2: list[Series] = [
|
|||||||
tvdb_id="295294",
|
tvdb_id="295294",
|
||||||
tmdb_id=None,
|
tmdb_id=None,
|
||||||
),
|
),
|
||||||
status=WatchedStatus(completed=True, time=0),
|
status=WatchedStatus(completed=True, time=0, viewed_date=viewed_date),
|
||||||
),
|
),
|
||||||
MediaItem(
|
MediaItem(
|
||||||
identifiers=MediaIdentifiers(
|
identifiers=MediaIdentifiers(
|
||||||
@@ -180,7 +187,9 @@ tv_shows_watched_list_2: list[Series] = [
|
|||||||
tvdb_id="295295",
|
tvdb_id="295295",
|
||||||
tmdb_id=None,
|
tmdb_id=None,
|
||||||
),
|
),
|
||||||
status=WatchedStatus(completed=False, time=300670),
|
status=WatchedStatus(
|
||||||
|
completed=False, time=300670, viewed_date=viewed_date
|
||||||
|
),
|
||||||
),
|
),
|
||||||
MediaItem(
|
MediaItem(
|
||||||
identifiers=MediaIdentifiers(
|
identifiers=MediaIdentifiers(
|
||||||
@@ -190,7 +199,7 @@ tv_shows_watched_list_2: list[Series] = [
|
|||||||
tvdb_id="295298",
|
tvdb_id="295298",
|
||||||
tmdb_id=None,
|
tmdb_id=None,
|
||||||
),
|
),
|
||||||
status=WatchedStatus(completed=True, time=0),
|
status=WatchedStatus(completed=True, time=0, viewed_date=viewed_date),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -211,7 +220,7 @@ tv_shows_watched_list_2: list[Series] = [
|
|||||||
tvdb_id="9959300",
|
tvdb_id="9959300",
|
||||||
tmdb_id=None,
|
tmdb_id=None,
|
||||||
),
|
),
|
||||||
status=WatchedStatus(completed=True, time=0),
|
status=WatchedStatus(completed=True, time=0, viewed_date=viewed_date),
|
||||||
),
|
),
|
||||||
MediaItem(
|
MediaItem(
|
||||||
identifiers=MediaIdentifiers(
|
identifiers=MediaIdentifiers(
|
||||||
@@ -221,7 +230,9 @@ tv_shows_watched_list_2: list[Series] = [
|
|||||||
tvdb_id="10009417",
|
tvdb_id="10009417",
|
||||||
tmdb_id=None,
|
tmdb_id=None,
|
||||||
),
|
),
|
||||||
status=WatchedStatus(completed=False, time=300741),
|
status=WatchedStatus(
|
||||||
|
completed=False, time=300741, viewed_date=viewed_date
|
||||||
|
),
|
||||||
),
|
),
|
||||||
MediaItem(
|
MediaItem(
|
||||||
identifiers=MediaIdentifiers(
|
identifiers=MediaIdentifiers(
|
||||||
@@ -231,7 +242,7 @@ tv_shows_watched_list_2: list[Series] = [
|
|||||||
tvdb_id="10009420",
|
tvdb_id="10009420",
|
||||||
tmdb_id=None,
|
tmdb_id=None,
|
||||||
),
|
),
|
||||||
status=WatchedStatus(completed=True, time=0),
|
status=WatchedStatus(completed=True, time=0, viewed_date=viewed_date),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -252,7 +263,7 @@ tv_shows_watched_list_2: list[Series] = [
|
|||||||
tvdb_id="8438181",
|
tvdb_id="8438181",
|
||||||
tmdb_id=None,
|
tmdb_id=None,
|
||||||
),
|
),
|
||||||
status=WatchedStatus(completed=True, time=0),
|
status=WatchedStatus(completed=True, time=0, viewed_date=viewed_date),
|
||||||
),
|
),
|
||||||
MediaItem(
|
MediaItem(
|
||||||
identifiers=MediaIdentifiers(
|
identifiers=MediaIdentifiers(
|
||||||
@@ -262,7 +273,7 @@ tv_shows_watched_list_2: list[Series] = [
|
|||||||
tvdb_id="9829910",
|
tvdb_id="9829910",
|
||||||
tmdb_id=None,
|
tmdb_id=None,
|
||||||
),
|
),
|
||||||
status=WatchedStatus(completed=True, time=0),
|
status=WatchedStatus(completed=True, time=0, viewed_date=viewed_date),
|
||||||
),
|
),
|
||||||
MediaItem(
|
MediaItem(
|
||||||
identifiers=MediaIdentifiers(
|
identifiers=MediaIdentifiers(
|
||||||
@@ -272,7 +283,7 @@ tv_shows_watched_list_2: list[Series] = [
|
|||||||
tvdb_id="9870382",
|
tvdb_id="9870382",
|
||||||
tmdb_id=None,
|
tmdb_id=None,
|
||||||
),
|
),
|
||||||
status=WatchedStatus(completed=True, time=0),
|
status=WatchedStatus(completed=True, time=0, viewed_date=viewed_date),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -299,7 +310,7 @@ expected_tv_show_watched_list_1: list[Series] = [
|
|||||||
tmdb_id="968589",
|
tmdb_id="968589",
|
||||||
tvdb_id="295296",
|
tvdb_id="295296",
|
||||||
),
|
),
|
||||||
status=WatchedStatus(completed=True, time=0),
|
status=WatchedStatus(completed=True, time=0, viewed_date=viewed_date),
|
||||||
),
|
),
|
||||||
MediaItem(
|
MediaItem(
|
||||||
identifiers=MediaIdentifiers(
|
identifiers=MediaIdentifiers(
|
||||||
@@ -309,7 +320,9 @@ expected_tv_show_watched_list_1: list[Series] = [
|
|||||||
tmdb_id="968590",
|
tmdb_id="968590",
|
||||||
tvdb_id="295297",
|
tvdb_id="295297",
|
||||||
),
|
),
|
||||||
status=WatchedStatus(completed=False, time=240000),
|
status=WatchedStatus(
|
||||||
|
completed=False, time=240000, viewed_date=viewed_date
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -330,7 +343,7 @@ expected_tv_show_watched_list_1: list[Series] = [
|
|||||||
tmdb_id="4661246",
|
tmdb_id="4661246",
|
||||||
tvdb_id="10009418",
|
tvdb_id="10009418",
|
||||||
),
|
),
|
||||||
status=WatchedStatus(completed=True, time=0),
|
status=WatchedStatus(completed=True, time=0, viewed_date=viewed_date),
|
||||||
),
|
),
|
||||||
MediaItem(
|
MediaItem(
|
||||||
identifiers=MediaIdentifiers(
|
identifiers=MediaIdentifiers(
|
||||||
@@ -340,7 +353,9 @@ expected_tv_show_watched_list_1: list[Series] = [
|
|||||||
tmdb_id="4712059",
|
tmdb_id="4712059",
|
||||||
tvdb_id="10009419",
|
tvdb_id="10009419",
|
||||||
),
|
),
|
||||||
status=WatchedStatus(completed=False, time=240000),
|
status=WatchedStatus(
|
||||||
|
completed=False, time=240000, viewed_date=viewed_date
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -367,7 +382,7 @@ expected_tv_show_watched_list_2: list[Series] = [
|
|||||||
tvdb_id="295294",
|
tvdb_id="295294",
|
||||||
tmdb_id=None,
|
tmdb_id=None,
|
||||||
),
|
),
|
||||||
status=WatchedStatus(completed=True, time=0),
|
status=WatchedStatus(completed=True, time=0, viewed_date=viewed_date),
|
||||||
),
|
),
|
||||||
MediaItem(
|
MediaItem(
|
||||||
identifiers=MediaIdentifiers(
|
identifiers=MediaIdentifiers(
|
||||||
@@ -377,7 +392,9 @@ expected_tv_show_watched_list_2: list[Series] = [
|
|||||||
tvdb_id="295295",
|
tvdb_id="295295",
|
||||||
tmdb_id=None,
|
tmdb_id=None,
|
||||||
),
|
),
|
||||||
status=WatchedStatus(completed=False, time=300670),
|
status=WatchedStatus(
|
||||||
|
completed=False, time=300670, viewed_date=viewed_date
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -398,7 +415,7 @@ expected_tv_show_watched_list_2: list[Series] = [
|
|||||||
tvdb_id="9959300",
|
tvdb_id="9959300",
|
||||||
tmdb_id=None,
|
tmdb_id=None,
|
||||||
),
|
),
|
||||||
status=WatchedStatus(completed=True, time=0),
|
status=WatchedStatus(completed=True, time=0, viewed_date=viewed_date),
|
||||||
),
|
),
|
||||||
MediaItem(
|
MediaItem(
|
||||||
identifiers=MediaIdentifiers(
|
identifiers=MediaIdentifiers(
|
||||||
@@ -408,7 +425,9 @@ expected_tv_show_watched_list_2: list[Series] = [
|
|||||||
tvdb_id="10009417",
|
tvdb_id="10009417",
|
||||||
tmdb_id=None,
|
tmdb_id=None,
|
||||||
),
|
),
|
||||||
status=WatchedStatus(completed=False, time=300741),
|
status=WatchedStatus(
|
||||||
|
completed=False, time=300741, viewed_date=viewed_date
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -426,7 +445,7 @@ movies_watched_list_1: list[MediaItem] = [
|
|||||||
tmdb_id="10378",
|
tmdb_id="10378",
|
||||||
tvdb_id="12352",
|
tvdb_id="12352",
|
||||||
),
|
),
|
||||||
status=WatchedStatus(completed=True, time=0),
|
status=WatchedStatus(completed=True, time=0, viewed_date=viewed_date),
|
||||||
),
|
),
|
||||||
MediaItem(
|
MediaItem(
|
||||||
identifiers=MediaIdentifiers(
|
identifiers=MediaIdentifiers(
|
||||||
@@ -436,7 +455,7 @@ movies_watched_list_1: list[MediaItem] = [
|
|||||||
tmdb_id="1029575",
|
tmdb_id="1029575",
|
||||||
tvdb_id="351194",
|
tvdb_id="351194",
|
||||||
),
|
),
|
||||||
status=WatchedStatus(completed=True, time=0),
|
status=WatchedStatus(completed=True, time=0, viewed_date=viewed_date),
|
||||||
),
|
),
|
||||||
MediaItem(
|
MediaItem(
|
||||||
identifiers=MediaIdentifiers(
|
identifiers=MediaIdentifiers(
|
||||||
@@ -446,7 +465,7 @@ movies_watched_list_1: list[MediaItem] = [
|
|||||||
tmdb_id="466420",
|
tmdb_id="466420",
|
||||||
tvdb_id="135852",
|
tvdb_id="135852",
|
||||||
),
|
),
|
||||||
status=WatchedStatus(completed=False, time=240000),
|
status=WatchedStatus(completed=False, time=240000, viewed_date=viewed_date),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -462,7 +481,7 @@ movies_watched_list_2: list[MediaItem] = [
|
|||||||
tmdb_id="1029575",
|
tmdb_id="1029575",
|
||||||
tvdb_id=None,
|
tvdb_id=None,
|
||||||
),
|
),
|
||||||
status=WatchedStatus(completed=True, time=0),
|
status=WatchedStatus(completed=True, time=0, viewed_date=viewed_date),
|
||||||
),
|
),
|
||||||
MediaItem(
|
MediaItem(
|
||||||
identifiers=MediaIdentifiers(
|
identifiers=MediaIdentifiers(
|
||||||
@@ -472,7 +491,7 @@ movies_watched_list_2: list[MediaItem] = [
|
|||||||
tmdb_id="507089",
|
tmdb_id="507089",
|
||||||
tvdb_id=None,
|
tvdb_id=None,
|
||||||
),
|
),
|
||||||
status=WatchedStatus(completed=True, time=0),
|
status=WatchedStatus(completed=True, time=0, viewed_date=viewed_date),
|
||||||
),
|
),
|
||||||
MediaItem(
|
MediaItem(
|
||||||
identifiers=MediaIdentifiers(
|
identifiers=MediaIdentifiers(
|
||||||
@@ -482,7 +501,7 @@ movies_watched_list_2: list[MediaItem] = [
|
|||||||
tmdb_id="695721",
|
tmdb_id="695721",
|
||||||
tvdb_id=None,
|
tvdb_id=None,
|
||||||
),
|
),
|
||||||
status=WatchedStatus(completed=False, time=301215),
|
status=WatchedStatus(completed=False, time=301215, viewed_date=viewed_date),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -498,7 +517,7 @@ expected_movie_watched_list_1: list[MediaItem] = [
|
|||||||
tmdb_id="10378",
|
tmdb_id="10378",
|
||||||
tvdb_id="12352",
|
tvdb_id="12352",
|
||||||
),
|
),
|
||||||
status=WatchedStatus(completed=True, time=0),
|
status=WatchedStatus(completed=True, time=0, viewed_date=viewed_date),
|
||||||
),
|
),
|
||||||
MediaItem(
|
MediaItem(
|
||||||
identifiers=MediaIdentifiers(
|
identifiers=MediaIdentifiers(
|
||||||
@@ -508,7 +527,7 @@ expected_movie_watched_list_1: list[MediaItem] = [
|
|||||||
tmdb_id="466420",
|
tmdb_id="466420",
|
||||||
tvdb_id="135852",
|
tvdb_id="135852",
|
||||||
),
|
),
|
||||||
status=WatchedStatus(completed=False, time=240000),
|
status=WatchedStatus(completed=False, time=240000, viewed_date=viewed_date),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -524,7 +543,7 @@ expected_movie_watched_list_2: list[MediaItem] = [
|
|||||||
tmdb_id="507089",
|
tmdb_id="507089",
|
||||||
tvdb_id=None,
|
tvdb_id=None,
|
||||||
),
|
),
|
||||||
status=WatchedStatus(completed=True, time=0),
|
status=WatchedStatus(completed=True, time=0, viewed_date=viewed_date),
|
||||||
),
|
),
|
||||||
MediaItem(
|
MediaItem(
|
||||||
identifiers=MediaIdentifiers(
|
identifiers=MediaIdentifiers(
|
||||||
@@ -534,7 +553,7 @@ expected_movie_watched_list_2: list[MediaItem] = [
|
|||||||
tmdb_id="695721",
|
tmdb_id="695721",
|
||||||
tvdb_id=None,
|
tvdb_id=None,
|
||||||
),
|
),
|
||||||
status=WatchedStatus(completed=False, time=301215),
|
status=WatchedStatus(completed=False, time=301215, viewed_date=viewed_date),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -562,7 +581,7 @@ tv_shows_2_watched_list_1: list[Series] = [
|
|||||||
tmdb_id="282843",
|
tmdb_id="282843",
|
||||||
tvdb_id="176357",
|
tvdb_id="176357",
|
||||||
),
|
),
|
||||||
status=WatchedStatus(completed=True, time=0),
|
status=WatchedStatus(completed=True, time=0, viewed_date=viewed_date),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|||||||
2
uv.lock
generated
2
uv.lock
generated
@@ -84,7 +84,7 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jellyplex-watched"
|
name = "jellyplex-watched"
|
||||||
version = "8.0.0"
|
version = "8.2.0"
|
||||||
source = { virtual = "." }
|
source = { virtual = "." }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "loguru" },
|
{ name = "loguru" },
|
||||||
|
|||||||
Reference in New Issue
Block a user