[16] add `plex_watchlist` builder

pull/1024/head
meisnate12 2 years ago
parent 11a325bc20
commit 49580fd543

@ -1 +1 @@
1.17.3-develop15
1.17.3-develop16

@ -7,6 +7,7 @@ No configuration is required for these builders.
| Attribute | Description | Works with Movies | Works with Shows | Works with Playlists and Custom Sort |
|:----------------------------------------------|:-------------------------------------------------------------------------|:-----------------:|:----------------:|:------------------------------------:|
| [`plex_all`](#plex-all) | Gets every movie/show in your library. Useful with [Filters](../filters) | ✅ | ✅ | ❌ |
| [`plex_watchlist`](#plex-watchlist) | Gets every movie/show in your Watchlist. | ✅ | ✅ | ✅ |
| [`plex_pilots`](#plex-pilots) | Gets the first episode of every show in your library | ❌ | ✅ | ✅ |
| [`plex_collectionless`](#plex-collectionless) | Gets every movie/show that is not in a collection | ✅ | ✅ | ❌ |
| [`plex_search`](#plex-search) | Gets every movie/show based on the search parameters provided | ✅ | ✅ | ✅ |
@ -25,6 +26,31 @@ collections:
rating.gte: 9
```
## Plex Watchlist
Finds every item in your Watchlist.
The expected input is the sort you want returned. It defaults to `added.asc`.
### Sort Options
| Sort Option | Description |
|:--------------------------------------------|:--------------------------------------------|
| `title.asc`<br>`title.desc` | Sort by Title |
| `release.asc`<br>`release.desc` | Sort by Release Date (Originally Available) |
| `critic_rating.asc`<br>`critic_rating.desc` | Sort by Critic Rating |
| `added.asc`<br>`added.desc` | Sort by Date Added to your Watchlist |
The `sync_mode: sync` and `collection_order: custom` Details are recommended.
```yaml
collections:
My Watchlist:
plex_watchlist: critic_rating.desc
collection_order: custom
sync_mode: sync
```
## Plex Pilots
Gets the first episode of every show in your library. This only works with `builder_level: episode`

@ -141,7 +141,7 @@ smart_invalid = ["collection_order", "builder_level"]
smart_only = ["collection_filtering"]
smart_url_invalid = ["filters", "run_again", "sync_mode", "show_filtered", "show_missing", "save_report", "smart_label"] + radarr_details + sonarr_details
custom_sort_builders = [
"plex_search", "plex_pilots", "tmdb_list", "tmdb_popular", "tmdb_now_playing", "tmdb_top_rated",
"plex_search", "plex_watchlist", "plex_pilots", "tmdb_list", "tmdb_popular", "tmdb_now_playing", "tmdb_top_rated",
"tmdb_trending_daily", "tmdb_trending_weekly", "tmdb_discover", "reciperr_list", "trakt_chart", "trakt_userlist",
"tvdb_list", "imdb_chart", "imdb_list", "imdb_watchlist", "stevenlu_popular", "anidb_popular", "tmdb_upcoming", "tmdb_airing_today",
"tmdb_on_the_air", "trakt_list", "trakt_watchlist", "trakt_collection", "trakt_trending", "trakt_popular", "trakt_boxoffice",
@ -1275,6 +1275,10 @@ class CollectionBuilder:
def _plex(self, method_name, method_data):
if method_name in ["plex_all", "plex_pilots"]:
self.builders.append((method_name, self.builder_level))
elif method_name == "plex_watchlist":
if method_data not in plex.watchlist_sorts:
logger.warning(f"{self.Type} Warning: Watchlist sort: {method_data} invalid defaulting to added.asc")
self.builders.append((method_name, method_data if method_data in plex.watchlist_sorts else "added.asc"))
elif method_name in ["plex_search", "plex_collectionless"]:
for dict_data in util.parse(self.Type, method_name, method_data, datatype="listdict"):
dict_methods = {dm.lower(): dm for dm in dict_data}
@ -1498,7 +1502,7 @@ class CollectionBuilder:
logger.info(f"Builder: {method} loaded from Cache")
return self.config.Cache.query_list_ids(list_key)
if "plex" in method:
ids = self.library.get_rating_keys(method, value)
ids = self.library.get_rating_keys(method, value, self.playlist)
elif "tautulli" in method:
ids = self.library.Tautulli.get_rating_keys(value, self.playlist)
elif "anidb" in method:

@ -18,7 +18,7 @@ from xml.etree.ElementTree import ParseError
logger = util.logger
builders = ["plex_all", "plex_pilots", "plex_collectionless", "plex_search"]
builders = ["plex_all", "plex_watchlist", "plex_pilots", "plex_collectionless", "plex_search"]
library_types = ["movie", "show", "artist"]
search_translation = {
"episode_title": "episode.title",
@ -410,6 +410,12 @@ sort_types = {
"album": ("title.asc", 9, album_sorts),
"track": ("title.asc", 10, track_sorts)
}
watchlist_sorts = {
"added.asc": "watchlistedAt:asc", "added.desc": "watchlistedAt:desc",
"title.asc": "titleSort:asc", "title.desc": "titleSort:desc",
"release.asc": "originallyAvailableAt:asc", "release.desc": "originallyAvailableAt:desc",
"critic_rating.asc": "rating:asc", "critic_rating.desc": "rating:desc",
}
class Plex(Library):
def __init__(self, config, params):
@ -802,11 +808,70 @@ class Plex(Library):
raise Failed(f"Collection Error: No valid Plex Collections in {collections}")
return valid_collections
def get_rating_keys(self, method, data):
def get_watchlist(self, sort=None, is_playlist=False):
if is_playlist:
libtype = None
elif self.is_movie:
libtype = "movie"
else:
libtype = "show"
watchlist = self.PlexServer.myPlexAccount().watchlist(sort=watchlist_sorts[sort], libtype=libtype)
ids = []
for item in watchlist:
tmdb_id = []
tvdb_id = []
imdb_id = []
if self.config.Cache:
cache_id, _, media_type, _ = self.config.Cache.query_guid_map(item.guid)
if cache_id:
ids.append(("tmdb" if "movie" in media_type else "tvdb", cache_id))
try:
fin = False
for guid_tag in item.guids:
url_parsed = requests.utils.urlparse(guid_tag.id)
if url_parsed.scheme == "tvdb":
if isinstance(item, Show):
ids.append(("tvdb", int(url_parsed.netloc)))
fin = True
elif url_parsed.scheme == "imdb":
imdb_id.append(url_parsed.netloc)
elif url_parsed.scheme == "tmdb":
if isinstance(item, Movie):
ids.append(("tmdb", int(url_parsed.netloc)))
fin = True
tmdb_id.append(int(url_parsed.netloc))
if fin:
break
if fin:
continue
except requests.exceptions.ConnectionError:
continue
if imdb_id and not tmdb_id:
for imdb in imdb_id:
tmdb, tmdb_type = self.config.Convert.imdb_to_tmdb(imdb)
if tmdb:
tmdb_id.append(tmdb)
if tmdb_id and isinstance(item, Show) and not tvdb_id:
for tmdb in tmdb_id:
tvdb = self.config.Convert.tmdb_to_tvdb(tmdb)
if tvdb:
tvdb_id.append(tvdb)
if isinstance(item, Show) and tvdb_id:
ids.extend([("tvdb", t_id) for t_id in tvdb_id])
if isinstance(item, Movie) and tmdb_id:
ids.extend([("tmdb", t_id) for t_id in tmdb_id])
logger.debug("")
logger.debug(f"{len(ids)} Keys Found: {ids}")
return ids
def get_rating_keys(self, method, data, is_playlist=False):
items = []
if method == "plex_all":
logger.info(f"Processing Plex All {data.capitalize()}s")
items = self.get_all(builder_level=data)
elif method == "plex_watchlist":
logger.info(f"Processing Plex Watchlist")
return self.get_watchlist(sort=data, is_playlist=is_playlist)
elif method == "plex_pilots":
logger.info(f"Processing Plex Pilot {data.capitalize()}s")
items = []

@ -761,11 +761,13 @@ def run_playlists(config):
logger.debug("")
logger.debug(f"Builder: {method}: {value}")
logger.info("")
if "plex" in method:
if method == "plex_watchlist":
ids = builder.libraries[0].get_rating_keys(method, value, True)
elif "plex" in method:
ids = []
for pl_library in builder.libraries:
try:
ids.extend(pl_library.get_rating_keys(method, value))
ids.extend(pl_library.get_rating_keys(method, value, True))
except Failed as e:
if builder.validate_builders:
raise

Loading…
Cancel
Save