Synapse ararat, вложенные файлы на русском языке

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Synapse ararat, вложенные файлы на русском языке

Сообщение mildok » 05.08.2016 14:04:56

Lazarus 1.6.0, fpc 3.0.0
synapse 40, также проблема наблюдается в 203 trunk'е.

Здравствуйте, отправлять письма и пристёгивать файлы - получается, проблем нет.

Проблема с кодировкой пристёгнутых файлов- она меняется на системную, то есть на CP1251.

В заголовках письма выглядит так:
Content-Disposition: attachment;
FileName="=?ISO-8859-5?Q?=C0=FC=C0=F5=C0=A6=C1=5F=C0=F0_=C1=5F=C0=5F=C0=F4=C1=A3=C1=5F=C0=F5=C0=A6=C1=5F=C0=F0_?=
=?ISO-8859-5?Q?=C0=5F=C0=F5=C0=F4=C1=F3=C0=F8=C0=5F=C0=A5=C1=5F.txt?="
Content-Description: Attached file: Новый текстовый
документ.txt


Отображается в письме так:
РќРѕРІС_Р№ С_Р_РєСЃС_РѕРІС_Р№ Р_РѕРєСѓРјР_РЅС_.txt


Код:
Код: Выделить всё
  MsgMail := TMimeMess.Create; //создаем новое сообщение
  MsgMail.Header.CharsetCode:=UTF_8;
  MsgMail.MessagePart.CharsetCode:=UTF_8;
  MsgMail.MessagePart.DefaultCharset:='UTF-8';
  MsgMail.MessagePart.TargetCharset:=UTF_8;
  MsgMail.MessagePart.ConvertCharset:=true;
  MIMEPartMails := MsgMail.AddPartMultipart('mixed', nil);
  MsgMail.AddPartTextEx(BodyBig, MIMEPartMails, UTF_8, true, ME_7BIT);

  MsgMail.AddPartBinaryFromFile('D:\Новая папка\Новая папка\Новый текстовый документ.txt', MIMEPartMails);

  MsgMail.EncodeMessage;


Насколько я понимаю происходит вот что:

Код: Выделить всё
function TMimeMess.AddPartBinaryFromFile(const FileName: string; const PartParent: TMimePart): TMimepart;
Begin
...
   Result := AddPartBinary(tmp, ExtractFileName(FileName), PartParent);
...

Код: Выделить всё
function TMimeMess.AddPartBinary(const Stream: TStream; const FileName: string; const PartParent: TMimePart): TMimepart;
begin
...
   Result := AddPart(PartParent);
...

Код: Выделить всё
function TMimeMess.AddPart(const PartParent: TMimePart): TMimePart;
begin
...
    Result := PartParent.AddSubPart;
  Result.Clear;
end;

Код: Выделить всё
function TMIMEPart.AddSubPart: TMimePart;
begin
  Result := TMimePart.Create;
  Result.DefaultCharset := FDefaultCharset;
  FSubParts.Add(Result);
...

Код: Выделить всё
constructor TMIMEPart.Create;
begin
...
  FTargetCharset := GetCurCP;
...
end;

Код: Выделить всё
procedure TMIMEPart.Clear;
begin
...
  FTargetCharset := GetCurCP; 
...


Как видно значение FTargetCharset теряется в функции TMIMEPart.AddSubPart и заменяется на кодировку системы в которой запущена программа, и мой любимый UTF-8 меняется на CP1251.
И повторно теряется в функции TMimeMess.AddPart, когда происходит Clear, который также меняется значение FTargetCharset на текущую системную.
В результате чего проблема проявляется здесь:

Код: Выделить всё
procedure TMIMEPart.EncodePartHeader;
...
begin
...
  if FDisposition <> '' then
  begin
    s := '';
    if FFileName <> '' then
      s := '; FileName=' + QuoteStr(InlineCodeEx(FileName, FTargetCharset), '"');
    FHeaders.Insert(0, 'Content-Disposition: ' + LowerCase(FDisposition) + s);
  end;


Всё верно в FTargetCharset будет равно CP1251, а не UTF-8.

Собственно проблема решается, например вот так:
Код: Выделить всё
procedure TMIMEPart.Clear;
begin
...
//  FTargetCharset := GetCurCP; 
...


Код: Выделить всё
...
function TMIMEPart.AddSubPart: TMimePart;
begin
  Result := TMimePart.Create;
  Result.DefaultCharset := FDefaultCharset;
  Result.TargetCharset := FTargetCharset;
  FSubParts.Add(Result);
...


Или вообще вот так:
Код: Выделить всё
procedure TMIMEPart.EncodePartHeader;
...
begin
...
  if FDisposition <> '' then
  begin
    s := '';
    FTargetCharset := UTF_8;
    if FFileName <> '' then
      s := '; FileName=' + QuoteStr(InlineCodeEx(FileName, FTargetCharset), '"');
    FHeaders.Insert(0, 'Content-Disposition: ' + LowerCase(FDisposition) + s);
  end;


Но это какие-то нехорошие способы - скажите что я делаю не так? :(
mildok
новенький
 
Сообщения: 22
Зарегистрирован: 08.05.2010 14:09:36

Re: Synapse ararat, вложенные файлы на русском языке

Сообщение mildok » 11.08.2016 11:29:31

Всё хорошо - пошевелил немного мозгами пришёл к такому коду:

Код: Выделить всё
  MsgMail := TMimeMess.Create; //создаем новое сообщение
  MsgMail.Header.CharsetCode:=UTF_8;
  MsgMail.MessagePart.CharsetCode:=UTF_8;
  MsgMail.MessagePart.DefaultCharset:='UTF-8';
  MsgMail.MessagePart.TargetCharset:=UTF_8;
  MsgMail.MessagePart.ConvertCharset:=true;
  MIMEPartMails := MsgMail.AddPartMultipart('mixed', nil);
  MsgMail.AddPartTextEx(BodyBig, MIMEPartMails, UTF_8, true, ME_7BIT);

  tmp1:=MsgMail.AddPartBinaryFromFile('D:\Новая папка\Новая папка\Новый текстовый документ.txt', MIMEPartMails);
  tmp1.TargetCharset:=UTF_8;
  tmp1.EncodePartHeader; 

  MsgMail.EncodeMessage;


То есть после AddPartBinaryFromFile ставим мою любимую кодировку, UTF_8. И заново кодируем заголовки EncodePartHeader.
Всё - теперь названия файлов, приходящие на почту имеют правильную кодировку. Тему можно закрывать.


Люблю Synapse и Lazarus :D
mildok
новенький
 
Сообщения: 22
Зарегистрирован: 08.05.2010 14:09:36


Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: Google [Bot] и гости: 246

Рейтинг@Mail.ru