View Full Version : مشكل در خواندن subject نامه هاي الكترونيك با TIdMessage
Kamyar.Kimiyabeigi
دوشنبه 08 مهر 1387, 09:45 صبح
با سلام
من با دلفي به gmail وصل ميشم و email ها رو ميگيرم. اما دو تا مشكل دارم :
نامه هايي كه موضوع فارسي دارن را درست نمايش نميده
بدنه نامه رو خالي مياره؟
vcldeveloper
دوشنبه 08 مهر 1387, 17:11 عصر
چه کدی نوشتید؟
Kamyar.Kimiyabeigi
سه شنبه 09 مهر 1387, 07:32 صبح
procedure TForm1.Button1Click(Sender: TObject);
var
iMsgCount, I, intIndex, j: Integer;
begin
POP3.Connect;
iMsgCount := POP3.CheckMessages;
Memo1.Lines.Add('CheckMessages: ' + IntToSTr(iMsgCount));
for I := 1 to iMsgCount do
begin
Msg.Clear;
POP3.Retrieve(I, Msg);
// POP3.RetrieveHeader(I, Msg);
Memo1.Lines.Add('Subject: ' + Msg.Subject);
Memo1.Lines.Add('IsEncode: ' + IntTostr((Ord(Msg.IsEncoded))));
Memo1.Lines.Add('Date: ' + DateToStr(Msg.Date));
if Msg.MessageParts.Count > 0 then
begin
for j := 0 to Msg.MessageParts.Count-1 do
begin
if Msg.MessageParts[j] is TIdText then
Memo1.Lines.Add('Body: ' + TIdText(Msg.MessageParts[j]).Body.Text);
end;
end;
// else
// Memo1.Lines.Add('Body: ' + Msg.Body.Text);
Memo1.Lines.Add('*****************************');
end;
Memo1.Lines.Add('End');
end;
vcldeveloper
پنج شنبه 11 مهر 1387, 17:17 عصر
نامه هايي كه موضوع فارسي دارن را درست نمايش نميده
مطمئن هستید که CodePage ویندوز برای متن های غیر یونیکد روی فارسی تنظیم شده؟
فکر کنم Subject نامه ها بصورت ASCII ارسال میشه. اگر به فرض، یونیکد ارسال بشه، که علت درست نمایش داده نشدنش مشخص هست؛ نوع string در دلفی ANSI هست، در Indy هم به همین شکل.
برای متن نامه ها هم آیا ContentTransfer و ContentType آنها را چک کردید؟ اگر بله، مقدارشان چی بود؟
Kamyar.Kimiyabeigi
دوشنبه 15 مهر 1387, 08:41 صبح
مطمئن هستید که CodePage ویندوز برای متن های غیر یونیکد روی فارسی تنظیم شده؟
فکر کنم Subject نامه ها بصورت ASCII ارسال میشه. اگر به فرض، یونیکد ارسال بشه، که علت درست نمایش داده نشدنش مشخص هست؛ نوع string در دلفی ANSI هست، در Indy هم به همین شکل.
ببخشيد منظورتونو متوجه نشدم از اينكه Codepage ويندوز براي متنهاي غير يونيكد روي فارسي تنظيم باشه؟
برای متن نامه ها هم آیا ContentTransfer و ContentType آنها را چک کردید؟ اگر بله، مقدارشان چی بود؟
مقدار ContentTransfer و ContentType رو چك كردم خالي بود ولي اگر مستقيم از خود TidMessage از Body.Text استفاده كنم خروجي يك چيز كلي هست كه شامل همه چيزه هم اين دوتا متغير مقدار دارن هم Body مياد منتها همه داخل Body.Text هست و جدا كردنشون سخته. من براتون برناممو ميزارم شما لطف كنين يك بررسي كنيد شايد من جايي اشتباه كار كرده باشم.
بازم ممنون
vcldeveloper
دوشنبه 15 مهر 1387, 10:56 صبح
منظورتونو متوجه نشدم از اينكه Codepage ويندوز براي متنهاي غير يونيكد روي فارسي تنظيم باشه؟منظورم صفحه سوم در تظنیمات Regional Settings ویندوز هست.
من براتون برناممو ميزارم شما لطف كنين يك بررسي كنيد شايد من جايي اشتباه كار كرده باشم.متاسفانه نتوستم برنامه تون رو کامپایل کنم، چون نسخه Indy که استفاده کردید 10 هست، و من نسخه 9 را دارم.
آیا نامه هایی که دریافت می کنید، IsEncoded شان True هست؟ اگر IsEncoded فعال باشه، باید MessageParts را بخونید و برای هر Part هم ContentTranfer و ContentType آن را بدست بیارید. اما اگر IsEncoded فعال نیست، پس متن بصورت متن ساده ASCII ارسال شده.
Kamyar.Kimiyabeigi
شنبه 20 مهر 1387, 09:18 صبح
procedure TForm1.Button1Click(Sender: TObject);
var
iMsgCount, I, intIndex, j: Integer;
begin
POP3.Connect;
iMsgCount := POP3.CheckMessages;
Memo1.Lines.Add('CheckMessages: ' + IntToSTr(iMsgCount));
for I := 1 to iMsgCount do
begin
Msg.Clear;
POP3.Retrieve(I, Msg);
// POP3.RetrieveHeader(I, Msg);
if Msg.IsEncoded then
Memo1.Lines.Add('IsEncode: True')
else
Memo1.Lines.Add('IsEncode: False');
Memo1.Lines.Add('ContentTranfer : ' + Msg.ContentTransferEncoding);
Memo1.Lines.Add('ContentType : ' + Msg.ContentType);
Memo1.Lines.Add('Subject: ' + Msg.Subject);
Memo1.Lines.Add('IsEncode: ' + IntTostr((Ord(Msg.IsEncoded))));
Memo1.Lines.Add('Date: ' + DateToStr(Msg.Date));
{if Msg.MessageParts.Count > 0 then
begin
for j := 0 to Msg.MessageParts.Count-1 do
begin
if Msg.MessageParts[j] is TIdText then
Memo1.Lines.Add('Body: ' + TIdText(Msg.MessageParts[j]).Body.Text);
end;
end;
else}
Memo1.Lines.Add('Body: ' + Msg.Body.Text);
Memo1.Lines.Add('*****************************');
end;
Memo1.Lines.Add('End');
end;
من يك ميل زدم و نتيجه رو به صورت زير گرفتم با توجه به كدي كه در بالا براتون گذاشتم
CheckMessages: 1
IsEncode: False
ContentTranfer :
ContentType : text/plain
Subject:
IsEncode: 0
Date: 1899/12/30
Body:
Content-Type: text/plain; charset=us-ascii
body is not empty
Kamyar Kimiyabeigi
--0-2117900021-1223704697=:27726
Content-Type: text/html; charset=us-ascii
<html><head><style type="text/css"><!-- DIV {margin:0px;} --></style></head><body><div style="font-family:times new roman,new york,times,serif;font-size:14pt">body is not empty<br><div> </div>Kamyar Kimiyabeigi<div><br></div></div><br>
</body></html>
--0-2117900021-1223704697=:27726--
*****************************
End
حالا من چه جوري اين متن رو كه body is not empty هست از body.text بگيرم ؟
vcldeveloper
یک شنبه 21 مهر 1387, 03:55 صبح
حالا من چه جوري اين متن رو كه body is not empty هست از body.text بگيرم ؟
الان body.text چی برمیگردونه؟ قاعداتا باید کد HTML را برگردونه. به شما چیز دیگه ایی میده؟
Kamyar.Kimiyabeigi
یک شنبه 21 مهر 1387, 13:43 عصر
خيلي ممنون متن body رو از داخل html دراوردم و براي متنهايي كه فارسي داره هم از TIdDecoderQuotedPrintable استفاده كردم و درست شد.
بازم ممنون
m.yazdian
یک شنبه 12 آبان 1387, 08:37 صبح
سلام دوست عزیز
در پست های بالا دیدم که شمااطلاعات جامعی در زمینه scket و کارکردن با اون دارین.
من یه مشکلی دارم تو پروژه ام که البته این پروژه با vb.net نوشته شده نه delphi اونم اینه که من وقتی به سرور pop3 وصل میشو و بعد از ارسال نام کاربری و کلمه عبور و فرمان RERE 1 سرور در ج.اب متن نامه من را برای من برمب گرداند . (ولی مشکل اینجاست که من نمی دونم بخش های Body , Attachment , Subject , From , Date را چجوری می تونم خارج کنم ؟؟؟؟) همه این اطلاعات بصورت یه stream در یک خط از سرور دریافت میشه واگر من بخوام اونو نمایش بدم کلی اطلاعات دیگه هم باهاش نمایش داده میشه .
اگر ممکنه نحوه Parse کردن این stream رو برای من توضیح بدین.
من تو codeproject مقاله های زیادی دیدم فکر میکنم که با توجه به Mime Type ها باید این کار رو کرد ولی من موفق به انجام این کار نشدم.
ممنون میشم اگر کمکی کنید .
Public
Class GMail
Dim TCP As Net.Sockets.TcpClient
Dim POP3Stream As System.IO.Stream
Dim inStream As System.IO.StreamReader
Dim strDataIn, strNumMains(2) AsString
Dim intNoEmails AsInteger
PublicFunction Connection(ByVal strServer AsString, ByVal strUserName AsString, ByVal strPassword AsString) AsString
'connect to the pop3 server over port 110
Try
TCP =
New Net.Sockets.TcpClient
TCP.Connect(strServer, 110)
'create stream into the ip
POP3Stream = TCP.GetStream
inStream = New System.IO.StreamReader(POP3Stream)
'Make sure we get the ok back from the server
If WaitFor("+OK") Then SendData("USER " & strUserName)
'send the email down
If WaitFor("+OK") Then SendData("PASS " & strPassword)
WaitFor("+OK")
Catch ex As Exception
Return ex.Message
ExitFunction
EndTry
EndFunction
Function GetMailStat() AsInteger
'send the stat command and make sure it returns as expected
Try
SendData(
"STAT")
If WaitFor("+OK") = FalseThen
GetMailStat =
"0"
ExitFunction
Else
'split up the response. It should be +OK Num of emails size of emails
strNumMains = Split(strDataIn,
" ")
GetMailStat = strNumMains(1)
intNoEmails = strNumMains(1)
EndIf
Catch ex As Exception
GetMailStat = 0
intNoEmails = 0
EndTry
EndFunction
PublicFunction SendData(ByVal strCommand AsString)
Dim outBuff AsByte()
outBuff = ConvertStringToByteArray(strCommand & vbCrLf)
POP3Stream.Write(outBuff, 0, strCommand.Length + 2)
EndFunction
PublicFunction WaitFor(ByVal strTarget AsString) AsBoolean
strDataIn = inStream.ReadLine
If InStr(strDataIn, strTarget) Then
WaitFor =
True
Else
WaitFor =
False
EndIf
EndFunction
PublicSharedFunction ConvertStringToByteArray(ByVal stringToConvert AsString) AsByte()
Return (New System.Text.ASCIIEncoding).GetBytes(stringToConver t)
EndFunction
PublicFunction GetMailMessage(ByVal intNum AsInteger) AsString
Dim strTemp AsString
Dim strEmailMess AsString = ""
Try
'send the command to the server to return that email back. Command is RETR and the email no ie RETR 1
SendData(
"RETR " & Str(intNum))
'make sure we get a proper response back
If WaitFor("+OK") = FalseThen
GetMailMessage = (
"No Email was Retrived")
ExitFunction
EndIf
'Should be ok at this point to read in the tcp stream. We read it in until the end of the email
'whitch is signified by a line containing only a fullpoint(chr46)
strTemp = inStream.ReadLine
While (strTemp <> ".")
strEmailMess = strEmailMess & strTemp & vbCrLf
strTemp = inStream.ReadLine
EndWhile
GetMailMessage = strEmailMess
Catch ex As Exception
'just return an error message if we fell over
GetMailMessage =
"No Email was Retrived"
EndTry
EndFunction
PublicFunction ParseHeader(ByVal strHeader AsString, ByVal strType AsString) AsString
Dim intLenToStart AsInteger
Dim intLenToLineEnd AsInteger
Dim strTmp AsString
intLenToStart = (InStr(strHeader, strType) - 1)
intLenToLineEnd = InStr(Mid(strHeader, intLenToStart), vbCrLf)
strTmp = strHeader.Substring(intLenToStart, intLenToLineEnd)
ParseHeader = strTmp
EndFunction
PublicFunction ParseAttachment(ByVal strBody AsString) AsString
Dim str, sTemp AsString
Dim intStart, intEnd AsInteger
Dim Buffer(1024) AsByte
If InStr(strBody, "Content-Disposition: attachment;") <> 0 Then
intStart = (InStr(strBody,
"Content-Disposition: attachment;") + 51)
intEnd = InStr(strBody, vbCrLf & "0")
str = strBody.Substring(intStart, intEnd)
str = Replace(str, vbCrLf, "")
EndIf
Return str
EndFunction
PublicFunction ParseBody(ByVal strBody AsString) AsString
Dim str AsString
Dim intLenStart, intLenEnd AsInteger
Dim Buffer(1024) AsByte
Try
If InStr(strBody, "Content-Transfer-Encoding: base64") = 0 Then
intLenStart = (InStr(strBody,
"Content-Type: text/html") + 100)
intLenEnd = InStr(Mid(strBody, intLenStart), vbCrLf & "------=_Part")
str = strBody.Substring(intLenStart, intLenEnd)
Else
intLenStart = (InStr(strBody,
"Content-Type: text/html") + 102)
intLenEnd = InStr(Mid(strBody, intLenStart), vbCrLf & "------=_Part")
str = strBody.Substring(intLenStart, intLenEnd)
Buffer = Convert.FromBase64String(str)
str = Encoding.UTF8.GetString(Buffer)
EndIf
Catch ex As Exception
str = "Cannot read the message"
EndTry
Return str
EndFunction
PublicSub Quit()
Dim message AsString
message =
"Quit" + vbCrLf
SendData(message)
TCP.Close()
EndSub
EndClass
Kamyar.Kimiyabeigi
یک شنبه 12 آبان 1387, 11:11 صبح
راستش تو دلفي براحتي subject & date & from & to & ... قابل دسترسي هست ولي تو vb نميدونم به چه صورت هست من تو دلفي از TIdMessage استفاده كردم.
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.