refactor: Move files into src directory
Refactored project structure: Moved all Python modules to a src/ directory, updated imports accordingly. Added new environment variables to Dockerfile and docker-compose.yml. Removed Dockerfile.test and TODO file.
This commit is contained in:
@@ -5,6 +5,8 @@ FROM python:3.11-slim
|
|||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
# Set environment variables using the ARG values
|
# Set environment variables using the ARG values
|
||||||
|
ENV TARGET_RESERVATION_TIME=${TARGET_RESERVATION_TIME}
|
||||||
|
ENV BOOKING_WINDOW_END_DELTA_MINUTES=${BOOKING_WINDOW_END_DELTA_MINUTES}
|
||||||
ENV CROSSFIT_USERNAME=${CROSSFIT_USERNAME}
|
ENV CROSSFIT_USERNAME=${CROSSFIT_USERNAME}
|
||||||
ENV CROSSFIT_PASSWORD=${CROSSFIT_PASSWORD}
|
ENV CROSSFIT_PASSWORD=${CROSSFIT_PASSWORD}
|
||||||
ENV EMAIL_FROM=${EMAIL_FROM}
|
ENV EMAIL_FROM=${EMAIL_FROM}
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
# Use the official Python image from the Docker Hub
|
|
||||||
FROM python:3.11-slim
|
|
||||||
|
|
||||||
# Set the working directory
|
|
||||||
WORKDIR /app
|
|
||||||
|
|
||||||
# Copy the requirements file into the container
|
|
||||||
COPY requirements.txt .
|
|
||||||
|
|
||||||
# Install the dependencies
|
|
||||||
RUN pip install --no-cache-dir -r requirements.txt
|
|
||||||
|
|
||||||
# Copy the rest of the application code
|
|
||||||
COPY . .
|
|
||||||
|
|
||||||
# Run the test script
|
|
||||||
CMD ["python", "test_telegram_notifier.py"]
|
|
||||||
36
TODO
36
TODO
@@ -1,36 +0,0 @@
|
|||||||
Missing or Inadequate Test Coverage
|
|
||||||
1. SessionConfig Class (session_config.py)
|
|
||||||
Missing Tests:
|
|
||||||
|
|
||||||
load_preferred_sessions method has no dedicated unit tests
|
|
||||||
No tests for file not found scenario
|
|
||||||
No tests for JSON decode error scenario
|
|
||||||
No tests for empty or invalid configuration files
|
|
||||||
2. SessionNotifier Class (session_notifier.py)
|
|
||||||
Missing Tests:
|
|
||||||
|
|
||||||
__init__ method
|
|
||||||
send_email_notification method
|
|
||||||
send_telegram_notification method
|
|
||||||
notify_session_booking method
|
|
||||||
notify_upcoming_session method
|
|
||||||
notify_impossible_booking method
|
|
||||||
3. CrossFitBooker Class (crossfit_booker_functional.py) - Missing Tests
|
|
||||||
get_auth_headers function (functional version)
|
|
||||||
prepare_booking_data function
|
|
||||||
is_bookable_and_preferred function
|
|
||||||
process_booking_results function
|
|
||||||
is_upcoming_preferred function
|
|
||||||
4. CrossFitBooker Class (crossfit_booker.py) - Missing Tests
|
|
||||||
is_session_bookable method (non-functional version)
|
|
||||||
_make_request method
|
|
||||||
5. Integration and Edge Cases
|
|
||||||
No tests for the main entry point (book_crossfit.py)
|
|
||||||
Limited testing of error conditions and edge cases for many methods
|
|
||||||
No performance or stress tests
|
|
||||||
No tests for concurrent booking scenarios
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Add integration tests for the complete booking flow
|
|
||||||
Improve edge case coverage in existing tests
|
|
||||||
@@ -9,6 +9,8 @@ services:
|
|||||||
- TZ=Europe/Paris
|
- TZ=Europe/Paris
|
||||||
- CROSSFIT_USERNAME=${CROSSFIT_USERNAME}
|
- CROSSFIT_USERNAME=${CROSSFIT_USERNAME}
|
||||||
- CROSSFIT_PASSWORD=${CROSSFIT_PASSWORD}
|
- CROSSFIT_PASSWORD=${CROSSFIT_PASSWORD}
|
||||||
|
- TARGET_RESERVATION_TIME=${TARGET_RESERVATION_TIME}
|
||||||
|
- BOOKING_WINDOW_END_DELTA_MINUTES=${BOOKING_WINDOW_END_DELTA_MINUTES}
|
||||||
- SMTP_SERVER=${SMTP_SERVER}
|
- SMTP_SERVER=${SMTP_SERVER}
|
||||||
- EMAIL_FROM=${EMAIL_FROM}
|
- EMAIL_FROM=${EMAIL_FROM}
|
||||||
- EMAIL_TO=${EMAIL_TO}
|
- EMAIL_TO=${EMAIL_TO}
|
||||||
|
|||||||
2
main.py
2
main.py
@@ -6,7 +6,7 @@ This script initializes the CrossFitBooker and starts the booking process.
|
|||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
from crossfit_booker import CrossFitBooker
|
from src.crossfit_booker import CrossFitBooker
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
"""
|
"""
|
||||||
|
|||||||
0
src/__init__.py
Normal file
0
src/__init__.py
Normal file
@@ -14,13 +14,16 @@ from urllib.parse import urlencode
|
|||||||
from typing import List, Dict, Optional, Any, Tuple
|
from typing import List, Dict, Optional, Any, Tuple
|
||||||
|
|
||||||
# Import the SessionNotifier class
|
# Import the SessionNotifier class
|
||||||
from session_notifier import SessionNotifier
|
from src.session_notifier import SessionNotifier
|
||||||
|
|
||||||
# Import the preferred sessions from the session_config module
|
# Import the preferred sessions from the session_config module
|
||||||
from session_config import PREFERRED_SESSIONS
|
from src.session_config import PREFERRED_SESSIONS
|
||||||
|
|
||||||
# Import the AuthHandler class
|
# Import the AuthHandler class
|
||||||
from auth import AuthHandler
|
from src.auth import AuthHandler
|
||||||
|
|
||||||
|
# Import SessionManager
|
||||||
|
from src.session_manager import SessionManager
|
||||||
|
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
|
|
||||||
@@ -238,7 +241,6 @@ class Booker:
|
|||||||
Returns:
|
Returns:
|
||||||
Optional[Dict[str, Any]]: Dictionary containing available sessions if successful, None otherwise.
|
Optional[Dict[str, Any]]: Dictionary containing available sessions if successful, None otherwise.
|
||||||
"""
|
"""
|
||||||
from session_manager import SessionManager
|
|
||||||
session_manager = SessionManager(self.auth_handler)
|
session_manager = SessionManager(self.auth_handler)
|
||||||
return session_manager.get_available_sessions(start_date, end_date)
|
return session_manager.get_available_sessions(start_date, end_date)
|
||||||
|
|
||||||
@@ -252,7 +254,6 @@ class Booker:
|
|||||||
Returns:
|
Returns:
|
||||||
bool: True if booking is successful, False otherwise.
|
bool: True if booking is successful, False otherwise.
|
||||||
"""
|
"""
|
||||||
from session_manager import SessionManager
|
|
||||||
session_manager = SessionManager(self.auth_handler)
|
session_manager = SessionManager(self.auth_handler)
|
||||||
return session_manager.book_session(session_id)
|
return session_manager.book_session(session_id)
|
||||||
|
|
||||||
@@ -263,7 +264,6 @@ class Booker:
|
|||||||
Returns:
|
Returns:
|
||||||
A list of dictionaries containing information about the booked sessions.
|
A list of dictionaries containing information about the booked sessions.
|
||||||
"""
|
"""
|
||||||
from session_manager import SessionManager
|
|
||||||
session_manager = SessionManager(self.auth_handler)
|
session_manager = SessionManager(self.auth_handler)
|
||||||
return session_manager.get_booked_sessions()
|
return session_manager.get_booked_sessions()
|
||||||
|
|
||||||
@@ -278,7 +278,6 @@ class Booker:
|
|||||||
Returns:
|
Returns:
|
||||||
bool: True if the session is bookable, False otherwise.
|
bool: True if the session is bookable, False otherwise.
|
||||||
"""
|
"""
|
||||||
from session_manager import SessionManager
|
|
||||||
session_manager = SessionManager(self.auth_handler)
|
session_manager = SessionManager(self.auth_handler)
|
||||||
return session_manager.is_session_bookable(session, current_time)
|
return session_manager.is_session_bookable(session, current_time)
|
||||||
|
|
||||||
@@ -293,7 +292,6 @@ class Booker:
|
|||||||
Returns:
|
Returns:
|
||||||
bool: True if the session matches a preferred session, False otherwise.
|
bool: True if the session matches a preferred session, False otherwise.
|
||||||
"""
|
"""
|
||||||
from session_manager import SessionManager
|
|
||||||
session_manager = SessionManager(self.auth_handler)
|
session_manager = SessionManager(self.auth_handler)
|
||||||
return session_manager.matches_preferred_session(session, current_time)
|
return session_manager.matches_preferred_session(session, current_time)
|
||||||
|
|
||||||
@@ -305,6 +303,5 @@ class Booker:
|
|||||||
sessions (List[Dict[str, Any]]): List of session data.
|
sessions (List[Dict[str, Any]]): List of session data.
|
||||||
current_time (datetime): Current time for comparison.
|
current_time (datetime): Current time for comparison.
|
||||||
"""
|
"""
|
||||||
from session_manager import SessionManager
|
|
||||||
session_manager = SessionManager(self.auth_handler)
|
session_manager = SessionManager(self.auth_handler)
|
||||||
session_manager.display_upcoming_sessions(sessions, current_time)
|
session_manager.display_upcoming_sessions(sessions, current_time)
|
||||||
@@ -4,16 +4,16 @@ import os
|
|||||||
from typing import Dict, Any, Optional
|
from typing import Dict, Any, Optional
|
||||||
|
|
||||||
# Import the AuthHandler class
|
# Import the AuthHandler class
|
||||||
from auth import AuthHandler
|
from src.auth import AuthHandler
|
||||||
|
|
||||||
# Import the SessionManager class
|
# Import the SessionManager class
|
||||||
from session_manager import SessionManager
|
from src.session_manager import SessionManager
|
||||||
|
|
||||||
# Import the Booker class
|
# Import the Booker class
|
||||||
from booker import Booker
|
from src.booker import Booker
|
||||||
|
|
||||||
# Import the SessionNotifier class
|
# Import the SessionNotifier class
|
||||||
from session_notifier import SessionNotifier
|
from src.session_notifier import SessionNotifier
|
||||||
|
|
||||||
# Load environment variables
|
# Load environment variables
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
@@ -11,10 +11,10 @@ import requests
|
|||||||
from dateutil.parser import parse
|
from dateutil.parser import parse
|
||||||
|
|
||||||
# Import the preferred sessions from the session_config module
|
# Import the preferred sessions from the session_config module
|
||||||
from session_config import PREFERRED_SESSIONS
|
from src.session_config import PREFERRED_SESSIONS
|
||||||
|
|
||||||
# Import the AuthHandler class
|
# Import the AuthHandler class
|
||||||
from auth import AuthHandler
|
from src.auth import AuthHandler
|
||||||
|
|
||||||
class SessionManager:
|
class SessionManager:
|
||||||
"""
|
"""
|
||||||
Reference in New Issue
Block a user