Indy - POP3 problem z dekodowaniem nagłówka (tematu)

0

Witam!

Chciałbym w Delphi wylistować tematy z mojej poczty e-mail, jednak napotkałem problem z translacją tematu z nagłówka wiadomośći e-mail:

przykład:

"Re: =?UTF-8?q?Podzi=C4=99kowanie_za_transakcj=C4=99?="

Używam oczywiście komponentów Indy, natomiast Delphi jest w wersji 7.

Z tego co czytałem trzeba by było zdekodować z "Base 64" a potem zdekodować UTF-8, ale to tylko w teorii bo w praktyce takie dekodowanie nic mi nie daje (głupoty totalne).

Ustawianie "charsetu" dla komponentu TIdMessage też nic nie daje.


Mam przy okazji jeszcze jedno pytanie które mnie dręczy - mam w skrzynce email ponad 40 tysięcy wiadomości (poczta na onecie) - zastanawia mnie w jaki sposób działa klient e-mail - że pomio tylu wiadomości - pobiera on tylko te nowe. Czym się sugeruje klient pocztowy? Bo na pewno nie synchronizuje wiadomości które mam w kliencie pocztowym i wiadomości które są na serwerze. Pobieranie poczty zajmuje dosłownie sekundę. Jak to robi klient e-mail? i czy przy pomocy Indy też mogę tak zrobić?

Kawałek kodu:

     IdPOP31.Connect();
    MsgCount := IdPOP31.CheckMessages;
    for i:= Pred(MsgCount) downto (Pred(MsgCount)-10) do
    begin
      try
        FMailMessage := TIdMessage.Create(nil);
        FMailMessage.CharSet := 'UTF-8';
        FmailMessage.ContentTransferEncoding := 'quoted-printable' ;

zaczołem kombinować z pobieraniem najnowszych wiadomośći e-mail, ale to nie jest dobra metoda...

dodam że klienty poczty email nie synchronizują tego co jest na komputerze i tego co na serwerze, - bowiem zsynchronizowanie 40 tysięcy wiadomości nie zajeło by 1 sekundy...

0

Indy 9 i starsze wersje 10 nie dekoduje nagłówków UTF-8 tylko ISO i Windows ale w najnowszej do pobrania z http://indy.fulgan.com/ZIP/ (na oficjalnej stronie nie ma tej wersji) już nie ma problemu a więc pozostaje zainstalować najnowszą wersję Indy lub wnieść poprawkę w pliku IdCoderHeader.pas a następnie skompilować ponownie Indy Protocols. W funkcji DecodeHeader dodaj:
W Indy 9 po:

  // Get the Charset part.
  encodingstartpos:=PosStartAt('=?ISO', UpperCase(Header),1);
  if encodingstartpos = 0 then
    encodingstartpos:=PosStartAt('=?WINDOWS', UpperCase(Header),1);

dodaj:

  if encodingstartpos = 0 then
    encodingstartpos:=PosStartAt('=?UTF', UpperCase(Header),1);

W Indy 10 po:

  // Get the Charset part.
  EncodingBeforeEnd := -1;
  LEncodingStartPos := PosIdx('=?ISO', Sys.UpperCase(Header), 1); {do not localize}
  if LEncodingStartPos = 0 then begin
    LEncodingStartPos := PosIdx('=?WINDOWS', Sys.UpperCase(Header), 1); {do not localize}
  end;
  if LEncodingStartPos = 0 then begin
    LEncodingStartPos := PosIdx('=?KOI8', Sys.UpperCase(Header), 1); {do not localize}
  end;

dodaj:

  if LEncodingStartPos = 0 then begin
    LEncodingStartPos := PosIdx('=?UTF', Sys.UpperCase(Header), 1); {do not localize}
  end;

Po poprawce (lub w najnowszym Indy) powinno działać:

Subject:= UTF8ToAnsi(DecodeHeader(IdMessage.Subject));

Co do odbierania tylko nowych wiadomości to pobierasz sobie listę UIDL pozycja na liście wygląda np. tak:
1 0000000000a80e85
1 to numer wiadomości a kolejne litery i cyfry to ten unikalny identyfikator a więc za każdym razem pobierasz UIDL sprawdzasz których jeszcze nie ma w bazie i odczytujesz te wiadomości następnie zapisujesz do bazy identyfikatory wiadomości które już odczytałeś.

IdPOP3.UIDL(sl); //sl - typu TStringList lub TIdStringList

1 użytkowników online, w tym zalogowanych: 0, gości: 1