Seite 1 von 1

Mailabrufe

Verfasst: Mittwoch 2. Januar 2019, 13:25
von reneschmidt
Hallo zusammen,

ich möchte mit Python Mail aus einem Postfach abrufen und die Anhänge speichern.

Hintergrund ist, das E-Mails mit bestimmten Anhängen eingehen die automatisch abgearbeitet werden können. Andere Mails müssen händisch abgearbeitet werden. Daher liste ich mir den Posteingang und dort nur die ungelesenen Mails. Prüfen ob die Mail nur einen Anhang hat und ob dieser Anhang die entsprechende Dateiendung hat. Wenn ja verschiebe ich die Mail und verarbeite den Anhang.

Mein Problem ist jetzt, das in dem Postfach auch HTML E-Mails landen wo in der Signatur eine Bild ist welches vom Script als Anhang erkannt wird und dadurch fällt die Mail dann durchs Raster.

Gibt es eine Möglichkeit nur die eigentlichen Anhänge zu einer Mail auszugeben und die in die HTML E-Mail eingebundenen Bilder zu erkennen und auszuschlißen?

Ich verwende die Python imaplib zum abruf:

Code: Alles auswählen

#!/usr/bin/python
import email
from email.header import Header, decode_header, make_header
import os
import poplib
import time
import subprocess
import imaplib
import re
import sys

MAILSERVER = ''
BENUTZER = ''
PASSWORT = ''

POSTEINGANG = "INBOX"
VERARBEITUNGSVERZEICHNIS = POSTEINGANG + "/V E R A R B E I T E T"

#Verbindung zum Server aufbauen
imap = imaplib.IMAP4_SSL(MAILSERVER)
imap.login(BENUTZER,PASSWORT)


#Lesen der ungelesenen Mail im Posteingang
imap.select(POSTEINGANG)
#typ, data  = imap.search(None, 'UnSeen')
typ, data  = imap.search(None, 'All')

for mailid in data[0].split(' '):
        typ, maildata = imap.fetch(mailid,'(RFC822)')
        emailBody = maildata[0][1]
        mail = email.message_from_string(emailBody)

        decode = email.header.decode_header(mail['Subject'])[0]
        subject = unicode(decode[0])
        print subject

        attcnt = 0

        #Lesen der Dateianhaenge
        for part in mail.walk():
                if part.get_content_maintype() == 'multipart':
                        # print part.as_string()
                        continue
                if part.get('Content-Disposition') is None:
                        # print part.as_string()
                        continue
                fileName = part.get_filename()
                print fileName
                #print fileName
                attcnt = attcnt + 1


        #Wenn nur ein Dateianhang vorhanden ist, wird weiter verarbeitet
        if attcnt == 1:
                #pruefen der Datei ob PDF:
                if fileName[-4:].upper() == ".PDF":
                        tmpcnt = 0
                        dateiname = ABLAGEPFAD + "/" + str(tmpcnt) + "-" + fileName
                        while os.path.exists(dateiname):
                                tmpcnt = tmpcnt + 1
                                dateiname = ABLAGEPFAD + "/" + str(tmpcnt) + "-" + fileName

                        print dateiname
                        fp = open(dateiname, 'wb')
                        fp.write(part.get_payload(decode=True))
                        fp.close()

                        #kopieren der Mail
                        imap.copy(mailid, hverzeichnis)
                        imap.store(mailid, '+FLAGS', '\\Deleted')
        else:
                imap.store(mailid, '-FLAGS', '\Seen')

imap.close()
imap.logout()

Re: Mailabrufe

Verfasst: Mittwoch 2. Januar 2019, 13:30
von Sirius3
Eingebettete Bilder unterscheiden sich rein technisch nicht von anderen Anhängen. Aber Du untersuchst ja die Anhänge schon weiter, und arbeitest nur die ab, die einen PDF-Angang haben. Wo ist also Dein Problem?

Re: Mailabrufe

Verfasst: Mittwoch 2. Januar 2019, 17:50
von DasIch
@Sirius3 Der Code funktioniert nicht mehr wenn es mehr als einen Anhang gibt, also z.B. Bild von der Signatur + PDF.

Re: Mailabrufe

Verfasst: Mittwoch 2. Januar 2019, 18:21
von __blackjack__
Das/Ein Problem ist, dass der Code gar nicht sauber ”Anhänge” erfasst. Nicht alles was nicht 'multipart' ist und einen 'Content-Disposition'-Wert hat, ist auch ein Anhang. Und man könnte da auch gleich nach dem Inhaltstyp und/oder Dateinamen filtern.

Der Name `attcnt` ist falsch, das müsste `atthoe` heissen. Oder kann man tatsächlich „attention cunt“ sagen? Ich kenne nur „attention whore“. Vielleicht sollte man aber auch einfach das Abkürzen sein lassen. :twisted:

Re: Mailabrufe

Verfasst: Donnerstag 3. Januar 2019, 09:38
von Sirius3
@reneschmidt: das Problem ist, dass Du zwei for-Schleifen vermischst, statt sie sauber zu trennen. Erster Schritt ist die richtigen Anhänge zu suchen, zweiter, sie weiter zu verarbeiten.
Nach Konvention wird immer mit 4 Leerzeichen pro Ebene eingerückt und Variablen klein_mit_unterstrich geschrieben.

Code: Alles auswählen

attachements = [part for part in mail.walk()
    if part.get_filename('').lower().endswith('.pdf')]
if attachements:
    for attachement in attachements:
        filename = os.path.basename(attachement.get_filename())
        for filecount in itertools.count():
            fullname = os.path.join(ABLAGEPFAD, '{:03d}-{}'.format(filecount, filename))
            if not os.path.exists(fullname):
                break
        with open(fullname, 'wb') as output:
            output.write(attachement.get_payload(decode=True))
    imap.copy(mailid, hverzeichnis)
    imap.store(mailid, '+FLAGS', '\\Deleted')
else:
    imap.store(mailid, '-FLAGS', '\\Seen')