diff --git a/espncricinfo/exceptions.py b/espncricinfo/exceptions.py index ebf89f8..315cab7 100644 --- a/espncricinfo/exceptions.py +++ b/espncricinfo/exceptions.py @@ -24,4 +24,16 @@ class NoSeriesError(TypeError): """ Exception raised if a series_id is not valid or does not exist. """ - pass \ No newline at end of file + pass + +class NoSeasonError(TypeError): + """ + Exception raised if a series_id is not valid or does not exist. + """ + pass + +class NoTeamError(TypeError): + """ + Exception raised if a series_id is not valid or does not exist. + """ + pass diff --git a/espncricinfo/livematches.py b/espncricinfo/livematches.py new file mode 100644 index 0000000..13df5aa --- /dev/null +++ b/espncricinfo/livematches.py @@ -0,0 +1,93 @@ +import requests, re +from bs4 import BeautifulSoup + +class Team(object): + def __init__(self, teamname, score): + self.name = teamname + self.score = score + +class LiveMatch(object): + def __init__(self, match_time, match_id, match_number, venue, date, year, series, teams, match_status): + self.match_time = match_time + self.match_id = match_id + self.match_number = match_number + self.venue = venue + self.date = date + self.year = year + self.series = series + self.teams = teams + self.match_status = match_status + self.match_name = f"{teams[0].name} vs {teams[1].name}" + + def __repr__(self): + teams_info = " | ".join([f"{team[0]}: {team[1]}" for team in self.teams]) + return (f"Match Time: {self.match_time}\n" + f"Match Number: {self.match_number}\n" + f"Venue: {self.venue}\n" + f"Date: {self.date}, {self.year}\n" + f"Series: {self.series}\n" + f"Teams: {teams_info}\n" + f"Status: {self.match_status}\n") + +class LiveMatches: + + def __init__(self): + self.match_url = "https://www.espncricinfo.com/live-cricket-score" + self.headers = {'user-agent': 'Mozilla/5.0'} + self._live_matches = [] + self.html = None + + @property + def live_matches(self): + if not self._live_matches: + self._get_live_matches() + return self._live_matches + + def _fetch_html(self): + response = requests.get(self.match_url, headers=self.headers) + if response.status_code != 200: + print("Failed to retrieve page") + return None + return BeautifulSoup(response.text, "html.parser") + + def _get_live_matches(self): + self.html = self._fetch_html() + if not self.html: + return [] + + parent_div = self.html.select_one("html > body > div > section > section > div:nth-of-type(3) > div > div:nth-of-type(3) > div:nth-of-type(1) > div:nth-of-type(1) > div:nth-of-type(3) > div > div:nth-of-type(1) > div > div:nth-of-type(2) > div") + if parent_div: + for match_ in parent_div.find_all(recursive=False): + span_text = match_.select_one("span.ds-text-tight-xs.ds-font-bold.ds-uppercase.ds-leading-5") + div_text = match_.select_one("div.ds-text-tight-xs.ds-truncate.ds-text-typo-mid3") + match_time = span_text.text.strip() if span_text else "N/A" + match_date = div_text.text.strip() if div_text else "N/A" + + teams = [] + teams_div = match_.select_one("div.ds-flex.ds-flex-col.ds-mt-2.ds-mb-2") + for team in teams_div.find_all("div", class_="ci-team-score"): + team_div = team.find("div", class_="ds-flex ds-items-center ds-min-w-0 ds-mr-1") + team_name = team_div.get("title") if team_div else "Unknown" + score_div = team.find("div", class_="ds-text-compact-s") + if score_div: + overs_target = score_div.select_one('span[class*="ds-mr-0.5"]') + overs_target_text = overs_target.text.strip() if overs_target else "" + scores = [s.text.strip() for s in score_div.select("strong")] + formatted_score = f"{overs_target_text} {' & '.join(scores)}" if overs_target_text else " & ".join(scores) + else: + formatted_score = None + teams.append(Team(team_name, formatted_score)) + + if match_date != "N/A": + match_number, venue, date, year, series = match_date.split(", ") + else: + match_number = venue = date = year = series = "N/A" + + match_status_p = match_.find("p", class_="ds-text-tight-s ds-font-medium ds-truncate ds-text-typo") + match_status = match_status_p.text.strip() if match_status_p else "N/A" + a_div = match_.select_one("a.ds-no-tap-higlight") + match_url = a_div.get("href") or "" + match_id = re.search(r'-(\d+)/[^/]+$', match_url).group(1) + + self._live_matches.append(LiveMatch(match_time, match_id, match_number, venue, date, year, series, teams, match_status)) + return self._live_matches diff --git a/espncricinfo/match.py b/espncricinfo/match.py index e96bc8a..60a7988 100644 --- a/espncricinfo/match.py +++ b/espncricinfo/match.py @@ -1,6 +1,7 @@ import json import requests from bs4 import BeautifulSoup +from espncricinfo.misc import * from espncricinfo.exceptions import MatchNotFoundError, NoScorecardError class Match(object): @@ -47,12 +48,12 @@ def __init__(self, match_id): self.followon = self._followon() self.scheduled_overs = self._scheduled_overs() self.innings_list = self._innings_list() - self.innings = self._innings() - self.latest_batting = self._latest_batting() - self.latest_bowling = self._latest_bowling() + self.innings = [ Inning(inn) for inn in self._innings() ] + self.latest_batting = [ Batsman(bdata) for bdata in (self._latest_batting() or []) if bdata ] + self.latest_bowling = [ Bowler(bldata) for bldata in (self._latest_bowling() or []) if bldata ] self.latest_innings = self._latest_innings() self.latest_innings_fow = self._latest_innings_fow() - self.team_1 = self._team_1() + self.team_1 = Team(self._team_1()) self.team_1_id = self._team_1_id() self.team_1_abbreviation = self._team_1_abbreviation() self.team_1_players = self._team_1_players() @@ -60,7 +61,7 @@ def __init__(self, match_id): self.team_1_run_rate = self._team_1_run_rate() self.team_1_overs_batted = self._team_1_overs_batted() self.team_1_batting_result = self._team_1_batting_result() - self.team_2 = self._team_2() + self.team_2 = Team(self._team_2()) self.team_2_id = self._team_2_id() self.team_2_abbreviation = self._team_2_abbreviation() self.team_2_players = self._team_2_players() @@ -68,6 +69,8 @@ def __init__(self, match_id): self.team_2_run_rate = self._team_2_run_rate() self.team_2_overs_batted = self._team_2_overs_batted() self.team_2_batting_result = self._team_2_batting_result() + self.note = self._note() + self.live = self._live() if not self.status == 'dormant': self.home_team = self._home_team() self.batting_first = self._batting_first() @@ -133,6 +136,13 @@ def __str__(self): def __unicode__(self): return self.json['description'] + def _note(self): + return self.json['live']['status'] + + def _live(self): + live = Live(self.json['live']) + return live + def _status(self): return self.match_json()['match_status'] @@ -339,54 +349,78 @@ def _team_2_batting_result(self): return None def _home_team(self): - if self._team_1_id() == self.match_json()['home_team_id']: + home_team_id = self.match_json().get('home_team_id', None) + if not home_team_id: + return None + if self._team_1_id() == home_team_id: return self._team_1_abbreviation() else: return self._team_2_abbreviation() def _batting_first(self): - if self._team_1_id() == self.match_json()['batting_first_team_id']: + batting_first_team_id = self.match_json().get('batting_first_team_id', None) + if not batting_first_team_id: + return None + if self._team_1_id() == batting_first_team_id: return self._team_1_abbreviation() else: return self._team_2_abbreviation() def _match_winner(self): - if self._team_1_id() == self.match_json()['winner_team_id']: + winner_team_id = self.match_json().get('winner_team_id', None) + if not winner_team_id: + return None + if self._team_1_id() == winner_team_id: return self._team_1_abbreviation() else: return self._team_2_abbreviation() def _toss_winner(self): - if self._team_1_id() == self.match_json()['toss_winner_team_id']: + toss_winner_team_id = self.match_json().get('toss_winner_team_id', None) + if not toss_winner_team_id: + return None + if self._team_1_id() == toss_winner_team_id: return self._team_1_id() else: return self._team_2_id() def _toss_decision(self): - if self.match_json()['toss_decision'] == '' and len(self.innings) > 0: - if self.innings[0]['batting_team_id'] == self.toss_winner: + toss_decision = self.match_json().get('toss_decision', None) + if not toss_decision: + return None + if toss_decision == '' and len(self.innings) > 0: + if self.innings[0].batting_team_id == self.toss_winner: decision = '1' else: decision = '2' else: - decision = self.match_json()['toss_decision'] + decision = toss_decision return decision def _toss_decision_name(self): - if self.match_json()['toss_decision_name'] == '' and len(self.innings) > 0: - if self.innings[0]['batting_team_id'] == self.toss_winner: + toss_decision_name = self.match_json().get('toss_decision_name', None) + if not toss_decision_name: + return None + if toss_decision_name == '' and len(self.innings) > 0: + if self.innings[0].batting_team_id == self.toss_winner: decision_name = 'bat' else: decision_name = 'bowl' else: - decision_name = self.match_json()['toss_decision_name'] + decision_name = toss_decision_name return decision_name def _toss_choice_team_id(self): - return self.match_json()['toss_choice_team_id'] + toss_choice_team_id = self.match_json().get('toss_choice_team_id', None) + if not toss_choice_team_id: + return None + return toss_choice_team_id def _toss_winner_team_id(self): - return self.match_json()['toss_winner_team_id'] + toss_winner_team_id = self.match_json().get('toss_winner_team_id', None) + if not toss_winner_team_id: + return None + return toss_winner_team_id # comms_json methods diff --git a/espncricinfo/misc.py b/espncricinfo/misc.py new file mode 100644 index 0000000..1d6c692 --- /dev/null +++ b/espncricinfo/misc.py @@ -0,0 +1,206 @@ + +class BatterPlaying: + def __init__(self, batting_data): + self.balls_faced = int(batting_data.get("balls_faced") or 0) + self.batting_position = int(batting_data.get("batting_position") or 0) + self.fours = int(batting_data.get("fours") or 0) + self.innings_number = int(batting_data.get("innings_number") or 0) + self.live_current = int(batting_data.get("live_current") or 0) + self.is_batting = batting_data.get("live_current_name") == "striker" + self.minutes = int(batting_data.get("minutes") or 0) + self.player_id = int(batting_data.get("player_id") or 0) + self.runs = int(batting_data.get("runs") or 0) + self.sixes = int(batting_data.get("sixes") or 0) + self.team_id = int(batting_data.get("team_id") or 0) + self.strike_rate = batting_data.get("strike_rate") or "0.0" + + def __repr__(self): + return f"BatterPlaying(Player ID: {self.player_id}, Runs: {self.runs}, Balls Faced: {self.balls_faced})" + +class BowlerPlaying: + def __init__(self, bowling_data): + self.player_id = int(bowling_data.get("player_id") or 0) + self.team_id = int(bowling_data.get("team_id") or 0) + self.innings_number = int(bowling_data.get("innings_number") or 0) + self.overs = float(bowling_data.get("overs") or 0.0) + self.maidens = int(bowling_data.get("maidens") or 0) + self.conceded = int(bowling_data.get("conceded") or 0) + self.wickets = int(bowling_data.get("wickets") or 0) + self.economy_rate = float(bowling_data.get("economy_rate") or 0.0) + self.noballs = int(bowling_data.get("noballs") or 0) + self.wides = int(bowling_data.get("wides") or 0) + self.live_current = int(bowling_data.get("live_current") or 0) + self.is_bowling = bowling_data.get("live_current_name", "") == "current bowler" + + def __repr__(self): + return f"BowlerPlaying(Player ID: {self.player_id}, Overs: {self.overs}, Wickets: {self.wickets}, Economy: {self.economy_rate})" + +class Batsman: + def __init__(self, data): + self.balls_faced = int(data.get("balls_faced") or 0) + self.hand = data.get("hand", "") + self.image_path = data.get("image_path", "") + self.name = data.get("known_as", "") + self.notout = int(data.get("notout") or 0) + self.player_id = int(data.get("player_id") or 0) + self.popular_name = data.get("popular_name", "") + self.position = int(data.get("position") or 0) + self.position_group = data.get("position_group", "") + self.runs = int(data.get("runs") or 0) + + def __str__(self): + return (f"Batsman {self.known_as} (ID: {self.player_id}): " + f"Runs: {self.runs}, Balls Faced: {self.balls_faced}, " + f"Position: {self.position} ({self.position_group}), " + f"Not Out: {'Yes' if self.notout else 'No'}") + +class Bowler: + def __init__(self, data): + self.conceded = int(data.get("conceded") or 0) + self.hand = data.get("hand", "") + self.image_path = data.get("image_path", "") + self.name = data.get("known_as", "") + self.maidens = int(data.get("maidens") or 0) + self.overs = float(data.get("overs") or 0.0) + self.pacespin = data.get("pacespin", "") + self.player_id = int(data.get("player_id") or 0) + self.popular_name = data.get("popular_name", "") + self.position = int(data.get("position") or 0) + self.wickets = int(data.get("wickets") or 0) + self.is_bowling = data.get("live_current_name", "") == "current bowler" + self.is_previous = data.get("live_current_name", "") == "previous bowler" + + def __str__(self): + return (f"Bowler {self.known_as} (ID: {self.player_id}): " + f"Wickets: {self.wickets}, Overs: {self.overs}, Runs Conceded: {self.conceded}, " + f"Maidens: {self.maidens}, Bowling Style: {self.pacespin}, " + f"Hand: {self.hand}, Position: {self.position}, " + f"Current Status: {self.live_current_name}") + +class Inning: + def __init__(self, data): + self.ball_limit = int(data.get("ball_limit") or 0) + self.balls = int(data.get("balls") or 0) + self.batted = int(data.get("batted") or 0) + self.batting_team_id = int(data.get("batting_team_id") or 0) + self.bowling_team_id = int(data.get("bowling_team_id") or 0) + self.bpo = int(data.get("bpo") or 6) + self.byes = int(data.get("byes") or 0) + self.event = int(data.get("event") or 0) + self.event_name = data.get("event_name", "") + self.extras = int(data.get("extras") or 0) + self.number = int(data.get("innings_number") or 0) + self.numth = data.get("innings_numth", "") + self.lead = int(data.get("lead") or 0) + self.legbyes = int(data.get("legbyes") or 0) + self.live_current = int(data.get("live_current") or 0) + self.live_current_name = data.get("live_current_name", "") + self.minutes = data.get("minutes") + self.noballs = int(data.get("noballs") or 0) + self.old_penalty_or_bonus = int(data.get("old_penalty_or_bonus") or 0) + self.over_limit = float(data.get("over_limit") or 0.0) + self.over_limit_run_rate = float(data.get("over_limit_run_rate") or 0.0) + self.over_split_limit = float(data.get("over_split_limit") or 0.0) + self.overs = float(data.get("overs") or 0.0) + self.overs_docked = int(data.get("overs_docked") or 0) + self.penalties = int(data.get("penalties") or 0) + self.penalties_field_end = int(data.get("penalties_field_end") or 0) + self.penalties_field_start = int(data.get("penalties_field_start") or 0) + self.run_rate = float(data.get("run_rate") or 0.0) + self.runs = int(data.get("runs") or 0) + self.target = int(data.get("target") or 0) + self.wickets = int(data.get("wickets") or 0) + self.wides = int(data.get("wides") or 0) + + def __str__(self): + return (f"Innings {self.innings_number} ({self.innings_numth}): " + f"{self.batting_team_id} vs {self.bowling_team_id}, " + f"Runs: {self.runs}, Wickets: {self.wickets}, Overs: {self.overs}, " + f"Run Rate: {self.run_rate}, Event: {self.event_name}") + +class Player: + def __init__(self, player_data): + self.age_days = int(player_data.get("age_days") or 0) + self.age_years = int(player_data.get("age_years") or 0) + self.alpha_name = player_data.get("alpha_name") + self.batting_hand = player_data.get("batting_hand") + self.batting_style = player_data.get("batting_style") + self.batting_style_long = player_data.get("batting_style_long") + self.bowling_hand = player_data.get("bowling_hand") + self.bowling_pacespin = player_data.get("bowling_pacespin") + self.bowling_style = player_data.get("bowling_style") + self.bowling_style_long = player_data.get("bowling_style_long") + self.captain = int(player_data.get("captain") or 0) + self.card_long = player_data.get("card_long") + self.card_qualifier = player_data.get("card_qualifier") + self.card_short = player_data.get("card_short") + self.dob = player_data.get("dob") + self.image_id = int(player_data.get("image_id") or 0) + self.keeper = int(player_data.get("keeper") or 0) + self.name = player_data.get("known_as") + self.match_player_id = int(player_data.get("match_player_id") or 0) + self.mobile_name = player_data.get("mobile_name") + self.object_id = int(player_data.get("object_id") or 0) + self.id = int(player_data.get("player_id") or 0) + self.name_id = player_data.get("player_name_id", "0") + self.primary_role = player_data.get("player_primary_role") + self.style_id = int(player_data.get("player_style_id") or 0) + self.p_type = int(player_data.get("player_type") or 0) + self.type_name = player_data.get("player_type_name") + self.popular_name = player_data.get("popular_name") + self.portrait_alt_id = player_data.get("portrait_alt_id") + self.portrait_object_id = int(player_data.get("portrait_object_id") or 0) + self.status_id = int(player_data.get("status_id") or 0) + + def __repr__(self): + return f"Player({self.known_as}, {self.batting_hand}, {self.bowling_style_long})" + +class Team: + def __init__(self, team_data): + self.batsmen_in_side = int(team_data.get("batsmen_in_side") or 0) + self.content_id = int(team_data.get("content_id") or 0) + self.country_id = int(team_data.get("country_id") or 0) + self.fielders_in_side = int(team_data.get("fielders_in_side") or 0) + self.image_id = int(team_data.get("image_id") or 0) + self.logo_alt_id = team_data.get("logo_alt_id") + self.logo_espncdn = team_data.get("logo_espncdn") + self.logo_height = int(team_data.get("logo_height") or 0) + self.logo_image_height = int(team_data.get("logo_image_height") or 0) + self.logo_image_path = team_data.get("logo_image_path") + self.logo_image_width = int(team_data.get("logo_image_width") or 0) + self.logo_object_id = int(team_data.get("logo_object_id") or 0) + self.logo_path = team_data.get("logo_path") + self.logo_width = int(team_data.get("logo_width") or 0) + self.object_id = int(team_data.get("object_id") or 0) + self.players = [Player(p) for p in team_data.get("player", [])] + self.players_in_side = int(team_data.get("players_in_side") or 0) + self.site_id = int(team_data.get("site_id") or 0) + self.abbreviation = team_data.get("team_abbreviation") + self.filename = team_data.get("team_filename") + self.general_name = team_data.get("team_general_name") + self.id = int(team_data.get("team_id") or 0) + self.name = team_data.get("team_name") + self.short_name = team_data.get("team_short_name") + self.url_component = team_data.get("url_component") + + def __repr__(self): + return f"Team({self.team_name}, Players: {len(self.players)})" + +class Live: + def __init__(self, json_data): + self.batting = [ BatterPlaying(data) for data in json_data['batting'] ] + self.bowling = [ BowlerPlaying(data) for data in json_data['bowling'] ] + self.status = json_data['status'] + self.ball_limit = int(json_data.get('innings', {}).get('ball_limit') or 0) + self.balls = int(json_data.get('innings', {}).get('balls') or 0) + self.current_inning = int(json_data.get('innings', {}).get('innings_number') or 0) + self.batting_team_id = int(json_data.get('innings', {}).get('batting_team_id') or 0) + self.bowling_team_id = int(json_data.get('innings', {}).get('bowling_team_id') or 0) + self.overs = float(json_data.get('innings', {}).get('overs') or 0.0) + self.remaining_balls = int(json_data.get('innings', {}).get('remaining_balls') or 0) + self.rrr = float(json_data.get('innings', {}).get('required_run_rate') or 0.0) + self.crr = float(json_data.get('innings', {}).get('run_rate') or 0.0) + self.runs = int(json_data.get('innings', {}).get('runs') or 0) + self.target = int(json_data.get('innings', {}).get('target') or 0) + self.team_id = int(json_data.get('innings', {}).get('team_id') or 0) + self.wickets = int(json_data.get('innings', {}).get('wickets') or 0) diff --git a/espncricinfo/seasons.py b/espncricinfo/seasons.py new file mode 100644 index 0000000..0f466b8 --- /dev/null +++ b/espncricinfo/seasons.py @@ -0,0 +1,63 @@ +import requests +from datetime import datetime +from espncricinfo.exceptions import NoSeasonError + +class Season: + def __init__(self, season_id, series_id=8039): + self.id = season_id + self.series_id = series_id + self.json_url = f"http://core.espnuk.org/v2/sports/cricket/leagues/{series_id}/seasons/{season_id}" + self.headers = {'user-agent': 'Mozilla/5.0'} + self.json = self.get_json(self.json_url) + + if self.json: + self.year = self.json.get('year') + self.start_date = self.parse_date(self.json.get('startDate')) + self.end_date = self.parse_date(self.json.get('endDate')) + self.name = self.json.get('name') + self.short_name = self.json.get('shortName') + self.slug = self.json.get('slug') + self._teams_url = self.json.get('teams', {}).get('$ref') + self._series = None + self._teams = [] + self.rankings_url = self.json.get('rankings', {}).get('$ref') + + @property + def series(self): + if self._series is None: + from espncricinfo.series import Series + links = self.json.get('links', []) + if links and len(links)>5: + series_url = links[5]["href"] + series_id = series_url.split("/series/")[-1].split(".html")[0] + self._series = Series(series_id) + return self._series + + @property + def teams(self): + if self._teams is None: + from espncricinfo.teams import Team + teams_json = self.get_json(self._teams_url) + teams_ = teams_json.get('items', []) + for t in teams_: + team_id = t.split("/teams/")[-1] + team_ = Team(team_id) + self._teams.append(team_) + return self._teams + + def get_json(self, url): + response = requests.get(url, headers=self.headers) + if response.status_code == 404: + raise NoSeasonError("Season not found.") + return response.json() + + def parse_date(self, date_str): + if date_str: + return datetime.strptime(date_str, "%Y-%m-%dT%H:%MZ") + return None + + def __str__(self): + return self.name if self.name else "Unknown Season" + + def __repr__(self): + return f"Season(id={self.id}, year={self.year}, name={self.name}, start_date={self.start_date}, end_date={self.end_date})" diff --git a/espncricinfo/series.py b/espncricinfo/series.py index 7999d5e..677b408 100644 --- a/espncricinfo/series.py +++ b/espncricinfo/series.py @@ -1,17 +1,17 @@ import requests -from bs4 import BeautifulSoup from espncricinfo.exceptions import MatchNotFoundError, NoSeriesError +from espncricinfo.match import Match class Series(object): - def __init__(self, series_id): self.series_id = series_id self.json_url = "http://core.espnuk.org/v2/sports/cricket/leagues/{0}/".format(str(series_id)) - self.events_url = "http://core.espnuk.org/v2/sports/cricket/leagues/{0}/events".format(str(series_id)) self.seasons_url = "http://core.espnuk.org/v2/sports/cricket/leagues/{0}/seasons".format(str(series_id)) self.headers = {'user-agent': 'Mozilla/5.0'} self.json = self.get_json(self.json_url) - self.seasons = self._get_seasons() + self._seasons = [] + self.events_url = f"{0}/events".format(self.seasons[0]) + self._current_season = None self.years = self._get_years_from_seasons() if self.json: self.name = self.json['name'] @@ -24,6 +24,29 @@ def __init__(self, series_id): if self.events_json: self.events = self._build_events() + self.current_events = self._get_current_events() + self.matches = self._build_matches() + self.current_matches = self._get_current_matches() + + @property + def seasons(self): + if not self._seasons: + from espncricinfo.seasons import Season + season_json = self.get_json(self.seasons_url) + if season_json: + season_urls = [x['$ref'] for x in season_json['items']] + for url in season_urls: + season = Season(url.split("/seasons/")[-1]) + self._seasons.append(season) + if len(self._seasons) > 0: + self._current_season = self._seasons[0] + return self._seasons + + @property + def current_season(self): + if not self._current_season: + self.seasons() + return self._current_season def get_json(self, url): r = requests.get(url,headers=self.headers) @@ -38,13 +61,6 @@ def __str__(self): def __unicode__(self): return self.name - def _get_seasons(self): - season_json = self.get_json(self.seasons_url) - if season_json: - return [x['$ref'] for x in season_json['items']] - else: - return None - def _get_years_from_seasons(self): return [x.split('/')[9] for x in self.seasons] @@ -55,8 +71,27 @@ def _get_events(self): else: return None + def _get_current_events(self): + events_json = self.get_json(self.events[0]) + if events_json: + return [x['$ref'] for x in events_json['items']] + else: + return None + + def _get_current_matches(self): + matches = [] + for match_url in self.current_events: + matches.append(Match(match_url.split("/events/")[-1])) + return matches + def _build_events(self): events = [] for event in self.events_json: events.append(self.get_json(event['$ref'])) return events + + def _build_matches(self): + matches = [] + for match_url in self.events: + matches.append(Match(match_url.split("/events/")[-1])) + return matches diff --git a/espncricinfo/teams.py b/espncricinfo/teams.py new file mode 100644 index 0000000..4ed3e51 --- /dev/null +++ b/espncricinfo/teams.py @@ -0,0 +1,54 @@ +import json +import requests +from datetime import datetime +from espncricinfo.exceptions import MatchNotFoundError, NoTeamError +from espncricinfo.match import Match + +class Team: + def __init__(self, team_id, league_id=8081): + self.id = team_id + self.json_url = f"http://core.espnuk.org/v2/sports/cricket/leagues/{league_id}/teams/{series_id}/" + self.headers = {'user-agent': 'Mozilla/5.0'} + self.json = self.get_json(self.json_url) + + if self.json: + self.location = self.json.get('location') + self.name = self.json.get('name') + self.nickname = self.json.get('nickname') + self.short_name = self.json.get('abbreviation') + self.slug = self.json.get('slug') + self.color = self.json.get('color') + self.logo = next((logo.get("href") for logo in data.get("logos", []) if "href" in logo), None) + self.is_national = self.json.get('slug') + self.is_active = self.json.get('is_active') + self.match_date = self.parse_date(self.json.get('event').get('date')) + self._match_url = self.json.get('event').get('$ref') + self.match = Match(self.match_url.split("/events/")[-1]) + self._players_url = self.json.get('athletes').get('$ref') + self._players = [] + + @property + def players(self): + if not self._players: + from espncricinfo.player import Player + players_json = self.get_json(self._players_url) + if players_json: + player_urls = [x['$ref'] for x in players_json['items']] + for url in player_urls: + player_ = Player(url.split("/athletes/")[-1]) + self._players.append(player_) + return self._players + + def get_json(self, url): + response = requests.get(url, headers=self.headers) + if response.status_code == 404: + raise NoTeamError("Season not found.") + return response.json() + + def parse_date(self, date_str): + if date_str: + return datetime.strptime(date_str, "%Y-%m-%dT%H:%MZ") + return None + + def __repr__(self): + return f"Team({self.team_id}, {self.name}, {self.short_name})"