Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как декодировать сообщения из TIdPOP3


Страницы:   1 2

Делфиец ©   (2010-10-26 08:43:00) 

Пишу простую почтовую проверялку писем с использованием компонентов Indy  TIdPOP3, TidMessage.

Проблема: в том, что некоторые письма отображаются в ином коде.  
Вопрос: Есть ли какой нибудь компонент Indy, который бы автоматически распознавал кодировку и декодировал в нужный код? Или как-нибудь исправить другим способом?


Сергей М.   (2010-10-27 11:05:00) [1]

Тогда  IdHeaderCoderPlain.pas  обязан быть в папке с индейскими исходниками.
Значит ты не указал путь к этой папке в списке Library path


Делфиец   (2010-10-27 10:52:00) [2]


> Сергей М. ©   (27.10.10 10:34) [20]


На свойствах компонентов версия определяется 10.1.5


Сергей М.   (2010-10-27 10:34:00) [3]

у тебя 9-ка что ли ?
этот юнит для 10-ки


Делфиец   (2010-10-27 10:31:00) [4]


> Сергей М. ©   (27.10.10 10:00) [18]


Проходится изобретать велосипед, когда не понимаешь как другие делают.
Еще ранее этот юнит "MsgHdrCoders" скачивал, но вот так и не разобрался  
проблемой стал этот модуль Uses IdHeaderCoderPlain
[DCC Error] MsgHdrCoders.pas(6): F1026 File not found: 'IdHeaderCoderPlain.dcu'


Сергей М.   (2010-10-27 10:00:00) [5]


unit MsgHdrCoders;

interface

uses
 IdHeaderCoderPlain;

type
 TCodeMatrix = array[1..255] of char;

const
 FirstCodes =
   #1#2#3#4#5#6#7#8#9#10#11#12#13#14#15#16#17#18#19#20#21#22#23#24#25#26#27#28+
  #29#30#31' !"#$%&''()*+,-./0123456789:;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^' +
   '_`abcdefghijklmnopqrstuvwxyz{|}~\x7F';
 cmAnsiToKoi8R: TCodeMatrix = FirstCodes
 + 'ЂЃ‚ѓ„…†‡€‰Љ‹ЊЌЋЏђ‘’“”•–—?™љ›њќћџ ЎўЈ¤Ґ¦§Ё©Є«¬­®Ї°±Ііґµ¶·Ј—є»јЅѕїбвчздецъй'
   + 'клмнопртуфхжигюыэящшьасБВЧЗДЕЦЪЙКЛМНОПРТУФХЖИГЮЫЭЯЩШЬАС';
 cmAnsiToKoi8U: TCodeMatrix = FirstCodes
 + 'ЂЃ‚ѓ„…†‡€‰Љ‹ЊЌЋЏђ‘’“”•–—?™љ›њќћџ ЎўЈ¤Ґ¦§Ё©Є«¬­®Ї°±Ііґµ¶·Ј—є»јЅѕїбвчздецъй'
   + 'клмнопртуфхжигюыэящшьасБВЧЗДЕЦЪЙКЛМНОПРТУФХЖИГЮЫЭЯЩШЬАС';
 cmKoi8RToAnsi: TCodeMatrix = FirstCodes
 + '-¦-¬L-++T++---¦¦---?¦•v??? ?°?·?=¦-ёг㬬¬LLL---¦¦¦¦Ё¦¦TTT¦¦¦+++©юабцдефгх'
   + 'ийклмнопярстужвьызшэщчъЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧЪ';
 cmKoi8UToAnsi: TCodeMatrix = FirstCodes
 + '-¦-¬L-++T++---¦¦---?¦•v??? ?°?·?=¦-ёєгії¬LLL-ґў¦¦¦¦ЁЄ¦ІЇT¦¦¦+ҐЎ©юабцдефгх'
   + 'ийклмнопярстужвьызшэщчъЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧЪ';
 cmOemDosToAnsi: TCodeMatrix = FirstCodes
 + 'АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп---¦+¦¦¬¬¦¦¬---¬L+T+-+¦¦L'
   + 'г¦T¦=+¦¦TTLL-г++----¦¦-рстуфхцчшщъыьэюяЁёЄєЇїЎў°•·v№¤¦ ';
 cmIsoToAnsi: TCodeMatrix = FirstCodes
 + '???????????????????????????????? ЁЂЃЄЅІЇЈЉЊЋЌ­ЎЏАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШ'
   + 'ЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя№ёђѓєѕіїјљњћќ§ўџ';
type

 TIdHeaderCoderKOI8 = class(TIdHeaderCoderPlain)
 public
   class function Decode(const ACharSet, AData: String): String; override;
   class function Encode(const ACharSet, AData: String): String; override;
   class function CanHandle(const ACharSet: String): Boolean; override;
 end;

function ConvertCharset(AString: String; AMatrix: TCodeMatrix): String;

implementation

uses IdGlobal, IdHeaderCoderBase;

function ConvertCharset(AString: String; AMatrix: TCodeMatrix): String;
var
 i: Integer;
begin
 Result := '';
 for i:= 1 to Length(AString) do
   Result := Result + AMatrix[Ord(AString[i])];
end;

{ TIdHeaderCoderKOI8 }

class function TIdHeaderCoderKOI8.CanHandle(const ACharSet: String): Boolean;
begin
 Result := TextIsSame(ACharSet, 'KOI8-R') or TextIsSame(ACharSet, 'KOI8-U');
end;

class function TIdHeaderCoderKOI8.Decode(const ACharSet, AData: String): String;
begin
 if TextIsSame(ACharSet, 'KOI8-R') then
   Result := ConvertCharset(AData, cmKoi8RToAnsi)
 else if TextIsSame(ACharSet, 'KOI8-U') then
   Result := ConvertCharset(AData, cmKoi8UToAnsi);
end;

class function TIdHeaderCoderKOI8.Encode(const ACharSet, AData: String): String;
begin
 if TextIsSame(ACharSet, 'KOI8-R') then
   Result := ConvertCharset(AData, cmAnsiToKoi8R)
 else if TextIsSame(ACharSet, 'KOI8-U') then
   Result := ConvertCharset(AData, cmAnsiToKoi8U);
end;

initialization
 RegisterHeaderCoder(TIdHeaderCoderKOI8);
finalization
 UnregisterHeaderCoder(TIdHeaderCoderKOI8);

end.


Сергей М.   (2010-10-27 10:00:00) [6]


> Делфиец


Ты изобрел велосипед.

Просто подключи к проекту, использующему IdPOP3, юнит след.содержания:


unit MsgHdrCoders;

interface

uses
 IdHeaderCoderPlain;

type
 TCodeMatrix = array[1..255] of char;

const
 FirstCodes =
   #1#2#3#4#5#6#7#8#9#10#11#12#13#14#15#16#17#18#19#20#21#22#23#24#25#26#27#28+
  #29#30#31' !"#$%&''()*+,-./0123456789:;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^' +
   '_`abcdefghijklmnopqrstuvwxyz{|}~\x7F';
 cmAnsiToKoi8R: TCodeMatrix = FirstCodes
 + '€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—?™š›& #339;žŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·£— º»¼½¾¿áâ÷çäåöú& #233;'
   + 'êëìíîïðòóôõæè& #227;þûýÿùøüàñÁÂ× 99;ÄÅÖÚÉÊËÌÍÎÏÐÒ ;ÓÔÕÆÈÃÞÛÝßÙØÜ& #192;Ñ';
 cmAnsiToKoi8U: TCodeMatrix = FirstCodes
 + '€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—?™š›& #339;žŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·£— º»¼½¾¿áâ÷çäåöú& #233;'
   + 'êëìíîïðòóôõæè& #227;þûýÿùøüàñÁÂ× 99;ÄÅÖÚÉÊËÌÍÎÏÐÒ ;ÓÔÕÆÈÃÞÛÝßÙØÜ& #192;Ñ';
 cmKoi8RToAnsi: TCodeMatrix = FirstCodes
 + '-¦-¬L-++T++---¦¦---?¦•v??? ?°?·?=¦-¸ã㬬¬LLL---¦¦¦¦¨¦¦TTT¦¦¦+++©þàáöäåôãõ'
   + 'èéêëìíîïÿðñòó& #230;âüûçøýù÷úÞÀÁ 14;ÄÅÔÃÕÈÉÊËÌÍÎÏ ;ßÐÑÒÓÆÂÜÛÇØÝÙ& #215;Ú';
 cmKoi8UToAnsi: TCodeMatrix = FirstCodes
 + '-¦-¬L-++T++---¦¦---?¦•v??? ?°?·?=¦-¸ºã³¿¬LLL-´¢¦¦¦¦¨ª¦²¯T¦¦¦+¥¡©þàáöäåôãõ'
   + 'èéêëìíîïÿðñòó& #230;âüûçøýù÷úÞÀÁ 14;ÄÅÔÃÕÈÉÊËÌÍÎÏ ;ßÐÑÒÓÆÂÜÛÇØÝÙ& #215;Ú';
 cmOemDosToAnsi: TCodeMatrix = FirstCodes
 + 'ÀÁÂÃÄÅÆÇÈÉÊËÌ& #205;ÎÏÐÑÒÓÔÕÖרÙ 18;ÛÜÝÞßàáâãäåæç ;èéêëìíîï---¦+¦¦¬¬¦¦¬---¬L+T+-+¦¦L'
   + 'ã¦T¦=+¦¦TTLL-ã++----¦¦-ðñòóôõö÷øùúûü&# 253;þÿ¨¸ªº¯¿¡¢°•·v¹¤¦ ';
 cmIsoToAnsi: TCodeMatrix = FirstCodes
 + '???????????????????????????????? ¨€ª½²¯£ŠŒŽ­¡ ÀÁÂÃÄÅÆÇÈÉÊËÌ&# 205;ÎÏÐÑÒÓÔÕÖר'
   + 'ÙÚÛÜÝÞßàáâãäå& #230;çèéêëìíîïðñò 43;ôõö÷øùúûüýþÿ¹ ;¸ƒº¾³¿¼šœž§¢ Ÿ';
type

 TIdHeaderCoderKOI8 = class(TIdHeaderCoderPlain)
 public
   class function Decode(const ACharSet, AData: String): String; override;
   class function Encode(const ACharSet, AData: String): String; override;
   class function CanHandle(const ACharSet: String): Boolean; override;
 end;

function ConvertCharset(AString: String; AMatrix: TCodeMatrix): String;

implementation

uses IdGlobal, IdHeaderCoderBase;

function ConvertCharset(AString: String; AMatrix: TCodeMatrix): String;
var
 i: Integer;
begin
 Result := '';
 for i:= 1 to Length(AString) do
   Result := Result + AMatrix[Ord(AString[i])];
end;

{ TIdHeaderCoderKOI8 }

class function TIdHeaderCoderKOI8.CanHandle(const ACharSet: String): Boolean;
begin
 Result := TextIsSame(ACharSet, 'KOI8-R') or TextIsSame(ACharSet, 'KOI8-U');
end;

class function TIdHeaderCoderKOI8.Decode(const ACharSet, AData: String): String;
begin
 if TextIsSame(ACharSet, 'KOI8-R') then
   Result := ConvertCharset(AData, cmKoi8RToAnsi)
 else if TextIsSame(ACharSet, 'KOI8-U') then
   Result := ConvertCharset(AData, cmKoi8UToAnsi);
end;

class function TIdHeaderCoderKOI8.Encode(const ACharSet, AData: String): String;
begin
 if TextIsSame(ACharSet, 'KOI8-R') then
   Result := ConvertCharset(AData, cmAnsiToKoi8R)
 else if TextIsSame(ACharSet, 'KOI8-U') then
   Result := ConvertCharset(AData, cmAnsiToKoi8U);
end;

initialization
  RegisterHeaderCoder(TIdHeaderCoderKOI8); // регистрация класса KOI8-кодека ! Аналогично пишется и регистрируется любой другой кодек
finalization
 UnregisterHeaderCoder(TIdHeaderCoderKOI8);

end.


Делфиец   (2010-10-27 08:30:00) [7]

исправил некий ляп:

function GetCode(Msg: TIdMessage): TMsgCode;
var temp: string;
begin
 if Msg.CharSet <> '' then begin
   Result := StrToCodeType(AnsiLowerCase(Msg.CharSet));
   Exit;
 end;

 if Msg.Headers.Values['Subject'] <> '' then begin
   Result := StrToCodeType(ExtractCharType(AnsiLowerCase(Msg.Headers.Values['Subject'])));
   Exit;
 end;

 if Msg.Headers.Values['From'] <> '' then begin
   Result := StrToCodeType(ExtractCharType(AnsiLowerCase(Msg.Headers.Values['From'])));
   exit;
 end;

end;


Делфиец   (2010-10-27 07:30:00) [8]

Как то пришлось потрудиться придумал такой способ определения кодировки:

Type TMsgCode = (UNK, KOI8R, KOI8U, WIN1251, UTF8);

const
 c_win_1251 = 'windows-1251';
 c_koi8_r  = 'koi8-r';
 c_koi8_u  = 'koi8-u';
 c_utf8    = 'utf8';

function GetCode(Msg: TIdMessage): TMsgCode;

implementation

function StrToCodeType(Str: String): TMsgCode;
var index: Integer;
begin
 index := AnsiIndexStr(Str,['',c_koi8_r,c_koi8_u,c_win_1251,c_utf8]);
 Result := TMsgCode(Index);
end;

function ExtractCharType(StrValue: String): String;
begin
 StrValue := StringReplace(StrValue,'=?','',[rfIgnoreCase]);
 Result   := Copy(StrValue,1,AnsiPos('?',StrValue)-1);
end;

function GetCode(Msg: TIdMessage): TMsgCode;
var temp: string;
begin
 if Msg.CharSet <> '' then begin
   Result := StrToCodeType(AnsiLowerCase(Msg.CharSet));
   Exit;
 end;
 
 if Msg.Headers.Values['Subject'] <> '' then begin
   Result := StrToCodeType(AnsiLowerCase(Msg.Headers.Values['Subject']));
 end;
end;

end;

// ................ применение .........

case GetCode(IdMessage) of
 UNK     : ;
 KOI8R   : ;
 KOI8U   : ;
 WIN1251 : ;
 UTF8    : ;
end;


Игорь Шевченко   (2010-10-26 15:02:00) [9]

для Mail2000 я руками писал. Работает


George   (2010-10-26 14:23:00) [10]


> Anatoly Podgoretsky ©   (26.10.10 13:01) [12]

Ну видимо да, как то так.


Anatoly Podgoretsky   (2010-10-26 13:01:00) [11]


> И это, насколько я помню, Инди должен автоматом хавать.
> Ну у меня хавал.

Что значит хавал, то есть с помощью ГСЧ выбирал одну из пяти кодировок и перекодировал, а я там еще Юникод упустил.


Anatoly Podgoretsky   (2010-10-26 12:59:00) [12]

> Делфиец  (26.10.2010 10:06:06)  [6]

koi-8 можно перекодировать только в 1251, 866, ISO, MAC, IBM


Anatoly Podgoretsky   (2010-10-26 12:58:00) [13]

> George  (26.10.2010 10:02:05)  [5]

Телепатически, не телепатически откуда, а куда иначе ни как.


Anatoly Podgoretsky   (2010-10-26 12:54:00) [14]

> Делфиец  (26.10.2010 09:56:04)  [4]

Вот это можно перекодировать.


George   (2010-10-26 12:30:00) [15]


> Но в Subject: =?koi8-r?B?6c7Gz9LNwcPJ0Q==?=    - содержит
> указание на кодировку как бы этим воспользоваться.

И это, насколько я помню, Инди должен автоматом хавать. Ну у меня хавал.


Dennis I. Komarov   (2010-10-26 10:58:00) [16]


> это что нужно иметь на все типы кодировок разные модули?

Да нет конечно, просто пишешь юзеру мессагу, типа влом мне всякой ересью заниматься...


Делфиец   (2010-10-26 10:06:00) [17]


> Делфиец   (26.10.10 09:56) [4]


Интересно, что отправленные письма из Outlook не содержат:
Content-Type
Content-Transfer-Encoding
Но в Subject: =? koi8-r?B?6c7Gz9LNwcPJ0Q==?=    - содержит указание на кодировку как бы этим воспользоваться.

Модуль для конвертации koi8 в Windows-1251 имеется, но вот а если письмо попадется в другой кодировке это что нужно иметь на все типы кодировок разные модули?


George   (2010-10-26 10:02:00) [18]


> Anatoly Podgoretsky ©   (26.10.10 09:48) [3]

Дык почему телепатическим? Насколько я знаю, исходя из заголовков как раз таки пляска идет.


Делфиец   (2010-10-26 09:56:00) [19]


> Anatoly Podgoretsky ©   (26.10.10 08:51) [1]
> Если есть в заголовке признак кодировке, то можно перекодировать,
>  в ограниченое количество других кодировок, но естественно
> руками.


В некоторых есть, а в некоторых нет:

-------------------------------------------------------
2 Subject:  | From.Name: =?UёF-8?B?0K/QvdC40L0g0JDQu9C10LrRgdC10Lk=?= | From.Adress: aleksey.yanin@usk.ilimgroup.ru | From.Size   : 1093 | Date: 19.10.2010 16:56:39
IdMessage.Headers.GetText:Return-Path: <aleksey.yanin@usk.ilimgroup.ru>
Received: from [195.46.103.14] (HELO [192.168.164.36])
 by usk.ilimgroup.ru (CommuniGate Pro SMTP 5.2.11)
 with ESMTP id 4026409 for konstantin.naumkin@usk.ilimgroup.ru; Tue, 19 Oct 2010 16:56:40 +0900
X-AntiVirus: Checked by Dr.Web [version: 5.0, engine: 5.00.2.03300, virus records: 1686365, updated: 19.10.2010]
Message-ID: <4CBD4F37.3010708@usk.ilimgroup.ru>
Date: Tue, 19 Oct 2010 16:56:39 +0900
From: =?UTF-8?B?0K/QvdC40L0g0JDQu9C10LrRgdC10Lk=?=
<aleksey.yanin@usk.ilimgroup.ru>
Organization: =?UTF-8?B?0J7QkNCeICLQk9GA0YPQv9C/0LAgItCY0LvQuNC8Ig==?=
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.2.9) Gecko/20100915 Thunderbird/3.1.4
MIME-Version: 1.0
To: konstantin.naumkin@usk.ilimgroup.ru
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit

2 Subject:  | From.Name: =?UTF-8?B?0K/QvdC40L0g0JDQu9C10LrRgdC10Lk=?= | From.Adress: aleksey.yanin@usk.ilimgroup.ru | From.Size   : 1093 | Date: 19.10.2010 16:56:39
-------------------------------------------------------
3 Subject: Информация | From.Name: PostMaster | From.Adress: post@usk.ilimgroup.ru | From.Size   : 1857478 | Date: 20.10.2010 13:45:08
IdMessage.Headers.GetText:Return-Path: <post@usk.ilimgroup.ru>
Received: from [195.46.103.14] (account post HELO kirshinaSA)
 by usk.ilimgroup.ru (CommuniGate Pro SMTP 5.2.11)
 with ESMTPA id 4030570 for all@usk.ilimgroup.ru; Wed, 20 Oct 2010 13:45:10 +0900
X-AntiVirus: Checked by Dr.Web [version: 5.0, engine: 5.00.2.03300, virus records: 1687584, updated: 20.10.2010]
From: "PostMaster" <post@usk.ilimgroup.ru>
To: <all@usk.ilimgroup.ru>
Subject: =?koi8-r?B?6c7Gz9LNwcPJ0Q==?=
Date: Wed, 20 Oct 2010 13:45:08 +0900
Message-ID: <002801cb7011$937c6870$ba753950$@ilimgroup.ru>
MIME-Version: 1.0
Content-Type: multipart/mixed;
boundary="----=_NextPart_000_0029_01CB705D.03641070"
X-Mailer: Microsoft Office Outlook 12.0
Thread-Index: Actv/7JdlAclew9EQnGEdbe4Ybfz4gACOsNAAAI5LlA=
Content-Language: ru

3 Subject: йОЖПТНБГЙС | From.Name: PostMaster | From.Adress: post@usk.ilimgroup.ru | From.Size   : 1857478 | Date: 20.10.2010 13:45:08
-------------------------------------------------------


Anatoly Podgoretsky   (2010-10-26 09:48:00) [20]

Ну да автоматически, и при этом телепатическим методом, определяет в какую кодировку преобразовывать. POP3 это не визуальный компонент.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо