|
"""JSON parser for Opta F1 feeds.""" |
|
|
|
from datetime import datetime |
|
from typing import Any |
|
|
|
from ...base import MissingDataError |
|
from .base import OptaJSONParser, assertget |
|
|
|
|
|
class F1JSONParser(OptaJSONParser): |
|
"""Extract data from a Opta F1 data stream. |
|
|
|
Parameters |
|
---------- |
|
path : str |
|
Path of the data file. |
|
""" |
|
|
|
def _get_feed(self) -> dict[str, Any]: |
|
for node in self.root: |
|
if "OptaFeed" in node["data"].keys(): |
|
return node |
|
raise MissingDataError |
|
|
|
def _get_doc(self) -> dict[str, Any]: |
|
f1 = self._get_feed() |
|
data = assertget(f1, "data") |
|
optafeed = assertget(data, "OptaFeed") |
|
optadocument = assertget(optafeed, "OptaDocument") |
|
return optadocument |
|
|
|
def extract_competitions(self) -> dict[tuple[int, int], dict[str, Any]]: |
|
"""Return a dictionary with all available competitions. |
|
|
|
Returns |
|
------- |
|
dict |
|
A mapping between (competion ID, season ID) tuples and the |
|
information available about each competition in the data stream. |
|
""" |
|
optadocument = self._get_doc() |
|
attr = assertget(optadocument, "@attributes") |
|
competition_id = int(assertget(attr, "competition_id")) |
|
season_id = int(assertget(attr, "season_id")) |
|
competition = { |
|
|
|
"season_id": season_id, |
|
"season_name": str(assertget(attr, "season_id")), |
|
"competition_id": competition_id, |
|
"competition_name": assertget(attr, "competition_name"), |
|
} |
|
return {(competition_id, season_id): competition} |
|
|
|
def extract_games(self) -> dict[int, dict[str, Any]]: |
|
"""Return a dictionary with all available games. |
|
|
|
Returns |
|
------- |
|
dict |
|
A mapping between game IDs and the information available about |
|
each game in the data stream. |
|
""" |
|
optadocument = self._get_doc() |
|
attr = assertget(optadocument, "@attributes") |
|
matchdata = assertget(optadocument, "MatchData") |
|
matches = {} |
|
for match in matchdata: |
|
matchattr = assertget(match, "@attributes") |
|
matchinfo = assertget(match, "MatchInfo") |
|
matchinfoattr = assertget(matchinfo, "@attributes") |
|
game_id = int(assertget(matchattr, "uID")[1:]) |
|
matches[game_id] = { |
|
|
|
"game_id": game_id, |
|
"competition_id": int(assertget(attr, "competition_id")), |
|
"season_id": int(assertget(attr, "season_id")), |
|
"game_day": int(assertget(matchinfoattr, "MatchDay")), |
|
"game_date": datetime.strptime(assertget(matchinfo, "Date"), "%Y-%m-%d %H:%M:%S"), |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
teamdata = assertget(match, "TeamData") |
|
for team in teamdata: |
|
teamattr = assertget(team, "@attributes") |
|
side = assertget(teamattr, "Side") |
|
teamid = assertget(teamattr, "TeamRef") |
|
score = assertget(teamattr, "Score") |
|
if side == "Home": |
|
matches[game_id]["home_team_id"] = int(teamid[1:]) |
|
matches[game_id]["home_score"] = int(score) |
|
else: |
|
matches[game_id]["away_team_id"] = int(teamid[1:]) |
|
matches[game_id]["away_score"] = int(score) |
|
return matches |
|
|