show reset : mark episodes unwatched in plex
MODIFY
plextraktsync/media.py
plextraktsync/media.py
@@ -160,7 +160,9 @@ def mark_watched_trakt(self, dry_run):
self.trakt_api.mark_watched(self.trakt, self.plex.seen_date)
elif self.is_episode:
if self.show_reset_at and self.plex.seen_date < self.show_reset_at:
- return
+ logger.info(f"Show {self.plex.item.show().title} has been reset in trakt at {self.show_reset_at}.")
+ logger.info(f"Marking {self.plex.item.show().title} as unwatched in Plex.")
+ self.plex_api.reset_show(show=self.plex.item.show(), reset_date=self.show_reset_at)
if not dry_run:
logger.info(f"Marking as watched in Trakt: {self}")
self.trakt_api.mark_watched(

MODIFY
plextraktsync/plex_api.py
plextraktsync/plex_api.py
@@ -639,6 +639,11 @@ def history(self, m, device=False, account=False):
def mark_watched(self, m):
m.markPlayed()
+ @nocache
+ @retry()
+ def mark_unwatched(self, m):
+ m.markUnplayed()
+
@nocache
def has_sessions(self):
try:
@@ -710,3 +715,14 @@ def search_online(self, title: str, media_type: str):
except NotFound:
return None
return map(PlexLibraryItem, result)
+
+ @nocache
+ def reset_show(self, show, reset_date):
+ reset_count = 0
+ for ep in show.watched():
+ if ep.lastViewedAt < reset_date:
+ self.mark_unwatched(ep)
+ reset_count += 1
+ else:
+ logger.debug(f"{show.title} {ep.seasonEpisode} watched at {ep.lastViewedAt} after reset date {reset_date}")
+ logger.debug(f"{show.title}: {reset_count} Plex episode(s) marked as unwatched.")

show reset : mark episodes unwatched in plex