tmp/test-doxy-mms/MarekMailSystem/MarekMailSystem2/Email.cs

Go to the documentation of this file.
00001 using System;
00002 using System.Collections.Generic;
00003 using System.Collections.ObjectModel;
00004 using System.Text;
00005 using System.Net.Mail;
00006 using System.Text.RegularExpressions;
00007 
00008 
00009 namespace MarekMailSystem2
00010 {
00011     // TODO: zrobic jakos gwarancje zamykania zalacznikow na czas.
00012     // chyba tak: kazac uzytkownikowi robic Email.Dispose jesli juz
00013     // nie zamieza kolejny raz (narazie) wysylac tego emaila.
00014     // a my musimy DOKLADNIE przemyslec jak zaimplementowac Email.Dispose!
00015     // (aha i przeczytac jeszcze raz wogole o tym mechanizmie Disposable)
00016 
00017     // TODO: wazna rzecz do sprawdzenia: w msdnie pisza sprzeczne rzeczy o
00018     // konstruowaniu zalacznikow i alternateviewsow: raz w new Attachment(napis)
00019     // napis oznacza nazwe pliku, a raz zawartosc zalacznika.
00020     // tak jest np tu: http://msdn2.microsoft.com/en-us/library/56wesadc.aspx
00021     // (w syntax mamy string fileName, ale w examplu juz mamy zwykly text)
00022     // AA jednak nie bo w examplu recznie przestawiaja content type na text plain...
00023     // Zatem: czeka minie czytanie o tych content i media typach.. (rfc...)
00024 
00034     public class Email
00035     {
00036         public Email()
00037         {
00038         }
00039         public Email(string from, string to, string subject, string body)
00040             : this()
00041         {
00042             From = from;
00043             To = to;
00044             Subject = subject;
00045             Body = body;
00046         }
00047 
00052         public Email(string to, string subject, string body)
00053             : this()
00054         {
00055             To = to;
00056             Subject = subject;
00057             Body = body;
00058         }
00059 
00060         private DateTime sendingTime;
00061 
00066         public DateTime SendingTime
00067         {
00068             get { return sendingTime; }
00069             internal set { sendingTime = value; }
00070         }
00071 
00072         private EmailStatus sendingStatus = new EmailStatus();
00073 
00077         public EmailStatus SendingStatus
00078         {
00079             get { return sendingStatus; }
00080             internal set { sendingStatus = value; }
00081         }
00082 
00083 
00084         private string from;
00088         public string From
00089         {
00090             get { return from; }
00091             set { from = value; }
00092         }
00093 
00094 
00095         private string to;
00096 
00100         public string To
00101         {
00102             get { return to; }
00103             set { to = value; }
00104         }
00105 
00106 
00107         private string cc;
00108 
00112         public string Cc
00113         {
00114             get { return cc; }
00115             set { cc = value; }
00116         }
00117 
00118         private string bcc;
00119 
00123         public string Bcc
00124         {
00125             get { return bcc; }
00126             set { bcc = value; }
00127         }
00128 
00129         private string replyTo;
00130 
00134         public string ReplyTo
00135         {
00136             get { return replyTo; }
00137             set { replyTo = value; }
00138         }
00139 
00140 
00141         private string sender;
00142 
00146         public string Sender
00147         {
00148             get { return sender; }
00149             set { sender = value; }
00150         }
00151 
00152         private List<string> fileAttachments = new List<string>();
00153         public List<string> FileAttachments
00154         {
00155             get { return fileAttachments; }
00156         }       
00157         // TODO: osobna lista zalacznikow w strumieniach/tablicach bajtow...
00158 
00159 
00160         private string subject = "";
00161 
00165         public string Subject
00166         {
00167             get { return subject; }
00168             set { subject = value; }
00169         }
00170 
00171 
00172         private string body = "";
00173 
00177         public string Body
00178         {
00179             get { return body; }
00180             set { body = value; }
00181         }
00182 
00183 
00184         private bool isBodyHtml;
00185 
00189         public bool IsBodyHtml
00190         {
00191             get { return isBodyHtml; }
00192             set { isBodyHtml = value; }
00193         }
00194 
00195         private bool altView = true;
00196 
00202         public bool AltView
00203         {
00204             get { return altView; }
00205             set { altView = value; }
00206         }
00207 
00208 
00209         private MailPriority priority = MailPriority.Normal;
00210 
00214         public MailPriority Priority
00215         {
00216             get { return priority; }
00217             set { priority = value; }
00218         }
00219         
00220         private static TemplateEngine engine = new TemplateEngine(true);
00221 
00227         public void ProcessTemplate(Dictionary<string, string> context)
00228         {
00229             From = engine.Process(context,From);
00230             To = engine.Process(context, To);
00231             Cc = engine.Process(context, Cc);
00232             Bcc = engine.Process(context, Bcc);
00233             ReplyTo = engine.Process(context, ReplyTo);
00234             Sender = engine.Process(context, Sender);
00235             Subject = engine.Process(context, Subject);
00236             Body = engine.Process(context, Body);
00237         }
00238 
00239 
00240 
00241         public override string ToString()
00242         {
00243             string fileattlist = "";
00244             foreach (string att in FileAttachments)
00245                 fileattlist += "    " + att + "\n";
00246             return
00247                 "MarekMailSystem2.Email {" +
00248                 "\n  SendingTime      : " + SendingTime.ToString() +
00249                 "\n  SendingStatus    : " + SendingStatus.ToString() +
00250                 "\n  From             : " + From +
00251                 "\n  To               : " + From +
00252                 "\n  Cc               : " + Cc +
00253                 "\n  Bcc              : " + Bcc +
00254                 "\n  ReplyTo          : " + ReplyTo +
00255                 "\n  Sender           : " + Sender +
00256                 "\n  Subject          : " + Subject +
00257                 "\n  Body {\n" + Body +
00258                 "\n  }" +
00259                 "\n  FileAttachments {\n" + fileattlist +
00260                 "  }" +
00261                 "\n  IsBodyHtml       : " + IsBodyHtml.ToString() +
00262                 "\n  AltView          : " + AltView.ToString() +
00263                 "\n  Priority         : " + Priority.ToString() +
00264                 "\n}";
00265         }
00266 
00267 
00268         internal MailMessage ConstructMailMessage()
00269         {
00270             MailMessage message = new MailMessage();
00271 
00272             if (From != null && From != "") message.From = new MailAddress(From);
00273             cnvStringToMailAddressCollection(To, message.To);
00274             cnvStringToMailAddressCollection(Cc, message.CC);
00275             cnvStringToMailAddressCollection(Bcc, message.Bcc);
00276             if (ReplyTo != null && ReplyTo != "") message.ReplyTo = new MailAddress(ReplyTo);
00277             if (Sender != null && Sender != "") message.Sender = new MailAddress(Sender);
00278             foreach (string att in FileAttachments)
00279                 message.Attachments.Add(new Attachment(att));
00280             message.Subject = Subject;
00281             if (!AltView)
00282             {
00283                 message.Body = Body;
00284                 message.IsBodyHtml = IsBodyHtml;
00285             }
00286             else
00287             {
00288                 string text; string html;
00289                 if (IsBodyHtml)
00290                 {
00291                     html = Body;
00292                     text = GetTextFromHtml(html);
00293                 }
00294                 else
00295                 {
00296                     text = Body;
00297                     html = GetHtmlFromText(text);
00298                 }
00299                 message.Body = text;
00300                 message.AlternateViews.Clear();
00301                 message.AlternateViews.Add(AlternateView.CreateAlternateViewFromString(
00302                     html, Encoding.UTF8, "text/html"));
00303             }
00304             message.Priority = Priority;
00305             return message;
00306         }
00307 
00308         // We assume here that mailcollection can have max 1 element.
00309         private void cnvStringToMailAddressCollection(string s, MailAddressCollection c)
00310         {
00311             if (s == null || s == "") c.Clear();
00312             else
00313                 if (c.Count == 0) c.Add(new MailAddress(s));
00314                 else c[0] = new MailAddress(s);
00315         }
00316 
00317         static public string GetHtmlFromText(string text)
00318         {
00319             return
00320                 "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n" +
00321                 "<html>\n" +
00322                 "<head>\n" +
00323                 "  <meta content=\"text/html;charset=UTF-8\" http-equiv=\"Content-Type\">\n" +
00324                 "</head>\n" +
00325                 "<body>\n" +
00326                 "<pre>\n" +
00327                 text + "\n" +
00328                 "</pre>\n" +
00329                 "</body>\n" +
00330                 "</html>\n";
00331         }
00332 
00333         static public string GetTextFromHtml(string html)
00334         {
00335             // Replace line breaks with space
00336             string result = html.Replace("\r", " ");
00337             result = result.Replace("\n", " ");
00338 
00339             // Remove step-formatting
00340             result = result.Replace("\t", string.Empty);
00341 
00342             // Remove repeating speces becuase browsers ignore them
00343             result = Regex.Replace(result,@"( )+", " ");
00344 
00345             // Remove the header (prepare first by clearing attributes)
00346             result = Regex.Replace(result, @"<( )*head([^>])*>", "<head>", RegexOptions.IgnoreCase);
00347             result = Regex.Replace(result, @"(<( )*(/)( )*head( )*>)", "</head>", RegexOptions.IgnoreCase);
00348             result = Regex.Replace(result, @"(<head>).*?(</head>)", string.Empty, RegexOptions.IgnoreCase);
00349 
00350             // remove all scripts (prepare first by clearing attributes)
00351             result = Regex.Replace(result,@"<( )*script([^>])*>", "<script>",RegexOptions.IgnoreCase);
00352             result = Regex.Replace(result,@"(<( )*(/)( )*script( )*>)", "</script>", RegexOptions.IgnoreCase);
00353             result = Regex.Replace(result, @"(<script>).*?(</script>)", string.Empty, RegexOptions.IgnoreCase);
00354 
00355             // remove all styles (prepare first by clearing attributes)
00356             result = Regex.Replace(result, @"<( )*style([^>])*>", "<style>", RegexOptions.IgnoreCase);
00357             result = Regex.Replace(result, @"(<( )*(/)( )*style( )*>)", "</style>", RegexOptions.IgnoreCase);
00358             result = Regex.Replace(result, @"(<style>).*?(</style>)", string.Empty,  RegexOptions.IgnoreCase);
00359 
00360             // insert tabs in spaces of <td> tags
00361             result = Regex.Replace(result, @"<( )*td([^>])*>", "\t", RegexOptions.IgnoreCase);
00362 
00363             // insert line breaks in places of <BR> and <LI> tags
00364             result = Regex.Replace(result, @"<( )*br( )*>", "\n", RegexOptions.IgnoreCase);
00365             result = Regex.Replace(result, @"<( )*li( )*>", "\n", RegexOptions.IgnoreCase);
00366 
00367             // insert line paragraphs (double line breaks) in place
00368             // if <P>, <DIV> and <TR> tags
00369             result = Regex.Replace(result, @"<( )*div([^>])*>", "\r\r", RegexOptions.IgnoreCase);
00370             result = Regex.Replace(result, @"<( )*tr([^>])*>", "\r\r", RegexOptions.IgnoreCase);
00371             result = Regex.Replace(result, @"<( )*p([^>])*>", "\r\r", RegexOptions.IgnoreCase);
00372 
00373             // Remove remaining tags like <a>, links, images,
00374             // comments etc - anything thats enclosed inside < >
00375             result = Regex.Replace(result, @"<[^>]*>", string.Empty, RegexOptions.IgnoreCase);
00376 
00377             // replace special characters:
00378             result = Regex.Replace(result, @"&nbsp;", " ", RegexOptions.IgnoreCase);
00379             result = Regex.Replace(result, @"&bull;", " * ", RegexOptions.IgnoreCase);
00380             result = Regex.Replace(result, @"&lsaquo;", "<", RegexOptions.IgnoreCase);
00381             result = Regex.Replace(result, @"&rsaquo;", ">", RegexOptions.IgnoreCase);
00382             result = Regex.Replace(result, @"&trade;", "(tm)", RegexOptions.IgnoreCase);
00383             result = Regex.Replace(result, @"&frasl;", "/",  RegexOptions.IgnoreCase);
00384             result = Regex.Replace(result, @"&lt;", "<", RegexOptions.IgnoreCase);
00385             result = Regex.Replace(result, @"&gt;", ">", RegexOptions.IgnoreCase);
00386             result = Regex.Replace(result, @"&copy;", "(c)", RegexOptions.IgnoreCase);
00387             result = Regex.Replace(result, @"&reg;", "(r)", RegexOptions.IgnoreCase);
00388             // Remove all others. More can be added, see
00389             // http://hotwired.lycos.com/webmonkey/reference/special_characters/
00390             result = Regex.Replace(result, @"&(.{2,6});", string.Empty, RegexOptions.IgnoreCase);
00391 
00392             // make line breaking consistent
00393             result = result.Replace("\r", "\n");
00394 
00395             // Remove extra line breaks and tabs:
00396             // replace over 2 breaks with 2 and over 4 tabs with 4. 
00397             // Prepare first to remove any whitespaces inbetween
00398             // the escaped characters and remove redundant tabs inbetween linebreaks
00399             result = Regex.Replace(result, @"(\n)( )+(\n)", "\n\n", RegexOptions.IgnoreCase);
00400             result = Regex.Replace(result, @"(\t)( )+(\t)", "\t\t", RegexOptions.IgnoreCase);
00401             result = Regex.Replace(result, @"(\t)( )+(\n)", "\t\n", RegexOptions.IgnoreCase);
00402             result = Regex.Replace(result, @"(\n)( )+(\t)", "\n\t", RegexOptions.IgnoreCase);
00403             // Remove redundant tabs
00404             result = Regex.Replace(result, @"(\n)(\t)+(\n)", "\n\n", RegexOptions.IgnoreCase);
00405             // Remove multible tabs followind a linebreak with just one tab
00406             result = Regex.Replace(result, @"(\n)(\t)+", "\n\t", RegexOptions.IgnoreCase);
00407 
00408             result = Regex.Replace(result, @"(\n){3,}", "\n\n", RegexOptions.IgnoreCase);
00409             result = Regex.Replace(result, @"(\t){5,}", "\t\t\t\t", RegexOptions.IgnoreCase);
00410 
00411             return result;
00412         }
00413 
00414 
00415     }
00416 
00417 }

Generated on Thu Oct 25 11:32:52 2007 for Marek Mail System by  doxygen 1.5.3-20071008