pysportbot 0.0.1__tar.gz → 0.0.3__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.
Files changed (22) hide show
  1. {pysportbot-0.0.1 → pysportbot-0.0.3}/PKG-INFO +9 -8
  2. {pysportbot-0.0.1 → pysportbot-0.0.3}/README.md +5 -4
  3. {pysportbot-0.0.1 → pysportbot-0.0.3}/pyproject.toml +3 -3
  4. {pysportbot-0.0.1 → pysportbot-0.0.3}/pysportbot/__init__.py +5 -2
  5. {pysportbot-0.0.1 → pysportbot-0.0.3}/pysportbot/centres.py +3 -2
  6. {pysportbot-0.0.1 → pysportbot-0.0.3}/pysportbot/service/__main__.py +3 -1
  7. {pysportbot-0.0.1 → pysportbot-0.0.3}/pysportbot/service/service.py +6 -4
  8. {pysportbot-0.0.1 → pysportbot-0.0.3}/pysportbot/utils/logger.py +39 -4
  9. {pysportbot-0.0.1 → pysportbot-0.0.3}/LICENSE +0 -0
  10. {pysportbot-0.0.1 → pysportbot-0.0.3}/pysportbot/activities.py +0 -0
  11. {pysportbot-0.0.1 → pysportbot-0.0.3}/pysportbot/authenticator.py +0 -0
  12. {pysportbot-0.0.1 → pysportbot-0.0.3}/pysportbot/bookings.py +0 -0
  13. {pysportbot-0.0.1 → pysportbot-0.0.3}/pysportbot/endpoints.py +0 -0
  14. {pysportbot-0.0.1 → pysportbot-0.0.3}/pysportbot/service/__init__.py +0 -0
  15. {pysportbot-0.0.1 → pysportbot-0.0.3}/pysportbot/service/booking.py +0 -0
  16. {pysportbot-0.0.1 → pysportbot-0.0.3}/pysportbot/service/config_loader.py +0 -0
  17. {pysportbot-0.0.1 → pysportbot-0.0.3}/pysportbot/service/config_validator.py +0 -0
  18. {pysportbot-0.0.1 → pysportbot-0.0.3}/pysportbot/service/scheduling.py +0 -0
  19. {pysportbot-0.0.1 → pysportbot-0.0.3}/pysportbot/session.py +0 -0
  20. {pysportbot-0.0.1 → pysportbot-0.0.3}/pysportbot/utils/__init__.py +0 -0
  21. {pysportbot-0.0.1 → pysportbot-0.0.3}/pysportbot/utils/errors.py +0 -0
  22. {pysportbot-0.0.1 → pysportbot-0.0.3}/pysportbot/utils/time.py +0 -0
@@ -1,8 +1,8 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pysportbot
3
- Version: 0.0.1
3
+ Version: 0.0.3
4
4
  Summary: A python-based bot for automatic resasports slot booking
5
- Home-page: https://github.com/jbeirer/pysportbot
5
+ Home-page: https://github.com/jbeirer/resasports-bot
6
6
  Author: Joshua Falco Beirer
7
7
  Author-email: jbeirer@cern.ch
8
8
  Requires-Python: >=3.9,<3.13
@@ -16,8 +16,8 @@ Requires-Dist: pandas (>=2.2.3,<3.0.0)
16
16
  Requires-Dist: pytz (>=2024.2,<2025.0)
17
17
  Requires-Dist: requests (>=2.32.3,<3.0.0)
18
18
  Requires-Dist: schedule (>=1.2.2,<2.0.0)
19
- Project-URL: Documentation, https://jbeirer.github.io/pysportbot/
20
- Project-URL: Repository, https://github.com/jbeirer/pysportbot
19
+ Project-URL: Documentation, https://jbeirer.github.io/resasports-bot/
20
+ Project-URL: Repository, https://github.com/jbeirer/resasports-bot
21
21
  Description-Content-Type: text/markdown
22
22
 
23
23
  # No queues. Just gains.
@@ -44,8 +44,8 @@ pip install pysportbot
44
44
  ```python
45
45
  from pysportbot import SportBot
46
46
 
47
- # Create bot instance, will list available centres is requested
48
- bot = SportBot(log_level='INFO', print_centres=False)
47
+ # Create bot instance, will list available centres if requested
48
+ bot = SportBot(log_level='INFO', print_centres=False, time_zone = 'Europe/Madrid')
49
49
 
50
50
  # Connect to service with email and password as well as the name of the centre
51
51
  bot.login('email', 'password', 'centre')
@@ -59,7 +59,7 @@ bot.daily_slots(activity='YourFavouriteGymClass', day = '2025-01-03', limit = 10
59
59
  # Book an activity slot on a specific day and time
60
60
  bot.book(activity='YourFavouriteGymClass', start_time = '2024-12-30 07:00:00')
61
61
 
62
- # Cancel an activity slot ona specific day and time
62
+ # Cancel an activity slot on a specific day and time
63
63
  bot.cancel(activity='YourFavouriteGymClass', start_time = '2024-12-30 07:00:00')
64
64
  ```
65
65
 
@@ -139,7 +139,8 @@ python -m pysportbot.service --help
139
139
  Currently supported options include
140
140
  1. ```--retry-attempts``` sets the number of retries attempted in case a booking attempt fails
141
141
  2. ```--retry-delay-minutes``` sets the delay in minutes between retries for weekly bookings
142
- 3. ```--time_zone``` sets the time zone for the service
142
+ 3. ```--time-zone``` sets the time zone for the service (e.g. Europe/Madrid)
143
+ 4. ```--log-level``` sets the log-level of the service (e.g. DEBUG, INFO, WARNING, ERROR)
143
144
 
144
145
  ## LICENSE
145
146
 
@@ -22,8 +22,8 @@ pip install pysportbot
22
22
  ```python
23
23
  from pysportbot import SportBot
24
24
 
25
- # Create bot instance, will list available centres is requested
26
- bot = SportBot(log_level='INFO', print_centres=False)
25
+ # Create bot instance, will list available centres if requested
26
+ bot = SportBot(log_level='INFO', print_centres=False, time_zone = 'Europe/Madrid')
27
27
 
28
28
  # Connect to service with email and password as well as the name of the centre
29
29
  bot.login('email', 'password', 'centre')
@@ -37,7 +37,7 @@ bot.daily_slots(activity='YourFavouriteGymClass', day = '2025-01-03', limit = 10
37
37
  # Book an activity slot on a specific day and time
38
38
  bot.book(activity='YourFavouriteGymClass', start_time = '2024-12-30 07:00:00')
39
39
 
40
- # Cancel an activity slot ona specific day and time
40
+ # Cancel an activity slot on a specific day and time
41
41
  bot.cancel(activity='YourFavouriteGymClass', start_time = '2024-12-30 07:00:00')
42
42
  ```
43
43
 
@@ -117,7 +117,8 @@ python -m pysportbot.service --help
117
117
  Currently supported options include
118
118
  1. ```--retry-attempts``` sets the number of retries attempted in case a booking attempt fails
119
119
  2. ```--retry-delay-minutes``` sets the delay in minutes between retries for weekly bookings
120
- 3. ```--time_zone``` sets the time zone for the service
120
+ 3. ```--time-zone``` sets the time zone for the service (e.g. Europe/Madrid)
121
+ 4. ```--log-level``` sets the log-level of the service (e.g. DEBUG, INFO, WARNING, ERROR)
121
122
 
122
123
  ## LICENSE
123
124
 
@@ -1,10 +1,10 @@
1
1
  [tool.poetry]
2
2
  name = "pysportbot"
3
- version = "v0.0.1"
3
+ version = "v0.0.3"
4
4
  description = " A python-based bot for automatic resasports slot booking"
5
5
  authors = ["Joshua Falco Beirer <jbeirer@cern.ch>"]
6
- repository = "https://github.com/jbeirer/pysportbot"
7
- documentation = "https://jbeirer.github.io/pysportbot/"
6
+ repository = "https://github.com/jbeirer/resasports-bot"
7
+ documentation = "https://jbeirer.github.io/resasports-bot/"
8
8
  readme = "README.md"
9
9
  packages = [
10
10
  {include = "pysportbot"}
@@ -1,3 +1,5 @@
1
+ # pysportbot/sportbot.py
2
+
1
3
  import logging
2
4
  from typing import Optional
3
5
 
@@ -15,10 +17,12 @@ from .utils.logger import set_log_level, setup_logger
15
17
  class SportBot:
16
18
  """Unified interface for interacting with the booking system."""
17
19
 
18
- def __init__(self, log_level: str = "INFO", print_centres: bool = False) -> None:
20
+ def __init__(self, log_level: str = "INFO", print_centres: bool = False, time_zone: str = "Europe/Madrid") -> None:
19
21
  setup_logger(log_level)
20
22
  self._logger = logging.getLogger("SportBot")
21
23
  self._logger.info("Initializing SportBot...")
24
+ self._logger.info(f"Log level: {log_level}")
25
+ self._logger.info(f"Time zone: {time_zone}")
22
26
  self._centres = Centres(print_centres)
23
27
  self._session: Session = Session()
24
28
  self._auth: Optional[Authenticator] = None
@@ -32,7 +36,6 @@ class SportBot:
32
36
  self._logger.info(f"Log level changed to {log_level}.")
33
37
 
34
38
  def login(self, email: str, password: str, centre: str) -> None:
35
-
36
39
  # Check if the selected centre is valid
37
40
  self._centres.check_centre(centre)
38
41
  self._logger.info(f"Selected centre: {centre}")
@@ -33,12 +33,13 @@ class Centres:
33
33
  }
34
34
  }
35
35
  self._df_centres = self.fetch_centres()
36
- if print_centres:
37
- self.print_centres()
38
36
 
39
37
  # list of centre (slugs)
40
38
  self.centre_list = self._df_centres["slug"].tolist()
41
39
 
40
+ if print_centres:
41
+ self.print_centres()
42
+
42
43
  def check_centre(self, centre: str) -> None:
43
44
  """
44
45
  Set the user selected centre.
@@ -15,7 +15,8 @@ def main() -> None:
15
15
  parser.add_argument(
16
16
  "--retry-delay-minutes", type=int, default=2, help="Delay in minutes between retries for weekly bookings."
17
17
  )
18
- parser.add_argument("--time_zone", type=str, default="Europe/Madrid", help="Timezone for the service.")
18
+ parser.add_argument("--time-zone", type=str, default="Europe/Madrid", help="Timezone for the service.")
19
+ parser.add_argument("--log-level", type=str, default="INFO", help="Logging level for the service.")
19
20
  args = parser.parse_args()
20
21
 
21
22
  config: Dict[str, Any] = load_config(args.config)
@@ -25,6 +26,7 @@ def main() -> None:
25
26
  retry_attempts=args.retry_attempts,
26
27
  retry_delay_minutes=args.retry_delay_minutes,
27
28
  time_zone=args.time_zone,
29
+ log_level=args.log_level,
28
30
  )
29
31
 
30
32
 
@@ -9,8 +9,6 @@ from pysportbot.utils.logger import get_logger
9
9
  from .booking import schedule_bookings
10
10
  from .config_validator import validate_activities, validate_config
11
11
 
12
- logger = get_logger(__name__)
13
-
14
12
 
15
13
  def run_service(
16
14
  config: Dict[str, Any],
@@ -18,12 +16,16 @@ def run_service(
18
16
  retry_attempts: int,
19
17
  retry_delay_minutes: int,
20
18
  time_zone: str = "Europe/Madrid",
19
+ log_level: str = "INFO",
21
20
  ) -> None:
21
+ # Initialize service logger
22
+ logger = get_logger(__name__)
23
+ logger.setLevel(log_level)
22
24
 
23
25
  # Validate the configuration file
24
26
  validate_config(config)
25
-
26
- bot = SportBot()
27
+ # Initialize the SportBot instance
28
+ bot = SportBot(log_level=log_level, time_zone=time_zone)
27
29
  bot.login(config["email"], config["password"], config["centre"])
28
30
 
29
31
  # Validate the activities in the configuration file
@@ -1,5 +1,8 @@
1
1
  import logging
2
- from typing import ClassVar
2
+ from datetime import datetime
3
+ from typing import ClassVar, Optional
4
+
5
+ import pytz
3
6
 
4
7
  from .errors import ErrorMessages
5
8
 
@@ -15,6 +18,32 @@ class ColorFormatter(logging.Formatter):
15
18
  "RESET": "\033[0m", # Reset
16
19
  }
17
20
 
21
+ def __init__(self, fmt: str, datefmt: str, tz: pytz.BaseTzInfo) -> None:
22
+ """
23
+ Initialize the formatter with a specific timezone.
24
+
25
+ Args:
26
+ fmt (str): The log message format.
27
+ datefmt (str): The date format.
28
+ tz (pytz.BaseTzInfo): The timezone for log timestamps.
29
+ """
30
+ super().__init__(fmt, datefmt)
31
+ self.timezone = tz
32
+
33
+ def formatTime(self, record: logging.LogRecord, datefmt: Optional[str] = None) -> str:
34
+ """
35
+ Override to format the time in the desired timezone.
36
+
37
+ Args:
38
+ record (logging.LogRecord): The log record.
39
+ datefmt (Optional[str]): The date format.
40
+
41
+ Returns:
42
+ str: The formatted timestamp.
43
+ """
44
+ record_time = datetime.fromtimestamp(record.created, self.timezone)
45
+ return record_time.strftime(datefmt or self.default_time_format)
46
+
18
47
  def format(self, record: logging.LogRecord) -> str:
19
48
  """
20
49
  Format the log record with color-coded log levels.
@@ -30,12 +59,13 @@ class ColorFormatter(logging.Formatter):
30
59
  return super().format(record)
31
60
 
32
61
 
33
- def setup_logger(level: str = "INFO") -> None:
62
+ def setup_logger(level: str = "INFO", timezone: str = "Europe/Madrid") -> None:
34
63
  """
35
- Configure the root logger with color-coded output.
64
+ Configure the root logger with color-coded output in the specified timezone.
36
65
 
37
66
  Args:
38
67
  level (str): The desired logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL).
68
+ timezone (str): The desired timezone for log timestamps (e.g., Europe/Madrid).
39
69
  """
40
70
  root_logger = logging.getLogger()
41
71
  root_logger.setLevel(logging._nameToLevel[level.upper()])
@@ -43,7 +73,12 @@ def setup_logger(level: str = "INFO") -> None:
43
73
  if not root_logger.hasHandlers(): # Avoid duplicate handlers
44
74
  handler = logging.StreamHandler()
45
75
  handler.setLevel(logging._nameToLevel[level.upper()])
46
- formatter = ColorFormatter("[%(asctime)s] [%(levelname)s] %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
76
+ tz = pytz.timezone(timezone)
77
+ formatter = ColorFormatter(
78
+ "[%(asctime)s] [%(levelname)s] %(message)s",
79
+ datefmt="%Y-%m-%d %H:%M:%S",
80
+ tz=tz,
81
+ )
47
82
  handler.setFormatter(formatter)
48
83
  root_logger.addHandler(handler)
49
84
 
File without changes