diff --git a/src/alpine_bits_python/api.py b/src/alpine_bits_python/api.py index a0ef4fb..cacdab9 100644 --- a/src/alpine_bits_python/api.py +++ b/src/alpine_bits_python/api.py @@ -78,12 +78,13 @@ event_dispatcher = EventDispatcher() async def push_listener(customer: DBCustomer, reservation: DBReservation, hotel): """Push listener that sends reservation data to hotel's push endpoint. + Only called for reservations that match this hotel's hotel_id. """ push_endpoint = hotel.get("push_endpoint") if not push_endpoint: _LOGGER.warning( - f"No push endpoint configured for hotel {hotel.get('hotel_id')}" + "No push endpoint configured for hotel %s", hotel.get("hotel_id") ) return @@ -94,12 +95,16 @@ async def push_listener(customer: DBCustomer, reservation: DBReservation, hotel) # Double-check hotel matching (should be guaranteed by dispatcher) if hotel_id != reservation_hotel_id: _LOGGER.warning( - f"Hotel ID mismatch: listener for {hotel_id}, reservation for {reservation_hotel_id}" + "Hotel ID mismatch: listener for %s, reservation for %s", + hotel_id, + reservation_hotel_id, ) return _LOGGER.info( - f"Processing push notification for hotel {hotel_id}, reservation {reservation.unique_id}" + "Processing push notification for hotel %s, reservation %s", + hotel_id, + reservation.unique_id, ) # Prepare payload for push notification @@ -113,15 +118,18 @@ async def push_listener(customer: DBCustomer, reservation: DBReservation, hotel) if request.status_code != 200: _LOGGER.error( - f"Failed to generate push request for hotel {hotel_id}, reservation {reservation.unique_id}: {request.xml_content}" + "Failed to generate push request for hotel %s, reservation %s: %s", + hotel_id, + reservation.unique_id, + request.xml_content, ) return # save push request to file logs_dir = "logs/push_requests" - if not os.path.exists(logs_dir): - os.makedirs(logs_dir, mode=0o755, exist_ok=True) + if not Path.exists(logs_dir): + Path.mkdir(logs_dir, mode=0o755, exist_ok=True) stat_info = os.stat(logs_dir) _LOGGER.info( f"Created directory owner: uid:{stat_info.st_uid}, gid:{stat_info.st_gid}" diff --git a/src/alpine_bits_python/config_loader.py b/src/alpine_bits_python/config_loader.py index ed4e4a4..168a916 100644 --- a/src/alpine_bits_python/config_loader.py +++ b/src/alpine_bits_python/config_loader.py @@ -13,14 +13,36 @@ from voluptuous import ( Schema, ) +from alpine_bits_python.const import ( + CONF_ALPINE_BITS_AUTH, + CONF_DATABASE, + CONF_HOTEL_ID, + CONF_HOTEL_NAME, + CONF_LOGGING, + CONF_LOGGING_FILE, + CONF_LOGGING_LEVEL, + CONF_PASSWORD, + CONF_PUSH_ENDPOINT, + CONF_PUSH_TOKEN, + CONF_PUSH_URL, + CONF_PUSH_USERNAME, + CONF_SERVER, + CONF_SERVER_CODE, + CONF_SERVER_CODECONTEXT, + CONF_SERVER_COMPANYNAME, + CONF_SERVER_RES_ID_SOURCE_CONTEXT, + CONF_USERNAME, + ENV_ALPINE_BITS_CONFIG_PATH, +) + # --- Voluptuous schemas --- database_schema = Schema({Required("url"): str}, extra=PREVENT_EXTRA) logger_schema = Schema( { - Required("level"): str, - Optional("file"): str, # If not provided, log to console + Required(CONF_LOGGING_LEVEL, default="INFO"): str, + Optional(CONF_LOGGING_FILE): str, # If not provided, log to console }, extra=PREVENT_EXTRA, ) @@ -35,24 +57,24 @@ def ensure_string(value): server_info = Schema( { - Required("codecontext", default="ADVERTISING"): ensure_string, - Required("code", default="70597314"): ensure_string, - Required("companyname", default="99tales Gmbh"): ensure_string, - Required("res_id_source_context", default="99tales"): ensure_string, + Required(CONF_SERVER_CODECONTEXT, default="ADVERTISING"): ensure_string, + Required(CONF_SERVER_CODE, default="70597314"): ensure_string, + Required(CONF_SERVER_COMPANYNAME, default="99tales Gmbh"): ensure_string, + Required(CONF_SERVER_RES_ID_SOURCE_CONTEXT, default="99tales"): ensure_string, } ) hotel_auth_schema = Schema( { - Required("hotel_id"): ensure_string, - Required("hotel_name"): str, - Required("username"): str, - Required("password"): str, - Optional("push_endpoint"): { - Required("url"): str, - Required("token"): str, - Optional("username"): str, + Required(CONF_HOTEL_ID): ensure_string, + Required(CONF_HOTEL_NAME): str, + Required(CONF_USERNAME): str, + Required(CONF_PASSWORD): str, + Optional(CONF_PUSH_ENDPOINT): { + Required(CONF_PUSH_URL): str, + Required(CONF_PUSH_TOKEN): str, + Optional(CONF_PUSH_USERNAME): str, }, }, extra=PREVENT_EXTRA, @@ -62,10 +84,10 @@ basic_auth_schema = Schema(All([hotel_auth_schema], Length(min=1))) config_schema = Schema( { - Required("database"): database_schema, - Required("alpine_bits_auth"): basic_auth_schema, - Required("server"): server_info, - Optional("logger", default={"level": "INFO", "file": None}): logger_schema, + Required(CONF_DATABASE): database_schema, + Required(CONF_ALPINE_BITS_AUTH): basic_auth_schema, + Required(CONF_SERVER): server_info, + Required(CONF_LOGGING): logger_schema, }, extra=PREVENT_EXTRA, ) @@ -81,15 +103,13 @@ class Config: testing_mode: bool = False, ): if config_folder is None: - config_folder = os.environ.get("ALPINEBITS_CONFIG_DIR") + config_folder = os.environ.get(ENV_ALPINE_BITS_CONFIG_PATH) if not config_folder: - config_folder = os.path.abspath( - os.path.join(os.path.dirname(__file__), "../../config") - ) + config_folder = Path(__file__).parent.joinpath("../../config").resolve() if isinstance(config_folder, str): config_folder = Path(config_folder) self.config_folder = config_folder - self.config_path = os.path.join(config_folder, config_name) + self.config_path = config_folder / config_name self.secrets = Secrets(config_folder) self.testing_mode = testing_mode self._load_config() diff --git a/src/alpine_bits_python/const.py b/src/alpine_bits_python/const.py index 743289d..7e4d2ce 100644 --- a/src/alpine_bits_python/const.py +++ b/src/alpine_bits_python/const.py @@ -1,3 +1,34 @@ +from typing import Final + RESERVATION_ID_TYPE: str = ( "13" # Default reservation ID type for Reservation. 14 would be cancellation ) + + +CONF_LOGGING: Final[str] = "logger" + +CONF_LOGGING_LEVEL: Final[str] = "level" +CONF_LOGGING_FILE: Final[str] = "file" + + +CONF_DATABASE: Final[str] = "database" + + +CONF_SERVER: Final[str] = "server" +CONF_SERVER_CODECONTEXT: Final[str] = "codecontext" +CONF_SERVER_CODE: Final[str] = "code" +CONF_SERVER_COMPANYNAME: Final[str] = "companyname" +CONF_SERVER_RES_ID_SOURCE_CONTEXT: Final[str] = "res_id_source_context" + + +CONF_ALPINE_BITS_AUTH: Final[str] = "alpine_bits_auth" +CONF_HOTEL_ID: Final[str] = "hotel_id" +CONF_HOTEL_NAME: Final[str] = "hotel_name" +CONF_USERNAME: Final[str] = "username" +CONF_PASSWORD: Final[str] = "password" +CONF_PUSH_ENDPOINT: Final[str] = "push_endpoint" +CONF_PUSH_URL: Final[str] = "url" +CONF_PUSH_TOKEN: Final[str] = "token" +CONF_PUSH_USERNAME: Final[str] = "username" + +ENV_ALPINE_BITS_CONFIG_PATH: Final[str] = "ALPINE_BITS_CONFIG_DIR"