[2] Add Page Topics Options to `imdb_search`

pull/1971/head
meisnate12 8 months ago
parent 10df95d255
commit 26f1cebab4

@ -4,6 +4,7 @@ Updated gitpython requirement to 3.1.43
# Removed Features # Removed Features
# New Features # New Features
Add Page Topics Options to `imdb_search`
# Updates # Updates

@ -1 +1 @@
1.21.0-develop1 1.21.0-develop2

@ -183,7 +183,7 @@ The `sync_mode: sync` and `collection_order: custom` Setting are recommended sin
You can also view the available keywords on the [IMDb Keyword Search page](https://www.imdb.com/search/keyword/). You can also view the available keywords on the [IMDb Keyword Search page](https://www.imdb.com/search/keyword/).
| Search Parameter | Description | | Search Parameter | Description |
|:-------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |:------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `limit` | Specify how items you want returned by the query.<br>**Options:** Any Integer greater than `0`<br>**Default:** `100` | | `limit` | Specify how items you want returned by the query.<br>**Options:** Any Integer greater than `0`<br>**Default:** `100` |
| `sort_by` | Choose from one of the many available sort options.<br>**Options:** `popularity.asc`, `popularity.desc`, `title.asc`, `title.desc`, `rating.asc`, `rating.desc`, `votes.asc`, `votes.desc`, `box_office.asc`, `box_office.desc`, `runtime.asc`, `runtime.desc`, `year.asc`, `year.desc`, `release.asc`, `release.desc`<br>**Default:** `popularity.asc` | | `sort_by` | Choose from one of the many available sort options.<br>**Options:** `popularity.asc`, `popularity.desc`, `title.asc`, `title.desc`, `rating.asc`, `rating.desc`, `votes.asc`, `votes.desc`, `box_office.asc`, `box_office.desc`, `runtime.asc`, `runtime.desc`, `year.asc`, `year.desc`, `release.asc`, `release.desc`<br>**Default:** `popularity.asc` |
| `title` | Search by title name.<br>**Options:** Any String | | `title` | Search by title name.<br>**Options:** Any String |
@ -202,6 +202,32 @@ The `sync_mode: sync` and `collection_order: custom` Setting are recommended sin
| `event.winning` | Item must have won a category at the event given. Can be a comma-separated list.<br>**Options:** `cannes`, `choice`, `spirit`, `sundance`, `bafta`, `oscar`, `emmy`, `golden`, `oscar_picture`, `oscar_director`, `national_film_board_preserved`, `razzie`, or any [IMDb Event ID](https://www.imdb.com/event/all/) (ex. `ev0050888`) | | `event.winning` | Item must have won a category at the event given. Can be a comma-separated list.<br>**Options:** `cannes`, `choice`, `spirit`, `sundance`, `bafta`, `oscar`, `emmy`, `golden`, `oscar_picture`, `oscar_director`, `national_film_board_preserved`, `razzie`, or any [IMDb Event ID](https://www.imdb.com/event/all/) (ex. `ev0050888`) |
| `imdb_top` | Item must be in the top number of given Movies.<br>**Options:** Any Integer greater than `0` | | `imdb_top` | Item must be in the top number of given Movies.<br>**Options:** Any Integer greater than `0` |
| `imdb_bottom` | Item must be in the bottom number of given Movies.<br>**Options:** Any Integer greater than `0` | | `imdb_bottom` | Item must be in the bottom number of given Movies.<br>**Options:** Any Integer greater than `0` |
| `topic` | Item must match at least one given topic. Can be a comma-separated list.<br>**Options:** `alternate_version`, `award`, `business_info`, `crazy_credit`, `goof`, `location`, `plot`, `quote`, `soundtrack`, `technical`, `trivia` |
| `topic.not` | Item must not match any of the given topic. Can be a comma-separated list.<br>**Options:** `alternate_version`, `award`, `business_info`, `crazy_credit`, `goof`, `location`, `plot`, `quote`, `soundtrack`, `technical`, `trivia` |
| `alternate_version` | Item's Alternate Version must contain all the given strings. Can be a comma-separated list.<br>**Options:** Any String |
| `alternate_version.any` | Item's Alternate Version must contain at least one of the given strings. Can be a comma-separated list.<br>**Options:** Any String |
| `alternate_version.not` | Item's Alternate Version must not contain any of the given strings. Can be a comma-separated list.<br>**Options:** Any String |
| `crazy_credit` | Item's Crazy Credits must contain all the given strings. Can be a comma-separated list.<br>**Options:** Any String |
| `crazy_credit.any` | Item's Crazy Credits must contain at least one of the given strings. Can be a comma-separated list.<br>**Options:** Any String |
| `crazy_credit.not` | Item's Crazy Credits must not contain any of the given strings. Can be a comma-separated list.<br>**Options:** Any String |
| `location` | Item's Location must contain all the given strings. Can be a comma-separated list.<br>**Options:** Any String |
| `location.any` | Item's Location must contain at least one of the given strings. Can be a comma-separated list.<br>**Options:** Any String |
| `location.not` | Item's Location must not contain any of the given strings. Can be a comma-separated list.<br>**Options:** Any String |
| `goof` | Item's Goofs must contain all the given strings. Can be a comma-separated list.<br>**Options:** Any String |
| `goof.any` | Item's Goofs must contain at least one of the given strings. Can be a comma-separated list.<br>**Options:** Any String |
| `goof.not` | Item's Goofs must not contain any of the given strings. Can be a comma-separated list.<br>**Options:** Any String |
| `plot` | Item's Plot must contain all the given strings. Can be a comma-separated list.<br>**Options:** Any String |
| `plot.any` | Item's Plot must contain at least one of the given strings. Can be a comma-separated list.<br>**Options:** Any String |
| `plot.not` | Item's Plot must not contain any of the given strings. Can be a comma-separated list.<br>**Options:** Any String |
| `quote` | Item's Quote must contain all the given strings. Can be a comma-separated list.<br>**Options:** Any String |
| `quote.any` | Item's Quote must contain at least one of the given strings. Can be a comma-separated list.<br>**Options:** Any String |
| `quote.not` | Item's Quote must not contain any of the given strings. Can be a comma-separated list.<br>**Options:** Any String |
| `soundtrack` | Item's Soundtrack must contain all the given strings. Can be a comma-separated list.<br>**Options:** Any String |
| `soundtrack.any` | Item's Soundtrack must contain at least one of the given strings. Can be a comma-separated list.<br>**Options:** Any String |
| `soundtrack.not` | Item's Soundtrack must not contain any of the given strings. Can be a comma-separated list.<br>**Options:** Any String |
| `trivia` | Item's Trivia must contain all the given strings. Can be a comma-separated list.<br>**Options:** Any String |
| `trivia.any` | Item's Trivia must contain at least one of the given strings. Can be a comma-separated list.<br>**Options:** Any String |
| `trivia.not` | Item's Trivia must not contain any of the given strings. Can be a comma-separated list.<br>**Options:** Any String |
| `company` | Item must have been released by any company given. Can be a comma-separated list.<br>**Options:** `fox`, `dreamworks`, `mgm`, `paramount`, `sony`, `universal`, `disney`, `warner`, or any IMDb Company ID (ex. `co0023400`) | | `company` | Item must have been released by any company given. Can be a comma-separated list.<br>**Options:** `fox`, `dreamworks`, `mgm`, `paramount`, `sony`, `universal`, `disney`, `warner`, or any IMDb Company ID (ex. `co0023400`) |
| `content_rating` | Item must have the given content rating. Can be a list.<br>**Options:** Dictionary with two attributes `rating` and `region`<br>`rating`: Any String to match the content rating<br>`region`: [2 Digit ISO 3166 Country Code](https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes) | | `content_rating` | Item must have the given content rating. Can be a list.<br>**Options:** Dictionary with two attributes `rating` and `region`<br>`rating`: Any String to match the content rating<br>`region`: [2 Digit ISO 3166 Country Code](https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes) |
| `country` | Item must match with every given country. Can be a comma-separated list.<br>**Options:** [2 Digit ISO 3166 Country Code](https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes) | | `country` | Item must match with every given country. Can be a comma-separated list.<br>**Options:** [2 Digit ISO 3166 Country Code](https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes) |
@ -210,7 +236,7 @@ The `sync_mode: sync` and `collection_order: custom` Setting are recommended sin
| `country.origin` | Item must match any given country as the origin country. Can be a comma-separated list.<br>**Options:** [2 Digit ISO 3166 Country Code](https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes) | | `country.origin` | Item must match any given country as the origin country. Can be a comma-separated list.<br>**Options:** [2 Digit ISO 3166 Country Code](https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes) |
| `keyword` | Item must match with every given keyword. Can be a comma-separated list.<br>**Options:** Any Valid [IMDb Keyword](https://www.imdb.com/search/keyword/) | | `keyword` | Item must match with every given keyword. Can be a comma-separated list.<br>**Options:** Any Valid [IMDb Keyword](https://www.imdb.com/search/keyword/) |
| `keyword.any` | Item must match at least one given keyword. Can be a comma-separated list.<br>**Options:** Any Valid [IMDb Keyword](https://www.imdb.com/search/keyword/) | | `keyword.any` | Item must match at least one given keyword. Can be a comma-separated list.<br>**Options:** Any Valid [IMDb Keyword](https://www.imdb.com/search/keyword/) |
| `keyword.not` | Item must not match any given keyword. Can be a comma-separated list.<br>**Options:** Any String | | `keyword.not` | Item must not match any given keyword. Can be a comma-separated list.<br>**Options:** Any Valid [IMDb Keyword](https://www.imdb.com/search/keyword/) |
| `series` | Item must match at least one given series. Can be a comma-separated list.<br>**Options:** Any IMDb ID (ex. `tt0096697`) | | `series` | Item must match at least one given series. Can be a comma-separated list.<br>**Options:** Any IMDb ID (ex. `tt0096697`) |
| `series.not` | Item must not match any given series. Can be a comma-separated list.<br>**Options:** Any IMDb ID (ex. `tt0096697`) | | `series.not` | Item must not match any given series. Can be a comma-separated list.<br>**Options:** Any IMDb ID (ex. `tt0096697`) |
| `list` | Item must be on every given list. Can be a comma-separated list.<br>**Options:** Any IMDb List ID (ex. `ls000024621`) | | `list` | Item must be on every given list. Can be a comma-separated list.<br>**Options:** Any IMDb List ID (ex. `ls000024621`) |

@ -1579,6 +1579,8 @@ class CollectionBuilder:
new_dictionary[lower_method] = util.parse(self.Type, search_method, search_data, parent=method_name) new_dictionary[lower_method] = util.parse(self.Type, search_method, search_data, parent=method_name)
elif search_attr == "type": elif search_attr == "type":
new_dictionary[lower_method] = util.parse(self.Type, search_method, search_data, datatype="lowerlist", parent=method_name, options=imdb.title_type_options) new_dictionary[lower_method] = util.parse(self.Type, search_method, search_data, datatype="lowerlist", parent=method_name, options=imdb.title_type_options)
elif search_attr == "topic":
new_dictionary[lower_method] = util.parse(self.Type, search_method, search_data, datatype="lowerlist", parent=method_name, options=imdb.topic_options)
elif search_attr == "release": elif search_attr == "release":
new_dictionary[lower_method] = util.parse(self.Type, search_method, search_data, datatype="date", parent=method_name, date_return="%Y-%m-%d") new_dictionary[lower_method] = util.parse(self.Type, search_method, search_data, datatype="date", parent=method_name, date_return="%Y-%m-%d")
elif search_attr == "rating": elif search_attr == "rating":
@ -1642,7 +1644,7 @@ class CollectionBuilder:
countries.append(str(country)) countries.append(str(country))
if countries: if countries:
new_dictionary[lower_method] = countries new_dictionary[lower_method] = countries
elif search_attr in ["keyword", "language"]: elif search_attr in ["keyword", "language", "alternate_version", "crazy_credit", "location", "goof", "plot", "quote", "soundtrack", "trivia"]:
new_dictionary[lower_method] = util.parse(self.Type, search_method, search_data, datatype="lowerlist", parent=method_name) new_dictionary[lower_method] = util.parse(self.Type, search_method, search_data, datatype="lowerlist", parent=method_name)
elif search_attr == "cast": elif search_attr == "cast":
casts = [] casts = []

@ -47,6 +47,19 @@ genre_options = {a.lower(): a for a in [
"News", "Short", "Western", "Sport", "Reality-TV", "Horror", "Fantasy", "Film-Noir", "Music", "Romance", "News", "Short", "Western", "Sport", "Reality-TV", "Horror", "Fantasy", "Film-Noir", "Music", "Romance",
"Talk-Show", "Thriller", "War", "Sci-Fi", "Musical", "Mystery", "Game-Show" "Talk-Show", "Thriller", "War", "Sci-Fi", "Musical", "Mystery", "Game-Show"
]} ]}
topic_options = {
"alternate_version": "ALTERNATE_VERSION",
"award": "AWARD",
"business_info": "BUSINESS_INFO",
"crazy_credit": "CRAZY_CREDIT",
"goof": "GOOF",
"location": "LOCATION",
"plot": "PLOT",
"quote": "QUOTE",
"soundtrack": "SOUNDTRACK",
"technical": "TECHNICAL",
"trivia": "TRIVIA",
}
company_options = { company_options = {
"fox": ["co0000756", "co0176225", "co0201557", "co0017497"], "fox": ["co0000756", "co0176225", "co0201557", "co0017497"],
"dreamworks": ["co0067641", "co0040938", "co0252576", "co0003158"], "dreamworks": ["co0067641", "co0040938", "co0252576", "co0003158"],
@ -253,7 +266,7 @@ class IMDb:
def _search_json(self, data): def _search_json(self, data):
out = { out = {
"locale": "en-US", "locale": "en-US",
"first": data["limit"] if "limit" in data and data["limit"] < 250 else 250, "first": data["limit"] if "limit" in data and 0 < data["limit"] < 250 else 250,
"titleTypeConstraint": {"anyTitleTypeIds": [title_type_options[t] for t in data["type"]] if "type" in data else []}, "titleTypeConstraint": {"anyTitleTypeIds": [title_type_options[t] for t in data["type"]] if "type" in data else []},
} }
sort = data["sort_by"] if "sort_by" in data else "popularity.asc" sort = data["sort_by"] if "sort_by" in data else "popularity.asc"
@ -261,43 +274,44 @@ class IMDb:
out["sortBy"] = sort_by_options[sort_by] out["sortBy"] = sort_by_options[sort_by]
out["sortOrder"] = sort_order.upper() out["sortOrder"] = sort_order.upper()
if "type.not" in data: def check_constraint(bases, mods, constraint, lower="", translation=None, range_name=None):
out["titleTypeConstraint"]["excludeTitleTypeIds"] = [title_type_options[t] for t in data["type.not"]] if not isinstance(bases, list):
bases = [bases]
if "release.after" in data or "release.before" in data: if range_name and not isinstance(range_name, list):
num_range = {} range_name = [range_name]
if "release.after" in data: for i, attr in enumerate(bases):
num_range["start"] = data["release.after"] attrs = [(f"{attr}.{m}" if m else attr, m, im) for m, im in mods]
if "release.before" in data: if any([m in data for m, _ in attrs]):
num_range["end"] = data["release.before"] if constraint not in out:
out["releaseDateConstraint"] = {"releaseDateRange": num_range} out[constraint] = {}
range_data = {}
if "title" in data: for full_attr, mod, imdb_mod in attrs:
out["titleTextConstraint"] = {"searchTerm": data["title"]} if full_attr in data:
if range_name is not None:
if any([a in data for a in ["rating.gte", "rating.lte", "votes.gte", "votes.lte"]]): range_data[imdb_mod] = data[full_attr]
out["userRatingsConstraint"] = {} elif translation is None:
num_range = {} out[constraint][f"{imdb_mod}{lower}"] = data[full_attr]
if "rating.gte" in data: elif isinstance(translation, tuple):
num_range["min"] = data["rating.gte"] out[constraint][f"{imdb_mod}{lower}"] = [d.replace(translation[0], translation[1]) for d in data[full_attr]]
if "rating.lte" in data: elif isinstance(translation, dict):
num_range["max"] = data["rating.lte"] out[constraint][f"{imdb_mod}{lower}"] = [translation[d] for d in data[full_attr]]
out["userRatingsConstraint"]["aggregateRatingRange"] = num_range if range_data:
num_range = {} out[constraint][range_name[i]] = range_data
if "votes.gte" in data:
num_range["min"] = data["votes.gte"] check_constraint("type", [("not", "excludeTitleTypeIds")], "titleTypeConstraint", translation=title_type_options)
if "votes.lte" in data: check_constraint("release", [("after", "start"), ("before", "end")], "releaseDateConstraint", range_name="releaseDateRange")
num_range["max"] = data["votes.lte"] check_constraint("title", [("", "searchTerm")], "titleTextConstraint")
out["userRatingsConstraint"]["ratingsCountRange"] = num_range check_constraint(["rating", "votes"], [("gte", "min"), ("lte", "max")], "userRatingsConstraint", range_name=["aggregateRatingRange", "ratingsCountRange"])
check_constraint("genre", [("", "all"), ("any", "any"), ("not", "exclude")], "genreConstraint", lower="GenreIds", translation=genre_options)
if any([a in data for a in ["genre", "genre.any", "genre.not"]]): check_constraint("topic", [("", "all"), ("any", "any"), ("not", "no")], "withTitleDataConstraint", lower="DataAvailable", translation=topic_options)
out["genreConstraint"] = {} check_constraint("alternate_version", [("", "all"), ("any", "any")], "alternateVersionMatchingConstraint", lower="AlternateVersionTextTerms")
if "genre" in data: check_constraint("crazy_credit", [("", "all"), ("any", "any")], "crazyCreditMatchingConstraint", lower="CrazyCreditTextTerms")
out["genreConstraint"]["allGenreIds"] = [genre_options[g] for g in data["genre"]] check_constraint("location", [("", "all"), ("any", "any")], "filmingLocationConstraint", lower="Locations")
if "genre.any" in data: check_constraint("goof", [("", "all"), ("any", "any")], "goofMatchingConstraint", lower="GoofTextTerms")
out["genreConstraint"]["anyGenreIds"] = [genre_options[g] for g in data["genre.any"]] check_constraint("plot", [("", "all"), ("any", "any")], "plotMatchingConstraint", lower="PlotTextTerms")
if "genre.not" in data: check_constraint("quote", [("", "all"), ("any", "any")], "quoteMatchingConstraint", lower="QuoteTextTerms")
out["genreConstraint"]["excludeGenreIds"] = [genre_options[g] for g in data["genre.not"]] check_constraint("soundtrack", [("", "all"), ("any", "any")], "soundtrackMatchingConstraint", lower="SoundtrackTextTerms")
check_constraint("trivia", [("", "all"), ("any", "any")], "triviaMatchingConstraint", lower="TriviaTextTerms")
if "event" in data or "event.winning" in data: if "event" in data or "event.winning" in data:
input_list = [] input_list = []
@ -325,21 +339,8 @@ class IMDb:
ranges.append({"rankRange": num_range, "rankedTitleListType": "TITLE_METER"}) ranges.append({"rankRange": num_range, "rankedTitleListType": "TITLE_METER"})
out["rankedTitleListConstraint"] = {"allRankedTitleLists": ranges} out["rankedTitleListConstraint"] = {"allRankedTitleLists": ranges}
if any([a in data for a in ["series", "series.not"]]): check_constraint("series", [("", "any"), ("not", "exclude")], "episodicConstraint", lower="SeriesIds")
out["episodicConstraint"] = {} check_constraint("list", [("", "inAllLists"), ("any", "inAnyList"), ("not", "notInAnyList")], "listConstraint")
if "series" in data:
out["episodicConstraint"]["anySeriesIds"] = data["series"]
if "series.not" in data:
out["episodicConstraint"]["excludeSeriesIds"] = data["series.not"]
if any([a in data for a in ["list", "list.any", "list.not"]]):
out["listConstraint"] = {}
if "list" in data:
out["listConstraint"]["inAllLists"] = data["list"]
if "list.any" in data:
out["listConstraint"]["inAnyList"] = data["list.any"]
if "list.not" in data:
out["listConstraint"]["notInAnyList"] = data["list.not"]
if "company" in data: if "company" in data:
company_ids = [] company_ids = []
@ -350,56 +351,12 @@ class IMDb:
company_ids.append(c) company_ids.append(c)
out["creditedCompanyConstraint"] = {"anyCompanyIds": company_ids} out["creditedCompanyConstraint"] = {"anyCompanyIds": company_ids}
if "content_rating" in data: check_constraint("content_rating", [("", "anyRegionCertificateRatings")], "certificateConstraint")
out["certificateConstraint"] = {"anyRegionCertificateRatings": data["content_rating"]} check_constraint("country", [("", "all"), ("any", "any"), ("not", "exclude"), ("origin", "anyPrimary")], "originCountryConstraint", lower="Countries")
check_constraint("keyword", [("", "all"), ("any", "any"), ("not", "exclude")], "keywordConstraint", lower="Keywords", translation=(" ", "-"))
if any([a in data for a in ["country", "country.any", "country.not", "country.origin"]]): check_constraint("language", [("", "all"), ("any", "any"), ("not", "exclude"), ("primary", "anyPrimary")], "languageConstraint", lower="Languages")
out["originCountryConstraint"] = {} check_constraint("cast", [("", "all"), ("any", "any"), ("not", "exclude")], "creditedNameConstraint", lower="NameIds")
if "country" in data: check_constraint("runtime", [("gte", "min"), ("lte", "max")], "runtimeConstraint", range_name="runtimeRangeMinutes")
out["originCountryConstraint"]["allCountries"] = data["country"]
if "country.any" in data:
out["originCountryConstraint"]["anyCountries"] = data["country.any"]
if "country.not" in data:
out["originCountryConstraint"]["excludeCountries"] = data["country.not"]
if "country.origin" in data:
out["originCountryConstraint"]["anyPrimaryCountries"] = data["country.origin"]
if any([a in data for a in ["keyword", "keyword.any", "keyword.not"]]):
out["keywordConstraint"] = {}
if "keyword" in data:
out["keywordConstraint"]["allKeywords"] = [k.replace(" ", "-") for k in data["keyword"]]
if "keyword.any" in data:
out["keywordConstraint"]["anyKeywords"] = [k.replace(" ", "-") for k in data["keyword.any"]]
if "keyword.not" in data:
out["keywordConstraint"]["excludeKeywords"] = [k.replace(" ", "-") for k in data["keyword.not"]]
if any([a in data for a in ["language", "language.any", "language.not", "language.primary"]]):
out["languageConstraint"] = {}
if "language" in data:
out["languageConstraint"]["allLanguages"] = data["language"]
if "language.any" in data:
out["languageConstraint"]["anyLanguages"] = data["language.any"]
if "language.not" in data:
out["languageConstraint"]["excludeLanguages"] = data["language.not"]
if "language.primary" in data:
out["languageConstraint"]["anyPrimaryLanguages"] = data["language.primary"]
if any([a in data for a in ["cast", "cast.any", "cast.not"]]):
out["creditedNameConstraint"] = {}
if "cast" in data:
out["creditedNameConstraint"]["allNameIds"] = data["cast"]
if "cast.any" in data:
out["creditedNameConstraint"]["anyNameIds"] = data["cast.any"]
if "cast.not" in data:
out["creditedNameConstraint"]["excludeNameIds"] = data["cast.not"]
if "runtime.gte" in data or "runtime.lte" in data:
num_range = {}
if "runtime.gte" in data:
num_range["min"] = data["runtime.gte"]
if "runtime.lte" in data:
num_range["max"] = data["runtime.lte"]
out["runtimeConstraint"] = {"runtimeRangeMinutes": num_range}
if "adult" in data and data["adult"]: if "adult" in data and data["adult"]:
out["explicitContentConstraint"] = {"explicitContentFilter": "INCLUDE_ADULT"} out["explicitContentConstraint"] = {"explicitContentFilter": "INCLUDE_ADULT"}

Loading…
Cancel
Save