Payloads are now built with Jinja templates
This commit is contained in:
parent
ccd019eb4c
commit
badced0a30
12 changed files with 222 additions and 175 deletions
|
@ -90,3 +90,7 @@ def init_log_config():
|
|||
with open(logging_file, "r") as f:
|
||||
logging_config = yaml.safe_load(f.read())
|
||||
logging.config.dictConfig(logging_config)
|
||||
|
||||
|
||||
ROOT_PATH = Path(__file__).parent.resolve()
|
||||
RESOURCES_DIR = Path(ROOT_PATH, "resources")
|
||||
|
|
7
resa_padel/gestion_sports/gestion_sports_config.py
Normal file
7
resa_padel/gestion_sports/gestion_sports_config.py
Normal file
|
@ -0,0 +1,7 @@
|
|||
from pathlib import Path
|
||||
|
||||
import config
|
||||
|
||||
RESOURCES_DIR = Path(config.RESOURCES_DIR, "gestion-sports")
|
||||
BOOKING_TEMPLATE = Path(RESOURCES_DIR, "booking-payload.txt")
|
||||
LOGIN_TEMPLATE = Path(RESOURCES_DIR, "login-payload.txt")
|
|
@ -6,7 +6,10 @@ from urllib.parse import urljoin
|
|||
from aiohttp import ClientResponse, ClientSession
|
||||
|
||||
import config
|
||||
from gestion_sports.gestion_sports_payload_builder import GestionSportsPayloadBuilder
|
||||
from gestion_sports.payload_builders import (
|
||||
GestionSportsLoginPayloadBuilder,
|
||||
GestionSportsBookingPayloadBuilder,
|
||||
)
|
||||
from models import BookingFilter, Club, User
|
||||
|
||||
DATE_FORMAT = "%d/%m/%Y"
|
||||
|
@ -26,7 +29,6 @@ class GestionSportsConnector:
|
|||
LOGGER.info("Initializing connection to GestionSports API")
|
||||
self.url = url
|
||||
self.session = session
|
||||
self.payload_builder = GestionSportsPayloadBuilder()
|
||||
|
||||
@property
|
||||
def landing_url(self) -> str:
|
||||
|
@ -72,12 +74,8 @@ class GestionSportsConnector:
|
|||
|
||||
:return: the response from the login
|
||||
"""
|
||||
payload = (
|
||||
self.payload_builder.login(user.login)
|
||||
.password(user.password)
|
||||
.club_id(club.id)
|
||||
.build_login_payload()
|
||||
)
|
||||
payload_builder = GestionSportsLoginPayloadBuilder()
|
||||
payload = payload_builder.user(user).club(club).build()
|
||||
|
||||
async with self.session.post(
|
||||
self.login_url, data=payload, headers=POST_HEADERS
|
||||
|
@ -105,10 +103,11 @@ class GestionSportsConnector:
|
|||
return_exceptions=True,
|
||||
)
|
||||
|
||||
return await self.get_booked_court(bookings)
|
||||
return self.get_booked_court(bookings)
|
||||
|
||||
@staticmethod
|
||||
async def get_booked_court(bookings):
|
||||
def get_booked_court(bookings):
|
||||
LOGGER.info(bookings)
|
||||
for court, is_booked in bookings:
|
||||
if is_booked:
|
||||
return court
|
||||
|
@ -117,23 +116,23 @@ class GestionSportsConnector:
|
|||
async def book_one_court(
|
||||
self, booking_filter: BookingFilter, court_id: int
|
||||
) -> tuple[int, bool]:
|
||||
payload_builder = GestionSportsBookingPayloadBuilder()
|
||||
payload = (
|
||||
self.payload_builder.date(booking_filter.date.date().strftime(DATE_FORMAT))
|
||||
.time(booking_filter.date.time().strftime(TIME_FORMAT))
|
||||
.sport_id(booking_filter.sport_id)
|
||||
.court_id(court_id)
|
||||
.build_booking_payload()
|
||||
payload_builder.booking_filter(booking_filter).court_id(court_id).build()
|
||||
)
|
||||
return court_id, await self.is_court_booked(payload)
|
||||
LOGGER.info(payload)
|
||||
|
||||
async def is_court_booked(self, payload: str) -> bool:
|
||||
async with self.session.post(
|
||||
self.booking_url, data=payload, headers=POST_HEADERS
|
||||
) as response:
|
||||
return self.is_response_status_ok(await response.text())
|
||||
resp_json = await response.text()
|
||||
|
||||
return court_id, self.is_response_status_ok(resp_json)
|
||||
|
||||
@staticmethod
|
||||
def is_response_status_ok(response: str) -> bool:
|
||||
|
||||
LOGGER.info(response)
|
||||
formatted_result = response.removeprefix('"').removesuffix('"')
|
||||
result_json = json.loads(formatted_result)
|
||||
return result_json["status"] == "ok"
|
||||
|
|
|
@ -1,69 +0,0 @@
|
|||
from exceptions import ArgumentMissing
|
||||
|
||||
|
||||
class GestionSportsPayloadBuilder:
|
||||
def __init__(self):
|
||||
self._login = None
|
||||
self._password = None
|
||||
self._club_id = None
|
||||
self._date = None
|
||||
self._time = None
|
||||
self._sport_id = None
|
||||
self._court_id = None
|
||||
|
||||
def login(self, login: str):
|
||||
self._login = login
|
||||
return self
|
||||
|
||||
def password(self, password: str):
|
||||
self._password = password
|
||||
return self
|
||||
|
||||
def club_id(self, club_id: str):
|
||||
self._club_id = club_id
|
||||
return self
|
||||
|
||||
def date(self, date: str):
|
||||
self._date = date
|
||||
return self
|
||||
|
||||
def time(self, time: str):
|
||||
self._time = time
|
||||
return self
|
||||
|
||||
def sport_id(self, sport_id: int):
|
||||
self._sport_id = sport_id
|
||||
return self
|
||||
|
||||
def court_id(self, court_id: int):
|
||||
self._court_id = court_id
|
||||
return self
|
||||
|
||||
def build_login_payload(self):
|
||||
if self._login is None:
|
||||
raise ArgumentMissing("Login not provided")
|
||||
if self.password is None:
|
||||
raise ArgumentMissing("Password not provided")
|
||||
if self._club_id is None:
|
||||
raise ArgumentMissing("Club ID not provided")
|
||||
|
||||
return (
|
||||
f"ajax=connexionUser&id_club={self._club_id}&email={self._login}&form_ajax=1&pass={self._password}&compte"
|
||||
f"=user&playeridonesignal=0&identifiant=identifiant&externCo=true"
|
||||
).encode("utf-8")
|
||||
|
||||
def build_booking_payload(self):
|
||||
if self._date is None:
|
||||
raise ArgumentMissing("Date not provided")
|
||||
if self._time is None:
|
||||
raise ArgumentMissing("Time not provided")
|
||||
if self._sport_id is None:
|
||||
raise ArgumentMissing("Sport ID not provided")
|
||||
if self._court_id is None:
|
||||
raise ArgumentMissing("Court ID not provided")
|
||||
|
||||
return (
|
||||
f"ajax=addResa&date={self._date}&hour={self._time}&duration=90&partners=null|null|null"
|
||||
f"&paiement=facultatif&idSport={self._sport_id}&creaPartie=false&idCourt={self._court_id}"
|
||||
f"&pay=false&token=undefined&totalPrice=44&saveCard=0&foodNumber=0"
|
||||
).encode("utf-8")
|
59
resa_padel/gestion_sports/payload_builders.py
Normal file
59
resa_padel/gestion_sports/payload_builders.py
Normal file
|
@ -0,0 +1,59 @@
|
|||
from jinja2 import Environment, FileSystemLoader
|
||||
|
||||
from exceptions import ArgumentMissing
|
||||
from gestion_sports.gestion_sports_config import LOGIN_TEMPLATE, BOOKING_TEMPLATE
|
||||
from models import User, Club, BookingFilter
|
||||
|
||||
|
||||
class GestionSportsLoginPayloadBuilder:
|
||||
def __init__(self):
|
||||
self._user: User | None = None
|
||||
self._club: Club | None = None
|
||||
self._template = LOGIN_TEMPLATE
|
||||
|
||||
def user(self, user: User):
|
||||
self._user = user
|
||||
return self
|
||||
|
||||
def club(self, club: Club):
|
||||
self._club = club
|
||||
return self
|
||||
|
||||
def build(self):
|
||||
if self._user is None:
|
||||
raise ArgumentMissing("No user was provided")
|
||||
if self._club is None:
|
||||
raise ArgumentMissing("No club was provided")
|
||||
|
||||
environment = Environment(loader=FileSystemLoader(self._template.parent))
|
||||
template = environment.get_template(self._template.name)
|
||||
|
||||
return template.render(club=self._club, user=self._user)
|
||||
|
||||
|
||||
class GestionSportsBookingPayloadBuilder:
|
||||
def __init__(self):
|
||||
self._booking_filter: BookingFilter | None = None
|
||||
self._court_id: int | None = None
|
||||
self._template = BOOKING_TEMPLATE
|
||||
|
||||
def booking_filter(self, booking_filter: BookingFilter):
|
||||
self._booking_filter = booking_filter
|
||||
return self
|
||||
|
||||
def court_id(self, court_id: int):
|
||||
self._court_id = court_id
|
||||
return self
|
||||
|
||||
def build(self):
|
||||
if self._booking_filter is None:
|
||||
raise ArgumentMissing("No booking filter was provided")
|
||||
if self.court_id is None:
|
||||
raise ArgumentMissing("No court id was provided")
|
||||
|
||||
environment = Environment(loader=FileSystemLoader(self._template.parent))
|
||||
template = environment.get_template(self._template.name)
|
||||
|
||||
return template.render(
|
||||
court_id=self._court_id, booking_filter=self._booking_filter
|
||||
)
|
1
resa_padel/resources/gestion-sports/booking-payload.txt
Normal file
1
resa_padel/resources/gestion-sports/booking-payload.txt
Normal file
|
@ -0,0 +1 @@
|
|||
ajax=addResa&date={{ booking_filter.date.date().strftime("%d/%m/%Y") }}&hour={{ booking_filter.date.time().strftime("%H:%M") }}&duration=90&partners=null|null|null&paiement=facultatif&idSport={{ booking_filter.sport_id }}&creaPartie=false&idCourt={{ court_id }}&pay=false&token=undefined&totalPrice=44&saveCard=0&foodNumber=0
|
1
resa_padel/resources/gestion-sports/login-payload.txt
Normal file
1
resa_padel/resources/gestion-sports/login-payload.txt
Normal file
|
@ -0,0 +1 @@
|
|||
ajax=connexionUser&id_club={{ club.id }}&email={{ user.login }}&form_ajax=1&pass={{ user.password }}&compte=user&playeridonesignal=0&identifiant=identifiant&externCo=true
|
Loading…
Add table
Add a link
Reference in a new issue