123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229 |
- #!/usr/bin/env python3
- import gspread
- from oauth2client.service_account import ServiceAccountCredentials
- import datetime
- import time
- from nba_api.stats.static import players
- from nba_api.stats.endpoints import playergamelog
- spreadsheet_key = '1QBQvGSMesox1gwjpaoK-0-p3n-c4I_L73PWCggjdayM' # 2019 Official
- #spreadsheet_key = '14pHOScaGXvN83iCca6_5p6QoViYvo223cIJD9nnl7TI' # 2019 Test
- json_keyfile = 'NBA Playoffs Game-1f9a46f0715c.json'
- current_day = 'today' # today, else:
- #current_day = datetime.date(2018, 4, 15) # set date manually
- nba_cooldown = 2 # in seconds, don't hammer the NBA.com API too hard
- ###############################################################################
- def getWorksheet(spreadsheet_key, json_keyfile):
- scope = ['https://spreadsheets.google.com/feeds',
- 'https://www.googleapis.com/auth/drive']
- credentials = ServiceAccountCredentials.from_json_keyfile_name(json_keyfile, scope)
- gc = gspread.authorize(credentials)
- spreadsheet = gc.open_by_key(spreadsheet_key)
- worksheet = spreadsheet.get_worksheet(0)
- return worksheet
- def setDates(current_day):
- if current_day == 'today':
- # in case games go past midnight
- current_date = datetime.datetime.now() - datetime.timedelta(hours=3)
- current_date = current_date.date()
- else:
- current_date = current_day
- url_date = current_date.strftime('%m/%d/%Y')
- current_year = current_date.year
- if current_date.month > 6:
- current_season = '{}-{}'.format(str(current_year),
- str(current_year + 1)[2:])
- else:
- current_season = '{}-{}'.format(str(current_year - 1),
- str(current_year)[2:])
- return url_date, current_season, current_date
-
- def getFirstRowLastRow(worksheet, current_date):
- date_col_values = worksheet.col_values(1) # get all date cell values from column 1
- final_row = len(date_col_values) # get number of rows in spreadsheet
- date_cells = worksheet.range('A4:A'+str(final_row)) # get all date cells
- first_row = ""
- last_row = ""
- for date_cell in date_cells:
- if first_row != "":
- if date_cell.row == final_row:
- last_row = final_row
- break
- elif date_cell.value != "":
- last_row = date_cell.row - 1
- break
- continue
- elif date_cell.value != "":
- date_cell_day = datetime.datetime.strptime('{} {}'.format(date_cell.value,
- str(current_date.year)),
- '%A, %B %d %Y')
- date_cell_day = date_cell_day.date()
- if date_cell_day == current_date:
- first_row = date_cell.row
- return first_row, last_row
- def parsePlayersCells(todays_cells):
- player_cells = []
- player_names = []
- for cell in todays_cells:
- if cell.col == 3 and cell.value != "" and cell.value[-7:] != "-FIX!!!":
- player_cells.append(cell)
- player_name = cleanPlayerName(cell)
- player_names.append(player_name)
- player_names_unique = list(dict.fromkeys(player_names))
- return player_cells, player_names_unique
-
- def cleanPlayerName(player_cell):
- raw_name = player_cell.value
- first_name_last_name = raw_name.split()
- first_name = first_name_last_name[0]
- first_name = first_name.replace('.', '')
- last_name = first_name_last_name[1]
- player_name = first_name + ' ' + last_name
- return player_name
- def getPlayerStats(player_id, url_date, current_season):
- player_game_logs = playergamelog.PlayerGameLog(player_id=player_id,
- league_id_nullable='00',
- season_type_all_star='Playoffs',
- date_from_nullable=url_date,
- date_to_nullable=url_date)
- player_game_logs = player_game_logs.get_dict()
- player_game_logs_results = player_game_logs.get('resultSets')[0]
- player_game_logs_headers = player_game_logs_results.get('headers')
- # if player has no stats for this day, list will be empty
- if len(player_game_logs_results.get('rowSet')) < 1:
- player_stats_dict = None
- else:
- player_game_logs_values = player_game_logs_results.get('rowSet')[0]
- player_stats_dict = dict(zip(player_game_logs_headers, player_game_logs_values))
- return player_stats_dict
- def buildStatsDict(player_names_unique, url_date, current_season):
- stats_dict = {}
- for player_name in player_names_unique:
- player_info = players.find_players_by_full_name(player_name)
- if len(player_info) < 1:
- print("\nPlayer \"" + player_name + "\" not found, please fix name!")
- stats_dict[player_name] = "Fix Name!"
- continue
- player_id = player_info[0].get('id')
- stats_dict[player_name] = getPlayerStats(player_id, url_date, current_season)
- print('{} {}{} {}{}'.format('Got', player_name, '\'s (ID:', str(player_id), ') stats from NBA.com'))
- time.sleep(nba_cooldown)
- return stats_dict
- def updatePlayerStatsLocal(todays_cells, player_cell, player_stats, update, player_update):
- for cell in todays_cells:
- if cell.row == player_cell.row:
- if (cell.col == 4 and player_stats.get("PTS") != "" and
- str(cell.value) != str(player_stats.get("PTS"))):
- cell.value = str(player_stats.get("PTS"))
- update = True
- player_update = True
- elif (cell.col == 5 and player_stats.get("REB") != "" and
- str(cell.value) != str(player_stats.get("REB"))):
- cell.value = str(player_stats.get("REB"))
- update = True
- player_update = True
- elif (cell.col == 6 and player_stats.get("AST") != "" and
- str(cell.value) != str(player_stats.get("AST"))):
- cell.value = str(player_stats.get("AST"))
- update = True
- player_update = True
- elif (cell.col == 7 and player_stats.get("STL") != "" and
- str(cell.value) != str(player_stats.get("STL"))):
- cell.value = str(player_stats.get("STL"))
- update = True
- player_update = True
- elif (cell.col == 8 and player_stats.get("BLK") != "" and
- str(cell.value) != str(player_stats.get("BLK"))):
- cell.value = str(player_stats.get("BLK"))
- update = True
- player_update = True
- elif (cell.col == 9 and player_stats.get("TOV") != "" and
- str(cell.value) != str(player_stats.get("TOV"))):
- cell.value = str(player_stats.get("TOV"))
- update = True
- player_update = True
- elif (cell.col == 10 and player_stats.get("WL") != "" and
- str(cell.value) != str(player_stats.get("WL"))):
- cell.value = str(player_stats.get("WL"))
- update = True
- player_update = True
- return todays_cells, update, player_update
-
- if __name__ == "__main__":
- while True:
- url_date, current_season, current_date = setDates(current_day)
- print("Date: " + str(current_date))
-
- # open worksheet, find today's action, and create unique list of players
- try:
- worksheet = getWorksheet(spreadsheet_key, json_keyfile)
- first_row, last_row = getFirstRowLastRow(worksheet, current_date)
- if first_row == "":
- print("No games today! Pausing for 1000 seconds...")
- time.sleep(1000)
- continue
- todays_cells = worksheet.range(first_row, 3, last_row, 10)
- player_cells, player_names_unique = parsePlayersCells(todays_cells)
- print("Today's players:", end=' ', flush=True)
- print(player_names_unique)
- except gspread.exceptions.APIError:
- print("Google API overloaded, retrying in 10 seconds...")
- time.sleep(10)
- continue
- except:
- time.sleep(10)
- continue
- # Build stats dictionary from unique list of players
- print("Retrieving player stats from NBA.com...")
- stats_dict = buildStatsDict(player_names_unique, url_date, current_season)
- update = False # only update the sheet if it has changed
- for player_cell in player_cells:
- player_update = False # Return if individual player stats have changed
- player_name = cleanPlayerName(player_cell)
- if stats_dict.get(player_name) != None: # skip players with empty stats
- if stats_dict.get(player_name) == "Fix Name!":
- player_cell.value = str(player_cell.value) + "-FIX!!!"
- update = True
- else:
- player_stats = stats_dict.get(player_name)
- todays_cells, update, player_update = updatePlayerStatsLocal(todays_cells,
- player_cell,
- player_stats,
- update,
- player_update)
- if player_update == True:
- print("Updated " + player_name + "\'s stats")
- elif player_update == False:
- print(player_name + "\'s stats have not changed")
-
- if update == True:
- while True:
- try:
- print("Pushing changes to google sheet...")
- worksheet.update_cells(todays_cells, 'USER_ENTERED')
- break
- except gspread.exceptions.APIError:
- print("Google API overloaded, adding a 10 second delay...")
- time.sleep(10)
- continue
- else:
- print("No update necessary, pausing for 30 seconds...")
- time.sleep(30)
-
- continue # restart entire loop
|