def __check_werte(self, kontaktdaten: dict): """ Prüft mithilfe von den kontakt_tools ob alle Daten da und gültig sind Args: kontaktdaten (dict): Kontaktdaten Raises: ValidationError: Daten Fehlerhaft MissingValuesError: Daten Fehlen """ kontakt_tools.check_kontaktdaten(kontaktdaten, self.modus) if self.modus == Modus.TERMIN_SUCHEN: kontakt_tools.validate_kontaktdaten(kontaktdaten) elif self.modus == Modus.CODE_GENERIEREN: kontakt_tools.validate_plz_impfzentren( kontaktdaten["plz_impfzentren"]) kontakt_tools.validate_email( kontaktdaten["kontakt"]["notificationReceiver"]) try: kontakt_tools.validate_phone(kontaktdaten["kontakt"]["phone"]) except ValidationError as error: raise ValidationError( "Telefonnummer: +49 nicht vergessen") from error
def __check_werte(self, kontaktdaten: dict): """ Prüft mithilfe von den kontakt_tools ob alle Daten da und gültig sind Args: kontaktdaten (dict): Kontaktdaten modus: Modus der geprüft werden soll Raises: ValidationError: Daten Fehlerhaft MissingValuesError: Daten Fehlen """ kontakt_tools.check_kontaktdaten(kontaktdaten, self.modus) kontakt_tools.validate_kontaktdaten(kontaktdaten)
def input_kontaktdaten_key(kontaktdaten, path, prompt, transformer=lambda x: x): target = kontaktdaten for key in path[:-1]: target = target[key] key = path[-1] while True: try: value = transformer(input(prompt).strip()) # Wenn transformer None zurückgibt, setzen wir den Key nicht. if value is not None: target[key] = value validate_kontaktdaten(kontaktdaten) break except ValidationError as exc: print(f"\n{str(exc)}\n")
def __lade_alle_werte(self): """ Lädt alle Kontaktdaten und den Suchzeitraum in das GUI """ try: kontaktdaten = kontakt_tools.get_kontaktdaten(self.standard_speicherpfad) if not kontaktdaten: # ToDo: Evtl. Meldung anzeigen return kontakt_tools.check_kontaktdaten(kontaktdaten, Modus.CODE_GENERIEREN) kontakt_tools.validate_kontaktdaten(kontaktdaten) self.i_plz_impfzentren.setText(self.__get_impfzentren_plz(kontaktdaten["plz_impfzentren"])) self.i_telefon.setText(kontaktdaten["kontakt"]["phone"]) self.i_mail.setText(kontaktdaten["kontakt"]["notificationReceiver"]) # Versuche alle Werte zu laden, wenn möglich try: kontakt_tools.check_kontaktdaten(kontaktdaten, Modus.TERMIN_SUCHEN) kontakt_tools.validate_kontaktdaten(kontaktdaten) except MissingValuesError as exc: return except ValidationError as exc: return # Wird nur bei Terminsuche benötigt self.__set_vermittlungscodes(kontaktdaten["codes"]) self.i_anrede_combo_box.setEditText(kontaktdaten["kontakt"]["anrede"]) self.i_vorname.setText(kontaktdaten["kontakt"]["vorname"]) self.i_nachname.setText(kontaktdaten["kontakt"]["nachname"]) self.i_strasse.setText(kontaktdaten["kontakt"]["strasse"]) self.i_hausnummer.setText(kontaktdaten["kontakt"]["hausnummer"]) self.i_plz_wohnort.setText(kontaktdaten["kontakt"]["plz"]) self.i_wohnort.setText(kontaktdaten["kontakt"]["ort"]) # Prüfen ob neuer key in kontaktdaten exisitiert if "notifications" in kontaktdaten: self.__set_notifications(kontaktdaten['notifications']) try: self.__set_zeitrahmen(kontaktdaten["zeitrahmen"]) # Subkeys von "zeitrahmen" brauchen nicht gecheckt werden, da # `kontaktdaten["zeitrahmen"] == {}` zulässig ist. except ValueError: self.__reset_zeitrahmen() self.__oeffne_error(title="Kontaktdaten", text="Falscher Suchzeitraum", info= "Der Suchzeitraum Ihrer Kontaktdaten ist fehlerhaft." " Überprüfen Sie die Daten im Reiter Zeitrahmen und" " speichern Sie die Kontaktdaten.") pass except MissingValuesError as exc: self.__reset_vermittlungscodes() self.__reset_kontakdaten() self.__reset_zeitrahmen() self.__reset_notifications() self.__oeffne_error(title="Kontaktdaten", text="Falsches Format", info= "Die von Ihnen gewählte Datei hat ein falsches Format. " "Laden Sie eine andere Datei oder überschreiben Sie die " "Datei, indem Sie auf Speichern klicken.") except ValidationError as exc: self.__reset_vermittlungscodes() self.__reset_kontakdaten() self.__reset_zeitrahmen() self.__reset_notifications() self.__oeffne_error(title="Kontaktdaten", text="Falsches Format", info= "Die von Ihnen gewählte Datei hat ein falsches Format. " "Laden Sie eine andere Datei oder überschreiben Sie die " "Datei, indem Sie auf Speichern klicken.") # Wechsel auf den ersten Reiter self.tabWidget.setCurrentIndex(0)
def update_kontaktdaten_interactive(known_kontaktdaten, command, configure_notifications, filepath=None): """ Interaktive Eingabe und anschließendes Abspeichern der Kontaktdaten. :param known_kontaktdaten: Bereits bekannte Kontaktdaten, die nicht mehr abgefragt werden sollen. :param command: Entweder "code" oder "search". Bestimmt, welche Kontaktdaten überhaupt benötigt werden. :param configure_notifications: Boolean - die Option zum einrichten von Pushover und Telegram wird nur bei true angezeigt :param filepath: Pfad zur JSON-Datei zum Abspeichern der Kontaktdaten. Default: data/kontaktdaten.json im aktuellen Ordner :return: Dictionary mit Kontaktdaten """ assert (command in ["code", "search"]) # Werfe Fehler, falls die übergebenen Kontaktdaten bereits ungültig sind. validate_kontaktdaten(known_kontaktdaten) kontaktdaten = copy.deepcopy(known_kontaktdaten) with open(filepath, 'w', encoding='utf-8') as file: if "plz_impfzentren" not in kontaktdaten: print( "Mit einem Code kann in mehreren Impfzentren gleichzeitig nach einem Termin gesucht werden.\n" "Eine Übersicht über die Gruppierung der Impfzentren findest du hier:\n" "https://github.com/iamnotturner/vaccipy/wiki/Ein-Code-fuer-mehrere-Impfzentren\n\n" "Trage nun die PLZ deines Impfzentrums ein. Für mehrere Impfzentren die PLZ's kommagetrennt nacheinander.\n" "Beispiel: 68163, 69124, 69469\n") input_kontaktdaten_key( kontaktdaten, ["plz_impfzentren"], "> PLZ's der Impfzentren: ", lambda x: unique([plz.strip() for plz in x.split(",")])) print() if "codes" not in kontaktdaten and command == "search": print( "Bitte gebe jetzt die Vermittlungscodes passend zu den ausgewählten Impfzentren ein.\n" "Beachte dabei, dass nur ein Vermittlungscode je Gruppierung benötigt wird.\n" "Weitere Infos: https://github.com/iamnotturner/vaccipy/wiki/Ein-Code-fuer-mehrere-Impfzentren\n\n" "Mehrere Vermittlungscodes müssen durch Kommas getrennt werden.\n" "Beispiel: ABCD-1234-EFGH, ABCD-4321-EFGH, 1234-56AB-CDEF\n") input_kontaktdaten_key( kontaktdaten, ["codes"], "> Vermittlungscodes: ", lambda x: unique([code.strip() for code in x.split(",")])) print() if "kontakt" not in kontaktdaten: kontaktdaten["kontakt"] = {} if "anrede" not in kontaktdaten["kontakt"] and command == "search": input_kontaktdaten_key(kontaktdaten, ["kontakt", "anrede"], "> Anrede (Frau/Herr/Kind/Divers): ") if "vorname" not in kontaktdaten["kontakt"] and command == "search": input_kontaktdaten_key(kontaktdaten, ["kontakt", "vorname"], "> Vorname: ") if "nachname" not in kontaktdaten["kontakt"] and command == "search": input_kontaktdaten_key(kontaktdaten, ["kontakt", "nachname"], "> Nachname: ") if "strasse" not in kontaktdaten["kontakt"] and command == "search": input_kontaktdaten_key(kontaktdaten, ["kontakt", "strasse"], "> Strasse (ohne Hausnummer): ") if "hausnummer" not in kontaktdaten["kontakt"] and command == "search": input_kontaktdaten_key(kontaktdaten, ["kontakt", "hausnummer"], "> Hausnummer: ") if "plz" not in kontaktdaten["kontakt"] and command == "search": input_kontaktdaten_key(kontaktdaten, ["kontakt", "plz"], "> PLZ des Wohnorts: ") if "ort" not in kontaktdaten["kontakt"] and command == "search": input_kontaktdaten_key(kontaktdaten, ["kontakt", "ort"], "> Wohnort: ") if "phone" not in kontaktdaten["kontakt"]: input_kontaktdaten_key( kontaktdaten, ["kontakt", "phone"], "> Telefonnummer: +49", lambda x: x if x.startswith("+49") else f"+49{remove_prefix(x, '0')}") if "notificationChannel" not in kontaktdaten["kontakt"]: kontaktdaten["kontakt"]["notificationChannel"] = "email" if "notificationReceiver" not in kontaktdaten["kontakt"]: input_kontaktdaten_key(kontaktdaten, ["kontakt", "notificationReceiver"], "> Mail: ") if configure_notifications: if "notifications" not in kontaktdaten: kontaktdaten["notifications"] = {} if "pushover" not in kontaktdaten["notifications"]: while True: kontaktdaten["notifications"]["pushover"] = {} if input("> Benachtigung mit Pushover einrichten? (y/n): " ).lower() != "n": print() input_kontaktdaten_key( kontaktdaten, ["notifications", "pushover", "app_token"], "> Geben Sie den Pushover APP Token ein: ") input_kontaktdaten_key( kontaktdaten, ["notifications", "pushover", "user_key"], "> Geben Sie den Pushover User Key ein: ") try: validation_code = str( pushover_validation( kontaktdaten["notifications"]["pushover"])) except PushoverNotificationError as exc: print( f"Fehler: {exc}\nBitte versuchen Sie es erneut." ) continue validation_input = input( "Geben Sie den Validierungscode ein:").strip() if validation_input == validation_code: break del kontaktdaten["notifications"]["pushover"] print("Validierung fehlgeschlagen.") print() else: print() break if "telegram" not in kontaktdaten["notifications"]: while True: kontaktdaten["notifications"]["telegram"] = {} if input("> Benachtigung mit Telegram einrichten? (y/n): " ).lower() != "n": print() input_kontaktdaten_key( kontaktdaten, ["notifications", "telegram", "api_token"], "> Geben Sie den Telegram API Token ein: ") input_kontaktdaten_key( kontaktdaten, ["notifications", "telegram", "chat_id"], "> Geben Sie die Telegram Chat ID ein: ") try: validation_code = str( telegram_validation( kontaktdaten["notifications"]["telegram"])) except TelegramNotificationError as exc: print( f"Fehler: {exc}\nBitte versuchen Sie es erneut." ) continue validation_input = input( "Geben Sie den Validierungscode ein:").strip() if validation_input == validation_code: break del kontaktdaten["notifications"]["telegram"] print("Validierung fehlgeschlagen.") print() else: print() break if "zeitrahmen" not in kontaktdaten and command == "search": kontaktdaten["zeitrahmen"] = {} if input("> Zeitrahmen festlegen? (y/n): ").lower() != "n": print() input_kontaktdaten_key( kontaktdaten, ["zeitrahmen", "einhalten_bei"], "> Für welchen Impftermin soll der Zeitrahmen gelten? (1/2/beide): " ) input_kontaktdaten_key( kontaktdaten, ["zeitrahmen", "von_datum"], "> Von Datum (Leer lassen zum Überspringen): ", lambda x: x if x else None) # Leeren String zu None umwandeln input_kontaktdaten_key( kontaktdaten, ["zeitrahmen", "bis_datum"], "> Bis Datum (Leer lassen zum Überspringen): ", lambda x: x if x else None) # Leeren String zu None umwandeln input_kontaktdaten_key( kontaktdaten, ["zeitrahmen", "von_uhrzeit"], "> Von Uhrzeit (Leer lassen zum Überspringen): ", lambda x: x if x else None) # Leeren String zu None umwandeln input_kontaktdaten_key( kontaktdaten, ["zeitrahmen", "bis_uhrzeit"], "> Bis Uhrzeit (Leer lassen zum Überspringen): ", lambda x: x if x else None) # Leeren String zu None umwandeln print( "Trage nun die Wochentage ein, an denen die ausgewählten Impftermine liegen dürfen.\n" "Mehrere Wochentage können durch Komma getrennt werden.\n" "Beispiel: Mo, Di, Mi, Do, Fr, Sa, So\n" "Leer lassen, um alle Wochentage auszuwählen.") input_kontaktdaten_key(kontaktdaten, ["zeitrahmen", "wochentage"], "> Erlaubte Wochentage: ", parse_wochentage) print() json.dump(kontaktdaten, file, ensure_ascii=False, indent=4) return kontaktdaten
def update_kontaktdaten_interactive(known_kontaktdaten, command, filepath=None): """ Interaktive Eingabe und anschließendes Abspeichern der Kontaktdaten. :param known_kontaktdaten: Bereits bekannte Kontaktdaten, die nicht mehr abgefragt werden sollen. :param command: Entweder "code" oder "search". Bestimmt, welche Kontaktdaten überhaupt benötigt werden. :param filepath: Pfad zur JSON-Datei zum Abspeichern der Kontaktdaten. Default: data/kontaktdaten.json im aktuellen Ordner :return: Dictionary mit Kontaktdaten """ assert (command in ["code", "search"]) # Werfe Fehler, falls die übergebenen Kontaktdaten bereits ungültig sind. validate_kontaktdaten(known_kontaktdaten) kontaktdaten = copy.deepcopy(known_kontaktdaten) with open(filepath, 'w', encoding='utf-8') as file: if "plz_impfzentren" not in kontaktdaten: print( "Mit einem Code kann in mehreren Impfzentren gleichzeitig nach einem Termin gesucht werden.\n" "Eine Übersicht über die Gruppierung der Impfzentren findest du hier:\n" "https://github.com/iamnotturner/vaccipy/wiki/Ein-Code-fuer-mehrere-Impfzentren\n\n" "Trage nun die PLZ deines Impfzentrums ein. Für mehrere Impfzentren die PLZ's kommagetrennt nacheinander.\n" "Beispiel: 68163, 69124, 69469\n") input_kontaktdaten_key( kontaktdaten, ["plz_impfzentren"], "> PLZ's der Impfzentren: ", lambda x: list(set([plz.strip() for plz in x.split(",")]))) if "code" not in kontaktdaten and command == "search": input_kontaktdaten_key(kontaktdaten, ["code"], "> Code: ") if "kontakt" not in kontaktdaten: kontaktdaten["kontakt"] = {} if "anrede" not in kontaktdaten["kontakt"] and command == "search": input_kontaktdaten_key(kontaktdaten, ["kontakt", "anrede"], "> Anrede (Frau/Herr/...): ") if "vorname" not in kontaktdaten["kontakt"] and command == "search": input_kontaktdaten_key(kontaktdaten, ["kontakt", "vorname"], "> Vorname: ") if "nachname" not in kontaktdaten["kontakt"] and command == "search": input_kontaktdaten_key(kontaktdaten, ["kontakt", "nachname"], "> Nachname: ") if "strasse" not in kontaktdaten["kontakt"] and command == "search": input_kontaktdaten_key(kontaktdaten, ["kontakt", "strasse"], "> Strasse (ohne Hausnummer): ") if "hausnummer" not in kontaktdaten["kontakt"] and command == "search": input_kontaktdaten_key(kontaktdaten, ["kontakt", "hausnummer"], "> Hausnummer: ") if "plz" not in kontaktdaten["kontakt"] and command == "search": input_kontaktdaten_key(kontaktdaten, ["kontakt", "plz"], "> PLZ des Wohnorts: ") if "ort" not in kontaktdaten["kontakt"] and command == "search": input_kontaktdaten_key(kontaktdaten, ["kontakt", "ort"], "> Wohnort: ") if "phone" not in kontaktdaten["kontakt"]: input_kontaktdaten_key( kontaktdaten, ["kontakt", "phone"], "> Telefonnummer: +49", lambda x: x if x.startswith("+49") else f"+49{remove_prefix(x, '0')}") if "notificationChannel" not in kontaktdaten["kontakt"]: kontaktdaten["kontakt"]["notificationChannel"] = "email" if "notificationReceiver" not in kontaktdaten["kontakt"]: input_kontaktdaten_key(kontaktdaten, ["kontakt", "notificationReceiver"], "> Mail: ") if "zeitrahmen" not in kontaktdaten and command == "search": kontaktdaten["zeitrahmen"] = {} if input("> Zeitrahmen festlegen? (y/n): ").lower() != "n": print() input_kontaktdaten_key( kontaktdaten, ["zeitrahmen", "einhalten_bei"], "> Für welchen Impftermin soll der Zeitrahmen gelten? (1/2/beide): " ) input_kontaktdaten_key( kontaktdaten, ["zeitrahmen", "von_datum"], "> Von Datum (Leer lassen zum Überspringen): ", lambda x: x if x else None) # Leeren String zu None umwandeln input_kontaktdaten_key( kontaktdaten, ["zeitrahmen", "bis_datum"], "> Bis Datum (Leer lassen zum Überspringen): ", lambda x: x if x else None) # Leeren String zu None umwandeln input_kontaktdaten_key( kontaktdaten, ["zeitrahmen", "von_uhrzeit"], "> Von Uhrzeit (Leer lassen zum Überspringen): ", lambda x: x if x else None) # Leeren String zu None umwandeln input_kontaktdaten_key( kontaktdaten, ["zeitrahmen", "bis_uhrzeit"], "> Bis Uhrzeit (Leer lassen zum Überspringen): ", lambda x: x if x else None) # Leeren String zu None umwandeln print( "Trage nun die Wochentage ein, an denen die ausgewählten Impftermine liegen dürfen.\n" "Mehrere Wochentage können durch Komma getrennt werden.\n" "Beispiel: Mo, Di, Mi, Do, Fr, Sa, So\n" "Leer lassen, um alle Wochentage auszuwählen.") input_kontaktdaten_key(kontaktdaten, ["zeitrahmen", "wochentage"], "> Erlaubte Wochentage: ", parse_wochentage) json.dump(kontaktdaten, file, ensure_ascii=False, indent=4) return kontaktdaten