string IMetaWeblog.AddPost(string blogid, string username, string password, MetaWeblogPost post, bool publish)
        {
            var user = ValidateUser(username, password);

            var node = BlogRoot().Children("ArticulateArchive").FirstOrDefault();

            if (node == null)
            {
                throw new XmlRpcFaultException(0, "No Articulate Archive node found");
            }

            var content = _applicationContext.Services.ContentService.CreateContent(
                post.Title, node.Id, "ArticulateRichText", user.Id);

            var extractFirstImageAsProperty = true;

            if (node.HasProperty("extractFirstImage"))
            {
                extractFirstImageAsProperty = node.GetPropertyValue <bool>("extractFirstImage");
            }

            AddOrUpdateContent(content, post, user, publish, extractFirstImageAsProperty);

            return(content.Id.ToString(CultureInfo.InvariantCulture));
        }
        string IMetaWeblog.AddPost(string blogid, string username, string password, MetaWeblogPost post, bool publish)
        {
            var user = ValidateUser(username, password);

            var root = BlogRoot();

            var node = root.ChildrenOfType(ArticulateConstants.ArticulateArchiveContentTypeAlias).FirstOrDefault();

            if (node == null)
            {
                throw new XmlRpcFaultException(0, "No Articulate Archive node found");
            }

            var contentType = _contentTypeService.Get("ArticulateRichText");

            if (contentType == null)
            {
                throw new InvalidOperationException("No content type found with alias 'ArticulateRichText'");
            }

            var content = _contentService.CreateWithInvariantOrDefaultCultureName(
                post.Title, node.Id, contentType, _localizationService, user.Id);

            var extractFirstImageAsProperty = false;

            if (root.HasProperty("extractFirstImage"))
            {
                extractFirstImageAsProperty = root.Value <bool>("extractFirstImage");
            }

            AddOrUpdateContent(content, contentType, post, user, publish, extractFirstImageAsProperty);

            return(content.Id.ToString(CultureInfo.InvariantCulture));
        }
        string IMetaWeblog.AddPost(string blogid, string username, string password, MetaWeblogPost post, bool publish)
        {
            var user = ValidateUser(username, password);

            var node = BlogRoot().Children(x => x.DocumentTypeAlias.InvariantEquals("ArticulateArchive")).FirstOrDefault();

            if (node == null)
            {
                throw new XmlRpcFaultException(0, "No Articulate Archive node found");
            }

            var content = _applicationContext.Services.ContentService.CreateContent(
                post.Title, node.Id, "ArticulateRichText", user.Id);

            AddOrUpdateContent(content, post, user, publish);

            return(content.Id.ToString(CultureInfo.InvariantCulture));
        }
        bool IMetaWeblog.UpdatePost(string postid, string username, string password, MetaWeblogPost post, bool publish)
        {
            var user = ValidateUser(username, password);

            var asInt = postid.TryConvertTo <int>();

            if (!asInt)
            {
                return(false);
            }

            //first see if it's published
            var content = _contentService.GetById(asInt.Result);

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

            var node = BlogRoot().ChildrenOfType(ArticulateConstants.ArticulateArchiveContentTypeAlias).FirstOrDefault();

            if (node == null)
            {
                throw new XmlRpcFaultException(0, "No Articulate Archive node found");
            }

            var contentType = _contentTypeService.Get(content.ContentTypeId);

            if (contentType == null)
            {
                throw new InvalidOperationException($"No content type found with id '{content.ContentTypeId}'");
            }

            var extractFirstImageAsProperty = true;

            if (node.HasProperty("extractFirstImage"))
            {
                extractFirstImageAsProperty = node.Value <bool>("extractFirstImage");
            }

            AddOrUpdateContent(content, contentType, post, user, publish, extractFirstImageAsProperty);

            return(true);
        }
        private void AddOrUpdateContent(IContent content, MetaWeblogPost post, IUser user, bool publish)
        {
            content.Name = post.Title;
            content.SetValue("author", user.Name);
            if (content.HasProperty("richText"))
            {
                content.SetValue("richText", post.Content);
            }
            if (!post.Slug.IsNullOrWhiteSpace())
            {
                content.SetValue("umbracoUrlName", post.Slug);
            }
            if (!post.Excerpt.IsNullOrWhiteSpace())
            {
                content.SetValue("excerpt", post.Excerpt);
            }
            if (post.AllowComments == 1)
            {
                content.SetValue("enableComments", 1);
            }
            else if (post.AllowComments == 2)
            {
                content.SetValue("enableComments", 0);
            }
            content.SetTags("categories", post.Categories, true, "ArticulateCategories");
            var tags = post.Tags.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Distinct().ToArray();

            content.SetTags("tags", tags, true, "ArticulateTags");

            if (publish)
            {
                if (post.CreateDate != DateTime.MinValue)
                {
                    content.SetValue("publishedDate", post.CreateDate);
                }

                _applicationContext.Services.ContentService.SaveAndPublishWithStatus(content, user.Id);
            }
            else
            {
                _applicationContext.Services.ContentService.Save(content, user.Id);
            }
        }
        bool IMetaWeblog.UpdatePost(string postid, string username, string password, MetaWeblogPost post, bool publish)
        {
            var user = ValidateUser(username, password);

            var asInt = postid.TryConvertTo <int>();

            if (!asInt)
            {
                return(false);
            }

            //first see if it's published
            var content = _applicationContext.Services.ContentService.GetById(asInt.Result);

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

            AddOrUpdateContent(content, post, user, publish);

            return(true);
        }
        bool IMetaWeblog.UpdatePost(string postid, string username, string password, MetaWeblogPost post, bool publish)
        {
            var user = ValidateUser(username, password);

            var asInt = postid.TryConvertTo <int>();

            if (!asInt)
            {
                return(false);
            }

            //first see if it's published
            var content = _applicationContext.Services.ContentService.GetById(asInt.Result);

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

            var node = BlogRoot().Children("ArticulateArchive").FirstOrDefault();

            if (node == null)
            {
                throw new XmlRpcFaultException(0, "No Articulate Archive node found");
            }

            var extractFirstImageAsProperty = true;

            if (node.HasProperty("extractFirstImage"))
            {
                extractFirstImageAsProperty = node.GetPropertyValue <bool>("extractFirstImage");
            }

            AddOrUpdateContent(content, post, user, publish, extractFirstImageAsProperty);

            return(true);
        }
        private void AddOrUpdateContent(IContent content, MetaWeblogPost post, IUser user, bool publish, bool extractFirstImageAsProperty)
        {
            content.Name = post.Title;
            content.SetValue("author", user.Name);
            if (content.HasProperty("richText"))
            {
                var firstImage = "";

                //we need to replace all absolute image paths with relative ones
                var contentToSave = _mediaSrc.Replace(post.Content, match =>
                {
                    if (match.Groups.Count == 2)
                    {
                        var imageSrc = match.Groups[1].Value.EnsureStartsWith('/');
                        if (firstImage.IsNullOrWhiteSpace())
                        {
                            firstImage = imageSrc;
                        }
                        return(" src=\"" + imageSrc + "\"");
                    }
                    return(null);
                });

                var imagesProcessed = 0;

                //now replace all absolute anchor paths with relative ones
                contentToSave = _mediaHref.Replace(contentToSave, match =>
                {
                    if (match.Groups.Count == 2)
                    {
                        var href = " href=\"" +
                                   match.Groups[1].Value.EnsureStartsWith('/') +
                                   "\" class=\"a-image-" + imagesProcessed + "\" ";

                        imagesProcessed++;

                        return(href);
                    }
                    return(null);
                });

                content.SetValue("richText", contentToSave);

                if (extractFirstImageAsProperty &&
                    content.HasProperty("postImage") &&
                    !firstImage.IsNullOrWhiteSpace())
                {
                    content.SetValue("postImage", firstImage);
                    //content.SetValue("postImage", JsonConvert.SerializeObject(JObject.FromObject(new
                    //{
                    //    src = firstImage
                    //})));
                }
            }

            if (!post.Slug.IsNullOrWhiteSpace())
            {
                content.SetValue("umbracoUrlName", post.Slug);
            }
            if (!post.Excerpt.IsNullOrWhiteSpace())
            {
                content.SetValue("excerpt", post.Excerpt);
            }

            if (post.AllowComments == 1)
            {
                content.SetValue("enableComments", 1);
            }
            else if (post.AllowComments == 2)
            {
                content.SetValue("enableComments", 0);
            }

            content.SetTags("categories", post.Categories, true, "ArticulateCategories");
            var tags = post.Tags.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Distinct().ToArray();

            content.SetTags("tags", tags, true, "ArticulateTags");

            if (publish)
            {
                if (post.CreateDate != DateTime.MinValue)
                {
                    content.SetValue("publishedDate", post.CreateDate);
                }

                _applicationContext.Services.ContentService.SaveAndPublishWithStatus(content, user.Id);
            }
            else
            {
                _applicationContext.Services.ContentService.Save(content, user.Id);
            }
        }
        private void AddOrUpdateContent(IContent content, IContentType contentType, MetaWeblogPost post, IUser user, bool publish, bool extractFirstImageAsProperty)
        {
            content.SetInvariantOrDefaultCultureName(post.Title, contentType, _localizationService);

            content.SetInvariantOrDefaultCultureValue("author", user.Name, contentType, _localizationService);
            if (content.HasProperty("richText"))
            {
                var firstImage = "";

                // Extract the articulate firstImage.
                // Re-update the URL to be the one from the media file system.
                // Live writer will always make the urls absolute even if we return a relative path from NewMediaObject
                // so we will re-update it. If it's the default media file system then this will become a relative path
                // which is what we want, if it's a custom file system it will update it to it's absolute path.
                var contentToSave = _mediaSrc.Replace(post.Content, match =>
                {
                    if (match.Groups.Count == 2)
                    {
                        var relativePath        = match.Groups[1].Value;
                        var mediaFileSystemPath = _mediaFileSystem.GetUrl(relativePath);
                        if (firstImage.IsNullOrWhiteSpace())
                        {
                            // get the first images absolute media path
                            firstImage = mediaFileSystemPath;
                        }
                        return(" src=\"" + mediaFileSystemPath + "\"");
                    }
                    return(null);
                });

                var imagesProcessed = 0;

                // Now ensure all anchors have the custom class
                // and the media file system path is re-updated as per above
                contentToSave = _mediaHref.Replace(contentToSave, match =>
                {
                    if (match.Groups.Count == 2)
                    {
                        var relativePath        = match.Groups[1].Value;
                        var mediaFileSystemPath = _mediaFileSystem.GetUrl(relativePath);

                        var href = " href=\"" +
                                   mediaFileSystemPath +
                                   "\" class=\"a-image-" + imagesProcessed + "\" ";

                        imagesProcessed++;

                        return(href);
                    }
                    return(null);
                });

                content.SetInvariantOrDefaultCultureValue("richText", contentToSave, contentType, _localizationService);

                if (extractFirstImageAsProperty &&
                    content.HasProperty("postImage") &&
                    !firstImage.IsNullOrWhiteSpace())
                {
                    var configuration = _dataTypeService.GetDataType(content.Properties["postImage"].PropertyType.DataTypeId).ConfigurationAs <ImageCropperConfiguration>();
                    var crops         = configuration?.Crops ?? Array.Empty <ImageCropperConfiguration.Crop>();

                    var imageCropValue = new ImageCropperValue
                    {
                        Src   = firstImage,
                        Crops = crops.Select(x => new ImageCropperValue.ImageCropperCrop
                        {
                            Alias  = x.Alias,
                            Height = x.Height,
                            Width  = x.Width
                        }).ToList()
                    };

                    content.SetInvariantOrDefaultCultureValue(
                        "postImage",
                        JsonConvert.SerializeObject(imageCropValue),
                        contentType,
                        _localizationService);
                }
            }

            if (!post.Slug.IsNullOrWhiteSpace())
            {
                content.SetInvariantOrDefaultCultureValue("umbracoUrlName", post.Slug, contentType, _localizationService);
            }
            if (!post.Excerpt.IsNullOrWhiteSpace())
            {
                content.SetInvariantOrDefaultCultureValue("excerpt", post.Excerpt, contentType, _localizationService);
            }

            if (post.AllowComments == 1)
            {
                content.SetInvariantOrDefaultCultureValue("enableComments", 1, contentType, _localizationService);
            }
            else if (post.AllowComments == 2)
            {
                content.SetInvariantOrDefaultCultureValue("enableComments", 0, contentType, _localizationService);
            }

            content.AssignInvariantOrDefaultCultureTags("categories", post.Categories, contentType, _localizationService);
            var tags = post.Tags.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Distinct().ToArray();

            content.AssignInvariantOrDefaultCultureTags("tags", tags, contentType, _localizationService);

            if (publish)
            {
                if (post.CreateDate != DateTime.MinValue)
                {
                    content.SetInvariantOrDefaultCultureValue("publishedDate", post.CreateDate, contentType, _localizationService);
                }

                _contentService.SaveAndPublish(content, userId: user.Id);
            }
            else
            {
                _contentService.Save(content, user.Id);
            }
        }