Hi guys,

I did a few modifications to the standard MailTask in NAnt. At first, I
thought about building my own alternative version, but it was not really
worth it for my very simple needs: Send HTML email based on an HTML file on
disk.

With that in mind, I did two modifications to the MailTask:

1) Added a format attribute which can take the value "Html" or "Text", which
map directly to the BodyFormat member of the MailMessage class.

2) Modified the code that interprets the files property in such a way that
when you only reference a single file to add to the message body, no
filename gets prepended on the body. This makes it very nice to use for
dynamically generated message content. (as an aside, I don't think adding
the file's name to the message body is that useful, particularly since it
will add a relative filename probably meaningless to the receptor). I'm not
sure however if this suites other people, but it would be extremely easy to
add a simple attribute to control this (or add an alternative property).
Anyone has any problem with this?

Anyway, I've attached the modified file in case anyone is interested in
it...

--
Tomas Restrepo
[EMAIL PROTECTED]
// NAnt - A .NET build tool
// Copyright (C) 2001 Gerry Shaw
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// Jay Turpin ([EMAIL PROTECTED])
// Gerry Shaw ([EMAIL PROTECTED])

using System;
using System.Text;
using System.Web.Mail;
using System.IO;
using SourceForge.NAnt.Attributes;
using SourceForge.NAnt;

namespace SourceForge.NAnt.Tasks { 

        /// <summary>A task to send SMTP email.</summary>
    /// <remarks>
    /// Text and text files to include in the message body may be specified as well as 
binary attachments.
    /// </remarks>
    /// <example>
    ///   <para>Sends an email from [EMAIL PROTECTED] to three recipients with a 
subject about the attachments.  The body of the message will be the combined contents 
of body1.txt through body4.txt.  The body1.txt through body3.txt files will also be 
included as attachments.  The message will be sent using the smtpserver.anywhere.com 
SMTP server.</para>
    ///   <code><![CDATA[
    ///     <mail 
    ///       from="[EMAIL PROTECTED]" 
    ///       tolist="[EMAIL PROTECTED]" 
    ///       cclist="[EMAIL PROTECTED]" 
    ///       bcclist="[EMAIL PROTECTED]" 
    ///       subject="Msg 7: With attachments" 
    ///       files="body1.txt,body2.txt;body3.txt,body4.txt" 
    ///       attachments="body1.txt,body2.txt;,body3.txt" 
    ///       mailhost="smtpserver.anywhere.com"/>
    ///   ]]></code>
    /// </example>
    [TaskName("mail")]
    public class MailTask : Task
    {
        
        string _from = "";      
        string _toList = "";        
        string _ccList = "";        
        string _bccList = "";        
        string _mailHost = "localhost";
        string _subject = "";        
        string _message = "";        
        string _files = "";        
        string _attachments = "";
        MailFormat _format = MailFormat.Text;
  
        /// <summary>Email address of sender </summary>
        [TaskAttribute("from", Required=true)]
        public string From { get { return _from; } set { _from = value; } }
        
        /// <summary>Comma- or semicolon-separated list of recipient email 
addresses</summary>
        [TaskAttribute("tolist", Required=true)]
        public string ToList {
            // convert to semicolon delimited
            get { return _toList.Replace("," , ";"); }
            set { _toList = value.Replace("," , ";"); }
        }

        /// <summary>Comma- or semicolon-separated list of CC: recipient email 
addresses </summary>
        [TaskAttribute("cclist")]
        public string CcList { 
            // convert to semicolon delimited
            get { return _ccList.Replace("," , ";"); } 
            set { _ccList = value.Replace("," , ";"); }
        }

        /// <summary> Comma- or semicolon-separated list of BCC: recipient email 
addresses</summary>
        [TaskAttribute("bcclist")]
        public string BccList { 
            // convert to semicolon delimited
            get { return _bccList.Replace("," , ";"); } 
            set { _bccList = value.Replace("," , ";"); }
        }

        /// <summary>Host name of mail server. Defaults to "localhost"</summary>
        [TaskAttribute("mailhost")]
        public string Mailhost { get { return _mailHost; } set { _mailHost = value; } }
  
        /// <summary>Text to send in body of email message.</summary>
        [TaskAttribute("message")]
        public string Message { get { return _message; } set { _message = value; } }

        /// <summary>Text to send in subject line of email message.</summary>
        [TaskAttribute("subject")]
        public string Subject { get { return _subject; } set { _subject = value; } }

        /// <summary>Format of the message body.</summary>
        [TaskAttribute("format")]
        public string Format { 
           get { return _format.ToString(); } 
           set { _format = (MailFormat)Enum.Parse(typeof(MailFormat), value); } 
        }

       /// <summary>Name(s) of text files to send as part of body of the email 
message. 
        /// Multiple file names are comma- or semicolon-separated.
        /// </summary>
        [TaskAttribute("files")]
        public string Files { 
            // convert to semicolon delimited
            get { return _files.Replace("," , ";"); } 
            set { _files = value.Replace("," , ";"); }
        }

        /// <summary>Name(s) of files to send as attachments to email message.
        /// Multiple file names are comma- or semicolon-separated.
        /// </summary>
        [TaskAttribute("attachments")]
        public string Attachments { 
            // convert to semicolon delimited
            get { return _attachments.Replace("," , ";"); } 
            set { _attachments = value.Replace("," , ";"); }
        }

        ///<summary>Initializes task and ensures the supplied attributes are 
valid.</summary>
        ///<param name="taskNode">Xml node used to define this task instance.</param>
        protected override void InitializeTask(System.Xml.XmlNode taskNode) {

            if (From.Length == 0) {
                throw new BuildException("Mail attribute \"from\" is required.", 
Location);
            }

            if (ToList.Length == 0 && CcList.Length == 0 && BccList.Length == 0) {
                throw new BuildException("Mail must provide at least one of these 
attributes: \"tolist\", \"cclist\" or \"bcclist\".", Location);
            }

        }

        /// <summary>
        /// This is where the work is done
        /// </summary>
        protected override void ExecuteTask() {

            MailMessage mailMessage = new MailMessage();
            
            mailMessage.From = this.From;
            mailMessage.To = this.ToList;
            mailMessage.Bcc = this.BccList;
            mailMessage.Cc = this.CcList;
            mailMessage.Subject = this.Subject;
            mailMessage.BodyFormat = this._format;

            // Begin build message body
            StringWriter bodyWriter = new StringWriter();
            if (Message.Length > 0) {
                bodyWriter.WriteLine(Message);
                bodyWriter.WriteLine();
            }

            

            // Append file(s) to message body
            if (Files.Length > 0) {
                string[] fileList = Files.Split(new char[]{';'});
                string content;
                if ( fileList.Length == 1 ) {
                   content = ReadFile(fileList[0]);
                   if ( content != null )
                     bodyWriter.Write(content);
                } else {
                  foreach (string fileName in fileList) {
                     content = ReadFile(fileName);
                     if ( content != null ) {
                        bodyWriter.WriteLine(fileName);
                        bodyWriter.WriteLine(content);
                        bodyWriter.WriteLine("");
                     }
                  }
                }
            }

            // add message body to mailMessage
            string bodyText = bodyWriter.ToString();
            if (bodyText.Length != 0) {
                mailMessage.Body = bodyText;
            } else {
                throw new BuildException("Mail attribute \"file\" or \"message\" is 
required.");
            }

            // Append file(s) to message body
            if (Attachments.Length > 0) {
                string[] attachList = Attachments.Split(new char[]{';'});
                foreach (string fileName in attachList) {
                    try {
                        // MailAttachment likes fully-qualified file names, use 
FileInfo to get them
                        FileInfo fileInfo = new FileInfo(fileName);
                        MailAttachment attach = new MailAttachment(fileInfo.FullName);
                        mailMessage.Attachments.Add(attach);
                    } catch {
                        string msg = "WARNING! File \"" + fileName + "\" NOT attached 
to message. File does not exist or cannot be accessed. Check: " + Location.ToString() 
+ "attachments=\"" + Attachments + "\"";
                        Log.WriteLine(LogPrefix + msg);
                    }
                }
            }

            // send message
            try {
                SmtpMail.SmtpServer = this.Mailhost;
                SmtpMail.Send(mailMessage);
            } catch (Exception e) {
                StringBuilder msg = new StringBuilder();
                msg.Append(LogPrefix + "Error enountered while sending mail 
message.\n");
                msg.Append(LogPrefix + "Make sure that mailhost=" + this.Mailhost + " 
is valid\n");
                msg.Append(LogPrefix + "Internal Message: " + e.Message + "\n");
                msg.Append(LogPrefix + "Stack Trace:\n");
                msg.Append(e.ToString() + "\n");
                throw new BuildException("Error sending mail:\n " + msg.ToString());
            }
        }

       /// <summary>
       /// Reads a text file and returns the contents
       /// in a string
       /// </summary>
       /// <param name="filename"></param>
       /// <returns></returns>
       private string ReadFile(string filename)
       {
          StreamReader reader = null;
          try {
             reader = new StreamReader(File.OpenRead(filename));
             return reader.ReadToEnd();
          } catch {
             string msg = "WARNING! File \"" + filename + "\" NOT added to message 
body. File does not exist or is not readable. Check: " + Location.ToString() + 
"files=\"" + Files + "\"";
             Log.WriteLine(LogPrefix + msg);
             return null;
          } finally {
             if ( reader != null )
                reader.Close();
          }
       }

    }
}

Reply via email to