You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
156 lines
5.0 KiB
156 lines
5.0 KiB
#!/usr/bin/env python
|
|
|
|
import os
|
|
from datetime import datetime, timedelta
|
|
|
|
import requests
|
|
import bs4
|
|
from bs4 import BeautifulSoup
|
|
|
|
from init_api import get_service
|
|
|
|
import dotenv
|
|
|
|
|
|
class Match:
|
|
|
|
def __init__(self, team1: str, team2: str, score1: int, score2: int, raw_time: str, stage: str, roundName: str):
|
|
self.team1 = team1
|
|
self.team2 = team2
|
|
self.score1 = score1
|
|
self.score2 = score2
|
|
self.stage = stage
|
|
self.roundName = roundName
|
|
self.time = datetime(*list(map(lambda v: int(v), raw_time.split(","))))
|
|
self.eventId = None
|
|
|
|
def get_format(self) -> int:
|
|
if self.stage == "Play-In":
|
|
if self.roundName == "Qualifiers" or self.roundName == "EMEA vs NA":
|
|
return 5
|
|
return 3
|
|
if self.stage == "Swiss":
|
|
if self.roundName in ["Round 1", "Round 2"]:
|
|
return 1
|
|
if self.roundName == "Round 3" and self.time.day == 22:
|
|
return 1
|
|
return 3
|
|
if self.stage == "Knockout":
|
|
return 5
|
|
|
|
def event_data(self):
|
|
return {
|
|
"start": {
|
|
"dateTime": self.time.isoformat() + "Z"
|
|
},
|
|
"end": {
|
|
"dateTime": (self.time + timedelta(hours=self.get_format())).isoformat() + "Z"
|
|
},
|
|
"summary": f"{self.team1} - {self.team2}",
|
|
"description": f"{self.stage} {self.roundName} BO{self.get_format()}\n{self.score1} - {self.score2}"
|
|
}
|
|
|
|
def update_event(self):
|
|
api = get_service()
|
|
api.events().update(
|
|
calendarId=os.environ["CALENDAR_ID"],
|
|
eventId=self.eventId,
|
|
body=self.event_data()
|
|
).execute()
|
|
|
|
def create_event(self):
|
|
api = get_service()
|
|
api.events().insert(
|
|
calendarId=os.environ["CALENDAR_ID"],
|
|
body=self.event_data()
|
|
).execute()
|
|
|
|
def is_in_calendar(self, calendar_events):
|
|
for event in calendar_events:
|
|
if datetime.fromisoformat(event["start"]["dateTime"][:-1]) == self.time:
|
|
self.eventId = event["id"]
|
|
return True
|
|
return False
|
|
|
|
def __repr__(self):
|
|
return f"{self.team1:3} - {self.time} - {self.team2}"
|
|
|
|
|
|
def fetch_matches():
|
|
sources = [
|
|
"https://lol.fandom.com/wiki/2023_Worlds_Qualifying_Series",
|
|
"https://lol.fandom.com/wiki/2023_Season_World_Championship/Play-In",
|
|
"https://lol.fandom.com/wiki/2023_Season_World_Championship/Main_Event"
|
|
]
|
|
stages = ["Play-In", "Swiss", "Knockout"]
|
|
|
|
matches: list[Match] = []
|
|
|
|
for src in sources:
|
|
fetched_data = requests.get(src).text
|
|
soup = BeautifulSoup(fetched_data, "html.parser")
|
|
|
|
match_lists: list[bs4.Tag] = soup.find_all(attrs={"class": "matchlist"})
|
|
|
|
for match_list in match_lists:
|
|
roundName = match_list.find("tr").find("th").find(recursive=False, string=True).text
|
|
raw_matches: list[bs4.Tag] = match_list.find_all(attrs={"class", "ml-row"})
|
|
|
|
# somehow identify stage...
|
|
stage = stages[0] if (src == sources[0] or src == sources[1]) else \
|
|
(stages[1] if "Round" in roundName else stages[2])
|
|
|
|
for raw_match in raw_matches:
|
|
raw_time = raw_match.find(attrs={"class", "TimeInLocal"}).text
|
|
scores = raw_match.find_all(attrs={"class", "matchlist-score"})
|
|
scores = [0, 0] if not scores else tuple(map(lambda v: int(v.text), scores))
|
|
score1 = scores[0]
|
|
score2 = scores[1]
|
|
team1 = raw_match.find(attrs={"class", "matchlist-team1"}).find(attrs={"class", "teamname"}).text
|
|
team2 = raw_match.find(attrs={"class", "matchlist-team2"}).find(attrs={"class", "teamname"}).text
|
|
matches.append(Match(team1, team2, score1, score2, raw_time, stage, roundName))
|
|
|
|
return matches
|
|
|
|
|
|
def get_calendar_events():
|
|
api = get_service()
|
|
start = "2023-04-01T00:00:00Z"
|
|
end = "2023-11-20T00:00:00Z"
|
|
calendarId = os.environ.get("CALENDAR_ID")
|
|
events = api.events().list(
|
|
calendarId=calendarId, timeMin=start, timeMax=end,
|
|
maxResults=2500, singleEvents=True,
|
|
orderBy='startTime'
|
|
).execute()["items"]
|
|
return events
|
|
|
|
|
|
def delete_calendar_events():
|
|
api = get_service()
|
|
calendarId = os.environ.get("CALENDAR_ID")
|
|
events = get_calendar_events()
|
|
for event in events:
|
|
api.events().delete(calendarId=calendarId, eventId=event["id"]).execute()
|
|
print("Deleted all calendar events")
|
|
|
|
|
|
def update():
|
|
dotenv.load_dotenv()
|
|
|
|
events = get_calendar_events()
|
|
|
|
for match in fetch_matches():
|
|
print(f"Processing match: {match}")
|
|
if match.is_in_calendar(events):
|
|
print(f"Event found: {match.eventId}")
|
|
match.update_event()
|
|
print("Event updated")
|
|
else:
|
|
match.create_event()
|
|
print("Event created")
|
|
print("")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
update()
|
|
|