Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Сети > IdPOP3, Как с ним работать?


Автор: Dimyan 3.3.2005, 15:09
Помогите разобратся пожалуйста
почитал я про этот IdPOP3 нифига понять путем не могу
попробывал сделать функцию она говорит что не может сохранить приатаченный файл
Код

 IdPOP31.Connect(50000);
 for i:=1 to IdPOP31.CheckMessages do
 begin
   if IdPOP31.Retrieve(i, IdMessage1) then
   begin
     TIdAttachment(IdMessage1.MessageParts.Items[i]).SaveToFile(
     TIdAttachment(IdMessage1.MessageParts.Items[i]).FileName);
     TIdAttachment.Create(IdMessage1.MessageParts, TIdAttachment(IdMessage1.MessageParts.Items[i]).FileName);
   end;
 end;

Мне нужно получить файл с почты, сохранить его в установленное место и вытащить из него приаттаченный файл, точнее даже сообщение сохронять не обязательно, главное сохранить приаттаченый файл

Автор: _hunter 3.3.2005, 15:37
перед использованием объекта его создать неплохо бы ;)
а у тебя создание в конце идет + указатель теряется

Автор: Snowy 3.3.2005, 15:44
Нужно брать Items не от i, а от 0 до TIdMessageParts.AttachmentCount-1

Автор: Dimyan 4.3.2005, 08:16
Все равно что то не получается smile(
Код

procedure TMainForm.ReceiveMail();
var
 i, MesCnt :Integer;
 Attach :TIdAttachment;
begin
try
MessageBase.Clear;

 ReceiveBase.Connect(50000);
 if ReceiveBase.Connected then
 begin
   MesCnt := ReceiveBase.CheckMessages;
   while MesCnt > 0 do
   begin
     if ReceiveBase.Retrieve(MesCnt, MessageBase) then
     begin
       for i:=0 to MessageBase.MessageParts.Count do
       begin
         if MessageBase.MessageParts.Items[i].ClassType = TIdAttachment then
         begin
           Attach := MessageBase.MessageParts.Items[i] as TIdAttachment;
           Attach.SaveToFile(Attach.FileName);
         end;
       end;
     end;
     dec(MesCnt);
   end;
  end;
finally
 if ReceiveBase.Connected then ReceiveBase.Disconnect;
 Attach.Free;
end;
end;


где: MessageBase - TIdMessage
ReceiveBase - TIdPOP3

Пишет что ошибка сохранения аттача smile(
Подскажте плиз где ошибка, уже второй день с этим РОР3 бьюсь, нифига не выходит smile(

Автор: Snowy 4.3.2005, 10:55
Вот накатал пример. В Uses нужно добавить IdPOP3 и IdMessage.
В остальном функция самодостаточна.
Для сохранения рекомендую добавить каталог к FileName.
Код

procedure ReseiveMail(Host: string; Port: integer; User, Password: string);
var
 pop: TIdPOP3;
 m:   TIdMessage;
 mc,i: integer;
begin
 pop:=TIdPOP3.Create(nil);
 pop.Host:=Host; pop.Port:=Port;
 pop.Username:=User; pop.Password:=Password;
 try
   pop.Connect(60000);
   mc:=pop.CheckMessages;
   while mc>0 do begin
     m:=TIdMessage.Create(pop);
     pop.Retrieve(mc,m);
     for i:=0 to m.MessageParts.Count-1 do
       with m.MessageParts do
         if items[i].ClassType=TIdAttachment then
           with TIdAttachment(items[i]) do
             try
               if FileExists(FileName) then DeleteFile(FileName);
               SaveToFile(FileName);
             except
               ShowMessage('Не удается сохранить файл');
             end;
     m.Free; dec(mc);
   end;
   ShowMessage('Все в порядке');
 except
   ShowMessage('Не удалось подключиться к серверу');
 end;
 pop.Free;
end;

Автор: Dimyan 4.3.2005, 12:12
Почему то вот не начинается выполнение цикла smile
Код

for i:=0 to m.MessageParts.Count-1 do

хотя почта на ящике есть и вся она с одним приаттаченым файлом
говорит что m.MessageParts.Count = 1, ну и соответственно при m.MessageParts.Count-1 получается 0 и цикл перестает крутиться smile

Автор: Snowy 4.3.2005, 12:18
Сейчас проверил. Код рабочий. Аттач складывается в папочку.
Попробуй указать полный путь, куда сохранять файл.

Цитата(Dimyan @ 4.3.2005, 12:12)
m.MessageParts.Count = 1, ну и соответственно при m.MessageParts.Count-1 получается 0

Все правильно - крутим от 0 до 0 = 1 раз.
Можно крутить от -255 до -255 = 1 раз.
Пусть 0 не пугает. Тут все нормально.

Автор: Dimyan 4.3.2005, 12:50
Я вот так указал и ноль эффекта
Код

if FileExists('C:\'+ FileName) then DeleteFile('C:\'+ FileName);
SaveToFile('C:\'+ FileName);


точнее я проверил несколько раз, и почему то он не входит в цикл smile(
более того я попробывал закоментировать цикл и поставить вместо i ноль (просто для проверки)
и как оказалось что
Код

if items[0].ClassType=TIdAttachment then
           with TIdAttachment(items[0]) do
             try
               if FileExists('C:\'+ FileName) then DeleteFile('C:\'+ FileName);
               SaveToFile('C:\'+ FileName);
             except
               ShowMessage('Не удается сохранить файл');
             end;

тоже проскакивает smile как будто items[0].ClassType не равно TIdAttachment
Добавлено @ 12:55
вот блин а теперь все получилось
чет я намудрил короче

Snowy, спасибо все работает
Добавлено @ 12:55
вот блин а теперь все получилось
чет я намудрил короче

Snowy, спасибо все работает
Добавлено @ 12:58
Snowy, подскажи еще если не сложно, а как теперь можно узанать адрес от кого пришло сообщение?

Автор: Snowy 4.3.2005, 13:33
m.From.Name - имя
m.From. Address - адрес
m.From.Text - имя и адрес вместе
Добавлено @ 13:35
Все string;
И еще добавь перед m.Free строчку
pop.Delete(mc);
Чтобы удалять сообщения из ящика.

Автор: Dimyan 4.3.2005, 14:12
А еще такой вопрос:
Как можно сохранить аттачмент со своим именем файла?

Автор: Snowy 4.3.2005, 14:16
C каким своим?
Ты же ручками пишешь:
SaveToFile('C:\'+FileName);
C каким именем хочешь, с таким и сохраняй.
Что ты имеешь ввиду под "своим именем файла"?

Автор: Dimyan 4.3.2005, 14:36
Snowy, я это и имел в виду, все уже чтото заработался домой пора, а то глюки начинаются smile(

Автор: TP@MB@Y 16.6.2005, 22:47
Хм. А если в письме два вложенных файла? Первый сохраняется нормально, а вот как дело доходит до второго - ошибка!
Как в этой ситуации действовать?

Автор: Snowy 17.6.2005, 09:32
Цитата(TP @ 16.6.2005, 22:47)
А если в письме два вложенных файла?

Да хоть десять.
Приведенный пример перебирает все части письма и складывает все аттачи в папку.
Точно помню, что проверял.
Даже, если вдруг имена совпадут (что маловероятно).
Попробуй запусть не в дельфи, а сам ехешник.

Автор: TP@MB@Y 18.6.2005, 20:08
Snowy
Странно... без дельфей все работает нормально smile

Тока я заметил интересную вещь: скаченый файл увеличивается на 2 байта! Скорее всего это символы 10 и 13
Почему? И как это предотвратить?

Автор: Snowy 20.6.2005, 09:46
Цитата(TP @ 18.6.2005, 20:08)
Странно... без дельфей все работает нормально

Ничего странного. Конструкции try ... except так себя и ведут при включенном отладчике.

Цитата(TP @ 18.6.2005, 20:08)
Тока я заметил интересную вещь: скаченый файл увеличивается на 2 байта! Скорее всего это символы 10 и 13
Почему? И как это предотвратить?

Что-то не замечал.
Проверял с архивами - вполне работоспособны после сохранения.
На размер не смотрел...
Сомневаюсь, что что-то не так, но проверить сейчас нет возможности.
Если все же так, то дело не в этом коде, а в реализации TIdAttachment.
Попробуй сравнить исходный файл и принятый при помощи консольной комманды:
fc /b file1.ext file2.ext

Автор: TP@MB@Y 20.6.2005, 23:10
А вообще письмо может не отправиться? Т.е. допустим коннект установлен, все поля заполнены, но по какой то внешней причине send() не срабатывает. Как узнать, чтобы переслать письмо?

Автор: Snowy 21.6.2005, 09:17
Цитата(TP @ 20.6.2005, 23:10)
А вообще письмо может не отправиться?

Письмо может не отправиться из-за плохой связи, либо, если сервер не остроили условия или он требует аутентификацию.
Вообще-то топик про IdPOP3.

Цитата(TP @ 20.6.2005, 23:10)
send() не срабатывает. Как узнать, чтобы переслать письмо?

По-моему так:
Код

try
  smtp.Send;
except
  не удалось отправить
end;

Автор: TP@MB@Y 24.6.2005, 01:02
Snowy
Ясно.

Сорри, за оффтоп, но как сделать чтобы отправленое письмо было в кодировке windows-1251 ?

Автор: Snowy 24.6.2005, 09:54
Цитата(TP @ 24.6.2005, 01:02)
как сделать чтобы отправленое письмо было в кодировке windows-1251 ?

Нужно прописать ее в TIdMessage.ContentTransferEncoding
Но это свойство не перекодирует само письмо, а только указывает какая кодировка.
Ты сам должен заполнять текст письма в нужной кодировке.
В заголовке она только конкретизируется для почтового клиента, чтобы ему не приходилось догадываться.
Если исходный текст у тебя в другой кодировке - читай FAQ по кодировкам.

P.S. и на будущее - если у тебя возник другой вопрос - создай для него отдельный топик.
А то придет злой модератор и будет громко ругаться.
Да и шансов получить ответ будет больше.

Автор: Alex 30.6.2005, 10:13
Цитата(Snowy @ 24.6.2005, 10:54)
А то придет злой модератор и будет громко ругаться

Будет!
Модератор: Пожалуйста, один топик - один вопрос. Тема закрыта.

Автор: mrVerus 10.3.2009, 07:39
Парни помогите очень нужно получить письмо и сожранить его с аттачментом в файл *.eml не изменяя структуры  оставить для других клиентских программ не дешифруя а просто сохронить. Зарание спасибо!!!

Автор: Matematik 10.3.2009, 20:31
mrVerus

> получить письмо и сожранить его с аттачментом в файл *.eml не изменяя структуры 

Пример соединения с POP3 есть вверху.
Вместо Retrieve() пользуй RetrieveRaw(), метод получает письмо, ничего в нем не меняя, и сохраняет его в TStringList, который можно далее сохранить в файл

Код

// var sl:TStringList;
sl := TStringList.Create;
try
  pop.RetrieveRaw(mc, sl); 
  sl.SaveToFile('mail.eml');
finally
  sl.Free;
end


Автор: mrVerus 11.3.2009, 14:04
Спасибо тебе Matematik огромное. Я пишу почтовый сервер для лакалки с пересылкой на внешний почтовый ящик на номпонентах idSMTPServer,idPOP3Server,idPOP3 и idSMTP. Сколько код не долбил и читал описание получения нормально нигде не описано с серверами хоть как то понятно. Еще раз спасиб.

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