[34] trakt builder overhaul

pull/811/head
meisnate12 3 years ago
parent 7b7b174e61
commit c5cd72c777

@ -1 +1 @@
1.16.2-develop33 1.16.2-develop34

@ -4,31 +4,14 @@ You can find items using the features of [Trakt.tv](https://trakt.tv/) (Trakt).
[Configuring Trakt](../../config/trakt) in the config is required for any of these builders. [Configuring Trakt](../../config/trakt) in the config is required for any of these builders.
| Attribute | Description | Works with Movies | Works with Shows | Works with Playlists and Custom Sort | | Attribute | Description | Works with Movies | Works with Shows | Works with Playlists and Custom Sort |
|:---------------------------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------------:|:----------------:|:------------------------------------:| |:--------------------------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------------:|:----------------:|:------------------------------------:|
| [`trakt_list`](#trakt-list) | Finds every item in the Trakt List | ✅ | ✅ | ✅ | | [`trakt_list`](#trakt-list) | Finds every movie/show in the Trakt List | ✅ | ✅ | ✅ |
| [`trakt_list_details`](#trakt-list) | Finds every item in the Trakt List and updates the collection summary with the list description | ✅ | ✅ | ✅ | | [`trakt_list_details`](#trakt-list) | Finds every movie/show in the Trakt List and updates the collection summary with the list description | ✅ | ✅ | ✅ |
| [`trakt_watchlist`](#trakt-user-watchlist) | Finds every item in a Users Watchlist | ✅ | ✅ | ✅ | | [`trakt_chart`](#trakt-chart) | Finds the movies/shows in the Trakt Chart | ✅ | ✅ | ✅ |
| [`trakt_collection`](#trakt-user-collection) | Finds every item in a Users Collection | ✅ | ✅ | ✅ | | [`trakt_userlist`](#trakt-userlist) | Finds every movie/show in the Trakt Userlist | ✅ | ✅ | ✅ |
| [`trakt_trending`](#trakt-trending) | Finds the movies/shows in Trakt's Trending [Movies](https://trakt.tv/movies/trending)/[Shows](https://trakt.tv/shows/trending) list | ✅ | ✅ | ✅ | | [`trakt_recommendations`](#trakt-recommendations) | Finds the movies/shows in Trakt's Personal Recommendations for your User [Movies](https://trakt.docs.apiary.io/#reference/recommendations/movies/get-movie-recommendations)/[Shows](https://trakt.docs.apiary.io/#reference/recommendations/shows/get-show-recommendations) | ✅ | ✅ | ✅ |
| [`trakt_popular`](#trakt-popular) | Finds the movies/shows in Trakt's Popular [Movies](https://trakt.tv/movies/popular)/[Shows](https://trakt.tv/shows/popular) list | ✅ | ✅ | ✅ | | [`trakt_boxoffice`](#trakt-box-office) | Finds the 10 movies in Trakt's Top Box Office [Movies](https://trakt.tv/movies/boxoffice) list | ✅ | ❌ | ✅ |
| [`trakt_recommended_personal`](#trakt-recommended) | Finds the movies/shows in Trakt's Personal Recommendations for your User [Movies](https://trakt.docs.apiary.io/#reference/recommendations/movies/get-movie-recommendations)/[Shows](https://trakt.docs.apiary.io/#reference/recommendations/shows/get-show-recommendations) | ✅ | ✅ | ✅ |
| [`trakt_recommended_daily`](#trakt-recommended) | Finds the movies/shows in Trakt's Daily Recommended [Movies](https://trakt.tv/movies/recommended/daily)/[Shows](https://trakt.tv/shows/recommended/daily) list | ✅ | ✅ | ✅ |
| [`trakt_recommended_weekly`](#trakt-recommended) | Finds the movies/shows in Trakt's Weekly Recommended [Movies](https://trakt.tv/movies/recommended/weekly)/[Shows](https://trakt.tv/shows/recommended/weekly) list | ✅ | ✅ | ✅ |
| [`trakt_recommended_monthly`](#trakt-recommended) | Finds the movies/shows in Trakt's Monthly Recommended [Movies](https://trakt.tv/movies/recommended/monthly)/[Shows](https://trakt.tv/shows/recommended/monthly) list | ✅ | ✅ | ✅ |
| [`trakt_recommended_yearly`](#trakt-recommended) | Finds the movies/shows in Trakt's Yearly Recommended [Movies](https://trakt.tv/movies/recommended/yearly)/[Shows](https://trakt.tv/shows/recommended/yearly) list | ✅ | ✅ | ✅ |
| [`trakt_recommended_all`](#trakt-recommended) | Finds the movies/shows in Trakt's All-Time Recommended [Movies](https://trakt.tv/movies/recommended/all)/[Shows](https://trakt.tv/shows/recommended/all) list | ✅ | ✅ | ✅ |
| [`trakt_watched_daily`](#trakt-watched) | Finds the movies/shows in Trakt's Daily Watched [Movies](https://trakt.tv/movies/watched/daily)/[Shows](https://trakt.tv/shows/watched/daily) list | ✅ | ✅ | ✅ |
| [`trakt_watched_weekly`](#trakt-watched) | Finds the movies/shows in Trakt's Weekly Watched [Movies](https://trakt.tv/movies/watched/weekly)/[Shows](https://trakt.tv/shows/watched/weekly) list | ✅ | ✅ | ✅ |
| [`trakt_watched_monthly`](#trakt-watched) | Finds the movies/shows in Trakt's Monthly Watched [Movies](https://trakt.tv/movies/watched/monthly)/[Shows](https://trakt.tv/shows/watched/monthly) list | ✅ | ✅ | ✅ |
| [`trakt_watched_yearly`](#trakt-watched) | Finds the movies/shows in Trakt's Yearly Watched [Movies](https://trakt.tv/movies/watched/yearly)/[Shows](https://trakt.tv/shows/watched/yearly) list | ✅ | ✅ | ✅ |
| [`trakt_watched_all`](#trakt-watched) | Finds the movies/shows in Trakt's All-Time Watched [Movies](https://trakt.tv/movies/watched/all)/[Shows](https://trakt.tv/shows/watched/all) list | ✅ | ✅ | ✅ |
| [`trakt_collected_daily`](#trakt-collected) | Finds the movies/shows in Trakt's Daily Collected [Movies](https://trakt.tv/movies/collected/daily)/[Shows](https://trakt.tv/shows/collected/daily) list | ✅ | ✅ | ✅ |
| [`trakt_collected_weekly`](#trakt-collected) | Finds the movies/shows in Trakt's Weekly Collected [Movies](https://trakt.tv/movies/collected/weekly)/[Shows](https://trakt.tv/shows/collected/weekly) list | ✅ | ✅ | ✅ |
| [`trakt_collected_monthly`](#trakt-collected) | Finds the movies/shows in Trakt's Monthly Collected [Movies](https://trakt.tv/movies/collected/monthly)/[Shows](https://trakt.tv/shows/collected/monthly) list | ✅ | ✅ | ✅ |
| [`trakt_collected_yearly`](#trakt-collected) | Finds the movies/shows in Trakt's Yearly Collected [Movies](https://trakt.tv/movies/collected/yearly)/[Shows](https://trakt.tv/shows/collected/yearly) list | ✅ | ✅ | ✅ |
| [`trakt_collected_all`](#trakt-collected) | Finds the movies/shows in Trakt's All-Time Collected [Movies](https://trakt.tv/movies/collected/all)/[Shows](https://trakt.tv/shows/collected/all) list | ✅ | ✅ | ✅ |
| [`trakt_boxoffice`](#trakt-box-office) | Finds the 10 movies in Trakt's Top Box Office [Movies](https://trakt.tv/movies/boxoffice) list | ✅ | ❌ | ✅ |
## Trakt List ## Trakt List
@ -38,6 +21,8 @@ The expected input is a Trakt List URL. Multiple values are supported only as a
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order. The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
**Trakt Lists cannot be sorted through the API, but the list is always returned to the default list order if you own the list.**
```yaml ```yaml
collections: collections:
Christmas: Christmas:
@ -65,131 +50,92 @@ collections:
sync_mode: sync sync_mode: sync
``` ```
## Trakt User Watchlist ## Trakt Chart
Finds every item in a Users Watchlist. Finds the movies/shows in the Trakt Chart. The options are detailed below.
The expected input is a user's Trakt Username or `me`. Multiple values are supported as either a list or a comma-separated string. The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order. | Attribute | Description & Values |
|:--------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `chart` | **Description:** Which Trakt chart to query<br>**Values:**<table class="clearTable"><tr><td>`trending`</td><td>Trakt's Trending [Movies](https://trakt.tv/movies/trending)/[Shows](https://trakt.tv/shows/trending) list</td></tr><tr><td>`popular`</td><td>Trakt's Popular [Movies](https://trakt.tv/movies/popular)/[Shows](https://trakt.tv/shows/popular) list</td></tr><tr><td>`recommended`</td><td>Trakt's Recommended [Movies](https://trakt.tv/movies/recommended)/[Shows](https://trakt.tv/shows/recommended) list</td></tr><tr><td>`watched`</td><td>Trakt's Watched [Movies](https://trakt.tv/movies/watched)/[Shows](https://trakt.tv/shows/watched) list</td></tr><tr><td>`collected`</td><td>Trakt's Collected [Movies](https://trakt.tv/movies/collected)/[Shows](https://trakt.tv/shows/collected) list</td></tr></table> |
| `time_period` | **Description:** Time Period for the chart. Does not work with `trending` or `popular` chart types.<br>**Default:** `weekly`<br>**Values:** `daily`, `weekly`, `monthly`, `yearly`, or `all` |
| `limit` | **Description:** Don't return more then this number<br>**Default:** `10`<br>**Values:** Number of Items to query. |
```yaml These are the links to the trakt charts that is looked at by time period.
collections:
Trakt Watchlist:
trakt_watchlist: me
collection_order: custom
sync_mode: sync
```
## Trakt User Collection
Finds every item in a Users Collection. | Period | Collected | Recommended | Watched |
|:---------|:-----------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------:|
The expected input is a user's Trakt Username or `me`. Multiple values are supported as either a list or a comma-separated string. | Daily | [Movies](https://trakt.tv/movies/collected/daily)/[Shows](https://trakt.tv/shows/collected/daily) | [Movies](https://trakt.tv/movies/recommended/daily)/[Shows](https://trakt.tv/shows/recommended/daily) | [Movies](https://trakt.tv/movies/watched/daily)/[Shows](https://trakt.tv/shows/watched/daily) |
| Weekly | [Movies](https://trakt.tv/movies/collected/weekly)/[Shows](https://trakt.tv/shows/collected/weekly) | [Movies](https://trakt.tv/movies/recommended/weekly)/[Shows](https://trakt.tv/shows/recommended/weekly) | [Movies](https://trakt.tv/movies/watched/weekly)/[Shows](https://trakt.tv/shows/watched/weekly) |
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order. | Monthly | [Movies](https://trakt.tv/movies/collected/monthly)/[Shows](https://trakt.tv/shows/collected/monthly) | [Movies](https://trakt.tv/movies/recommended/monthly)/[Shows](https://trakt.tv/shows/recommended/monthly) | [Movies](https://trakt.tv/movies/watched/monthly)/[Shows](https://trakt.tv/shows/watched/monthly) |
| Yearly | [Movies](https://trakt.tv/movies/collected/yearly)/[Shows](https://trakt.tv/shows/collected/yearly) | [Movies](https://trakt.tv/movies/recommended/yearly)/[Shows](https://trakt.tv/shows/recommended/yearly) | [Movies](https://trakt.tv/movies/watched/yearly)/[Shows](https://trakt.tv/shows/watched/yearly) |
```yaml | All-Time | [Movies](https://trakt.tv/movies/collected/all)/[Shows](https://trakt.tv/shows/collected/all) | [Movies](https://trakt.tv/movies/recommended/all)/[Shows](https://trakt.tv/shows/recommended/all) | [Movies](https://trakt.tv/movies/watched/all)/[Shows](https://trakt.tv/shows/watched/all) |
collections:
Trakt Collection:
trakt_collection:
- me
- traktbuddy
sync_mode: sync
```
## Trakt Trending
Finds the movies/shows in Trakt's Trending [Movies](https://trakt.tv/movies/trending)/[Shows](https://trakt.tv/shows/trending) list.
The expected input is a single integer value of how many movies/shows to query.
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
```yaml ```yaml
collections: collections:
Trakt Trending: Trakt Trending:
trakt_trending: 30 trakt_chart:
chart: trending
limit: 30
collection_order: custom collection_order: custom
sync_mode: sync sync_mode: sync
``` ```
## Trakt Popular You can use multiple charts in one builder using a list.
Finds the movies/shows in Trakt's Popular [Movies](https://trakt.tv/movies/popular)/[Shows](https://trakt.tv/shows/popular) list.
The expected input is a single integer value of how many movies/shows to query.
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
```yaml ```yaml
collections: collections:
Trakt Popular: Trakt Trending & Popular:
trakt_popular: 30 trakt_chart:
- chart: trending
limit: 30
- chart: popular
limit: 30
collection_order: custom collection_order: custom
sync_mode: sync sync_mode: sync
``` ```
## Trakt Recommended ## Trakt Userlist
Finds the movies/shows in Trakt's Recommended lists. Finds every movie/show in the Trakt Userlist.
| Builder | Period | Movie List | Show List | The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
|:-----------------------------|:--------:|:--------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------:|
| `trakt_recommended_personal` | Custom | [Movies](https://trakt.docs.apiary.io/#reference/recommendations/movies/get-movie-recommendations) | [Shows](https://trakt.docs.apiary.io/#reference/recommendations/shows/get-show-recommendations) |
| `trakt_recommended_daily` | Daily | [Daily Movies](https://trakt.tv/movies/recommended/daily) | [Daily Shows](https://trakt.tv/shows/recommended/daily) |
| `trakt_recommended_weekly` | Weekly | [Weekly Movies](https://trakt.tv/movies/recommended/weekly) | [Weekly Shows](https://trakt.tv/shows/recommended/weekly) |
| `trakt_recommended_monthly` | Monthly | [Monthly Movies](https://trakt.tv/movies/recommended/monthly) | [Monthly Shows](https://trakt.tv/shows/recommended/monthly) |
| `trakt_recommended_yearly` | Yearly | [Yearly Movies](https://trakt.tv/movies/recommended/yearly) | [Yearly Shows](https://trakt.tv/shows/recommended/yearly) |
| `trakt_recommended_all` | All-Time | [All-Time Movies](https://trakt.tv/movies/recommended/all) | [All-Time Shows](https://trakt.tv/shows/recommended/all) |
The expected input is a single integer value of how many movies/shows to query. | Attribute | Description & Values |
|:-----------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order. | `userlist` | **Description:** Which Trakt userlist to query<br>**Values:**<table class="clearTable"><tr><td>`trending`</td><td>Trakt's Trending [Movies](https://trakt.tv/movies/trending)/[Shows](https://trakt.tv/shows/trending) list</td></tr><tr><td>`popular`</td><td>Trakt's Popular [Movies](https://trakt.tv/movies/popular)/[Shows](https://trakt.tv/shows/popular) list</td></tr><tr><td>`recommended`</td><td>Trakt's Recommended [Movies](https://trakt.tv/movies/recommended)/[Shows](https://trakt.tv/shows/recommended) list</td></tr><tr><td>`watched`</td><td>Trakt's Watched [Movies](https://trakt.tv/movies/watched)/[Shows](https://trakt.tv/shows/watched) list</td></tr><tr><td>`collected`</td><td>Trakt's Collected [Movies](https://trakt.tv/movies/collected)/[Shows](https://trakt.tv/shows/collected) list</td></tr></table> |
| `user` | **Description:** The User who's user lists you want to query.<br>**Default:** `me`<br>**Values:** Username of User or `me` for the authenticated user. |
| `sort_by` | **Description:** How to sort the results<br>**Default:** `rank`<br>**Values:** `rank`, `added`, `released`, `title` |
```yaml ```yaml
collections: collections:
Trakt Recommended: Trakt Watchlist:
trakt_recommended_weekly: 30 trakt_userlist:
userlist: watchlist
user: me
sort_by: released
collection_order: custom collection_order: custom
sync_mode: sync sync_mode: sync
``` ```
## Trakt Watched You can use multiple charts in one builder using a list.
Finds the movies/shows in Trakt's Watched lists.
| Builder | Period | Movie List | Show List |
|:------------------------|:--------:|:---------------------------------------------------------:|:-------------------------------------------------------:|
| `trakt_watched_daily` | Daily | [Daily Movies](https://trakt.tv/movies/watched/daily) | [Daily Shows](https://trakt.tv/shows/watched/daily) |
| `trakt_watched_weekly` | Weekly | [Weekly Movies](https://trakt.tv/movies/watched/weekly) | [Weekly Shows](https://trakt.tv/shows/watched/weekly) |
| `trakt_watched_monthly` | Monthly | [Monthly Movies](https://trakt.tv/movies/watched/monthly) | [Monthly Shows](https://trakt.tv/shows/watched/monthly) |
| `trakt_watched_yearly` | Yearly | [Yearly Movies](https://trakt.tv/movies/watched/yearly) | [Yearly Shows](https://trakt.tv/shows/watched/yearly) |
| `trakt_watched_all` | All-Time | [All-Time Movies](https://trakt.tv/movies/watched/all) | [All-Time Shows](https://trakt.tv/shows/watched/all) |
The expected input is a single integer value of how many movies/shows to query.
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
```yaml ```yaml
collections: collections:
Trakt Watched: Trakt Watchlist:
trakt_watched_weekly: 30 trakt_userlist:
- userlist: watched
user: me
- userlist: collected
user: me
collection_order: custom collection_order: custom
sync_mode: sync sync_mode: sync
``` ```
## Trakt Collected ## Trakt Recommendations
Finds the movies/shows in Trakt's Collected [Movies](https://trakt.tv/movies/collected/weekly)/[Shows](https://trakt.tv/shows/collected/weekly) list. Finds the movies/shows in Trakt's Recommendations for [Movies](https://trakt.docs.apiary.io/#reference/recommendations/movies/get-movie-recommendations)/[Shows](https://trakt.docs.apiary.io/#reference/recommendations/shows/get-show-recommendations)
| Builder | Period | Movie List | Show List |
|:--------------------------|:--------:|:-----------------------------------------------------------:|:---------------------------------------------------------:|
| `trakt_collected_daily` | Daily | [Daily Movies](https://trakt.tv/movies/collected/daily) | [Daily Shows](https://trakt.tv/shows/collected/daily) |
| `trakt_collected_weekly` | Weekly | [Weekly Movies](https://trakt.tv/movies/collected/weekly) | [Weekly Shows](https://trakt.tv/shows/collected/weekly) |
| `trakt_collected_monthly` | Monthly | [Monthly Movies](https://trakt.tv/movies/collected/monthly) | [Monthly Shows](https://trakt.tv/shows/collected/monthly) |
| `trakt_collected_yearly` | Yearly | [Yearly Movies](https://trakt.tv/movies/collected/yearly) | [Yearly Shows](https://trakt.tv/shows/collected/yearly) |
| `trakt_collected_all` | All-Time | [All-Time Movies](https://trakt.tv/movies/collected/all) | [All-Time Shows](https://trakt.tv/shows/collected/all) |
The expected input is a single integer value of how many movies/shows to query. The expected input is a single integer value of how many movies/shows to query.
@ -197,8 +143,8 @@ The `sync_mode: sync` and `collection_order: custom` Details are recommended sin
```yaml ```yaml
collections: collections:
Trakt Collected: Trakt Recommendations:
trakt_collected_weekly: 30 trakt_recommendations: 30
collection_order: custom collection_order: custom
sync_mode: sync sync_mode: sync
``` ```

@ -120,7 +120,7 @@ Depending on the `type` of dynamic collection, `data` is used to specify the opt
| [`genre`](#genre) | Create a collection for each genre found in the library | &#10060; | &#9989; | &#9989; | &#9989; | &#9989; | | [`genre`](#genre) | Create a collection for each genre found in the library | &#10060; | &#9989; | &#9989; | &#9989; | &#9989; |
| [`content_rating`](#content-rating) | Create a collection for each content rating found in the library | &#10060; | &#9989; | &#9989; | &#10060; | &#9989; | | [`content_rating`](#content-rating) | Create a collection for each content rating found in the library | &#10060; | &#9989; | &#9989; | &#10060; | &#9989; |
| [`year`](#year) | Create a collection for each year found in the library | &#10060; | &#9989; | &#9989; | &#10060; | &#10060; | | [`year`](#year) | Create a collection for each year found in the library | &#10060; | &#9989; | &#9989; | &#10060; | &#10060; |
| [`decade`](#decade) | Create a collection for each decade found in the library | &#10060; | &#9989; | &#10060; | &#10060; | &#10060; | | [`decade`](#decade) | Create a collection for each decade found in the library | &#10060; | &#9989; | &#9989; | &#10060; | &#10060; |
| [`country`](#country) | Create a collection for each country found in the library | &#10060; | &#9989; | &#10060; | &#9989; | &#9989; | | [`country`](#country) | Create a collection for each country found in the library | &#10060; | &#9989; | &#10060; | &#9989; | &#9989; |
| [`resolution`](#resolution) | Create a collection for each resolution found in the library | &#10060; | &#9989; | &#9989; | &#10060; | &#10060; | | [`resolution`](#resolution) | Create a collection for each resolution found in the library | &#10060; | &#9989; | &#9989; | &#10060; | &#10060; |
| [`subtitle_language`](#subtitle-language) | Create a collection for each subtitle language found in the library | &#10060; | &#9989; | &#9989; | &#10060; | &#10060; | | [`subtitle_language`](#subtitle-language) | Create a collection for each subtitle language found in the library | &#10060; | &#9989; | &#9989; | &#10060; | &#10060; |
@ -1585,7 +1585,6 @@ Defines how multiple `keys` can be combined under a parent key.
For example, the `addons` attribute can be used to combine multiple `keys`, i.e. merging "MTV2", "MTV3" and "MTV (UK)" into the "MTV" collection. For example, the `addons` attribute can be used to combine multiple `keys`, i.e. merging "MTV2", "MTV3" and "MTV (UK)" into the "MTV" collection.
```yaml ```yaml
dynamic_collections: dynamic_collections:
networks: networks:
@ -1597,6 +1596,8 @@ dynamic_collections:
- MTV (UK) - MTV (UK)
``` ```
You can also define custom keys under addons if the main key doesn't exist as a key it will be considered a custom key combining all keys into one key.
## Template ## Template
Name of the template to use for these dynamic collections. Each `type` has its own default template, but if you want to define and use your own template you can. Name of the template to use for these dynamic collections. Each `type` has its own default template, but if you want to define and use your own template you can.

@ -47,6 +47,7 @@ method_alias = {
"trakt_recommended": "trakt_recommended_weekly", "trakt_watched": "trakt_watched_weekly", "trakt_collected": "trakt_collected_weekly", "trakt_recommended": "trakt_recommended_weekly", "trakt_watched": "trakt_watched_weekly", "trakt_collected": "trakt_collected_weekly",
"collection_changes_webhooks": "changes_webhooks", "collection_changes_webhooks": "changes_webhooks",
"radarr_add": "radarr_add_missing", "sonarr_add": "sonarr_add_missing", "radarr_add": "radarr_add_missing", "sonarr_add": "sonarr_add_missing",
"trakt_recommended_personal": "trakt_recommendations"
} }
filter_translation = { filter_translation = {
"record_label": "studio", "record_label": "studio",
@ -745,7 +746,7 @@ class CollectionBuilder:
elif method_name == "tvdb_description": elif method_name == "tvdb_description":
self.summaries[method_name] = self.config.TVDb.get_list_description(method_data) self.summaries[method_name] = self.config.TVDb.get_list_description(method_data)
elif method_name == "trakt_description": elif method_name == "trakt_description":
self.summaries[method_name] = self.config.Trakt.list_description(self.config.Trakt.validate_trakt(method_data, self.library.is_movie)[0]) self.summaries[method_name] = self.config.Trakt.list_description(self.config.Trakt.validate_list(method_data, self.library.is_movie)[0])
elif method_name == "letterboxd_description": elif method_name == "letterboxd_description":
self.summaries[method_name] = self.config.Letterboxd.get_list_description(method_data, self.language) self.summaries[method_name] = self.config.Letterboxd.get_list_description(method_data, self.language)
elif method_name == "icheckmovies_description": elif method_name == "icheckmovies_description":
@ -1068,7 +1069,7 @@ class CollectionBuilder:
else: else:
raise Failed(f"{self.Type} Error: imdb_id {value} must begin with tt") raise Failed(f"{self.Type} Error: imdb_id {value} must begin with tt")
elif method_name == "imdb_list": elif method_name == "imdb_list":
for imdb_dict in self.config.IMDb.validate_imdb_lists(method_data, self.language): for imdb_dict in self.config.IMDb.validate_imdb_lists(self.Type, method_data, self.language):
self.builders.append((method_name, imdb_dict)) self.builders.append((method_name, imdb_dict))
elif method_name == "imdb_chart": elif method_name == "imdb_chart":
for value in util.get_list(method_data): for value in util.get_list(method_data):
@ -1265,21 +1266,37 @@ class CollectionBuilder:
def _trakt(self, method_name, method_data): def _trakt(self, method_name, method_data):
if method_name.startswith("trakt_list"): if method_name.startswith("trakt_list"):
trakt_lists = self.config.Trakt.validate_trakt(method_data, self.library.is_movie) trakt_lists = self.config.Trakt.validate_list(method_data)
for trakt_list in trakt_lists: for trakt_list in trakt_lists:
self.builders.append(("trakt_list", trakt_list)) self.builders.append(("trakt_list", trakt_list))
if method_name.endswith("_details"): if method_name.endswith("_details"):
self.summaries[method_name] = self.config.Trakt.list_description(trakt_lists[0]) self.summaries[method_name] = self.config.Trakt.list_description(trakt_lists[0])
elif method_name in ["trakt_watchlist", "trakt_collection"]:
for trakt_list in self.config.Trakt.validate_trakt(method_data, self.library.is_movie, trakt_type=method_name[6:]):
self.builders.append((method_name, trakt_list))
elif method_name == "trakt_boxoffice": elif method_name == "trakt_boxoffice":
if util.parse(self.Type, method_name, method_data, datatype="bool", default=False): if util.parse(self.Type, method_name, method_data, datatype="bool", default=False):
self.builders.append((method_name, 10)) self.builders.append((method_name, 10))
else: else:
raise Failed(f"{self.Type} Error: {method_name} must be set to true") raise Failed(f"{self.Type} Error: {method_name} must be set to true")
elif method_name == "trakt_recommendations":
self.builders.append((method_name, util.parse(self.Type, method_name, method_data, datatype="int", default=10, maximum=100)))
elif method_name in trakt.builders: elif method_name in trakt.builders:
self.builders.append((method_name, util.parse(self.Type, method_name, method_data, datatype="int", default=10))) if method_name in ["trakt_chart", "trakt_userlist"]:
trakt_dicts = method_data
final_method = method_name
elif method_name in ["trakt_watchlist", "trakt_collection"]:
trakt_dicts = []
for trakt_user in util.get_list(method_data, split=False):
trakt_dicts.append({"userlist": "watchlist" if "trakt_watchlist" else "collected", "user": trakt_user})
final_method = "trakt_userlist"
else:
terms = method_name.split("_")
trakt_dicts = {
"chart": terms[1],
"amount": util.parse(self.Type, method_name, method_data, datatype="int", default=10),
"time_period": terms[2] if len(terms) > 2 else None
}
final_method = "trakt_chart"
for trakt_dict in self.config.Trakt.validate_chart(final_method, trakt_dicts, self.language):
self.builders.append((method_name, trakt_dict))
def _tvdb(self, method_name, method_data): def _tvdb(self, method_name, method_data):
values = util.get_list(method_data) values = util.get_list(method_data)

@ -31,16 +31,16 @@ class IMDb:
def __init__(self, config): def __init__(self, config):
self.config = config self.config = config
def validate_imdb_lists(self, imdb_lists, language): def validate_imdb_lists(self, err_type, imdb_lists, language):
valid_lists = [] valid_lists = []
for imdb_dict in util.get_list(imdb_lists, split=False): for imdb_dict in util.get_list(imdb_lists, split=False):
if not isinstance(imdb_dict, dict): if not isinstance(imdb_dict, dict):
imdb_dict = {"url": imdb_dict} imdb_dict = {"url": imdb_dict}
dict_methods = {dm.lower(): dm for dm in imdb_dict} dict_methods = {dm.lower(): dm for dm in imdb_dict}
if "url" not in dict_methods: if "url" not in dict_methods:
raise Failed(f"Collection Error: imdb_list url attribute not found") raise Failed(f"{err_type} Error: imdb_list url attribute not found")
elif imdb_dict[dict_methods["url"]] is None: elif imdb_dict[dict_methods["url"]] is None:
raise Failed(f"Collection Error: imdb_list url attribute is blank") raise Failed(f"{err_type} Error: imdb_list url attribute is blank")
else: else:
imdb_url = imdb_dict[dict_methods["url"]].strip() imdb_url = imdb_dict[dict_methods["url"]].strip()
if not imdb_url.startswith(tuple([v for k, v in urls.items()])): if not imdb_url.startswith(tuple([v for k, v in urls.items()])):
@ -50,7 +50,7 @@ class IMDb:
list_count = None list_count = None
if "limit" in dict_methods: if "limit" in dict_methods:
if imdb_dict[dict_methods["limit"]] is None: if imdb_dict[dict_methods["limit"]] is None:
logger.warning(f"Collection Warning: imdb_list limit attribute is blank using 0 as default") logger.warning(f"{err_type} Warning: imdb_list limit attribute is blank using 0 as default")
else: else:
try: try:
value = int(str(imdb_dict[dict_methods["limit"]])) value = int(str(imdb_dict[dict_methods["limit"]]))
@ -59,7 +59,7 @@ class IMDb:
except ValueError: except ValueError:
pass pass
if list_count is None: if list_count is None:
logger.warning(f"Collection Warning: imdb_list limit attribute must be an integer 0 or greater using 0 as default") logger.warning(f"{err_type} Warning: imdb_list limit attribute must be an integer 0 or greater using 0 as default")
if list_count is None: if list_count is None:
list_count = 0 list_count = 0
valid_lists.append({"url": imdb_url, "limit": list_count}) valid_lists.append({"url": imdb_url, "limit": list_count})

@ -266,19 +266,14 @@ class MetadataFile(DataFile):
auto_type = dynamic[methods["type"]].lower() auto_type = dynamic[methods["type"]].lower()
og_exclude = util.parse("Config", "exclude", dynamic, parent=map_name, methods=methods, datatype="strlist") if "exclude" in methods else [] og_exclude = util.parse("Config", "exclude", dynamic, parent=map_name, methods=methods, datatype="strlist") if "exclude" in methods else []
include = util.parse("Config", "include", dynamic, parent=map_name, methods=methods, datatype="strlist") if "include" in methods else [] include = util.parse("Config", "include", dynamic, parent=map_name, methods=methods, datatype="strlist") if "include" in methods else []
custom_keys = util.parse("Config", "custom_keys", dynamic, parent=map_name, methods=methods, datatype="dictliststr") if "custom_keys" in methods else {}
if og_exclude and include: if og_exclude and include:
raise Failed(f"Config Error: {map_name} cannot have both include and exclude attributes") raise Failed(f"Config Error: {map_name} cannot have both include and exclude attributes")
addons = util.parse("Config", "addons", dynamic, parent=map_name, methods=methods, datatype="dictliststr") if "addons" in methods else {} addons = util.parse("Config", "addons", dynamic, parent=map_name, methods=methods, datatype="dictliststr") if "addons" in methods else {}
exclude = [str(e) for e in og_exclude] exclude = [str(e) for e in og_exclude]
for custom_key, combined_keys in custom_keys.items():
for combined_key in combined_keys:
if combined_key not in exclude:
exclude.append(combined_key)
for k, v in addons.items(): for k, v in addons.items():
if k in v: if k in v:
logger.warning(f"Config Warning: {k} cannot be an addon for itself") raise Failed(f"Config Warning: {k} cannot be an addon for itself")
exclude.extend([y for y in v if y != k]) exclude.extend([y for y in v if y != k and y not in exclude])
default_title_format = "<<key_name>>" default_title_format = "<<key_name>>"
default_template = None default_template = None
auto_list = {} auto_list = {}
@ -409,9 +404,9 @@ class MetadataFile(DataFile):
elif auto_type == "trakt_user_lists": elif auto_type == "trakt_user_lists":
dynamic_data = util.parse("Config", "data", dynamic, parent=map_name, methods=methods, datatype="list") dynamic_data = util.parse("Config", "data", dynamic, parent=map_name, methods=methods, datatype="list")
for option in dynamic_data: for option in dynamic_data:
_check_dict(self.config.Trakt.get_user_lists(option)) _check_dict(self.config.Trakt.all_user_lists(option))
elif auto_type == "trakt_liked_lists": elif auto_type == "trakt_liked_lists":
_check_dict(self.config.Trakt.get_liked_lists()) _check_dict(self.config.Trakt.all_liked_lists())
elif auto_type == "tmdb_popular_people": elif auto_type == "tmdb_popular_people":
dynamic_data = util.parse("Config", "data", dynamic, parent=map_name, methods=methods, datatype="int", minimum=1) dynamic_data = util.parse("Config", "data", dynamic, parent=map_name, methods=methods, datatype="int", minimum=1)
_check_dict(self.config.TMDb.get_popular_people(dynamic_data)) _check_dict(self.config.TMDb.get_popular_people(dynamic_data))
@ -421,15 +416,16 @@ class MetadataFile(DataFile):
_check_dict(self.config.Trakt.get_people(option)) _check_dict(self.config.Trakt.get_people(option))
else: else:
raise Failed(f"Config Error: {map_name} type attribute {dynamic[methods['type']]} invalid") raise Failed(f"Config Error: {map_name} type attribute {dynamic[methods['type']]} invalid")
for custom_key, combined_keys in custom_keys.items(): for add_key, combined_keys in addons.items():
if custom_key in all_keys: if add_key not in all_keys:
raise Failed(f"Config Error: Custom key: {custom_key} cannot be an actual key") final_keys = [ck for ck in combined_keys if ck in all_keys]
final_keys = [ck for ck in combined_keys if ck in all_keys] if final_keys:
if final_keys: if include:
if include: include.append(add_key)
include.append(custom_key) auto_list[add_key] = add_key
auto_list[custom_key] = custom_key addons[add_key] = final_keys
addons[custom_key] = final_keys else:
logger.warning(f"Config Error: {add_key} Custom Key must have at least one Key")
title_format = default_title_format title_format = default_title_format
if "title_format" in methods: if "title_format" in methods:
title_format = util.parse("Config", "title_format", dynamic, parent=map_name, methods=methods, default=default_title_format) title_format = util.parse("Config", "title_format", dynamic, parent=map_name, methods=methods, default=default_title_format)
@ -466,7 +462,6 @@ class MetadataFile(DataFile):
logger.debug(f"Data: {dynamic_data}") logger.debug(f"Data: {dynamic_data}")
logger.debug(f"Exclude: {exclude}") logger.debug(f"Exclude: {exclude}")
logger.debug(f"Addons: {addons}") logger.debug(f"Addons: {addons}")
logger.debug(f"Custom Keys: {custom_keys}")
logger.debug(f"Template: {template_name}") logger.debug(f"Template: {template_name}")
logger.debug(f"Template Variables: {template_variables}") logger.debug(f"Template Variables: {template_variables}")
logger.debug(f"Remove Prefix: {remove_prefix}") logger.debug(f"Remove Prefix: {remove_prefix}")

@ -8,15 +8,17 @@ logger = util.logger
redirect_uri = "urn:ietf:wg:oauth:2.0:oob" redirect_uri = "urn:ietf:wg:oauth:2.0:oob"
base_url = "https://api.trakt.tv" base_url = "https://api.trakt.tv"
builders = [ builders = [
"trakt_list", "trakt_list_details", "trakt_chart", "trakt_userlist", "trakt_boxoffice", "trakt_recommendations",
"trakt_collected_daily", "trakt_collected_weekly", "trakt_collected_monthly", "trakt_collected_yearly", "trakt_collected_all", "trakt_collected_daily", "trakt_collected_weekly", "trakt_collected_monthly", "trakt_collected_yearly", "trakt_collected_all",
"trakt_recommended_personal", "trakt_recommended_daily", "trakt_recommended_weekly", "trakt_recommended_monthly", "trakt_recommended_yearly", "trakt_recommended_all", "trakt_recommended_daily", "trakt_recommended_weekly", "trakt_recommended_monthly", "trakt_recommended_yearly", "trakt_recommended_all",
"trakt_watched_daily", "trakt_watched_weekly", "trakt_watched_monthly", "trakt_watched_yearly", "trakt_watched_all", "trakt_watched_daily", "trakt_watched_weekly", "trakt_watched_monthly", "trakt_watched_yearly", "trakt_watched_all",
"trakt_collection", "trakt_list", "trakt_list_details", "trakt_popular", "trakt_trending", "trakt_watchlist", "trakt_boxoffice" "trakt_collection", "trakt_popular", "trakt_trending", "trakt_watchlist"
] ]
sorts = [ sorts = [
"rank", "added", "title", "released", "runtime", "popularity", "rank", "added", "title", "released", "runtime", "popularity",
"percentage", "votes", "random", "my_rating", "watched", "collected" "percentage", "votes", "random", "my_rating", "watched", "collected"
] ]
periods = ["daily", "weekly", "monthly", "yearly", "all"]
id_translation = {"movie": "movie", "show": "show", "season": "show", "episode": "show", "person": "person", "list": "list"} id_translation = {"movie": "movie", "show": "show", "season": "show", "episode": "show", "person": "person", "list": "list"}
id_types = { id_types = {
"movie": ("tmdb", "TMDb ID"), "movie": ("tmdb", "TMDb ID"),
@ -194,16 +196,16 @@ class Trakt:
logger.error(f"Trakt Error: No {id_display} found for {name}") logger.error(f"Trakt Error: No {id_display} found for {name}")
return ids return ids
def get_user_lists(self, data): def all_user_lists(self, user):
try: try:
items = self._request(f"/users/{data}/lists") items = self._request(f"/users/{user}/lists")
except Failed: except Failed:
raise Failed(f"Trakt Error: User {data} not found") raise Failed(f"Trakt Error: User {user} not found")
if len(items) == 0: if len(items) == 0:
raise Failed(f"Trakt Error: User {data} has no lists") raise Failed(f"Trakt Error: User {user} has no lists")
return {self.build_user_url(data, i["ids"]["slug"]): i["name"] for i in items} return {self.build_user_url(user, i["ids"]["slug"]): i["name"] for i in items}
def get_liked_lists(self): def all_liked_lists(self):
items = self._request(f"/users/likes/lists") items = self._request(f"/users/likes/lists")
if len(items) == 0: if len(items) == 0:
raise Failed(f"Trakt Error: No Liked lists found") raise Failed(f"Trakt Error: No Liked lists found")
@ -212,7 +214,7 @@ class Trakt:
def build_user_url(self, user, name): def build_user_url(self, user, name):
return f"{base_url.replace('api.', '')}/users/{user}/lists/{name}" return f"{base_url.replace('api.', '')}/users/{user}/lists/{name}"
def _user_list(self, data): def _list(self, data):
try: try:
items = self._request(f"{requests.utils.urlparse(data).path}/items") items = self._request(f"{requests.utils.urlparse(data).path}/items")
except Failed: except Failed:
@ -221,70 +223,94 @@ class Trakt:
raise Failed(f"Trakt Error: List {data} is empty") raise Failed(f"Trakt Error: List {data} is empty")
return self._parse(items) return self._parse(items)
def _user_items(self, list_type, data, is_movie): def _userlist(self, list_type, user, is_movie, sort_by=None):
try: try:
items = self._request(f"/users/{data}/{list_type}/{'movies' if is_movie else 'shows'}") url_end = "movies" if is_movie else "shows"
if sort_by:
url_end = f"{url_end}/{sort_by}"
items = self._request(f"/users/{user}/{list_type}/{url_end}")
except Failed: except Failed:
raise Failed(f"Trakt Error: User {data} not found") raise Failed(f"Trakt Error: User {user} not found")
if len(items) == 0: if len(items) == 0:
raise Failed(f"Trakt Error: {data}'s {list_type.capitalize()} is empty") raise Failed(f"Trakt Error: {user}'s {list_type.capitalize()} is empty")
return self._parse(items, item_type="movie" if is_movie else "show") return self._parse(items, item_type="movie" if is_movie else "show")
def _user_recommendations(self, amount, is_movie): def _recommendations(self, limit, is_movie):
media_type = "Movie" if is_movie else "Show" media_type = "Movie" if is_movie else "Show"
try: try:
items = self._request(f"/recommendations/{'movies' if is_movie else 'shows'}/?limit={amount}") items = self._request(f"/recommendations/{'movies' if is_movie else 'shows'}/?limit={limit}")
except Failed: except Failed:
raise Failed(f"Trakt Error: failed to fetch {media_type} Recommendations") raise Failed(f"Trakt Error: failed to fetch {media_type} Recommendations")
if len(items) == 0: if len(items) == 0:
raise Failed(f"Trakt Error: no {media_type} Recommendations were found") raise Failed(f"Trakt Error: no {media_type} Recommendations were found")
return self._parse(items, typeless=True, item_type="movie" if is_movie else "show") return self._parse(items, typeless=True, item_type="movie" if is_movie else "show")
def _pagenation(self, pagenation, amount, is_movie): def _charts(self, chart_type, limit, is_movie, time_period=None):
items = self._request(f"/{'movies' if is_movie else 'shows'}/{pagenation}?limit={amount}") chart_url = f"{chart_type}/{time_period}" if time_period else chart_type
return self._parse(items, typeless=pagenation == "popular", item_type="movie" if is_movie else "show") items = self._request(f"/{'movies' if is_movie else 'shows'}/{chart_url}?limit={limit}")
return self._parse(items, typeless=chart_type == "popular", item_type="movie" if is_movie else "show")
def get_people(self, data): def get_people(self, data):
return {str(i[0][0]): i[0][1] for i in self._user_list(data) if i[1] == "tmdb_person"} return {str(i[0][0]): i[0][1] for i in self._list(data) if i[1] == "tmdb_person"}
def validate_trakt(self, trakt_lists, is_movie, trakt_type="list"): def validate_list(self, trakt_lists):
values = util.get_list(trakt_lists, split=False) values = util.get_list(trakt_lists, split=False)
trakt_values = [] trakt_values = []
for value in values: for value in values:
if isinstance(value, dict): if isinstance(value, dict):
raise Failed("Trakt Error: List cannot be a dictionary") raise Failed("Trakt Error: List cannot be a dictionary")
try: try:
if trakt_type == "list": self._list(value)
self._user_list(value)
else:
self._user_items(trakt_type, value, is_movie)
trakt_values.append(value) trakt_values.append(value)
except Failed as e: except Failed as e:
logger.error(e) logger.error(e)
if len(trakt_values) == 0: if len(trakt_values) == 0:
if trakt_type == "watchlist": raise Failed(f"Trakt Error: No valid Trakt Lists in {values}")
raise Failed(f"Trakt Error: No valid Trakt Watchlists in {values}")
elif trakt_type == "collection":
raise Failed(f"Trakt Error: No valid Trakt Collections in {values}")
else:
raise Failed(f"Trakt Error: No valid Trakt Lists in {values}")
return trakt_values return trakt_values
def validate_chart(self, method_name, err_type, data, is_movie):
valid_dicts = []
for trakt_dict in util.get_list(data, split=False):
if not isinstance(trakt_dict, dict):
raise Failed(f"{err_type} Error: {method_name} must be a dictionary")
dict_methods = {dm.lower(): dm for dm in trakt_dict}
try:
if method_name == "trakt_chart":
chart = util.parse(err_type, "chart", trakt_dict, methods=dict_methods, parent=method_name, options=["recommended", "watched", "collected", "trending", "popular"])
limit = util.parse(err_type, "limit", trakt_dict, methods=dict_methods, parent=method_name, datatype="int", default=10)
time_period = None
if chart in ["recommended", "watched", "collected"] and "time_period" in dict_methods:
time_period = util.parse(err_type, "time_period", trakt_dict, methods=dict_methods, parent=method_name, default="weekly", options=periods)
valid_dicts.append({"chart": chart, "limit": limit, "time_period": time_period})
else:
userlist = util.parse(err_type, "userlist", trakt_dict, methods=dict_methods, parent=method_name, options=["recommended", "watched", "collected", "watchlist"])
user = util.parse(err_type, "user", trakt_dict, methods=dict_methods, parent=method_name, default="me")
sort_by = None
if userlist in ["recommended", "watchlist"] and "sort" in dict_methods:
sort_by = util.parse(err_type, "sort_by", trakt_dict, methods=dict_methods, parent=method_name, default="rank", options=["rank", "added", "released", "title"])
self._userlist("collection" if userlist == "collected" else userlist, user, is_movie, sort_by=sort_by)
valid_dicts.append({"userlist": userlist, "user": user, "sort_by": sort_by})
except Failed as e:
logger.error(e)
if len(valid_dicts) == 0:
raise Failed(f"Trakt Error: No valid Trakt {method_name[6:].capitalize()}")
return valid_dicts
def get_trakt_ids(self, method, data, is_movie): def get_trakt_ids(self, method, data, is_movie):
pretty = method.replace("_", " ").title() pretty = method.replace("_", " ").title()
media_type = "Movie" if is_movie else "Show" media_type = "Movie" if is_movie else "Show"
if method in ["trakt_collection", "trakt_watchlist"]: if method == "trakt_list":
logger.info(f"Processing {pretty} {media_type}s for {data}")
return self._user_items(method[6:], data, is_movie)
elif method == "trakt_list":
logger.info(f"Processing {pretty}: {data}") logger.info(f"Processing {pretty}: {data}")
return self._user_list(data) return self._list(data)
elif method == "trakt_recommended_personal": elif method == "trakt_recommendations":
logger.info(f"Processing {pretty}: {data} {media_type}{'' if data == 1 else 's'}")
return self._user_recommendations(data, is_movie)
elif method in builders:
logger.info(f"Processing {pretty}: {data} {media_type}{'' if data == 1 else 's'}") logger.info(f"Processing {pretty}: {data} {media_type}{'' if data == 1 else 's'}")
terms = method.split("_") return self._recommendations(data, is_movie)
return self._pagenation(f"{terms[1]}{f'/{terms[2]}' if len(terms) > 2 else ''}", data, is_movie) elif method == "trakt_chart":
chart_title = data["chart"] if data["time_period"] else f"{data['chart']} {data['time_period'].capitalize()}"
logger.info(f"Processing {pretty}: {chart_title} {data['chart'].capitalize()} {media_type}{'' if data == 1 else 's'}")
return self._charts(data["chart"], data["limit"], is_movie, time_period=data["time_period"])
elif method == "trakt_userlist":
logger.info(f"Processing {pretty} {media_type}s from {data['user']}'s {data['userlist'].capitalize()}")
return self._userlist(data["userlist"], data["user"], is_movie, sort_by=data["sort_by"])
else: else:
raise Failed(f"Trakt Error: Method {method} not supported") raise Failed(f"Trakt Error: Method {method} not supported")

Loading…
Cancel
Save