public void Import_WithBlogPostHavingBase64EncodedContentWithAttachments_ProperlyRewritesAttachments() { // arrange var blog = new BlogMLBlog(); const string originalPostContent = @"<img src=""http://old.example.com/images/my-mug.jpg"" />"; var post = new BlogMLPost { Content = BlogMLContent.Create(originalPostContent, ContentTypes.Base64) }; var attachment = new BlogMLAttachment { Url = "http://old.example.com/images/my-mug.jpg", Embedded = false }; post.Attachments.Add(attachment); blog.Posts.Add(post); var repository = new Mock <IBlogImportRepository>(); repository.Setup(r => r.GetAttachmentDirectoryUrl()).Returns("http://new.example.com/images/"); repository.Setup(r => r.GetAttachmentDirectoryPath()).Returns(@"c:\web\images"); BlogMLPost publishedPost = null; repository.Setup(r => r.CreateBlogPost(blog, post)).Callback <BlogMLBlog, BlogMLPost>((b, p) => publishedPost = p); var service = new BlogImportService(repository.Object); // act service.Import(blog); // assert Assert.AreEqual(ContentTypes.Base64, publishedPost.Content.ContentType); Assert.AreEqual(@"<img src=""http://new.example.com/images/my-mug.jpg"" />", publishedPost.Content.UncodedText); }
private void ImportBlogPost(BlogMLBlog blog, BlogMLPost bmlPost) { if (bmlPost.Attachments.Count > 0) { //Updates the post content with new attachment urls. bmlPost.Content = BlogMLContent.Create(CreateFilesFromAttachments(bmlPost), ContentTypes.Base64); } string newEntryId = Repository.CreateBlogPost(blog, bmlPost); foreach (BlogMLComment bmlComment in bmlPost.Comments) { try { Repository.CreateComment(bmlComment, newEntryId); } catch (Exception e) { LogError(Resources.Import_ErrorWhileImportingComment, e); } } foreach (BlogMLTrackback bmlPingTrack in bmlPost.Trackbacks) { try { Repository.CreateTrackback(bmlPingTrack, newEntryId); } catch (Exception e) { LogError(Resources.Import_ErrorWhileImportingComment, e); } } }
protected void WriteStartBlogMLPost(BlogPost post) { WriteStartElement("post"); WriteNodeAttributes(post.Id.ToString(), post.ActivationDate, post.ModifiedOn, post.Status == PageStatus.Published); WriteAttributeString("post-url", post.PageUrl); WriteAttributeStringRequired("type", "normal"); WriteAttributeStringRequired("hasexcerpt", (!string.IsNullOrWhiteSpace(post.Description)).ToString().ToLower()); WriteAttributeStringRequired("views", "0"); WriteContent("title", BlogMLContent.Create(post.MetaTitle ?? post.Title, ContentTypes.Text)); WriteContent("post-name", BlogMLContent.Create(post.Title, ContentTypes.Text)); if (!string.IsNullOrWhiteSpace(post.Description)) { WriteBlogMLContent("excerpt", BlogMLContent.Create(post.Description, ContentTypes.Text)); } var content = post.PageContents .Where(pc => pc.Content is BlogPostContent && pc.Content.Status == ContentStatus.Published) .Select(pc => pc.Content) .FirstOrDefault(); if (content != null) { WriteBlogMLContent("content", BlogMLContent.Create(((BlogPostContent)content).Html, ContentTypes.Text)); } }
protected void WriteStartPost( string id, string title, ContentTypes titleContentType, DateTime dateCreated, DateTime dateModified, bool approved, string content, ContentTypes postContentType, string postUrl, UInt32 views, bool hasexcerpt, string excerpt, ContentTypes excerptContentType, BlogPostTypes blogpostType, string postName ) { WriteStartElement("post"); WriteNodeAttributes(id, dateCreated, dateModified, approved); WriteAttributeString("post-url", postUrl); WriteAttributeStringRequired("type", blogpostType.ToString().ToLower()); WriteAttributeStringRequired("hasexcerpt", hasexcerpt.ToString().ToLower()); WriteAttributeStringRequired("views", views.ToString()); WriteContent("title", BlogMLContent.Create(title, titleContentType)); WriteContent("content", BlogMLContent.Create(content, postContentType)); if (postName != null) { WriteContent("post-name", BlogMLContent.Create(postName, ContentTypes.Text)); } if (hasexcerpt) { WriteContent("excerpt", BlogMLContent.Create(excerpt, excerptContentType)); } }
public void Write_WithBlogContainingBase64EncodedPosts_WritesPostsToWriterAsBase64Encoded() { // arrange var stringWriter = new StringWriter(); var xmlWriter = new XmlTextWriter(stringWriter) { Formatting = Formatting.Indented }; var source = new Mock <IBlogMLSource>(); var dateTime = DateTime.ParseExact("20090123", "yyyyMMdd", CultureInfo.InvariantCulture); var blog = new BlogMLBlog { Title = "Subtext Blog", RootUrl = "http://subtextproject.com/", SubTitle = "A test blog", DateCreated = dateTime }; source.Setup(s => s.GetBlog()).Returns(blog); var post = new BlogMLPost { Content = BlogMLContent.Create("<p>This is a Test</p>", ContentTypes.Base64) }; var posts = new List <BlogMLPost> { post }; blog.Posts.Add(post); source.Setup(s => s.GetBlogPosts(false /*embedAttachments*/)).Returns(posts); var writer = new BlogMLWriter(source.Object, false /*embedAttachments*/); // act ((IBlogMLWriter)writer).Write(xmlWriter); // assert string output = stringWriter.ToString(); Console.WriteLine(Convert.ToBase64String(Encoding.UTF8.GetBytes("<p>This is a Test</p>"))); Assert.Contains(output, @"<content type=""base64""><![CDATA[PHA+VGhpcyBpcyBhIFRlc3Q8L3A+]]></content>"); }
protected void WriteContent(string elementName, BlogMLContent content) { WriteStartElement(elementName); string contentType = (Enum.GetName(typeof(ContentTypes), content.ContentType) ?? "text").ToLowerInvariant(); WriteAttributeString("type", contentType); Writer.WriteCData(content.Text ?? string.Empty); WriteEndElement(); }
public void Execute(BlogPostConversionData postConversionData) { var post = postConversionData.Post; var markdown = post.Content.Text; markdown = ReverseMarkdownHelper .DecodeAfterConversion(markdown); post.Content = BlogMLContent.Create( markdown, ContentTypes.Text); }
public void Execute(BlogPostConversionData postConversionData) { var post = postConversionData.Post; var mdConverter = new Converter(); var markdown = mdConverter.Convert( post.Content.UncodedText); postConversionData.Post.Content = BlogMLContent.Create( markdown, BlogML.ContentTypes.Text); }
public void ConvertBlogPost_WithPostHavingBase64EncodedExcerpt_DecodesContent() { // arrange var post = new BlogMLPost { HasExcerpt = true, Excerpt = BlogMLContent.Create("This is a story about a 3 hour voyage", ContentTypes.Base64) }; var mapper = new BlogMLImportMapper(); // act Entry entry = mapper.ConvertBlogPost(post, new BlogMLBlog(), null); // assert Assert.AreEqual("This is a story about a 3 hour voyage", entry.Description); }
private void WritePostComments(BlogMLPost.CommentCollection comments) { if (comments.Count > 0) { WriteStartComments(); foreach (BlogMLComment comment in comments) { string userName = string.IsNullOrEmpty(comment.UserName) ? "Anonymous" : comment.UserName; WriteComment(comment.ID, BlogMLContent.Create(comment.Title, ContentTypes.Text), comment.DateCreated, comment.DateModified, comment.Approved, userName, comment.UserEMail, comment.UserUrl, comment.Content); } WriteEndElement(); } }
protected void WriteAuthor( string id, string name, string email, DateTime dateCreated, DateTime dateModified, bool approved ) { WriteStartElement("author"); WriteNodeAttributes(id, dateCreated, dateModified, approved); WriteAttributeString("email", email); WriteContent("title", BlogMLContent.Create(name, ContentTypes.Text)); WriteEndElement(); }
public void Execute(BlogPostConversionData postConversionData) { var post = postConversionData.Post; var postHtml = post.Content.UncodedText; var htmlDoc = new HtmlDocument(); htmlDoc.LoadHtml(postHtml); ReplaceBlogImageUrls(htmlDoc); post.Content = BlogMLContent.Create( htmlDoc.DocumentNode.OuterHtml, ContentTypes.Html); }
protected void WriteTrackback( string id, string title, ContentTypes titleContentType, DateTime dateCreated, DateTime dateModified, bool approved, string url ) { WriteStartElement("trackback"); WriteNodeAttributes(id, dateCreated, dateModified, approved); WriteAttributeStringRequired("url", url); WriteContent("title", BlogMLContent.Create(title, titleContentType)); WriteEndElement(); }
public void Execute(BlogPostConversionData postConversionData) { var post = postConversionData.Post; var postHtml = post.Content.UncodedText; var htmlDoc = new HtmlDocument(); htmlDoc.LoadHtml(postHtml); EncodeSpecialCharactersInHugoShortcodes(htmlDoc); post.Content = BlogMLContent.Create( htmlDoc.DocumentNode.OuterHtml, ContentTypes.Html); }
public BlogMLPost ConvertEntry(EntryStatsView entry, bool embedAttachments) { string postUrl = null; var entryVirtualPath = Url.EntryUrl(entry); if (entryVirtualPath != null) { postUrl = entryVirtualPath.ToFullyQualifiedUrl(Blog).ToString(); } var post = new BlogMLPost { Title = entry.Title, PostUrl = postUrl, PostType = (entry.PostType == PostType.Story) ? BlogPostTypes.Article : BlogPostTypes.Normal, Approved = entry.IsActive, Content = BlogMLContent.Create(entry.Body ?? string.Empty, ContentTypes.Base64), HasExcerpt = entry.HasDescription, Excerpt = BlogMLContent.Create(entry.Description ?? string.Empty, ContentTypes.Base64), DateCreated = Blog.TimeZone.ToUtc(entry.DateCreated), DateModified = Blog.TimeZone.ToUtc(entry.IsActive ? entry.DateSyndicated : entry.DateModified), Views = (uint)entry.WebCount }; if (entry.HasEntryName) { post.PostName = entry.EntryName; } // When we support multiple authors, this will have to change post.Authors.Add(Blog.Id.ToString(CultureInfo.InvariantCulture)); post.Attachments.AddRange(GetPostAttachments(entry.Body, embedAttachments).ToArray()); var comments = (from c in entry.Comments where c.FeedbackType == FeedbackType.Comment select ConvertComment(c)).ToList(); if (comments.Count > 0) { post.Comments.AddRange(comments); } var trackbacks = (from c in entry.Comments where c.FeedbackType == FeedbackType.PingTrack select ConvertTrackback(c)).ToList(); if (trackbacks.Count > 0) { post.Trackbacks.AddRange(trackbacks); } return(post); }
public void Execute(BlogPostConversionData postConversionData) { var post = postConversionData.Post; var postHtml = post.Content.UncodedText; var htmlDoc = new HtmlDocument(); htmlDoc.LoadHtml(postHtml); FixSpacesInCodeElements(htmlDoc); FixSpacesInCodeSpanElements(htmlDoc); FixSpacesInInlineElements(htmlDoc); post.Content = BlogMLContent.Create( htmlDoc.DocumentNode.OuterHtml, ContentTypes.Html); }
protected void WriteCategory( string id, string title, ContentTypes titleContentType, DateTime dateCreated, DateTime dateModified, bool approved, string description, string parentRef ) { WriteStartElement("category"); WriteNodeAttributes(id, dateCreated, dateModified, approved); WriteAttributeString("description", description); WriteAttributeString("parentref", parentRef); WriteContent("title", BlogMLContent.Create(title, titleContentType)); WriteEndElement(); }
protected void WriteStartBlogMLPost(BlogMLPost post) { WriteStartElement("post"); WriteNodeAttributes(post.ID, post.DateCreated, post.DateModified, post.Approved); WriteAttributeString("post-url", post.PostUrl); WriteAttributeStringRequired("type", "normal"); WriteAttributeStringRequired("hasexcerpt", post.HasExcerpt.ToString().ToLowerInvariant()); WriteAttributeStringRequired("views", post.Views.ToString()); WriteContent("title", BlogMLContent.Create(post.Title, ContentTypes.Text)); WriteBlogMLContent("content", post.Content); if (!string.IsNullOrEmpty(post.PostName)) { WriteContent("post-name", BlogMLContent.Create(post.PostName, ContentTypes.Text)); } if (post.HasExcerpt) { WriteBlogMLContent("excerpt", post.Excerpt); } }
protected void WriteStartBlog( string title, ContentTypes titleContentType, string subTitle, ContentTypes subTitleContentType, string rootUrl, DateTime dateCreated) { Writer.WriteStartElement("blog", BlogMLNamespace); WriteAttributeStringRequired("root-url", rootUrl); WriteAttributeString("date-created", FormatDateTime(dateCreated)); // Write the default namespace, identified as xmlns with no prefix Writer.WriteAttributeString("xmlns", null, null, BlogMLNamespace); Writer.WriteAttributeString("xmlns", "xs", null, XMLSchemaNamespace); WriteContent("title", BlogMLContent.Create(title, titleContentType)); WriteContent("sub-title", BlogMLContent.Create(subTitle, subTitleContentType)); }
protected void WriteComment(string id, BlogMLContent title, DateTime dateCreated, DateTime dateModified, bool approved, string userName, string userEmail, string userUrl, BlogMLContent content ) { WriteStartElement("comment"); WriteNodeAttributes(id, dateCreated, dateModified, approved); WriteAttributeStringRequired("user-name", userName ?? ""); WriteAttributeString("user-url", userUrl ?? ""); WriteAttributeString("user-email", userEmail ?? ""); WriteContent("title", title); WriteContent("content", content); WriteEndElement(); }
protected void WriteStartBlog( string title, ContentTypes titleContentType, string subTitle, ContentTypes subTitleContentType, string rootUrl, DateTime dateCreated) { //WriteStartElement("blog"); Writer.WriteStartElement("blog", BlogMLNamespace); // fixes bug in Work Item 2004 WriteAttributeStringRequired("root-url", rootUrl); WriteAttributeString("date-created", FormatDateTime(dateCreated)); // Write the default namespace, identified as xmlns with no prefix Writer.WriteAttributeString("xmlns", null, null, "http://www.blogml.com/2006/09/BlogML"); Writer.WriteAttributeString("xmlns", "xs", null, "http://www.w3.org/2001/XMLSchema"); WriteContent("title", BlogMLContent.Create(title, titleContentType)); WriteContent("sub-title", BlogMLContent.Create(subTitle, subTitleContentType)); }
public BlogMLComment ConvertComment(FeedbackItem feedbackItem) { if (feedbackItem == null) { throw new ArgumentNullException("feedbackItem"); } if (feedbackItem.FeedbackType != FeedbackType.Comment) { throw new ArgumentException(String.Format(Resources.ArgumentException_CommentTypeMismatch, feedbackItem.FeedbackType, FeedbackType.Comment), "feedbackItem"); } return(new BlogMLComment { ID = feedbackItem.Id.ToString(CultureInfo.InvariantCulture), Title = feedbackItem.Title, UserUrl = feedbackItem.SourceUrl != null?feedbackItem.SourceUrl.ToString() : null, UserEMail = feedbackItem.Email, UserName = feedbackItem.Author, Approved = feedbackItem.Approved, Content = BlogMLContent.Create(feedbackItem.Body ?? string.Empty, ContentTypes.Base64), DateCreated = Blog.TimeZone.ToUtc(feedbackItem.DateCreated), DateModified = Blog.TimeZone.ToUtc(feedbackItem.DateModified) }); }
protected void WriteBlogMLContent(string elementName, BlogMLContent content) { WriteContent(elementName, content); }
/// <summary> /// Converts the blog export to BlogML /// </summary> public void Convert() { XDocument blogger = XDocument.Load(_bloggerExportPath); // extract basic information string blogTitle = blogger.Element(AtomNamespace + "feed").Element(AtomNamespace + "title").Value; DateTime blogUpdated = DateTime.Parse(blogger.Element(AtomNamespace + "feed").Element(AtomNamespace + "updated").Value).ToUniversalTime(); string authorName = blogger.Element(AtomNamespace + "feed").Element(AtomNamespace + "author").Element(AtomNamespace + "name").Value; string authorUri = blogger.Element(AtomNamespace + "feed").Element(AtomNamespace + "author").Element(AtomNamespace + "uri").Value; string authorEmail = blogger.Element(AtomNamespace + "feed").Element(AtomNamespace + "author").Element(AtomNamespace + "email").Value; // assume the updated date and then hunt backwards in time DateTime blogCreated = blogUpdated; LogMessage(string.Format(CultureInfo.CurrentCulture, Properties.Resources.Converter_MessageBlogTitle, blogTitle, blogUpdated)); LogMessage(string.Format(CultureInfo.CurrentCulture, Properties.Resources.Converter_MessageBlogAuthor, authorName, authorEmail, authorUri)); // parse ATOM entries var query = from entry in blogger.Descendants(AtomNamespace + "entry") select new { Id = entry.Element(AtomNamespace + "id").Value, Published = DateTime.Parse(entry.Element(AtomNamespace + "published").Value).ToUniversalTime(), Updated = DateTime.Parse(entry.Element(AtomNamespace + "updated").Value).ToUniversalTime(), Title = entry.Element(AtomNamespace + "title").Value, Content = entry.Element(AtomNamespace + "content").Value, AuthorName = entry.Element(AtomNamespace + "author").Element(AtomNamespace + "name").Value, AuthorUri = entry.Element(AtomNamespace + "author").Element(AtomNamespace + "uri") == null ? null : entry.Element(AtomNamespace + "author").Element(AtomNamespace + "uri").Value, AuthorEmail = entry.Element(AtomNamespace + "author").Element(AtomNamespace + "email") == null ? null : entry.Element(AtomNamespace + "author").Element(AtomNamespace + "email").Value, InReplyTo = entry.Element(ThrNamespace + "in-reply-to") == null ? null : entry.Element(ThrNamespace + "in-reply-to").Attribute("ref").Value, Categories = (from category in entry.Descendants(AtomNamespace + "category") select new { Scheme = category.Attribute("scheme").Value, Term = category.Attribute("term").Value, }), Links = (from link in entry.Descendants(AtomNamespace + "link") select new { Rel = link.Attribute("rel").Value, Type = link.Attribute("type").Value, Href = link.Attribute("href").Value, }), }; // separate out the different export categories from the ATOM entries Dictionary <string, BlogMLPost> posts = new Dictionary <string, BlogMLPost>(); List <CommentWithInReplyTo> comments = new List <CommentWithInReplyTo>(); List <BlogMLAuthor> authors = new List <BlogMLAuthor>(); List <BlogMLCategory> categories = new List <BlogMLCategory>(); NameValueCollection settings = new NameValueCollection(); string template = null; foreach (var q in query) { // update the blog created date as we find earlier entires if (q.Published < blogCreated) { blogCreated = q.Published; } // create a content holder BlogMLContent content = new BlogMLContent(); content.Text = q.Content; // find categories and the type of entry List <BlogMLCategoryReference> categoryRefs = new List <BlogMLCategoryReference>(); string entryKind = null; // get the type of entry and any post categories foreach (var c in q.Categories) { if (c.Scheme == "http://schemas.google.com/g/2005#kind") { entryKind = c.Term; } else if (c.Scheme == "http://www.blogger.com/atom/ns#") { BlogMLCategoryReference categoryRef = new BlogMLCategoryReference(); categoryRef.Ref = UpdateCategoriesGetRef(ref categories, c.Term, q.Published); categoryRefs.Add(categoryRef); } else { // we've found a category scheme we don't know about LogMessage(string.Format(CultureInfo.CurrentCulture, Properties.Resources.Converter_MessageUnexpectedCategoryScheme, c.Scheme)); } } // process entry based on the entry kind switch (entryKind) { case "http://schemas.google.com/blogger/2008/kind#template": template = q.Content; break; case "http://schemas.google.com/blogger/2008/kind#settings": LogMessage(string.Format(CultureInfo.CurrentCulture, Properties.Resources.Converter_ImportingSettings, q.Id, q.Content)); settings.Add(q.Id, q.Content); break; case "http://schemas.google.com/blogger/2008/kind#post": LogMessage(string.Format(CultureInfo.CurrentCulture, Properties.Resources.Converter_ImportingPost, q.Title)); // get a reference to the author of this entry BlogMLAuthorReference authorReference = new BlogMLAuthorReference(); authorReference.Ref = UpdateAuthorsGetRef(ref authors, q.AuthorName, q.AuthorEmail, q.Published); BlogMLPost post = new BlogMLPost(); post.Approved = true; post.Authors.Add(authorReference); if (categoryRefs.Count > 0) { post.Categories.AddRange(categoryRefs); } post.Content = content; post.DateCreated = q.Published; post.DateModified = q.Updated; post.HasExcerpt = false; post.ID = q.Id; post.PostType = BlogPostTypes.Normal; post.Title = q.Title; posts.Add(q.Id, post); break; case "http://schemas.google.com/blogger/2008/kind#comment": LogMessage(string.Format(CultureInfo.CurrentCulture, Properties.Resources.Converter_ImportingComment, q.Title)); BlogMLComment comment = new BlogMLComment(); comment.Approved = true; comment.Content = content; comment.DateCreated = q.Published; comment.DateModified = q.Updated; comment.ID = q.Id; comment.Title = q.Title; comment.UserEMail = q.AuthorEmail; comment.UserName = q.AuthorName; comment.UserUrl = q.AuthorUri; comments.Add(new CommentWithInReplyTo(comment, q.InReplyTo)); break; default: LogMessage(string.Format(CultureInfo.CurrentCulture, Properties.Resources.Converter_MessageUnexpectedEntryKind, entryKind)); break; } } // add comments to posts foreach (CommentWithInReplyTo comment in comments) { if (posts.ContainsKey(comment.InReplyTo)) { BlogMLPost post = posts[comment.InReplyTo]; LogMessage(string.Format(CultureInfo.CurrentCulture, Properties.Resources.Converter_AttachingComment, comment.Comment.Title, post.Title)); post.Comments.Add(comment.Comment); } else { LogMessage(string.Format(CultureInfo.CurrentCulture, Properties.Resources.Converter_OrphanedComment, comment.Comment.Title)); } } // build the blog LogMessage(Properties.Resources.Converter_BuildingBlogML); BlogMLBlog blog = new BlogMLBlog(); blog.Authors.AddRange(authors); blog.Categories.AddRange(categories); blog.DateCreated = blogCreated; blog.Posts.AddRange(posts.Values); blog.Title = blogTitle; // add blogger settings as extended properties foreach (string name in settings.Keys) { Pair <string, string> pair = new Pair <string, string>(); pair.Key = name; pair.Value = settings[name]; blog.ExtendedProperties.Add(pair); } // output BlogML LogMessage(string.Format(CultureInfo.CurrentCulture, Properties.Resources.Converter_WritingBlogML, _blogmlPath)); XmlWriterSettings writerSettings = new XmlWriterSettings(); writerSettings.CheckCharacters = true; writerSettings.CloseOutput = true; writerSettings.ConformanceLevel = ConformanceLevel.Document; writerSettings.Indent = true; using (XmlWriter writer = XmlWriter.Create(_blogmlPath, writerSettings)) { BlogMLSerializer.Serialize(writer, blog); } }