using System; using System.Configuration; using System.IO; using System.Linq; using System.Net; using System.Net.Mail; using LeafWeb.Core.DAL; using LeafWeb.Core.Entities; using LeafWeb.Core.Utility; using NLog; namespace LeafWeb.Web.Services { public class EmailNotificationService : IDisposable { private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); private readonly string _emailFromAddress; private const string EmailSuccessSubject = "LeafWeb Results"; private const string EmailErrorSubject = "LeafWeb processing error"; /// /// Comma separated values /// private readonly string _adminEmailAddresses; private readonly SmtpClient _smtpClient; private readonly DataService _dataService; private readonly DownloadUrlService _downloadUrlService; public EmailNotificationService(DataService dataService) { _dataService = dataService; _downloadUrlService = new DownloadUrlService(); _smtpClient = new SmtpClient( ConfigurationManager.AppSettings["SmtpHost"], Convert.ToInt32(ConfigurationManager.AppSettings["SmtpPort"])); if (!string.IsNullOrEmpty(ConfigurationManager.AppSettings["SmtpUserName"])) _smtpClient.Credentials = new NetworkCredential( ConfigurationManager.AppSettings["SmtpUserName"], ConfigurationManager.AppSettings["SmtpPassword"] ); _emailFromAddress = ConfigurationManager.AppSettings["EmailFromAddress"]; _adminEmailAddresses = ConfigurationManager.AppSettings["AdminEmailAddresses"]; } public EmailNotificationService() : this(new DataService()) { } public void SendLeafWebComplete(int leafInputId) { var leafInput = _dataService.GetLeafInput(leafInputId); var outputErrorMessage = leafInput.OutputErrorMessage; if (outputErrorMessage != null) SendLeafWebError(leafInput, outputErrorMessage.Contents.GetString()); else SendLeafWebSuccess(leafInput); } public void SendAdministratorMessage(string subject, string body) { var message = new MailMessage(_emailFromAddress, _adminEmailAddresses, subject, body); SendMessage(message); } private void SendLeafWebSuccess(LeafInput leafInput) { var body = $"Your leaf analysis job, {leafInput.Identifier}, has completed. "; body += FormatWarningMessage(leafInput); if (true) { var downloadUrl = _downloadUrlService.GetDownloadUrl(leafInput); body += "Download results with the following link:" + Environment.NewLine + Environment.NewLine + downloadUrl; var message = new MailMessage(_emailFromAddress, leafInput.Email, EmailSuccessSubject, body); SendMessage(message); } else { body += "Please see the attached results."; var message = new MailMessage(_emailFromAddress, leafInput.Email, EmailSuccessSubject, body); var fileStreams = (from outputFile in leafInput.OutputFiles select Tuple.Create(outputFile, new MemoryStream(outputFile.Contents))).ToList(); try { foreach (var fileStream in fileStreams) { var attachment = new Attachment(fileStream.Item2, fileStream.Item1.Filename); message.Attachments.Add(attachment); } SendMessage(message); } finally { // can't dispose those memory streams until the message is sent foreach (var stream in fileStreams.Select(f => f.Item2)) { stream.Dispose(); } } } } private void SendLeafWebError(LeafInput leafInput, string errorMessage) { var body = $"Your leaf analysis job, {leafInput.Identifier}, encountered the following errors." + Environment.NewLine + Environment.NewLine + Environment.NewLine + errorMessage + Environment.NewLine + Environment.NewLine + "You will need to correct your input and resubmit."; body += FormatWarningMessage(leafInput); var message = new MailMessage(_emailFromAddress, leafInput.Email, EmailErrorSubject, body); SendMessage(message); } private string FormatWarningMessage(LeafInput leafInput) { if (leafInput.OutputWarningMessage != null) return Environment.NewLine + Environment.NewLine + "The following warning message was generated." + Environment.NewLine + Environment.NewLine + leafInput.OutputWarningMessage.Contents.GetString() + Environment.NewLine; return string.Empty; } private void SendMessage(MailMessage mailMessage) { try { Logger.Debug("Email sending to " + mailMessage.To + ", subject: " + mailMessage.Subject); _smtpClient.Send(mailMessage); } catch (SmtpException ex) { Logger.Error(ex, "Failed to send mail: {0}", ex.Message); } } public void Dispose() { _dataService.Dispose(); } } }