pysportbot 0.0.1__py3-none-any.whl → 0.0.2__py3-none-any.whl

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/__init__.py CHANGED
@@ -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}")
pysportbot/centres.py CHANGED
@@ -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
 
@@ -1,8 +1,8 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pysportbot
3
- Version: 0.0.1
3
+ Version: 0.0.2
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
 
@@ -1,22 +1,22 @@
1
- pysportbot/__init__.py,sha256=s10xvSr9vq-naixIWa2Yizmj5fYnlNvMEEPoFA2looY,4754
1
+ pysportbot/__init__.py,sha256=4z5KKwrnwj_uiZYTUNgZIw_7s8ZT9C-Olz8_hzhPutw,4919
2
2
  pysportbot/activities.py,sha256=dyZDme6CidsBeGqB9lIHFYmlRKTmDLvTJGPoize17B0,4247
3
3
  pysportbot/authenticator.py,sha256=xEU9O6W6Yp9DCueoUD0ASMkm17yvdUZqTvV4h6WlSnI,5012
4
4
  pysportbot/bookings.py,sha256=vJ0kw74qyirZlbQ7M9XqlKtRoGzuHR0_t6-zUdgldkI,3123
5
- pysportbot/centres.py,sha256=f4OV_rJ4lO-mK7jZ165n-A62vVe09RKkl8Br_kXaq88,3398
5
+ pysportbot/centres.py,sha256=FTK-tXUOxiJvLCHP6Bk9XEQKODQZOwwkYLlioSJPBEk,3399
6
6
  pysportbot/endpoints.py,sha256=ANh5JAbdzyZQ-i4ODrhYlskPpU1gkBrw9UhMC7kRSvU,1353
7
7
  pysportbot/service/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
- pysportbot/service/__main__.py,sha256=bwpUt4udTBhcxkIozVaWBhwoTC5rtRWm36E6DBiWlQI,1182
8
+ pysportbot/service/__main__.py,sha256=egQ68-BFzvshF8d5DbVKI6ooL46pPD12v_T64CAbza0,1320
9
9
  pysportbot/service/booking.py,sha256=CNeMhYFAFi1UXIwAqtx8fKuO5jUsmnuf7VaSmkwIX1c,5425
10
10
  pysportbot/service/config_loader.py,sha256=elNNwcC7kwc0lmRqj95hAA50qSmLelWv5G2E62tDxP0,185
11
11
  pysportbot/service/config_validator.py,sha256=lGsSP7ubD816CQb0fZNYtdHWIXsFsZWtRLIjAMjSJRw,2167
12
12
  pysportbot/service/scheduling.py,sha256=bwqbiQQ9y4ss4UXZkWuOVCgCa9XlZt1n4TT_8z9bD7M,1973
13
- pysportbot/service/service.py,sha256=fW20cxAqfpPEMlLrooL13aFjwFVnZUKILFlDuuo_UBA,1121
13
+ pysportbot/service/service.py,sha256=JMq71x6KpaS16HRIfNTL8aLiiCT85PTmCLBIcebcK1U,1294
14
14
  pysportbot/session.py,sha256=pTQrz3bGzLYBtzVOgKv04l4UXDSgtA3Infn368bjg5I,1529
15
15
  pysportbot/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
16
  pysportbot/utils/errors.py,sha256=sUSs04yr_OmZeTywi1fzPsjVjkLd5iTpXlzlQqNKmgQ,5162
17
- pysportbot/utils/logger.py,sha256=KTjHEKExC5t00L1EGNN_IjA5JogTVTjzZg7hVRvYq_8,2333
17
+ pysportbot/utils/logger.py,sha256=_31g_qY4_aCMSXKo-63e10CwAs7ug7vSuq6TMNoRmek,3534
18
18
  pysportbot/utils/time.py,sha256=VZSW8AxFIoFD5ZSmLUPcwawp6PmpkcxNjP3Db-Hl_fw,1244
19
- pysportbot-0.0.1.dist-info/LICENSE,sha256=6ov3DypdEVYpp2pn_B1MniKWO5C9iDA4O6PGcbork6c,1077
20
- pysportbot-0.0.1.dist-info/METADATA,sha256=IO7N0DlnwHyrrZqy4EwbcrRrtRusrKktahUGpRmhkG4,5189
21
- pysportbot-0.0.1.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
22
- pysportbot-0.0.1.dist-info/RECORD,,
19
+ pysportbot-0.0.2.dist-info/LICENSE,sha256=6ov3DypdEVYpp2pn_B1MniKWO5C9iDA4O6PGcbork6c,1077
20
+ pysportbot-0.0.2.dist-info/METADATA,sha256=QhwVsv4EN1PCfQ-IPK8Yycazh60FbUkj3xZWN_lLZgU,5342
21
+ pysportbot-0.0.2.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
22
+ pysportbot-0.0.2.dist-info/RECORD,,