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