diff --git a/VERSION b/VERSION index f83516f7..b5931c05 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.19.1-develop27 +1.19.1-develop28 diff --git a/docs/builders/anilist.md b/docs/builders/anilist.md index 334c5ef5..e3ca3694 100644 --- a/docs/builders/anilist.md +++ b/docs/builders/anilist.md @@ -107,11 +107,17 @@ Both `username` and `list_name` are required. The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order. -| Attribute | Description | -|:------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `username` | **Description:** A user's AniList Username | -| `list_name` | **Description:** A user's AniList List Name | -| `sort_by` | **Description:** Sort Order to return
**Default:** `score`
**Values:**
`score`Sort by User Score
`popularity`Sort by Popularity
`status`Sort by Status
`progress`Sort by Progress
`last_updated`Sort by Last Updated
`last_added`Sort by Last Added
`start_date`Sort by Start Date
`completed_date`Sort by Completed Date
| +| Attribute | Description | +|:------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `username` | **Description:** A user's AniList Username | +| `list_name` | **Description:** A user's AniList List Name | +| `score.gt`1 | **Description:** Only return items that have a score greater then the given number.
**Values:** `0.0`-`10.0` | +| `score.gte`1 | **Description:** Only return items that have a score greater then or equal to the given number.
**Values:** `0.0`-`10.0` | +| `score.lt`1 | **Description:** Only return items that have a score less then the given number.
**Values:** `0.0`-`10.0` | +| `score.lte`1 | **Description:** Only return items that have a score less then or equal to the given number.
**Values:** `0.0`-`10.0` | +| `sort_by` | **Description:** Sort Order to return
**Default:** `score`
**Values:**
`score`Sort by User Score
`popularity`Sort by Popularity
`status`Sort by Status
`progress`Sort by Progress
`last_updated`Sort by Last Updated
`last_added`Sort by Last Added
`start_date`Sort by Start Date
`completed_date`Sort by Completed Date
| + +1 You can use multiple score filters but the number will have to match every filter. All unrated items are considered to have a 0 rating. ```yaml collections: diff --git a/docs/builders/plex.md b/docs/builders/plex.md index ee7948cb..99c60b06 100644 --- a/docs/builders/plex.md +++ b/docs/builders/plex.md @@ -4,13 +4,13 @@ This builder finds its items by using the features of Plex. 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.md) | ✅ | ✅ | ❌ | -| [`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.md) | Gets every movie/show that is not in a collection | ✅ | ✅ | ❌ | -| [`plex_search`](#plex-search) | Gets every movie/show based on the search parameters provided | ✅ | ✅ | ✅ | +| 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.md) | ✅ | ✅ | ❌ | +| [`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 | ✅ | ✅ | ✅ | ## Plex All diff --git a/docs/stylesheets/branch.js b/docs/stylesheets/branch.js index fb03ce69..4d745976 100644 --- a/docs/stylesheets/branch.js +++ b/docs/stylesheets/branch.js @@ -6,8 +6,8 @@ function checkURLForBranch() { if (currentURL.indexOf("nightly") !== -1) { // If "config" is found in the URL, change the CSS of .md-header to red - document.querySelector(".md-header").style.backgroundColor = "#ef5552"; - document.querySelector(".md-tabs").style.backgroundColor = "#ef5552"; + document.querySelector(".md-header").style.backgroundColor = "#262dbd"; + document.querySelector(".md-tabs").style.backgroundColor = "#262dbd"; // Change the text of const ellipsisSpan = document.querySelector(".md-ellipsis"); diff --git a/modules/anilist.py b/modules/anilist.py index 01189f39..58557a39 100644 --- a/modules/anilist.py +++ b/modules/anilist.py @@ -221,13 +221,14 @@ class AniList: return anilist_ids, ignore_ids, name - def _userlist(self, username, list_name, sort_by): + def _userlist(self, username, list_name, sort_by, score): query = """ query ($user: String, $sort: [MediaListSort]) { MediaListCollection (userName: $user, sort: $sort, type: ANIME) { lists { name entries { + score(format: POINT_10) media{id} } } @@ -237,7 +238,7 @@ class AniList: variables = {"user": username, "sort": userlist_sort_options[sort_by]} for alist in self._request(query, variables)["data"]["MediaListCollection"]["lists"]: if alist["name"] == list_name: - return [m["media"]["id"] for m in alist["entries"]] + return [m["media"]["id"] for m in alist["entries"] if not score or not any([util.is_number_filter(value, mod, m["score"]) for mod, value in score.items()])] return [] def validate_userlist(self, data): @@ -293,7 +294,7 @@ class AniList: anilist_ids, _, name = self._relations(data) logger.info(f"Processing AniList Relations: ({data}) {name} ({len(anilist_ids)} Anime)") elif method == "anilist_userlist": - anilist_ids = self._userlist(data["username"], data["list_name"], data["sort_by"]) + anilist_ids = self._userlist(data["username"], data["list_name"], data["sort_by"], data["score"]) logger.info(f"Processing AniList Userlist: {data['list_name']} from {data['username']} sorted by {pretty_user[data['sort_by']]}") else: if method == "anilist_popular": diff --git a/modules/builder.py b/modules/builder.py index 3c4e0eeb..f244f27c 100644 --- a/modules/builder.py +++ b/modules/builder.py @@ -1393,11 +1393,22 @@ class CollectionBuilder: elif method_name == "anilist_userlist": for dict_data in util.parse(self.Type, method_name, method_data, datatype="listdict"): dict_methods = {dm.lower(): dm for dm in dict_data} - self.builders.append((method_name, self.config.AniList.validate_userlist({ + new_dictionary = { "username": util.parse(self.Type, "username", dict_data, methods=dict_methods, parent=method_name), "list_name": util.parse(self.Type, "list_name", dict_data, methods=dict_methods, parent=method_name), "sort_by": util.parse(self.Type, "sort_by", dict_data, methods=dict_methods, parent=method_name, default="score", options=anilist.userlist_sort_options), - }))) + } + score_dict = {} + for search_method, search_data in dict_data.items(): + search_attr, modifier = os.path.splitext(str(search_method).lower()) + if search_attr == "score" and modifier in ["gt", "gte", "lt", "lte"]: + score = util.parse(self.Type, search_method, dict_data, datatype="int", default=-1, minimum=0, maximum=10, parent=method_name) + if score > -1: + score_dict[modifier] = score + elif search_attr not in ["username", "list_name", "sort_by"]: + raise Failed(f"{self.Type} Error: {method_name} {search_method} attribute not supported") + new_dictionary["score"] = score_dict + self.builders.append((method_name, self.config.AniList.validate_userlist(new_dictionary))) elif method_name == "anilist_search": if self.current_time.month in [12, 1, 2]: current_season = "winter" elif self.current_time.month in [3, 4, 5]: current_season = "spring" @@ -2525,7 +2536,7 @@ class CollectionBuilder: elif self.playlist and items_added: self.obj.addItems(items_added) elif items_added: - self.library.alter_collection(items_added, name, smart_label_collection=self.smart_label_collection) + self.library.alter_collection(items_added, name, smart_label_collection=self.smart_label_collection) if self.do_report and items_added: self.library.add_additions(self.name, [(i.title, self.library.get_id_from_maps(i.ratingKey)) for i in items_added], self.library.is_movie) logger.exorcise() @@ -2555,7 +2566,7 @@ class CollectionBuilder: self.library._reload(self.obj) self.obj.removeItems(items_removed) elif items_removed: - self.library.alter_collection(items_removed, self.name, smart_label_collection=self.smart_label_collection, add=False) + self.library.alter_collection(items_removed, self.name, smart_label_collection=self.smart_label_collection, add=False) if self.do_report and items_removed: self.library.add_removed(self.name, [(i.title, self.library.get_id_from_maps(i.ratingKey)) for i in items_removed], self.library.is_movie) logger.info("") diff --git a/modules/plex.py b/modules/plex.py index 15617cf6..d0e0ae70 100644 --- a/modules/plex.py +++ b/modules/plex.py @@ -882,16 +882,7 @@ class Plex(Library): def alter_collection(self, items, collection, smart_label_collection=False, add=True): self.Plex.batchMultiEdits(items) - if smart_label_collection: - if add: - self.Plex.addLabel(collection) - else: - self.Plex.removeLabel(collection) - else: - if add: - self.Plex.addCollection(collection) - else: - self.Plex.removeCollection(collection) + self.query_data(getattr(self.Plex, f"{'add' if add else 'remove'}{'Label' if smart_label_collection else 'Collection'}"), collection) self.Plex.saveMultiEdits() def move_item(self, collection, item, after=None):