// Spludlow Software // Copyright © Samuel P. Ludlow 2020 All Rights Reserved // Distributed under the terms of the GNU General Public License version 3 // Distributed WITHOUT ANY WARRANTY; without implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE // https://www.spludlow.co.uk/LICENCE.TXT // The Spludlow logo is a registered trademark of Samuel P. Ludlow and may not be used without permission // v1.14 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Web; using System.Net.Mail; using System.IO; using System.Data; // testMode on client not serer (server may serve test and live) // force test mode ??? in config ??>? // MasterHostId -> Render ?? using MailHostAddress namespace Spludlow.Email { public class SendMail { public static void Send(string subject, params object[] data) { Send(null, null, subject, null, null, data, false, null); } public static void Send(string subject, string[] attatchmentFilenames) { Send(null, null, subject, null, attatchmentFilenames, null, false, null); } public static void Send(string subject, string[] attatchmentFilenames, params object[] data) { Send(null, null, subject, null, attatchmentFilenames, data, false, null); } // More overloads ??? public static void Send(string toAddress, string subject, object[] data) { Send(null, new string[] { toAddress }, subject, null, null, data, false, null); } public static void Send(string toAddress, string subject, string[] attatchmentFilenames) { Send(null, new string[] { toAddress }, subject, null, attatchmentFilenames, null, false, null); } public static void Send(string toAddress, string subject, string[] attatchmentFilenames, object[] data) { Send(null, new string[] { toAddress }, subject, null, attatchmentFilenames, data, false, null); } public static void Send(string fromAddress, string[] toAddresses, string subject, string pageAddress, string[] attatchmentFilenames) { Send(fromAddress, toAddresses, subject, pageAddress, attatchmentFilenames, null, false, null); } public static void Send(string fromAddress, string[] toAddresses, string subject, string pageAddress, object[] data) { Send(fromAddress, toAddresses, subject, pageAddress, null, data, false, null); } public static void Send(string fromAddress, string[] toAddresses, string subject, string pageAddress, string[] attatchmentFilenames, object[] data) { Send(fromAddress, toAddresses, subject, pageAddress, attatchmentFilenames, data, false, null); } public static void Send(string fromAddress, string[] toAddresses, string subject, string pageAddress, string[] attatchmentFilenames, object[] data, bool testMode) { Send(fromAddress, toAddresses, subject, pageAddress, attatchmentFilenames, data, testMode, null); } public static void Send(string fromAddress, string[] toAddresses, string subject, string pageAddress, string[] attatchmentFilenames, object[] data, bool testMode, string renderHostAddress) { if (fromAddress == null) fromAddress = Spludlow.Config.Get("Spludlow.MailFromAddress"); if (toAddresses == null) toAddresses = new string[] { Spludlow.Config.Get("Spludlow.MailToAddress") }; if (subject == null) subject = "No Subject"; if (pageAddress == null) pageAddress = "Report.aspx"; if (renderHostAddress == null) renderHostAddress = Spludlow.Config.Get("Spludlow.MailHostAddress"); List attatchmentFilenameAndNames = new List(); // Allow passing (maybe tab delimeted ? Filename\tName) if (attatchmentFilenames != null) { foreach (string attatchmentFilename in attatchmentFilenames) { string tempFilename = Spludlow.WebServices.CreateProgramDataTempFilename(Path.GetExtension(attatchmentFilename)); // Check exists ??? File.Copy(attatchmentFilename, tempFilename); attatchmentFilenameAndNames.Add(new string[] { "@" + Path.GetFileName(tempFilename), Path.GetFileName(attatchmentFilename) }); } } if (data != null) { // Fix data objects not in DataSets List fixedData = new List(); foreach (object dataItem in data) { if (dataItem == null) { fixedData.Add(null); continue; } DataSet fixedItem = Spludlow.Data.ADO.WireDataSetObject(dataItem); if (fixedItem != null) fixedData.Add(fixedItem); else fixedData.Add(dataItem); } data = fixedData.ToArray(); } Spludlow.Call.Queue(renderHostAddress, "Spludlow", "Spludlow.Email.SendMail", "Receive", new object[] { fromAddress, toAddresses, subject, pageAddress, attatchmentFilenameAndNames.ToArray(), data, testMode, Environment.MachineName }, CallFlags.LargeParameters); // | CallFlags.InProcess); } public static void Receive(string fromAddress, string[] toAddresses, string subject, string pageAddress, string[][] attachmentFilenames, object[] data, bool testMode, string sourceHost) { if (pageAddress.StartsWith("http") == false) { pageAddress = Spludlow.Config.HostAddress(Environment.MachineName, true) + "Render/" + pageAddress; // or do in config ???? } pageAddress = AppendUrlParameter(pageAddress, "subject", subject); if (testMode == true) { StringBuilder newSubject = new StringBuilder(); foreach (string toAddress in toAddresses) { if (newSubject.Length > 0) newSubject.Append("; "); newSubject.Append(toAddress); } newSubject.Insert(0, "["); newSubject.Append("] "); newSubject.Append(subject); subject = newSubject.ToString(); toAddresses = new string[] { Spludlow.Config.Get("Spludlow.MailToAddress") }; } subject = Spludlow.Net.Smtp.FixSubject(subject); Encoding encoding = Encoding.UTF8; string html; if (data != null) // Need some way of getting rounf re-encoding here !!!!!!!!!!!!!!!!!! { string[][] encodedObjects = Spludlow.Parameters.EncodeParameters(data, true, false); // ?? large string[] pair = Spludlow.Parameters.EncodeParameter(encodedObjects, true, false); pair[0] = "[" + pair[0]; // Mark as encoded object[], will automatically decode to object[] pageAddress = AppendUrlParameter(pageAddress, "data", pair[0]); html = Spludlow.Net.Http.PostText(pageAddress, pair[1], encoding).Text; } else { html = Spludlow.Net.Http.GetText(pageAddress, encoding); } string[][] localAttachmentFilenames = null; if (attachmentFilenames != null && attachmentFilenames.Length > 0) // fix abovce !!!? { List localFilenames = new List(); foreach (string[] sourceNamePair in attachmentFilenames) { string name = sourceNamePair[1]; string localFilename = Spludlow.WebServices.GetProgramDataTempFile(sourceNamePair[0]); // remove original ??? localFilenames.Add(new string[] { localFilename, name }); } localAttachmentFilenames = localFilenames.ToArray(); } ReceiveSendMail(fromAddress, toAddresses, subject, localAttachmentFilenames, html); // Delete source and local attatcjemts ????? here } public static void ReceiveSendMail(string fromAddress, string[] toAddresses, string subject, string[][] attachmentFilenames, string html) { html = FixHtml(html); string smtpAddress = Spludlow.Config.Get("Spludlow.SmtpServer"); MailAddress fromMailAddress = new MailAddress(fromAddress); //fromMailAddress.DisplayName = ""; using (MailMessage mailMessage = new MailMessage()) { mailMessage.From = fromMailAddress; foreach (string toAddress in toAddresses) { MailAddress toMailAddress = new MailAddress(toAddress); //toMailAddress.DisplayName = ""; // Not matter mailMessage.To.Add(toMailAddress); } mailMessage.Subject = subject; mailMessage.IsBodyHtml = true; mailMessage.Body = html; if (attachmentFilenames != null) { foreach (string[] namePair in attachmentFilenames) { Attachment attachment = new Attachment(namePair[0]); attachment.Name = namePair[1]; mailMessage.Attachments.Add(attachment); } } Spludlow.Net.Smtp.Send(smtpAddress, mailMessage); System.Threading.Thread.Sleep(0); foreach (Attachment attachment in mailMessage.Attachments) attachment.Dispose(); } } private static string FixHtml(string input) { StringBuilder output = new StringBuilder(); using (StringReader reader = new StringReader(input)) { string line; while ((line = reader.ReadLine()) != null) { string trimLine = line.Trim(); if (trimLine.StartsWith("") == true) continue; int index = line.IndexOf("id=\"ContentPlaceHolder"); if (index != -1) { int indexEnd = line.IndexOf('"', index + 4); if (indexEnd != -1) { output.Append(line.Substring(0, index)); output.AppendLine(line.Substring(indexEnd + 1)); continue; } } output.AppendLine(line); } } return output.ToString(); } private static string AppendUrlParameter(string url, string name, string value) { StringBuilder result = new StringBuilder(url); if (url.Contains("?") == true) result.Append("&"); else result.Append("?"); result.Append(name); result.Append("="); result.Append(HttpUtility.UrlEncode(value)); return result.ToString(); } public static object[] GetPostedData(HttpRequest request, string dataTypeText) { string postedBody = Spludlow.Net.Http.PostedText(request, Encoding.UTF8); // encoding !!!! return (object[])Spludlow.Parameters.DecodeParameter(new string[] { dataTypeText, postedBody }); } } }