Версия для печати
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум на Исходниках.RU > Интернет, сети, протоколы > при отправке письма используя Indy 10, получаются "крякозябры" в теме


Автор: User32 02.09.09, 11:19
Многие кто когда либо отправлял или создавал письма используя Indy 10, получал совсем не читабельный вид темы письма
Как не странно, но разработчики решили, что в России для писем используют в основном KOI8R кодировку а не WINDOWS-1251.
Отсюда и такие "крякозябры" в теме письма.


Кпримеру:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    ...
    IdMessage1.CharSet := 'windows-1251'; //но это пока мы не исправим исходники роли не играет.
    ...
    IdMessage1.Subject := 'Тема письма';
    ...


Для исправления этого потребуется правка исходников Indy.
В модуле IdGlobalProtocols.pas находим функцию IdGetDefaultCharSet и меняем строку
LANG_RUSSIAN: Result := idcsKOI8_R;
на
LANG_RUSSIAN: Result := idcsWINDOWS_1251;
Ну и разумеется перекомпилируем.

Мне помогло, надеюсь поможет и вам ;)

Автор: mvdmvd 20.11.09, 08:43
Можно ли с Вами побеседовать?

Я, как то раз, в три часа ночи решил перейти на Indy 10? для того что бы отправлять письма через gmail.com ...
Лучше бы пошел спать!

У меня история такая: С темой у меня пока не получается еще - ...

Но даже пока еще не поменял в исходниках:

LANG_RUSSIAN: Result := idcsWINDOWS_1251;

устанавливая CharSet := 'windows-1251';

я отправлял письма на русском языке, потом просматривал в браузере - дошло по русски,
затем в том же Thunderbird-e получаю - все в порядке.

А на Indy 10-ом, хоть выспись - чего только не предпринимал.

Причем, меняя CharSet при отправке - в браузере я вижу, что кодировка самого тела меняется,
и я могу переключаться там и видеть, что совпадает с тем, что я отправил.

Но получить с помощью Indy 10 не получается.

Именно с такой ситуацией, Вы сталкивались?

Буду очень благодарен, если поддержите беседу, хотя бы парой писем.

Автор: X11 25.03.10, 21:01
У меня проблема другая.
Отправляю письмо хоть в юникоде, хоть в виндовой кодировке.
1. В теме указываю: Рассылка новых объектов
В письме приходит в ящик: новых объектов

2. Прикрепляю экселевский файл с русскоязычным названием. В ящик приходит с прикрплённым письмом, но имя Part1.2 или noname

D2007. Indy 10.5.7 (r4154 2010-03-25).

Добавлено
Вот код. Раньше на старой версии инди работал отлично.
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    procedure TfmEmail.SendMail(aRecordIndex:integer);
    Var
     q: TpFibQuery;
     IdEMailAddressList2, IdEMailAddressListCopy: TIdEMailAddressList;
    begin
      sCharSet := dbgmail.DataController.Values[aRecordIndex, dbgMailCHARSET.Index];
     
      if dbgmail.DataController.Values[aRecordIndex, dbgMailLOCKED.Index] then
        begin
     
          exit;
        end;
     
      Log('Отправка рассылки:' + dbgmail.DataController.Values[aRecordIndex, dbgMailname.Index]);
     
      IdSMTP1.DisConnect;
      IdMessage1.Clear;
      IdMessage1.From.Name    := '';
      SysLocale.PriLangID     := LANG_SYSTEM_DEFAULT;// LANG_RUSSIAN;// LANG_UKRAINIAN;
      IdMessage1.CharSet      := sCharSet;
      IdMessage1.ContentType  := 'multipart/related; type="multipart/alternative"';
    //  IdMessage1.ContentTransferEncoding := 'bit7';
      IdMessage1.ContentTransferEncoding := '8bit';
     
     
     
      IdSMTP1.ConnectTimeout  := 60*100;
     
      IdMessage1.From.Address := dbgmail.DataController.Values[aRecordIndex, dbgMailE_MAIL.Index];
      //от кого
      case ansiindextext(sCharSet, ['UTF-8', 'windows-1251']) of
    //    0: IdMessage1.From.Name    := AnsiToUtf8(dbgmail.DataController.Values[aRecordIndex, dbgMailFROM_NAME.Index]);
        0: IdMessage1.From.Name    := dbgmail.DataController.Values[aRecordIndex, dbgMailFROM_NAME.Index];
        1: IdMessage1.From.Name    := dbgmail.DataController.Values[aRecordIndex, dbgMailFROM_NAME.Index];
      end;
     
     
      //кому
      IdEMailAddressList2 := TIdEMailAddressList.Create(IdMessage1);
     
      //получатели
      case ansiindextext(sCharSet, ['UTF-8', 'windows-1251']) of
    //    0: IdEMailAddressList2.EMailAddresses := AnsiToUtf8(dbgmail.DataController.Values[aRecordIndex, dbgMailRECIPIENT.Index]);
        0: IdEMailAddressList2.EMailAddresses := dbgmail.DataController.Values[aRecordIndex, dbgMailRECIPIENT.Index];
        1: IdEMailAddressList2.EMailAddresses := dbgmail.DataController.Values[aRecordIndex, dbgMailRECIPIENT.Index];
      end;
     
      IdMessage1.Recipients.EMailAddresses := EncodeAddress(IdEMailAddressList2, 'B',  sCharSet);
     
     
      //копия
      if dbgMail.DataController.Values[aRecordIndex, dbgMailRECIPIENT_COPY.Index] <> null then
        begin
            IdEMailAddressListCopy := TIdEMailAddressList.Create(IdMessage1);
     
            //получатели
            case ansiindextext(sCharSet, ['UTF-8', 'windows-1251']) of
    //          0: IdEMailAddressListCopy.EMailAddresses := AnsiToUtf8(dbgMail.DataController.Values[aRecordIndex, dbgMailRECIPIENT_COPY.Index]);
              0: IdEMailAddressListCopy.EMailAddresses := dbgMail.DataController.Values[aRecordIndex, dbgMailRECIPIENT_COPY.Index];
              1: IdEMailAddressListCopy.EMailAddresses := dbgmail.DataController.Values[aRecordIndex, dbgMailRECIPIENT_COPY.Index];
            end;
            IdMessage1.CCList.EMailAddresses := EncodeAddress(IdEMailAddressListCopy, 'B',  sCharSet);
        end;
     
     
      //от кого
      case ansiindextext(sCharSet, ['UTF-8', 'windows-1251']) of
    //    0: IdMessage1.ReplyTo.EMailAddresses := AnsiToUtf8(dbgmail.DataController.Values[aRecordIndex, dbgMailSMTP_FROM.Index]);
        0: IdMessage1.ReplyTo.EMailAddresses := dbgmail.DataController.Values[aRecordIndex, dbgMailSMTP_FROM.Index];
        1: IdMessage1.ReplyTo.EMailAddresses := dbgmail.DataController.Values[aRecordIndex, dbgMailSMTP_FROM.Index];
      end;
     
      //тема
      case ansiindextext(sCharSet, ['UTF-8', 'windows-1251']) of
    //    0: IdMessage1.Subject    := AnsiToUtf8(dbgmail.DataController.Values[aRecordIndex, dbgMailSUBJECT.Index]);
        0: IdMessage1.Subject    := dbgmail.DataController.Values[aRecordIndex, dbgMailSUBJECT.Index];
        1: IdMessage1.Subject    := dbgmail.DataController.Values[aRecordIndex, dbgMailSUBJECT.Index];
      end;
     
     
        with TIdText.Create(IdMessage1.MessageParts, nil) do begin
          CharSet := sCharSet;
          case ansiindextext(sCharSet, ['UTF-8', 'windows-1251']) of
    //        0: Body.Add(AnsiToUtf8(dbgmail.DataController.Values[aRecordIndex, dbgMailTITLE.Index]));
            0: Body.Add(dbgmail.DataController.Values[aRecordIndex, dbgMailTITLE.Index]);
            1: Body.Add(dbgmail.DataController.Values[aRecordIndex, dbgMailTITLE.Index]);
          end;
     
          case ansiindextext(sCharSet, ['UTF-8', 'windows-1251']) of
    //        0: Body.Add(AnsiToUtf8(dbgmail.DataController.Values[aRecordIndex, dbgMailbody.Index]));
            0: Body.Add(dbgmail.DataController.Values[aRecordIndex, dbgMailbody.Index]);
            1: Body.Add(dbgmail.DataController.Values[aRecordIndex, dbgMailbody.Index]);
          end;
     
          case ansiindextext(sCharSet, ['UTF-8', 'windows-1251']) of
    //        0: Body.Add(AnsiToUtf8(dbgmail.DataController.Values[aRecordIndex, dbgMailFOOTER.Index]));
            0: Body.Add(dbgmail.DataController.Values[aRecordIndex, dbgMailFOOTER.Index]);
            1: Body.Add(dbgmail.DataController.Values[aRecordIndex, dbgMailFOOTER.Index]);
          end;
     
          ContentType := 'text/plain';
        end;
     
     
      IdMessage1.IsEncoded  := true;
     
      IdSMTP1.Host      := dbgmail.DataController.Values[aRecordIndex, dbgMailSMTP.Index];
      IdSMTP1.Username  := dbgmail.DataController.Values[aRecordIndex, dbgMailSMTP_USER.Index];
      IdSMTP1.Password  := Decrypt(dbgmail.DataController.Values[aRecordIndex, dbgMailSMTP_PASSWORD.Index], k_sm);
     
      case ansiindextext(dbgmail.DataController.Values[aRecordIndex, dbgMailSMTP_TYPE_CRYPT.Index], ['нет', 'неявное', 'явное', 'принудительное']) of
        0: IdSMTP1.UseTLS    := utNoTLSSupport;
        1: IdSMTP1.UseTLS    := utUseImplicitTLS;
        2: IdSMTP1.UseTLS    := utUseExplicitTLS;
        3: IdSMTP1.UseTLS    := utUseRequireTLS;
      end;
     
      IdSMTP1.Port      := dbgmail.DataController.Values[aRecordIndex, dbgMailSMTP_PORT.Index];
      IdSMTP1.AuthType  := satDefault;
     
      IdSSLIOHandlerSocketOpenSSL1.Destination  := IdSMTP1.Host + ':' + IntToStr(IdSMTP1.Port);
      IdSSLIOHandlerSocketOpenSSL1.Host         := IdSMTP1.Host;
      IdSSLIOHandlerSocketOpenSSL1.MaxLineAction:= maException;
      IdSSLIOHandlerSocketOpenSSL1.Port         := IdSMTP1.Port;
      IdSSLIOHandlerSocketOpenSSL1.DefaultPort  := 0;
      IdSSLIOHandlerSocketOpenSSL1.SSLOptions.Mode        := sslmUnassigned;
      IdSSLIOHandlerSocketOpenSSL1.SSLOptions.VerifyMode  := [];
      IdSSLIOHandlerSocketOpenSSL1.SSLOptions.VerifyDepth := 0;
     
      q := TpFibQuery.Create(nil);
      try
        q.Database := DM.fibDB;
        q.Transaction := trMailRead;
        q.SQL.Text    := 'SELECT NAME FROM MAIL_ATTACHMENTS where ID_MAIL = :m_ID';
        q.ParamByName('m_ID').AsInteger := dbgmail.DataController.Values[aRecordIndex, dbgMailID.Index];
        q.ExecQuery;
        q.GoToFirstRecordOnExecute := true;
        while not q.Eof do
            if FileExists(q.FieldByName('name').AsString) then
              begin
                with TIdAttachmentFile.Create(IdMessage1.MessageParts, q.FieldByName('name').AsString) do begin
                  case AnsiIndexText(ExtractFileExt(AnsiUpperCase(q.FieldByName('name').AsString)), ['.XLS', '.XLSX', '.RAR', '.ZIP', '.DOC', '.DOCX', '.HTML', '.TXT']) of
                    0: ContentType := 'application/vnd.ms-excel';
                    1: ContentType := 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
                    2: ContentType := 'application/x-rar-compres';
                    3: ContentType := 'application/zip';
                    4: ContentType := 'application/msword';
                    5: ContentType := 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
                    6: begin ContentType := 'text/html; charset=WINDOWS-1251'; {ContentDisposition := 'inline'} end;
                    7: begin ContentType := 'text/plain; charset=WINDOWS-1251'; {ContentDisposition := 'inline'} end;
                    else
                    ContentType := 'application/octet-stream';
     
                  end;
     
                  //FileName    := AnsiToUtf8(q.FieldByName('name').AsString);
                  FileName    := q.FieldByName('name').AsString;
                end;
                q.next;
              end;//if FileExists(q.FieldByName('name').AsString) then
      finally
        q.close;
        FreeAndNil(q);
      end;
     
      Log('Подключение к: ' + IdSMTP1.Host + ':'+IntToStr(IdSMTP1.Port));
      IdSMTP1.Connect;
     
      dxStatusBar1.Panels[1].Text := 'Отправка: ' + dbgmail.DataController.Values[aRecordIndex, dbgMailName.Index];
      Application.ProcessMessages;
     
      Log('Отправка.....');
      IdSMTP1.Send(IdMessage1);
     
      Log('Рассылка отправлена');
     
      Log('Отключение от сервера...');
      IdSMTP1.DisConnect;
     
      tMail.Edit;
      tMail.FBN('LAST_DATE').AsDateTime := now;
      tMail.FBN('SEND_COUNT').AsInteger := tMail.FBN('SEND_COUNT').AsInteger + 1;
      tMail.post;
      tMail.refresh;
     
      FreeAndNil(IdEMailAddressList2);
    end;

Автор: User32 29.06.10, 14:47
Цитата mvdmvd @
Можно ли с Вами побеседовать?

Я, как то раз, в три часа ночи решил перейти на Indy 10? для того что бы отправлять письма через gmail.com ...
Лучше бы пошел спать!

У меня история такая: С темой у меня пока не получается еще - ...

Но даже пока еще не поменял в исходниках:

LANG_RUSSIAN: Result := idcsWINDOWS_1251;

устанавливая CharSet := 'windows-1251';

я отправлял письма на русском языке, потом просматривал в браузере - дошло по русски,
затем в том же Thunderbird-e получаю - все в порядке.

А на Indy 10-ом, хоть выспись - чего только не предпринимал.

Причем, меняя CharSet при отправке - в браузере я вижу, что кодировка самого тела меняется,
и я могу переключаться там и видеть, что совпадает с тем, что я отправил.

Но получить с помощью Indy 10 не получается.

Именно с такой ситуацией, Вы сталкивались?

Буду очень благодарен, если поддержите беседу, хотя бы парой писем.

Ну не знаю, тут все индивидуально...
Какая версия Delphi и Indy?

У меня к примеру Delphi 6.0 EE + Indy 10.1.5 и уменя прекрасно работает вот этот пример.
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    procedure TForm1.Button1Click(Sender: TObject);
    var
      SL: TStringList;
      id_ris: string;
    begin
      SL := TStringList.Create;
      id_ris := 'ris_'+IntToHex(Random(MaxInt), 4) + IntToHex(Random(MaxInt), 4); // генерим идентификатор
      try
        SL.Add('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">');
        SL.Add('<html><head>');
        SL.Add('<title>Заголовок</title>'); //в принципи не нужен
        SL.Add('</head><body>');
        SL.Add('<div>Текст</div>');
        SL.Add('<img src="cid:' + id_ris + '">');// вот тут используем
        SL.Add('</body></html>');
        with TIdText.Create(IdMessage1.MessageParts, SL) do // загружаем тело письма
        begin
          ContentType := 'text/html'; // выставляем тип контента
          CharSet := 'windows-1251'; // выставляем тип кодировки
        end;
        with TIdAttachmentFile.Create(IdMessage1.MessageParts, 'C:\Копия Тестовое вложение Access.PNG') do
        begin
          ContentID := id_ris; // присваеваем идентификатор
        end;
     
        IdMessage1.Subject := 'Тестовое письмо'; // Тема письма
        IdMessage1.Recipients.EMailAddresses := 'user@mail.ru'; // Кому
        IdMessage1.From.Name := 'Президент России'; // От кого
        IdMessage1.From.Address:='president@mail.ru'; // EMail-От кого
        //*****************************************************
        IdSMTP1.MailAgent := 'Microsoft Outlook Express 6.00.2900.2180';
        IdSMTP1.Host := 'smtp.server.ru'; // Сервер SMTP
        IdSMTP1.Port := 25; // Порт сервера
        IdSMTP1.AuthType := satNone; // Тип аутенфикации \ без запроса логина и пароля
     
        IdSMTP1.Connect;
        IdSMTP1.Send(IdMessage1);
        IdSMTP1.Disconnect;
     
      finally
        SL.free;
      end;
    end;


Но при условии что мы изменили функцию IdGetDefaultCharSet в модуле IdGlobalProtocols.PAS

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    function IdGetDefaultCharSet: TIdCharSet;
    {$IFDEF USEINLINE}inline;{$ENDIF}
    begin
      {$IFDEF UNIX}
      Result := GIdDefaultCharSet;
      {$ENDIF}
      {$IFDEF DOTNET}
      Result := idcsUNICODE_1_1;
      // not a particular Unicode encoding - just unicode in general
      // i.e. DotNet native string is 2 byte Unicode, we do not concern ourselves
      // with Byte order. (though we have to concern ourselves once we start
      // writing to some stream or Bytes
      {$ENDIF}
      {$IFDEF WIN32_OR_WIN64_OR_WINCE}
      // Many defaults are set here when the choice is ambiguous. However for
      // IdMessage OnInitializeISO can be used by user to choose other.
      case SysLocale.PriLangID of
        LANG_CHINESE: begin
          if SysLocale.SubLangID = SUBLANG_CHINESE_SIMPLIFIED then begin
            Result := idcsGB2312;
          end else begin
            Result := idcsBig5;
          end;
        end;
        LANG_JAPANESE: Result := idcsISO_2022_JP;
        LANG_KOREAN: Result := idcscsEUCKR;
        // Kudzu
        // 1251 is the Windows standard for Russian but its not used in emails.
        // KOI8-R is by far the most widely used and thus the default.
    (* Изменения начинаются тут *)
    //    LANG_RUSSIAN: Result := idcsKOI8_R; //Rem by User32!!!
        LANG_RUSSIAN: Result := idcsWINDOWS_1251; //Add by User32!!!
    (* И заканчиваются тут *)
        // Kudzu
        // Ukranian is about 50/50 KOI8u and 1251, but 1251 is the newer one and
        // the Windows one so we default to it.
        LANG_UKRAINIAN: Result := idcswindows_1251;
        else begin
          Result := idcsISO_8859_1;
        end;
      end;
      {$ENDIF}
    end;


Добавлено
Цитата X11 @
У меня проблема другая.
Отправляю письмо хоть в юникоде, хоть в виндовой кодировке.
1. В теме указываю: Рассылка новых объектов
В письме приходит в ящик: новых объектов

2. Прикрепляю экселевский файл с русскоязычным названием. В ящик приходит с прикрплённым письмом, но имя Part1.2 или noname

D2007. Indy 10.5.7 (r4154 2010-03-25).

Я сейчас не работаю в Delphi 2007 - 2010, но вот эта статейка думаю может вам помочь.

http://denov.ru/?tag=tidattachmentfile

Powered by Invision Power Board (https://www.invisionboard.com)
© Invision Power Services (https://www.invisionpower.com)