Add external session preference #3
48
README.md
48
README.md
@@ -30,6 +30,20 @@ docker-compose up --build
|
|||||||
|
|
||||||
The application will automatically check for available sessions and book them based on your preferences. It will send notifications via email and Telegram when a booking is successful.
|
The application will automatically check for available sessions and book them based on your preferences. It will send notifications via email and Telegram when a booking is successful.
|
||||||
|
|
||||||
|
### Configuring Preferred Sessions
|
||||||
|
|
||||||
|
You can configure your preferred sessions using the `preferred_sessions.json` file. This file should contain a JSON array of session names, for example:
|
||||||
|
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
"Morning Class",
|
||||||
|
"Evening Class",
|
||||||
|
"Saturday Open Gym"
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
If the file is not found or contains invalid data, the application will use default hardcoded sessions.
|
||||||
|
|
||||||
### Environment Variables
|
### Environment Variables
|
||||||
|
|
||||||
The following environment variables are required:
|
The following environment variables are required:
|
||||||
@@ -44,16 +58,36 @@ The following environment variables are required:
|
|||||||
|
|
||||||
### Preferred Sessions
|
### Preferred Sessions
|
||||||
|
|
||||||
You can configure your preferred sessions in the `crossfit_booker.py` file. The preferred sessions are defined as a list of tuples, where each tuple contains the day of the week, start time, and session name.
|
You can configure your preferred sessions in the `preferred_sessions.json` file. The preferred sessions are defined as a list of objects, where each object contains the day of the week, start time, and session name.
|
||||||
|
|
||||||
```python
|
```json
|
||||||
PREFERRED_SESSIONS = [
|
[
|
||||||
(4, "17:00", "WEIGHTLIFTING"), # Friday 17:00 WEIGHTLIFTING
|
{
|
||||||
(5, "12:30", "HYROX"), # Saturday 12:30 HYROX
|
"day_of_week": 4,
|
||||||
(2, "18:30", "CONDITIONING"), # Wednesday 18:30 CONDITIONING
|
"start_time": "17:00",
|
||||||
|
"session_name_contains": "WEIGHTLIFTING"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"day_of_week": 5,
|
||||||
|
"start_time": "12:30",
|
||||||
|
"session_name_contains": "HYROX"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"day_of_week": 2,
|
||||||
|
"start_time": "18:30",
|
||||||
|
"session_name_contains": "CONDITIONING"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The application will automatically load the preferred sessions from this file. If the file is not found or contains invalid data, it will fall back to the default hardcoded sessions.
|
||||||
|
|
||||||
|
#### Fields
|
||||||
|
|
||||||
|
- `day_of_week`: Integer representing the day of the week (0=Monday, 6=Sunday)
|
||||||
|
- `start_time`: String representing the start time in HH:MM format
|
||||||
|
- `session_name_contains`: String containing the name or part of the name of the session
|
||||||
|
|
||||||
## Files
|
## Files
|
||||||
|
|
||||||
- `Dockerfile`: Docker image definition
|
- `Dockerfile`: Docker image definition
|
||||||
@@ -64,6 +98,7 @@ PREFERRED_SESSIONS = [
|
|||||||
- `book_crossfit.py`: Main application script
|
- `book_crossfit.py`: Main application script
|
||||||
- `crossfit_booker.py`: Crossfit booking script
|
- `crossfit_booker.py`: Crossfit booking script
|
||||||
- `session_notifier.py`: Session notification script
|
- `session_notifier.py`: Session notification script
|
||||||
|
- `preferred_sessions.json`: Configuration file for preferred sessions
|
||||||
- `requirements.txt`: Python dependencies
|
- `requirements.txt`: Python dependencies
|
||||||
|
|
||||||
## Project Structure
|
## Project Structure
|
||||||
@@ -79,6 +114,7 @@ PREFERRED_SESSIONS = [
|
|||||||
├── crossfit_booker.py
|
├── crossfit_booker.py
|
||||||
├── session_notifier.py
|
├── session_notifier.py
|
||||||
├── requirements.txt
|
├── requirements.txt
|
||||||
|
├── preferred_sessions.json
|
||||||
└── log
|
└── log
|
||||||
└── crossfit_booking.log
|
└── crossfit_booking.log
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -4,6 +4,20 @@ import traceback
|
|||||||
from crossfit_booker import CrossFitBooker
|
from crossfit_booker import CrossFitBooker
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
# Configure logging once at script startup
|
||||||
|
logging.basicConfig(
|
||||||
|
level=logging.DEBUG, # Change to DEBUG for more detailed logs
|
||||||
|
format='%(asctime)s - %(levelname)s - %(message)s',
|
||||||
|
handlers=[
|
||||||
|
logging.FileHandler("log/crossfit_booking.log"),
|
||||||
|
logging.StreamHandler()
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
logging.getLogger("requests").setLevel(logging.WARNING)
|
||||||
|
logging.info("Logging enhanced with request library noise reduction")
|
||||||
|
|
||||||
|
# Start the main runner
|
||||||
booker = CrossFitBooker()
|
booker = CrossFitBooker()
|
||||||
if not booker.login():
|
if not booker.login():
|
||||||
logging.error("Failed to login - Traceback: %s", traceback.format_exc())
|
logging.error("Failed to login - Traceback: %s", traceback.format_exc())
|
||||||
|
|||||||
@@ -18,6 +18,9 @@ from typing import List, Dict, Optional, Any
|
|||||||
# Import the SessionNotifier class
|
# Import the SessionNotifier class
|
||||||
from session_notifier import SessionNotifier
|
from session_notifier import SessionNotifier
|
||||||
|
|
||||||
|
# Import the preferred sessions from the session_config module
|
||||||
|
from session_config import PREFERRED_SESSIONS
|
||||||
|
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
|
|
||||||
# Configuration
|
# Configuration
|
||||||
@@ -38,29 +41,6 @@ RETRY_MAX = 3
|
|||||||
RETRY_BACKOFF = 1
|
RETRY_BACKOFF = 1
|
||||||
APP_VERSION = "5.09.21"
|
APP_VERSION = "5.09.21"
|
||||||
|
|
||||||
# Define your preferred sessions
|
|
||||||
# Format: List of tuples (day_of_week, start_time, session_name_contains)
|
|
||||||
# day_of_week: 0=Monday, 6=Sunday
|
|
||||||
PREFERRED_SESSIONS = [
|
|
||||||
# (0, "17:00", "HYROX"), # Monday 17:00 HYROX
|
|
||||||
(4, "17:00", "WEIGHTLIFTING"), # Friday 17:00 WEIGHTLIFTING
|
|
||||||
(5, "12:30", "HYROX"), # Saturday 12:30 HYROX
|
|
||||||
(2, "18:30", "CONDITIONING"), # Wednesday 18:30 CONDITIONING
|
|
||||||
# (5, "15:15", "BIG WOD") # Saturday 15:15 BIG WOD
|
|
||||||
]
|
|
||||||
|
|
||||||
# Configure logging once at script startup
|
|
||||||
logging.basicConfig(
|
|
||||||
level=logging.DEBUG, # Change to DEBUG for more detailed logs
|
|
||||||
format='%(asctime)s - %(levelname)s - %(message)s',
|
|
||||||
handlers=[
|
|
||||||
logging.FileHandler("log/crossfit_booking.log"),
|
|
||||||
logging.StreamHandler()
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
logging.getLogger("requests").setLevel(logging.WARNING)
|
|
||||||
logging.info("Logging enhanced with request library noise reduction")
|
|
||||||
|
|
||||||
class CrossFitBooker:
|
class CrossFitBooker:
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
version: '3.8'
|
|
||||||
|
|
||||||
services:
|
services:
|
||||||
crossfit-booker:
|
crossfit-booker:
|
||||||
|
|||||||
17
preferred_sessions.json
Normal file
17
preferred_sessions.json
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"day_of_week": 2,
|
||||||
|
"start_time": "18:30",
|
||||||
|
"session_name_contains": "CONDITIONING"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"day_of_week": 4,
|
||||||
|
"start_time": "17:00",
|
||||||
|
"session_name_contains": "WEIGHTLIFTING"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"day_of_week": 5,
|
||||||
|
"start_time": "12:30",
|
||||||
|
"session_name_contains": "HYROX"
|
||||||
|
}
|
||||||
|
]
|
||||||
42
session_config.py
Normal file
42
session_config.py
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
import json
|
||||||
|
import logging
|
||||||
|
from typing import List, Tuple
|
||||||
|
|
||||||
|
# Class to handle session configuration
|
||||||
|
class SessionConfig:
|
||||||
|
"""
|
||||||
|
Class to handle loading and managing preferred sessions configuration.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def load_preferred_sessions():
|
||||||
|
"""
|
||||||
|
Load preferred sessions from a JSON file.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
List[Tuple[int, str, str]]: List of preferred sessions in the format
|
||||||
|
(day_of_week, start_time, session_name_contains)
|
||||||
|
"""
|
||||||
|
preferred_sessions = []
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open("preferred_sessions.json", "r") as f:
|
||||||
|
data = json.load(f)
|
||||||
|
for item in data:
|
||||||
|
day_of_week = item.get("day_of_week", 0)
|
||||||
|
start_time = item.get("start_time", "00:00")
|
||||||
|
session_name_contains = item.get("session_name_contains", "")
|
||||||
|
preferred_sessions.append((day_of_week, start_time, session_name_contains))
|
||||||
|
except (FileNotFoundError, json.JSONDecodeError) as e:
|
||||||
|
logging.warning(f"Failed to load preferred sessions from file: {str(e)}")
|
||||||
|
# Fall back to default hardcoded sessions
|
||||||
|
# preferred_sessions = [
|
||||||
|
# (2, "18:30", "CONDITIONING"), # Wednesday 18:30 CONDITIONING
|
||||||
|
# (4, "17:00", "WEIGHTLIFTING"), # Friday 17:00 WEIGHTLIFTING
|
||||||
|
# (5, "12:30", "HYROX"), # Saturday 12:30 HYROX
|
||||||
|
# ]
|
||||||
|
|
||||||
|
return preferred_sessions
|
||||||
|
|
||||||
|
# Load preferred sessions using the SessionConfig class
|
||||||
|
PREFERRED_SESSIONS = SessionConfig.load_preferred_sessions()
|
||||||
Reference in New Issue
Block a user