Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi IdPOP3, UTF-8 Charset, Umlaute äöü (https://www.delphipraxis.net/133307-idpop3-utf-8-charset-umlaute-aeoeue.html)

MicAlter 29. Apr 2009 13:44


IdPOP3, UTF-8 Charset, Umlaute äöü
 
Hallo zusammen,

das Thema ist ja schon bekannt: EMail empfangen, Inhalt im UTF-8 Format, also Deutsche Umlaute entsprechend dem UTF-8 umgesetzt. Wie kriege ich dieses Ding nun nach ISO-8859-1 konvertiert???

Vielleicht habe ich ja auch nur ein Brett vor dem Kopf :gruebel:

Vorweg: Ich nutze Delphi 5 Enterprise mit Indy 9.0.18.

So sieht z.B. meine Nachricht aus:
Code:
Diese Mail wird im Unicode-Format (UTF-8) versandt.
 
Hier die deutschen Umlaute: ä ö ü ß Ä Ö Ü
Wenn ich die Mail nun mit meinem Programm auslese und den Inhalt wegschreibe, dann sieht das Ganze so aus:

Delphi-Quellcode:
POP.RetrieveRaw(1,MyStringList);
MyStringList.SaveToFile( 'c:\mail.txt' );
Code:
Received: from [127.0.0.1] by MA_NB_XP
  (ArGoSoft Mail Server Freeware, Version 1.8 (1.8.8.0)); Wed, 29 Apr 2009 13:00:20 +0200
From: "MicAlter" <micalter@yourdomain.de>
To: <micalter@yourdomain.de>
Subject: Testmail in UTF-8
Date: Wed, 29 Apr 2009 13:00:19 +0200
Message-ID: <7B3870150C1543989DC4E37A88602888@MANBXP>
MIME-Version: 1.0
Content-Type: multipart/alternative;
   boundary="----=_NextPart_000_0010_01C9C8CA.73884830"
X-Priority: 3 (Normal)
X-MSMail-Priority: Normal
X-Mailer: Microsoft Outlook, Build 10.0.6838
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.5579
Thread-Index: AcnIuOZp+T8pFEfISG+OaggCXaT6uQAAMDWw
Importance: Normal

This is a multi-part message in MIME format.

------=_NextPart_000_0010_01C9C8CA.73884830
Content-Type: text/plain;
   charset="utf-8"
Content-Transfer-Encoding: quoted-printable

Diese Mail wird im Unicode-Format (UTF-8) versandt.
=20
Hier die deutschen Umlaute: =C3=A4 =C3=B6 =C3=BC =C3=9F =C3=84 =C3=96 =
=C3=9C

------=_NextPart_000_0010_01C9C8CA.73884830
Content-Type: text/html;
   charset="utf-8"
Content-Transfer-Encoding: quoted-printable

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META HTTP-EQUIV=3D"Content-Type" CONTENT=3D"text/html; =
charset=3Dutf-8">
<TITLE>Nachricht</TITLE>

<META content=3D"MSHTML 6.00.6000.16825" name=3DGENERATOR></HEAD>
<BODY>
<DIV>
<DIV class=3DOutlookMessageHeader lang=3Dde dir=3Dltr align=3Dleft><FONT =
face=3DTahoma=20
size=3D2></FONT></DIV><FONT face=3DArial size=3D2><SPAN =
class=3D983435310-29042009>Diese=20
Mail wird im Unicode-Format (UTF-8) versandt.</SPAN></FONT></DIV>
<DIV><FONT face=3DArial size=3D2><SPAN=20
class=3D983435310-29042009></SPAN></FONT></DIV>
<DIV><FONT face=3DArial size=3D2><SPAN class=3D983435310-29042009>Hier =
die deutschen=20
Umlaute: =C3=A4 =C3=B6 =C3=BC =C3=9F =C3=84 =C3=96 =
=C3=9C</SPAN></FONT></DIV></BODY></HTML>

------=_NextPart_000_0010_01C9C8CA.73884830--
Wie ihr sehen könnt, werden die Umlaute nun wie folgt umgesetzt:
ä ^= =C3=A4
ö ^= =C3=B6
ü ^= =C3=BC
ß ^= =C3=9F
Ä ^= =C3=84
Ö ^= =C3=96
Ü ^= =C3=9C

So "richtiges" UTF-8 ist das doch nicht mehr, da der Body intern, also innerhalb des TIdPOP3-Objektes, als String vorliegt, oder?
Wie kann ich dieses nun korrekt umsetzen - natürlich ohne StringReplace?


Vielen Dank für die Unterstützung,
MicAlter

MicAlter 29. Apr 2009 13:45

Re: IdPOP3, UTF-8 Charset, Umlaute äöü
 
* t'schuldigung, wollte meinen Beitrag nur ändern * bitte löschen

mjustin 29. Apr 2009 16:58

Re: IdPOP3, UTF-8 Charset, Umlaute äöü
 
Zitat:

Zitat von MicAlter
Vorweg: Ich nutze Delphi 5 Enterprise mit Indy 9.0.18.

Von 9.0.18 bis zur aktuellen Version 10.2.3 bzw. 10.5.5 hat sich einiges getan, ich würde einen Test mit einer neueren Indy Version wagen (und die Komponente einfach dynamisch, ohne Installation in der IDE erzeugen, um die Deinstallations/Installations-Bauchschmerzen der Indy's zu minimieren).

Cheers,

himitsu 29. Apr 2009 17:08

Re: IdPOP3, UTF-8 Charset, Umlaute äöü
 
das ist erstmal UTF8-kodiert und dann nochmal so'ne komische Kodierung darüber, deren Namen ich ständig fergesse, wo alle Zeichen außerhalb des ASCII-Bereiches über Escape-Sequenzen kodiert werden "=" = Escapezeichen und danach dann Hexdezimal der Zeichencode des Zeichens.


Code:
=C3=A4
#$C3#$A4 aka #195#164
ä
Ä

=C3=9C
#$C3#$9C aka #195#156
Ü
Ü

[add]
steht doch drinnen :wall: http://de.wikipedia.org/wiki/Quoted-printable

Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable

[add2]
such mal im Forum oder bei Google nach
Hier im Forum suchenquoted-printable bzw. nach irgendwas wie Hier im Forum suchenMIMEDecode
(eventuell hat Letzeres dein INDY schon irgendwie mit dabei)

MicAlter 29. Apr 2009 17:58

Re: IdPOP3, UTF-8 Charset, Umlaute äöü
 
@mjustin: Leider darf ich, z.Zt. zumindest, die Indy-Version nicht austauschen...


Das mit dem quoted-printable ist es. Guter Hinweis, Danke himitsu.

Komisch aber, da dieses in Indy 9.x bereits implementiert ist. :gruebel:

Mittlerweile habe ich genau den Teil mal von Hand "quick'n dirty" programmiert:

Delphi-Quellcode:
function ConvertUTF8( AText : String ) : String;
    var i,nUTF8Code : Integer;
        sCode : String;
        sUTF8,wsUTF8Char : WideString;
    begin
      Result := '';
      sUTF8 := '';
      i := 1;
      while i <= length(AText) do
      begin
        //Sonderzeichen werden mit einem "=" gequoted
        if AText[i] = '=' then
        begin
          if i+2 <= length(AText) then
          begin
            sCode := Copy(AText,i+1,2);
            //IsHexable prüft nur, ob es gültige HEX-Zeichen 'a'..'z','A'..'Z','0'..'9' sind
            if IsHexable(sCode) then
            begin
              nUTF8Code := StrToInt('$'+sCode);
              wsUTF8Char := chr(nUTF8Code);
              sUTF8 := sUTF8 + wsUTF8Char;
            end;
          end;
          Inc(i,3);
        end
        else begin
          sUTF8 := sUTF8 + AText[i];
          Inc( i );
        end;

      end;

      //UTF8ToWideString aus dem Jedi-Paket
      Result := UTF8ToWideString(sUTF8);
    end;
Ist wirklich quick und wirklich dirty - aber für den ersten Test hat's gereicht.

Ich werd' mal sehen, warum die Indy-POP3-Komponente das nicht von sich aus macht... (lasse den Thread also noch offen)

MicAlter 29. Apr 2009 18:27

Re: IdPOP3, UTF-8 Charset, Umlaute äöü
 
Und nun mal in sauber(er) :)


Delphi-Quellcode:
uses ..., IdCoderQuotedPrintable, JclUnicode;

    var sBody : WideString;

    function ConvertQuotedPrintable( AText : String ) : String;
    var Decoder : TIdDecoderQuotedPrintable;
    begin
      Decoder := TIdDecoderQuotedPrintable.Create(nil);
      try
        Result := Decoder.DecodeToString( AText );
      finally
        FreeAndNil( Decoder );
      end;
    end;

    function ConvertUTF8( AText : WideString ) : WideString;
    begin
      Result := UTF8ToWideString(AText);
    end;

    if Pos( 'quoted-printable', IdMessage.ContentTransferEncoding ) > 0 then
       sBody := ConvertQuotedPrintable(IdMessage.Body.Text)
    else
      sBody := IdMessage.Body.Text;

    if Pos( 'utf-8', IdMessage.ContentType ) > 0 then
       sBody := ConvertUTF8(sBody);

himitsu 29. Apr 2009 18:49

Re: IdPOP3, UTF-8 Charset, Umlaute äöü
 
war am Ende also einfacher, als es aussah :mrgreen:


Ich würde den Funktionsparametern noch ein CONST verpassen,
denn vorallem WideString hat keine Referenzzählung und ohne würde für den Parameter eine eigene Kopie angelegt.
Delphi-Quellcode:
function ConvertQuotedPrintable ( const AText: String ) : String;

function ConvertUTF8( const AText : WideString ) : WideString;



oder alles in Kurz :angel:
Delphi-Quellcode:
uses ..., IdCoderQuotedPrintable, JclUnicode;

var sBody : WideString;

sBody := IdMessage.Body.Text;
if Pos( 'quoted-printable', IdMessage.ContentTransferEncoding ) > 0 then
  with TIdDecoderQuotedPrintable.Create(nil) do
    try
      sBody := DecodeToString(sBody);
    finally
      Free;
    end;
if Pos( 'utf-8', IdMessage.ContentType ) > 0 then
 sBody := UTF8ToWideString(sBody);

MicAlter 30. Apr 2009 08:45

Re: IdPOP3, UTF-8 Charset, Umlaute äöü
 
Ja, manchmal sieht man ja den Wald vor lauter Bäumen nicht...

Das mit dem CONST ist mir durchgegangen - guter Tipp :thumb: .

Ich habe beides in eine Funktion gepackt, damit man dieses auf für Text-Attachments benutzen kann. Wenn ich mir die Mail im HTML-Format sende, dann steht im Body (IdMessage.Body.Text) nur:
Delphi-Quellcode:
This is a multi-part message in MIME format.
Entsprechend muss zumindest geprüft werden, mit welchem Zeichensatz der HTML-Anhang codiert wurde. Würde also etwa so aussehen:

Delphi-Quellcode:
var TextAttachments : TStringList;
    sCurrentText : WideString;

TextAttachments := TStringList.Create;
try
  for i := 0 to IdMessage.MessageParts.Count-1 do
  begin
    if IdMessage.MessageParts[i] is TIdText then
    begin
      sCurrentText := StrPas( TIdText(IdMessage.MessageParts[i]).Body.Text );
      if Pos( 'utf-8', IdMessage.MessageParts[i].ContentType ) > 0 then
      begin      
        sCurrentText := ConvertUTF8( sCurrentText );
      end
      else begin
        //ggf. anderen Zeichensatz konvertieren...
      end;

      TextAttachments.Add( sCurrentText );
    end;
  end;

  //Verarbeite StringList "TextAttachments" mit konvertierten Text-Anlagen
  ...
finally
  FreeAndNil( TextAttachments );
end;
Falls jemand auch mal über dieses Problem stolpern sollte...

lg,
MicAlter

Samashy 14. Mär 2012 10:03

AW: IdPOP3, UTF-8 Charset, Umlaute äöü
 
Ich bin nun über dieses Problem gestolpert und komme nicht weiter.

Code:
Decoder.DecodeString(Result);
macht aus allen Umlauten A?

Ich arbeite mit Delphi 2009 und Indy 10


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:21 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz