pysportbot 0.0.13__tar.gz → 0.0.15__tar.gz
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-0.0.13 → pysportbot-0.0.15}/PKG-INFO +2 -2
- {pysportbot-0.0.13 → pysportbot-0.0.15}/pyproject.toml +10 -10
- {pysportbot-0.0.13 → pysportbot-0.0.15}/pysportbot/activities.py +32 -8
- {pysportbot-0.0.13 → pysportbot-0.0.15}/LICENSE +0 -0
- {pysportbot-0.0.13 → pysportbot-0.0.15}/README.md +0 -0
- {pysportbot-0.0.13 → pysportbot-0.0.15}/pysportbot/__init__.py +0 -0
- {pysportbot-0.0.13 → pysportbot-0.0.15}/pysportbot/authenticator.py +0 -0
- {pysportbot-0.0.13 → pysportbot-0.0.15}/pysportbot/bookings.py +0 -0
- {pysportbot-0.0.13 → pysportbot-0.0.15}/pysportbot/centres.py +0 -0
- {pysportbot-0.0.13 → pysportbot-0.0.15}/pysportbot/endpoints.py +0 -0
- {pysportbot-0.0.13 → pysportbot-0.0.15}/pysportbot/service/__init__.py +0 -0
- {pysportbot-0.0.13 → pysportbot-0.0.15}/pysportbot/service/__main__.py +0 -0
- {pysportbot-0.0.13 → pysportbot-0.0.15}/pysportbot/service/booking.py +0 -0
- {pysportbot-0.0.13 → pysportbot-0.0.15}/pysportbot/service/config_loader.py +0 -0
- {pysportbot-0.0.13 → pysportbot-0.0.15}/pysportbot/service/config_validator.py +0 -0
- {pysportbot-0.0.13 → pysportbot-0.0.15}/pysportbot/service/scheduling.py +0 -0
- {pysportbot-0.0.13 → pysportbot-0.0.15}/pysportbot/service/service.py +0 -0
- {pysportbot-0.0.13 → pysportbot-0.0.15}/pysportbot/service/threading.py +0 -0
- {pysportbot-0.0.13 → pysportbot-0.0.15}/pysportbot/session.py +0 -0
- {pysportbot-0.0.13 → pysportbot-0.0.15}/pysportbot/utils/__init__.py +0 -0
- {pysportbot-0.0.13 → pysportbot-0.0.15}/pysportbot/utils/errors.py +0 -0
- {pysportbot-0.0.13 → pysportbot-0.0.15}/pysportbot/utils/logger.py +0 -0
- {pysportbot-0.0.13 → pysportbot-0.0.15}/pysportbot/utils/time.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: pysportbot
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.15
|
4
4
|
Summary: A python-based bot for automatic resasports slot booking
|
5
5
|
Author: Joshua Falco Beirer
|
6
6
|
Author-email: jbeirer@cern.ch
|
@@ -12,7 +12,7 @@ Classifier: Programming Language :: Python :: 3.12
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.13
|
13
13
|
Requires-Dist: beautifulsoup4 (>=4.13.3,<5.0.0)
|
14
14
|
Requires-Dist: pandas (>=2.2.3,<3.0.0)
|
15
|
-
Requires-Dist: pytz (>=2025.
|
15
|
+
Requires-Dist: pytz (>=2025.2,<2026.0)
|
16
16
|
Requires-Dist: requests (>=2.32.3,<3.0.0)
|
17
17
|
Description-Content-Type: text/markdown
|
18
18
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
[project]
|
2
2
|
name = "pysportbot"
|
3
|
-
version = "v0.0.
|
3
|
+
version = "v0.0.15"
|
4
4
|
description = "A python-based bot for automatic resasports slot booking"
|
5
5
|
authors = [
|
6
6
|
{ name = "Joshua Falco Beirer", email = "jbeirer@cern.ch" }
|
@@ -18,26 +18,26 @@ python = ">=3.10,<3.14"
|
|
18
18
|
requests = "^2.32.3"
|
19
19
|
beautifulsoup4 = "^4.13.3"
|
20
20
|
pandas = "^2.2.3"
|
21
|
-
pytz = "^2025.
|
21
|
+
pytz = "^2025.2"
|
22
22
|
|
23
23
|
[tool.poetry.group.dev.dependencies]
|
24
|
-
pytest = "^8.3.
|
24
|
+
pytest = "^8.3.5"
|
25
25
|
pytest-cov = "^6.0.0"
|
26
26
|
deptry = "^0.23.0"
|
27
27
|
mypy = "^1.15.0"
|
28
|
-
pre-commit = "^4.
|
29
|
-
tox = "^4.24.
|
28
|
+
pre-commit = "^4.2.0"
|
29
|
+
tox = "^4.24.2"
|
30
30
|
ipykernel = "^6.29.5"
|
31
|
-
types-pytz = "^2025.1.0.
|
32
|
-
types-requests = "^2.32.0.
|
31
|
+
types-pytz = "^2025.1.0.20250318"
|
32
|
+
types-requests = "^2.32.0.20250306"
|
33
33
|
|
34
34
|
[tool.poetry.group.docs.dependencies]
|
35
35
|
mkdocs = "^1.6.1"
|
36
|
-
mkdocs-material = "^9.6.
|
37
|
-
mkdocstrings = {extras = ["python"], version = "^0.
|
36
|
+
mkdocs-material = "^9.6.9"
|
37
|
+
mkdocstrings = {extras = ["python"], version = "^0.29.0"}
|
38
38
|
|
39
39
|
[build-system]
|
40
|
-
requires = ["poetry-core>=2.
|
40
|
+
requires = ["poetry-core>=2.1.1"]
|
41
41
|
build-backend = "poetry.core.masonry.api"
|
42
42
|
|
43
43
|
[tool.black]
|
@@ -32,13 +32,27 @@ class Activities:
|
|
32
32
|
"""
|
33
33
|
logger.info("Fetching activities...")
|
34
34
|
response = self.session.post(Endpoints.ACTIVITIES, headers=self.headers)
|
35
|
+
|
35
36
|
if response.status_code != 200:
|
36
37
|
error_msg = ErrorMessages.failed_fetch("activities")
|
37
38
|
logger.error(error_msg)
|
38
39
|
raise RuntimeError(error_msg)
|
40
|
+
|
41
|
+
try:
|
42
|
+
activities = response.json().get("activities", {})
|
43
|
+
except json.JSONDecodeError as err:
|
44
|
+
error_msg = "Invalid JSON response while fetching activities."
|
45
|
+
logger.error(error_msg)
|
46
|
+
raise RuntimeError(error_msg) from err
|
47
|
+
|
48
|
+
if not activities:
|
49
|
+
logger.warning("No activities found in the response.")
|
50
|
+
|
51
|
+
df_activities = pd.DataFrame.from_dict(activities, orient="index")
|
52
|
+
df_activities.index = df_activities.index.astype(int) # Ensure index is integer for consistency
|
53
|
+
|
39
54
|
logger.info("Activities fetched successfully.")
|
40
|
-
|
41
|
-
return pd.DataFrame.from_dict(activities, orient="index")
|
55
|
+
return df_activities
|
42
56
|
|
43
57
|
def daily_slots(self, df_activities: DataFrame, activity_name: str, day: str) -> DataFrame:
|
44
58
|
"""
|
@@ -67,9 +81,10 @@ class Activities:
|
|
67
81
|
logger.error(error_msg)
|
68
82
|
raise ValueError(error_msg)
|
69
83
|
|
70
|
-
# Extract activity ID
|
71
|
-
activity_id
|
72
|
-
|
84
|
+
# Extract activity ID and category ID
|
85
|
+
# Ensures activity_id is an integer
|
86
|
+
activity_id = activity_match.index[0]
|
87
|
+
id_category_activity = activity_match.at[activity_id, "activityCategoryId"]
|
73
88
|
|
74
89
|
# Get Unix timestamp bounds for the day
|
75
90
|
unix_day_bounds = get_unix_day_bounds(day)
|
@@ -81,12 +96,19 @@ class Activities:
|
|
81
96
|
"end": unix_day_bounds[1],
|
82
97
|
}
|
83
98
|
response = self.session.get(Endpoints.SLOTS, headers=self.headers, params=params)
|
99
|
+
|
84
100
|
if response.status_code != 200:
|
85
101
|
error_msg = ErrorMessages.failed_fetch("slots")
|
86
102
|
logger.error(error_msg)
|
87
103
|
raise RuntimeError(error_msg)
|
88
104
|
|
89
|
-
|
105
|
+
try:
|
106
|
+
slots = response.json()
|
107
|
+
except json.JSONDecodeError as err:
|
108
|
+
error_msg = "Invalid JSON response while fetching slots."
|
109
|
+
logger.error(error_msg)
|
110
|
+
raise RuntimeError(error_msg) from err
|
111
|
+
|
90
112
|
if not slots:
|
91
113
|
warning_msg = ErrorMessages.no_slots(activity_name, day)
|
92
114
|
logger.warning(warning_msg)
|
@@ -110,10 +132,12 @@ class Activities:
|
|
110
132
|
"trainer",
|
111
133
|
]
|
112
134
|
df_slots = pd.DataFrame(slots)
|
113
|
-
|
135
|
+
|
136
|
+
# Ensure only desired columns are selected without KeyError
|
137
|
+
df_slots = df_slots.loc[:, df_slots.columns.intersection(columns)]
|
114
138
|
|
115
139
|
# Only select rows of the specified activity
|
116
|
-
df_slots = df_slots[df_slots
|
140
|
+
df_slots = df_slots[df_slots["id_activity"] == activity_id]
|
117
141
|
if df_slots.empty:
|
118
142
|
warning_msg = ErrorMessages.no_matching_slots(activity_name, day)
|
119
143
|
logger.warning(warning_msg)
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|