From ecbf8715c7117233a616e21ec39dd49a84571acb Mon Sep 17 00:00:00 2001 From: Everett Southwick Date: Fri, 22 Sep 2023 21:12:03 -0400 Subject: [PATCH 1/5] chore: update config to indicate fqdn preference --- config.example.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/config.example.json b/config.example.json index 34d1b5b..15c10e2 100644 --- a/config.example.json +++ b/config.example.json @@ -3,13 +3,13 @@ "log_level": "INFO", "schedule_interval": "1d", "plex": { - "base_url": "https://host:port", + "base_url": "https://plex.domain.com", "token": "" }, "radarr": { "enabled": true, "api_key": "", - "base_url": "https://host:port/api/v3", + "base_url": "https://radarr.domain.com/api/v3", "exempt_tag_names": [ "exempt-from-auto-delete", "some-other-tag" @@ -20,7 +20,7 @@ "sonarr": { "enabled": true, "api_key": "", - "base_url": "https://host:port/api/v3", + "base_url": "https://sonarr.domain.com/api/v3", "monitor_continuing_series": true, "exempt_tag_names": [ "exempt-from-auto-delete", @@ -39,7 +39,7 @@ "overseerr": { "enabled": true, "api_key": "", - "base_url": "http://host:port/api/v1", + "base_url": "http://overseerr.domain.com/api/v1", "fetch_limit": 20 }, "experimental": { From 7ba8a99d247449ecfa1d0c936598a72abd060016 Mon Sep 17 00:00:00 2001 From: Everett Southwick Date: Fri, 22 Sep 2023 21:14:03 -0400 Subject: [PATCH 2/5] chore: update references to url --- CONFIGURATION.md | 8 ++++---- config.example.json | 2 +- src/config.py | 16 ++++++++-------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/CONFIGURATION.md b/CONFIGURATION.md index 8e47442..e6b40e5 100644 --- a/CONFIGURATION.md +++ b/CONFIGURATION.md @@ -77,7 +77,7 @@ Set the interval at which the script runs by replacing the `schedule_interval` v ```json "plex": { - "base_url": "https://host:port", + "base_url": "https://plex.domain.com", "token": "" } ``` @@ -94,7 +94,7 @@ Replace the empty `token` value with your Plex token. "radarr": { "enabled": true, "api_key": "", - "base_url": "https://host:port/api/v3", + "base_url": "https://radarr.domain.com/api/v3", "exempt_tag_names": [ "exempt-from-auto-delete", "some-other-tag" @@ -128,7 +128,7 @@ Set the threshold for unwatched media deletion by replacing the `unwatched_delet "sonarr": { "enabled": true, "api_key": "", - "base_url": "https://host:port/api/v3", + "base_url": "https://sonarr.domain.com/api/v3", "monitor_continuing_series": true, "dynamic_load": { "enabled": false, @@ -199,7 +199,7 @@ Set the threshold for unwatched media deletion by replacing the `unwatched_delet "overseerr": { "enabled": true, "api_key": "", - "base_url": "http://host:port/api/v1", + "base_url": "https://overseerr.domain.com/api/v1", "fetch_limit": 20 } ``` diff --git a/config.example.json b/config.example.json index 15c10e2..542abe4 100644 --- a/config.example.json +++ b/config.example.json @@ -39,7 +39,7 @@ "overseerr": { "enabled": true, "api_key": "", - "base_url": "http://overseerr.domain.com/api/v1", + "base_url": "https://overseerr.domain.com/api/v1", "fetch_limit": 20 }, "experimental": { diff --git a/src/config.py b/src/config.py index 32172b4..2e8d7e8 100644 --- a/src/config.py +++ b/src/config.py @@ -91,10 +91,10 @@ def __init__(self): self.dry_run = True self.log_level = "INFO" self.schedule_interval = 86400 - self.plex = PlexConfig("https://host:port", "") - self.radarr = RadarrConfig(False, "", "https://host:port/api/v3", [], 7776000, 2592000) - self.sonarr = SonarrConfig(False, "", "https://host:port/api/v3", True, [], DynamicLoad(False, 3, 3, 7776000, 600), 7776000, 2592000) - self.overseerr = OverseerrConfig(False, "", "http://host:port/api/v1", 10) + self.plex = PlexConfig("https://plex.domain.com", "") + self.radarr = RadarrConfig(False, "", "https://radarr.domain.com/api/v3", [], 7776000, 2592000) + self.sonarr = SonarrConfig(False, "", "https://sonarr.domain.com/api/v3", True, [], DynamicLoad(False, 3, 3, 7776000, 600), 7776000, 2592000) + self.overseerr = OverseerrConfig(False, "", "https://overseerr.domain.com/api/v1", 10) self.experimental = Experimental(FreeSpace(False, 0, "", False, False, ProgressiveDeletion(False, 0, 86400))) config = self._get_config() @@ -133,14 +133,14 @@ def _parse_config(self, config: Dict[str, Any]) -> None: self.log_level = self._get_value_or_default(config, "log_level", "INFO") self.schedule_interval = self._get_value_or_default(config, "schedule_interval", 86400, True) plex_config = self._get_value_or_default(config, "plex", {}) - self.plex = PlexConfig(self._get_value_or_default(plex_config, "base_url", "https://host:port"), self._get_value_or_default(plex_config, "token", "")) + self.plex = PlexConfig(self._get_value_or_default(plex_config, "base_url", "https://plex.domain.com"), self._get_value_or_default(plex_config, "token", "")) radarr_config = self._get_value_or_default(config, "radarr", {}) - self.radarr = RadarrConfig(self._get_value_or_default(radarr_config, "enabled", False), self._get_value_or_default(radarr_config, "api_key", ""), self._get_value_or_default(radarr_config, "base_url", "https://host:port/api/v3"), self._get_value_or_default(radarr_config, "exempt_tag_names", []), self._get_value_or_default(radarr_config, "watched_deletion_threshold", 7776000, True), self._get_value_or_default(radarr_config, "unwatched_deletion_threshold", 2592000, True)) + self.radarr = RadarrConfig(self._get_value_or_default(radarr_config, "enabled", False), self._get_value_or_default(radarr_config, "api_key", ""), self._get_value_or_default(radarr_config, "base_url", "https://radarr.domain.com/api/v3"), self._get_value_or_default(radarr_config, "exempt_tag_names", []), self._get_value_or_default(radarr_config, "watched_deletion_threshold", 7776000, True), self._get_value_or_default(radarr_config, "unwatched_deletion_threshold", 2592000, True)) sonarr_config = self._get_value_or_default(config, "sonarr", {}) dynamic_load_config = self._get_value_or_default(sonarr_config, "dynamic_load", {}) - self.sonarr = SonarrConfig(self._get_value_or_default(sonarr_config, "enabled", False), self._get_value_or_default(sonarr_config, "api_key", ""), self._get_value_or_default(sonarr_config, "base_url", "https://host:port/api/v3"), self._get_value_or_default(sonarr_config, "monitor_continuing_series", True), self._get_value_or_default(sonarr_config, "exempt_tag_names", []), DynamicLoad(self._get_value_or_default(dynamic_load_config, "enabled", False), self._get_value_or_default(dynamic_load_config, "episodes_to_load", 3), self._get_value_or_default(dynamic_load_config, "episodes_to_keep", 3), self._get_value_or_default(dynamic_load_config, "watched_deletion_threshold", 7776000, True), self._get_value_or_default(dynamic_load_config, "schedule_interval", 600, True)), self._get_value_or_default(sonarr_config, "watched_deletion_threshold", 7776000, True), self._get_value_or_default(sonarr_config, "unwatched_deletion_threshold", 2592000, True)) + self.sonarr = SonarrConfig(self._get_value_or_default(sonarr_config, "enabled", False), self._get_value_or_default(sonarr_config, "api_key", ""), self._get_value_or_default(sonarr_config, "base_url", "https://sonarr.domain.com/api/v3"), self._get_value_or_default(sonarr_config, "monitor_continuing_series", True), self._get_value_or_default(sonarr_config, "exempt_tag_names", []), DynamicLoad(self._get_value_or_default(dynamic_load_config, "enabled", False), self._get_value_or_default(dynamic_load_config, "episodes_to_load", 3), self._get_value_or_default(dynamic_load_config, "episodes_to_keep", 3), self._get_value_or_default(dynamic_load_config, "watched_deletion_threshold", 7776000, True), self._get_value_or_default(dynamic_load_config, "schedule_interval", 600, True)), self._get_value_or_default(sonarr_config, "watched_deletion_threshold", 7776000, True), self._get_value_or_default(sonarr_config, "unwatched_deletion_threshold", 2592000, True)) overseerr_config = self._get_value_or_default(config, "overseerr", {}) - self.overseerr = OverseerrConfig(self._get_value_or_default(overseerr_config, "enabled", False), self._get_value_or_default(overseerr_config, "api_key", ""), self._get_value_or_default(overseerr_config, "base_url", "http://host:port/api/v1"), self._get_value_or_default(overseerr_config, "fetch_limit", 10)) + self.overseerr = OverseerrConfig(self._get_value_or_default(overseerr_config, "enabled", False), self._get_value_or_default(overseerr_config, "api_key", ""), self._get_value_or_default(overseerr_config, "base_url", "https://overseerr.domain.com/api/v1"), self._get_value_or_default(overseerr_config, "fetch_limit", 10)) experimental_config = self._get_value_or_default(config, "experimental", {}) free_space_config = self._get_value_or_default(experimental_config, "free_space", {}) progressive_deletion_config = self._get_value_or_default(free_space_config, "progressive_deletion", {}) From 82bd6727c1354598ac37c8bbd387e2510808e835 Mon Sep 17 00:00:00 2001 From: Everett Southwick Date: Tue, 26 Sep 2023 16:17:15 -0400 Subject: [PATCH 3/5] feat: dynamic load don't unload recent episodes --- src/clients/sonarr.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/clients/sonarr.py b/src/clients/sonarr.py index 025a893..9121213 100644 --- a/src/clients/sonarr.py +++ b/src/clients/sonarr.py @@ -1,4 +1,5 @@ """Sonarr API client.""" +import time from datetime import datetime import requests from retry import retry @@ -191,9 +192,12 @@ def __handle_continuing_series(self, series, dry_run: bool = False): def __get_episodes_to_load_and_unload(self, series, dynamic_media): episodes = self.__get_media_episodes(series.get("id")) - filtered_episodes = [episode for episode in episodes if episode.get("seasonNumber", -1) != 0 and episode.get("airDate") < datetime.now().isoformat()] + filtered_episodes = [episode for episode in episodes if episode.get("seasonNumber", -1) != 0 and episode.get("airDate") < datetime.now().isoformat() and episode.get("airDate") > datetime.fromtimestamp(time.time() - self.dynamic_load.watched_deletion_threshold).isoformat()] sorted_episodes = sorted(filtered_episodes, key=lambda x: (x['seasonNumber'], x['episodeNumber'])) episode_index = next((index for (index, episode) in enumerate(sorted_episodes) if episode.get("seasonNumber", 0) == dynamic_media.season and episode.get("episodeNumber", 0) == dynamic_media.episode), None) + + episodes_to_load = [] + episodes_to_unload = [] if episode_index is not None: load_index_start = episode_index + 1 load_index_end = episode_index + self.dynamic_load.episodes_to_keep + 1 @@ -207,8 +211,11 @@ def __get_episodes_to_load_and_unload(self, series, dynamic_media): return episodes_to_load, episodes_to_unload def __handle_episode_loading(self, episodes_to_load, series, dry_run): + if not episodes_to_load: + return + monitor_episode_ids = [] - search_episode_ids = [] + search_episode_ids = [] for episode in episodes_to_load: if not episode.get("monitored", False): monitor_episode_ids.append(episode["id"]) @@ -228,6 +235,9 @@ def __log_episode_loading(self, episode, series, dry_run): logger.info("[SONARR][DYNAMIC LOAD] Loading S%sE%s of %s", episode.get("seasonNumber"), episode.get("episodeNumber"), series.get("title")) def __handle_episode_unloading(self, episodes_to_unload, series, dry_run): + if not episodes_to_unload: + return 0 + unmonitor_episode_ids = [] delete_episode_file_ids = [] for episode in episodes_to_unload: From 65fc88666299eb1870bb9c116d0f81311089c4b2 Mon Sep 17 00:00:00 2001 From: Everett Southwick Date: Tue, 26 Sep 2023 16:17:36 -0400 Subject: [PATCH 4/5] chore: version 2.2.2 --- eraserr.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eraserr.py b/eraserr.py index b37f809..cf31641 100644 --- a/eraserr.py +++ b/eraserr.py @@ -2,7 +2,7 @@ import argparse from src.main import main -__version__ = "2.2.1" +__version__ = "2.2.2" def add_arguments(arg_parser: argparse.ArgumentParser): ''' From 37cec7b1dd6f144f3ecf75b8551c93e8ce582d48 Mon Sep 17 00:00:00 2001 From: Everett Southwick Date: Thu, 19 Oct 2023 22:38:58 -0400 Subject: [PATCH 5/5] chore: reduce log level of dynamic load --- src/clients/plex.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/clients/plex.py b/src/clients/plex.py index e4e0445..195c8b9 100644 --- a/src/clients/plex.py +++ b/src/clients/plex.py @@ -89,7 +89,7 @@ def __media_is_unloadable(self, media, session, watched_media_expiry_seconds): history = media.history(mindate=min_date) for entry in history: if entry.accountID != session.user.id: - logger.info("[PLEX][DYNAMIC LOAD] %s has been watched by a different user. It should not be unloaded.", media.grandparentTitle) + logger.debug("[PLEX][DYNAMIC LOAD] %s has been watched by a different user. It should not be unloaded.", media.grandparentTitle) return False return True