diff --git a/README.en.md b/README.en.md index e256577..0e51b62 100644 --- a/README.en.md +++ b/README.en.md @@ -57,6 +57,7 @@ The following steps must be performed for everyone who wants to receive messages - `birthday` - Birthday to be queried. Example: `23.06.1912`. - `group_size` - Size of the group for which an appointment is requested (2 to 15). Example: `5` - `zip_code` - Five-digit zip code for your vaccination center. Example: `49123` + - `with_vector` - For the under 60s: should also be searched for vector vaccines? Example: `true` - **\[EMAIL\]**: Email settings - `enable` - Specifies whether emails should be sent. `true` if yes, `false` otherwise. - `sender` - The email address from which the notifications should be sent. Example: `sender@server.tld`. @@ -89,6 +90,7 @@ The following steps must be performed for everyone who wants to receive messages [COMMON] zip_code=42042 birthdate=23.06.1912 +with_vector=true [EMAIL] enable=true diff --git a/README.md b/README.md index f45f4ce..5694a42 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,7 @@ Folgende Schritte muss für jeden ausgeführt werden, der Nachrichten empfangen - `birthdate` - Dein Geburtstag - Da die Verteilung vom Alter abhängig ist, ist dieser zwingend notwendig. Beispiel: `23.06.1912` - `group_size` - Gruppengröße - Wenn du lieber einen Gruppentermin suchen möchtest musst du birthdate auskommentieren und eine Gruppengröße angeben (zwischen 2 und 15). Es darf nur eins von beiden in der Config sein! Beispiel: `5` - `zip_code` - Fünfstellige PLZ für das Impfzentrum, das der Bot überwachen soll. Beispiel: `49123` + - `with_vector` - Für die unter 60-Jährigen: Soll auch nach Vector-Impfstoffen gesucht werden? Beispiel: `true` - **\[EMAIL\]**: E-Mail-Einstellungen. Bei manchen Anbietern müssen vorher bestimmte Einstellungen gemacht werden, eine Sammlung von Anleitungen findet ihr [hier](docs/SETUP_EMAIL_SERVICES.md). - `enable` - Legt fest, ob E-Mails versendet werden sollen. `true` wenn ja, sonst `false`. - `sender` - Die E-Mail-Adresse, von der die Benachrichtigungen versendet werden sollen. Beispiel: `sender@server.tld` @@ -96,6 +97,7 @@ Beispiel Config: [COMMON] zip_code=42042 birthdate=23.06.1912 +with_vector=true [EMAIL] enable=true diff --git a/config.example.ini b/config.example.ini index aecb0d1..910f090 100644 --- a/config.example.ini +++ b/config.example.ini @@ -5,6 +5,8 @@ birthdate=23.06.1912 ; group_size=5 ;;; Postleitzahl - Die Postleitzahl in der Impftermine gesucht werden. zip_code=42042 +;;; Für die unter 60-Jährigen: Soll auch nach Vector-Impfstoffen gesucht werden? Wenn ja 'true' sonst 'false' +with_vector=true [EMAIL] ;;; 'true' wenn eine Benachrichtigung per E-Mail gesendet werden soll, sonst 'false' diff --git a/src/api_wrapper.py b/src/api_wrapper.py index 9541ac5..d792493 100644 --- a/src/api_wrapper.py +++ b/src/api_wrapper.py @@ -14,22 +14,25 @@ class ShadowBanException(Exception): def fetch_api( - zip_code: int, - birthdate_timestamp: int = None, - group_size: int = None, - max_retries: int = 10, - sleep_after_error: int = 30, - jitter: int = 5, - user_agent: str = 'python' - ) -> any: + zip_code: int, + birthdate_timestamp: int = None, + group_size: int = None, + with_vector: bool = True, + max_retries: int = 10, + sleep_after_error: int = 30, + jitter: int = 5, + user_agent: str = 'python' +) -> any: """fetches the api with ip ban avoidance""" url = f"https://www.impfportal-niedersachsen.de/portal/rest/appointments/findVaccinationCenterListFree/{zip_code}?stiko=" if birthdate_timestamp: url += f"&count=1&birthdate={int(birthdate_timestamp)*1000}" elif group_size: url += f"&count={group_size}" + if with_vector: + url += f"&showWithVectorVaccine=true" fail_counter = 0 - + headers = { 'Accept': 'application/json', 'User-Agent': user_agent diff --git a/src/config_skeleton.py b/src/config_skeleton.py index 6c75be1..9021761 100644 --- a/src/config_skeleton.py +++ b/src/config_skeleton.py @@ -28,6 +28,11 @@ "default": None, "type": int, "regex": GROUP_SIZE_REGEX + }, + "with_vector": { + "default": True, + "type": bool, + "regex": BOOL_REGEX } }, "EMAIL": { diff --git a/src/impfbot.py b/src/impfbot.py index ee0fd39..6eb45bf 100644 --- a/src/impfbot.py +++ b/src/impfbot.py @@ -19,6 +19,7 @@ def check_for_slot() -> None: result = fetch_api( zip_code=settings.COMMON_ZIP_CODE, birthdate_timestamp=birthdate_timestamp, + with_vector=settings.COMMON_WITH_VECTOR, max_retries=10, sleep_after_error=settings.COOLDOWN_BETWEEN_FAILED_REQUESTS, user_agent=settings.USER_AGENT, @@ -28,6 +29,7 @@ def check_for_slot() -> None: result = fetch_api( zip_code=settings.COMMON_ZIP_CODE, group_size=settings.COMMON_GROUP_SIZE, + with_vector=settings.COMMON_WITH_VECTOR, max_retries=10, sleep_after_error=settings.COOLDOWN_BETWEEN_FAILED_REQUESTS, user_agent=settings.USER_AGENT, diff --git a/src/settings.py b/src/settings.py index 6f59aa0..d7e18bb 100644 --- a/src/settings.py +++ b/src/settings.py @@ -131,8 +131,18 @@ def __validate_option(section: str, option: str): f"[{section}] only one of 'birthdate' or 'group_size' is allowed in the same config.") else: if getattr(settings, option_name, None) is None: - raise ParseExeption( - f"[{section}] '{option}' must be in the config.") + if option_name == "COMMON_WITH_VECTOR": + if getattr(settings, option_name, None) is None: + value = SKELETON[section][option]["default"] + typ: any = SKELETON[section][option]["type"] + setattr(settings, option_name, typ(value)) + + __log.warning( + f"[{section}] '{option}' not set. Using default: '{value}'") + return + else: + raise ParseExeption( + f"[{section}] '{option}' must be in the config.") elif section in NOTIFIERS: option_name = f"{section.upper()}_{option.upper()}" diff --git a/tests/configs/test-config-valid.ini b/tests/configs/test-config-valid.ini index 16c6a8c..158791f 100644 --- a/tests/configs/test-config-valid.ini +++ b/tests/configs/test-config-valid.ini @@ -1,6 +1,7 @@ [COMMON] zip_code=30042 birthdate=23.6.1912 +with_vector=true [EMAIL] enable=true diff --git a/tests/test_impfbot.py b/tests/test_impfbot.py index ff1641f..c47a0dc 100644 --- a/tests/test_impfbot.py +++ b/tests/test_impfbot.py @@ -67,7 +67,7 @@ load("tests/configs/test-config-valid.ini") zip_code = settings.COMMON_ZIP_CODE -api_url = f'https://www.impfportal-niedersachsen.de/portal/rest/appointments/findVaccinationCenterListFree/{zip_code}?stiko=&count=1' +api_url = f'https://www.impfportal-niedersachsen.de/portal/rest/appointments/findVaccinationCenterListFree/{zip_code}?stiko=&count=1&showWithVectorVaccine=true' error_none = None @@ -88,7 +88,6 @@ def test_check_for_slot_in_stock(log_info_mock, mocker.get( url=api_url, json=in_stock - ) impfbot.check_for_slot() diff --git a/tests/test_settings.py b/tests/test_settings.py index 274deaa..536a246 100644 --- a/tests/test_settings.py +++ b/tests/test_settings.py @@ -144,10 +144,11 @@ def test_old(log_info_mock, # Check output assert log_info_mock.call_count == 1 - assert log_warning_mock.call_count == 12 + assert log_warning_mock.call_count == 13 for msg in log_warning_mock.call_args_list: assert (" is depracated please use: " in msg.args[0] or "[EMAIL] 'user' is missing; set sender as user" in msg.args[0] + or "[COMMON] 'with_vector' not set. Using default: 'True'" or "[ADVANCED] 'custom_message_prefix' not set. Using default: 'Impfbot'" in msg.args[0]) log_error_mock.assert_not_called() @@ -194,7 +195,7 @@ def test_missing_optional(log_info_mock, # Check output assert log_info_mock.call_count == 4 - assert log_warning_mock.call_count == 8 + assert log_warning_mock.call_count == 9 log_error_mock.assert_not_called() # EMAIL