This commit is contained in:
Florian Kaiser 2025-04-14 13:47:04 +02:00
commit b648c0f6b9
3 changed files with 129 additions and 0 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
attachments/*
config.json
.DS_Store
email_log.log

13
config.example.json Normal file
View File

@ -0,0 +1,13 @@
{
"accounts": [
{
"server": "",
"port": "",
"user": "",
"password": "",
"remote_folders": [],
"local_folder": "",
"since": ""
}
]
}

112
main.py Normal file
View File

@ -0,0 +1,112 @@
from datetime import datetime
import imaplib
import email
import os
import logging
import re
from email.header import decode_header
import json
def sanitize_filename(filename):
# Entfernt ungültige Zeichen aus dem Dateinamen
filename = re.sub(r'[^\w\s.-]', '', filename) # Entfernt alle Zeichen außer Buchstaben, Zahlen, Leerzeichen, Punkt, Bindestrich und Unterstrich
filename = filename.replace(' ', '_') # Ersetzt Leerzeichen durch Unterstriche
return filename
def decode_email_header(header):
decoded_header = ''
for part in decode_header(header):
if part[1] is not None:
decoded_header += part[0].decode(part[1])
else:
decoded_header += part[0]
return decoded_header
def process_emails(server, port, user, password, remote_folder, local_folder, since):
# Logging einrichten
logging.basicConfig(filename='email_log.log', level=logging.INFO)
# Ordner für Anhänge erstellen, falls er nicht existiert
if not os.path.exists(local_folder):
os.makedirs(local_folder)
# IMAP-Verbindung herstellen
mail = imaplib.IMAP4_SSL(server, port)
mail.login(user, password)
# Remote-Ordner auswählen
mail.select(remote_folder)
# Suchkriterien festlegen (z.B. alle E-Mails)
_, messages = mail.search(None, f'(SINCE "{since}")')
# Nachrichten-IDs extrahieren
msg_ids = messages[0].split()
print("IDs:", msg_ids)
# Nachrichten verarbeiten
for msg_id in msg_ids:
# Nachricht abrufen
_, msg = mail.fetch(msg_id, '(RFC822)')
raw_message = msg[0][1]
# Nachricht parsen
message = email.message_from_bytes(raw_message)
print("Betreff:", message['Subject'])
print("Absender:", message['From'])
print("Empfänger:", message['Date'])
# Anhänge speichern
for part in message.walk():
if part.get_content_maintype() == 'multipart':
continue
if part.get('Content-Disposition') is None:
continue
filename = part.get_filename()
if filename:
# Dateinamen dekodieren, falls er kodiert ist
if isinstance(filename, bytes):
filename = filename.decode('utf-8', errors='ignore')
else:
filename = decode_email_header(filename)
# Dateinamen bereinigen und mit der Nachrichten-ID erweitern
sanitized_filename = sanitize_filename(filename)
# Stelle sicher, dass die Dateiendung korrekt ist
if '.' not in sanitized_filename:
if part.get_content_type() == 'application/pdf':
sanitized_filename += '.pdf'
elif part.get_content_type() == 'image/jpeg':
sanitized_filename += '.jpg'
elif part.get_content_type() == 'image/png':
sanitized_filename += '.png'
# Fügen Sie weitere Dateitypen hinzu, falls erforderlich
attachment_filename = f"{msg_id.decode()}_{sanitized_filename}"
filepath = os.path.join(local_folder, attachment_filename)
try:
with open(filepath, 'wb') as f:
f.write(part.get_payload(decode=True))
logging.info(f'Anhang gespeichert: {attachment_filename}')
except Exception as e:
logging.error(f"Fehler beim Speichern des Anhangs {attachment_filename}: {e}")
# Verbindung schließen
mail.close()
mail.logout()
if __name__ == "__main__":
with open('config.json', 'r') as f:
config = json.load(f)
for key, item in enumerate(config['accounts']):
print(key, item)
for folder in item['remote_folders']:
print(item['user'], folder, item['since'])
process_emails(item['server'], item['port'], item['user'], item['password'], folder, item['local_folder'], item['since'])
config['accounts'][key]["since"] = datetime.now().strftime("%d-%b-%Y")
with open('config.json', 'w') as f:
json.dump(config, f)