---------- Původní zpráva ----------
Od: petr.fej...@seznam.cz <petr.fej...@seznam.cz>
Komu: synalist-public@lists.sourceforge.net
Datum: 4. 1. 2017 18:24:52
Předmět: Re: [Synalist] HOW to save the BODY part of a downloaded email
"Dne 04.01.2017 v 17:25 Stefan Kruger napsal(a):
> I can walk through the lines, no problem, but how do I know where the
> actual message starts and end?
You should walk through PARTS, not lines ! Synapse has for that purpose
event OnWalkPart a method WalkPart(), so obvious solution is to write
OnWalkPart handler and start walk e.g.
Mime := TMimeMess.Create;
try
Mime.DecodeMessage(AHeader,ABody);
Mime.MessagePart.OnWalkPart := self._HandleWalkBinaryParts;
Mime.MessagePart.WalkPart; // Parse parts
finally
Mime.Free;
end;
To write the event handler, you definitely need understand what
MIME is: generally, lines may contain complex tree of parts.
Have you read at least
http://synapse.ararat.cz/doku.php/public:howto:mimeparts for
introduction? As Roy said, you should
learn MIME format from RFC (for emails 1521, 1522)
An example of such event handler may look like this:
procedure TSMILDocument._HandleWalkBinaryParts
(const APart:TMimePart);
var
iPart: ISmilPartItem;
begin
if not Assigned(APart) then
exit;
TraceFmt('?? MIME Walk: Level=%d Primary=%s, Secondary=%s Boundary=%s
Size=%d',
[APart.SubLevel,APart.Primary,APart.Secondary,APart.Boundary,APart.
DecodedLines.Size]);
// Mandatory text part should be TEXT/XML part containing MM7 protocol
if (FMM7Level<0) and (APart.SubLevel=1) and
SameText(APart.Primary,'text') and SameText(APart.Secondary,'xml') then
begin
APart.DecodePart;
self.FMM7.LoadFromStream(APart.DecodedLines);
FMM7Level := Apart.SubLevel;
Trace(' = MIME Walk: The first TEXT/XML part representing MM7
protocol found at level');
end
// The end of MULTIPART/RELATED container has been reached already -
SMIL and related media should be collected
else if FMulRelEnd then
begin
end
// Enter hunt mode: looking for parent MULTIPART/RELATED containter
else if (APart.SubLevel=FMM7Level) and (FMulRelLevel<0) then
begin
if SameText(APart.Primary,'multipart') and
SameText(APart.Secondary,'related') then
begin
FMulRelLevel := APart.SubLevel;
TraceFmt(' = MIME Walk: MULTIPART/RELATED containter found at
level %d',[FMulRelLevel]);
end
else
begin
Trace(' ? MIME Walk: Still Looking for MULTIPART/RELATED
containter...');
end;
end
// The end of MULTIPART/RELATED is just reached
else if APart.SubLevel<=FMulRelLevel then
begin
FMulRelEnd := TRUE;
TraceFmt(' = MIME Walk: The end of MULTIPART/RELATED containter
has been reached at level %d',[APart.SubLevel]);
end
else if (FMulRelLevel>=0) and (APart.SubLevel=(FMulRelLevel+1)) then
begin
// This part contains SMIL document
if SameText(APart.Primary,'application') and
SameText(APart.Secondary,'smil') then
begin
TraceFmt(' = MIME Walk: SMIL part has been found at level
%d',[APart.SubLevel]);
FSmilFound := TRUE;
self.FLines.Assign(APart.PartBody);
self.ParseXML(nil);
self._ListReferredParts(self.FContent,FMulRelMedia);
end
// Collect SMIL related MEDIA in
else if SameText(APart.Primary,'text') and
SameText(APart.Secondary,'plain') then
begin
TraceFmt(' ? MIME Walk: Plain Text at level %d.
ContentType=%s/%s',[APart.SubLevel,APart.Primary,APart.Secondary]);
APart.TargetCharset := UCS_2LE;
APart.ConvertCharset := TRUE;
APart.DecodePart;
iPart := TSmilPartItem.Create;
iPart.AssignId(APart);
iPart.ContentType :=
Format('%s/%s',[APart.Primary,APart.Secondary]);
iPart.Charset := 'UTF-8';
iPart.SetContentSkipBOM(APart.DecodedLines);
self.FParts.Add(iPart);
end
else if SameText(APart.Primary,'image') then
begin
TraceFmt(' ? MIME Walk: Image at level %d.
ContentType=%s/%s',[APart.SubLevel,APart.Primary,APart.Secondary]);
iPart := TSmilPartItem.Create;
iPart.AssignId(APart);
iPart.ContentType :=
Format('%s/%s',[APart.Primary,APart.Secondary]);
APart.DecodePart;
iPart.SetContent(APart.DecodedLines);
self.FParts.Add(iPart);
end
else if SameText(APart.Primary,'audio') then
begin
TraceFmt(' ? MIME Walk: Audio at level %d.
ContentType=%s/%s',[APart.SubLevel,APart.Primary,APart.Secondary]);
iPart := TSmilPartItem.Create;
iPart.AssignId(APart);
iPart.ContentType :=
Format('%s/%s',[APart.Primary,APart.Secondary]);
APart.DecodePart;
iPart.SetContent(APart.DecodedLines);
self.FParts.Add(iPart);
end
else if SameText(APart.Primary,'video') then
begin
TraceFmt(' ? MIME Walk: Video at level %d.
ContentType=%s/%s',[APart.SubLevel,APart.Primary,APart.Secondary]);
iPart := TSmilPartItem.Create;
iPart.AssignId(APart);
iPart.ContentType :=
Format('%s/%s',[APart.Primary,APart.Secondary]);
APart.DecodePart;
iPart.SetContent(APart.DecodedLines);
self.FParts.Add(iPart);
end
else if SameText(APart.Primary,'Application') and
SameText(APart.Secondary,'octet-stream') then
begin
TraceFmt(' ? MIME Walk: Application/octet-stream at level %d.
FileName=%s',[APart.SubLevel,APart.FileName]);
TraceFmt(' ! MIME Walk: APPLICATION/OCTET-STREAM part -
unsupported kind of related media at level %d. Filename
"%s"',[APart.SubLevel,APart.FileName]);
end
else
begin
{~}{SPY}TraceFmt(' ? MIME Walk: Unsupported kind of related
media at level %d.
ContentType=%s/%s',[APart.SubLevel,APart.Primary,APart.Secondary]);
end;
end
// Ignore other parts
else
begin
if FMM7Level<0 then
TraceFmt(' ? MIME Walk: Enter-hunt mode: TEXT/XML part with MM7
protocol has not been found yet - ignoring part at level %d.
ContentType=%s/%s',[APart.SubLevel,APart.Primary,APart.Secondary])
else if FMulRelLevel<0 then
TraceFmt(' ? MIME Walk: Enter-hunt mode: MULTIPART/RELATED with
SMIL message has not been found yet - ignoring part at level %d.
ContentType=%s/%s',[APart.SubLevel,APart.Primary,APart.Secondary])
else
TraceFmt(' ? MIME Walk: Unexpected/unsupported part - ignoring
part at level %d.
ContentType=%s/%s',[APart.SubLevel,APart.Primary,APart.Secondary]);
end;
end;
HTH, pf
----------------------------------------------------------------------------
--
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
synalist-public mailing list
synalist-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/synalist-public
"
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
synalist-public mailing list
synalist-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/synalist-public