def team_schedule(): """ Use MLB Stats API to extract daily MLB Team Schedules for use in Game Watchability Index calculation Returns: {Date: {H1: Team_Name, A1: Team_Name, ..., H8: Team_Name, A8: Team_Name}} """ # Retrieve schedule of today's games today = datetime.datetime.today().strftime('%Y-%m-%d') schedule = statsapi.schedule(today) # Team Codes: # 108 LAA Angels # 109 ARI D-backs # 110 BAL Orioles # 111 BOS Red Sox # 112 CHC Cubs # 113 CIN Reds # 114 CLE Indians # 115 COL Rockies # 116 DET Tigers # 117 HOU Astros # 118 KC Royals # 119 LAD Dodgers # 120 WSH Nationals # 121 NYM Mets # 133 OAK Athletics # 134 PIT Pirates # 135 SD Padres # 136 SEA Mariners # 137 SF Giants # 138 STL Cardinals # 139 TB Rays # 140 TEX Rangers # 141 TOR Blue Jays # 142 MIN Twins # 143 PHI Phillies # 144 ATL Braves # 145 CWS White Sox # 146 MIA Marlins # 147 NYY Yankees # 158 MIL Brewers # Convert Team Codes into Abbreviations and use as new dictionary values daily_schedule = {} for team in range(len(schedule)): home_team = statsapi.lookup_team( schedule[team]['home_id'])[0]['fileCode'].upper() away_team = statsapi.lookup_team( schedule[team]['away_id'])[0]['fileCode'].upper() daily_schedule.update({ 'H' + str(team): home_team, 'A' + str(team): away_team }) # Append previous dictionary to main dictionary team_schedules = {today: daily_schedule} return team_schedules
def addBallpark(): global num_ballparks home = request.get_json() if num_ballparks < 1: if statsapi.lookup_team(home) != [] and statsapi.lookup_team( home) != None: new_ballpark = {} new_ballpark["ballpark"] = home ballpark.append(new_ballpark) num_ballparks += 1 return jsonify({'ballpark': ballpark}) else: return f"{ballpark} not found." else: return "There can be only 1 ballpark."
def get_teams(ids): #format list of teams from MYSql query into a single, de-duped list all_team_ids = [item for sublist in ids for item in sublist] all_team_ids = list(set(all_team_ids)) # look up teams with mlb-statsapi teams = [mlb.lookup_team(x) for x in all_team_ids] #flatten list of lists teams = [item for sublist in teams for item in sublist] #convert to dataframe to parse df = pd.DataFrame(teams, columns=['id', 'name']) # list all the teams in the American League AL_teams = [ 'Oakland Athletics', 'Kansas City Royals', 'Houston Astros', 'Detroit Tigers', 'Cleveland Indians', 'Boston Red Sox', 'Baltimore Orioles', 'Los Angeles Angels', 'New York Yankees', 'Chicago White Sox', 'Minnesota Twins', 'Texas Rangers', 'Toronto Blue Jays', 'Tampa Bay Rays', 'Seattle Mariners' ] # set the defaultleague value to NL df['league'] = 'NL' # replace "NL" with "AL" for teams in AL_teams df['league'] = df[df['name'].isin(AL_teams) == True]['league'].str.replace( 'N', 'A') #fill nan values with 'NL' df.fillna('NL', inplace=True) return df
async def get_team(self, searchName, message): teamsReturned = statsapi.lookup_team(searchName) if len(teamsReturned) > 1: teamSelected = await self.prompt_team(message, searchName, teamsReturned) elif len(teamsReturned) == 1: teamSelected = teamsReturned[0] elif len(teamsReturned) == 0: await message.channel.send('Hmmm I couldn\'t find and teams using \'' + searchName + '\'') return return teamSelected
def generateTeam(teamName, year): teamLookup = statsapi.lookup_team(teamName, activeStatus="B", season=year, sportIds=1) teamId = teamLookup[0]['id'] team = statsapi.get("team_roster", {"teamId": teamId, "season": year}) roster = [] for plyr in team['roster']: if plyr['status']['code'] == "A": pObj = generatePlayer("", year, playerId=plyr['person']['id']) roster.append(pObj) return Team(teamName, roster)
def mlb_data_current(preferred_team): now = datetime.datetime.now() game_data_set = {} # Read scoreboard options from config.json if it exists #config = get_config("config") #teamData = statsapi.lookup_team(config['preferred']['teams'][0]) for team in statsapi.lookup_team(preferred_team): now = datetime.datetime.now().strftime('%m/%d/%Y') todays_gameData = statsapi.schedule( date=datetime.datetime.now().strftime('%m/%d/%Y'), start_date=None, end_date=None, team=team['id'], opponent="", sportId=1, game_id=None) #todays_boxscore = statsapi.boxscore_data(todays_gameData[0]['game_id'], timecode=None) if len(todays_gameData) > 0: response = requests.get('https://statsapi.mlb.com/api/v1.1/game/' + str(todays_gameData[0]['game_id']) + '/feed/live') mlb_game_json_data = response.json( ) if response and response.status_code == 200 else None game_data_set['home_id'] = todays_gameData[0]['home_id'] game_data_set['away_id'] = todays_gameData[0]['away_id'] game_data_set['status'] = todays_gameData[0]['status'] game_data_set['home_score'] = todays_gameData[0]['home_score'] #game_data_set['home_hits'] = todays_boxscore['home']['teamStats']['batting']['hits'] #use live game data game_data_set['home_hits'] = mlb_game_json_data['liveData'][ 'boxscore']['teams']['home']['teamStats']['batting']['hits'] game_data_set['away_score'] = todays_gameData[0]['away_score'] #game_data_set['away_hits'] = todays_boxscore['away']['teamStats']['batting']['hits'] #use live game data game_data_set['away_hits'] = mlb_game_json_data['liveData'][ 'boxscore']['teams']['away']['teamStats']['batting']['hits'] game_data_set['current_inning'] = todays_gameData[0][ 'current_inning'] game_data_set['inning_state'] = todays_gameData[0]['inning_state'] game_data_set['game_datetime'] = mlb_game_json_data['gameData'][ 'datetime']['time'] + ' ' + mlb_game_json_data['gameData'][ 'datetime']['ampm'] if game_data_set['status'] != "Scheduled" or game_data_set[ 'status'] != "Pre-Game": game_data_set['outs_count'] = mlb_game_json_data['liveData'][ 'linescore']['outs'] break return game_data_set
def todays_game(): today = datetime.date.today() tommorrow = today + datetime.timedelta(days=1) # sched = statsapi.schedule(start_date='07/01/2018', end_date='07/31/2018', team=143, opponent=121) statsapi.lookup_team(147) sched_games = statsapi.schedule(start_date=today, end_date=tommorrow) today_games = {} tomorrow_games = {} for game in sched_games: if today == dt.strptime(game['game_date'], '%Y-%m-%d').date(): today_games[game['game_id']] = Game(game) else: tomorrow_games[game['game_id']] = Game(game) body = "" # now, print out Today's followed by Tommorrow's games body += "Today's Games: {}{}".format(today.isoformat(), os.linesep) for game in today_games: body += '{}'.format(today_games[game].summary_info()) body += "Tommorrow's Games: {}{}".format(tommorrow.isoformat(), os.linesep) for game in tomorrow_games: body += '{}'.format(tomorrow_games[game].summary_info()) return body
def calcTeamFip(playerID, team): team_info = statsapi.lookup_team(team) jsonify(team_info) team_id = str(team_info[0]['id']) get_pitcher_stats = requests.get(base_url + playerID + pitching_url) pitcher_stats = get_pitcher_stats.json() if 'splits' in pitcher_stats['stats']: pitcher_gs = float(pitcher_stats['stats'][0]['splits'][0]['stat']['gamesStarted']) if pitcher_gs == 0: pitcher_gs = 1 pitcher_ip_game = float(pitcher_stats['stats'][0]['splits'][0]['stat']['inningsPitched']) / pitcher_gs if pitcher_ip_game > 1.35 * ip_game_avr or pitcher_ip_game < 0.65 * ip_game_avr: pitcher_ip_game = ip_game_avr pitcher_hrs = float(pitcher_stats['stats'][0]['splits'][0]['stat']['homeRuns']) pitcher_bb = float(pitcher_stats['stats'][0]['splits'][0]['stat']['baseOnBalls']) pitcher_hbp = float(pitcher_stats['stats'][0]['splits'][0]['stat']['hitBatsmen']) pitcher_k = float(pitcher_stats['stats'][0]['splits'][0]['stat']['strikeOuts']) pitcher_ip = float(pitcher_stats['stats'][0]['splits'][0]['stat']['inningsPitched']) pitcher_Fip = (13 * (pitcher_hrs) + 3 * (pitcher_bb + pitcher_hbp) - 2 * pitcher_k) / pitcher_ip + FIP_const else: pitcher_Fip = league_avr_FIP pitcher_ip_game = ip_game_avr get_reliever_stats = requests.get(team_stats_url + team_id + team_pitching_url) reliever_stats = get_reliever_stats.json() num_pitchers = int(reliever_stats['stats'][0]['totalSplits']) pitcher_num = 0 reliever_hrs = 0.0 reliever_bb = 0.0 reliever_hbp = 0.0 reliever_k = 0.0 reliever_ip = 0.0 while pitcher_num < num_pitchers: if float(reliever_stats['stats'][0]['splits'][pitcher_num]['stat']['gamesPitched'] / 2 > float(reliever_stats['stats'][0]['splits'][pitcher_num]['stat']['gamesStarted'])): reliever_hrs += float(reliever_stats['stats'][0]['splits'][pitcher_num]['stat']['homeRuns']) reliever_bb += float(reliever_stats['stats'][0]['splits'][pitcher_num]['stat']['baseOnBalls']) reliever_hbp += float(reliever_stats['stats'][0]['splits'][pitcher_num]['stat']['hitBatsmen']) reliever_k += float(reliever_stats['stats'][0]['splits'][pitcher_num]['stat']['strikeOuts']) reliever_ip += float(reliever_stats['stats'][0]['splits'][pitcher_num]['stat']['inningsPitched']) pitcher_num += 1 reliever_Fip = (13 * (reliever_hrs) + 3 * (reliever_bb + reliever_hbp) - 2 * reliever_k) / reliever_ip + FIP_const team_Fip = pitcher_Fip * (pitcher_ip_game / 9) + reliever_Fip * ((9 - pitcher_ip_game) / 9) return team_Fip
def main(): #0 - No State #1 - Before Game #2 - During Game #3 - After Game gameState = 0 inningState = -1 homeRun = False states = [gameState, inningState, homeRun] teamName = input("Enter the team you would like to listen to: ") TeamData = sa.lookup_team(teamName) teamID = TeamData[0]['id'] printed = False os.system('cls' if os.name == 'nt' else 'clear') while 1: oldScoring = [] schedule = sa.schedule(datetime.date.today(), team=teamID) try: game = schedule[0] except: if not printed: print( "The " + teamName + " do not have a game today, their next game will be against the " + FSM.getGameInfo(teamID)[0] + " on " + FSM.getGameInfo(teamID)[1]) printed = True continue #try: states = FSM.stateMachine(FSM, game, states[0], states[1], teamName, oldScoring, teamID, states[2]) #except: # continue time.sleep(120)
def mlb_data_last_game(preferred_team): last_game_date = datetime.datetime.today() - timedelta(days=1) game_data_set = {} # Read scoreboard options from config.json if it exists #config = get_config("config") #teamData = statsapi.lookup_team(config['preferred']['teams'][0]) for team in statsapi.lookup_team(preferred_team): last_game_date = last_game_date.strftime('%m/%d/%Y') last_gameData = statsapi.schedule(date=last_game_date, start_date=None, end_date=None, team=team['id'], opponent="", sportId=1, game_id=None) if len(last_gameData) > 0: last_boxscore = statsapi.boxscore_data(last_gameData[0]['game_id'], timecode=None) game_data_set['home_id'] = last_gameData[0]['home_id'] game_data_set['away_id'] = last_gameData[0]['away_id'] game_data_set['status'] = last_gameData[0]['status'] game_data_set['home_score'] = last_gameData[0]['home_score'] game_data_set['home_hits'] = last_boxscore['home']['teamStats'][ 'batting']['hits'] game_data_set['away_score'] = last_gameData[0]['away_score'] game_data_set['away_hits'] = last_boxscore['away']['teamStats'][ 'batting']['hits'] break return game_data_set
#!/usr/bin/python import statsapi import datetime from dateutil import tz from sendgrid import SendGridAPIClient from sendgrid.helpers.mail import Mail import os sg = SendGridAPIClient(os.environ.get("SENDGRID_API_KEY")) destinations = os.environ.get("DESTINATIONS") from_email = os.environ.get("FROM_EMAIL") team = statsapi.lookup_team('chc')[0] today = datetime.date.today().strftime("%m/%d/%Y") games = statsapi.schedule(team=team["id"], date=today) from_zone = tz.tzutc() to_zone = tz.gettz("America/Chicago") for game in games: dt = datetime.datetime.strptime(game["game_datetime"], "%Y-%m-%dT%H:%M:%SZ") time = dt.replace( tzinfo=from_zone).astimezone(to_zone).strftime('%I:%M %p') message = "{} at {}".format(game["summary"], time) email_message = Mail(from_email=from_email, to_emails=destinations, subject="MLB",
def playerdatabase(): playerset_num = 0 player_database = [[], [], [], [], [], [], [], [], [], [], []] for playerset in players: playerset_database = [] player_num = 0 for player in playerset: print(len(playerset)) print(player_num) if statsapi.lookup_player(player) != [] and statsapi.lookup_player( player) != 'none': if playerset_num == 0 or playerset_num == 1: player_ID = str(statsapi.lookup_player(player)[0]['id']) get_player_stats = requests.get(base_url + player_ID + pitching_url) player_stats = get_player_stats.json() new_player = { "player_name": player, "era": player_stats['stats'][0]['splits'][0]['stat']['era'], "k_per_9": player_stats['stats'][0]['splits'][0]['stat'] ['strikeoutsPer9Inn'], "k_per_w": player_stats['stats'][0]['splits'][0]['stat'] ['strikeoutWalkRatio'], "whip": player_stats['stats'][0]['splits'][0]['stat']['whip'], "wins": player_stats['stats'][0]['splits'][0]['stat']['wins'], "player_team": str( statsapi.lookup_team( statsapi.lookup_player(player)[0] ['currentTeam']['id'])[0]['name']), "player_id": player_ID } playerset_database.append(new_player) else: player_ID = str(statsapi.lookup_player(player)[0]['id']) print(player_ID) get_player_stats = requests.get(base_url + player_ID + hitting_url) player_stats = get_player_stats.json() if playerset_num == 8: player_defense = [] else: get_player_fielding = requests.get(base_url + player_ID + fielding_url) player_fielding = get_player_fielding.json() index = 0 num_indexes = len( (player_fielding['stats'][0]['splits'])) player_defense = [] while index < num_indexes: new_position = { "position": player_fielding['stats'][0]['splits'][index] ['stat']['position']['abbreviation'], "fielding_perc": player_fielding['stats'][0]['splits'][index] ['stat']['fielding'], } player_defense.append(new_position) index += 1 new_player = { "player_name": player, "average": player_stats['stats'][0]['splits'][0]['stat']['avg'], "on_base_per": player_stats['stats'][0]['splits'][0]['stat']['obp'], "slugging_per": player_stats['stats'][0]['splits'][0]['stat']['slg'], "homeruns": player_stats['stats'][0]['splits'][0]['stat'] ['homeRuns'], "stolen_bases": player_stats['stats'][0]['splits'][0]['stat'] ['stolenBases'], "player_team": str( statsapi.lookup_team( statsapi.lookup_player(player)[0] ['currentTeam']['id'])[0]['name']), "player_id": player_ID, "fielding_perc": player_defense } playerset_database.append(new_player) player_num += 1 player_database[playerset_num] = playerset_database playerset_num += 1 return jsonify(player_database)
performance = pd.DataFrame([['Logreg', acc_logreg, prec_logreg, rec_logreg, f1_logreg], ['Random Forests', acc_rf, prec_rf, rec_rf, f1_rf], ['AdaBoost', acc_ada, prec_ada, rec_ada, f1_ada]], columns=['Model', 'Accuracy', 'Precision', 'Recall', "F1 Score"]) print("Model performance summary on validation set: \n", performance) performance.to_csv("data/model_stats/performance_{}.csv".format(today), index=False) models_dict = {'Logreg': logreg, 'Random Forests': rf_classifier, 'AdaBoost': boosted_dt} best_model = models_dict[performance.sort_values('F1 Score', ascending=False).iloc[0]['Model']] # Make predictions predictions = hits_test.take(np.argsort(best_model.predict_proba(data_test)[:, 1])[::-1][:10])[['Name', 'Team']].reset_index().iloc[:, 1:] predictions.columns = ["name", "team_id"] predictions["team_name"] = predictions['team_id'].apply(lambda x: statsapi.lookup_team(x)[0]['name']) predictions["hit_probability"] = np.sort(rf_classifier.predict_proba(data_test)[:, 1])[::-1][:10] predictions.drop(['team_id'], axis=1, inplace=True) predictions.columns = ['Name', 'Team', 'Hit Probability'] predictions.to_csv("data/predictions/predictions_{}.csv".format(today), index=False) print("Predictions for today: \n", predictions) # Add data for accuracy plot visualization for website accuracy_plot_data = pd.read_csv("data/plots/accuracy_plot_data.csv") new_day = today[:-5] latest_overall_acc = max(performance['Accuracy']) latest_top10_acc = float(predictions.iloc[-1]['player_got_hit']) accuracy_plot_data = accuracy_plot_data.append({"Day": new_day, "Overall Accuracy": latest_overall_acc,
def __init__(self): self.teams = statsapi.lookup_team("")
def lookupid(teamname): team_id = statsapi.lookup_team(teamname)[0]["id"] return team_id
def results(request): # url = "http://lookup-service-prod.mlb.com/json/named.search_player_all.bam?sport_code='mlb'&name_part={}" # url = 'http://api.openweathermap.org/data/2.5/weather?q={}&units=metric&appid=271d1234d3f497eed5b1d80a07b3fcd1' if request.method == 'POST': r = statsapi.lookup_player(request.POST.get("name_field"), season=2019) # search by name first # returns a list - if so, can work in r[0] for succ contexts # case 1: all 3 provided if (request.POST.get("name_field") != '' and request.POST.get("number_field") != ''\ and request.POST.get("team_field") != ''): num = request.POST.get("number_field") team = request.POST.get("team_field") team_list_dict = statsapi.lookup_team(team) if len(team_list_dict) == 0: # context = {'com': 'Inconsistent information - team does not exist'} context = {'com': []} else: players = [] for player in r: if len(team_list_dict) == 1: team_id = team_list_dict[0]['id'] if player['primaryNumber'] == num and player['currentTeam']['id'] == team_id: players.append(player) else: # len(team_list_dict) > 1 for ind_team in team_list_dict: team_id = ind_team['id'] if player['primaryNumber'] == num and player['currentTeam']['id'] == team_id: players.append(player) if len(players) != 0: context = {'com': players} # elif len(players) > 1: # context = {'com': 'Too broad - make information more specific'} else: # context = {'com': 'No player found - possibly inconsisent information'} context = {'com': []} # case 2: no info provided elif (request.POST.get("name_field") == '' and request.POST.get("number_field") == ''\ and request.POST.get("team_field") == ''): # context = {'com': 'No information given'} context = {'com': []} # case 3: name only elif (request.POST.get("name_field") != '' and request.POST.get("number_field") == ''\ and request.POST.get("team_field") == ''): if len(r) != 0: # multiple players context = {'com': r} # elif len(r) > 1: # more than 1 player # context = {'com': 'Too broad - add player information'} else: # no players # context = {'com': 'No player found'} context = {'com': []} # case 4: name, number elif (request.POST.get("name_field") != '' and request.POST.get("number_field") != ''\ and request.POST.get("team_field") == ''): num = request.POST.get("number_field") players = [] for player in r: try: if player['primaryNumber'] == num: # both strings so ok players.append(player) except: pass if len(players) != 0: context = {'com': players} # elif len(players) > 1: # context = {'com': 'Too broad - add player information'} else: # context = {'com': 'No player found'} context = {'com': []} # case 5: name, team elif (request.POST.get("name_field") != '' and request.POST.get("number_field") == ''\ and request.POST.get("team_field") != ''): team = request.POST.get("team_field") team_list_dict = statsapi.lookup_team(team) if len(team_list_dict) == 0: # context = {'com': 'Inconsistent information - team does not exist'} context = {'com': []} else: players = [] for player in r: if len(team_list_dict) == 1: team_id = team_list_dict[0]['id'] if player['currentTeam']['id'] == team_id: players.append(player) else: # len(team_list_dict) > 1 for ind_team in team_list_dict: team_id = ind_team['id'] if player['currentTeam']['id'] == team_id: players.append(player) if len(players) != 0: context = {'com': players} # elif len(players) > 1: # context = {'com': 'Too broad - multiple players share parts of this name'} else: # context = {'com': 'No player found'} context = {'com': []} # case 6: number only elif (request.POST.get("name_field") == '' and request.POST.get("number_field") != ''\ and request.POST.get("team_field") == ''): num = request.POST.get("number_field") number_list_dict = statsapi.lookup_player(num, season=2019) players = [] for player in number_list_dict: try: if player['primaryNumber'] == num: players.append(player) except: pass if len(players) != 0: context = {'com': players} # elif len(players) > 0: # context = {'com': 'Too broad - add player information'} else: # context = {'com': 'No player found - no player holds this jersey number'} context = {'com': []} # case 7: number, team elif (request.POST.get("name_field") == '' and request.POST.get("number_field") != ''\ and request.POST.get("team_field") != ''): num = request.POST.get("number_field") number_list_dict = statsapi.lookup_player(num, season=2019) team = request.POST.get("team_field") team_list_dict = statsapi.lookup_team(team) if len(team_list_dict) == 0: # context = {'com': 'Inconsistent information - team does not exist'} context = {'com': []} elif len(number_list_dict) == 0: # context = {'com': 'No player found - no player holds this jersey number'} context = {'com': []} else: players = [] for player in number_list_dict: try: if player['primaryNumber'] == num: players.append(player) except: pass players2 = [] for player in players: if len(team_list_dict) == 1: team_id = team_list_dict[0]['id'] if player['currentTeam']['id'] == team_id: players2.append(player) else: # len(team_list_dict) > 1 for ind_team in team_list_dict: team_id = ind_team['id'] if player['currentTeam']['id'] == team_id: players2.append(player) if len(players2) != 0: context = {'com': players2} # elif len(players2) > 1: #lowkey impossible for multiple numbers on same team # context = {'com': 'Too broad - multiple players share this jersey number'} else: # context = {'com': 'No player found - no player on this team holds this jersey number'} context = {'com': []} # case 8: team only elif (request.POST.get("name_field") == '' and request.POST.get("number_field") == ''\ and request.POST.get("team_field") != ''): team = request.POST.get("team_field") team_list_dict = statsapi.lookup_team(team) if len(team_list_dict) == 0: # context = {'com': 'Inconsistent information - team does not exist'} context = {'com': []} else: players = [] for team in team_list_dict: team_id = team['id'] all_players = statsapi.lookup_player(team_id, season=2019) for player in all_players: if player['currentTeam']['id'] == team_id: players.append(player) context = {'com': players} for player in context['com']: player['useName'] = player['useName'].lower() player['lastName'] = player['lastName'].lower() team_dict = statsapi.lookup_team(player['currentTeam']['id']) team_name = team_dict[0]['name'] player['teamName'] = team_name return render(request, "model1/results.html", context) else: # context = {'com': PlayerInput()} return render(request, "model1/home.html", {})
def run(self): self.dbc.execute( 'SELECT comment_id,date,reply FROM comments ORDER BY date DESC LIMIT 500;' ) comment_ids = self.dbc.fetchall() for cid in comment_ids: self.comments.update({ cid[0]: { 'date': cid[1], 'reply': cid[2], 'historical': True } }) while True: print('Monitoring comments in the following subreddit(s): {}...'. format(self.sub)) for comment in self.r.subreddit( self.sub).stream.comments(pause_after=self.pause_after): if not comment: break #take a break to delete downvoted replies if comment.id in self.comments.keys(): print('Already processed comment {}'.format(comment.id)) continue replyText = '' if str(self.r.user.me()).lower() in comment.body.lower( ) and comment.author != self.r.user.me(): self.comments.update({ comment.id: { 'sub': comment.subreddit, 'author': comment.author, 'post': comment.submission, 'date': time.time(), 'cmd': [], 'errors': [] } }) self.dbc.execute( "insert or ignore into comments (comment_id, sub, author, post, date) values (?, ?, ?, ?, ?);", (str(comment.id), str(comment.subreddit), str(comment.author), str( comment.submission), str(comment.created_utc))) print('({}) {} - {}: {}'.format(comment.subreddit, comment.id, comment.author, comment.body)) if 'help' in comment.body.lower(): self.comments[comment.id]['cmd'].append('help') replyText += 'Invoke me by including my name anywhere in your comment.\n\n' replyText += 'Include an available command in your comment: [help, score, careerstats, seasonstats, standings, winprob], ' replyText += 'along with the subject in curly brackets.\n\n' replyText += 'For stats commands, you can also include the type: [hitting, pitching, fielding].\n\n' replyText += 'For example, `careerstats {hamels} pitching` or `score {phillies}` or `standings {nle}` ' replyText += '(try including the word wildcard when asking for standings).\n\n' replyText += 'I am currently monitoring the following subreddit(s): ' + self.sub + '.' if 'seasonstats' in comment.body.lower(): self.comments[comment.id]['cmd'].append('seasonstats') if replyText != '': replyText += '\n\n*****\n\n' try: who = statsapi.lookup_player( comment.body[comment.body.find('{') + 1:comment.body.find('}' )])[0]['id'] what = [] if 'hitting' in comment.body.lower( ) or 'batting' in comment.body.lower(): what.append('hitting') if 'pitching' in comment.body.lower(): what.append('pitching') if 'fielding' in comment.body.lower(): what.append('fielding') if len(what): stats = statsapi.player_stats( who, str(what).replace('\'', '').replace(' ', ''), 'season') else: stats = statsapi.player_stats(who, type='season') replyText += '\n ' + stats.replace( '\n', '\n ') except Exception as e: print( 'Error generating response for seasonstats: {}' .format(e)) self.comments[comment.id]['errors'].append( 'Error generating response for seasonstats: {}' .format(e)) if 'careerstats' in comment.body.lower(): self.comments[comment.id]['cmd'].append('careerstats') if replyText != '': replyText += '\n\n*****\n\n' try: who = self.lookup_player( comment.body[comment.body.find('{') + 1:comment.body.find('}')]) what = [] if 'hitting' in comment.body.lower( ) or 'batting' in comment.body.lower(): what.append('hitting') if 'pitching' in comment.body.lower(): what.append('pitching') if 'fielding' in comment.body.lower(): what.append('fielding') if len(what): stats = statsapi.player_stats( who, str(what).replace('\'', '').replace(' ', ''), 'career') else: stats = statsapi.player_stats(who, type='career') replyText += '\n ' + stats.replace( '\n', '\n ') except Exception as e: print( 'Error generating response for careerstats: {}' .format(e)) self.comments[comment.id]['errors'].append( 'Error generating response for careerstats: {}' .format(e)) if 'nextgame' in comment.body.lower(): self.comments[comment.id]['cmd'].append('nextgame') if replyText != '': replyText += '\n\n*****\n\n' try: who = statsapi.lookup_team( comment.body[comment.body.find('{') + 1:comment.body.find('}' )])[0]['id'] next = statsapi.next_game(who) game = statsapi.schedule(game_id=next) replyText += game[0]['summary'] except Exception as e: print('Error generating response for nextgame: {}'. format(e)) self.comments[comment.id]['errors'].append( 'Error generating response for nextgame: {}'. format(e)) if 'lastgame' in comment.body.lower(): self.comments[comment.id]['cmd'].append('lastgame') if replyText != '': replyText += '\n\n*****\n\n' try: who = statsapi.lookup_team( comment.body[comment.body.find('{') + 1:comment.body.find('}' )])[0]['id'] last = statsapi.last_game(who) game = statsapi.schedule(game_id=last) replyText += game[0]['summary'] except Exception as e: print('Error generating response for lastgame: {}'. format(e)) self.comments[comment.id]['errors'].append( 'Error generating response for lastgame: {}'. format(e)) if 'winprob' in comment.body.lower(): self.comments[comment.id]['cmd'].append('winprob') if replyText != '': replyText += '\n\n*****\n\n' try: who = statsapi.lookup_team( comment.body[comment.body.find('{') + 1:comment.body.find('}' )])[0]['id'] game = statsapi.schedule(team=who)[0] contextMetrics = statsapi.get( 'game_contextMetrics', {'gamePk': game['game_id']}) away_win_prob = contextMetrics.get( 'awayWinProbability', '-') home_win_prob = contextMetrics.get( 'homeWinProbability', '-') replyText += '\n ' + game['summary'] + '\n' replyText += ' Current win probabilities: ' + game[ 'away_name'] + ' ' + str( away_win_prob ) + '%, ' + game['home_name'] + ' ' + str( home_win_prob) + '%' except Exception as e: print('Error generating response for winprob: {}'. format(e)) self.comments[comment.id]['errors'].append( 'Error generating response for winprob: {}'. format(e)) if 'score' in comment.body.lower( ) and 'Current win probabilities' not in replyText: self.comments[comment.id]['cmd'].append('score') if replyText != '': replyText += '\n\n*****\n\n' try: who = comment.body[comment.body.find('{') + 1:comment.body.find('}')].lower( ) if who in [ 'nle', 'nlw', 'nlc', 'ale', 'alw', 'alc', 'all' ]: todaysGames = statsapi.get( 'schedule', { 'fields': 'dates,date,games,gamePk,teams,away,team,division,abbreviation', 'sportId': 1, 'hydrate': 'team(division)' }) gamePks = '' for i in ( x['gamePk'] for x in todaysGames['dates'][0]['games'] if who == 'all' or x['teams']['away'] ['team']['division']['abbreviation'].lower( ) == who or x['teams']['home']['team'] ['division']['abbreviation'].lower() == who ): gamePks += '{},'.format(i) if len(gamePks): if gamePks[-1] == ',': gamePks = gamePks[:-1] games = statsapi.schedule(game_id=gamePks) for game in games: replyText += '\n ' + game['summary'] else: who = statsapi.lookup_team( comment.body[comment.body.find('{') + 1:comment.body.find('}')] )[0]['id'] game = statsapi.schedule(team=who) replyText += game[0]['summary'] except Exception as e: print('Error generating response for score: {}'. format(e)) self.comments[comment.id]['errors'].append( 'Error generating response for score: {}'. format(e)) if 'standings' in comment.body.lower(): self.comments[comment.id]['cmd'].append('standings') if replyText != '': replyText += '\n\n*****\n\n' try: if comment.body.find('{') != -1: who = comment.body[comment.body.find('{') + 1:comment.body. find('}')].lower() else: who = 'all' wc = True if any( True for x in ['wc', 'wildcard', 'wild card'] if x in comment.body) else False if who == 'all': standings = statsapi.standings( date=datetime.today().strftime('%m/%d/%Y'), include_wildcard=wc) elif who in [ 'nle', 'nlw', 'nlc', 'ale', 'alw', 'alc' ]: standings = statsapi.standings( date=datetime.today().strftime('%m/%d/%Y'), division=who, include_wildcard=wc) elif who in ['nl', 'al']: leagueId = 103 if who == 'al' else 104 standings = statsapi.standings( leagueId=leagueId, date=datetime.today().strftime('%m/%d/%Y'), include_wildcard=wc) replyText += '\n {}'.format( standings.replace('\n', '\n ')) except Exception as e: print( 'Error generating response for standings: {}'. format(e)) self.comments[comment.id]['errors'].append( 'Error generating response for standings: {}'. format(e)) if replyText != '': try: latest_reply = comment.reply(replyText + self.replyFooter) self.comments[comment.id].update( {'reply': latest_reply}) latest_reply.disable_inbox_replies() print( 'Replied with comment id {} and disabled inbox replies.' .format(latest_reply)) self.dbc.execute( "update comments set cmd=?,reply=? where comment_id=?;", (str(self.comments[comment.id]['cmd']), str(latest_reply), str(comment.id))) except Exception as e: print( 'Error replying to comment or disabling inbox replies: {}' .format(e)) self.comments[comment.id]['errors'].append( 'Error submitting comment or disabling inbox replies: {}' .format(e)) if len(self.comments[comment.id].get('errors')): self.dbc.execute( "update comments set errors=? where comment_id=?;", (str(self.comments[comment.id].get('errors')), str(comment.id))) self.db.commit() print('Checking for downvotes on {} replies...'.format( sum(1 for x in self.comments if self.comments[x].get('reply') and not self.comments[x].get('removed') and not self.comments[x].get('historical')))) for x in (x for x in self.comments if self.comments[x].get('reply') and not self.comments[x].get('removed') and not self.comments[x].get('historical')): if self.comments[x]['reply'].score <= self.del_threshold: print( 'Deleting comment {} with score ({}) at or below threshold ({})...' .format(self.comments[x]['reply'], self.comments[x]['reply'].score, self.del_threshold)) try: self.comments[x]['reply'].delete() self.comments[x].update({'removed': time.time()}) self.dbc.execute( "update comments set removed=? where comment_id=?;", (str(self.comments[x].get('removed')), str(x))) except Exception as e: print('Error deleting downvoted comment: {}'.format(e)) self.comments[x]['errors'].append( 'Error deleting downvoted comment: {}'.format(e)) self.db.commit() return
# away_probable_pitcher # home_pitcher_note # away_pitcher_note # away_score # home_score # current_inning # inning_state # venue_id # venue_name # summary # don't touch below here API_DATE_FORMAT = '%Y-%m-%dT%H:%M:%SZ' NOW = UTC.localize(datetime.utcnow()) found_teams = statsapi.lookup_team(TEAM_NAME) team_id = None if len(found_teams) != 1: print('no teams found or too many found') else: team_id = found_teams[0]['id'] schedule = statsapi.schedule( start_date=datetime.today().strftime("%Y-%m-%d"), end_date=(datetime.today() + timedelta(days=10)).strftime("%Y-%m-%d"), team=team_id) def is_utc_date_in_future(date_str): try:
async def playoff_Series_Embed(self, series, message): try: # Create a list of the games in the series seriesGames = series['games'] # Get the game ID of the last game in the series #lastGameId = seriesGames[len(seriesGames) - 1]['gamePk'] #contextParams = {'gamePk': lastGameId} #game_contextMetrics = statsapi.get(endpoint='game_contextMetrics', params=contextParams) homeRecordString = '(' + str( seriesGames[0]['teams']['home']['leagueRecord']['wins']) + '-' + str( seriesGames[0]['teams']['home']['leagueRecord']['losses']) + ')' awayRecordString = '(' + str( seriesGames[0]['teams']['away']['leagueRecord']['wins']) + '-' + str( seriesGames[0]['teams']['away']['leagueRecord']['losses']) + ')' #homeRecordString = '(' + str(game_contextMetrics['game']['teams']['home']['leagueRecord']['wins']) + '-' + str( # game_contextMetrics['game']['teams']['home']['leagueRecord']['losses']) + ')' #awayRecordString = '(' + str(game_contextMetrics['game']['teams']['away']['leagueRecord']['wins']) + '-' + str( # game_contextMetrics['game']['teams']['away']['leagueRecord']['losses']) + ')' titleString = seriesGames[0]['seriesDescription'] + '\n**' + \ seriesGames[0]['teams']['home']['team']['name'] + homeRecordString + '** vs **' \ + seriesGames[0]['teams']['away']['team']['name'] + awayRecordString + '**' # game_contextMetrics['game']['teams']['home']['leagueRecord']['wins'] playoffEmbed = discord.Embed() playoffEmbed.title = titleString playoffEmbed.type = 'rich' playoffEmbed.color = discord.Color.dark_blue() for games in seriesGames: # Get the team names from the game homeTeam = statsapi.lookup_team(games['teams']['home']['team']['name']) awayTeam = statsapi.lookup_team(games['teams']['away']['team']['name']) # Get the short team names # If the team isn't decided yet then pull it from the response if homeTeam: homeTeamShort = homeTeam[0]['fileCode'].upper() else: homeTeamShort = games['teams']['home']['team']['name'] if awayTeam: awayTeamShort = awayTeam[0]['fileCode'].upper() else: awayTeamShort = games['teams']['away']['team']['name'] if games['status']['detailedState'] == 'Final' or games['status']['detailedState'] == 'Game Over': homeScore = games['teams']['home']['score'] homeScoreString = str(homeScore) awayScore = games['teams']['away']['score'] awayScoreString = str(awayScore) if homeScore > awayScore: homeScoreString = '**' + homeScoreString + '**' elif awayScore > homeScore: awayScoreString = '**' + awayScoreString + '**' finalGameString = homeTeamShort + ' ' + homeScoreString + ' - ' + awayTeamShort + ' ' + awayScoreString + ' **F**' # \n' + \ # homeTeamShort + '(' + str(games['teams']['home']['leagueRecord']['wins']) + '-' + str(games['teams']['home']['leagueRecord']['losses']) + ') - ' + \ # awayTeamShort + '(' + str(games['teams']['away']['leagueRecord']['wins']) + '-' + str(games['teams']['away']['leagueRecord']['losses']) + ')' playoffEmbed.add_field(name='Game ' + str(games['seriesGameNumber']), value=finalGameString, inline=False) elif games['status']['detailedState'] == 'Scheduled' or games['status']['detailedState'] == 'Pre-Game': gameLocalTime = self.commonFunctions.get_Local_Time(games['gameDate']) valueString = awayTeamShort + ' vs ' + homeTeamShort + '\n' valueString = valueString + calendar.day_name[gameLocalTime.weekday()] + '\n' + gameLocalTime.strftime( '%m/%d/%Y') + ' at ' + gameLocalTime.strftime('%-I:%M%p') + ' EST' if games['ifNecessary'] == 'N': playoffEmbed.add_field(name='Game ' + str(games['seriesGameNumber']), value=valueString, inline=False) else: playoffEmbed.add_field(name=games['description'] + ' (If Necessary)', value=valueString, inline=False) elif games['status']['detailedState'] == 'In Progress' or games['status']['detailedState'] == 'Live': homeScore = games['teams']['home']['score'] homeScoreString = str(homeScore) awayScore = games['teams']['away']['score'] awayScoreString = str(awayScore) if homeScore > awayScore: homeScoreString = '**' + homeScoreString + '**' elif awayScore > homeScore: awayScoreString = '**' + awayScoreString + '**' liveGameString = awayTeamShort + ' ' + awayScoreString + ' - ' + homeTeamShort + ' ' + homeScoreString + '\n' + \ games['status']['detailedState'] playoffEmbed.add_field(name='Game ' + str(games['seriesGameNumber']) + '\nLive Game', value=liveGameString, inline=False) await message.channel.send(embed=playoffEmbed) except ConnectionError as ce: print('DEBUG: Request failed in playoff_Series_Embed | {}'.format(ce))
def get_team_name(id): return statsapi.lookup_team(id).pop(0)['teamName']
def Athletics(self): self.athletics = statsapi.lookup_team('oak')['id'] self.athleticsid = athletics[0]['id']
def lookupTeamInfo(self, id): teamInfoList = statsapi.lookup_team(id) if len(teamInfoList) != 1: print("Team id", id, "cannot be resolved to a single team") return return teamInfoList[0]
def home_game_check(gameid, teamid): if statsapi.schedule( game_id=gameid)[0]['away_name'] == statsapi.lookup_team( teamid)[0]['name']: print('There is no home game!')
import statsapi from datetime import datetime, date, timezone, timedelta import pytz # Only care about the Mets metsId = (statsapi.lookup_team("NYM"))[0]['id'] date_format = "%Y-%m-%dT%H:%M:%SZ" est_timezone = pytz.timezone('America/New_York') def getStartTime(game_datetime): d = datetime.fromisoformat(game_datetime[:-1]).replace(tzinfo=pytz.utc) # we need to strip 'Z' before parsing return d.astimezone(est_timezone).strftime('%I:%M %p') def getDailyMetsGameDetails(): try: gameDetails = statsapi.schedule(date=None, start_date=datetime.today().strftime('%Y-%m-%d'), end_date=None, team=metsId, opponent="", sportId=1, game_id=None)[0] except IndexError as e: return "There's no Mets game today." metsAreHome = True if gameDetails['home_name'] == "New York Mets" else False opposingTeam = gameDetails['away_name'] if metsAreHome else gameDetails['home_name'] # Get start time startTime = getStartTime(gameDetails['game_datetime']) # Mets starting pitcher metsStartingPitcher = gameDetails['home_probable_pitcher'] if (metsAreHome) else gameDetails['away_probable_pitcher'] return f"\nStart time is {startTime}. The Mets are playing the {opposingTeam}. Today's pitcher is {metsStartingPitcher}."
import statsapi from box import Box from player import Player MLB_TEAMS = [ t for t in statsapi.get("teams", {})["teams"] if t["sport"]["name"] == "Major League Baseball" ] ABRV_TO_ID = {t["abbreviation"]: t["id"] for t in MLB_TEAMS} ID_TO_ABRV = {t["id"]: t["abbreviation"] for t in MLB_TEAMS} class Team: def __init__(self, roster): self.fielders = [player for player in roster if player.position.code != "1"] self.pitchers = [player for player in roster if player.position.code == "1"] cubs = statsapi.lookup_team(ABRV_TO_ID["CHC"]) cubs_2016 = statsapi.get( "team_roster", {"teamId": ABRV_TO_ID["CHC"], "rosterType": "fullSeason", "season": 2016}, ) boxed_cubs_players = [Box(**player) for player in cubs_2016["roster"]] cubs_players = [Player(player) for player in boxed_cubs_players] CUBS = Team(cubs_players)
async def scheduled_Game_Embed(self, game, message): # If for some reason we get a list, take the first object if type(game) == list: game = game[0] # Get the UTC datetime string gameTimeLocal = self.commonFunctions.get_Local_Time(game['game_datetime']) homeTeam = statsapi.lookup_team(game['home_name']) awayTeam = statsapi.lookup_team(game['away_name']) # Get the game type gameType = game['game_type'] ''' [{'id': 'S', 'description': 'Spring Training'}, {'id': 'R', 'description': 'Regular season'}, {'id': 'F', 'description': 'Wild Card Game'}, {'id': 'D', 'description': 'Division Series'}, {'id': 'L', 'description': 'League Championship Series'}, {'id': 'W', 'description': 'World Series'}, {'id': 'C', 'description': 'Championship'}, {'id': 'N', 'description': 'Nineteenth Century Series'}, {'id': 'P', 'description': 'Playoffs'}, {'id': 'A', 'description': 'All-Star game'}, {'id': 'I', 'description': 'Intrasquad'}, {'id': 'E', 'description': 'Exhibition'}] ''' # contextParams = {'gamePk': game['game_id']} # game_contextMetrics = statsapi.get(endpoint='game_contextMetrics', params=contextParams) # game_contextMetrics = statsapi.schedule(game_id=game['game_id']) #print(game_contextMetrics) # game_contextMetrics = game_contextMetrics[0] # gameType = game_contextMetrics['gameType'] # If the teams have been announced then read the info if len(homeTeam) > 0: homeTeamShort = homeTeam[0]['fileCode'].upper() # Get the probable pitchers homeProbable = game['home_probable_pitcher'] homeNote = game['home_pitcher_note'] else: homeTeamShort = 'N/A' homeProbable = 'N/A' homeNote = 'N/A' if len(awayTeam) > 0: awayTeamShort = awayTeam[0]['fileCode'].upper() # Get the probable pitchers awayProbable = game['away_probable_pitcher'] awayNote = game['away_pitcher_note'] else: awayTeamShort = 'N/A' awayProbable = 'N/A' awayNote = 'N/A' # Create the embed object scheduledEmbed = discord.Embed() # Skipping playoff displays for now until game_contextMetrics is fixed or the info can be found elsewhere scheduledEmbed.title = '**' + game['away_name'] + '** vs **' + game['home_name'] + '**' ''' # Regular Season if gameType == 'R': scheduledEmbed.title = '**' + game['away_name'] + '** vs **' + game['home_name'] + '**' # Wildcard elif gameType == 'F': #contextParams = {'gamePk': game['game_id']} #game_contextMetrics = statsapi.get(endpoint='game_contextMetrics', params=contextParams) # Check if the game is a tiebreaker if game['tiebreaker'] == 'N': scheduledEmbed.title = '**Wildcard Game**\n\n**' + game['away_name'] + '** vs **' + game[ 'home_name'] + '**' else: scheduledEmbed.title = '**Wildcard Tiebreaker Game**\n\n**' + game['away_name'] + '** vs **' + game[ 'home_name'] + '**' # Division Series elif gameType == 'D': #contextParams = {'gamePk': game['game_id']} #game_contextMetrics = statsapi.get(endpoint='game_contextMetrics', params=contextParams) homeRecordString = str(game['teams']['home']['leagueRecord']['wins']) + '-' + str( game['teams']['home']['leagueRecord']['losses']) awayRecordString = str(game['teams']['away']['leagueRecord']['wins']) + '-' + str( game['teams']['away']['leagueRecord']['losses']) scheduledEmbed.title = '**Division Series Game ' + str( game['seriesGameNumber']) + '**\n\n**' + game[ 'away_name'] + '**(' + awayRecordString + ') vs ' + '**' + game[ 'home_name'] + '**(' + homeRecordString + ')' # League Championship Series elif gameType == 'L': #contextParams = {'gamePk': game['game_id']} #game_contextMetrics = statsapi.get(endpoint='game_contextMetrics', params=contextParams) homeRecordString = str(game['teams']['home']['leagueRecord']['wins']) + '-' + str( game['teams']['home']['leagueRecord']['losses']) awayRecordString = str(game['teams']['away']['leagueRecord']['wins']) + '-' + str( game['teams']['away']['leagueRecord']['losses']) scheduledEmbed.title = '**League Championship Series Game ' + str( game['seriesGameNumber']) + '**\n\n**' + game[ 'away_name'] + '**(' + awayRecordString + ') vs ' + '**' + game[ 'home_name'] + '**(' + homeRecordString + ')' # World Series elif gameType == 'W': #contextParams = {'gamePk': game['game_id']} #game_contextMetrics = statsapi.get(endpoint='game_contextMetrics', params=contextParams) homeRecordString = str(game['teams']['home']['leagueRecord']['wins']) + '-' + str( game['teams']['home']['leagueRecord']['losses']) awayRecordString = str(ggame['teams']['away']['leagueRecord']['wins']) + '-' + str( game['teams']['away']['leagueRecord']['losses']) scheduledEmbed.title = '**World Series Game ' + str( game['seriesGameNumber']) + '**\n\n**' + game[ 'away_name'] + '**(' + awayRecordString + ') vs ' + '**' + game[ 'home_name'] + '**(' + homeRecordString + ')' # Spring Training elif gameType == 'S': scheduledEmbed.title = '**Spring Training**\n\n**' + game['away_name'] + '** vs **' + game[ 'home_name'] + '**' else: scheduledEmbed.title = '**' + game['away_name'] + '** vs **' + game['home_name'] + '**' ''' scheduledEmbed.type = 'rich' # testEmbed.colour = scheduledEmbed.color = discord.Color.dark_blue() scheduledEmbed.add_field(name='Game Status:', value=game['status'], inline=False) # scoreEmbed.add_field(name='NAME', value='VALUE', inline=False) scheduledEmbed.add_field(name='Start Time:', value=gameTimeLocal.strftime('%-I:%M%p' + ' ET'), inline=False) # Check for returned values if not homeProbable: homeProbable = 'Unannounced' scheduledEmbed.add_field(name=homeTeamShort + ' Probable:', value=homeProbable, inline=True) # Check for returned values if not awayProbable: awayProbable = 'Unannounced' scheduledEmbed.add_field(name=awayTeamShort + ' Probable:', value=awayProbable, inline=True) # Check for returned values if not homeNote: homeNote = 'None' scheduledEmbed.add_field(name='Home Notes', value=homeNote, inline=False) # Check for returned values if not awayNote: awayNote = 'None' scheduledEmbed.add_field(name='Away Notes', value=awayNote, inline=False) await message.channel.send(content='Scheduled Game on ' + gameTimeLocal.strftime('%m/%d/%Y') + ':', embed=scheduledEmbed)
def run(self, bot=None): if not self.sub: log.error("No subreddit specified!") bot.STOP = True return self.dbc.execute( "SELECT comment_id, date, reply, errors, removed FROM {} ORDER BY date DESC LIMIT 500;" .format(self.dbTable)) comment_ids = self.dbc.fetchall() for cid in comment_ids: self.comments.update({ cid[0]: { "date": cid[1], "reply": self.r.comment(cid[2]) if cid[2] else None, "errors": cid[3], "removed": cid[4], "historical": True, } }) log.debug("Loaded {} comments from db.".format(len(self.comments))) log.info( "Monitoring comments in the following subreddit(s): {}...".format( self.sub)) while True: if bot and bot.STOP: log.info("Received stop signal...") return try: for comment in self.r.subreddit( self.sub).stream.comments(pause_after=self.pauseAfter): if bot and bot.STOP: log.info("Received stop signal...") return if not comment: break # Take a break to delete downvoted replies replyText = "" if (str(self.r.user.me()).lower() in comment.body.lower() and comment.author != self.r.user.me()): if comment.id in self.comments.keys(): log.debug("Already processed comment {}".format( comment.id)) continue elif ( comment.created_utc <= time.time() - 60 * 60 * 24 * self.historicalDays - 3600 ): # Add 1 hour buffer to ensure recent comments are processed log.debug( "Stream returned comment {} which is older than the HISTORICAL_DAYS setting ({}), ignoring..." .format(comment.id, self.historicalDays)) self.comments.update({ comment.id: { "sub": comment.subreddit, "author": comment.author, "post": comment.submission, "date": time.time(), "cmd": [], "errors": [], } }) continue self.comments.update({ comment.id: { "sub": comment.subreddit, "author": comment.author, "post": comment.submission, "date": time.time(), "cmd": [], "errors": [], } }) self.dbc.execute( "insert or ignore into {} (comment_id, sub, author, post, date) values (?, ?, ?, ?, ?);" .format(self.dbTable), ( str(comment.id), str(comment.subreddit), str(comment.author), str(comment.submission), str(comment.created_utc), ), ) log.debug("({}) {} - {}: {}".format( comment.subreddit, comment.id, comment.author, comment.body, )) if "help" in comment.body.lower(): self.comments[comment.id]["cmd"].append("help") replyText += "I am a bot that can provide MLB data, but I am not affiliated with MLB or any team.\n\n" replyText += "Invoke me by including my name anywhere in your comment.\n\n" replyText += "Include an available command in your comment: [help, score, careerstats, lastgame, nextgame, seasonstats, standings, winprob, rundiff], " replyText += "along with the subject in curly brackets.\n\n" replyText += "For stats commands, you can also include the type: [hitting, pitching, fielding].\n\n" replyText += "For example, `careerstats {hamels} pitching` or `score {phillies}` or `standings {nle}` " replyText += "(try including the word wildcard when asking for standings).\n\n" replyText += ( "I am currently monitoring the following subreddit(s): " + self.sub.replace("+", ", ") + ".") if "seasonstats" in comment.body.lower(): self.comments[comment.id]["cmd"].append( "seasonstats") if replyText != "": replyText += "\n\n*****\n\n" try: who = statsapi.lookup_player( comment.body[comment.body.find("{") + 1:comment.body.find("}")] )[0]["id"] what = [] if ("hitting" in comment.body.lower() or "batting" in comment.body.lower()): what.append("hitting") if "pitching" in comment.body.lower(): what.append("pitching") if "fielding" in comment.body.lower(): what.append("fielding") if len(what): stats = statsapi.player_stats( who, str(what).replace("'", "").replace(" ", ""), "season", ) else: stats = statsapi.player_stats( who, type="season") replyText += "\n " + stats.replace( "\n", "\n ") except Exception as e: log.error( "Error generating response for seasonstats: {}" .format(e)) self.comments[comment.id]["errors"].append( "Error generating response for seasonstats: {}" .format(e)) if "careerstats" in comment.body.lower(): self.comments[comment.id]["cmd"].append( "careerstats") if replyText != "": replyText += "\n\n*****\n\n" try: who = self.lookup_player( comment.body[comment.body.find("{") + 1:comment.body.find("}")]) what = [] if ("hitting" in comment.body.lower() or "batting" in comment.body.lower()): what.append("hitting") if "pitching" in comment.body.lower(): what.append("pitching") if "fielding" in comment.body.lower(): what.append("fielding") if len(what): stats = statsapi.player_stats( who, str(what).replace("'", "").replace(" ", ""), "career", ) else: stats = statsapi.player_stats( who, type="career") replyText += "\n " + stats.replace( "\n", "\n ") except Exception as e: log.error( "Error generating response for careerstats: {}" .format(e)) self.comments[comment.id]["errors"].append( "Error generating response for careerstats: {}" .format(e)) if "nextgame" in comment.body.lower(): self.comments[comment.id]["cmd"].append("nextgame") if replyText != "": replyText += "\n\n*****\n\n" try: who = statsapi.lookup_team( comment.body[comment.body.find("{") + 1:comment.body.find("}")] )[0]["id"] next = statsapi.next_game(who) game = statsapi.schedule(game_id=next) replyText += game[0]["summary"] except Exception as e: log.error( "Error generating response for nextgame: {}" .format(e)) self.comments[comment.id]["errors"].append( "Error generating response for nextgame: {}" .format(e)) if "lastgame" in comment.body.lower(): self.comments[comment.id]["cmd"].append("lastgame") if replyText != "": replyText += "\n\n*****\n\n" try: who = statsapi.lookup_team( comment.body[comment.body.find("{") + 1:comment.body.find("}")] )[0]["id"] last = statsapi.last_game(who) game = statsapi.schedule(game_id=last) replyText += game[0]["summary"] except Exception as e: log.error( "Error generating response for lastgame: {}" .format(e)) self.comments[comment.id]["errors"].append( "Error generating response for lastgame: {}" .format(e)) if "winprob" in comment.body.lower(): self.comments[comment.id]["cmd"].append("winprob") if replyText != "": replyText += "\n\n*****\n\n" try: who = statsapi.lookup_team( comment.body[comment.body.find("{") + 1:comment.body.find("}")] )[0]["id"] game = statsapi.schedule(team=who)[0] contextMetrics = statsapi.get( "game_contextMetrics", {"gamePk": game["game_id"]}) away_win_prob = contextMetrics.get( "awayWinProbability", "-") home_win_prob = contextMetrics.get( "homeWinProbability", "-") replyText += "\n " + game["summary"] + "\n" replyText += ( " Current win probabilities: " + game["away_name"] + " " + str(away_win_prob) + "%, " + game["home_name"] + " " + str(home_win_prob) + "%") except Exception as e: log.error( "Error generating response for winprob: {}" .format(e)) self.comments[comment.id]["errors"].append( "Error generating response for winprob: {}" .format(e)) if ("score" in comment.body.lower() and "Current win probabilities" not in replyText): self.comments[comment.id]["cmd"].append("score") if replyText != "": replyText += "\n\n*****\n\n" try: who = comment.body[comment.body.find("{") + 1:comment.body. find("}")].lower() if who in [ "nle", "nlw", "nlc", "ale", "alw", "alc", "all", ]: todaysGames = statsapi.get( "schedule", { "fields": "dates,date,games,gamePk,teams,away,team,division,abbreviation", "sportId": 1, "hydrate": "team(division)", }, ) gamePks = "" for i in (x["gamePk"] for x in todaysGames["dates"][0]["games"] if who == "all" or x["teams"] ["away"]["team"]["division"] ["abbreviation"].lower() == who or x["teams"]["home"]["team"] ["division"] ["abbreviation"].lower() == who): gamePks += "{},".format(i) if len(gamePks): if gamePks[-1] == ",": gamePks = gamePks[:-1] games = statsapi.schedule(game_id=gamePks) for game in games: replyText += "\n " + game["summary"] else: who = statsapi.lookup_team( comment.body[comment.body.find("{") + 1:comment.body.find("}")] )[0]["id"] game = statsapi.schedule(team=who) replyText += game[0]["summary"] except Exception as e: log.error( "Error generating response for score: {}". format(e)) self.comments[comment.id]["errors"].append( "Error generating response for score: {}". format(e)) if "standings" in comment.body.lower(): self.comments[comment.id]["cmd"].append( "standings") if replyText != "": replyText += "\n\n*****\n\n" try: if comment.body.find("{") != -1: who = comment.body[comment.body.find("{") + 1:comment.body. find("}")].lower() else: who = "all" wc = (True if any( True for x in ["wc", "wildcard", "wild card"] if x in comment.body) else False) if who == "all": standings = statsapi.standings( date=datetime.today().strftime( "%m/%d/%Y"), include_wildcard=wc, ) elif who in [ "nle", "nlw", "nlc", "ale", "alw", "alc" ]: standings = statsapi.standings( date=datetime.today().strftime( "%m/%d/%Y"), division=who, include_wildcard=wc, ) elif who in ["nl", "al"]: leagueId = 103 if who == "al" else 104 standings = statsapi.standings( leagueId=leagueId, date=datetime.today().strftime( "%m/%d/%Y"), include_wildcard=wc, ) replyText += "\n {}".format( standings.replace("\n", "\n ")) except Exception as e: log.error( "Error generating response for standings: {}" .format(e)) self.comments[comment.id]["errors"].append( "Error generating response for standings: {}" .format(e)) if "rundiff" in comment.body.lower(): self.comments[comment.id]["cmd"].append("rundiff") if replyText != "": replyText += "\n\n*****\n\n" try: whoTeamId = None if comment.body.find("{") != -1: who = comment.body[comment.body.find("{") + 1:comment.body. find("}")].lower() else: who = None params = { "hydrate": "team(division)", "fields": "records,standingsType,teamRecords,team,name,division,id,nameShort,abbreviation,runDifferential", } if who in [ "all", "nle", "nlw", "nlc", "ale", "alw", "alc", "nl", "al", ]: if who == "all": params.update({"leagueId": "103,104"}) elif who in [ "nle", "nlw", "nlc", "ale", "alw", "alc", ]: params.update({ "leagueId": "103" if who[0] == "a" else "104" }) elif who in ["nl", "al"]: params.update({ "leagueId": "103" if who == "al" else "104" }) else: whoTeamId = statsapi.lookup_team( who)[0]["id"] teamInfo = statsapi.get( "team", {"teamId": whoTeamId}) whoDivId = teamInfo["teams"][0][ "division"]["id"] whoLeagueId = teamInfo["teams"][0][ "league"]["id"] params.update({"leagueId": whoLeagueId}) r = statsapi.get("standings", params) rundiff = "" divisions = {} for y in r["records"]: for x in ( x for x in y["teamRecords"] if who == "all" or who == x["team"] ["division"]["abbreviation"].lower() or (whoTeamId and whoDivId == x["team"] ["division"]["id"]) or who in ["al", "nl"]): if (x["team"]["division"]["id"] not in divisions.keys()): divisions.update({ x["team"]["division"]["id"]: { "div_name": x["team"]["division"] ["name"], "teams": [], } }) team = { "name": x["team"]["name"], "run_diff": x["runDifferential"], } if (whoTeamId == x["team"]["id"] or not whoTeamId): divisions[x["team"]["division"][ "id"]]["teams"].append(team) for div in divisions.values(): if not whoTeamId: rundiff += div["div_name"] + "\n" for t in div["teams"]: rundiff += "{name:<21}: {run_diff:^5} run(s)\n".format( **t) rundiff += "\n" replyText += "\n {}".format( rundiff.replace("\n", "\n ")) except Exception as e: log.error( "Error generating response for rundiff: {}" .format(e)) self.comments[comment.id]["errors"].append( "Error generating response for rundiff: {}" .format(e)) if replyText != "": try: latest_reply = comment.reply( replyText + "\n\n" + self.replyFooter if len(self.replyFooter) > 0 else "") self.comments[comment.id].update( {"reply": latest_reply}) latest_reply.disable_inbox_replies() log.info( "Replied with comment id {} and disabled inbox replies." .format(latest_reply)) self.dbc.execute( "update {} set cmd=?,reply=? where comment_id=?;" .format(self.dbTable), ( str(self.comments[comment.id]["cmd"]), str(latest_reply), str(comment.id), ), ) except Exception as e: log.error( "Error replying to comment or disabling inbox replies: {}" .format(e)) self.comments[comment.id]["errors"].append( "Error submitting comment or disabling inbox replies: {}" .format(e)) if len(self.comments[comment.id].get("errors")): self.dbc.execute( "update {} set errors=? where comment_id=?;". format(self.dbTable), ( str(self.comments[comment.id].get( "errors")), str(comment.id), ), ) self.db.commit() except Exception as e: log.exception("Caught exception: {}".format(e)) raise log.debug("Checking for downvotes on {} replies...".format( sum(1 for x in self.comments if self.comments[x].get("reply") and not self.comments[x].get("removed") and float(self.comments[x].get("date")) >= time.time() - 60 * 60 * 24 * self.historicalDays))) for x in (x for x in self.comments if self.comments[x].get("reply") and not self.comments[x].get("removed") and float(self.comments[x].get("date")) >= time.time() - 60 * 60 * 24 * self.historicalDays): # print('Submission: {}, reply: {}'.format(self.r.comment(x).submission, self.comments[x]['reply'])) try: self.comments[x]["reply"].refresh() except praw.exceptions.ClientException as e: print( "Error refreshing attributes for comment reply {}: {}". format(self.comments[x]["reply"], e)) if "comment does not appear to be in the comment tree" in str( e): self.comments[x].update({"removed": time.time()}) self.dbc.execute( "update {} set removed=? where comment_id=?;". format(self.dbTable), (str(self.comments[x].get("removed")), str(x)), ) if (not self.comments[x].get("removed") and self.comments[x]["reply"].score <= self.delThreshold): log.info( "Deleting comment {} with score ({}) at or below threshold ({})..." .format( self.comments[x]["reply"], self.comments[x]["reply"].score, self.delThreshold, )) try: self.comments[x]["reply"].delete() self.comments[x].update({"removed": time.time()}) self.dbc.execute( "update {} set removed=? where comment_id=?;". format(self.dbTable), (str(self.comments[x].get("removed")), str(x)), ) except Exception as e: log.error( "Error deleting downvoted comment: {}".format(e)) self.comments[x]["errors"].append( "Error deleting downvoted comment: {}".format(e)) self.db.commit() limits = self.r.auth.limits if limits.get("remaining") < 60: log.warn( "Approaching Reddit API rate limit, sleeping for a minute... {}" .format(limits)) time.sleep(60) else: log.debug("Reddit API limits: {}".format(limits)) return
async def live_Game_Embed(self, game, message): # If for some reason we get a list, take the first object if type(game) == list: game = game[0] homeTeam = statsapi.lookup_team(game['home_name']) awayTeam = statsapi.lookup_team(game['away_name']) homeTeamShort = homeTeam[0]['fileCode'].upper() awayTeamShort = awayTeam[0]['fileCode'].upper() # print(game['game_id']) ''' homeScore = game['home_score'] homeScoreString = str(homeScore) awayScore = game['away_score'] awayScoreString = str(awayScore) if homeScore > awayScore: homeScoreString = '**' + homeScoreString + '**' elif awayScore > homeScore: awayScoreString = '**' + awayScoreString + '**' ''' # Build the content string # liveScoreString = '**' + game['home_name'] + '** vs **' + game['away_name'] + '**\n' # liveScoreString = liveScoreString + game['inning_state'] + ' ' + str(game['current_inning']) + '\n' # liveScoreString = liveScoreString + '```js\n' + statsapi.linescore(game['game_id']) + '```' contextParams = {'gamePk': game['game_id']} game_contextMetrics = statsapi.get(endpoint='game_contextMetrics', params=contextParams) gameType = game_contextMetrics['game']['gameType'] # Create the embed object scoreEmbed = discord.Embed() # Regular Season if gameType == 'R': scoreEmbed.title = '**' + game['away_name'] + '** vs **' + game['home_name'] + '**' # Wildcard elif gameType == 'F': # Check if the game is a tiebreaker if game_contextMetrics['game']['tiebreaker'] == 'N': scoreEmbed.title = '**Wildcard Game**\n\n**' + game['away_name'] + '** vs **' + game['home_name'] + '**' else: scoreEmbed.title = '**Wildcard Tiebreaker Game**\n\n**' + game['away_name'] + '** vs **' + game[ 'home_name'] + '**' # Division Series elif gameType == 'D': homeRecordString = str(game_contextMetrics['game']['teams']['home']['leagueRecord']['wins']) + '-' + str( game_contextMetrics['game']['teams']['home']['leagueRecord']['losses']) awayRecordString = str(game_contextMetrics['game']['teams']['away']['leagueRecord']['wins']) + '-' + str( game_contextMetrics['game']['teams']['away']['leagueRecord']['losses']) scoreEmbed.title = '**Division Series Game ' + str( game_contextMetrics['game']['seriesGameNumber']) + '**\n\n**' + game[ 'away_name'] + '**(' + awayRecordString + ') vs ' + '**' + game[ 'home_name'] + '**(' + homeRecordString + ')' # League Championship Series elif gameType == 'L': homeRecordString = str(game_contextMetrics['game']['teams']['home']['leagueRecord']['wins']) + '-' + str( game_contextMetrics['game']['teams']['home']['leagueRecord']['losses']) awayRecordString = str(game_contextMetrics['game']['teams']['away']['leagueRecord']['wins']) + '-' + str( game_contextMetrics['game']['teams']['away']['leagueRecord']['losses']) scoreEmbed.title = '**League Championship Series Game ' + str( game_contextMetrics['game']['seriesGameNumber']) + '**\n\n**' + game[ 'away_name'] + '**(' + awayRecordString + ') vs ' + '**' + game[ 'home_name'] + '**(' + homeRecordString + ')' # World Series elif gameType == 'W': homeRecordString = str(game_contextMetrics['game']['teams']['home']['leagueRecord']['wins']) + '-' + str( game_contextMetrics['game']['teams']['home']['leagueRecord']['losses']) awayRecordString = str(game_contextMetrics['game']['teams']['away']['leagueRecord']['wins']) + '-' + str( game_contextMetrics['game']['teams']['away']['leagueRecord']['losses']) scoreEmbed.title = '**World Series Game ' + str( game_contextMetrics['game']['seriesGameNumber']) + '**\n\n**' + game[ 'away_name'] + '**(' + awayRecordString + ') vs ' + '**' + game[ 'home_name'] + '**(' + homeRecordString + ')' # Spring Training elif gameType == 'S': homeRecordString = str(game_contextMetrics['game']['teams']['home']['leagueRecord']['wins']) + '-' + str( game_contextMetrics['game']['teams']['home']['leagueRecord']['losses']) awayRecordString = str(game_contextMetrics['game']['teams']['away']['leagueRecord']['wins']) + '-' + str( game_contextMetrics['game']['teams']['away']['leagueRecord']['losses']) scoreEmbed.title = '**Spring Training**\n\n**' + game['away_name'] + '** vs **' + game['home_name'] + '**' else: scoreEmbed.title = '**' + game['away_name'] + '** vs **' + game['home_name'] + '**' scoreEmbed.type = 'rich' scoreEmbed.color = discord.Color.dark_blue() scoreEmbed.add_field(name='**' + game['inning_state'] + ' ' + str(game['current_inning']) + '**', value='```js\n' + statsapi.linescore(game['game_id']) + '```', inline=False) # scoreEmbed.add_field(name=awayTeamShort , value=awayScoreString, inline=True) # scoreEmbed.add_field(name='Linescore', value='```' + statsapi.linescore(game['game_id']) + '```') homeWinProb = '{:.1f}'.format(game_contextMetrics['homeWinProbability']) awayWinProb = '{:.1f}'.format(game_contextMetrics['awayWinProbability']) # Show the win % scoreEmbed.add_field(name='**Win Probability**', value=awayTeamShort + ' ' + awayWinProb + ' - ' + homeTeamShort + ' ' + homeWinProb + '%') # scoreEmbed.add_field(name=homeTeamShort + ' win %', value=game_contextMetrics['homeWinProbability'].format(1), inline=True) # scoreEmbed.add_field(name=awayTeamShort + ' win %', value=game_contextMetrics['awayWinProbability'].format(1), inline=True) ''' DEBUG: game_contextMetrics DEBUG: %s {'game': {'gamePk': 55555, 'link': '/api/v1/game/55555/feed/live', 'gameType': 'R', 'season': '2006', 'gameDate': '2006-06-10T03:33:00Z', 'status': {'abstractGameState': 'Final', 'codedGameState': 'F', 'detailedState': 'Final', 'statusCode': 'F', 'startTimeTBD': True, 'abstractGameCode': 'F'}, 'teams': {'away': {'leagueRecord': {'wins': 7, 'losses': 0, 'pct': '1.000'}, 'score': 5, 'team': {'id': 604, 'name': 'DSL Blue Jays', 'link': '/api/v1/teams/604'}, 'isWinner': True, 'splitSquad': False, 'seriesNumber': 7}, 'home': {'leagueRecord': {'wins': 2, 'losses': 4, 'pct': '.333'}, 'score': 3, 'team': {'id': 616, 'name': 'DSL Indians', 'link': '/api/v1/teams/616'}, 'isWinner': False, 'splitSquad': False, 'seriesNumber': 6}}, 'venue': {'id': 401, 'name': 'Generic', 'link': '/api/v1/venues/401'}, 'content': {'link': '/api/v1/game/55555/content'}, 'isTie': False, 'gameNumber': 1, 'publicFacing': True, 'doubleHeader': 'N', 'gamedayType': 'N', 'tiebreaker': 'N', 'calendarEventID': '44-55555-2006-06-10', 'seasonDisplay': '2006', 'dayNight': 'day', 'scheduledInnings': 9, 'inningBreakLength': 0, 'gamesInSeries': 1, 'seriesGameNumber': 1, 'seriesDescription': 'Regular Season', 'recordSource': 'S', 'ifNecessary': 'N', 'ifNecessaryDescription': 'Normal Game', 'gameId': '2006/06/10/dblrok-dinrok-1'}, 'expectedStatisticsData': {}, 'leftFieldSacFlyProbability': {}, 'centerFieldSacFlyProbability': {}, 'rightFieldSacFlyProbability': {}, 'awayWinProbability': 100.0, 'homeWinProbability': 0.0} ''' # If the game is not a spring training game, pull the scoring plays if gameType != 'S': scoringPlaysList = statsapi.game_scoring_play_data(game['game_id']) scoringPlays = scoringPlaysList['plays'] #print(*scoringPlays) ''' {'result': {'description': 'Mike Yastrzemski homers (8) on a fly ball to right field. ', 'awayScore': 1, 'homeScore': 0}, 'about': {'atBatIndex': 1, 'halfInning': 'top', 'inning': 1, 'endTime': '2020-09-02T19:14:09.256Z'}, 'atBatIndex': 1} ''' if len(scoringPlays) > 0: # scoringPlaysList = scoringPlays.split('\n\n') # for plays in scoringPlaysList: # scoreEmbed.add_field(name=str(scoringPlaysList.index(plays) + 1), value=plays, inline=False) # Display only the latest scoring play scoreEmbed.add_field(name='**Latest scoring play**', value=scoringPlays[len(scoringPlays) - 1]['result']['description'], inline=False) if len(scoringPlays) > 1: # Set the footer to inform the user about additional plays scoreEmbed.set_footer(text='Reply with \'more\' in 30 seconds to see all scoring plays') # Send the message await message.channel.send(embed=scoreEmbed, tts=False) if len(scoringPlays) > 1: # Wait for the user response if await self.commonFunctions.wait_for_response(message, 'more', 30): # Create a new embed object to contain all scoring plays allPlaysEmbed = discord.Embed() # allPlaysEmbed.title = '**All scoring plays**' allPlaysEmbed.type = 'rich' allPlaysEmbed.color = discord.Color.dark_blue() scoring_plays_string = "" for index, plays in enumerate(scoringPlays): scoring_plays_string = scoring_plays_string + str(index + 1) + '. ' + plays['result']['description'] + '\n\n' allPlaysEmbed.add_field(name='**All scoring plays**', value=scoring_plays_string, inline=False) # for plays in scoringPlays: # allPlaysEmbed.add_field(name=str(scoringPlays.index(plays) + 1), # value=plays['result']['description'], inline=False) await message.channel.send(embed=allPlaysEmbed, tts=False) return else: return return else: # Send the message await message.channel.send(embed=scoreEmbed, tts=False) return