// NAnt - A .NET build tool
// Copyright (C) 2001-2003 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 (jayturpin@hotmail.com)
// Gerry Shaw (gerry_shaw@yahoo.com)
// Gert Driesen (gert.driesen@ardatis.com)
using System;
using System.Globalization;
using System.IO;
using System.Text;
using System.Web.Mail;
using NAnt.Core;
using NAnt.Core.Attributes;
using NAnt.Core.Types;
using NAnt.Core.Util;
namespace NAnt.Core.Tasks {
///
/// Sends an SMTP message.
///
///
///
/// Text and text files to include in the message body may be specified as
/// well as binary attachments.
///
///
///
///
/// Sends an email from nant@sourceforge.net to three recipients
/// with a subject about the attachments. The body of the message will be
/// the combined contents of all .txt files in the base directory.
/// All zip files in the base directory will be included as attachments.
/// The message will be sent using the smtpserver.anywhere.com SMTP
/// server.
///
///
///
///
///
///
///
///
///
///
/// ]]>
///
///
[TaskName("mail")]
public class MailTask : Task {
#region Private Instance Fields
private string _from = null;
private string _toList = null;
private string _ccList = null;
private string _bccList = null;
private string _mailHost = "localhost";
private string _subject = "";
private string _message = "";
private FileSet _files = new FileSet();
private FileSet _attachments = new FileSet();
private MailFormat _mailFormat = MailFormat.Text;
#endregion Private Instance Fields
#region Public Instance Properties
///
/// Email address of sender.
///
[TaskAttribute("from", Required=true)]
[StringValidator(AllowEmpty=false)]
public string From {
get { return _from; }
set { _from = StringUtils.ConvertEmptyToNull(value); }
}
///
/// Semicolon-separated list of recipient email addresses.
///
[TaskAttribute("tolist")]
public string ToList {
get { return _toList; }
set { _toList = value; }
}
///
/// Semicolon-separated list of CC: recipient email addresses.
///
[TaskAttribute("cclist")]
public string CcList {
get { return _ccList; }
set { _ccList = value; }
}
///
/// Semicolon-separated list of BCC: recipient email addresses.
///
[TaskAttribute("bcclist")]
public string BccList {
get { return _bccList; }
set { _bccList = value; }
}
///
/// Host name of mail server. The default is localhost.
///
[TaskAttribute("mailhost")]
public string Mailhost {
get { return _mailHost; }
set { _mailHost = StringUtils.ConvertEmptyToNull(value); }
}
///
/// Text to send in body of email message.
///
[TaskAttribute("message")]
public string Message {
get { return _message; }
set { _message = StringUtils.ConvertEmptyToNull(value); }
}
///
/// Text to send in subject line of email message.
///
[TaskAttribute("subject")]
public string Subject {
get { return _subject; }
set { _subject = StringUtils.ConvertEmptyToNull(value); }
}
///
/// Format of the message. The default is .
///
[TaskAttribute("format")]
public MailFormat Format {
get { return _mailFormat; }
set {
if (!Enum.IsDefined(typeof(MailFormat), value)) {
throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "An invalid format {0} was specified.", value));
} else {
this._mailFormat = value;
}
}
}
///
/// Files that are transmitted as part of the body of the email message.
///
[BuildElement("files")]
public FileSet Files {
get { return _files; }
set { _files = value; }
}
///
/// Attachments that are transmitted with the message.
///
[BuildElement("attachments")]
public FileSet Attachments {
get { return _attachments; }
set { _attachments = value; }
}
#endregion Public Instance Properties
#region Override implementation of Task
///
/// Initializes task and ensures the supplied attributes are valid.
///
/// Xml node used to define this task instance.
protected override void InitializeTask(System.Xml.XmlNode taskNode) {
if (StringUtils.IsNullOrEmpty(ToList) && StringUtils.IsNullOrEmpty(CcList) && StringUtils.IsNullOrEmpty(BccList)) {
throw new BuildException("There must be at least one name in"
+ " the \"tolist\", \"cclist\" or \"bcclist\" attributes"
+ " of the task.", Location);
}
}
///
/// This is where the work is done.
///
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;
// ensure base directory is set, even if fileset was not initialized
// from XML
if (Files.BaseDirectory == null) {
Files.BaseDirectory = new DirectoryInfo(Project.BaseDirectory);
}
if (Attachments.BaseDirectory == null) {
Attachments.BaseDirectory = new DirectoryInfo(Project.BaseDirectory);
}
// begin build message body
StringWriter bodyWriter = new StringWriter(CultureInfo.InvariantCulture);
if (!StringUtils.IsNullOrEmpty(Message)) {
bodyWriter.WriteLine(Message);
bodyWriter.WriteLine();
}
// append file(s) to message body
foreach (string fileName in Files.FileNames) {
try {
string content = ReadFile(fileName);
if (!StringUtils.IsNullOrEmpty(content)) {
bodyWriter.Write(content);
bodyWriter.WriteLine(string.Empty);
}
} catch (Exception ex) {
Log(Level.Warning, string.Format(CultureInfo.InvariantCulture,
ResourceUtils.GetString("NA1135"), fileName,
ex.Message));
}
}
// add message body to mailMessage
string bodyText = bodyWriter.ToString();
if (bodyText.Length != 0) {
mailMessage.Body = bodyText;
}
// add attachments to message
foreach (string fileName in Attachments.FileNames) {
try {
MailAttachment attachment = new MailAttachment(fileName);
mailMessage.Attachments.Add(attachment);
} catch (Exception ex) {
Log(Level.Warning, string.Format(CultureInfo.InvariantCulture,
ResourceUtils.GetString("NA1136"), fileName,
ex.Message));
}
}
// send message
try {
Log(Level.Info, "Sending mail to {0}.", mailMessage.To);
SmtpMail.SmtpServer = this.Mailhost;
SmtpMail.Send(mailMessage);
} catch (Exception ex) {
StringBuilder msg = new StringBuilder();
msg.Append("Error enountered while sending mail message."
+ Environment.NewLine);
msg.Append("Make sure that mailhost=" + this.Mailhost
+ " is valid" + Environment.NewLine);
throw new BuildException("Error sending mail:" + Environment.NewLine
+ msg.ToString(), Location, ex);
}
}
#endregion Override implementation of Task
#region Private Instance Methods
///
/// Reads a text file and returns the content
/// in a string.
///
/// The file to read content of.
///
/// The content of the specified file.
///
private string ReadFile(string filename) {
using (StreamReader reader = new StreamReader(File.OpenRead(filename))) {
return reader.ReadToEnd();
}
}
#endregion Private Instance Methods
}
}