diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..25c7260 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.env +log/ +!log/.gitkeep diff --git a/book_crossfit.py b/book_crossfit.py index 9415a95..6593f73 100755 --- a/book_crossfit.py +++ b/book_crossfit.py @@ -1,9 +1,21 @@ #!/usr/bin/env python3 -import requests +# Native modules import json -import time +import logging +from datetime import datetime, timedelta import os +import sys +import time + +# Third-party modules +import requests +from dateutil.parser import parse +import pytz +from dotenv import load_dotenv +from urllib.parse import urlencode +from typing import List, Dict, Optional + from datetime import datetime, timedelta # Parse session time (handles timezones if present) @@ -39,6 +51,17 @@ PREFERRED_SESSIONS = [ # (5, "15:15", "BIG WOD") # Saturday 15:15 BIG WOD ] +# Configure logging once at script startup +logging.basicConfig( + level=logging.INFO, + format='%(asctime)s - %(levelname)s - %(message)s', + handlers=[ + logging.FileHandler("log/crossfit_booking.log"), + logging.StreamHandler() + ] +) + + class CrossFitBooker: def __init__(self): self.auth_token = None @@ -176,9 +199,10 @@ class CrossFitBooker: def book_session(self, session_id: str) -> bool: """Book a specific session with debug logging.""" - print(f"\n[INFO] Attempting to book session_id: {session_id}") + + logging.info(f"Attempting to book session_id: {session_id}") if not self.auth_token or not self.user_id: - print("[ERROR] Not authenticated (missing auth_token or user_id)") + logging.error("Not authenticated: missing auth_token or user_id") return False try: @@ -206,27 +230,27 @@ class CrossFitBooker: data=urlencode(request_data) ) - print(f"[DEBUG] Response status: {response.status_code}") - print(f"[DEBUG] Response text: {response.text}") + logging.debug(f"Response status: {response.status_code}") + logging.debug(f"API response: {response.text}") if response.ok: try: json_response = response.json() if json_response.get("success", False): - print(f"[SUCCESS] Booked session {session_id}") + logging.info(f"Successfully booked session {session_id}") return True else: - print(f"[ERROR] API returned success:false: {json_response}") + logging.error(f"API returned success:false: {json_response}") return False except ValueError: - print("[ERROR] Invalid JSON response") + logging.error("Invalid JSON response") return False else: - print(f"[ERROR] HTTP {response.status_code}: {response.text}") + logging.error(f"HTTP {response.status_code}: {response.text}") return False except Exception as e: - print(f"[CRITICAL] Unexpected error: {str(e)}", exc_info=True) + logging.critical(f"Unexpected error: {str(e)}", exc_info=True) return False def is_session_bookable(self, session: Dict, current_time: datetime) -> bool: @@ -280,7 +304,7 @@ class CrossFitBooker: return False except Exception as e: - print(f"Error checking session: {str(e)}") + logging.error(f"Failed to check session: {str(e)}") return False def run_booking_cycle(self, current_time: datetime): @@ -330,7 +354,7 @@ class CrossFitBooker: # Initial login if not self.login(): - print("Failed to login, exiting") + logging.error("Authentication failed - exiting program") return while True: @@ -362,7 +386,7 @@ if __name__ == "__main__": session_data = booker.get_available_sessions(start_date, end_date) if not session_data or not session_data.get("success", False): - print("Failed to get session data") + logging.error("Failed to get session data") exit(1) activities = session_data.get("data", {}).get("activities_calendar", []) @@ -378,7 +402,7 @@ if __name__ == "__main__": bookable_sessions.append(session) # print(f"Bookable sessions: {json.dumps(bookable_sessions, indent=2)}") - print(f"\nFound {len(bookable_sessions)} sessions to book") + print(f"Found {len(bookable_sessions)} sessions to book") for session in bookable_sessions: diff --git a/crossfit.txt b/docs/crossfit.txt similarity index 100% rename from crossfit.txt rename to docs/crossfit.txt diff --git a/debug.txt b/docs/debug.txt similarity index 100% rename from debug.txt rename to docs/debug.txt diff --git a/sessions.json b/docs/sessions.json similarity index 100% rename from sessions.json rename to docs/sessions.json diff --git a/log/.gitkeep b/log/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/retrieve_sessions.py b/tools/retrieve_sessions.py similarity index 100% rename from retrieve_sessions.py rename to tools/retrieve_sessions.py