created a gestion sports services class that handles the connection while the connector is dedicated to the requests
This commit is contained in:
parent
bcd8dc0733
commit
e6023e0687
12 changed files with 513 additions and 593 deletions
127
resa_padel/gestion_sports_services.py
Normal file
127
resa_padel/gestion_sports_services.py
Normal file
|
@ -0,0 +1,127 @@
|
|||
import logging
|
||||
import time
|
||||
|
||||
import pendulum
|
||||
from aiohttp import ClientSession
|
||||
from connectors import GestionSportsConnector
|
||||
from models import BookingFilter, BookingOpening, Club, Court, User
|
||||
from pendulum import DateTime
|
||||
|
||||
LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class GestionSportsServices:
|
||||
@staticmethod
|
||||
async def book(
|
||||
club: Club, user: User, booking_filter: BookingFilter
|
||||
) -> Court | None:
|
||||
"""
|
||||
Perform a request for each court at the same time to increase the chances to get
|
||||
a booking.
|
||||
The gestion-sports backend does not allow several bookings at the same time
|
||||
so there is no need to make each request one after the other
|
||||
|
||||
:param club: the club in which the booking will be made
|
||||
:param user: the user that wants to book the court
|
||||
:param booking_filter: the booking conditions to meet
|
||||
:return: the booked court, or None if no court was booked
|
||||
"""
|
||||
connector = GestionSportsConnector(club)
|
||||
LOGGER.info(
|
||||
"Booking any available court from GestionSports API at %s",
|
||||
connector.booking_url,
|
||||
)
|
||||
|
||||
async with ClientSession() as session:
|
||||
# use asyncio to request a booking on every court
|
||||
# the gestion-sports backend is able to book only one court for a user
|
||||
await connector.land(session)
|
||||
await connector.login(session, user)
|
||||
|
||||
booking_opening = club.booking_platform.booking_opening
|
||||
GestionSportsServices.wait_until_booking_time(
|
||||
booking_filter, booking_opening
|
||||
)
|
||||
|
||||
bookings = await connector.book_any_court(session, booking_filter)
|
||||
|
||||
LOGGER.debug("Booking results:\n'%s'", bookings)
|
||||
return connector.get_booked_court(bookings, booking_filter.sport_name)
|
||||
|
||||
@staticmethod
|
||||
async def has_user_available_slots(user: User, club: Club) -> bool:
|
||||
connector = GestionSportsConnector(club)
|
||||
async with ClientSession() as session:
|
||||
await connector.land(session)
|
||||
await connector.login(session, user)
|
||||
bookings = await connector.get_ongoing_bookings(session)
|
||||
|
||||
return bool(bookings)
|
||||
|
||||
@staticmethod
|
||||
async def cancel_booking(user: User, club: Club, booking_filter: BookingFilter):
|
||||
connector = GestionSportsConnector(club)
|
||||
async with ClientSession() as session:
|
||||
await connector.land(session)
|
||||
await connector.login(session, user)
|
||||
await connector.cancel_booking(session, booking_filter)
|
||||
|
||||
@staticmethod
|
||||
async def cancel_booking_id(user: User, club: Club, booking_id: int):
|
||||
connector = GestionSportsConnector(club)
|
||||
async with ClientSession() as session:
|
||||
await connector.land(session)
|
||||
await connector.login(session, user)
|
||||
await connector.cancel_booking_id(session, booking_id)
|
||||
|
||||
@staticmethod
|
||||
def wait_until_booking_time(
|
||||
booking_filter: BookingFilter, booking_opening: BookingOpening
|
||||
) -> None:
|
||||
"""
|
||||
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 booking_opening:
|
||||
:param booking_filter: the booking information
|
||||
"""
|
||||
LOGGER.info("Waiting for booking time")
|
||||
booking_datetime = GestionSportsServices.build_booking_datetime(
|
||||
booking_filter, booking_opening
|
||||
)
|
||||
now = pendulum.now()
|
||||
duration_until_booking = booking_datetime - now
|
||||
LOGGER.debug(f"Current time: {now}, Datetime to book: {booking_datetime}")
|
||||
LOGGER.debug(
|
||||
f"Time to wait before booking: {duration_until_booking.hours:0>2}"
|
||||
f":{duration_until_booking.minutes:0>2}"
|
||||
f":{duration_until_booking.seconds:0>2}"
|
||||
)
|
||||
|
||||
while now < booking_datetime:
|
||||
time.sleep(1)
|
||||
now = pendulum.now()
|
||||
LOGGER.info("It's booking time!")
|
||||
|
||||
@staticmethod
|
||||
def build_booking_datetime(
|
||||
booking_filter: BookingFilter, booking_opening: BookingOpening
|
||||
) -> 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_opening:the booking opening conditions
|
||||
:param booking_filter: the booking information
|
||||
:return: the date and time when the booking is open
|
||||
"""
|
||||
date_to_book = booking_filter.date
|
||||
booking_date = date_to_book.subtract(days=booking_opening.days_before)
|
||||
|
||||
opening_time = pendulum.parse(booking_opening.opening_time)
|
||||
booking_hour = opening_time.hour
|
||||
booking_minute = opening_time.minute
|
||||
|
||||
return booking_date.at(booking_hour, booking_minute)
|
Loading…
Add table
Add a link
Reference in a new issue