예제 #1
0
        public void MdContentToNone()
        {
            var md     = "A quick brown **fox** jumped over the lazy dog.";
            var result = ContentProcessor.MarkdownToContent(md, ContentProcessor.MarkdownConvertType.None);

            Assert.IsTrue(result == "A quick brown **fox** jumped over the lazy dog.");
        }
예제 #2
0
        public TemplateProcessor FillContent(Content content)
        {
            var processor = new ContentProcessor(
                new ProcessContext(_wordDocument))
                            .SetRemoveContentControls(_isNeedToRemoveContentControls);

            var processResult = processor.FillContent(Document.Root.Element(W.body), content);

            if (_wordDocument.HasFooters)
            {
                foreach (var footer in _wordDocument.FooterParts.Values)
                {
                    var footerProcessResult = processor.FillContent(footer.Element(W.footer), content);
                    processResult.Merge(footerProcessResult);
                }
            }

            if (_wordDocument.HasHeaders)
            {
                foreach (var header in _wordDocument.HeaderParts.Values)
                {
                    var headerProcessResult = processor.FillContent(header.Element(W.header), content);
                    processResult.Merge(headerProcessResult);
                }
            }

            if (_isNeedToNoticeAboutErrors)
            {
                AddErrors(processResult.Errors);
            }

            return(this);
        }
        public void RemoveTags()
        {
            var html   = @"<p>Microsoft</p><p>Rocks!</p><p>Azure&nbsp;<br /><img src=""a.jpg"" /> The best <span>cloud</span>!</p>";
            var output = ContentProcessor.RemoveTags(html);

            Assert.IsTrue(output == "Microsoft Rocks! Azure  The best cloud!");
        }
        public void MdContentToHtml()
        {
            var md     = "A quick brown **fox** jumped over the lazy dog.";
            var result = ContentProcessor.MarkdownToContent(md, ContentProcessor.MarkdownConvertType.Html);

            Assert.IsTrue(result == "<p>A quick brown <strong>fox</strong> jumped over the lazy dog.</p>\n");
        }
예제 #5
0
        public void LazyLoadToImgTag_ExistLoading()
        {
            const string html   = @"<p>Work 996 and have some fu bao!</p><img loading=""lazy"" src=""icu.jpg"" /><video src=""java996.mp4""></video>";
            var          result = ContentProcessor.AddLazyLoadToImgTag(html);

            Assert.IsTrue(result == @"<p>Work 996 and have some fu bao!</p><img loading=""lazy"" src=""icu.jpg"" /><video src=""java996.mp4""></video>");
        }
 public int LogInUser(MyUser myUser)
 {
     if (myUser == null)
     {
         return(0);
     }
     return(ContentProcessor.LogInUser(myUser));
 }
 public int SaveUser(MyUser myUser)
 {
     if (myUser == null)
     {
         return(0);
     }
     return(ContentProcessor.RegisterNewUser(myUser));
 }
예제 #8
0
 public void Clear()
 {
     foreach (var child in this)
     {
         child.Clear();
     }
     Content = ContentProcessor.GetEmptyContent();
 }
        public void GetPostAbstract()
        {
            var html     = @"<p>Microsoft</p> <p>Rocks!</p><p>Azure <br /><img src=""a.jpg"" /> The best <span>cloud</span>!</p>";
            var result   = ContentProcessor.GetPostAbstract(html, 16);
            var expected = "Microsoft Rocks!" + "\u00A0\u2026";

            Assert.IsTrue(result == expected);
        }
 public static IBuildAction CreateAction(ContentImporter importer, ContentProcessor processor)
 {
     return(new ContentCompilerBuildAction()
     {
         Importer = importer,
         Processor = processor
     });
 }
예제 #11
0
 public bool SendNewLetter(MyMessage myMessage)
 {
     if (myMessage == null)
     {
         return(false);
     }
     return(ContentProcessor.SendLetter(myMessage));
 }
예제 #12
0
        public void MdContentToException()
        {
            var md = "A quick brown **fox** jumped over the lazy dog.";

            Assert.Throws <ArgumentOutOfRangeException>(() =>
            {
                var result = ContentProcessor.MarkdownToContent(md, (ContentProcessor.MarkdownConvertType) 4);
            });
        }
예제 #13
0
 public BlogReader(IFileSystem fileSystem,
                   ContentParser parser,
                   ContentConverter converter,
                   ContentProcessor processor)
 {
     _fileSystem = fileSystem;
     _parser     = parser;
     _converter  = converter;
     _processor  = processor;
 }
예제 #14
0
 public BlogReader(IFileSystem fileSystem, 
     ContentParser parser,
     ContentConverter converter,
     ContentProcessor processor)
 {
     _fileSystem = fileSystem;
     _parser = parser;
     _converter = converter;
     _processor = processor;
 }
예제 #15
0
        public string GetMyLetters(int userId)
        {
            if (userId == 0)
            {
                return(null);
            }

            string json = JsonConvert.SerializeObject(ContentProcessor.GetMyLetters(userId));

            // List<MyMessage> myMessageJSON = JsonConvert.DeserializeObject<List<MyMessage>>(json);
            return(json);
        }
        public TemplateProcessor FillContent(Content content)
        {
            var processResult =
                new ContentProcessor(
                    new ProcessContext(Document, NumberingPart, StylesPart))
                .SetRemoveContentControls(_isNeedToRemoveContentControls)
                .FillContent(Document.Root.Element(W.body), content);

            if (_isNeedToNoticeAboutErrors)
            {
                AddErrors(processResult.Errors);
            }

            return(this);
        }
예제 #17
0
        /// <summary>
        /// Extract vertex maps for all MCS conten, or only selected folders if useSelection == true.
        /// </summary>
        public static void ExtractVertexMaps(bool useSelection)
        {
            List <GameObject> content = GetContent(useSelection);

            if (content.Count == 0)
            {
                return;
            }

            _activeProcess         = new ContentProcessor("Extract", content, true);
            _activeProcess.Process = delegate() {
                GameObject obj = _activeProcess.GetObject();
                if (obj == null)
                {
                    return;
                }

                CoreMesh[] meshes = obj.GetComponentsInChildren <CoreMesh>();
                foreach (CoreMesh mesh in meshes)
                {
                    string collection = GetCollectionName(mesh.runtimeMorphPath);

                    //_activeProcess.status = collection + ":" + mesh.name;

                    SkinnedMeshRenderer smr = mesh.GetComponent <SkinnedMeshRenderer>();
                    if (smr != null)
                    {
                        string collectionConversionMapPath = _conversionMapPath + ((string.IsNullOrEmpty(collection) ? "" : "/" + collection));
                        Directory.CreateDirectory(collectionConversionMapPath);

                        VertexMap vertexMap = new VertexMap(smr.sharedMesh.vertices);
                        vertexMap.WriteToDisk(collectionConversionMapPath + "/" + mesh.name + ".json");
                    }
                }

                if (_activeProcess.isLast)
                {
                    if (EditorUtility.DisplayDialog("Complete!", "Extracted vertex maps were saved in Assets/MCS/ConversionMaps.\nYou can copy the files to your new Unity project.", "Show in Explorer", "Close"))
                    {
                        EditorUtility.RevealInFinder(_conversionMapPath);
                    }
                }
            };
        }
예제 #18
0
    public async Task <PostEntity> Handle(CreatePostCommand request, CancellationToken cancellationToken)
    {
        var abs = ContentProcessor.GetPostAbstract(
            string.IsNullOrEmpty(request.Payload.Abstract) ? request.Payload.EditorContent : request.Payload.Abstract.Trim(),
            _blogConfig.ContentSettings.PostAbstractWords,
            _settings.Editor == EditorChoice.Markdown);

        var post = new PostEntity
        {
            CommentEnabled      = request.Payload.EnableComment,
            Id                  = Guid.NewGuid(),
            PostContent         = request.Payload.EditorContent,
            ContentAbstract     = abs,
            CreateTimeUtc       = DateTime.UtcNow,
            LastModifiedUtc     = DateTime.UtcNow, // Fix draft orders
            Slug                = request.Payload.Slug.ToLower().Trim(),
            Author              = request.Payload.Author?.Trim(),
            Title               = request.Payload.Title.Trim(),
            ContentLanguageCode = request.Payload.LanguageCode,
            IsFeedIncluded      = request.Payload.FeedIncluded,
            PubDateUtc          = request.Payload.IsPublished ? DateTime.UtcNow : null,
            IsDeleted           = false,
            IsPublished         = request.Payload.IsPublished,
            IsFeatured          = request.Payload.Featured,
            IsOriginal          = request.Payload.IsOriginal,
            OriginLink          = string.IsNullOrWhiteSpace(request.Payload.OriginLink) ? null : Helper.SterilizeLink(request.Payload.OriginLink),
            HeroImageUrl        = string.IsNullOrWhiteSpace(request.Payload.HeroImageUrl) ? null : Helper.SterilizeLink(request.Payload.HeroImageUrl),
            InlineCss           = request.Payload.InlineCss,
            PostExtension       = new()
            {
                Hits  = 0,
                Likes = 0
            }
        };

        // check if exist same slug under the same day
        var todayUtc = DateTime.UtcNow.Date;

        if (_postRepo.Any(new PostSpec(post.Slug, todayUtc)))
        {
            var uid = Guid.NewGuid();
            post.Slug += $"-{uid.ToString().ToLower()[..8]}";
예제 #19
0
        public async Task <IActionResult> NewComment(Guid postId, NewCommentModel model, [FromServices] ISessionBasedCaptcha captcha)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest(ModelState));
            }
            if (!_blogConfig.ContentSettings.EnableComments)
            {
                return(Forbid());
            }

            if (!captcha.ValidateCaptchaCode(model.CaptchaCode, HttpContext.Session))
            {
                ModelState.AddModelError(nameof(model.CaptchaCode), "Wrong Captcha Code");
                return(Conflict(ModelState));
            }

            var response = await _commentService.CreateAsync(new CommentRequest(postId)
            {
                Username  = model.Username,
                Content   = model.Content,
                Email     = model.Email,
                IpAddress = DNT ? "N/A" : HttpContext.Connection.RemoteIpAddress.ToString()
            });

            if (_blogConfig.NotificationSettings.SendEmailOnNewComment && _notificationClient is not null)
            {
                _ = Task.Run(async() =>
                {
                    await _notificationClient.NotifyCommentAsync(response,
                                                                 s => ContentProcessor.MarkdownToContent(s, ContentProcessor.MarkdownConvertType.Html));
                });
            }

            if (_blogConfig.ContentSettings.RequireCommentReview)
            {
                return(Created("moonglade://empty", response));
            }

            return(Ok());
        }
예제 #20
0
        public async Task NotifyCommentAsync(
            string username, string email, string ipAddress, string postTitle, string commentContent, DateTime createTimeUtc)
        {
            var payload = new CommentPayload(
                username,
                email,
                ipAddress,
                postTitle,
                ContentProcessor.MarkdownToContent(commentContent, ContentProcessor.MarkdownConvertType.Html),
                createTimeUtc
                );

            try
            {
                await SendAsync(new NotificationRequest <CommentPayload>(MailMesageTypes.NewCommentNotification, payload));
            }
            catch (Exception e)
            {
                _logger.LogError(e, e.Message);
            }
        }
예제 #21
0
        public async Task <CommentReply> AddReply(Guid commentId, string replyContent)
        {
            var cmt = await _commentRepo.GetAsync(commentId);

            if (cmt is null)
            {
                throw new InvalidOperationException($"Comment {commentId} is not found.");
            }

            var id    = Guid.NewGuid();
            var model = new CommentReplyEntity
            {
                Id            = id,
                ReplyContent  = replyContent,
                CreateTimeUtc = DateTime.UtcNow,
                CommentId     = commentId
            };

            await _commentReplyRepo.AddAsync(model);

            var reply = new CommentReply
            {
                CommentContent   = cmt.CommentContent,
                CommentId        = commentId,
                Email            = cmt.Email,
                Id               = model.Id,
                PostId           = cmt.PostId,
                PubDateUtc       = cmt.Post.PubDateUtc.GetValueOrDefault(),
                ReplyContent     = model.ReplyContent,
                ReplyContentHtml = ContentProcessor.MarkdownToContent(model.ReplyContent, ContentProcessor.MarkdownConvertType.Html),
                ReplyTimeUtc     = model.CreateTimeUtc,
                Slug             = cmt.Post.Slug,
                Title            = cmt.Post.Title
            };

            await _audit.AddAuditEntry(EventType.Content, AuditEventId.CommentReplied, $"Replied comment id '{commentId}'");

            return(reply);
        }
예제 #22
0
 public TopicReader(
     IFileSystem fileSystem,
     ContentParser contentParser,
     ContentConverter contentConverter,
     ContentProcessor contentProcessor)
 {
     if (fileSystem == null)
     {
         throw new ArgumentNullException(nameof(fileSystem));
     }
     if (contentParser == null)
     {
         throw new ArgumentNullException(nameof(contentParser));
     }
     if (contentConverter == null)
     {
         throw new ArgumentNullException(nameof(contentConverter));
     }
     _fileSystem = fileSystem;
     _contentParser = contentParser;
     _contentConverter = contentConverter;
     _contentProcessor = contentProcessor;
 }
예제 #23
0
 public TopicReader(
     IFileSystem fileSystem,
     ContentParser contentParser,
     ContentConverter contentConverter,
     ContentProcessor contentProcessor)
 {
     if (fileSystem == null)
     {
         throw new ArgumentNullException(nameof(fileSystem));
     }
     if (contentParser == null)
     {
         throw new ArgumentNullException(nameof(contentParser));
     }
     if (contentConverter == null)
     {
         throw new ArgumentNullException(nameof(contentConverter));
     }
     _fileSystem       = fileSystem;
     _contentParser    = contentParser;
     _contentConverter = contentConverter;
     _contentProcessor = contentProcessor;
 }
예제 #24
0
    public async Task <CommentReply> Handle(ReplyCommentCommand request, CancellationToken cancellationToken)
    {
        var cmt = await _commentRepo.GetAsync(request.CommentId);

        if (cmt is null)
        {
            throw new InvalidOperationException($"Comment {request.CommentId} is not found.");
        }

        var id    = Guid.NewGuid();
        var model = new CommentReplyEntity
        {
            Id            = id,
            ReplyContent  = request.ReplyContent,
            CreateTimeUtc = DateTime.UtcNow,
            CommentId     = request.CommentId
        };

        await _commentReplyRepo.AddAsync(model);

        var reply = new CommentReply
        {
            CommentContent   = cmt.CommentContent,
            CommentId        = request.CommentId,
            Email            = cmt.Email,
            Id               = model.Id,
            PostId           = cmt.PostId,
            PubDateUtc       = cmt.Post.PubDateUtc.GetValueOrDefault(),
            ReplyContent     = model.ReplyContent,
            ReplyContentHtml = ContentProcessor.MarkdownToContent(model.ReplyContent, ContentProcessor.MarkdownConvertType.Html),
            ReplyTimeUtc     = model.CreateTimeUtc,
            Slug             = cmt.Post.Slug,
            Title            = cmt.Post.Title
        };

        return(reply);
    }
예제 #25
0
    public async Task Handle(CommentNotification notification, CancellationToken cancellationToken)
    {
        var payload = new CommentPayload(
            notification.Username,
            notification.Email,
            notification.IPAddress,
            notification.PostTitle,
            ContentProcessor.MarkdownToContent(notification.CommentContent, ContentProcessor.MarkdownConvertType.Html),
            notification.CreateTimeUtc
            );

        var response = await _client.SendNotification(MailMesageTypes.NewCommentNotification, payload);

        var respBody = await response.Content.ReadAsStringAsync(cancellationToken);

        if (response.IsSuccessStatusCode)
        {
            _logger.LogInformation($"Email is sent, server response: '{respBody}'");
        }
        else
        {
            throw new($"Email sending failed, response code: '{response.StatusCode}', response body: '{respBody}'");
        }
    }
예제 #26
0
        public virtual async Task <RssChannel> GetChannel(CancellationToken cancellationToken = default(CancellationToken))
        {
            var project = await ProjectService.GetCurrentProjectSettings();

            if (project == null)
            {
                return(null);
            }

            var itemsToGet         = project.DefaultFeedItems;
            var requestedFeedItems = ContextAccessor.HttpContext?.Request.Query["maxItems"].ToString();

            if (!string.IsNullOrWhiteSpace(requestedFeedItems))
            {
                int.TryParse(requestedFeedItems, out itemsToGet);
                if (itemsToGet > project.MaxFeedItems)
                {
                    itemsToGet = project.MaxFeedItems;
                }
            }

            var posts = await BlogService.GetRecentPosts(itemsToGet);

            if (posts == null)
            {
                return(null);
            }

            var channel = new RssChannel
            {
                Title         = project.Title,
                Copyright     = project.CopyrightNotice,
                Generator     = Name,
                RemoteFeedUrl = project.RemoteFeedUrl,
                RemoteFeedProcessorUseAgentFragment = project.RemoteFeedProcessorUseAgentFragment
            };

            if (!string.IsNullOrEmpty(project.Description))
            {
                channel.Description = project.Description;
            }
            else
            {
                // prevent error, channel desc cannot be empty
                channel.Description = "Welcome to my blog";
            }

            if (!string.IsNullOrEmpty(project.ChannelCategoriesCsv))
            {
                var channelCats = project.ChannelCategoriesCsv.Split(',');
                foreach (var cat in channelCats)
                {
                    channel.Categories.Add(new RssCategory(cat));
                }
            }

            var urlHelper = UrlHelperFactory.GetUrlHelper(ActionContextAccesor.ActionContext);

            if (!string.IsNullOrEmpty(project.Image))
            {
                channel.Image.Url = new Uri(urlHelper.Content(project.Image));
            }
            if (!string.IsNullOrEmpty(project.LanguageCode))
            {
                channel.Language = new CultureInfo(project.LanguageCode);
            }

            var baseUrl = string.Concat(
                ContextAccessor.HttpContext.Request.Scheme,
                "://",
                ContextAccessor.HttpContext.Request.Host.ToUriComponent()
                );

            // asp.net bug? the comments for this method say it returns an absolute fully qualified url but it returns relative
            // looking at latest code seems ok so maybe just a bug in rc1
            //https://github.com/aspnet/Mvc/blob/dev/src/Microsoft.AspNetCore.Mvc.Core/UrlHelperExtensions.cs
            //https://github.com/aspnet/Mvc/blob/dev/src/Microsoft.AspNetCore.Mvc.Core/Routing/UrlHelper.cs

            var indexUrl = urlHelper.RouteUrl(BlogRoutes.BlogIndexRouteName);

            if (indexUrl == null)
            {
                indexUrl = urlHelper.Action("Index", "Blog");
            }

            if (indexUrl.StartsWith("/"))
            {
                indexUrl = string.Concat(baseUrl, indexUrl);
            }
            channel.Link = new Uri(indexUrl);
            if (!string.IsNullOrEmpty(project.ManagingEditorEmail))
            {
                channel.ManagingEditor = project.ManagingEditorEmail;
            }

            if (!string.IsNullOrEmpty(project.ChannelRating))
            {
                channel.Rating = project.ChannelRating;
            }

            var feedUrl = string.Concat(
                ContextAccessor.HttpContext.Request.Scheme,
                "://",
                ContextAccessor.HttpContext.Request.Host.ToUriComponent(),
                ContextAccessor.HttpContext.Request.PathBase.ToUriComponent(),
                ContextAccessor.HttpContext.Request.Path.ToUriComponent(),
                ContextAccessor.HttpContext.Request.QueryString.ToUriComponent());

            channel.SelfLink = new Uri(feedUrl);

            channel.TimeToLive = project.ChannelTimeToLive;
            if (!string.IsNullOrEmpty(project.WebmasterEmail))
            {
                channel.Webmaster = project.WebmasterEmail;
            }

            DateTime mostRecentPubDate = DateTime.MinValue;
            var      items             = new List <RssItem>();

            foreach (var post in posts)
            {
                if (!post.PubDate.HasValue)
                {
                    continue;
                }

                if (post.PubDate.Value > mostRecentPubDate)
                {
                    mostRecentPubDate = post.PubDate.Value;
                }
                var rssItem = new RssItem
                {
                    Author = post.Author
                };

                if (post.Categories.Count > 0)
                {
                    foreach (var c in post.Categories)
                    {
                        rssItem.Categories.Add(new RssCategory(c));
                    }
                }

                var postUrl = await BlogUrlResolver.ResolvePostUrl(post, project).ConfigureAwait(false);

                if (string.IsNullOrEmpty(postUrl))
                {
                    //TODO: log
                    continue;
                }

                if (postUrl.StartsWith("/"))
                {
                    //postUrl = urlHelper.Content(postUrl);
                    postUrl = string.Concat(
                        ContextAccessor.HttpContext.Request.Scheme,
                        "://",
                        ContextAccessor.HttpContext.Request.Host.ToUriComponent(),
                        postUrl);
                }

                var filteredResult = ContentProcessor.FilterHtmlForRss(post, project, baseUrl);
                rssItem.Description = filteredResult.FilteredContent;
                if (!filteredResult.IsFullContent)
                {
                    //TODO: localize
                    var readMore = " <a href='" + postUrl + "'>...read more</a>";
                    rssItem.Description += readMore;
                }

                //rssItem.Enclosures

                rssItem.Guid            = new RssGuid(postUrl, true);
                rssItem.Link            = new Uri(postUrl);
                rssItem.PublicationDate = post.PubDate.Value;
                //rssItem.Source
                rssItem.Title = post.Title;

                items.Add(rssItem);
            }

            channel.PublicationDate = mostRecentPubDate;
            channel.Items           = items;

            return(channel);
        }
예제 #27
0
 protected AgdContentProcessor(ContentProcessor nextProcessor, string contentType, IApplication application)
     : base(nextProcessor)
 {
     _application = application;
     _contentType = contentType;
 }
예제 #28
0
 protected ContentProcessor(ContentProcessor nextProcessor)
 {
     _nextProcessor = nextProcessor;
 }
예제 #29
0
    public async Task <PostEntity> Handle(UpdatePostCommand request, CancellationToken cancellationToken)
    {
        var post = await _postRepo.GetAsync(request.Id);

        if (null == post)
        {
            throw new InvalidOperationException($"Post {request.Id} is not found.");
        }

        post.CommentEnabled  = request.Payload.EnableComment;
        post.PostContent     = request.Payload.EditorContent;
        post.ContentAbstract = ContentProcessor.GetPostAbstract(
            string.IsNullOrEmpty(request.Payload.Abstract) ? request.Payload.EditorContent : request.Payload.Abstract.Trim(),
            _blogConfig.ContentSettings.PostAbstractWords,
            _settings.Editor == EditorChoice.Markdown);

        // Address #221: Do not allow published posts back to draft status
        // postModel.IsPublished = request.Request.IsPublished;
        // Edit draft -> save and publish, ignore false case because #221
        bool isNewPublish = false;

        if (request.Payload.IsPublished && !post.IsPublished)
        {
            post.IsPublished = true;
            post.PubDateUtc  = DateTime.UtcNow;

            isNewPublish = true;
        }

        // #325: Allow changing publish date for published posts
        if (request.Payload.PublishDate is not null && post.PubDateUtc.HasValue)
        {
            var tod          = post.PubDateUtc.Value.TimeOfDay;
            var adjustedDate = request.Payload.PublishDate.Value;
            post.PubDateUtc = adjustedDate.AddTicks(tod.Ticks);
        }

        post.Author              = request.Payload.Author?.Trim();
        post.Slug                = request.Payload.Slug.ToLower().Trim();
        post.Title               = request.Payload.Title.Trim();
        post.LastModifiedUtc     = DateTime.UtcNow;
        post.IsFeedIncluded      = request.Payload.FeedIncluded;
        post.ContentLanguageCode = request.Payload.LanguageCode;
        post.IsFeatured          = request.Payload.Featured;
        post.IsOriginal          = request.Payload.IsOriginal;
        post.OriginLink          = string.IsNullOrWhiteSpace(request.Payload.OriginLink) ? null : Helper.SterilizeLink(request.Payload.OriginLink);
        post.HeroImageUrl        = string.IsNullOrWhiteSpace(request.Payload.HeroImageUrl) ? null : Helper.SterilizeLink(request.Payload.HeroImageUrl);
        post.InlineCss           = request.Payload.InlineCss;

        // compute hash
        var input    = $"{post.Slug}#{post.PubDateUtc.GetValueOrDefault():yyyyMMdd}";
        var checkSum = Helper.ComputeCheckSum(input);

        post.HashCheckSum = checkSum;

        // 1. Add new tags to tag lib
        var tags = string.IsNullOrWhiteSpace(request.Payload.Tags) ?
                   Array.Empty <string>() :
                   request.Payload.Tags.Split(',').ToArray();

        foreach (var item in tags.Where(item => !_tagRepo.Any(p => p.DisplayName == item)))
        {
            await _tagRepo.AddAsync(new()
            {
                DisplayName    = item,
                NormalizedName = Tag.NormalizeName(item, _tagNormalizationDictionary)
            });
        }

        // 2. update tags
        post.Tags.Clear();
        if (tags.Any())
        {
            foreach (var tagName in tags)
            {
                if (!Tag.ValidateName(tagName))
                {
                    continue;
                }

                var tag = await _tagRepo.GetAsync(t => t.DisplayName == tagName);

                if (tag is not null)
                {
                    post.Tags.Add(tag);
                }
            }
        }

        // 3. update categories
        var catIds = request.Payload.CategoryList.Where(p => p.IsChecked).Select(p => p.Id).ToArray();

        post.PostCategory.Clear();

        if (catIds is { Length : > 0 })
예제 #30
0
        public void RemoveTags_Empty()
        {
            var output = ContentProcessor.RemoveTags(string.Empty);

            Assert.AreEqual(string.Empty, output);
        }
예제 #31
0
        /// <summary>
        /// Removes morphs from selected assets. Useful in cases like hair moving unnaturally with eye blinks.
        /// </summary>
        public static void RemoveMorphsFromSelected(List <string> morphNamesToBeRemoved)
        {
            List <GameObject> content = GetContent(true);

            if (content.Count == 0 || morphNamesToBeRemoved == null || morphNamesToBeRemoved.Count == 0)
            {
                return;
            }

            if (!EditorUtility.DisplayDialog("Warning", "This process is nonreversible.\nAre you sure?", "Yes", "Cancel"))
            {
                return;
            }

            // Load common conversion tools and data
            _conversionData = new ConversionData();

            _activeProcess         = new ContentProcessor("Edit", content, true);
            _activeProcess.Process = delegate() {
                GameObject obj = _activeProcess.GetObject();
                if (obj == null)
                {
                    return;
                }

                CoreMesh[] meshes = obj.GetComponentsInChildren <CoreMesh>();
                foreach (CoreMesh mesh in meshes)
                {
                    //_activeProcess.status = mesh.name + " : Checking...";

                    // Check smr
                    SkinnedMeshRenderer smr = mesh.GetComponent <SkinnedMeshRenderer>();
                    if (smr == null)
                    {
                        continue;
                    }

                    // Create temp directory for generated .morph files
                    string morphPath = Path.Combine(Application.streamingAssetsPath, mesh.runtimeMorphPath);
                    Directory.CreateDirectory(morphPath);

                    try {
                        // Get manifest
                        var manifest = _conversionData.GetManifestForCoreMesh(mesh, _manifestSelectionMethod);

                        // Process morphs
                        List <string> morphNames = new List <string>(manifest.names);
                        morphNames.Add("base"); // Add "base" morph that's not in the manifest but is required for clothing and hair

                        foreach (string morph in morphNames)
                        {
                            MorphData data = _conversionData.GetMorphData(morphPath, morph);
                            if (data != null)
                            {
                                if (morphNamesToBeRemoved.Contains(morph))
                                {
                                    _activeProcess.status = mesh.name + " : Removed Morph " + morph;
                                }
                                else
                                {
                                    // Save .morph file for keeping
                                    MCS_Utilities.MorphExtraction.MorphExtraction.WriteMorphDataToFile(data, morphPath + "/" + data.name + ".morph", false, false);
                                }
                            }
                        }

                        // Repack morphs into .morph.mr file
                        //_activeProcess.status = mesh.name + " : Rebuilding MR...";
                        RepackMorphs(morphPath);

                        //_activeProcess.status = mesh.name + " : Success!";
                    } catch {
                        _activeProcess.status = mesh.name + " : FAILED";
                    } finally {
                        MCS_Utilities.Paths.TryDirectoryDelete(morphPath);
                    }
                }
            };
        }
예제 #32
0
        public void LazyLoadToImgTag_Empty()
        {
            var result = ContentProcessor.AddLazyLoadToImgTag(string.Empty);

            Assert.IsTrue(result == string.Empty);
        }
예제 #33
0
 private string FormatPostContent(string rawContent)
 {
     return(_settings.Editor == EditorChoice.Markdown ?
            ContentProcessor.MarkdownToContent(rawContent, ContentProcessor.MarkdownConvertType.Html, false) :
            rawContent);
 }
예제 #34
0
        /// <summary>
        /// Remaps morph data for all MCS content, or only selected folders if useSelection == true.
        /// </summary>
        public static void ConvertMorphData(bool useSelection)
        {
            if (!useSelection)
            {
                if (!EditorUtility.DisplayDialog("Warning", "This will attempt to convert all MCS morph data in your project. This process is nonreversible.\nAre you sure?", "Yes", "Cancel"))
                {
                    return;
                }
            }

            List <GameObject> content = GetContent(useSelection);

            if (content.Count == 0)
            {
                return;
            }

            // Load common conversion tools and data
            _conversionData = new ConversionData();

            _activeProcess         = new ContentProcessor("Convert", content, true);
            _activeProcess.Process = delegate() {
                GameObject obj = _activeProcess.GetObject();
                if (obj == null)
                {
                    return;
                }

                CoreMesh[] meshes = obj.GetComponentsInChildren <CoreMesh>();
                foreach (CoreMesh mesh in meshes)
                {
                    //_activeProcess.status = mesh.name + " : Checking...";
                    _conversionData.CreateReport(mesh.name);

                    // Check if already converted
                    if (_conversionData.GetMorphData(mesh.runtimeMorphPath, "_2019compatible") != null)
                    {
                        _conversionData.CloseReport("Skipped (already converted)");
                        continue;
                    }

                    // Check smr
                    SkinnedMeshRenderer smr = mesh.GetComponent <SkinnedMeshRenderer>();
                    if (smr == null)
                    {
                        _conversionData.CloseReport("Skipped (no SkinnedMeshRenderer found)");
                        continue;
                    }

                    // Check for original vertex map
                    string vmPath = "";
                    foreach (string path in _conversionData.vertexMaps)
                    {
                        if (path.Contains(mesh.name + ".json"))
                        {
                            vmPath = path;
                            break;
                        }
                    }
                    if (vmPath == "")
                    {
                        _conversionData.CloseReport("Skipped (no vertex map found)");
                        continue;
                    }

                    // Create temp directory for generated .morph files
                    string morphPath = Path.Combine(Application.streamingAssetsPath, mesh.runtimeMorphPath);
                    Directory.CreateDirectory(morphPath);

                    // Run process
                    try {
                        // Read vertex map
                        string    mapData   = File.ReadAllText(vmPath);
                        VertexMap vertexMap = JsonUtility.FromJson <VertexMap>(mapData);

                        // Generate retarget map
                        //_activeProcess.status = mesh.name + " : Generating Target Map...";
                        Dictionary <int, int> ttsMap = _conversionData.projectionMeshMap.GenerateTargetToSourceMap(vertexMap.vertices, smr.sharedMesh.vertices);

                        // Get manifest
                        var manifest = _conversionData.GetManifestForCoreMesh(mesh, _manifestSelectionMethod);

                        // Process morphs
                        int           n          = 0;
                        int           total      = manifest.names.Length;
                        List <string> morphNames = new List <string>(manifest.names);
                        morphNames.Add("base"); // Add "base" morph that's not in the manifest but is required for clothing and hair

                        foreach (string morph in morphNames)
                        {
                            //_activeProcess.status = string.Format("{0} : Processing Morph {1}/{2}", mesh.name, n, total);
                            n++;

                            MorphData source = _conversionData.GetMorphData(morphPath, morph); // Not all assets will have all morphs
                            if (source != null)
                            {
                                // Retarget morphs
                                MorphData target = RemapMorphData(smr, source, ttsMap);
                                // Save new .morph file
                                MCS_Utilities.MorphExtraction.MorphExtraction.WriteMorphDataToFile(target, morphPath + "/" + target.name + ".morph", false, false);
                            }
                        }

                        // Inject evidence of conversion so we don't accidentally remap again.
                        MorphData note = new MorphData();
                        note.name = "_2019compatible";
                        MCS_Utilities.MorphExtraction.MorphExtraction.WriteMorphDataToFile(note, morphPath + "/" + note.name + ".morph", false, false);

                        // Repack morphs into .morph.mr file
                        _activeProcess.status = mesh.name + " : Repacking Morphs...";
                        RepackMorphs(morphPath);

                        _conversionData.CloseReport("Success");
                    } catch {
                        _conversionData.CloseReport("Failed");
                    } finally {
                        MCS_Utilities.Paths.TryDirectoryDelete(morphPath);
                    }
                }

                if (_activeProcess.isLast)
                {
                    _conversionData.PrintSummary();
                }
            };
        }