import asyncio import logging import time import config import pendulum from aiohttp import ClientSession from gestion_sports.gestion_sports_connector import GestionSportsConnector from models import BookingFilter, Club, User from pendulum import DateTime LOGGER = logging.getLogger(__name__) def wait_until_booking_time(club: Club, booking_filter: BookingFilter): """ Wait until the booking is open. The booking filter contains the date and time of the booking. The club has the information about when the booking is open for that date. :param club: the club where to book a court :param booking_filter: the booking information """ LOGGER.info("Waiting booking time") booking_datetime = build_booking_datetime(booking_filter, club) now = pendulum.now() while now < booking_datetime: time.sleep(1) now = pendulum.now() def build_booking_datetime(booking_filter: BookingFilter, club: Club) -> DateTime: """ Build the date and time when the booking is open for a given match date. The booking filter contains the date and time of the booking. The club has the information about when the booking is open for that date. :param booking_filter: the booking information :param club: the club where to book a court :return: the date and time when the booking is open """ date_to_book = booking_filter.date booking_date = date_to_book.subtract(days=club.booking_open_days_before) booking_hour = club.booking_opening_time.hour booking_minute = club.booking_opening_time.minute return booking_date.at(booking_hour, booking_minute) async def book(club: Club, user: User, booking_filter: BookingFilter) -> int | None: """ Book a court for a user to a club following a booking filter :param club: the club where to book a court :param user: the user information :param booking_filter: the information related to the booking :return: the id of the booked court, or None if no court was booked """ async with ClientSession() as session: platform = GestionSportsConnector(session, club.url) await platform.land() await platform.login(user, club) wait_until_booking_time(club, booking_filter) return await platform.book(booking_filter, club) def main() -> int | None: """ Main function used to book a court :return: the id of the booked court, or None if no court was booked """ user = config.get_user() booking_filter = config.get_booking_filter() club = config.get_club() LOGGER.info( "Starting booking court of %s for user %s at club %s at %s", booking_filter.sport_id, user.login, club.id, booking_filter.date, ) court_booked = asyncio.run(book(club, user, booking_filter)) if court_booked: LOGGER.info( "Court %s booked successfully at %s", court_booked, booking_filter.date ) else: LOGGER.info("Booking did not work") return court_booked