Mehrere E-Mail Postfächer auf einem PC auswerten und an Connect senden

  • EssalG

    Ich habe bei uns eine Version laufen die PDFs auswertet, allerdings müssen die daten als Text im PDF stehen (so das du sie z.B. beim öffnen mit Acrobat Reader markieren kannst).

    Das war allerdings ein mittelschwerer Schmerz im A*** bis das sauber lief.

    Ich verwende dazu pdfminer

    Den code will ich so wie er jetzt ist allerdings nicht veröffentlichen weil da viele edge cases abgefangen sind die nur uns betreffen und ich die nicht für jede Feuerwehr anpassen will (die meisen Leute haben keine Programmiererfahrung und ich nicht die Zeit das für alle zu tun :-/).

    Im Grunde ist das der kern der Geschichte:

    raw_text enthält dann den Text den das PDF enthielt. Allerdings ist der manchmal ein wenig durcheinander gewürfelt und ich hab noch keine Variante der laparms gefunden die das behebt.

    Vielleicht hilf dir das ja weiter

  • Danke für die Antwort. Habe gerade eine eigene Lösung gefunden.

    Ich werte per Email Parser von FrozenFrog die Mail mit der PDF aus. Dieser wertet die PDF aus und schreibt aus der PDF eine neue Mail, die er wieder an das Mailpostfach schickt. Diese Mail beinhaltet dann alle wichtigen Infos und wird mittels Python an Connect weitergeleitet.

  • So sieht die Email aus, ich habe gerade Probleme diese auszuwerten und bekomme immer eine Fehlermeldung:

  • Damit kenne ich mich halt überhaupt nicht aus, muss die Struktur 1 zu 1 gleich sein?

  • Nein, im Grunde definierst du eine variable in die das Ergebnis des entsprechenden Regex gespeichert wird.

    Hier ein Besipiel

    Code
    - var: start
      regex: 'Einsatzzeit (.*)\n'

    die Variable heisst hier start , der dazugehörige Regex ist Einsatzzeit (.*)\n

    Dieser Regex sucht nach dem Wort Einsatzzeit, gefolgt von einem Leerzeichen und packt alles danach bis zum Zeilenumbruch (\n) in die variable start.

    An deinem Beispiel Alarm von weiter Oben würdest du z.B. die Strasse haben wollen.

    Code
    - var: street
      regex: 'Straße (.*)\n'

    Das würde die variable street mit "Teststraße" befüllen.

    Und zu einem Screenshot, überall wo None steht, konnte kein Wert gefunden werden.

    Das was bei start steht ist glaube ich ein Überbleibsel von Pyrokevin112

    Der muss in seinen Mails Datum und Zeit gesondert parsen und zusammenfrickeln.

    Poste vielleicht auch mal noch dein python code, dann schau ich mir das mal an

  • Genau das selbe Problem was ich mitunter auch habe. Leite ich die Alarmmail weiter und lass die auswerten, funktioniert es.

    Markiere ich die Mail als ungelesen und lasse die auswerten bekomme ich auch diesen Fehler und konnte keine Daten auswerten

    Administrator in 5 Ortswehren im Landkreis Harz

    Mitglied in der Feuerwehr Welterbestadt Quedlinburg

    Ofw Gernrode

  • Poste vielleicht auch mal noch dein python code, dann schau ich mir das mal an

    Ist das mein Python Code? Wo finde ich den

    Spoiler anzeigen

    import logging

    import os

    import sys

    import time

    from datetime import datetime as dt

    import click

    import yaml

    from feuersoftware import PublicAPI

    from alarmparser import AlarmParser

    from mailcheck import Mail

    from telegram import telegram_bot

    #Zur Nutzung des Telegram-Bots müssen nur die Zeilen 42,69,128 auskommentiert werden, also die Raute entfernen.

    LOGLEVEL = "DEBUG"

    format = "%(asctime)s.%(msecs)03d - %(name)s - %(levelname)s - %(message)s"

    dateformat = "%Y-%m-%d %H:%M:%S"

    logging.basicConfig(level=LOGLEVEL, format=format, datefmt=dateformat)

    LOGGER = logging.getLogger(">>>main<<<")

    hdlr = logging.FileHandler('z_Logging.log')

    hdlr.setLevel(level=logging.INFO)

    formatter = logging.Formatter('%(asctime)s.%(msecs)03d - %(name)s - %(levelname)s - %(message)s')

    hdlr.setFormatter(formatter)

    LOGGER.addHandler(hdlr)


    class Observer:

    def __init__(self, config):

    self.config = config

    def run(self):

    while True:

    try:

    for account in self.config.get("accounts"):

    try:

    self.check_mail(account)

    except:

    postfachname = account.get("name")

    LOGGER.error(f"Fehler in Observer {postfachname} aufgetreten - probiere weiter in 1 Sekunde")

    #telegram_bot.telegram_bot_sendtext(f"ERROR - Fehler in Observer {postfachname} aufgetreten")

    time.sleep(1)

    except KeyboardInterrupt:

    LOGGER.info("Ctrl + C received. Stopping now!")

    sys.exit(0)

    time.sleep(5)

    def check_mail(self, account):

    """Check a mail account for new alarm mails."""

    _start = dt.now()

    name = account.get("name")

    mailcfg = account.get("mail")

    mail = Mail(mailcfg.get("host"), mailcfg.get("user"), mailcfg.get("password"))

    msgids = mail.search_mails(mailcfg.get("subject"))

    text = mail.get_text(msgids)

    if not text:

    return

    _fetchtime = dt.now()

    LOGGER.info(f"Fetching the alarmmail from {mailcfg.get('user')} took {(_fetchtime - _start).total_seconds()} seconds")

    data = AlarmParser(self.config, text).data

    _parsetime = dt.now()

    LOGGER.info(f"Parsing the alarmmail took {(_parsetime - _fetchtime).total_seconds()} seconds")

    alarmdata = self.assign_data(data)

    self.alert(account, alarmdata)

    _alerttime = dt.now()

    LOGGER.info(f"Sending to Connect API took {(_alerttime - _parsetime).total_seconds()} seconds")

    LOGGER.info(f"Entire process took {(_alerttime - _start).total_seconds()} seconds")

    #telegram_bot.telegram_bot_sendtext(f"ALARM - {name}")

    def assign_data(self, data):

    """Assign data to right api fields, transform values if necessary."""

    alarmdata = {

    # "start": dt.now().strftime('%Y-%m-%dT%H:%M:%S'),

    "start": f"{dt.now().strftime('%Y-%m-%d')}T{data.get('start')}:00",

    "keyword": data.get("keyword"),

    "number": data.get("number"),

    "address": f"{data.get('street')} {data.get('housenumber')}, {data.get('city')} - {data.get('district')}",

    "facts": data.get("comment"),

    "properties": [

    {"key": "Objekt", "value": data.get("object")},

    {"key": "Sondersignal", "value": data.get("siren")},

    ],

    "ric": data.get("assigned"),

    }

    LOGGER.info(alarmdata)

    return alarmdata

    def alert(self, account, alarmdata):

    """Send alarm data to Feuersoftware API."""

    api = PublicAPI(account.get("connect").get("token"))

    r = api.post_operation(

    start=alarmdata.get("start"),

    keyword=alarmdata.get("keyword"),

    status="new",

    alarmenabled=True,

    address=alarmdata.get("address"),

    facts=alarmdata.get("facts"),

    number=alarmdata.get("number"),

    properties=alarmdata.get("properties"),

    ric=alarmdata.get("ric"),

    )


    @click.command()

    @click.argument("configfile", type=click.Path(exists=True))

    def main(configfile):

    LOGGER.info("Programm wurde gestartet")

    with open(configfile) as cfg:

    config = yaml.load(cfg, Loader=yaml.BaseLoader)

    if not config:

    LOGGER.error("No config file found at %s!", configfile)

    sys.exit(1)


    observerloop(config)

    def observerloop(config):

    while True:

    try:

    observer = Observer(config)

    observer.run()

    except: # catch *all* exceptions

    LOGGER.error("Fehler in observerloop aufgetreten - starte erneut in 10 Sekunden")

    #telegram_bot.telegram_bot_sendtext("ERROR - Fehler in observerloop aufgetreten")

    time.sleep(10)


    if __name__ == "__main__":

    main()

  • Sorry :D

  • Moin Zusammen,

    ich hätte mal eine Frage jedoch möchte ich mich erstmal für die Bereitstellung bedanken. Eine Coole Sache.

    Gibt es die Möglichkeit einen LiveLogger laufen zu lassen oder ein zusehen ? Bei mir geht nach dem Start immer nur kurz die CMD auf und ist dann weg. In der Log steht zwar erfolgreich gestartet aber ob alle Verbindungen passen sieht man nicht oder ? Ich habe jz extra mal ein falsches Passwort für die Mail eingeben aber es passiert nix.

    Danke und Gruß

    Sepp

  • Ok danke dir schon mal.

    Irgendwie sagt mir mein Gefühl es stimmt was noch nicht. Sagt dir das was ?

    Edit: Danke dir passt soweit. Fehler kam von einem nicht vollständigen gelöschten Dummy in der Confg.

  • Hey Zusammen,

    ich nochmal. Soweit klappt die Schnittstelle super jedoch habe ich das Problem das er mir in meinem Postfach die Email nicht als gelesen markiert und dadurch permanent weiter alarmiert. Ist jemanden dazu was bekannt ?

    Den Time-Out hatte ich jz mal mit 60 Sekunden probiert aber kommt trotzdem ein Alarm nach dem anderen rein.

    Wir benutzen Strato als Anbieter der Maildressen.

    Hat einer eine Idee oder kann man da was am Skript einstellen ?

    Gruß