From 4e4f78334a3fd90a067096109fe8948e17e8cc32 Mon Sep 17 00:00:00 2001 From: Jef Roosens Date: Wed, 11 Aug 2021 13:09:44 +0200 Subject: [PATCH] Added tennis.py file --- padel/__main__.py | 0 padel/tennis.py | 73 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 padel/__main__.py create mode 100644 padel/tennis.py diff --git a/padel/__main__.py b/padel/__main__.py new file mode 100644 index 0000000..e69de29 diff --git a/padel/tennis.py b/padel/tennis.py new file mode 100644 index 0000000..f1cfde1 --- /dev/null +++ b/padel/tennis.py @@ -0,0 +1,73 @@ +import requests +from bs4 import BeautifulSoup +from datetime import date, time, timedelta, datetime + + +BASE_URL = "https://www.tennisvlaanderen.be/terreinreservatie-dagplanning" + + +def extract_timeslots(tbody, column_headers): + counters = [0] * len(column_headers) + timeslots = [] + + for tr in tbody.findAll("tr"): + # Determine time for row + time_str = tr.find("th").text + hour, minute = map(int, time_str.split(":")) + start_time = time(hour=hour, minute=minute) + + # Iterate over each column + for td in tr.findAll("td"): + # Find first empty counter + counter_index = next((i for i in range(len(counters)) if counters[i] <= 0), None) + + # this means there's no empty counters atm + if counter_index is None: + break + + block_length = int(td["rowspan"]) + counters[counter_index] += block_length + + # By default, a slot is just not available for hire + code = 2 + length = timedelta(minutes=15 * block_length) + + if td.find("div", class_="reservation-detail free"): + code = 0 + + elif td.find("div", class_="reservation-detail regular-reservation"): + code = 1 + + timeslots.append((column_headers[counter_index], code, start_time, length)) + + counters = [i - 1 for i in counters] + + return timeslots + + +def extract_calendar(soup: BeautifulSoup, reservation_date): + reservation_date = reservation_date or date.today() + reservation_t = soup.find("div", class_="reservation-table") + + # Get court names + header_trs_txts = reservation_t.find("thead").find("tr").findAll("th") + court_names = [th.text.strip() for th in header_trs_txts if th.text.strip()] + + # the real stuff + tbody = reservation_t.find("tbody") + timeslots = extract_timeslots(tbody, court_names) + + # Here, we convert the timeslots to datetime instead of time + return [(col, status, datetime.combine(reservation_date, start), duration) for col, status, start, duration in timeslots] + + +def get_time_slots(club_id: int, date: date = None): + params = {"clubId": club_id} + + if date: + params["planningDay"] = date.strftime("%d-%m-%Y") + + r = requests.get(BASE_URL, params=params) + soup = BeautifulSoup(r.content, "html.parser") + + return extract_calendar(soup, date)