Skip to content

Commit

Permalink
[65] update imdb_awards
Browse files Browse the repository at this point in the history
  • Loading branch information
meisnate12 committed Jan 1, 2024
1 parent 3860254 commit 0e20fdb
Show file tree
Hide file tree
Showing 9 changed files with 105 additions and 183 deletions.
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.19.1-develop64
1.19.1-develop65
145 changes: 0 additions & 145 deletions defaults/both/content_rating_de.yml.orig

This file was deleted.

5 changes: 5 additions & 0 deletions docs/config/files.md
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,11 @@ You can have some control of the files from inside your Configuration file by us

<div id="schedule" />Used to schedule when this file is run using the [schedule options](schedule.md).

??? warning

This does not work with Overlays as they cannot be scheduled individually. Use the
[`schedule_overlays` Library Attribute](libraries.md#schedule-overlays) to schedule Overlays.

<hr style="margin: 0px;">

**Attribute:** `schedule`
Expand Down
2 changes: 1 addition & 1 deletion docs/config/libraries.md
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ The available attributes for each library are as follows:
??? blank "`schedule_overlays` - Used to schedule overlays.<a class="headerlink" href="#schedule-overlays" title="Permanent link">¶</a>"

<div id="schedule-overlays" />Used to schedule overlays to run when desired. Overlays are applied all at once in a
batch therfore you cannot schedule individual Overlay Files, as any unscheduled overlay file will be removed each
batch therefore you cannot schedule individual Overlay Files, as any unscheduled overlay file will be removed each
time PMM is run.

<hr style="margin: 0px;">
Expand Down
23 changes: 16 additions & 7 deletions docs/files/builders/imdb.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,13 +130,22 @@ collections:

Finds every item in an [IMDb Event](https://www.imdb.com/event/).

| Award Parameter | Description |
|:------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `event_id` | Specify the IMDb Event ID to search.<br>**Options:** The ID found in the URLs linked on the [IMDb Events Page](https://www.imdb.com/event/). (ex. `ev0000003`) |
| `event_year` | Specify the Year of the Event to look at.<br>**Options:** Any Year under the Event History Sidebar on an Event page. |
| `award_filter` | Filter by the Award heading. Can only accept multiple values as a list.<br>**Options:** Any Black Award heading on an Event Page. |
| `category_filter` | Filter by the Category heading. Can only accept multiple values as a list.<br>**Options:** Any Gold/Yellow Category heading on an Event Page. |
| `winning` | Filter by if the Item Won the award.<br>**Options:** `true`/`false`<br>**Default:** `false` |
| Award Parameter | Description |
|:--------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `event_id` | Specify the IMDb Event ID to search. **This attribute is required.**<br>**Options:** The ID found in the URLs linked on the [IMDb Events Page](https://www.imdb.com/event/). (ex. `ev0000003`) |
| `event_year`<sup>1</sup> | Specify the year of the Event to look at. **This attribute is required.**<br>**Options:** Any year, list of years, or year range (ex. `2000-2009` or `2000-current`) from the years under the Event History Sidebar on an Event page. |
| `award_filter` | Filter by the Award heading. Can only accept multiple values as a list.<br>**Options:** Any Black Award heading on an Event Page. |
| `category_filter` | Filter by the Category heading. Can only accept multiple values as a list.<br>**Options:** Any Gold/Yellow Category heading on an Event Page. |
| `winning` | Filter by if the Item Won the award.<br>**Options:** `true`/`false`<br>**Default:** `false` |

1. When using multiple years the only available Event IDs are:

```yaml
{%
include-markdown "https://raw.githubusercontent.com/meisnate12/PMM-IMDb-Awards/master/event_ids.yml"
comments=false
%}
```

```yaml
collections:
Expand Down
3 changes: 3 additions & 0 deletions docs/stylesheets/extra.css
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
--md-default-bg-color: #252525;
--md-footer-bg-color--dark: var(--md-default-bg-color);
}
strong {
color: #00bc8c;
}

.md-banner {
background-color: #252525;
Expand Down
37 changes: 27 additions & 10 deletions modules/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -1507,18 +1507,35 @@ def _imdb(self, method_name, method_data):
for dict_data in util.parse(self.Type, method_name, method_data, datatype="listdict"):
dict_methods = {dm.lower(): dm for dm in dict_data}
event_id = util.parse(self.Type, "event_id", dict_data, parent=method_name, methods=dict_methods, regex=(r"(ev\d+)", "ev0000003"))
year_options = self.config.IMDb.get_event_years(event_id)
git_event, year_options = self.config.IMDb.get_event_years(event_id)
if not year_options:
raise Failed(f"{self.Type} Error: imdb_award event_id attribute: No event found at {imdb.base_url}/event/{event_id}")
event_year = str(util.parse(self.Type, "event_year", dict_data, parent=method_name, methods=dict_methods, options=year_options))
try:
award_filters = util.parse(self.Type, "award_filter", dict_data, parent=method_name, methods=dict_methods, datatype="lowerlist")
except Failed:
award_filters = []
try:
category_filters = util.parse(self.Type, "category_filter", dict_data, parent=method_name, methods=dict_methods, datatype="lowerlist")
except Failed:
category_filters = []
if "event_year" not in dict_methods:
raise Failed(f"{self.Type} Error: imdb_award event_year attribute not found")
og_year = dict_data[dict_methods["event_year"]]
if not og_year:
raise Failed(f"{self.Type} Error: imdb_award event_year attribute is blank")
if og_year == "all":
event_year = year_options
elif not isinstance(og_year, list) and "-" in str(og_year) and len(str(og_year)) > 7:
try:
min_year, max_year = og_year.split("-")
min_year = int(min_year)
max_year = int(max_year) if max_year != "current" else None
event_year = []
for option in year_options:
check = int(option.split("-")[0] if "-" in option else option)
if check >= min_year and (max_year is None or check <= max_year):
event_year.append(option)
except ValueError:
raise Failed(f"{self.Type} Error: imdb_award event_year attribute invalid: {og_year}")
else:
event_year = util.parse(self.Type, "event_year", og_year, parent=method_name, datatype="strlist", options=year_options)

if len(event_year) > 1 and not git_event:
raise Failed(f"{self.Type} Error: Only specific events work when using multiple years. Event Options: {self.config.IMDb.events_validation.keys()}")
award_filters = util.parse(self.Type, "award_filter", dict_data, parent=method_name, methods=dict_methods, datatype="lowerlist")
category_filters = util.parse(self.Type, "category_filter", dict_data, parent=method_name, methods=dict_methods, datatype="lowerlist")
final_category = []
final_awards = []
if award_filters or category_filters:
Expand Down
69 changes: 51 additions & 18 deletions modules/imdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
"razzie": {"eventId": "ev0000558"},
}
base_url = "https://www.imdb.com"
git_base = "https://raw.githubusercontent.com/meisnate12/PMM-IMDb-Awards/master"
graphql_url = "https://api.graphql.imdb.com/"
list_url = f"{base_url}/list/ls"

Expand All @@ -81,6 +82,8 @@ def __init__(self, config):
self._ratings = None
self._genres = None
self._episode_ratings = None
self._events_validation = None
self._events = {}

def _request(self, url, language=None, xpath=None, params=None):
logger.trace(f"URL: {url}")
Expand All @@ -93,6 +96,17 @@ def _request(self, url, language=None, xpath=None, params=None):
def _graph_request(self, json_data):
return self.config.post_json(graphql_url, headers={"content-type": "application/json"}, json=json_data)

@property
def events_validation(self):
if self._events_validation is None:
self._events_validation = self.config.load_yaml(f"{git_base}/event_validation.yml")
return self._events_validation

def get_event(self, event_id):
if event_id not in self._events:
self._events[event_id] = self.config.load_yaml(f"{git_base}/events/{event_id}.yml")
return self._events[event_id]

def validate_imdb_lists(self, err_type, imdb_lists, language):
valid_lists = []
for imdb_dict in util.get_list(imdb_lists, split=False):
Expand Down Expand Up @@ -146,13 +160,17 @@ def validate_imdb_watchlists(self, err_type, users, language):
return valid_users

def get_event_years(self, event_id):
if event_id in self.events_validation:
return True, self.events_validation[event_id]["years"]
final = []
for event_link in self._request(f"{base_url}/event/{event_id}", xpath="//div[@class='event-history-widget']//a/@href"):
parts = event_link.split("/")
final.append(f"{parts[3]}{f'-{parts[4]}' if parts[4] != '1' else ''}")
return final
return False, final

def get_award_names(self, event_id, event_year):
if event_id in self.events_validation:
return self.events_validation[event_id]["awards"], self.events_validation[event_id]["categories"]
award_names = []
category_names = []
event_slug = f"{event_year}/1" if "-" not in event_year else event_year.replace("-", "/")
Expand Down Expand Up @@ -421,23 +439,34 @@ def _search(self, data):

def _award(self, data):
final_list = []
event_slug = f"{data['event_year']}/1" if "-" not in data["event_year"] else data["event_year"].replace("-", "/")
for text in self._request(f"{base_url}/event/{data['event_id']}/{event_slug}/?ref_=ev_eh", xpath="//div[@class='article']/script/text()")[0].split("\n"):
if text.strip().startswith("IMDbReactWidgets.NomineesWidget.push"):
jsonline = text.strip()
obj = json.loads(jsonline[jsonline.find('{'):-3])
for award in obj["nomineesWidgetModel"]["eventEditionSummary"]["awards"]:
if data["award_filter"] and award["awardName"] not in data["award_filter"]:
if len(data["event_year"]) > 1:
event_data = self.get_event(data["event_id"])
for event_year in data["event_year"]:
for award, categories in event_data[event_year].items():
if data["award_filter"] and award not in data["award_filter"]:
continue
for cat in award["categories"]:
if data["category_filter"] and cat["categoryName"] not in data["category_filter"]:
for cat in categories:
if data["category_filter"] and cat not in data["category_filter"]:
continue
final_list.extend(categories["winner" if data["winning"] else "nominee"])
else:
event_slug = f"{data['event_year'][0]}/1" if "-" not in data["event_year"][0] else data["event_year"][0].replace("-", "/")
for text in self._request(f"{base_url}/event/{data['event_id']}/{event_slug}/?ref_=ev_eh", xpath="//div[@class='article']/script/text()")[0].split("\n"):
if text.strip().startswith("IMDbReactWidgets.NomineesWidget.push"):
jsonline = text.strip()
obj = json.loads(jsonline[jsonline.find('{'):-3])
for award in obj["nomineesWidgetModel"]["eventEditionSummary"]["awards"]:
if data["award_filter"] and award["awardName"] not in data["award_filter"]:
continue
for nom in cat["nominations"]:
if data["winning"] and not nom["isWinner"]:
for cat in award["categories"]:
if data["category_filter"] and cat["categoryName"] not in data["category_filter"]:
continue
imdb_id = next((n["const"] for n in nom["primaryNominees"] + nom["secondaryNominees"] if n["const"].startswith("tt")), None)
if imdb_id:
final_list.append(imdb_id)
for nom in cat["nominations"]:
if data["winning"] and not nom["isWinner"]:
continue
imdb_id = next((n["const"] for n in nom["primaryNominees"] + nom["secondaryNominees"] if n["const"].startswith("tt")), None)
if imdb_id:
final_list.append(imdb_id)
break
return final_list

Expand Down Expand Up @@ -501,7 +530,7 @@ def _ids_from_chart(self, chart, language):
else:
raise Failed(f"IMDb Error: chart: {chart} not ")
links = self._request(f"{base_url}/{url}", language=language, xpath="//li//a[@class='ipc-title-link-wrapper']/@href")
return [re.search("(tt\\d+)", l).group(1) for l in links]
return [re.search("(tt\\d+)", link).group(1) for link in links]

def get_imdb_ids(self, method, data, language):
if method == "imdb_id":
Expand All @@ -518,8 +547,12 @@ def get_imdb_ids(self, method, data, language):
logger.info(f"Processing IMDb Watchlist: {data}")
return [(_i, "imdb") for _i in self._watchlist(data, language)]
elif method == "imdb_award":
event_slug = f"{data['event_year']}/1" if "-" not in data["event_year"] else data["event_year"].replace("-", "/")
logger.info(f"Processing IMDb Award: {base_url}/{data['event_id']}/{event_slug}/?ref_=ev_eh")
if len(data["event_year"]) == 1:
event_slug = f"{data['event_year'][0]}/1" if "-" not in data["event_year"][0] else data["event_year"][0].replace("-", "/")
logger.info(f"Processing IMDb Award: {base_url}/{data['event_id']}/{event_slug}/?ref_=ev_eh")
else:
logger.info(f"Processing IMDb Award: {data['event_id']}")
logger.info(f" event_year: {data['event_year']}")
for k in ["award_filter", "category_filter", "winning"]:
logger.info(f" {k}: {data[k]}")
return [(_i, "imdb") for _i in self._award(data)]
Expand Down
2 changes: 1 addition & 1 deletion modules/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -776,7 +776,7 @@ def parse(error, attribute, data, datatype=None, methods=None, parent=None, defa
if not isinstance(value, list):
value = [value]
for v in value:
if v:
if v or v == 0:
if options is None or (options and (v in options or (datatype == "strlist" and str(v) in options))):
final_list.append(str(v) if datatype == "strlist" else v)
elif options:
Expand Down

0 comments on commit 0e20fdb

Please sign in to comment.