From 699097345ce65c1e0eed53f095779d1cffb1ed63 Mon Sep 17 00:00:00 2001 From: Jef Roosens Date: Wed, 11 Aug 2021 13:55:39 +0200 Subject: [PATCH] Started main.py file --- padel/__main__.py | 46 ++++++++++++++++++++++++++++++++++++++++++++++ padel/tennis.py | 31 ++++++++++++++++++++++++++----- padel/weather.py | 26 ++++++++++++++++++++++++++ 3 files changed, 98 insertions(+), 5 deletions(-) create mode 100644 padel/weather.py diff --git a/padel/__main__.py b/padel/__main__.py index e69de29..8ada0b1 100644 --- a/padel/__main__.py +++ b/padel/__main__.py @@ -0,0 +1,46 @@ +from tennis import get_time_slots, get_club_address +import argparse +from configparser import ConfigParser +from pathlib import Path +from weather import WeatherAPI + + +def existing_path(path_str): + path = Path(path_str) + + if not path.exists() or not path.is_file(): + raise argparse.ArgumentTypeError("Config file doesn't exist or isn't a file.") + + return path + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("-c", "--config-file", help="Path to config file.", + default="padel.ini", type=existing_path) + parser.add_argument("-d", "--days", + help="How many days in advance to look.", default=1, + type=int) + parser.add_argument("club_id", help="ID of the club to check.", type=int) + + args = parser.parse_args() + + # Read config file + config = ConfigParser() + # TODO check if config file can be read + config.read(args.config_file) + + club_address = get_club_address(args.club_id) + + if club_address is None: + print("Couldn't get club address.") + return + + weather_api = WeatherAPI(config["DEFAULT"]["weather_api_key"]) + weather_forecasts = weather_api.get_hourly_conditions(club_address, + days=args.days) + timeslots = get_time_slots(args.club_id, days=args.days) + + +if __name__ == "__main__": + main() diff --git a/padel/tennis.py b/padel/tennis.py index f1cfde1..441bd64 100644 --- a/padel/tennis.py +++ b/padel/tennis.py @@ -61,13 +61,34 @@ def extract_calendar(soup: BeautifulSoup, reservation_date): 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): +def get_time_slots(club_id: int, days=1): + dates = [date.today() + timedelta(days=i) for i in range(days)] params = {"clubId": club_id} - if date: - params["planningDay"] = date.strftime("%d-%m-%Y") + output = [] - r = requests.get(BASE_URL, params=params) + for planning_date in dates: + params["planningDay"] = planning_date.strftime("%d-%m-%Y") + + r = requests.get(BASE_URL, params=params) + soup = BeautifulSoup(r.content, "html.parser") + + output.extend(extract_calendar(soup, planning_date)) + + return output + +def get_club_address(club_id: int): + r = requests.get(BASE_URL, params={ + "clubId": club_id, + "tab": "club", + }) soup = BeautifulSoup(r.content, "html.parser") - return extract_calendar(soup, date) + tab_div = soup.find("div", id="club") + info_ul = tab_div.find("ul") + + for li in info_ul.findAll("li"): + if li.find("span", text="Adres (hoofdlocatie)"): + return li.find("span", class_="list-value").text.strip() + + return None diff --git a/padel/weather.py b/padel/weather.py new file mode 100644 index 0000000..fe4f607 --- /dev/null +++ b/padel/weather.py @@ -0,0 +1,26 @@ +import requests + + +class WeatherAPI: + BASE_URL = "https://api.weatherapi.com/v1" + + def __init__(self, api_key): + self._api_key = api_key + + def _get(self, endpoint, params): + params["key"] = self._api_key + return requests.get(f"{self.BASE_URL}{endpoint}", params=params) + + def get_hourly_conditions(self, query, days=1): + r = self._get("/forecast.json", { + "q": query, + "days": days, + "aqi": "no", + "alert": "no", + }) + + if r.status_code != 200: + return None + + data = r.json() + return sum([obj["hour"] for obj in data["forecast"]["forecastday"]], [])