mirror of https://github.com/stijndcl/didier
Clean up Football matches a lot
parent
2b96f3ec41
commit
8238bdf6de
|
@ -1,9 +1,9 @@
|
|||
from bs4 import BeautifulSoup
|
||||
import datetime
|
||||
from decorators import help
|
||||
from discord.ext import commands
|
||||
from enums.help_categories import Category
|
||||
from functions import checks, config
|
||||
from functions.football import getMatches
|
||||
import requests
|
||||
import tabulate
|
||||
|
||||
|
@ -25,37 +25,13 @@ class Football(commands.Cog):
|
|||
@jpl.command(name="Matches", aliases=["M"], usage="[Week]*")
|
||||
async def matches(self, ctx, *args):
|
||||
args = list(args)
|
||||
|
||||
# Default is current day
|
||||
if not args:
|
||||
args = [str(config.get("jpl_day"))]
|
||||
|
||||
if all(letter.isdigit() for letter in args[0]):
|
||||
current_day = requests.get("https://api.sporza.be/web/soccer/matchdays/161733/{}".format(args[0])).json()
|
||||
current_day = current_day["groupedMatches"][0]["matches"]
|
||||
|
||||
# Create dictionaries for every match
|
||||
matches_formatted = {}
|
||||
for i, match in enumerate(current_day):
|
||||
matchDic = {"home": match["homeTeam"]["name"], "away": match["awayTeam"]["name"]}
|
||||
|
||||
# Add date
|
||||
matchDate = datetime.datetime.strptime(match["startDateTime"].split("+")[0], "%Y-%m-%dT%H:%M:%S.%f")
|
||||
matchDic["date"] = matchDate.strftime("%d/%m")
|
||||
matchDic["day"] = self.get_weekday(matchDate.weekday())
|
||||
|
||||
# TODO check back when there's active games (to find the key in the dict) & add the current time if not over
|
||||
# Add scores
|
||||
if match["status"] == "END": # Status != [not_yet_started] whatever it is
|
||||
matchDic["score"] = "{} - {}".format(match["homeScore"], match["awayScore"])
|
||||
else:
|
||||
# If there's no score, show when the match starts
|
||||
matchDic["score"] = "{}:{}".format(
|
||||
("" if len(str(matchDate.hour)) == 2 else "0") + str(matchDate.hour), # Leading Zero
|
||||
("" if len(str(matchDate.minute)) == 2 else "0") + str(matchDate.minute)) # Leading Zero
|
||||
|
||||
matches_formatted[i] = matchDic
|
||||
|
||||
# Put every formatted version of the matches in a list
|
||||
matchList = list([self.format_match(matches_formatted[match]) for match in matches_formatted])
|
||||
await ctx.send("```Jupiler Pro League - Speeldag {}\n\n{}```".format(args[0], tabulate.tabulate(matchList, headers=["Dag", "Datum", "Thuis", "Stand", "Uit", "Tijd"])))
|
||||
await ctx.send(getMatches(int(args[0])))
|
||||
else:
|
||||
return await ctx.send("Dit is geen geldige speeldag.")
|
||||
|
||||
|
|
|
@ -0,0 +1,134 @@
|
|||
from enum import Enum
|
||||
from attr import dataclass, field
|
||||
from functions.timeFormatters import fromString
|
||||
from functions.scraping import getJPLMatches
|
||||
from functions.stringFormatters import leadingZero
|
||||
from datetime import datetime
|
||||
import tabulate
|
||||
|
||||
|
||||
class Status(Enum):
|
||||
AfterToday = "--:--"
|
||||
NotStarted = "--:--"
|
||||
Over = "Einde"
|
||||
HalfTime = "Rust"
|
||||
|
||||
|
||||
@dataclass
|
||||
class Match:
|
||||
"""
|
||||
Class representing a football match between two teams
|
||||
"""
|
||||
matchDict: dict
|
||||
home: str = field(init=False)
|
||||
homeScore: int = 0
|
||||
away: str = field(init=False)
|
||||
awayScore: int = 0
|
||||
start: datetime = field(init=False)
|
||||
date: str = field(init=False)
|
||||
weekDay: str = field(init=False)
|
||||
status: Status = field(init=False)
|
||||
|
||||
def __attrs_post_init__(self):
|
||||
"""
|
||||
Parse class attributes out of a dictionary returned from an API request
|
||||
"""
|
||||
# The API isn't public, so every single game state is differently formatted
|
||||
self.status = self._getStatus(self.matchDict[Navigation.Status.value])
|
||||
self.home = self.matchDict[Navigation.HomeTeam.value][Navigation.Name.value]
|
||||
self.away = self.matchDict[Navigation.AwayTeam.value][Navigation.Name.value]
|
||||
|
||||
if self._hasStarted():
|
||||
self.homeScore = self.matchDict[Navigation.HomeScore.value]
|
||||
self.awayScore = self.matchDict[Navigation.AwayScore.value]
|
||||
|
||||
self.start = fromString(self.matchDict["startDateTime"], formatString="%Y-%m-%dT%H:%M:%S.%f%z")
|
||||
self.date = self.start.strftime("%d/%m")
|
||||
self.weekDay = self._getWeekday()
|
||||
|
||||
def _getStatus(self, status: str):
|
||||
"""
|
||||
Gets the string representation for the status of this match
|
||||
"""
|
||||
# LiveTime only exists if the status is live
|
||||
# Avoids KeyErrors
|
||||
if status.lower() == "live":
|
||||
# Half time
|
||||
if Navigation.LiveMatchPhase.value in self.matchDict and \
|
||||
Navigation.LiveMatchPhase.value == Navigation.HalfTime.value:
|
||||
return Status.HalfTime.value
|
||||
|
||||
# Current time
|
||||
return self.matchDict[Navigation.LiveTime.value]
|
||||
|
||||
# If no special status, pull it out of this dict
|
||||
statusses: dict = {
|
||||
"after_today": Status.AfterToday.value,
|
||||
"not_started": Status.NotStarted.value,
|
||||
"end": Status.Over.value
|
||||
}
|
||||
|
||||
return statusses[status.lower()]
|
||||
|
||||
def _getWeekday(self):
|
||||
"""
|
||||
Gets the day of the week this match is played on
|
||||
"""
|
||||
day = self.start.weekday()
|
||||
days = ["Ma", "Di", "Wo", "Do", "Vr", "Za", "Zo"]
|
||||
return days[day]
|
||||
|
||||
def getInfo(self):
|
||||
"""
|
||||
Returns a list of all the info of this class in order to create a table
|
||||
"""
|
||||
return [self.weekDay, self.date, self.home, self._getScore(), self.away, self.status]
|
||||
|
||||
def _getScore(self):
|
||||
"""
|
||||
Returns a string representing the scoreboard
|
||||
"""
|
||||
# No score to show yet, show time when the match starts
|
||||
if not self._hasStarted():
|
||||
return "{}:{}".format(leadingZero(str(self.start.hour)), leadingZero(str(self.start.minute)))
|
||||
|
||||
return "{} - {}".format(self.homeScore, self.awayScore)
|
||||
|
||||
def _hasStarted(self):
|
||||
return self.status not in [Status.AfterToday.value, Status.NotStarted.value]
|
||||
|
||||
|
||||
class Navigation(Enum):
|
||||
"""
|
||||
Enum to navigate through the matchdict,
|
||||
seeing as the API is private the keys of the dict could change every now and then
|
||||
so this makes sure a key only has to be changed once.
|
||||
"""
|
||||
AwayTeam = "awayTeam"
|
||||
HomeTeam = "homeTeam"
|
||||
AwayScore = "awayScore"
|
||||
HomeScore = "homeScore"
|
||||
LiveTime = "liveTime"
|
||||
LiveMatchPhase = "liveMatchPhase"
|
||||
HalfTime = "HALF_TIME"
|
||||
Status = "status"
|
||||
Name = "name"
|
||||
|
||||
|
||||
def getMatches(matchweek: int):
|
||||
"""
|
||||
Function that constructs the table for a given matchweek
|
||||
"""
|
||||
current_day = getJPLMatches(matchweek)
|
||||
|
||||
# API request failed
|
||||
if current_day is None:
|
||||
return "Er ging iets mis. Probeer het later opnieuw."
|
||||
|
||||
matches = list(map(Match, current_day))
|
||||
matches = list(map(lambda x: x.getInfo(), matches))
|
||||
|
||||
header = "Jupiler Pro League - Speeldag {}".format(matchweek)
|
||||
table = tabulate.tabulate(matches, headers=["Dag", "Datum", "Thuis", "Stand", "Uit", "Tijd"])
|
||||
|
||||
return "```{}\n\n{}```".format(header, table)
|
|
@ -76,3 +76,16 @@ def getMatchweek():
|
|||
|
||||
# "Speeldag DD" -> split on space & take second
|
||||
return match[0].split(" ")[1]
|
||||
|
||||
|
||||
def getJPLMatches(week: int):
|
||||
"""
|
||||
JPL matches for a given matchweek
|
||||
"""
|
||||
current_day = get("https://api.sporza.be/web/soccer/matchdays/161733/{}".format(week))
|
||||
|
||||
# Something went wrong
|
||||
if current_day.status_code != 200:
|
||||
return None
|
||||
|
||||
return current_day.json()["groupedMatches"][0]["matches"]
|
||||
|
|
Loading…
Reference in New Issue