Esempio n. 1
0
        private void SavePostCustomFieldsToMetadata(Post post, WeblogPostMetadata meta)
        {
            if (post.CustomFields != null)
            {
                if (meta.CustomFields == null)
                {
                    meta.CustomFields = new Dictionary <string, CustomField>();
                }

                foreach (var cf in post.CustomFields)
                {
                    if (cf.Key == "mt_markdown" || cf.Key == "wp_post_thumbnail")
                    {
                        // These fields have specific handling, we don't want to persist their value,
                        // but we need to persist their ID.
                        meta.CustomFields[cf.Key] = new CustomField
                        {
                            Id  = cf.Id,
                            Key = cf.Key
                        };
                    }
                    else
                    {
                        meta.CustomFields[cf.Key] = cf;
                    }
                }
            }
        }
Esempio n. 2
0
        private void WebLogStart_Loaded(object sender, System.Windows.RoutedEventArgs e)
        {
            //Model.LoadWebLognames();

            var editor = Model.AppModel.ActiveEditor;

            if (editor == null)
            {
                return;
            }

            var markdown = editor.GetMarkdown();

            Model.ActivePostMetadata = WeblogPostMetadata.GetPostConfigFromMarkdown(markdown, Model.ActivePost, Model.ActiveWeblogInfo);

            Model.MetadataCustomFields =
                new ObservableCollection <CustomField>(
                    Model.ActivePostMetadata.CustomFields.Select(kv => kv.Value));

            var lastBlog = WeblogAddinConfiguration.Current.LastWeblogAccessed;

            if (string.IsNullOrEmpty(Model.ActivePostMetadata.WeblogName))
            {
                Model.ActivePostMetadata.WeblogName = lastBlog;
            }

            // Code bindings
            ComboWeblogType.ItemsSource = Enum.GetValues(typeof(WeblogTypes)).Cast <WeblogTypes>();

            // have to do this here otherwise MetadataCustomFields is not updating in model
            DataContext = Model;
        }
Esempio n. 3
0
        public string NewWeblogPost(WeblogPostMetadata meta)
        {
            if (meta == null)
            {
                meta = new WeblogPostMetadata()
                {
                    Title = "Post Title",
                };
            }


            if (string.IsNullOrEmpty(meta.WeblogName))
            {
                meta.WeblogName = "Name of registered blog to post to";
            }


            string post =
                $@"# {meta.Title}

{meta.MarkdownBody}

<!-- Post Configuration -->
<!--
```xml
<blogpost>
<title>{meta.Title}</title>
<abstract>
{meta.Abstract}
</abstract>
<categories>
{meta.Categories}
</categories>
<isDraft>{meta.IsDraft}</isDraft>
<featuredImage>{meta.FeaturedImageUrl}</featuredImage>
<keywords>
{meta.Keywords}
</keywords>
<weblogs>
<postid>{meta.PostId}</postid>
<weblog>
{meta.WeblogName}
</weblog>
</weblogs>
</blogpost>
```
-->
<!-- End Post Configuration -->
";

            if (WeblogAddinConfiguration.Current.AddFrontMatterToNewBlogPost)
            {
                post = String.Format(WeblogAddinConfiguration.Current.FrontMatterTemplate,
                                     meta.Title, DateTime.Now) +
                       post;
            }

            return(post);
        }
        /// <summary>
        /// Strips the Markdown Meta data from the message and populates
        /// the post structure with the meta data values.
        /// </summary>
        /// <param name="markdown"></param>
        /// <returns></returns>
        public WeblogPostMetadata GetPostConfigFromMarkdown(string markdown)
        {
            var meta = new WeblogPostMetadata()
            {
                RawMarkdownBody = markdown,
                MarkdownBody    = markdown
            };


            string config = StringUtils.ExtractString(markdown,
                                                      "<!-- Post Configuration -->",
                                                      "<!-- End Post Configuration -->",
                                                      caseSensitive: false, allowMissingEndDelimiter: true, returnDelimiters: true);

            if (string.IsNullOrEmpty(config))
            {
                return(meta);
            }

            // strip the config section
            meta.MarkdownBody = meta.MarkdownBody.Replace(config, "");


            // check for title in first line and remove it
            // since the body shouldn't render the title
            var lines = StringUtils.GetLines(markdown);

            if (lines.Length > 0 && lines[0].Trim().StartsWith("# "))
            {
                meta.MarkdownBody = meta.MarkdownBody.Replace(lines[0], "").Trim();
                meta.Title        = lines[0].Trim().Replace("# ", "");
            }


            if (string.IsNullOrEmpty(meta.Title))
            {
                meta.Title = StringUtils.ExtractString(config, "\n<title>", "\n</title>").Trim();
            }
            meta.Abstract   = StringUtils.ExtractString(config, "\n<abstract>", "\n</abstract>").Trim();
            meta.Keywords   = StringUtils.ExtractString(config, "\n<keywords>", "\n</keywords>").Trim();
            meta.Categories = StringUtils.ExtractString(config, "\n<categories>", "\n</categories>").Trim();
            meta.PostId     = StringUtils.ExtractString(config, "\n<postid>", "</postid>").Trim();
            meta.WeblogName = StringUtils.ExtractString(config, "\n<weblog>", "</weblog>").Trim();

            ActivePost.Title      = meta.Title;
            ActivePost.Categories = meta.Categories.Split(new [] { ',' }, StringSplitOptions.RemoveEmptyEntries);

            ActivePost.mt_excerpt  = meta.Abstract;
            ActivePost.mt_keywords = meta.Keywords;

            return(meta);
        }
Esempio n. 5
0
        public string NewWeblogPost(WeblogPostMetadata meta)
        {
            if (meta == null)
            {
                meta = new WeblogPostMetadata()
                {
                    Title = "Post Title",
                };
            }


            if (string.IsNullOrEmpty(meta.WeblogName))
            {
                meta.WeblogName = "Name of registered blog to post to";
            }

            return
                ($@"# {meta.Title}

{meta.MarkdownBody}

<!-- Post Configuration -->
<!--
```xml
<blogpost>
<title>{meta.Title}</title>
<abstract>
{meta.Abstract}
</abstract>
<categories>
{meta.Categories}
</categories>
<isDraft>{meta.IsDraft}</isDraft>
<featuredImage>{meta.FeaturedImageUrl}</featuredImage>
<keywords>
{meta.Keywords}
</keywords>
<weblogs>
<postid>{meta.PostId}</postid>
<weblog>
{meta.WeblogName}
</weblog>
</weblogs>
</blogpost>
```
-->
<!-- End Post Configuration -->
");
        }
Esempio n. 6
0
        /// <summary>
        /// This method sets the RawMarkdownBody
        /// </summary>
        /// <param name="meta"></param>
        /// <returns>Updated Markdown - also sets the RawMarkdownBody and MarkdownBody</returns>
        public string SetConfigInMarkdown(WeblogPostMetadata meta)
        {
            string markdown   = meta.RawMarkdownBody;
            string origConfig = StringUtils.ExtractString(markdown, "<!-- Post Configuration -->", "<!-- End Post Configuration -->", false, false, true);
            string newConfig  = $@"<!-- Post Configuration -->
<!--
```xml
<blogpost>
<title>{meta.Title}</title>
<abstract>
{meta.Abstract}
</abstract>
<categories>
{meta.Categories}
</categories>
<keywords>
{meta.Keywords}
</keywords>
<isDraft>{meta.IsDraft}</isDraft>
<featuredImage>{meta.FeaturedImageUrl}</featuredImage>
<weblogs>
<postid>{meta.PostId}</postid>
<weblog>
{meta.WeblogName}
</weblog>
</weblogs>
</blogpost>
```
-->
<!-- End Post Configuration -->";

            if (string.IsNullOrEmpty(origConfig))
            {
                markdown += "\r\n" + newConfig;
            }
            else
            {
                markdown = markdown.Replace(origConfig, newConfig);
            }

            meta.RawMarkdownBody = markdown;
            meta.MarkdownBody    = meta.RawMarkdownBody.Replace(newConfig, "");

            return(markdown);
        }
Esempio n. 7
0
        public string NewWeblogPost(WeblogPostMetadata meta)
        {
            if (meta == null)
            {
                meta = new WeblogPostMetadata()
                {
                    Title        = "Post Title",
                    MarkdownBody = string.Empty
                };
            }


            if (string.IsNullOrEmpty(meta.WeblogName))
            {
                meta.WeblogName = "Name of registered blog to post to";
            }

            bool hasFrontMatter = meta.MarkdownBody != null &&
                                  (meta.MarkdownBody.TrimStart().StartsWith("---\n") ||
                                   meta.MarkdownBody.TrimStart().StartsWith("---\r"));
            string post;

            if (hasFrontMatter)
            {
                post = meta.MarkdownBody;
            }
            else
            {
                post =
                    $@"# {meta.Title}

{meta.MarkdownBody}
";
            }
            meta.RawMarkdownBody = post;
            meta.MarkdownBody    = post;

            if (!hasFrontMatter)
            {
                post = meta.SetPostYaml();
            }

            return(post);
        }
Esempio n. 8
0
        public string NewWeblogPost(WeblogPostMetadata meta)
        {
            if (meta == null)
            {
                meta = new WeblogPostMetadata()
                {
                    Title = "Post Title",
                };
            }


            if (string.IsNullOrEmpty(meta.WeblogName))
            {
                meta.WeblogName = "Name of registered blog to post to";
            }


            string post =
                $@"# {meta.Title}

{meta.MarkdownBody}
";

            if (WeblogAddinConfiguration.Current.AddFrontMatterToNewBlogPost)
            {
                post = String.Format(WeblogAddinConfiguration.Current.FrontMatterTemplate,
                                     meta.Title, DateTime.Now) +
                       post;
            }
            else
            {
                meta.RawMarkdownBody = post;
                meta.MarkdownBody    = post;

                // Add Yaml data to post
                post = meta.SetPostYaml();
            }

            return(post);
        }
Esempio n. 9
0
        private void WebLogStart_Loaded(object sender, System.Windows.RoutedEventArgs e)
        {
            //Model.LoadWebLognames();

            var editor = Model.AppModel.ActiveEditor;

            if (editor == null)
            {
                return;
            }

            var markdown = editor.GetMarkdown();

            Model.ActivePostMetadata = WeblogPostMetadata.GetPostConfigFromMarkdown(markdown, Model.ActivePost, Model.ActiveWeblogInfo);

            var lastBlog = WeblogAddinConfiguration.Current.LastWeblogAccessed;

            if (string.IsNullOrEmpty(Model.ActivePostMetadata.WeblogName))
            {
                Model.ActivePostMetadata.WeblogName = lastBlog;
            }
        }
Esempio n. 10
0
        public string NewWeblogPost(WeblogPostMetadata meta)
        {
            if (meta == null)
            {
                meta = new WeblogPostMetadata()
                {
                    Title = "Post Title",
                };
            }

            if (string.IsNullOrEmpty(meta.WeblogName))
            {
                meta.WeblogName = "Name of registered blog to post to";
            }

            return
                ($@"# {meta.Title}



<!-- Post Configuration -->
<!--
```xml
<abstract>
</abstract>
<categories>
</categories>
<keywords>
</keywords>
<weblog>
{meta.WeblogName}
</weblog>
```
-->
<!-- End Post Configuration -->
");
        }
        /// <summary>
        /// Serializes a meta weblog post to YAML including extra fields.
        /// </summary>
        /// <param name="meta">MetaWebLogPostData instance or null which uses this object</param>
        /// <param name="addFrontMatterDashes">if true adds the leading and trailing Frontmatter dashes to the YAML</param>
        /// <returns></returns>
        public string SerializeToYaml(WeblogPostMetadata meta = null, bool addFrontMatterDashes = false)
        {
            if (meta == null)
            {
                meta = this;
            }

            var serializer = new SerializerBuilder()
                             .WithNamingConvention(CamelCaseNamingConvention.Instance)
                             .Build();

            // hide fields  if none are set
            var customFields = CustomFields;

            if (CustomFields != null && CustomFields.Count < 1)
            {
                CustomFields = null;
            }
            if (string.IsNullOrEmpty(PostId))
            {
                PostId = null;
            }

            string yaml = serializer.Serialize(this);

            if (meta.ExtraValues.Count > 0)
            {
                yaml = yaml.TrimEnd() + mmApp.NewLine + ExtraValuesToYaml(ExtraValues);
            }

            if (addFrontMatterDashes)
            {
                yaml = $"---{mmApp.NewLine}{yaml}---{mmApp.NewLine}";
            }

            return(yaml);
        }
Esempio n. 12
0
        public void CreateDownloadedPostOnDisk(Post post, string weblogName)
        {
            string filename = mmFileUtils.SafeFilename(post.Title);

            var folder = Path.Combine(WeblogAddinConfiguration.Current.PostsFolder,
                                      "Downloaded", weblogName,
                                      filename);

            if (!Directory.Exists(folder))
            {
                Directory.CreateDirectory(folder);
            }
            var outputFile = Path.Combine(folder, StringUtils.ToCamelCase(filename) + ".md");


            bool   isMarkdown    = false;
            string body          = post.Body;
            string featuredImage = null;

            if (post.CustomFields != null)
            {
                var cf = post.CustomFields.FirstOrDefault(custf => custf.Id == "mt_markdown");
                if (cf != null)
                {
                    body       = cf.Value;
                    isMarkdown = true;
                }

                cf = post.CustomFields.FirstOrDefault(custf => custf.Id == "wp_post_thumbnail");
                if (cf != null)
                {
                    featuredImage = cf.Value;
                }
            }
            if (!isMarkdown)
            {
                if (!string.IsNullOrEmpty(post.mt_text_more))
                {
                    // Wordpress ReadMore syntax - SERIOUSLY???
                    if (string.IsNullOrEmpty(post.mt_excerpt))
                    {
                        post.mt_excerpt = HtmlUtils.StripHtml(post.Body);
                    }

                    body = MarkdownUtilities.HtmlToMarkdown(body) +
                           "\n\n<!--more-->\n\n" +
                           MarkdownUtilities.HtmlToMarkdown(post.mt_text_more);
                }
                else
                {
                    body = MarkdownUtilities.HtmlToMarkdown(body);
                }
            }

            string categories = null;

            if (post.Categories != null && post.Categories.Length > 0)
            {
                categories = string.Join(",", post.Categories);
            }


            // Create the new post by creating a file with title preset
            var meta = new WeblogPostMetadata()
            {
                Title            = post.Title,
                MarkdownBody     = body,
                Categories       = categories,
                Keywords         = post.mt_keywords,
                Abstract         = post.mt_excerpt,
                PostId           = post.PostId.ToString(),
                WeblogName       = weblogName,
                FeaturedImageUrl = featuredImage
            };

            string newPostMarkdown = NewWeblogPost(meta);

            File.WriteAllText(outputFile, newPostMarkdown);

            mmApp.Configuration.LastFolder = Path.GetDirectoryName(outputFile);

            if (isMarkdown)
            {
                string html = post.Body;
                string path = mmApp.Configuration.LastFolder;

                // do this synchronously so images show up :-<
                ShowStatus("Downloading post images...");
                SaveMarkdownImages(html, path);
                ShowStatus("Post download complete.", 5000);

                //new Action<string,string>(SaveImages).BeginInvoke(html,path,null, null);
            }

            Model.Window.OpenTab(outputFile);
        }
Esempio n. 13
0
        /// <summary>
        /// Strips the Markdown Meta data from the message and populates
        /// the post structure with the meta data values.
        /// </summary>
        /// <param name="markdown">The raw markdown document with YAML header (optional)</param>
        /// <param name="post">Optional empty <seealso cref="Post"/> object that is filled with the meta data in.</param>
        public static WeblogPostMetadata GetPostYamlConfigFromMarkdown(string markdown, Post post = null)
        {
            var meta = new WeblogPostMetadata()
            {
                RawMarkdownBody = markdown,
                MarkdownBody    = markdown,
                WeblogName      = WeblogAddinConfiguration.Current.LastWeblogAccessed,
                CustomFields    = new Dictionary <string, CustomField>()
            };


            if (string.IsNullOrEmpty(markdown))
            {
                return(meta);
            }

            markdown = markdown.Trim();

            if (!markdown.StartsWith("---\n") && !markdown.StartsWith("---\r"))
            {
                return(meta);
            }



            // YAML with --- so we can replace
            string extractedYaml = MarkdownUtilities.ExtractFrontMatter(markdown, false);

            if (string.IsNullOrEmpty(extractedYaml))
            {
                return(meta);
            }

            // just the YAML text
            var yaml = extractedYaml.Trim('-', ' ', '\r', '\n');

            var input = new StringReader(yaml);

            var deserializer = new DeserializerBuilder()
                               .IgnoreUnmatchedProperties()
                               .WithNamingConvention(new CamelCaseNamingConvention())
                               .Build();

            WeblogPostMetadata yamlMeta = null;

            try
            {
                yamlMeta = deserializer.Deserialize <WeblogPostMetadata>(input);
            }
            catch
            {
                return(meta);
            }

            if (yamlMeta == null)
            {
                return(meta);
            }

            if (meta.CustomFields == null)
            {
                meta.CustomFields = new Dictionary <string, CustomField>();
            }

            meta = yamlMeta;

            meta.MarkdownBody    = markdown.Replace(extractedYaml, "");
            meta.RawMarkdownBody = markdown;
            meta.YamlFrontMatter = yaml;
            if (string.IsNullOrEmpty(meta.WeblogName))
            {
                meta.WeblogName = WeblogAddinConfiguration.Current.LastWeblogAccessed;
            }


            if (post != null)
            {
                post.Title = meta.Title?.Trim();
                if (!string.IsNullOrEmpty(meta.Categories))
                {
                    post.Categories = meta.Categories.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                    for (int i = 0; i < post.Categories.Length; i++)
                    {
                        post.Categories[i] = post.Categories[i].Trim();
                    }
                }

                if (!string.IsNullOrEmpty(meta.Keywords))
                {
                    post.Tags = meta.Keywords.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                    for (int i = 0; i < post.Tags.Length; i++)
                    {
                        post.Tags[i] = post.Tags[i].Trim();
                    }
                }

                post.Permalink   = meta.Permalink;
                post.DateCreated = meta.PostDate;
                if (post.DateCreated < new DateTime(2000, 1, 1))
                {
                    post.DateCreated = DateTime.Now;
                }

                post.mt_excerpt  = meta.Abstract;
                post.mt_keywords = meta.Keywords;

                if (meta.CustomFields != null)
                {
                    post.CustomFields = meta.CustomFields.Values.ToArray();
                }
            }

            return(meta);
        }
Esempio n. 14
0
        /// <summary>
        /// Strips the Markdown Meta data from the message and populates
        /// the post structure with the meta data values.
        /// </summary>
        /// <param name="markdown"></param>
        /// <returns></returns>
        public WeblogPostMetadata GetPostConfigFromMarkdown(string markdown)
        {
            var meta = new WeblogPostMetadata()
            {
                RawMarkdownBody = markdown,
                MarkdownBody    = markdown,
                WeblogName      = WeblogAddinConfiguration.Current.LastWeblogAccessed
            };

            // check for title in first line and remove it
            // since the body shouldn't render the title
            var lines = StringUtils.GetLines(markdown);

            if (lines.Length > 0 && lines[0].StartsWith("# "))
            {
                meta.MarkdownBody = meta.MarkdownBody.Replace(lines[0], "").Trim();
                meta.Title        = lines[0].Trim().Substring(2);
            }
            else if (lines.Length > 2 && lines[0] == "---" && meta.MarkdownBody.Contains("layout: post"))
            {
                var block = mmFileUtils.ExtractString(meta.MarkdownBody, "---", "---", returnDelimiters: true);
                if (!string.IsNullOrEmpty(block))
                {
                    meta.Title        = StringUtils.ExtractString(block, "title: ", "\n").Trim();
                    meta.MarkdownBody = meta.MarkdownBody.Replace(block, "").Trim();
                }
            }


            string config = StringUtils.ExtractString(markdown,
                                                      "<!-- Post Configuration -->",
                                                      "<!-- End Post Configuration -->",
                                                      caseSensitive: false, allowMissingEndDelimiter: true, returnDelimiters: true);

            if (string.IsNullOrEmpty(config))
            {
                return(meta);
            }

            // strip the config section
            meta.MarkdownBody = meta.MarkdownBody.Replace(config, "");


            string title = StringUtils.ExtractString(config, "\n<title>", "</title>").Trim();

            if (string.IsNullOrEmpty(meta.Title))
            {
                meta.Title = title;
            }
            meta.Abstract   = StringUtils.ExtractString(config, "\n<abstract>", "\n</abstract>").Trim();
            meta.Keywords   = StringUtils.ExtractString(config, "\n<keywords>", "\n</keywords>").Trim();
            meta.Categories = StringUtils.ExtractString(config, "\n<categories>", "\n</categories>").Trim();
            meta.PostId     = StringUtils.ExtractString(config, "\n<postid>", "</postid>").Trim();
            string strIsDraft = StringUtils.ExtractString(config, "\n<isDraft>", "</isDraft>").Trim();

            if (strIsDraft != null && strIsDraft == "True")
            {
                meta.IsDraft = true;
            }
            string weblogName = StringUtils.ExtractString(config, "\n<weblog>", "</weblog>").Trim();

            if (!string.IsNullOrEmpty(weblogName))
            {
                meta.WeblogName = weblogName;
            }

            string featuredImageUrl = StringUtils.ExtractString(config, "\n<featuredImage>", "</featuredImage>");

            if (!string.IsNullOrEmpty(featuredImageUrl))
            {
                meta.FeaturedImageUrl = featuredImageUrl.Trim();
            }

            ActivePost.Title      = meta.Title;
            ActivePost.Categories = meta.Categories.Split(new [] { ',' }, StringSplitOptions.RemoveEmptyEntries);

            ActivePost.mt_excerpt  = meta.Abstract;
            ActivePost.mt_keywords = meta.Keywords;

            return(meta);
        }
        /// <summary>
        /// Parses a YAML block of text into a WeblogPostMetaData structure.
        /// Any fields that don't match the meta structure are parsed into
        /// ExtraFields
        /// </summary>
        /// <param name="yaml"></param>
        /// <returns></returns>
        public static WeblogPostMetadata ParseFromYaml(string yaml)
        {
            var parser = new YamlStream();

            try
            {
                parser.Load(new StringReader(yaml));
            }
            catch
            {
                return(null);
            }

            var meta = new WeblogPostMetadata();

            var root = (YamlMappingNode)parser.Documents[0].RootNode;

            foreach (var entry in root.Children)
            {
                var key = entry.Key?.ToString();

                if (string.IsNullOrEmpty(key))
                {
                    continue;
                }
                if (key.Equals("Title", StringComparison.OrdinalIgnoreCase))
                {
                    meta.Title = entry.Value?.ToString();
                }
                else if (key.Equals("Abstract", StringComparison.OrdinalIgnoreCase))
                {
                    meta.Abstract = entry.Value?.ToString();
                }
                else if (key.Equals("PostId", StringComparison.OrdinalIgnoreCase))
                {
                    meta.PostId = entry.Value?.ToString();
                }
                else if (key.Equals("PostStatus", StringComparison.OrdinalIgnoreCase))
                {
                    meta.PostStatus = entry.Value?.ToString();
                }

                else if (key.Equals("PostDate", StringComparison.OrdinalIgnoreCase))
                {
                    if (!DateTime.TryParse(entry.Value.ToString(), out DateTime dt))
                    {
                        meta.PostDate = DateTime.UtcNow;
                    }
                    else
                    {
                        meta.PostDate = dt;
                    }
                }
                else if (key.Equals("WeblogName", StringComparison.OrdinalIgnoreCase))
                {
                    meta.WeblogName = entry.Value?.ToString();
                }
                else if (key.Equals("Keywords", StringComparison.OrdinalIgnoreCase))
                {
                    meta.Keywords = entry.Value?.ToString();
                }
                else if (key.Equals("Categories", StringComparison.OrdinalIgnoreCase))
                {
                    meta.Categories = entry.Value?.ToString();
                }
                else if (key.Equals("PermaLink", StringComparison.OrdinalIgnoreCase))
                {
                    meta.Permalink = entry.Value?.ToString();
                }
                else if (key.Equals("FeaturedImageUrl", StringComparison.OrdinalIgnoreCase))
                {
                    meta.FeaturedImageUrl = entry.Value?.ToString();
                }
                else if (key.Equals("FeaturedImageId", StringComparison.OrdinalIgnoreCase))
                {
                    meta.FeaturedImageId = entry.Value?.ToString();
                }
                else if (key.Equals("DontInferFeaturedImage", StringComparison.OrdinalIgnoreCase))
                {
                    bool.TryParse(entry.Value.ToString(), out bool val);
                    meta.DontInferFeaturedImage = val;
                }
                else if (key.Equals("DontStripH1Header", StringComparison.OrdinalIgnoreCase))
                {
                    bool.TryParse(entry.Value.ToString(), out bool val);
                    meta.DontStripH1Header = val;
                }
                else if (key.Equals("CustomFields", StringComparison.OrdinalIgnoreCase))
                {
                    YamlMappingNode fields;
                    try
                    {
                        fields = (YamlMappingNode)entry.Value;
                    }
                    catch
                    {
                        continue; // empty or missing
                    }

                    foreach (var item in fields.Children)
                    {
                        string k = item.Key.ToString();
                        string v = ((YamlMappingNode)item.Value).Children["value"].ToString();
                        meta.CustomFields.Add(k, new CustomField {
                            Value = v, Key = k
                        });
                    }
                }
                else
                {
                    meta.ExtraValues.Add(entry.Key.ToString(), entry.Value?.ToString());
                }
            }

            return(meta);
        }
Esempio n. 16
0
        /// <summary>
        /// Parses each of the images in the document and posts them to the server.
        /// Updates the HTML with the returned Image Urls
        /// </summary>
        /// <param name="html">HTML that contains images</param>
        /// <param name="filename">image file name</param>
        /// <param name="wrapper">blog wrapper instance that sends</param>
        /// <param name="metaData">metadata containing post info</param>
        /// <returns>update HTML string for the document with updated images</returns>
        private string SendImages(string html, string filename, MetaWeblogWrapper wrapper, WeblogPostMetadata metaData)
        {
            var basePath = Path.GetDirectoryName(filename);
            var baseName = Path.GetFileName(basePath);

            var doc = new HtmlDocument();

            doc.LoadHtml(html);
            try
            {
                // send up normalized path images as separate media items
                var images = doc.DocumentNode.SelectNodes("//img");
                if (images != null)
                {
                    foreach (HtmlNode img in images)
                    {
                        string imgFile = img.Attributes["src"]?.Value as string;
                        if (imgFile == null)
                        {
                            continue;
                        }

                        if (!imgFile.StartsWith("http://") && !imgFile.StartsWith("https://"))
                        {
                            imgFile = Path.Combine(basePath, imgFile.Replace("/", "\\"));
                            if (File.Exists(imgFile))
                            {
                                var media = new MediaObject()
                                {
                                    Type = "application/image",
                                    Bits = File.ReadAllBytes(imgFile),
                                    Name = baseName + "/" + Path.GetFileName(imgFile)
                                };
                                var mediaResult = wrapper.NewMediaObject(media);
                                img.Attributes["src"].Value = mediaResult.URL;

                                // use first image as featured image
                                if (string.IsNullOrEmpty(metaData.FeaturedImageUrl))
                                {
                                    metaData.FeaturedImageUrl = mediaResult.URL;
                                }
                            }
                        }
                    }

                    html = doc.DocumentNode.OuterHtml;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error posting images to Weblog: " + ex.Message,
                                mmApp.ApplicationName,
                                MessageBoxButton.OK,
                                MessageBoxImage.Exclamation);
                mmApp.Log(ex);
                return(null);
            }

            return(html);
        }
Esempio n. 17
0
        /// <summary>
        /// Strips the Markdown Meta data from the message and populates
        /// the post structure with the meta data values.
        /// </summary>
        /// <param name="markdown"></param>
        /// <param name="post"></param>
        /// <param name="weblogInfo"></param>
        public static WeblogPostMetadata GetPostYamlConfigFromMarkdown(string markdown, Post post, WeblogInfo weblogInfo)
        {
            var meta = new WeblogPostMetadata()
            {
                RawMarkdownBody = markdown,
                MarkdownBody    = markdown,
                WeblogName      = WeblogAddinConfiguration.Current.LastWeblogAccessed,
                CustomFields    = new Dictionary <string, CustomField>()
            };


            if (string.IsNullOrEmpty(markdown))
            {
                return(meta);
            }

            markdown = markdown.Trim();

            if (!markdown.StartsWith("---\n") && !markdown.StartsWith("---\r"))
            {
                return(meta);
            }

            string extractedYaml = null;
            //var match = YamlExtractionRegex.Match(markdown);
            var match = YamlExtractionRegex.Match(markdown);

            if (match.Success)
            {
                extractedYaml = match.Value;
            }

            //var extractedYaml = StringUtils.ExtractString(markdown.TrimStart(), "---\n", "\n---\n",returnDelimiters: true);
            if (string.IsNullOrEmpty(extractedYaml))
            {
                return(meta);
            }

            var yaml  = StringUtils.ExtractString(markdown, "---", "\n---", returnDelimiters: false).Trim();
            var input = new StringReader(yaml);

            var deserializer = new DeserializerBuilder()
                               .IgnoreUnmatchedProperties()
                               .WithNamingConvention(new CamelCaseNamingConvention())
                               .Build();

            WeblogPostMetadata yamlMeta = null;

            try
            {
                yamlMeta = deserializer.Deserialize <WeblogPostMetadata>(input);
            }
            catch
            {
                return(meta);
            }

            if (yamlMeta == null)
            {
                return(meta);
            }

            if (meta.CustomFields == null)
            {
                meta.CustomFields = new Dictionary <string, CustomField>();
            }

            meta = yamlMeta;
            meta.MarkdownBody    = markdown.Replace(extractedYaml, "");
            meta.RawMarkdownBody = markdown;


            post.Title = meta.Title;
            if (!string.IsNullOrEmpty(meta.Categories))
            {
                post.Categories = meta.Categories.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            }

            if (!string.IsNullOrEmpty(meta.Keywords))
            {
                post.Tags = meta.Keywords.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            }

            post.mt_excerpt  = meta.Abstract;
            post.mt_keywords = meta.Keywords;

            if (meta.CustomFields != null)
            {
                post.CustomFields = meta.CustomFields.Values.ToArray();
            }

            return(meta);
        }
Esempio n. 18
0
        /// <summary>
        /// High level method that sends posts to the Weblog
        ///
        /// </summary>
        /// <returns></returns>
        public bool SendPost(WeblogInfo weblogInfo, bool sendAsDraft = false)
        {
            var editor = Model.ActiveEditor;

            if (editor == null)
            {
                return(false);
            }

            var doc = editor.MarkdownDocument;

            WeblogModel.ActivePost = new Post()
            {
                DateCreated = DateTime.Now
            };

            // start by retrieving the current Markdown from the editor
            string markdown = editor.GetMarkdown();



            // Retrieve Meta data from post and clean up the raw markdown
            // so we render without the config data
            var meta = WeblogPostMetadata.GetPostConfigFromMarkdown(markdown, WeblogModel.ActivePost, weblogInfo);

            string html = doc.RenderHtml(meta.MarkdownBody, WeblogAddinConfiguration.Current.RenderLinksOpenExternal);

            WeblogModel.ActivePost.Body       = html;
            WeblogModel.ActivePost.PostId     = meta.PostId;
            WeblogModel.ActivePost.PostStatus = meta.PostStatus;

            // Custom Field Processing:
            // Add custom fields from existing post
            // then add or update our custom fields
            var customFields = new Dictionary <string, CustomField>();

            // load existing custom fields from post online if possible
            if (!string.IsNullOrEmpty(meta.PostId))
            {
                var existingPost = GetPost(meta.PostId, weblogInfo);
                if (existingPost != null && meta.CustomFields != null && existingPost.CustomFields != null)
                {
                    customFields = existingPost.CustomFields
                                   .ToDictionary(cf => cf.Key, cf => cf);
                }
            }
            // add custom fields from Weblog configuration
            if (weblogInfo.CustomFields != null)
            {
                foreach (var kvp in weblogInfo.CustomFields)
                {
                    if (!customFields.ContainsKey(kvp.Key))
                    {
                        AddOrUpdateCustomField(customFields, kvp.Key, kvp.Value);
                    }
                }
            }
            // add custom fields from Meta data
            if (meta.CustomFields != null)
            {
                foreach (var kvp in meta.CustomFields)
                {
                    AddOrUpdateCustomField(customFields, kvp.Key, kvp.Value.Value);
                }
            }
            if (!string.IsNullOrEmpty(markdown))
            {
                AddOrUpdateCustomField(customFields, "mt_markdown", markdown);
            }

            WeblogModel.ActivePost.CustomFields = customFields.Values.ToArray();

            var config = WeblogAddinConfiguration.Current;

            var kv = config.Weblogs.FirstOrDefault(kvl => kvl.Value.Name == meta.WeblogName);

            if (kv.Equals(default(KeyValuePair <string, WeblogInfo>)))
            {
                MessageBox.Show("Invalid Weblog configuration selected.",
                                "Weblog Posting Failed",
                                MessageBoxButton.OK, MessageBoxImage.Exclamation);
                return(false);
            }
            weblogInfo = kv.Value;

            var type = weblogInfo.Type;

            if (type == WeblogTypes.Unknown)
            {
                type = weblogInfo.Type;
            }


            string basePath = Path.GetDirectoryName(doc.Filename);
            string postUrl  = null;

            if (type == WeblogTypes.MetaWeblogApi || type == WeblogTypes.Wordpress)
            {
                MetaWebLogWordpressApiClient client;
                client = new MetaWebLogWordpressApiClient(weblogInfo);

                // if values are already configured don't overwrite them again
                client.DontInferFeaturedImage = meta.DontInferFeaturedImage;
                client.FeaturedImageUrl       = meta.FeaturedImageUrl;
                client.FeatureImageId         = meta.FeaturedImageId;

                if (!client.PublishCompletePost(WeblogModel.ActivePost, basePath,
                                                sendAsDraft, markdown))
                {
                    mmApp.Log($"Error sending post to Weblog at {weblogInfo.ApiUrl}: " + client.ErrorMessage);
                    MessageBox.Show("Error sending post to Weblog: " + client.ErrorMessage,
                                    mmApp.ApplicationName,
                                    MessageBoxButton.OK,
                                    MessageBoxImage.Exclamation);
                    return(false);
                }

                var post = client.GetPost(WeblogModel.ActivePost.PostId);
                if (post != null)
                {
                    postUrl = post.Url;
                }
            }
            if (type == WeblogTypes.Medium)
            {
                var client = new MediumApiClient(weblogInfo);
                var result = client.PublishCompletePost(WeblogModel.ActivePost, basePath, sendAsDraft);
                if (result == null)
                {
                    mmApp.Log($"Error sending post to Weblog at {weblogInfo.ApiUrl}: " + client.ErrorMessage);
                    MessageBox.Show($"Error sending post to Weblog: " + client.ErrorMessage,
                                    mmApp.ApplicationName,
                                    MessageBoxButton.OK,
                                    MessageBoxImage.Exclamation);
                    return(false);
                }

                // this is null
                postUrl = client.PostUrl;
            }

            meta.PostId = WeblogModel.ActivePost.PostId.ToString();

            // retrieve the raw editor markdown
            markdown             = editor.GetMarkdown();
            meta.RawMarkdownBody = markdown;

            // add the meta configuration to it
            markdown = meta.SetPostYaml();

            // write it back out to editor
            editor.SetMarkdown(markdown, updateDirtyFlag: true);

            try
            {
                // preview post
                if (!string.IsNullOrEmpty(weblogInfo.PreviewUrl))
                {
                    var url = weblogInfo.PreviewUrl.Replace("{0}", WeblogModel.ActivePost.PostId.ToString());
                    ShellUtils.GoUrl(url);
                }
                else
                {
                    if (!string.IsNullOrEmpty(postUrl))
                    {
                        ShellUtils.GoUrl(postUrl);
                    }
                    else
                    {
                        ShellUtils.GoUrl(new Uri(weblogInfo.ApiUrl).GetLeftPart(UriPartial.Authority));
                    }
                }
            }
            catch
            {
                mmApp.Log("Failed to display Weblog Url after posting: " +
                          weblogInfo.PreviewUrl ?? postUrl ?? weblogInfo.ApiUrl);
            }

            return(true);
        }
Esempio n. 19
0
        /// <summary>
        /// Strips the Markdown Meta data from the message and populates
        /// the post structure with the meta data values.
        /// </summary>
        /// <param name="markdown"></param>
        /// <param name="post"></param>
        /// <param name="weblogInfo"></param>
        /// <returns></returns>
        public static WeblogPostMetadata GetPostConfigFromMarkdown(string markdown, Post post, WeblogInfo weblogInfo)
        {
            var meta = new WeblogPostMetadata()
            {
                RawMarkdownBody = markdown,
                MarkdownBody    = markdown,
                WeblogName      = WeblogAddinConfiguration.Current.LastWeblogAccessed,
                CustomFields    = new Dictionary <string, CustomField>()
            };

            // check for title in first line and remove it
            // since the body shouldn't render the title
            var lines = StringUtils.GetLines(markdown, 40);

            if (lines.Length > 2 && lines[0] == "---")
            {
                var block = mmFileUtils.ExtractString(meta.MarkdownBody, "---", "\n---", returnDelimiters: true);
                if (!string.IsNullOrEmpty(block))
                {
                    meta = WeblogPostMetadata.GetPostYamlConfigFromMarkdown(markdown, post, weblogInfo);
                    meta.RawMarkdownBody = markdown;
                    if (string.IsNullOrEmpty(meta.WeblogName))
                    {
                        meta.WeblogName = WeblogAddinConfiguration.Current.LastWeblogAccessed;
                    }

                    meta.MarkdownBody = meta.MarkdownBody.Replace(block, "").Trim();

                    // update to what's left
                    lines = StringUtils.GetLines(meta.MarkdownBody, 10);
                }
            }
            if (lines.Length > 0 && lines[0].StartsWith("# "))
            {
                if (!meta.DontStripH1Header && weblogInfo.Type != WeblogTypes.Medium) // medium wants the header in the text
                {
                    meta.MarkdownBody = meta.MarkdownBody.Replace(lines[0], "").Trim();
                }

                if (string.IsNullOrEmpty(meta.Title))
                {
                    meta.Title = lines[0].Trim().Substring(2);
                }
            }

            string config = StringUtils.ExtractString(markdown,
                                                      "<!-- Post Configuration -->",
                                                      "<!-- End Post Configuration -->",
                                                      caseSensitive: false, allowMissingEndDelimiter: true, returnDelimiters: true);

            if (string.IsNullOrEmpty(config))
            {
                return(meta);
            }

            // strip the config section
            meta.MarkdownBody = meta.MarkdownBody.Replace(config, "");


            string title = StringUtils.ExtractString(config, "\n<title>", "</title>").Trim();

            if (string.IsNullOrEmpty(meta.Title))
            {
                meta.Title = title;
            }
            meta.Abstract   = StringUtils.ExtractString(config, "\n<abstract>", "\n</abstract>").Trim();
            meta.Keywords   = StringUtils.ExtractString(config, "\n<keywords>", "\n</keywords>").Trim();
            meta.Categories = StringUtils.ExtractString(config, "\n<categories>", "\n</categories>").Trim();
            meta.PostId     = StringUtils.ExtractString(config, "\n<postid>", "</postid>").Trim();
            string strIsDraft = StringUtils.ExtractString(config, "\n<isDraft>", "</isDraft>").Trim();

            if (strIsDraft != null && strIsDraft == "True")
            {
                meta.PostStatus = "draft";
            }
            string weblogName = StringUtils.ExtractString(config, "\n<weblog>", "</weblog>").Trim();

            if (!string.IsNullOrEmpty(weblogName))
            {
                meta.WeblogName = weblogName;
            }

            string inferFeaturedImage = StringUtils.ExtractString(config, "\n<inferFeaturedImage>", "</inferFeaturedImage>");

            if (!string.IsNullOrEmpty(inferFeaturedImage))
            {
                meta.DontInferFeaturedImage = inferFeaturedImage != "False" && inferFeaturedImage != "false";
            }

            string featuredImageUrl = StringUtils.ExtractString(config, "\n<featuredImage>", "</featuredImage>");

            if (!string.IsNullOrEmpty(featuredImageUrl))
            {
                meta.FeaturedImageUrl = featuredImageUrl.Trim();
            }

            string featuredImageId = StringUtils.ExtractString(config, "\n<featuredImageId>", "</featuredImageId>");

            if (!string.IsNullOrEmpty(featuredImageId))
            {
                meta.FeaturedImageId = featuredImageId.Trim();
            }


            string customFieldsString = StringUtils.ExtractString(config, "\n<customFields>", "</customFields>", returnDelimiters: true);

            if (!string.IsNullOrEmpty(customFieldsString))
            {
                try
                {
                    var dom = new XmlDocument();
                    dom.LoadXml(customFieldsString);

                    foreach (XmlNode child in dom.DocumentElement.ChildNodes)
                    {
                        if (child.NodeType == XmlNodeType.Element)
                        {
                            var    key   = child.FirstChild.InnerText;
                            var    value = child.ChildNodes[1].InnerText;
                            string id    = null;
                            if (child.ChildNodes.Count > 2)
                            {
                                id = child.ChildNodes[2].InnerText;
                            }

                            meta.CustomFields.Add(key, new CustomField {
                                Key = key, Value = value, Id = id
                            });
                        }
                    }
                }
                catch { }
            }

            post.Title      = meta.Title;
            post.Categories = meta.Categories.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            post.Tags       = meta.Keywords.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

            post.mt_excerpt  = meta.Abstract;
            post.mt_keywords = meta.Keywords;

            return(meta);
        }
Esempio n. 20
0
        /// <summary>
        /// This method sets the RawMarkdownBody
        /// </summary>
        /// <param name="meta"></param>
        /// <returns>Updated Markdown - also sets the RawMarkdownBody and MarkdownBody</returns>
        public string SetConfigInMarkdown(WeblogPostMetadata meta)
        {
            string markdown = meta.RawMarkdownBody;


            string customFields = null;

            if (meta.CustomFields != null && meta.CustomFields.Count > 0)
            {
                StringBuilder sb = new StringBuilder();
                sb.AppendLine();
                sb.AppendLine("<customFields>");
                foreach (var cf in meta.CustomFields)
                {
                    sb.AppendLine("\t<customField>");
                    sb.AppendLine($"\t\t<key>{cf.Key}</key>");
                    sb.AppendLine($"\t\t<value>{System.Net.WebUtility.HtmlEncode(cf.Value)}</value>");
                    sb.AppendLine("\t</customField>");
                }
                sb.AppendLine("</customFields>");
                customFields = sb.ToString();
            }

            string origConfig = StringUtils.ExtractString(markdown, "<!-- Post Configuration -->", "<!-- End Post Configuration -->", false, false, true);
            string newConfig  = $@"<!-- Post Configuration -->
<!--
```xml
<blogpost>
<title>{meta.Title}</title>
<abstract>
{meta.Abstract}
</abstract>
<categories>
{meta.Categories}
</categories>
<keywords>
{meta.Keywords}
</keywords>
<isDraft>{meta.IsDraft}</isDraft>
<featuredImage>{meta.FeaturedImageUrl}</featuredImage>{customFields}
<weblogs>
<postid>{meta.PostId}</postid>
<weblog>
{meta.WeblogName}
</weblog>
</weblogs>
</blogpost>
```
-->
<!-- End Post Configuration -->";

            if (string.IsNullOrEmpty(origConfig))
            {
                markdown += "\r\n" + newConfig;
            }
            else
            {
                markdown = markdown.Replace(origConfig, newConfig);
            }

            meta.RawMarkdownBody = markdown;
            meta.MarkdownBody    = meta.RawMarkdownBody.Replace(newConfig, "");

            return(markdown);
        }