AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke .eml Dateien auslesen - wie decodieren?
Thema durchsuchen
Ansicht
Themen-Optionen

.eml Dateien auslesen - wie decodieren?

Ein Thema von nezumi7 · begonnen am 5. Nov 2013 · letzter Beitrag vom 17. Dez 2013
Antwort Antwort
nezumi7

Registriert seit: 11. Apr 2011
71 Beiträge
 
#1

.eml Dateien auslesen - wie decodieren?

  Alt 5. Nov 2013, 07:27
Hallo,

ich habe alle meine emails als ".eml"-Dateien auf der Festplatte gespeichert. Um da ein System reinzubringen, möchte ich Absender, Empfänger, Datum, Betreff, Anhänge(Namen) und den Nachrichtentext auslesen und in einer Datenbank ablegen.

Ich muss die Nachrichten nicht vom Server abholen und brauch keine Internetverbindung.

Bei Indy gibts ein Beispiel für ein email-Programm, das ich versucht habe so zu ändern, dass anstatt "Retrieve.Message", die Nachricht von der Festplatte geladen wird.


Code:
begin
If opendialog1.Execute then begin
{stTemp := Statusbar1.Panels[1].text;
   if lvHeaders.Selected = nil then
      begin
         Exit;
      end; }
//Showbusy(true);
   Msg.Clear;
   Memo1.Clear;
   //lvMessageParts.Items.Clear;
   From.Caption := '';
   Cc.Caption := '';
   Subject.Caption := '';
   Date.Caption := '';
   Receipt.Caption := '';
   Organization.Caption := '';
   Priority.Caption := '';
   pnlAttachments.visible := false;

//get message and put into MSG
   //ShowStatus('Retrieving message "' + lvHeaders.Selected.SubItems.Strings[3] + '"');
   //POP.Retrieve(lvHeaders.Selected.Index + 1, Msg);
   msg.LoadFromFile(opendialog1.FileName);
   //statusbar1.Panels[0].text := lvHeaders.Selected.SubItems.Strings[3];
//Setup fields on screen from MSG
   From.Caption := Msg.From.Text;
   Recipients.Caption := Msg.Recipients.EmailAddresses;
   Cc.Caption := Msg.CCList.EMailAddresses;
   Subject.Caption := Msg.Subject;
   Date.Caption := FormatDateTime('dd mmm yyyy hh:mm:ss', Msg.Date);
   Receipt.Caption := Msg.ReceiptRecipient.Text;
   Organization.Caption := Msg.Organization;
   Priority.Caption := IntToStr(Ord(Msg.Priority) + 1);
//Setup attachments list
   ShowStatus('Decoding attachments (' + IntToStr(Msg.MessageParts.Count) + ')');
   for intIndex := 0 to Pred(Msg.MessageParts.Count) do
      begin
         if (Msg.MessageParts.Items[intIndex] is TIdAttachmentFile) then
            begin //general attachment
               pnlAttachments.visible := true;
               li := lvMessageParts.Items.Add;
               li.ImageIndex := 8;
               li.Caption := TIdAttachmentFile(Msg.MessageParts.Items[intIndex]).Filename;
               li.SubItems.Add(TIdAttachmentFile(Msg.MessageParts.Items[intIndex]).ContentType);
            end
         else
            begin //body text
               if Msg.MessageParts.Items[intIndex] is TIdText then
                  begin
                     Memo1.Lines.Clear;
                     Memo1.Lines.AddStrings(TIdText(Msg.MessageParts.Items[intIndex]).Body);
                  end
            end;
      end;
   //ShowStatus(stTemp);
   //Showbusy(false);

end;
end;
Das klappt alles wunderbar, nur beim eigentlichen Nachrichtentext kommt entweder gar nix, oder ein Text mit lauter html-tags oder es werden Umlaute nicht richtig dargestellt.

Ich weiß, dass man das noch irgendwie decodieren muss ("quoted-printable", "mime", "utf-8"), hab aber keine Idee, wie das geht.

Kann mir da jemand einen Tipp geben?
Geht das überhaupt grundsätzlich?

Danke,
Stephan
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
3.010 Beiträge
 
Delphi 2009 Professional
 
#2

AW: .eml Dateien auslesen - wie decodieren?

  Alt 5. Nov 2013, 08:36
Ist es eventuell eine ältere Indy Version? Aktuell ist 10.6, und man muss sie nach dem Download nicht "installieren" sondern nur die Source-Verzeichnisse dem Projekt hinzufügen. (Die alte Indy Version braucht dazu auch nicht deinstalliert zu werden.)
Michael Justin
  Mit Zitat antworten Zitat
nezumi7

Registriert seit: 11. Apr 2011
71 Beiträge
 
#3

AW: .eml Dateien auslesen - wie decodieren?

  Alt 5. Nov 2013, 13:13
Vielen Dank für den Tipp. Ich habe Delphi 6 und Indy 10 Komma irgendwas, werde das heute Abend dann mal mit Indy 10.6 ausprobieren und berichten.

Wenn ich Dich richtig verstanden habe, braucht man überhaupt keinen Decoder einbauen und verwenden? Mich macht stutzig, dass es bei Indy so viele davon gibt...

LG, Stephan.
  Mit Zitat antworten Zitat
nezumi7

Registriert seit: 11. Apr 2011
71 Beiträge
 
#4

AW: .eml Dateien auslesen - wie decodieren?

  Alt 5. Nov 2013, 17:01
So, ich hab jetzt die neueste Indy Version (10.6). Leider ist das Problem dadurch nicht behoben...

Hat noch jemand eine Idee?

LG, Stephan.
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.558 Beiträge
 
Delphi 12 Athens
 
#5

AW: .eml Dateien auslesen - wie decodieren?

  Alt 6. Nov 2013, 13:55
Das kann man gar nicht so abschließend beantworten. Aber vielleicht helfen ein paar Informationen weiter, mit denen Du Deine eigenen Rückschlüsse ziehen kannst:

Mails bestehen grob gesagt aus Header, Body und Anhängen.

Der Mailtext wird dabei oft als "text/plain" verschickt, dann ist er im Body zu finden. Oder (nur) als "text/html", dann ist er bei den Indys in den Messageparts zu finden. Oft gibt es auch beides, also den reinen Text und eine alternative Fassung des Textes, die ist dann auch den "Messageparts" zu finden. Das sind dann i.d.R. HTML-Fassungen, könnte aber auch (ganz, ganz selten) RTF sein. Im Mailheader ist darüber eine Info zu finden, dort steht dann z.B. "multipart/alternative". Ich habe aber auch schon erlebt, dass im Body-Text eine Art Mini-HTML verwendet wurde, der Text aber als "text/plain" deklariert wurde.

Und Letzteres ist ein Beispiel für die ganzen Probleme beim Mails entschlüsseln und auch für die Limits, die in den Indy-Komponenten stecken. Indy's arbeiten voll RFC-Konform, also nach internationalen Standards. Aber that's it. Wenn eine Mail einen Standard nicht einhält, dann wird eben ein Fehler ausgeworfen, eine weitere Abarbeitung der Mail findet dann ab der fehlerhaften Stelle nicht mehr statt.

Und es sind massenweise fehlerhafte Mails unterwegs, von irgendwelchen Web-Mailversendern, Eigenkonstruktionen von Firmen, was auch immer. Aus diesem Grunde rufe ich für mein Mail-Programm (Safer Mail) die Mails in der RAW-Fassung ab, also so, wie der Server mir die Daten anliefert, die Interpretation der Mails mache ich dann selber (was auch nicht einfach ist und selbst nach 10 Jahren Arbeit daran immer wieder nachtjustiert werden muss).

Will damit sagen, dass Du für Dein Projekt möglicherweise nicht alles 100%-tig dekodieren kannst, es sei denn, Du willst einen irren Aufwand dafür betreiben.

Du solltest also für Dein Projekt prüfen, ob der Body einen Text hat. Wenn ja, OK. Wenn nicht, dann must Du die Messageparts durchlaufen und anhand der Content-Type-Informationen prüfen, welche Textart vorliegt. Dann kannst Du z.B. aus einer HTML-Mail eine reine Textmail machen (hier gibt es diverse Units im Netz zu finden, nach "HTML to Text" suchen), es sei denn Du willst lieber die HTML-Fassung verwenden, die könntest Du dann in einer TWebbrowser-Komponente anzeigen lassen. Wenn der HTML-Text aber Schadcode enthalten sollte, könnte das ein Risiko sein, weil die TWebBrowser-Komponente für sich alleine keine Schutzfunktionen bietet.

Da gibt es aber auch noch ein paar andere Fallstricke, z.B. bei Textteilen, die als "inline" deklariert sind (prüft man im "Content-Disposition"-Eintrag). Die landen in den Messageparts und Du musst dann unter Umständen aus mehreren Messageparts einen einheitlichen Text gestalten. So gibt es Konstruktionen (z.B. bei Apple-Mails hatte ich schon diverse Fälle), wo der eigentliche Mailtext aus einer Komposition von einfachen ANSI-Texten und HTML-Texten bestand. Um das irgendwie anzeigen zu können, muss man daraus entweder einen neuen HTML-Text basteln oder eben alles in reinen Text umwandeln.

Soweit die TidMessage-Komponente die Decodierung des in der Mail verwendeten Charsets nicht anbietet oder aufgrund einer fehlerhaften Komposition der Mail nicht schafft, musst Du den Mailtext selbst decodieren. Da kann z.B. in der einfachsten Form die Funktion "Utf8ToAnsi" verwendet werden, wenn ein UTF-8 codierter Text vorliegt. Die charset-Information findest Du im Header als Zusatz für den Content-Type bzw. jeweils bei den Messageparts.

Leider kann ich keinen Beispiel-Source-Code posten, da ich es ja wie gesagt, für meine Zwecke anders gelöst habe (neben den erläuterten technischen Gründen vor allem aber, um das Bedrohungspotential der Mail besser beurteilen zu können, bzw. in den Griff zu bekommen). Aber ich hoffe, die Ausführungen bringen Dich ein wenig weiter.

Geändert von Harry Stahl ( 6. Nov 2013 um 14:15 Uhr)
  Mit Zitat antworten Zitat
nezumi7

Registriert seit: 11. Apr 2011
71 Beiträge
 
#6

AW: .eml Dateien auslesen - wie decodieren?

  Alt 6. Nov 2013, 17:46
Hallo Harry,

super! Vielen Dank für Deine ausführlichen Erläuterungen. Das hilft mir auf jeden Fall schon mal weiter, weil ich einfach nicht wusste, ob man nicht lediglich bei einer Indy Komponente irgendeine Eigenschaft einstellen muss - und gut ist. So wie Du schreibst, ist wohl trotz Indy noch viel Handarbeit erforderlich und jetzt weiß ich zumindest, wo ich ansetzen muss, um mich da durchzufrickeln...

Thanks a lot,

Stephan
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:54 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz