diff --git a/plextraktsync/config.default.yml b/plextraktsync/config.default.yml index 0459d6956c..5614d89927 100644 --- a/plextraktsync/config.default.yml +++ b/plextraktsync/config.default.yml @@ -76,6 +76,16 @@ sync: # Sync Play Progress from Trakt to Plex playback_status: false +# Configuration for liked lists +liked_lists: + # Whether to keep watched items in the list + keep_watched: true + +# Configuration override for specific lists +#liked_list: +# "Saw Collection": +# keep_watched: true + # settings for 'watch' command watch: add_collection: false diff --git a/plextraktsync/config/SyncConfig.py b/plextraktsync/config/SyncConfig.py index bcad138c22..df6fe8a735 100644 --- a/plextraktsync/config/SyncConfig.py +++ b/plextraktsync/config/SyncConfig.py @@ -4,13 +4,19 @@ from typing import TYPE_CHECKING if TYPE_CHECKING: + from typing import Any + from plextraktsync.config.Config import Config from plextraktsync.config.PlexServerConfig import PlexServerConfig class SyncConfig: + config: dict[str, Any] + def __init__(self, config: Config, server_config: PlexServerConfig): self.config = dict(config["sync"]) + self.liked_lists = config["liked_lists"] + self.liked_lists_overrides = config["liked_list"] or {} self.server_config = server_config.sync_config def __getitem__(self, key): @@ -61,6 +67,10 @@ def sync_watched_status(self): self.trakt_to_plex["watched_status"] or self.plex_to_trakt["watched_status"] ) + @property + def liked_lists_keep_watched(self): + return self.liked_lists["keep_watched"] + @cached_property def sync_playback_status(self): return self["trakt_to_plex"]["playback_status"] diff --git a/plextraktsync/sync/Sync.py b/plextraktsync/sync/Sync.py index 14961659bd..9c36b0c58a 100644 --- a/plextraktsync/sync/Sync.py +++ b/plextraktsync/sync/Sync.py @@ -24,7 +24,10 @@ def __init__(self, config: SyncConfig, plex: PlexApi, trakt: TraktApi): @cached_property def trakt_lists(self): - return TraktUserListCollection() + return TraktUserListCollection( + self.config.liked_lists_keep_watched, + self.config.liked_lists_overrides, + ) @cached_property def pm(self): diff --git a/plextraktsync/trakt/TraktUserList.py b/plextraktsync/trakt/TraktUserList.py index d21de74261..40001e37ef 100644 --- a/plextraktsync/trakt/TraktUserList.py +++ b/plextraktsync/trakt/TraktUserList.py @@ -23,12 +23,14 @@ def __init__( trakt_id: int = None, name: str = None, items=None, + keep_watched: bool = None, ): self.trakt_id = trakt_id self.name = name self._items = items self.description = None self.plex_items = [] + self.keep_watched = keep_watched def __iter__(self): return iter(self.items) @@ -64,8 +66,8 @@ def load_items(self): return pl.description, self.build_dict(pl) @classmethod - def from_trakt_list(cls, list_id: int, list_name: str): - return cls(trakt_id=list_id, name=list_name) + def from_trakt_list(cls, list_id: int, list_name: str, keep_watched: bool): + return cls(trakt_id=list_id, name=list_name, keep_watched=keep_watched) @classmethod def from_watchlist(cls, items: list[TraktPlayable]): @@ -98,6 +100,10 @@ def add(self, m: Media): # Already in the list return + if not self.keep_watched and m.plex.is_watched: + # Skip adding watched items + return + self.logger.info( f"Adding {m.title_link} ({m.plex_key}) to Plex list {self.title_link}", extra={"markup": True}, @@ -128,7 +134,14 @@ def plex_items_sorted(self): if len(self.plex_items) == 0: return [] - plex_items = [(r, p.item) for (r, p) in self.plex_items] + plex_items = [ + (r, p.item) + for (r, p) in self.plex_items + if self.keep_watched or (not self.keep_watched and not p.is_watched) + ] + if len(plex_items) == 0: + return [] + _, items = zip(*sorted(dict(reversed(plex_items)).items())) return items diff --git a/plextraktsync/trakt/TraktUserListCollection.py b/plextraktsync/trakt/TraktUserListCollection.py index 8de23d0c8e..73871ba794 100644 --- a/plextraktsync/trakt/TraktUserListCollection.py +++ b/plextraktsync/trakt/TraktUserListCollection.py @@ -14,6 +14,11 @@ class TraktUserListCollection(UserList): logger = logging.getLogger(__name__) + def __init__(self, keep_watched: bool, trakt_lists_overrides: dict): + super().__init__() + self.keep_watched = keep_watched + self.trakt_lists_overrides = trakt_lists_overrides + @property def is_empty(self): return not len(self) @@ -36,6 +41,8 @@ def add_watchlist(self, items: list[TraktPlayable]): return tl def add_list(self, list_id: int, list_name: str): - tl = TraktUserList.from_trakt_list(list_id, list_name) + list_config = self.trakt_lists_overrides.get(list_name, {}) + keep_watched = list_config.get("keep_watched", self.keep_watched) + tl = TraktUserList.from_trakt_list(list_id, list_name, keep_watched) self.append(tl) return tl