home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 December / Chip_2001-12_cd1.bin / zkuste / delphi / unity / d23456 / SYNAPSE.ZIP / source / lib / MIMEmess.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  2001-08-09  |  10.5 KB  |  375 lines

  1. {==============================================================================|
  2. | Project : Delphree - Synapse                                   | 001.005.000 |
  3. |==============================================================================|
  4. | Content: MIME message object                                                 |
  5. |==============================================================================|
  6. | The contents of this file are Subject to the Mozilla Public License Ver. 1.1 |
  7. | (the "License"); you may not use this file except in compliance with the     |
  8. | License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ |
  9. |                                                                              |
  10. | Software distributed under the License is distributed on an "AS IS" basis,   |
  11. | WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for |
  12. | the specific language governing rights and limitations under the License.    |
  13. |==============================================================================|
  14. | The Original Code is Synapse Delphi Library.                                 |
  15. |==============================================================================|
  16. | The Initial Developer of the Original Code is Lukas Gebauer (Czech Republic).|
  17. | Portions created by Lukas Gebauer are Copyright (c)2000,2001.                |
  18. | All Rights Reserved.                                                         |
  19. |==============================================================================|
  20. | Contributor(s):                                                              |
  21. |==============================================================================|
  22. | History: see HISTORY.HTM From distribution package                           |
  23. |          (Found at URL: http://www.ararat.cz/synapse/)                       |
  24. |==============================================================================}
  25.  
  26. {$WEAKPACKAGEUNIT ON}
  27.  
  28. unit MIMEmess;
  29.  
  30. interface
  31.  
  32. uses
  33.   Classes, SysUtils,
  34.   MIMEpart, SynaChar, SynaUtil, MIMEinLn;
  35.  
  36. type
  37.   TMessHeader = class(TObject)
  38.   private
  39.     FFrom: string;
  40.     FToList: TStringList;
  41.     FSubject: string;
  42.     FOrganization: string;
  43.     FCustomHeaders: TStringList;
  44.   public
  45.     constructor Create;
  46.     destructor Destroy; override;
  47.     procedure Clear;
  48.     procedure EncodeHeaders(Value: TStringList);
  49.     procedure DecodeHeaders(Value: TStringList);
  50.   published
  51.     property From: string read FFrom Write FFrom;
  52.     property ToList: TStringList read FToList;
  53.     property Subject: string read FSubject Write FSubject;
  54.     property Organization: string read FOrganization Write FOrganization;
  55.     property CustomHeaders: TStringList read FCustomHeaders;
  56.   end;
  57.  
  58.   TMimeMess = class(TObject)
  59.   private
  60.     FPartList: TList;
  61.     FLines: TStringList;
  62.     FHeader: TMessHeader;
  63.     FMultipartType: string;
  64.   public
  65.     constructor Create;
  66.     destructor Destroy; override;
  67.     procedure Clear;
  68.     function AddPart: Integer;
  69.     procedure AddPartText(Value: TStringList);
  70.     procedure AddPartHTML(Value: TStringList);
  71.     procedure AddPartHTMLBinary(Value, Cid: string);
  72.     procedure AddPartBinary(Value: string);
  73.     procedure EncodeMessage;
  74.     procedure FinalizeHeaders;
  75.     procedure ParseHeaders;
  76.     procedure DecodeMessage;
  77.   published
  78.     property PartList: TList read FPartList;
  79.     property Lines: TStringList read FLines;
  80.     property Header: TMessHeader read FHeader;
  81.     property MultipartType: string read FMultipartType Write FMultipartType;
  82.   end;
  83.  
  84. implementation
  85.  
  86. {==============================================================================}
  87.  
  88. constructor TMessHeader.Create;
  89. begin
  90.   inherited Create;
  91.   FToList := TStringList.Create;
  92.   FCustomHeaders := TStringList.Create;
  93. end;
  94.  
  95. destructor TMessHeader.Destroy;
  96. begin
  97.   FCustomHeaders.Free;
  98.   FToList.Free;
  99.   inherited Destroy;
  100. end;
  101.  
  102. {==============================================================================}
  103.  
  104. procedure TMessHeader.Clear;
  105. begin
  106.   FFrom := '';
  107.   FToList.Clear;
  108.   FSubject := '';
  109.   FOrganization := '';
  110.   FCustomHeaders.Clear;
  111. end;
  112.  
  113. procedure TMessHeader.EncodeHeaders(Value: TStringList);
  114. var
  115.   n: Integer;
  116. begin
  117.   for n := FCustomHeaders.Count - 1 downto 0 do
  118.     if FCustomHeaders[n] <> '' then
  119.       Value.Insert(0, FCustomHeaders[n]);
  120.   Value.Insert(0, 'x-mailer: Synapse - Delphi TCP/IP library by Lukas Gebauer');
  121.   Value.Insert(0, 'MIME-Version: 1.0 (produced by Synapse)');
  122.   Value.Insert(0, 'date: ' + Rfc822DateTime(Now));
  123.   if FOrganization <> '' then
  124.     Value.Insert(0, 'Organization: ' + InlineCode(FOrganization));
  125.   if FSubject <> '' then
  126.     Value.Insert(0, 'Subject: ' + InlineCode(FSubject));
  127.   for n := 0 to FToList.Count - 1 do
  128.     Value.Insert(0, 'To: ' + InlineEmail(FToList[n]));
  129.   Value.Insert(0, 'From: ' + InlineEmail(FFrom));
  130. end;
  131.  
  132. procedure TMessHeader.DecodeHeaders(Value: TStringList);
  133. var
  134.   s: string;
  135.   x: Integer;
  136.   cp: TMimeChar;
  137. begin
  138.   cp := GetCurCP;
  139.   Clear;
  140.   x := 0;
  141.   while Value.Count > x do
  142.   begin
  143.     s := NormalizeHeader(Value, x);
  144.     if s = '' then
  145.       Break;
  146.     if Pos('FROM:', UpperCase(s)) = 1 then
  147.     begin
  148.       FFrom := InlineDecode(SeparateRight(s, ':'), cp);
  149.       continue;
  150.     end;
  151.     if Pos('SUBJECT:', UpperCase(s)) = 1 then
  152.     begin
  153.       FSubject := InlineDecode(SeparateRight(s, ':'), cp);
  154.       continue;
  155.     end;
  156.     if Pos('ORGANIZATION:', UpperCase(s)) = 1 then
  157.     begin
  158.       FOrganization := InlineDecode(SeparateRight(s, ':'), cp);
  159.       continue;
  160.     end;
  161.     if Pos('TO:', UpperCase(s)) = 1 then
  162.     begin
  163.       FToList.Add(InlineDecode(SeparateRight(s, ':'), cp));
  164.       continue;
  165.     end;
  166.     FCustomHeaders.Add(s);
  167.   end;
  168. end;
  169.  
  170. {==============================================================================}
  171.  
  172. constructor TMimeMess.Create;
  173. begin
  174.   inherited Create;
  175.   FPartList := TList.Create;
  176.   FLines := TStringList.Create;
  177.   FHeader := TMessHeader.Create;
  178.   FMultipartType := 'Mixed';
  179. end;
  180.  
  181. destructor TMimeMess.Destroy;
  182. begin
  183.   FHeader.Free;
  184.   Lines.Free;
  185.   PartList.Free;
  186.   inherited Destroy;
  187. end;
  188.  
  189. {==============================================================================}
  190.  
  191. procedure TMimeMess.Clear;
  192. var
  193.   n: Integer;
  194. begin
  195.   FMultipartType := 'Mixed';
  196.   Lines.Clear;
  197.   for n := 0 to FPartList.Count - 1 do
  198.     TMimePart(FPartList[n]).Free;
  199.   FPartList.Clear;
  200.   FHeader.Clear;
  201. end;
  202.  
  203. {==============================================================================}
  204.  
  205. function TMimeMess.AddPart: Integer;
  206. begin
  207.   Result := FPartList.Add(TMimePart.Create);
  208. end;
  209.  
  210. {==============================================================================}
  211.  
  212. procedure TMimeMess.AddPartText(Value: TStringList);
  213. begin
  214.   with TMimePart(FPartList[AddPart]) do
  215.   begin
  216.     Value.SaveToStream(DecodedLines);
  217.     Primary := 'text';
  218.     Secondary := 'plain';
  219.     Description := 'Message text';
  220.     Disposition := 'inline';
  221.     CharsetCode := IdealCharsetCoding(Value.Text, TargetCharset,
  222.       [ISO_8859_1, ISO_8859_2, ISO_8859_3, ISO_8859_4, ISO_8859_5,
  223.       ISO_8859_6, ISO_8859_7, ISO_8859_8, ISO_8859_9, ISO_8859_10]);
  224.     EncodingCode := ME_QUOTED_PRINTABLE;
  225.     EncodePart;
  226.   end;
  227. end;
  228.  
  229. {==============================================================================}
  230.  
  231. procedure TMimeMess.AddPartHTML(Value: TStringList);
  232. begin
  233.   with TMimePart(FPartList[AddPart]) do
  234.   begin
  235.     Value.SaveToStream(DecodedLines);
  236.     Primary := 'text';
  237.     Secondary := 'html';
  238.     Description := 'HTML text';
  239.     Disposition := 'inline';
  240.     CharsetCode := UTF_8;
  241.     EncodingCode := ME_QUOTED_PRINTABLE;
  242.     EncodePart;
  243.   end;
  244. end;
  245.  
  246. {==============================================================================}
  247.  
  248. procedure TMimeMess.AddPartBinary(Value: string);
  249. var
  250.   s: string;
  251. begin
  252.   with TMimePart(FPartList[AddPart]) do
  253.   begin
  254.     DecodedLines.LoadFromFile(Value);
  255.     s := ExtractFileName(Value);
  256.     MimeTypeFromExt(s);
  257.     Description := 'Attached file: ' + s;
  258.     Disposition := 'attachment';
  259.     FileName := s;
  260.     EncodingCode := ME_BASE64;
  261.     EncodePart;
  262.   end;
  263. end;
  264.  
  265. procedure TMimeMess.AddPartHTMLBinary(Value, Cid: string);
  266. var
  267.   s: string;
  268. begin
  269.   with TMimePart(FPartList[AddPart]) do
  270.   begin
  271.     DecodedLines.LoadFromFile(Value);
  272.     s := ExtractFileName(Value);
  273.     MimeTypeFromExt(s);
  274.     Description := 'Included file: ' + s;
  275.     Disposition := 'inline';
  276.     ContentID := Cid;
  277.     FileName := s;
  278.     EncodingCode := ME_BASE64;
  279.     EncodePart;
  280.   end;
  281. end;
  282.  
  283. {==============================================================================}
  284.  
  285. procedure TMimeMess.EncodeMessage;
  286. var
  287.   bound: string;
  288.   n: Integer;
  289. begin
  290.   FLines.Clear;
  291.   if FPartList.Count = 1 then
  292.     FLines.Assign(TMimePart(FPartList[0]).Lines)
  293.   else
  294.   begin
  295.     bound := GenerateBoundary;
  296.     for n := 0 to FPartList.Count - 1 do
  297.     begin
  298.       FLines.Add('--' + bound);
  299.       FLines.AddStrings(TMimePart(FPartList[n]).Lines);
  300.     end;
  301.     FLines.Add('--' + bound + '--');
  302.     with TMimePart.Create do
  303.     try
  304.       Self.FLines.SaveToStream(DecodedLines);
  305.       Primary := 'Multipart';
  306.       Secondary := FMultipartType;
  307.       Description := 'Multipart message';
  308.       Boundary := bound;
  309.       EncodePart;
  310.       Self.FLines.Assign(Lines);
  311.     finally
  312.       Free;
  313.     end;
  314.   end;
  315. end;
  316.  
  317. {==============================================================================}
  318.  
  319. procedure TMimeMess.FinalizeHeaders;
  320. begin
  321.   FHeader.EncodeHeaders(FLines);
  322. end;
  323.  
  324. {==============================================================================}
  325.  
  326. procedure TMimeMess.ParseHeaders;
  327. begin
  328.   FHeader.DecodeHeaders(FLines);
  329. end;
  330.  
  331. {==============================================================================}
  332.  
  333. procedure TMimeMess.DecodeMessage;
  334. var
  335.   l: TStringList;
  336.   m: TMimePart;
  337.   i: Integer;
  338.   bound: string;
  339. begin
  340.   l := TStringList.Create;
  341.   m := TMimePart.Create;
  342.   try
  343.     l.Assign(FLines);
  344.     FHeader.Clear;
  345.     ParseHeaders;
  346.     m.ExtractPart(l, 0);
  347.     if m.PrimaryCode = MP_MULTIPART then
  348.     begin
  349.       bound := m.Boundary;
  350.       i := 0;
  351.       repeat
  352.         with TMimePart(PartList[AddPart]) do
  353.         begin
  354.           Boundary := bound;
  355.           i := ExtractPart(l, i);
  356.           DecodePart;
  357.         end;
  358.       until i >= l.Count - 2;
  359.     end
  360.     else
  361.     begin
  362.       with TMimePart(PartList[AddPart]) do
  363.       begin
  364.         ExtractPart(l, 0);
  365.         DecodePart;
  366.       end;
  367.     end;
  368.   finally
  369.     m.Free;
  370.     l.Free;
  371.   end;
  372. end;
  373.  
  374. end.
  375.