[57] #784 add radarr_taglist, sonarr_taglist, radarr_all, and sonarr_all

pull/858/head
meisnate12 3 years ago
parent 82f6cad5f7
commit f1918c02f4

@ -1 +1 @@
1.16.5-develop56 1.16.5-develop57

@ -0,0 +1,40 @@
# Radarr Builders
You can find items in your Plex using the features of [Radarr](https://radarr.video/).
[Configuring Radarr](../../config/radarr) in the config is required for any of these builders.
| Attribute | Description | Works with Movies | Works with Shows | Works with Playlists and Custom Sort |
|:------------------------------------|:---------------------------------------------|:-----------------:|:----------------:|:------------------------------------:|
| [`radarr_all`](#radarr-all) | Gets all Movies in Radarr. | ✅ | ❌ | ❌ |
| [`radarr_taglist`](#radarr-taglist) | Gets Movies from Radarr based on their tags. | ✅ | ❌ | ❌ |
## Radarr All
Gets all Movies in Radarr.
```yaml
collections:
ALL Radarr Movies:
radarr_all: true
```
## Radarr Taglist
Gets Movies from Radarr based on their tags.
Set the attribute to the tag you want to search for. Multiple values are supported as either a list or a comma-separated string.
```yaml
collections:
Radarr Movies Without Tags:
radarr_taglist: action, drama
```
If no tag is specified then it gets every Movie without a tag.
```yaml
collections:
Radarr Movies Without Tags:
radarr_taglist:
```

@ -0,0 +1,40 @@
# Sonarr Builders
You can find items in your Plex using the features of [Sonarr](https://sonarr.tv/).
[Configuring Sonarr](../../config/sonarr) in the config is required for any of these builders.
| Attribute | Description | Works with Movies | Works with Shows | Works with Playlists and Custom Sort |
|:------------------------------------|:---------------------------------------------|:-----------------:|:----------------:|:------------------------------------:|
| [`sonarr_all`](#sonarr-all) | Gets all Series in Sonarr. | ❌ | ✅ | ❌ |
| [`sonarr_taglist`](#sonarr-taglist) | Gets Series from Sonarr based on their tags. | ❌ | ✅ | ❌ |
## Sonarr All
Gets all Series in Sonarr.
```yaml
collections:
ALL Sonarr Series:
sonarr_all: true
```
## Sonarr Taglist
Gets Series from Sonarr based on their tags.
Set the attribute to the tag you want to search for. Multiple values are supported as either a list or a comma-separated string.
```yaml
collections:
Sonarr Series Without Tags:
sonarr_taglist: action, drama
```
If no tag is specified then it gets every Movie without a tag.
```yaml
collections:
Sonarr Series Without Tags:
sonarr_taglist:
```

@ -13,15 +13,15 @@ advance_new_agent = ["item_metadata_language", "item_use_original_title"]
advance_show = ["item_episode_sorting", "item_keep_episodes", "item_delete_episodes", "item_season_display", "item_episode_sorting"] advance_show = ["item_episode_sorting", "item_keep_episodes", "item_delete_episodes", "item_season_display", "item_episode_sorting"]
all_builders = anidb.builders + anilist.builders + flixpatrol.builders + icheckmovies.builders + imdb.builders + \ all_builders = anidb.builders + anilist.builders + flixpatrol.builders + icheckmovies.builders + imdb.builders + \
letterboxd.builders + mal.builders + plex.builders + reciperr.builders + tautulli.builders + \ letterboxd.builders + mal.builders + plex.builders + reciperr.builders + tautulli.builders + \
tmdb.builders + trakt.builders + tvdb.builders + mdblist.builders tmdb.builders + trakt.builders + tvdb.builders + mdblist.builders + radarr.builders + sonarr.builders
show_only_builders = [ show_only_builders = [
"tmdb_network", "tmdb_show", "tmdb_show_details", "tvdb_show", "tvdb_show_details", "tmdb_airing_today", "tmdb_network", "tmdb_show", "tmdb_show_details", "tvdb_show", "tvdb_show_details", "tmdb_airing_today",
"tmdb_on_the_air", "collection_level", "item_tmdb_season_titles" "tmdb_on_the_air", "collection_level", "item_tmdb_season_titles", "sonarr_all", "sonarr_taglist"
] ]
movie_only_builders = [ movie_only_builders = [
"letterboxd_list", "letterboxd_list_details", "icheckmovies_list", "icheckmovies_list_details", "stevenlu_popular", "letterboxd_list", "letterboxd_list_details", "icheckmovies_list", "icheckmovies_list_details", "stevenlu_popular",
"tmdb_collection", "tmdb_collection_details", "tmdb_movie", "tmdb_movie_details", "tmdb_now_playing", "tmdb_collection", "tmdb_collection_details", "tmdb_movie", "tmdb_movie_details", "tmdb_now_playing",
"tvdb_movie", "tvdb_movie_details", "tmdb_upcoming", "trakt_boxoffice", "reciperr_list" "tvdb_movie", "tvdb_movie_details", "tmdb_upcoming", "trakt_boxoffice", "reciperr_list", "radarr_all", "radarr_taglist"
] ]
music_only_builders = ["item_album_sorting"] music_only_builders = ["item_album_sorting"]
summary_details = [ summary_details = [
@ -50,7 +50,7 @@ collectionless_details = ["collection_order", "plex_collectionless", "label", "l
item_false_details = ["item_lock_background", "item_lock_poster", "item_lock_title"] item_false_details = ["item_lock_background", "item_lock_poster", "item_lock_title"]
item_bool_details = ["item_tmdb_season_titles", "revert_overlay", "item_refresh"] + item_false_details item_bool_details = ["item_tmdb_season_titles", "revert_overlay", "item_refresh"] + item_false_details
item_details = ["non_item_remove_label", "item_label", "item_radarr_tag", "item_sonarr_tag", "item_overlay", "item_refresh_delay"] + item_bool_details + list(plex.item_advance_keys.keys()) item_details = ["non_item_remove_label", "item_label", "item_radarr_tag", "item_sonarr_tag", "item_overlay", "item_refresh_delay"] + item_bool_details + list(plex.item_advance_keys.keys())
none_details = ["label.sync", "item_label.sync"] none_details = ["label.sync", "item_label.sync", "radarr_taglist", "sonarr_taglist"]
radarr_details = [ radarr_details = [
"radarr_add_missing", "radarr_add_existing", "radarr_upgrade_existing", "radarr_folder", "radarr_monitor", "radarr_add_missing", "radarr_add_existing", "radarr_upgrade_existing", "radarr_folder", "radarr_monitor",
"radarr_search", "radarr_availability", "radarr_quality", "radarr_tag", "item_radarr_tag" "radarr_search", "radarr_availability", "radarr_quality", "radarr_tag", "item_radarr_tag"
@ -718,9 +718,9 @@ class CollectionBuilder:
self._details(method_name, method_data, method_final, methods) self._details(method_name, method_data, method_final, methods)
elif method_name in item_details: elif method_name in item_details:
self._item_details(method_name, method_data, method_mod, method_final, methods) self._item_details(method_name, method_data, method_mod, method_final, methods)
elif method_name in radarr_details: elif method_name in radarr_details or method_name in radarr.builders:
self._radarr(method_name, method_data) self._radarr(method_name, method_data)
elif method_name in sonarr_details: elif method_name in sonarr_details or method_name in sonarr.builders:
self._sonarr(method_name, method_data) self._sonarr(method_name, method_data)
elif method_name in anidb.builders: elif method_name in anidb.builders:
self._anidb(method_name, method_data) self._anidb(method_name, method_data)
@ -1018,6 +1018,10 @@ class CollectionBuilder:
self.radarr_details["quality"] = method_data self.radarr_details["quality"] = method_data
elif method_name == "radarr_tag": elif method_name == "radarr_tag":
self.radarr_details["tag"] = util.get_list(method_data, lower=True) self.radarr_details["tag"] = util.get_list(method_data, lower=True)
elif method_name == "radarr_taglist":
self.builders.append((method_name, util.get_list(method_data, lower=True)))
elif method_name == "radarr_all":
self.builders.append((method_name, True))
def _sonarr(self, method_name, method_data): def _sonarr(self, method_name, method_data):
if method_name in ["sonarr_add_missing", "sonarr_add_existing", "sonarr_upgrade_existing", "sonarr_season", "sonarr_search", "sonarr_cutoff_search"]: if method_name in ["sonarr_add_missing", "sonarr_add_existing", "sonarr_upgrade_existing", "sonarr_season", "sonarr_search", "sonarr_cutoff_search"]:
@ -1036,6 +1040,10 @@ class CollectionBuilder:
raise Failed(f"{self.Type} Error: {method_name} attribute must be either standard, daily, or anime") raise Failed(f"{self.Type} Error: {method_name} attribute must be either standard, daily, or anime")
elif method_name == "sonarr_tag": elif method_name == "sonarr_tag":
self.sonarr_details["tag"] = util.get_list(method_data, lower=True) self.sonarr_details["tag"] = util.get_list(method_data, lower=True)
elif method_name == "sonarr_taglist":
self.builders.append((method_name, util.get_list(method_data, lower=True)))
elif method_name == "sonarr_all":
self.builders.append((method_name, True))
def _anidb(self, method_name, method_data): def _anidb(self, method_name, method_data):
if method_name == "anidb_popular": if method_name == "anidb_popular":
@ -1452,7 +1460,7 @@ class CollectionBuilder:
if "plex" in method: if "plex" in method:
ids = self.library.get_rating_keys(method, value) ids = self.library.get_rating_keys(method, value)
elif "tautulli" in method: elif "tautulli" in method:
ids = self.library.Tautulli.get_rating_keys(self.library, value, self.playlist) ids = self.library.Tautulli.get_rating_keys(value, self.playlist)
elif "anidb" in method: elif "anidb" in method:
anidb_ids = self.config.AniDB.get_anidb_ids(method, value) anidb_ids = self.config.AniDB.get_anidb_ids(method, value)
ids = self.config.Convert.anidb_to_ids(anidb_ids, self.library) ids = self.config.Convert.anidb_to_ids(anidb_ids, self.library)
@ -1480,6 +1488,10 @@ class CollectionBuilder:
ids = self.config.TMDb.get_tmdb_ids(method, value, self.library.is_movie, self.tmdb_region) ids = self.config.TMDb.get_tmdb_ids(method, value, self.library.is_movie, self.tmdb_region)
elif "trakt" in method: elif "trakt" in method:
ids = self.config.Trakt.get_trakt_ids(method, value, self.library.is_movie) ids = self.config.Trakt.get_trakt_ids(method, value, self.library.is_movie)
elif "radarr" in method:
ids = self.library.Radarr.get_tmdb_ids(method, value)
elif "sonarr" in method:
ids = self.library.Sonarr.get_tvdb_ids(method, value)
else: else:
ids = [] ids = []
logger.error(f"{self.Type} Error: {method} method not supported") logger.error(f"{self.Type} Error: {method} method not supported")

@ -138,7 +138,8 @@ class DataFile:
variables["playlist_name"] = str(name) variables["playlist_name"] = str(name)
if self.data_type == "Overlay" and "overlay_name" not in variables: if self.data_type == "Overlay" and "overlay_name" not in variables:
variables["overlay_name"] = str(name) variables["overlay_name"] = str(name)
variables["library_type"] = self.library.type.lower()
variables["library_type"] = self.library.type.lower() if self.library else "items"
template_name = variables["name"] template_name = variables["name"]
template, temp_vars = self.templates[template_name] template, temp_vars = self.templates[template_name]

@ -5,6 +5,7 @@ from arrapi.exceptions import ArrException
logger = util.logger logger = util.logger
builders = ["radarr_all", "radarr_taglist"]
availability_translation = {"announced": "announced", "cinemas": "inCinemas", "released": "released", "db": "preDB"} availability_translation = {"announced": "announced", "cinemas": "inCinemas", "released": "released", "db": "preDB"}
apply_tags_translation = {"": "add", "sync": "replace", "remove": "remove"} apply_tags_translation = {"": "add", "sync": "replace", "remove": "remove"}
availability_descriptions = {"announced": "For Announced", "cinemas": "For In Cinemas", "released": "For Released", "db": "For PreDB"} availability_descriptions = {"announced": "For Announced", "cinemas": "For In Cinemas", "released": "For Released", "db": "For PreDB"}
@ -217,3 +218,21 @@ class Radarr:
remove_items.append(movie) remove_items.append(movie)
if remove_items: if remove_items:
self.api.delete_multiple_movies(remove_items) self.api.delete_multiple_movies(remove_items)
def get_tmdb_ids(self, method, data):
ids = []
for movie in self.api.all_movies():
append = False
if method == "radarr_all":
append = True
elif method == "radarr_taglist":
if data:
for tag in movie.tags:
if tag.label.lower() in data:
append = True
break
elif not movie.tags:
append = True
if append:
ids.append((movie.tmdbId, "tmdb"))
return ids

@ -5,6 +5,7 @@ from arrapi.exceptions import ArrException
logger = util.logger logger = util.logger
builders = ["sonarr_all", "sonarr_taglist"]
series_types = ["standard", "daily", "anime"] series_types = ["standard", "daily", "anime"]
monitor_translation = { monitor_translation = {
"all": "all", "future": "future", "missing": "missing", "existing": "existing", "all": "all", "future": "future", "missing": "missing", "existing": "existing",
@ -243,3 +244,21 @@ class Sonarr:
remove_items.append(series) remove_items.append(series)
if remove_items: if remove_items:
self.api.delete_multiple_series(remove_items) self.api.delete_multiple_series(remove_items)
def get_tvdb_ids(self, method, data):
ids = []
for series in self.api.all_series():
append = False
if method == "sonarr_all":
append = True
elif method == "sonarr_taglist":
if data:
for tag in series.tags:
if tag.label.lower() in data:
append = True
break
elif not series.tags:
append = True
if append:
ids.append((series.tvdbId, "tvdb"))
return ids

@ -23,11 +23,11 @@ class Tautulli:
if response["response"]["result"] != "success": if response["response"]["result"] != "success":
raise Failed(f"Tautulli Error: {response['response']['message']}") raise Failed(f"Tautulli Error: {response['response']['message']}")
def get_rating_keys(self, library, params, all_items): def get_rating_keys(self, params, all_items):
query_size = int(params["list_size"]) + int(params["list_buffer"]) query_size = int(params["list_size"]) + int(params["list_buffer"])
logger.info(f"Processing Tautulli Most {params['list_type'].capitalize()}: {params['list_size']} {'Movies' if library.is_movie else 'Shows'}") logger.info(f"Processing Tautulli Most {params['list_type'].capitalize()}: {params['list_size']} {'Movies' if self.library.is_movie else 'Shows'}")
response = self._request(f"{self.url}/api/v2?apikey={self.apikey}&cmd=get_home_stats&time_range={params['list_days']}&stats_count={query_size}") response = self._request(f"{self.url}/api/v2?apikey={self.apikey}&cmd=get_home_stats&time_range={params['list_days']}&stats_count={query_size}")
stat_id = f"{'popular' if params['list_type'] == 'popular' else 'top'}_{'movies' if library.is_movie else 'tv'}" stat_id = f"{'popular' if params['list_type'] == 'popular' else 'top'}_{'movies' if self.library.is_movie else 'tv'}"
stat_type = "users_watched" if params['list_type'] == 'popular' else "total_plays" stat_type = "users_watched" if params['list_type'] == 'popular' else "total_plays"
items = None items = None
@ -38,19 +38,19 @@ class Tautulli:
if items is None: if items is None:
raise Failed("Tautulli Error: No Items found in the response") raise Failed("Tautulli Error: No Items found in the response")
section_id = library.Plex.key section_id = self.library.Plex.key
rating_keys = [] rating_keys = []
for item in items: for item in items:
if (all_items or item["section_id"] == section_id) and len(rating_keys) < int(params['list_size']): if (all_items or item["section_id"] == section_id) and len(rating_keys) < int(params['list_size']):
if int(item[stat_type]) < params['list_minimum']: if int(item[stat_type]) < params['list_minimum']:
continue continue
try: try:
plex_item = library.fetchItem(int(item["rating_key"])) plex_item = self.library.fetchItem(int(item["rating_key"]))
if not isinstance(plex_item, (Movie, Show)): if not isinstance(plex_item, (Movie, Show)):
raise BadRequest raise BadRequest
rating_keys.append((item["rating_key"], "ratingKey")) rating_keys.append((item["rating_key"], "ratingKey"))
except (BadRequest, NotFound): except (BadRequest, NotFound):
new_item = library.exact_search(item["title"], year=item["year"]) new_item = self.library.exact_search(item["title"], year=item["year"])
if new_item: if new_item:
rating_keys.append((new_item[0].ratingKey, "ratingKey")) rating_keys.append((new_item[0].ratingKey, "ratingKey"))
else: else:

@ -664,7 +664,7 @@ def run_playlists(config):
elif "tautulli" in method: elif "tautulli" in method:
ids = [] ids = []
for pl_library in builder.libraries: for pl_library in builder.libraries:
ids.extend(pl_library.Tautulli.get_rating_keys(pl_library, value, True)) ids.extend(pl_library.Tautulli.get_rating_keys(value, True))
else: else:
ids = builder.gather_ids(method, value) ids = builder.gather_ids(method, value)

Loading…
Cancel
Save