Zeichensatzkonvertierung für Windows-Dateinamen
Verfasst: Donnerstag 16. November 2023, 00:52
Moin, zusammen.
Seit einigen Tagen mache ich meine ersten Schritte in der Python-Programmierung. Ich habe jetzt für mich ein Programmierprojekt definiert, das folgendes leisten soll:
1. Unter Windows ein oder mehrere aus Thunderbird in ein Verzeichnis exportierte Emails (*.eml-Datei(en)) in ein bestimmtes Dateinamen-Schema umzuwandeln
2. Diese Datei(en) anschließend in eine PDF-Datei umzuwandeln.
Derzeit experimentiere ich noch mit Punkt 1.
Das Dateinamen-Schema soll wie folgt ausschauen: YYYY-MM-DD hhmmss [Absender] Subject
Dabei soll 'YYYY-MM-DD hhmmss' Versanddatum und -uhrzeit der Email sein. Also z.B. '2023-11-01 122304 [Hans Müller] Betreff dieser Email.eml.
Der Absender in [] enstammt dem "Sender"-Feld des Mail-Headers. ("Hans.Müller@mailserver.de" <hans.mueller@mailserver.de>)
Je nachdem ob die Sender-Angabe einen Mail-Tag hat oder nicht, wäre dies in diesem Beispiel "Hans Müller" oder "hans mueller".
Fast funktioniert das Ganze schon so wie gewünscht. Woran ich jedoch scheitere, ist die erforderlche Zeichenkonvertierung für den Dateinamen. Dies immer dann, wenn der Tag diakritische Zeichen enthält. Vielleich kann jemand, der bis hierher mitglesen hat, mir einen hilfreichen Hinweis geben.
Dafür schon einmal im Voraus vielen Dank.
Viele Grüße
Seit einigen Tagen mache ich meine ersten Schritte in der Python-Programmierung. Ich habe jetzt für mich ein Programmierprojekt definiert, das folgendes leisten soll:
1. Unter Windows ein oder mehrere aus Thunderbird in ein Verzeichnis exportierte Emails (*.eml-Datei(en)) in ein bestimmtes Dateinamen-Schema umzuwandeln
2. Diese Datei(en) anschließend in eine PDF-Datei umzuwandeln.
Derzeit experimentiere ich noch mit Punkt 1.
Das Dateinamen-Schema soll wie folgt ausschauen: YYYY-MM-DD hhmmss [Absender] Subject
Dabei soll 'YYYY-MM-DD hhmmss' Versanddatum und -uhrzeit der Email sein. Also z.B. '2023-11-01 122304 [Hans Müller] Betreff dieser Email.eml.
Der Absender in [] enstammt dem "Sender"-Feld des Mail-Headers. ("Hans.Müller@mailserver.de" <hans.mueller@mailserver.de>)
Je nachdem ob die Sender-Angabe einen Mail-Tag hat oder nicht, wäre dies in diesem Beispiel "Hans Müller" oder "hans mueller".
Fast funktioniert das Ganze schon so wie gewünscht. Woran ich jedoch scheitere, ist die erforderlche Zeichenkonvertierung für den Dateinamen. Dies immer dann, wenn der Tag diakritische Zeichen enthält. Vielleich kann jemand, der bis hierher mitglesen hat, mir einen hilfreichen Hinweis geben.
Dafür schon einmal im Voraus vielen Dank.
Viele Grüße
Code: Alles auswählen
import os
import re
import email
import unicodedata
import shutil
from tkinter import filedialog
import tkinter as tk
from datetime import datetime
from urllib.parse import quote
# Funktion zum Extrahieren des Datums, der Uhrzeit, des Mail-Tags und des Betreffs aus der E-Mail
def extract_email_info(eml_file):
with open(eml_file, 'r', encoding='cp1252') as file:
msg = email.message_from_file(file)
date_str = msg['Date']
subject = msg['Subject']
from_field = msg['From']
# with open(eml_file, 'r', encoding='utf-8') as file:
# Das Datum und die Uhrzeit aus dem E-Mail-Header extrahieren
email_date = datetime.strptime(date_str, "%a, %d %b %Y %H:%M:%S %z")
date_formatted = email_date.strftime("%Y-%m-%d %H%M%S")
# Den Mail-Tag aus dem 'From:'-Feld extrahieren
mail_tag = from_field.split('<')[0].strip()
# Diakritische Zeichen normalisieren
mail_tag = unicodedata.normalize('NFKD', mail_tag).encode('ascii', 'ignore').decode('utf-8')
# Das Prefix wie 'Re: ' oder 'Aw: ' aus dem Betreff entfernen
subject = re.sub(r'^re:', "", subject, count = 1, flags = re.I).strip()
subject = re.sub(r'^aw:', "", subject, count = 1, flags = re.I).strip()
# Diakritische Zeichen im Betreff normalisieren
subject = unicodedata.normalize('NFKD', subject).encode('ascii', 'ignore').decode('utf-8')
# Die Anführungszeichen um den Mail-Tag und entfernen
mail_tag = mail_tag.strip('\"').split('@')[0].replace(".", " ")
# Wenn ein @-Zeichen im Mail-Tag ist, nur den Teil vor dem @-Zeichen verwenden
# if '@' in mail_tag:
# mail_tag = mail_tag.split('@')[0]
return date_formatted, mail_tag, subject
# Funktion zum Konvertieren der Dateinamen
def rename_eml_files(eml_files):
for eml_file in eml_files:
date_formatted, mail_tag, subject = extract_email_info(eml_file)
_, extension = os.path.splitext(eml_file)
subject = subject.replace(':', '').lstrip() # Doppelpunkte entfernen
# Das aktuelle Verzeichnis (Verzeichnis der Ausgangsdatei) ermitteln
current_directory = os.path.dirname(eml_file)
# Den neuen Dateipfad erstellen (mit os.path.join() für Windows-Kompatibilität)
new_filename = os.path.join(current_directory, f"{date_formatted} [{mail_tag}] {quote(subject.strip())}{extension}")
new_filename = new_filename.replace('"', '') # Anführungszeichen entfernen
new_filename = new_filename.replace(' .eml', '.eml') # Leerzeichen vor .eml entfernen
# new_filename = new_filename.replace(' ', ' ') # Doppelte Leerzeichen auf ein Leerzeichen reduzieren
# new_filename = new_filename.replace(':', '') # Doppelpunkte entfernen
try:
os.rename(eml_file, new_filename)
print(f"Umbenannt: {eml_file} -> {new_filename}")
except Exception as e:
print(f"Fehler beim Umbenennen von {eml_file}: {str(e)}")
# GUI zum Auswählen der Dateien
def select_files():
root = tk.Tk()
root.withdraw() # Das Hauptfenster ausblenden
# Dateiauswahldialog anzeigen und Pfad in Windows-Format konvertieren
file_paths = filedialog.askopenfilenames(
title="E-Mails auswählen",
filetypes=[("EML-Dateien", "*.eml")]
)
if file_paths:
# Konvertiere Pfad zu Windows-Stil
file_paths = [os.path.normpath(path) for path in file_paths]
rename_eml_files(file_paths)
else:
print("Keine Dateien ausgewählt.")
if __name__ == "__main__":
select_files()