Exemple #1
0
    public static string Inline(string source)
    {
        using var pm = new PreMailer.Net.PreMailer(source);
        var html = pm.MoveCssInline(css: EmailCssContent, removeComments: true, stripIdAndClassAttributes: false, removeStyleElements: false).Html;

        return(html);
    }
Exemple #2
0
        /// <summary>
        /// In-lines the CSS for the current HTML
        /// </summary>
        /// <param name="removeStyleElements">If set to <c>true</c> the style elements are removed.</param>
        /// <param name="ignoreElements">CSS selector for STYLE elements to ignore (e.g. mobile-specific styles etc.)</param>
        /// <param name="css">A string containing a style-sheet for inlining.</param>
        /// <param name="stripIdAndClassAttributes">True to strip ID and class attributes</param>
        /// <param name="removeComments">True to remove comments, false to leave them intact</param>
        /// <param name="precompiledStyles"></param>
        /// <returns>Returns the html input, with styles moved to inline attributes.</returns>
        public InlineResult MoveCssInline(bool removeStyleElements = false, string ignoreElements = null, string css = null, bool stripIdAndClassAttributes = false, bool removeComments = false, SortedList <string, StyleClass> precompiledStyles = null)
        {
            // Store the variables used for inlining the CSS
            _removeStyleElements       = removeStyleElements;
            _stripIdAndClassAttributes = stripIdAndClassAttributes;
            _ignoreElements            = ignoreElements;

            // Gather all of the CSS that we can work with.
            var cssSourceNodes = CssSourceNodes();
            var cssLinkNodes   = CssLinkNodes();
            var cssSources     = new List <ICssSource>(ConvertToStyleSources(cssSourceNodes));

            cssSources.AddRange(ConvertToStyleSources(cssLinkNodes));
            cssSources.AddRange(PreMailer.ConvertToStyleSources(css));

            var cssBlocks = PreMailer.GetCssBlocks(cssSources);

            if (_removeStyleElements)
            {
                RemoveStyleElements(cssSourceNodes);
                RemoveStyleElements(cssLinkNodes);
            }

            var joinedBlocks   = PreMailer.Join(cssBlocks);
            var validSelectors = CleanUnsupportedSelectors(joinedBlocks);

            if (precompiledStyles != null)
            {
                precompiledStyles.ToList().ForEach(kvp => { validSelectors.Add(kvp.Key, kvp.Value); });
            }

            var elementsWithStyles = FindElementsWithStyles(validSelectors);
            var mergedStyles       = MergeStyleClasses(elementsWithStyles);

            StyleClassApplier.ApplyAllStyles(mergedStyles);

            if (_stripIdAndClassAttributes)
            {
                StripElementAttributes("id", "class");
            }

            if (removeComments)
            {
                var comments = _document.Descendents <IComment>().ToList();

                foreach (var comment in comments)
                {
                    comment.Remove();
                }
            }

            var html = _document.ToHtml(new AutoSelectedMarkupFormatter(_document.Doctype));

            return(new InlineResult(html, _warnings));
        }
Exemple #3
0
        /// <summary>
        /// Function to precompile a style sheet allowing it be be preserved in
        /// memory for performance purposes.
        /// </summary>
        /// <param name="css">A string containing a style-sheet for inlining.</param>
        /// <param name="warnings">A list of warnings indicating css elements that are not supported.</param>
        /// <returns>A tokenized sorted list representing the css that was passed in</returns>
        public static SortedList <string, StyleClass> PrecompileCssString(string css, out List <string> warnings)
        {
            var cssSource    = new List <ICssSource>(PreMailer.ConvertToStyleSources(css));
            var cssBlocks    = PreMailer.GetCssBlocks(cssSource);
            var joinedBlocks = PreMailer.Join(cssBlocks);

            warnings = new List <string>();
            var cleanJoinedBlocks = PreMailer.CleanUnsupportedSelectors(joinedBlocks, warnings);

            return(cleanJoinedBlocks);
        }
Exemple #4
0
        public string GenerateEmailBody(PersonModel model)
        {
            // Create a model for our email
            var templateFolderPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin", "EmailTemplates");
            var templateFilePath   = Path.Combine(templateFolderPath, "Email.cshtml");
            // Generate the email body from the template file.
            // 'templateFilePath' should contain the absolute path of your template file.
            //var TemplateService = new TemplateService();
            var emailHtmlBody = TemplateService.Parse(File.ReadAllText(templateFilePath), model, null, "Email");

            /*
             *  Move CSS Inline.  https://github.com/milkshakesoftware/PreMailer.Net
             */
            var pm = new PreMailer.Net.PreMailer(emailHtmlBody);
            //pm.AddAnalyticsTags(source, medium, campaign, content, domain = null); // Optional to add analytics tags
            var result = pm.MoveCssInline();

            return(result.Html);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="mailInfo"></param>
        /// <param name="recepients">receivers</param>
        /// <param name="testMode">No mails are sent, generating report for user</param>
        /// <returns>A html formatted report of the send process</returns>
        public override SendMailLog SendEmail(MailInformation mailInfo, JobWorkItems recepients, bool testMode)
        {
            _log.Debug("Starting Send");
            // for logging
            SendMailLog log = new SendMailLog();

            // Need someone to send to
            if (recepients.Items.Count == 0)
            {
                _log.Error("Trying to send newsletter with an empty JobWorkCollection. Please check the collection before attemting to send mail.");
                throw new ArgumentNullException("recepients", "Recipient collection is empty, there is no recipients to send to.");
            }

            // And, we need a sender address
            if (string.IsNullOrEmpty(mailInfo.From))
            {
                _log.Error("Missing from address.");
                throw new ArgumentNullException("mailInfo", "Missing from address.");
            }

            // Inline all css
            PreMailer.Net.PreMailer preMailer = new PreMailer.Net.PreMailer(mailInfo.BodyHtml);
            if (mailInfo.Utm.HasValidUtmCode)
            {
                preMailer.AddAnalyticsTags(mailInfo.Utm.Source, mailInfo.Utm.Medium, mailInfo.Utm.Campaign,
                    mailInfo.Utm.Content);
            }
            InlineResult cssInline = preMailer.MoveCssInline();
            mailInfo.BodyHtml = cssInline.Html;

            // Log any messages, debug is only detected
            // if we have an HttpContext.
            if (IsInDebugMode())
            {
                log.WarningMessages.Add("Premailer CSS warning messages are only shown in debug mode. Primarily for developers.");
                log.WarningMessages.AddRange(cssInline.Warnings.ToArray());
            }

            // Loop through receivers collection, add to collection and send
            // one email per batch size.
            int batchRun = 0;
            int batchSize = GetBatchSize();

            do
            {
                IEnumerable<JobWorkItem> workItems = recepients.Skip(batchRun*batchSize).Take(batchSize);
                int numberofItemsToSend = workItems.Count();
                if (numberofItemsToSend == 0)
                    break;
                batchRun++;

                try
                {
                    if (SendMailBatch(mailInfo, workItems, testMode))
                    {
                        // Mark each item as sent
                        foreach (JobWorkItem workItem in workItems)
                        {
                            log.SuccessMessages.Add(workItem.EmailAddress);
                            // Update status and save it
                            workItem.Status = JobWorkStatus.Complete;
                            // Only save if real work item (could be a test item)
                            if (workItem.JobId > 0)
                                workItem.Save();
                        }
                    }
                }
                catch (Exception ex)
                {
                    _log.Error(string.Format("Error sending batch (to {0} recipients).", recepients.Count()), ex);
                    string exceptionMsg = ex.Message;
                    log.ErrorMessages.Add(exceptionMsg);

                    // Update work item
                    foreach (JobWorkItem workItem in workItems)
                    {
                        workItem.Status = JobWorkStatus.Failed;
                        if (exceptionMsg.Length >= 2000)
                            exceptionMsg = exceptionMsg.Substring(0, 1999);
                        workItem.Info = exceptionMsg;
                        if (workItem.JobId > 0)
                            workItem.Save();
                    }

                    // can't continue
                    break;
                }
            } while (true);

            // Finished
            log.SendStop = DateTime.Now;

            _log.Debug("Ending Send");
            // return report
            return log;
        }
		/// <summary>
		/// In-lines the CSS within the HTML given.
		/// </summary>
		/// <param name="html">The HTML input.</param>
		/// <param name="removeStyleElements">If set to <c>true</c> the style elements are removed.</param>
		/// <param name="ignoreElements">CSS selector for STYLE elements to ignore (e.g. mobile-specific styles etc.)</param>
		/// <returns>Returns the html input, with styles moved to inline attributes.</returns>
		public static InlineResult MoveCssInline(string html, bool removeStyleElements = false, string ignoreElements = null)
		{
			var pm = new PreMailer(html, removeStyleElements, ignoreElements);
			return pm.Process();
		}
Exemple #7
0
        /// <summary>
        /// In-lines the CSS within the HTML given.
        /// </summary>
        /// <param name="html">The HTML input.</param>
        /// <param name="removeStyleElements">If set to <c>true</c> the style elements are removed.</param>
        /// <param name="ignoreElements">CSS selector for STYLE elements to ignore (e.g. mobile-specific styles etc.)</param>
        /// <param name="css">A string containing a style-sheet for inlining.</param>
        /// <returns>Returns the html input, with styles moved to inline attributes.</returns>
        public static InlineResult MoveCssInline(string html, bool removeStyleElements = false, string ignoreElements = null, string css = null, bool stripIdAndClassAttributes = false)
        {
            var pm = new PreMailer(html, removeStyleElements, ignoreElements, css, stripIdAndClassAttributes);

            return(pm.Process());
        }
        /// <summary>
        /// In-lines the CSS within the HTML given.
        /// </summary>
        /// <param name="html">The HTML input.</param>
        /// <param name="removeStyleElements">If set to <c>true</c> the style elements are removed.</param>
        /// <param name="ignoreElements">CSS selector for STYLE elements to ignore (e.g. mobile-specific styles etc.)</param>
        /// <returns>Returns the html input, with styles moved to inline attributes.</returns>
        public static InlineResult MoveCssInline(string html, bool removeStyleElements = false, string ignoreElements = null)
        {
            var pm = new PreMailer(html, removeStyleElements, ignoreElements);

            return(pm.Process());
        }
Exemple #9
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="mailInfo"></param>
        /// <param name="recepients">receivers</param>
        /// <param name="testMode">No mails are sent, generating report for user</param>
        /// <returns>A html formatted report of the send process</returns>
        public override SendMailLog SendEmail(MailInformation mailInfo, JobWorkItems recepients, bool testMode)
        {
            _log.Debug("Starting Send");
            // for logging
            SendMailLog log = new SendMailLog();

            // Need someone to send to
            if (recepients.Items.Count == 0)
            {
                _log.Error("Trying to send newsletter with an empty JobWorkCollection. Please check the collection before attemting to send mail.");
                throw new ArgumentNullException("recepients", "Recipient collection is empty, there is no recipients to send to.");
            }

            // And, we need a sender address
            if (string.IsNullOrEmpty(mailInfo.From))
            {
                _log.Error("Missing from address.");
                throw new ArgumentNullException("mailInfo", "Missing from address.");
            }

            // Inline all css
            PreMailer.Net.PreMailer preMailer = new PreMailer.Net.PreMailer(mailInfo.BodyHtml);
            if (mailInfo.Utm.HasValidUtmCode)
            {
                preMailer.AddAnalyticsTags(mailInfo.Utm.Source, mailInfo.Utm.Medium, mailInfo.Utm.Campaign,
                                           mailInfo.Utm.Content);
            }
            InlineResult cssInline = preMailer.MoveCssInline();

            mailInfo.BodyHtml = cssInline.Html;

            // Log any messages, debug is only detected
            // if we have an HttpContext.
            if (IsInDebugMode())
            {
                log.WarningMessages.Add("Premailer CSS warning messages are only shown in debug mode. Primarily for developers.");
                log.WarningMessages.AddRange(cssInline.Warnings.ToArray());
            }

            // Loop through receivers collection, add to collection and send
            // one email per batch size.
            int batchRun  = 0;
            int batchSize = GetBatchSize();

            do
            {
                IEnumerable <JobWorkItem> workItems = recepients.Skip(batchRun * batchSize).Take(batchSize);
                int numberofItemsToSend             = workItems.Count();
                if (numberofItemsToSend == 0)
                {
                    break;
                }
                batchRun++;

                try
                {
                    if (SendMailBatch(mailInfo, workItems, testMode))
                    {
                        // Mark each item as sent
                        foreach (JobWorkItem workItem in workItems)
                        {
                            log.SuccessMessages.Add(workItem.EmailAddress);
                            // Update status and save it
                            workItem.Status = JobWorkStatus.Complete;
                            // Only save if real work item (could be a test item)
                            if (workItem.JobId > 0)
                            {
                                workItem.Save();
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    _log.Error(string.Format("Error sending batch (to {0} recipients).", recepients.Count()), ex);
                    string exceptionMsg = ex.Message;
                    log.ErrorMessages.Add(exceptionMsg);

                    // Update work item
                    foreach (JobWorkItem workItem in workItems)
                    {
                        workItem.Status = JobWorkStatus.Failed;
                        if (exceptionMsg.Length >= 2000)
                        {
                            exceptionMsg = exceptionMsg.Substring(0, 1999);
                        }
                        workItem.Info = exceptionMsg;
                        if (workItem.JobId > 0)
                        {
                            workItem.Save();
                        }
                    }

                    // can't continue
                    break;
                }
            } while (true);

            // Finished
            log.SendStop = DateTime.Now;

            _log.Debug("Ending Send");
            // return report
            return(log);
        }