From e3358e1a6e01b4b067ae181fb2e9db0f8571c1d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elan=20Ruusam=C3=A4e?= Date: Tue, 25 Oct 2022 01:28:46 +0300 Subject: [PATCH 1/6] Add is_episode property to PlexLibraryItem --- plextraktsync/plex/PlexLibraryItem.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plextraktsync/plex/PlexLibraryItem.py b/plextraktsync/plex/PlexLibraryItem.py index cbc461ee96..a1165b2049 100644 --- a/plextraktsync/plex/PlexLibraryItem.py +++ b/plextraktsync/plex/PlexLibraryItem.py @@ -27,6 +27,10 @@ def __init__(self, item: PlexMedia, plex: PlexApi = None): def is_legacy_agent(self): return not self.item.guid.startswith("plex://") + @cached_property + def is_episode(self): + return self.type == "episode" + @cached_property def is_discover(self): # Use __dict__ access to prevent reloads: From b1173745c841b8b04854d84ae8daab78ef2f5f02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elan=20Ruusam=C3=A4e?= Date: Tue, 25 Oct 2022 02:24:36 +0300 Subject: [PATCH 2/6] Add Media class identity to __str__ --- plextraktsync/media.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plextraktsync/media.py b/plextraktsync/media.py index 34657e86b0..72c8a9029d 100644 --- a/plextraktsync/media.py +++ b/plextraktsync/media.py @@ -225,9 +225,9 @@ def plex_history(self, **kwargs): def __str__(self): if self.plex: - return str(self.plex) + return f"Media<{str(self.plex).strip('<>')}>" - return str(self.trakt) + return f"Media<{str(self.trakt)}>" class MediaFactory: From 9c2ce76553d41f52978e1423483f205d2f809d72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elan=20Ruusam=C3=A4e?= Date: Tue, 25 Oct 2022 01:20:20 +0300 Subject: [PATCH 3/6] Ensure plex is passed as named argument to PlexLibraryItem --- plextraktsync/walker.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plextraktsync/walker.py b/plextraktsync/walker.py index db5061ffac..3d9d08fc92 100644 --- a/plextraktsync/walker.py +++ b/plextraktsync/walker.py @@ -314,7 +314,7 @@ def get_plex_episodes(self, episodes: list[Episode]) -> Generator[Media, Any, No show = self.mf.resolve_guid(guid) if not show: continue - me = self.mf.resolve_any(PlexLibraryItem(pe), show) + me = self.mf.resolve_any(PlexLibraryItem(pe, plex=self.plex), show) if not me: continue From adf6ccff4dd7bc4d4f6846d698ba0bcde6815a64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elan=20Ruusam=C3=A4e?= Date: Tue, 25 Oct 2022 01:22:34 +0300 Subject: [PATCH 4/6] Add show property to PlexLibraryItem --- plextraktsync/plex/PlexLibraryItem.py | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/plextraktsync/plex/PlexLibraryItem.py b/plextraktsync/plex/PlexLibraryItem.py index a1165b2049..9a7ac27cea 100644 --- a/plextraktsync/plex/PlexLibraryItem.py +++ b/plextraktsync/plex/PlexLibraryItem.py @@ -13,15 +13,23 @@ if TYPE_CHECKING: from plexapi.media import MediaPart + from plexapi.video import Episode, Movie, Show from plextraktsync.plex.PlexApi import PlexApi - from plextraktsync.plex.types import PlexMedia class PlexLibraryItem: - def __init__(self, item: PlexMedia, plex: PlexApi = None): + def __init__(self, + item: Movie | Show | Episode, + show: Show | None = None, + plex: PlexApi = None, + ): self.item = item self.plex = plex + if show and self.is_episode: + self._show = show + else: + self._show = None @property def is_legacy_agent(self): @@ -31,6 +39,16 @@ def is_legacy_agent(self): def is_episode(self): return self.type == "episode" + @property + def show(self): + return self._show + + @show.setter + def show(self, show: Show): + if not self.is_episode: + raise RuntimeError("show property can only be set to episodes") + self._show = show + @cached_property def is_discover(self): # Use __dict__ access to prevent reloads: From 5bb5966a700e73b7eed3ad22f09303866ee005f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elan=20Ruusam=C3=A4e?= Date: Tue, 25 Oct 2022 01:30:19 +0300 Subject: [PATCH 5/6] Pass show property when creating PlexLibraryItem --- plextraktsync/plex/PlexLibraryItem.py | 2 +- plextraktsync/walker.py | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/plextraktsync/plex/PlexLibraryItem.py b/plextraktsync/plex/PlexLibraryItem.py index 9a7ac27cea..82b9f13a05 100644 --- a/plextraktsync/plex/PlexLibraryItem.py +++ b/plextraktsync/plex/PlexLibraryItem.py @@ -302,7 +302,7 @@ def watch_progress(self, view_offset): def episodes(self): for ep in self._get_episodes(): - yield PlexLibraryItem(ep, plex=self.plex) + yield PlexLibraryItem(ep, show=self.item, plex=self.plex) @retry() def _get_episodes(self): diff --git a/plextraktsync/walker.py b/plextraktsync/walker.py index 3d9d08fc92..9dd1b1dda1 100644 --- a/plextraktsync/walker.py +++ b/plextraktsync/walker.py @@ -5,6 +5,7 @@ from typing import TYPE_CHECKING, NamedTuple from plextraktsync.decorators.measure_time import measure_time +# <<<<<<< HEAD from plextraktsync.mixin.SetWindowTitle import SetWindowTitle from plextraktsync.plex.PlexGuid import PlexGuid from plextraktsync.plex.PlexLibraryItem import PlexLibraryItem @@ -19,6 +20,11 @@ from plextraktsync.media import Media, MediaFactory from plextraktsync.plex.PlexApi import PlexApi from plextraktsync.plex.PlexLibrarySection import PlexLibrarySection +# ======= +# from plextraktsync.media import Media, MediaFactory +# from plextraktsync.plex_api import PlexApi, PlexLibraryItem, PlexLibrarySection +# from plextraktsync.trakt_api import TraktApi, TraktItem +# >>>>>>> f10d7a3e (Pass show property when creating PlexLibraryItem) class WalkConfig: @@ -310,11 +316,12 @@ def walk_shows(self, shows: set[Media], title="Processing Shows"): def get_plex_episodes(self, episodes: list[Episode]) -> Generator[Media, Any, None]: it = self.progressbar(episodes, desc="Processing episodes") for pe in it: - guid = PlexGuid(pe.grandparentGuid, "show") - show = self.mf.resolve_guid(guid) + ps = self.plex.fetch_item(pe.grandparentKey) + show = self.mf.resolve_any(ps) if not show: continue - me = self.mf.resolve_any(PlexLibraryItem(pe, plex=self.plex), show) + pm = PlexLibraryItem(pe, show=ps.item, plex=self.plex) + me = self.mf.resolve_any(pm, show) if not me: continue From 7e02987e00bc874e06f4016b76fc662ed6f6833d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elan=20Ruusam=C3=A4e?= Date: Tue, 25 Oct 2022 02:23:16 +0300 Subject: [PATCH 6/6] Remove _get_episodes wrapper With @flatten_list can use yield and @retry together --- plextraktsync/plex/PlexLibraryItem.py | 16 ++++++++-------- plextraktsync/walker.py | 7 ------- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/plextraktsync/plex/PlexLibraryItem.py b/plextraktsync/plex/PlexLibraryItem.py index 82b9f13a05..b7d6c2f107 100644 --- a/plextraktsync/plex/PlexLibraryItem.py +++ b/plextraktsync/plex/PlexLibraryItem.py @@ -6,6 +6,7 @@ from trakt.utils import timestamp +from plextraktsync.decorators.flatten import flatten_list from plextraktsync.decorators.retry import retry from plextraktsync.factory import factory from plextraktsync.plex.PlexGuid import PlexGuid @@ -300,19 +301,18 @@ def watch_progress(self, view_offset): percent = view_offset / self.item.duration * 100 return percent - def episodes(self): - for ep in self._get_episodes(): - yield PlexLibraryItem(ep, show=self.item, plex=self.plex) - @retry() - def _get_episodes(self): + @flatten_list + def episodes(self): if self.type == "season": show_id = self.item.parentRatingKey season = self.item.seasonNumber + filters = {"show.id": show_id, "season.index": season} + else: + filters = {"show.id": self.item.ratingKey} - return self.library.search(libtype='episode', filters={'show.id': show_id, 'season.index': season}) - - return self.library.search(libtype='episode', filters={'show.id': self.item.ratingKey}) + for ep in self.library.search(libtype="episode", filters=filters): + yield PlexLibraryItem(ep, show=self.item, plex=self.plex) @cached_property def season_number(self): diff --git a/plextraktsync/walker.py b/plextraktsync/walker.py index 9dd1b1dda1..520668797b 100644 --- a/plextraktsync/walker.py +++ b/plextraktsync/walker.py @@ -5,9 +5,7 @@ from typing import TYPE_CHECKING, NamedTuple from plextraktsync.decorators.measure_time import measure_time -# <<<<<<< HEAD from plextraktsync.mixin.SetWindowTitle import SetWindowTitle -from plextraktsync.plex.PlexGuid import PlexGuid from plextraktsync.plex.PlexLibraryItem import PlexLibraryItem from plextraktsync.trakt.TraktApi import TraktApi from plextraktsync.trakt.TraktItem import TraktItem @@ -20,11 +18,6 @@ from plextraktsync.media import Media, MediaFactory from plextraktsync.plex.PlexApi import PlexApi from plextraktsync.plex.PlexLibrarySection import PlexLibrarySection -# ======= -# from plextraktsync.media import Media, MediaFactory -# from plextraktsync.plex_api import PlexApi, PlexLibraryItem, PlexLibrarySection -# from plextraktsync.trakt_api import TraktApi, TraktItem -# >>>>>>> f10d7a3e (Pass show property when creating PlexLibraryItem) class WalkConfig: