commit b648c0f6b9533c625e12eb2edf48741bf21dac57 Author: Florian Kaiser Date: Mon Apr 14 13:47:04 2025 +0200 Init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e27cb32 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +attachments/* +config.json +.DS_Store +email_log.log \ No newline at end of file diff --git a/config.example.json b/config.example.json new file mode 100644 index 0000000..60c18ea --- /dev/null +++ b/config.example.json @@ -0,0 +1,13 @@ +{ + "accounts": [ + { + "server": "", + "port": "", + "user": "", + "password": "", + "remote_folders": [], + "local_folder": "", + "since": "" + } + ] +} diff --git a/main.py b/main.py new file mode 100644 index 0000000..ca9d006 --- /dev/null +++ b/main.py @@ -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)