async void RenderMultipartRelated(IMailFolder folder, UniqueId uid, BodyPartMultipart bodyPart) { // download the entire multipart/related for simplicity since we'll probably end up needing all of the image attachments anyway... var related = await folder.GetBodyPartAsync(uid, bodyPart) as MultipartRelated; RenderMultipartRelated(related); }
async void RenderText(IMailFolder folder, UniqueId uid, BodyPartText bodyPart) { var entity = await folder.GetBodyPartAsync(uid, bodyPart); RenderText((TextPart)entity); }
public async Task <string> RenderMultipartRelatedAsync(IMailFolder folder, UniqueId uid, BodyPartMultipart bodyPart) { var related = await folder.GetBodyPartAsync(uid, bodyPart) as MultipartRelated; return(RenderMultipartRelated(related)); }
async void RenderRelated (IMailFolder folder, UniqueId uid, BodyPartMultipart related) { var start = related.ContentType.Parameters["start"]; BodyPartText root = null; if (!string.IsNullOrEmpty (start)) { // if the 'start' parameter is set, it overrides the default behavior of using the first // body part as the main document. root = related.BodyParts.OfType<BodyPartText> ().FirstOrDefault (x => x.ContentId == start); } else if (related.BodyParts.Count > 0) { // this will generally either be a text/html part (which is what we are looking for) or a multipart/alternative var multipart = related.BodyParts[0] as BodyPartMultipart; if (multipart != null) { if (multipart.ContentType.Matches ("multipart", "alternative") && multipart.BodyParts.Count > 0) { // find the last text/html part (which will be the closest to what the sender saw in their WYSIWYG editor) // or, failing that, the last text part. for (int i = multipart.BodyParts.Count; i > 0; i--) { var bodyPart = multipart.BodyParts[i - 1] as BodyPartText; if (bodyPart == null) continue; if (bodyPart.ContentType.Matches ("text", "html")) { root = bodyPart; break; } if (root == null) root = bodyPart; } } } else { root = related.BodyParts[0] as BodyPartText; } } if (root == null) return; var text = await folder.GetBodyPartAsync (uid, root) as TextPart; if (text != null && text.ContentType.Matches ("text", "html")) { var doc = new HtmlAgilityPack.HtmlDocument (); var saved = new Dictionary<MimePart, string> (); TextPart html; doc.LoadHtml (text.Text); // find references to related MIME parts and replace them with links to links to the saved attachments foreach (var img in doc.DocumentNode.SelectNodes ("//img[@src]")) { var src = img.Attributes["src"]; int index; Uri uri; if (src == null || src.Value == null) continue; // parse the <img src=...> attribute value into a Uri if (Uri.IsWellFormedUriString (src.Value, UriKind.Absolute)) uri = new Uri (src.Value, UriKind.Absolute); else uri = new Uri (src.Value, UriKind.Relative); // locate the index of the attachment within the multipart/related (if it exists) if ((index = related.BodyParts.IndexOf (uri)) != -1) { var bodyPart = related.BodyParts[index] as BodyPartBasic; if (bodyPart == null) { // the body part is not a basic leaf part (IOW it's a multipart or message-part) continue; } var attachment = await folder.GetBodyPartAsync (uid, bodyPart) as MimePart; // make sure the referenced part is a MimePart (as opposed to another Multipart or MessagePart) if (attachment == null) continue; string fileName; // save the attachment (if we haven't already saved it) if (!saved.TryGetValue (attachment, out fileName)) { fileName = attachment.FileName; if (string.IsNullOrEmpty (fileName)) fileName = Guid.NewGuid ().ToString (); if (!Directory.Exists (uid.ToString ())) Directory.CreateDirectory (uid.ToString ()); fileName = Path.Combine (uid.ToString (), fileName); using (var stream = File.Create (fileName)) attachment.ContentObject.DecodeTo (stream); saved.Add (attachment, fileName); } // replace the <img src=...> value with the local file name src.Value = "file://" + Path.GetFullPath (fileName); } } if (saved.Count > 0) { // we had to make some modifications to the original html part, so create a new // (temporary) text/html part to render html = new TextPart ("html"); using (var writer = new StringWriter ()) { doc.Save (writer); html.Text = writer.GetStringBuilder ().ToString (); } } else { html = text; } RenderText (html); } else if (text != null) { RenderText (text); } }
async Task <string> RenderTextAsync(IMailFolder folder, UniqueId uid, BodyPartText bodyPart) { var entity = await folder.GetBodyPartAsync(uid, bodyPart); return(RenderText((TextPart)entity)); }
async void RenderText (IMailFolder folder, UniqueId uid, BodyPartText bodyPart) { var entity = await folder.GetBodyPartAsync (uid, bodyPart); RenderText ((TextPart) entity); }
async void RenderMultipartRelated (IMailFolder folder, UniqueId uid, BodyPartMultipart bodyPart) { // download the entire multipart/related for simplicity since we'll probably end up needing all of the image attachments anyway... var related = await folder.GetBodyPartAsync (uid, bodyPart) as MultipartRelated; RenderMultipartRelated (related); }
async void RenderRelated(IMailFolder folder, UniqueId uid, BodyPartMultipart related) { var start = related.ContentType.Parameters["start"]; BodyPartText root = null; if (!string.IsNullOrEmpty(start)) { // if the 'start' parameter is set, it overrides the default behavior of using the first // body part as the main document. root = related.BodyParts.OfType <BodyPartText> ().FirstOrDefault(x => x.ContentId == start); } else if (related.BodyParts.Count > 0) { // this will generally either be a text/html part (which is what we are looking for) or a multipart/alternative var multipart = related.BodyParts[0] as BodyPartMultipart; if (multipart != null) { if (multipart.ContentType.Matches("multipart", "alternative") && multipart.BodyParts.Count > 0) { // find the last text/html part (which will be the closest to what the sender saw in their WYSIWYG editor) // or, failing that, the last text part. for (int i = multipart.BodyParts.Count; i > 0; i--) { var bodyPart = multipart.BodyParts[i - 1] as BodyPartText; if (bodyPart == null) { continue; } if (bodyPart.ContentType.Matches("text", "html")) { root = bodyPart; break; } if (root == null) { root = bodyPart; } } } } else { root = related.BodyParts[0] as BodyPartText; } } if (root == null) { return; } var text = await folder.GetBodyPartAsync(uid, root) as TextPart; if (text != null && text.ContentType.Matches("text", "html")) { var doc = new HtmlAgilityPack.HtmlDocument(); var saved = new Dictionary <MimePart, string> (); TextPart html; doc.LoadHtml(text.Text); // find references to related MIME parts and replace them with links to links to the saved attachments foreach (var img in doc.DocumentNode.SelectNodes("//img[@src]")) { var src = img.Attributes["src"]; int index; Uri uri; if (src == null || src.Value == null) { continue; } // parse the <img src=...> attribute value into a Uri if (Uri.IsWellFormedUriString(src.Value, UriKind.Absolute)) { uri = new Uri(src.Value, UriKind.Absolute); } else { uri = new Uri(src.Value, UriKind.Relative); } // locate the index of the attachment within the multipart/related (if it exists) if ((index = related.BodyParts.IndexOf(uri)) != -1) { var bodyPart = related.BodyParts[index] as BodyPartBasic; if (bodyPart == null) { // the body part is not a basic leaf part (IOW it's a multipart or message-part) continue; } var attachment = await folder.GetBodyPartAsync(uid, bodyPart) as MimePart; // make sure the referenced part is a MimePart (as opposed to another Multipart or MessagePart) if (attachment == null) { continue; } string fileName; // save the attachment (if we haven't already saved it) if (!saved.TryGetValue(attachment, out fileName)) { fileName = attachment.FileName; if (string.IsNullOrEmpty(fileName)) { fileName = Guid.NewGuid().ToString(); } if (!Directory.Exists(uid.ToString())) { Directory.CreateDirectory(uid.ToString()); } fileName = Path.Combine(uid.ToString(), fileName); using (var stream = File.Create(fileName)) attachment.ContentObject.DecodeTo(stream); saved.Add(attachment, fileName); } // replace the <img src=...> value with the local file name src.Value = "file://" + Path.GetFullPath(fileName); } } if (saved.Count > 0) { // we had to make some modifications to the original html part, so create a new // (temporary) text/html part to render html = new TextPart("html"); using (var writer = new StringWriter()) { doc.Save(writer); html.Text = writer.GetStringBuilder().ToString(); } } else { html = text; } RenderText(html); } else if (text != null) { RenderText(text); } }
public static async void RenderMultipartRelated(IMailFolder folder, UniqueId uid, BodyPartMultipart bodyPart, WebBrowserEditabil pWebBrowser) { var related = await folder.GetBodyPartAsync(uid, bodyPart) as MultipartRelated; RenderMultipartRelated(related, pWebBrowser); }
private static async void RenderText(IMailFolder folder, UniqueId uid, BodyPartText bodyPart, WebBrowserEditabil pWebBrowser) { var entity = await folder.GetBodyPartAsync(uid, bodyPart); RenderText((TextPart)entity, pWebBrowser); }