pysportbot 0.0.16__py3-none-any.whl → 0.0.17__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pysportbot/authenticator.py +29 -5
- pysportbot/service/booking.py +10 -6
- {pysportbot-0.0.16.dist-info → pysportbot-0.0.17.dist-info}/METADATA +1 -1
- {pysportbot-0.0.16.dist-info → pysportbot-0.0.17.dist-info}/RECORD +6 -6
- {pysportbot-0.0.16.dist-info → pysportbot-0.0.17.dist-info}/LICENSE +0 -0
- {pysportbot-0.0.16.dist-info → pysportbot-0.0.17.dist-info}/WHEEL +0 -0
pysportbot/authenticator.py
CHANGED
@@ -30,6 +30,27 @@ class Authenticator:
|
|
30
30
|
self.user_id = None
|
31
31
|
# Centre selected by the user
|
32
32
|
self.centre = centre
|
33
|
+
# Timeout of requests
|
34
|
+
self.timeout = (5, 10)
|
35
|
+
|
36
|
+
def is_session_valid(self) -> bool:
|
37
|
+
"""
|
38
|
+
Check if the current session is still valid.
|
39
|
+
|
40
|
+
Returns:
|
41
|
+
bool: True if session is valid, False otherwise.
|
42
|
+
"""
|
43
|
+
try:
|
44
|
+
response = self.session.post(Endpoints.USER, headers=self.headers, timeout=self.timeout)
|
45
|
+
if response.status_code == 200:
|
46
|
+
response_dict = json.loads(response.content.decode("utf-8"))
|
47
|
+
return bool(response_dict.get("user"))
|
48
|
+
else:
|
49
|
+
logger.debug(f"Session validation failed with status code: {response.status_code}")
|
50
|
+
return False
|
51
|
+
except Exception as e:
|
52
|
+
logger.debug(f"Session validation failed with exception: {e}")
|
53
|
+
return False
|
33
54
|
|
34
55
|
def login(self, email: str, password: str) -> None:
|
35
56
|
"""
|
@@ -46,11 +67,12 @@ class Authenticator:
|
|
46
67
|
|
47
68
|
# Step 1: Fetch CSRF token
|
48
69
|
logger.debug(f"GET {Endpoints.USER_LOGIN} | Headers: {json.dumps(self.headers, indent=2)}")
|
49
|
-
response = self.session.get(Endpoints.USER_LOGIN, headers=self.headers)
|
70
|
+
response = self.session.get(Endpoints.USER_LOGIN, headers=self.headers, timeout=self.timeout)
|
50
71
|
if response.status_code != 200:
|
51
72
|
logger.error(f"Failed to fetch login popup: {response.status_code}")
|
52
73
|
raise RuntimeError(ErrorMessages.failed_fetch("login popup"))
|
53
74
|
logger.debug("Login popup fetched successfully.")
|
75
|
+
|
54
76
|
soup = BeautifulSoup(response.text, "html.parser")
|
55
77
|
csrf_tag = soup.find("input", {"name": "_csrf_token"})
|
56
78
|
if csrf_tag is None:
|
@@ -70,7 +92,7 @@ class Authenticator:
|
|
70
92
|
f"POST {Endpoints.LOGIN_CHECK} | Headers: {json.dumps(self.headers, indent=2)} | "
|
71
93
|
f"Payload: {json.dumps(payload, indent=2)}"
|
72
94
|
)
|
73
|
-
response = self.session.post(Endpoints.LOGIN_CHECK, data=payload, headers=self.headers)
|
95
|
+
response = self.session.post(Endpoints.LOGIN_CHECK, data=payload, headers=self.headers, timeout=self.timeout)
|
74
96
|
if response.status_code != 200:
|
75
97
|
logger.error(f"Login failed: {response.status_code}, {response.text}")
|
76
98
|
raise ValueError(ErrorMessages.failed_login())
|
@@ -79,7 +101,7 @@ class Authenticator:
|
|
79
101
|
# Step 3: Retrieve credentials for Nubapp
|
80
102
|
cred_endpoint = Endpoints.get_cred_endpoint(self.centre)
|
81
103
|
logger.debug(f"GET {cred_endpoint} | Headers: {json.dumps(self.headers, indent=2)}")
|
82
|
-
response = self.session.get(cred_endpoint, headers=self.headers)
|
104
|
+
response = self.session.get(cred_endpoint, headers=self.headers, timeout=self.timeout)
|
83
105
|
if response.status_code != 200:
|
84
106
|
logger.error(f"Failed to retrieve Nubapp credentials: {response.status_code}")
|
85
107
|
raise RuntimeError(ErrorMessages.failed_fetch("credentials"))
|
@@ -94,14 +116,16 @@ class Authenticator:
|
|
94
116
|
f"GET {Endpoints.NUBAP_LOGIN} | Headers: {json.dumps(self.headers, indent=2)} | "
|
95
117
|
f"Params: {json.dumps(nubapp_creds, indent=2)}"
|
96
118
|
)
|
97
|
-
response = self.session.get(
|
119
|
+
response = self.session.get(
|
120
|
+
Endpoints.NUBAP_LOGIN, headers=self.headers, params=nubapp_creds, timeout=self.timeout
|
121
|
+
)
|
98
122
|
if response.status_code != 200:
|
99
123
|
logger.error(f"Login to Nubapp failed: {response.status_code}, {response.text}")
|
100
124
|
raise ValueError(ErrorMessages.failed_login_nubapp())
|
101
125
|
logger.info("Login to Nubapp successful!")
|
102
126
|
|
103
127
|
# Step 5: Get user information
|
104
|
-
response = self.session.post(Endpoints.USER, headers=self.headers, allow_redirects=True)
|
128
|
+
response = self.session.post(Endpoints.USER, headers=self.headers, allow_redirects=True, timeout=self.timeout)
|
105
129
|
|
106
130
|
if response.status_code == 200:
|
107
131
|
response_dict = json.loads(response.content.decode("utf-8"))
|
pysportbot/service/booking.py
CHANGED
@@ -117,19 +117,23 @@ def schedule_bookings(
|
|
117
117
|
logger.debug(f"Re-authenticating in {reauth_time:.2f} seconds.")
|
118
118
|
time.sleep(reauth_time)
|
119
119
|
|
120
|
-
# Re-authenticate before booking
|
121
|
-
logger.info("Re-authenticating before booking.")
|
120
|
+
# Re-authenticate before booking if necessary
|
122
121
|
try:
|
123
|
-
bot.
|
124
|
-
|
125
|
-
|
122
|
+
if bot._auth and bot._auth.is_session_valid():
|
123
|
+
logger.info("Session still valid. Skipping re-authentication.")
|
124
|
+
else:
|
125
|
+
logger.info("Attempting re-authenticating before booking.")
|
126
|
+
bot.login(config["email"], config["password"], config["centre"])
|
127
|
+
|
128
|
+
except Exception as e:
|
129
|
+
logger.warning(f"Re-authentication failed before booking execution with {e}.")
|
126
130
|
|
127
131
|
# Wait the remaining time until execution
|
128
132
|
now = datetime.now(pytz.timezone(time_zone))
|
129
133
|
remaining_time = (execution_time - now).total_seconds()
|
130
134
|
if remaining_time > 0:
|
131
135
|
logger.info(f"Waiting {remaining_time:.2f} seconds until booking execution.")
|
132
|
-
|
136
|
+
time.sleep(max(0, remaining_time))
|
133
137
|
|
134
138
|
# Global booking delay
|
135
139
|
if booking_delay > 0:
|
@@ -1,12 +1,12 @@
|
|
1
1
|
pysportbot/__init__.py,sha256=tZwOIuLO1-a3d4KKA5nNfXfN6PjJxem_hxyuff9utk4,6425
|
2
2
|
pysportbot/activities.py,sha256=MATA0feSsDSoeFnHa4Y_dLv3gw4P6MFg-0kAEybqVIY,4991
|
3
|
-
pysportbot/authenticator.py,sha256=
|
3
|
+
pysportbot/authenticator.py,sha256=rs3QG9aEFxG0THMm-7STqnfMlvBG3a56KnBYMYNvSmQ,6142
|
4
4
|
pysportbot/bookings.py,sha256=W91AYGPu0sCpGliuiVdlENsoGYzH8P6v-SyKisbSb7g,3127
|
5
5
|
pysportbot/centres.py,sha256=FTK-tXUOxiJvLCHP6Bk9XEQKODQZOwwkYLlioSJPBEk,3399
|
6
6
|
pysportbot/endpoints.py,sha256=ANh5JAbdzyZQ-i4ODrhYlskPpU1gkBrw9UhMC7kRSvU,1353
|
7
7
|
pysportbot/service/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
8
8
|
pysportbot/service/__main__.py,sha256=gsKfDMOmsVC3LHCQs0Dmp7YWJBlZeGcTsX-Mx4mk6ro,1496
|
9
|
-
pysportbot/service/booking.py,sha256=
|
9
|
+
pysportbot/service/booking.py,sha256=ifeo1LbtPvls-hpQOZW5TvoqeZ1MJxIipim4RHTH7nI,5908
|
10
10
|
pysportbot/service/config_loader.py,sha256=t086yaAyAKkCJTpxedwhyJ7QqSf5XROGDzjrFLsUxJE,179
|
11
11
|
pysportbot/service/config_validator.py,sha256=0P_pcXU7s3T3asODqFtv3mSp1HyPoVBphE4Qe1mxcps,2615
|
12
12
|
pysportbot/service/scheduling.py,sha256=trz4zweZB2W9rwWAnW9Y6YkCo-f4dqtKyhaY_yqpJ-Y,2024
|
@@ -17,7 +17,7 @@ pysportbot/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,
|
|
17
17
|
pysportbot/utils/errors.py,sha256=IRarfGtk1tETxUGAhPAIbeits_u2tJvVCGTtkHIdYFQ,5146
|
18
18
|
pysportbot/utils/logger.py,sha256=ANayMEeeAIVGKvITAxOFm2EdCbzBBTpNywuytAr4Z90,5366
|
19
19
|
pysportbot/utils/time.py,sha256=VZSW8AxFIoFD5ZSmLUPcwawp6PmpkcxNjP3Db-Hl_fw,1244
|
20
|
-
pysportbot-0.0.
|
21
|
-
pysportbot-0.0.
|
22
|
-
pysportbot-0.0.
|
23
|
-
pysportbot-0.0.
|
20
|
+
pysportbot-0.0.17.dist-info/LICENSE,sha256=6ov3DypdEVYpp2pn_B1MniKWO5C9iDA4O6PGcbork6c,1077
|
21
|
+
pysportbot-0.0.17.dist-info/METADATA,sha256=PW2ipkWtyRp83h_Zd1fTre_5LTuKFfGR2AT-96pnmno,8045
|
22
|
+
pysportbot-0.0.17.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
|
23
|
+
pysportbot-0.0.17.dist-info/RECORD,,
|
File without changes
|
File without changes
|