import requests from tabulate import tabulate from colorama import Fore from plugin import plugin, require from utilities.animations import SpinnerThread API_KEY = '1ebd3b92bf5041249f8c1e7a540ce98c' url = 'https://api.football-data.org/v2' headers = {'X-Auth-Token': API_KEY} def fetch(route): r = requests.get(url + route, headers=headers) r = r.json() if "errorCode" in r.keys(): return None return r @require(network=True) @plugin('football') class Football(): """ Provides football competition information (tournament/league standings) and daily match info. Enter 'football' to use. """ def __call__(self, jarvis, s): # Attribution to the football-data.org API print("Football data provided by the Football-Data.org API\n") # Ask for user option (competition or match info) option = self.get_option(jarvis) if option is None: return # Present the list of competitions # (common step for both choices) compId = self.get_competition(jarvis) # Proceed according to option if compId is None: return if option == 'competitions': self.competition(jarvis, compId) elif option == 'matches': self.matches(jarvis, compId) print() def get_option(self, jarvis): """ Get user input for choosing between match info or competition info """ options = {1: 'competitions', 2: 'matches'} # Ask for the option jarvis.say("What information do you want:", Fore.BLUE) print() print("1: Competition/league standings") print("2: Today's matches") print("3: Exit") print() while True: try: option = int(jarvis.input("Enter your choice: ", Fore.GREEN)) if option == 3: return elif option == 1 or option == 2: return options[option] else: jarvis.say( "Invalid input! Enter a number from the choices provided.", Fore.YELLOW) except ValueError: jarvis.say( "Invalid input! Enter a number from the choices provided.", Fore.YELLOW) print() def get_competition(self, jarvis): """ Takes input from user for selecting a competition """ # Fetch top-tier competitions jarvis.spinner_start('Fetching ') r = fetch("/competitions?plan=TIER_ONE") if r is None: jarvis.spinner_stop("Error in fetching data - try again later.", Fore.YELLOW) return comps = r["competitions"] jarvis.spinner_stop("Pick a competition:", Fore.BLUE) # Print the list of competitions print() for i in range(r["count"]): print("{}: {}, {}".format( i + 1, comps[i]["name"], comps[i]["area"]["name"])) print("0: Exit") print() # Take input option while True: try: option = int(jarvis.input("Enter your choice: ", Fore.BLUE)) if option == 0: return None elif option in range(1, r["count"] + 1): return comps[option - 1]["id"] else: jarvis.say( "Invalid input! Enter a number from the choices provided.", Fore.YELLOW) except ValueError: jarvis.say( "Invalid input! Enter a number from the choices provided.", Fore.YELLOW) print() def competition(self, jarvis, compId): """ Fetches details of a competition and outputs the competition's current standings """ # Fetch competition info) jarvis.spinner_start('Fetching ') r = fetch("/competitions/{}/standings".format(compId)) if r is None: jarvis.spinner_stop("Error in fetching data - try again later.", Fore.YELLOW) return jarvis.spinner_stop('') print() self.printStandings(jarvis, r["standings"]) def printStandings(self, jarvis, tables): """ Helper function for validating, formatting and printing the standings table """ if len(tables) == 0: # No standings available jarvis.say("No standings found for this competition.", Fore.BLUE) return if tables[0]["group"] is None: # League table - print top three jarvis.say("First position: {}".format( tables[0]["table"][0]["team"]["name"])) jarvis.say("Second position: {}".format( tables[0]["table"][1]["team"]["name"])) jarvis.say("Third position: {}".format( tables[0]["table"][2]["team"]["name"])) print() # General case jarvis.say("Here are the full standings: ", Fore.BLUE) print() for table in tables: # Loop through all standing tables if table["type"] != "TOTAL": # Do not print HOME and AWAY tables continue if table["group"] is not None: # Group table - print the group name print(Fore.BLUE + "GROUP " + table["group"][6] + Fore.RESET) print() stList = [] for team in table["table"]: # Set "team" property to only team name team["team"] = team["team"]["name"] stList.append([team[k] for k in team]) # Print the standings table print(tabulate(stList, headers=[ "#", "Team", "P", "W", "D", "L", "Points", "GF", "GA", "GD"])) print() def matches(self, jarvis, compId): """ Fetches today's matches in given competition and prints the match info """ print() jarvis.spinner_start('Fetching ') r = fetch("/matches?competitions={}".format(compId)) if r is None: jarvis.spinner_stop("Error in fetching data - try again later.", Fore.YELLOW) return jarvis.spinner_stop('') if r["count"] == 0: jarvis.say("No matches found for today.", Fore.BLUE) return else: # Print each match info for match in r["matches"]: matchInfo = self.formatMatchInfo(match) length = len(matchInfo) jarvis.say(matchInfo[0], Fore.BLUE) for i in range(1, length): print(matchInfo[i]) print() def formatMatchInfo(self, match): """ Helper function for formatting and printing match info """ lines = [] # Get home and away team names homeTeam = match["homeTeam"]["name"].upper() awayTeam = match["awayTeam"]["name"].upper() lines.append("{} vs {}".format(homeTeam, awayTeam)) # Get type and status of match group = match["group"] status = match["status"] lines.append("Group: {}".format(group)) lines.append("Status: {}".format(status.capitalize())) # Get the scores if status != "SCHEDULED": # Get the score after 90 mins ordinary time scores = match["score"] homeScore = scores["halfTime"]["homeTeam"] + \ scores["fullTime"]["homeTeam"] awayScore = scores["halfTime"]["awayTeam"] + \ scores["fullTime"]["awayTeam"] lines.append("SCORE: {} - {}".format(homeScore, awayScore)) if scores["extraTime"]["homeTeam"] is not None: # Match went on to extra time homeExtra = scores["extraTime"]["homeTeam"] awayExtra = scores["extraTime"]["awayTeam"] lines.append( "Extra time: {} - {}".format(homeExtra, awayExtra)) if scores["penalties"]["homeTeam"] is not None: # Match went on to penalties homePen = scores["penalties"]["homeTeam"] awayPen = scores["penalties"]["awayTeam"] lines.append("Penalties: {} - {}".format(homePen, awayPen)) # Return list of lines return lines