Esempio n. 1
0
        private int UpdateChildrenCount(CommentTreeContext context, CommentTree commentTree, List <Guid> comments)
        {
            var childrenCount = comments.Count;

            foreach (var comment in comments)
            {
                if (context.CommentsChildrenCount.ContainsKey(comment))
                {
                    continue;
                }

                if (!commentTree.Tree.ContainsKey(comment))
                {
                    context.CommentsChildrenCount[comment] = 0;
                    continue;
                }

                var count = UpdateChildrenCount(context, commentTree, commentTree.Tree[comment]);

                context.CommentsChildrenCount[comment] = count;

                childrenCount += count;
            }

            return(childrenCount);
        }
Esempio n. 2
0
        private CommentTree GetCommentTree(List <RedditComment> comments, RedditComment comment, bool parity)
        {
            List <RedditComment> children = comments.Where(child => child.parentID.ToString() == comment.id.ToString()).ToList();

            if (children.Count == 0)
            {
                comment.parity = parity;
                return(new CommentTree()
                {
                    children = null, comment = comment
                });
            }
            else
            {
                RedditComment whatcomment = comment;
                comment.parity = parity;
                CommentTree rt = new CommentTree()
                {
                    children = new List <CommentTree>(),
                    comment  = whatcomment
                };
                List <CommentTree> what = new List <CommentTree>();
                foreach (var item in children)
                {
                    what.Add(GetCommentTree(comments, item, !parity));
                }
                rt.children = what;

                return(rt);
            }
        }
Esempio n. 3
0
        public CommentTree GetCommentTree(Guid postId)
        {
            //todo: this method is very db intensive. however, it should be easy to improve performance once
            // a caching strategy is implemented.

            var comments = _commentService.GetAllCommentsForPost(postId);

            var tree = new CommentTree
            {
                PostId     = postId,
                CommentIds = comments.Select(x => x.Id).ToList(),
                Parents    = comments.ToDictionary(x => x.Id, x => x.ParentId),
                Tree       = new Dictionary <Guid, List <Guid> >(),
                Depth      = comments.ToDictionary(x => x.Id, x => 0)
            };

            // loop through comments to figure out if we have children comments
            foreach (var comment in comments)
            {
                List <Guid> children;

                var parentId = comment.ParentId ?? Guid.Empty;

                if (tree.Tree.ContainsKey(parentId))
                {
                    children = tree.Tree[parentId];
                }
                else
                {
                    children            = new List <Guid>();
                    tree.Tree[parentId] = children;
                }

                children.Add(comment.Id);
            }

            // loop through commetns to figure out depth if there are children comments
            foreach (var comment in comments)
            {
                if (!comment.ParentId.HasValue)
                {
                    tree.Depth[comment.Id] = 0;
                    continue;
                }

                var parentId = comment.ParentId;
                var depth    = 0;
                while (parentId.HasValue)
                {
                    depth++;
                    parentId = tree.Parents[parentId.Value];
                }

                tree.Depth[comment.Id] = depth;
            }


            return(tree);
        }
Esempio n. 4
0
        private static string GenerateCommentHtml(CommentTree tree)
        {
            var sb = new StringBuilder();

            for (int i = tree.branches.Count - 1; i >= 0; i--)
            {
                sb.Append(GenerateCommentHtml(tree.branches[i].comment, GenerateCommentHtml(tree.branches[i])));
            }
            return(sb.ToString());
        }
Esempio n. 5
0
        public CommentTree GetCommentTree(Guid postId)
        {
            // TODO: this method is very db intensive. however, it should be easy to improve the performance once a caching strategy is implemented.

            var comments = _commentService.GetAllCommentsForPost(postId);

            var tree = new CommentTree
            {
                PostId = postId,
                CommentIds = comments.Select(x => x.Id).ToList(),
                Parents = comments.ToDictionary(x => x.Id, x => x.ParentId),
                Tree = new Dictionary<Guid, List<Guid>>(),
                Depth = comments.ToDictionary(x => x.Id, x => 0)
            };

            foreach (var comment in comments)
            {
                List<Guid> children;

                var parentId = comment.ParentId ?? Guid.Empty;

                if (tree.Tree.ContainsKey(parentId))
                    children = tree.Tree[parentId];
                else
                {
                    children = new List<Guid>();
                    tree.Tree[parentId] = children;
                }

                children.Add(comment.Id);
            }

            foreach (var comment in comments)
            {
                if (!comment.ParentId.HasValue)
                {
                    tree.Depth[comment.Id] = 0;
                    continue;
                }

                var parentId = comment.ParentId;
                var depth = 0;
                while (parentId.HasValue)
                {
                    depth++;
                    parentId = tree.Parents[parentId.Value];
                }
                tree.Depth[comment.Id] = depth;
            }

            return tree;
        }
Esempio n. 6
0
        private List <HouseShow> GetApprovedShows()
        {
            var list = _dataAccessService.ExecuteProcedureAsync <HouseShow>("GetApprovedHouseShows").Result.ToList();

            foreach (var concert in list)
            {
                var concertId   = concert.EventConcertId;
                var allComments = GetAllComments(concertId);

                var tree = new CommentTree(allComments);
                concert.Comments = tree.GetEventComments();
            }

            return(list);
        }
Esempio n. 7
0
        public async Task <IActionResult> Comments(string id)
        {
            RedditPost post = await _context.Posts.FindAsync(id);

            post.created_string = SecondsToAgoString((Int64)post.created_utc);

            List <RedditComment> RList = _context.Comments
                                         .Where(a => a.postID == id)
                                         .ToList();

            RList.Reverse();

            string      current_id  = post.id;
            CommentTree commentTree = new CommentTree();

            commentTree.children = new List <CommentTree>();
            commentTree.comment  = null;
            List <RedditComment> TopLevelComments = RList.Where(a => a.parentID.ToString() == current_id).ToList();

            foreach (var TopLevelComment in TopLevelComments)
            {
                CommentTree child_comment_tree = GetCommentTree(RList, TopLevelComment, true);
                commentTree.children.Add(child_comment_tree);
            }

            foreach (var item in RList)
            {
                item.createdString = SecondsToAgoString(item.unixTimestamp);
            }

            string subreddit = post.subreddit;

            CommentsPage commentsPage = new CommentsPage()
            {
                post        = post,
                commentTree = commentTree
            };

            return(View(commentsPage));
        }
        public IEnumerable <ICommentTree> CreateCommentTree(IEnumerable <GitComment> gitComments, char separator = '/')
        {
            Dictionary <long, GitComment> searchableGitComments = new Dictionary <long, GitComment>();

            foreach (var comment in gitComments)
            {
                searchableGitComments.Add(comment.Id, comment);
            }

            Dictionary <int, List <ObjectTree> > result = new Dictionary <int, List <ObjectTree> >();

            var maxLevel = -1;

            foreach (var comment in gitComments)
            {
                var           level = 0;
                List <long>   ids   = new List <long>();
                StringBuilder path  = new StringBuilder();

                ids.Add(comment.Id);
                var tmpComment = comment;
                while (tmpComment.Parent != null)
                {
                    ids.Add(tmpComment.Parent.Id);
                    level++;

                    tmpComment = searchableGitComments[tmpComment.Parent.Id];
                }

                if (!result.ContainsKey(level))
                {
                    result[level] = new List <ObjectTree>();
                    if (level > maxLevel)
                    {
                        maxLevel = level;
                    }
                }

                for (var pathIndex = ids.Count - 1; pathIndex > -1; pathIndex -= 1)
                {
                    path.Append(ids[pathIndex]);

                    if (pathIndex > 0)
                    {
                        path.Append(separator);
                    }
                }

                result[level].Add(new ObjectTree(path.ToString(), new GitComment()
                {
                    Content   = comment.Content,
                    CreatedOn = comment.CreatedOn,
                    Id        = comment.Id,
                    Parent    = comment.Parent,
                    User      = comment.User,
                    UpdatedOn = comment.UpdatedOn,
                    Inline    = comment.Inline,
                    IsDeleted = comment.IsDeleted,
                    Version   = comment.Version
                }));
            }



            ICommentTree entryComment = new CommentTree(null);

            for (var i = 0; i <= maxLevel; i++)
            {
                List <ObjectTree> preparedComments = result[i];
                foreach (var objectTree in preparedComments)
                {
                    ICommentTree currentComment = entryComment;
                    var          pathChunks     = objectTree.Path.Split(separator);
                    foreach (var pathChunk in pathChunks)
                    {
                        var tmp = currentComment.Comments.Where(x => x.Comment.Id.Equals(long.Parse(pathChunk)));
                        if (tmp.Any())
                        {
                            currentComment = tmp.Single();
                        }
                        else
                        {
                            ICommentTree newItem = new CommentTree(objectTree.GitComment);
                            currentComment.Comments.Add(newItem);
                            currentComment = newItem;
                        }
                    }
                }
            }

            return(entryComment.Comments);
        }
Esempio n. 9
0
        public List <ICommentNode> Build(CommentTree tree, CommentTreeContext treeContext, User currentUser)
        {
            var wrapped = _commentWrapper.Wrap(treeContext.Comments, currentUser).ToDictionary(x => x.Comment.Id, x => new CommentNode(x));
            var final   = new List <ICommentNode>();
            var walked  = new List <Guid>();

            // lets mark any comments as collapsed if needed
            foreach (var comment in wrapped.Values)
            {
                // todo: make this configurable per-user
                int minimumScore = 0;
                if ((comment.Comment.Author != null && currentUser != null) && currentUser.Id == comment.Comment.Author.Id)
                {
                    // the current user is the author, don't collapse!
                    comment.Collapsed = false;
                }
                else if (comment.Comment.Score < minimumScore)
                {
                    // to many down votes to show to the user
                    comment.Collapsed = true;
                }
                else
                {
                    // the current user is not the author, and we have enough upvotes to display,
                    // don't collapse
                    comment.Collapsed = false;
                }
            }

            foreach (var comment in wrapped.Values)
            {
                comment.NumberOfChildren = treeContext.CommentsChildrenCount[comment.Comment.Comment.Id];

                CommentNode parent = null;

                if (comment.Comment.Comment.ParentId.HasValue)
                {
                    parent = wrapped.ContainsKey(comment.Comment.Comment.ParentId.Value)
                        ? wrapped[comment.Comment.Comment.ParentId.Value]
                        : null;
                }

                if (comment.Comment.Comment.ParentId.HasValue && treeContext.Comments.Contains(comment.Comment.Comment.ParentId.Value))
                {
                    // parent comment is visible
                    comment.IsParentVisible = true;
                }

                if (parent != null && comment.Comment.CurrentUserIsAuthor)
                {
                    // this comment is the current user, so lets walk the parents
                    // and uncollapse any comments which may be collapsed
                    var ancestor = parent;
                    while (ancestor != null && !walked.Contains(ancestor.Comment.Comment.Id))
                    {
                        ancestor.Collapsed = false;
                        walked.Add(ancestor.Comment.Comment.Id);
                        ancestor = (ancestor.Comment.Comment.ParentId.HasValue && wrapped.ContainsKey(comment.Comment.Comment.ParentId.Value))
                            ? wrapped[comment.Comment.Comment.ParentId.Value]
                            : null;
                    }
                }

                if (treeContext.MoreRecursion.Contains(comment.Comment.Comment.Id))
                {
                    comment.Children.Add(new MoreRecursionNode(comment.Comment));
                }

                if (parent != null)
                {
                    comment.Parent = comment.Comment;
                    parent.Children.Add(comment);
                }
                else
                {
                    if (comment.Comment.Comment.ParentId.HasValue)
                    {
                        // we don't have a parent here, but this comment does have a parent
                        // we need to get it
                        comment.Parent = _commentWrapper.Wrap(comment.Comment.Comment.ParentId.Value);
                    }

                    final.Add(comment);
                }
            }

            foreach (var visibleId in wrapped.Keys)
            {
                // this item is already scheduled to have a new link to see all the children
                if (treeContext.MoreRecursion.Contains(visibleId))
                {
                    continue;
                }

                var children        = tree.Tree.ContainsKey(visibleId) ? tree.Tree[visibleId] : new List <Guid>();
                var missingChildren = children.Where(x => !treeContext.Comments.Contains(x)).ToList();

                if (missingChildren.Count > 0)
                {
                    var visibleChildren = children.Where(x => treeContext.Comments.Contains(x)).ToList();
                    var visibleCount    = visibleChildren.Sum(x => (treeContext.CommentsChildrenCount[x]) + 1);
                    var missingCount    = treeContext.CommentsChildrenCount[visibleId] - visibleCount;
                    var missingDepth    = (tree.Depth.ContainsKey(visibleId) ? tree.Depth[visibleId] : 0) + 1 - treeContext.OffsetDepth;

                    var moreChildren = new MoreChildren();
                    moreChildren.ChildComments.AddRange(missingChildren);
                    moreChildren.MissingCount = missingCount;
                    moreChildren.PostId       = tree.PostId;
                    moreChildren.Sort         = treeContext.Sort;
                    moreChildren.Depth        = missingDepth;
                    wrapped[visibleId].Children.Add(moreChildren);
                }
            }

            if (treeContext.TopLevelCandidates.Count > 0)
            {
                var moreChildren = new MoreChildren();
                moreChildren.ChildComments.AddRange(treeContext.TopLevelCandidates);
                moreChildren.MissingCount = moreChildren.ChildComments.Sum(x => (treeContext.CommentsChildrenCount.ContainsKey(x) ? treeContext.CommentsChildrenCount[x] : 0) + 1);
                moreChildren.PostId       = tree.PostId;
                moreChildren.Sort         = treeContext.Sort;
                moreChildren.Depth        = 0;
                final.Add(moreChildren);
            }

            return(final);
        }
Esempio n. 10
0
                #pragma warning restore 0649

        private static void GetArticle(HttpListenerContext client, int categoryIndex)
        {
            var req = client.Request;
            var url = req.Url.Segments;

            if (url.Length < 3)
            {
                client.Error(HttpStatusCode.BadRequest);
                return;
            }
            if (url[url.Length - 1].Contains("."))
            {
                client.GetFile();
                return;
            }
            if (!articles[categoryIndex].ContainsKey(url[2]))
            {
                client.Error(HttpStatusCode.NotFound);
                return;
            }
            var article = articles[categoryIndex][url[2]];
            var path    = ChickenSoup.RootFolder + article.Path;

            if (File.Exists(path))
            {
                var content  = File.ReadAllText(path);
                var comments = article.GetComments();
                var tree     = new CommentTree();
                foreach (var comment in comments)
                {
                    if (!tree.Add(comment))
                    {
                        throw new FormatException($"Comment file of {article.Name} has an invalid comment: {comment}");
                    }
                }
                var response = ArticleTemplate.Replace("{title}", article.Title)
                               .Replace("{time}", article.Date.ToString())
                               .Replace("{time(O)}", article.Date.ToString("O"));
                Action <Article, string, string> replaceLinks = (otherArticle, replace, conditional) =>
                {
                    if (otherArticle != null)
                    {
                        response = response.Replace(replace, otherArticle.Url);
                        response.Replace(replace, "");
                        response.Replace(conditional, "");
                    }
                    else
                    {
                        var s = response.IndexOf(conditional, StringComparison.InvariantCulture);
                        if (s < 0)
                        {
                            return;
                        }
                        var e = response.IndexOf(")}", s + conditional.Length, StringComparison.InvariantCulture) + 2;
                        response = response.Remove(s, e - s);
                    }
                };
                replaceLinks(article.Next, "{next}", "{next??(");
                replaceLinks(article.Previous, "{previous}", "{previous??(");
                response = response.Replace("{content}", File.ReadAllText(path))
                           .Replace("{comments}", GenerateCommentHtml(tree));
                client.WriteAndClose(response, "html", HttpStatusCode.OK);
            }
            else
            {
                client.Error(HttpStatusCode.NotFound);
            }
        }
Esempio n. 11
0
        public CommentTreeContext Build(CommentTree commentTree,
                                        Dictionary <Guid, double> sorter,
                                        List <Guid> children = null,
                                        Guid?comment         = null,
                                        int?limit            = null,
                                        int?maxDepth         = null,
                                        int context          = 0,
                                        bool continueThread  = true,
                                        bool loadMore        = true)
        {
            if (children != null && comment != null)
            {
                throw new Exception("You cannot build a tree for both a single comment, and multiple comments.");
            }

            var result = new CommentTreeContext();

            result.MaxDepth = maxDepth;

            if (children != null && children.Count == 0)
            {
                return(result);
            }

            if (commentTree.CommentIds.Count == 0)
            {
                return(result);
            }

            if (sorter == null)
            {
                sorter = new Dictionary <Guid, double>();
            }

            var candidates = new PriorityQueue <CommentQueue>();

            if (children != null)
            {
                UpdateCandidates(candidates, sorter, children.Where(x => commentTree.CommentIds.Contains(x)));
                result.DontCollapse.AddRange(candidates.Select(x => x.CommentId));
            }
            else if (comment.HasValue)
            {
                var currentComment = (Guid?)comment;
                var path           = new List <Guid>();

                if (!commentTree.CommentIds.Contains(comment.Value))
                {
                    throw new CommentNotFoundException();
                }

                while (currentComment.HasValue && path.Count <= context)
                {
                    path.Add(currentComment.Value);
                    currentComment = commentTree.Parents[currentComment.Value];
                }

                result.DontCollapse.AddRange(path);

                foreach (var commentId in path)
                {
                    var parent = commentTree.Parents[commentId];
                    commentTree.Tree[parent ?? Guid.Empty] = new List <Guid> {
                        commentId
                    };
                }

                UpdateCandidates(candidates, sorter, new List <Guid> {
                    path[path.Count - 1]
                });

                result.OffsetDepth = commentTree.Depth[path[path.Count - 1]];
            }
            else
            {
                var topLevelComments = commentTree.Tree.ContainsKey(Guid.Empty)
                    ? commentTree.Tree[Guid.Empty]
                    : new List <Guid>();
                UpdateCandidates(candidates, sorter, topLevelComments);
            }

            var items = new List <Guid>();

            while ((!limit.HasValue || items.Count < limit.Value) && candidates.Count > 0)
            {
                var candidate = candidates.Dequeue();

                var commentDepth = commentTree.Depth[candidate.CommentId] - result.OffsetDepth;

                if (!maxDepth.HasValue || commentDepth < maxDepth.Value)
                {
                    items.Add(candidate.CommentId);
                    if (commentTree.Tree.ContainsKey(candidate.CommentId))
                    {
                        UpdateCandidates(candidates, sorter, commentTree.Tree[candidate.CommentId]);
                    }
                }
                else if (continueThread && commentTree.Parents[candidate.CommentId] != null)
                {
                    var parentId = commentTree.Parents[candidate.CommentId].Value;
                    if (!result.MoreRecursion.Contains(parentId))
                    {
                        result.MoreRecursion.Add(parentId);
                    }
                }
            }

            result.Comments.AddRange(items);
            result.TopLevelComments.AddRange(result.Comments.Where(x => commentTree.Depth[x] == 0));
            result.TopLevelCandidates = candidates.Where(x => ((commentTree.Depth.ContainsKey(x.CommentId) ? commentTree.Depth[x.CommentId] : 0) == 0)).Select(x => x.CommentId).ToList();

            UpdateChildrenCount(result, commentTree, items.Union(result.TopLevelCandidates).ToList());

            return(result);
        }
        public List<ICommentNode> Build(CommentTree tree, CommentTreeContext treeContext, User currentUser)
        {
            var wrapped = _commentWrapper.Wrap(treeContext.Comments, currentUser).ToDictionary(x => x.Comment.Id, x => new CommentNode(x));
            var final = new List<ICommentNode>();
            var walked = new List<Guid>();

            // lets mark any comments as collapsed if needed
            foreach (var comment in wrapped.Values)
            {
                // TODO: make this configurable per-user
                int minimumScore = 0;
                if ((comment.Comment.Author != null && currentUser != null) && currentUser.Id == comment.Comment.Author.Id)
                {
                    // the current user is the author, don't collapse!
                    comment.Collapsed = false;
                }
                else if (comment.Comment.Score < minimumScore)
                {
                    // too many down votes to show to the user
                    comment.Collapsed = true;
                }
                else
                {
                    // the current user is not the author, and we have enough upvotes to display,
                    // don't collapse
                    comment.Collapsed = false;
                }
            }

            foreach (var comment in wrapped.Values)
            {
                comment.NumberOfChildren = treeContext.CommentsChildrenCount[comment.Comment.Comment.Id];

                CommentNode parent = null;

                if (comment.Comment.Comment.ParentId.HasValue)
                    parent = wrapped.ContainsKey(comment.Comment.Comment.ParentId.Value)
                        ? wrapped[comment.Comment.Comment.ParentId.Value]
                        : null;

                if (comment.Comment.Comment.ParentId.HasValue && treeContext.Comments.Contains(comment.Comment.Comment.ParentId.Value))
                    comment.IsParentVisible = true;

                if (parent != null && comment.Comment.CurrentUserIsAuthor)
                {
                    // this comment is the current user, so lets walk the parents
                    // and uncollapse any comments which may be collapsed
                    var ancestor = parent;
                    while (ancestor != null && !walked.Contains(ancestor.Comment.Comment.Id))
                    {
                        ancestor.Collapsed = false;
                        walked.Add(ancestor.Comment.Comment.Id);
                        ancestor = (ancestor.Comment.Comment.ParentId.HasValue && wrapped.ContainsKey(comment.Comment.Comment.ParentId.Value))
                            ? wrapped[comment.Comment.Comment.ParentId.Value]
                            : null;
                    }
                }

                if (treeContext.MoreRecursion.Contains(comment.Comment.Comment.Id))
                    comment.Children.Add(new MoreRecursionNode(comment.Comment));

                if (parent != null)
                {
                    comment.Parent = comment.Comment;
                    parent.Children.Add(comment);
                }
                else
                {
                    if (comment.Comment.Comment.ParentId.HasValue)
                    {
                        // we don't have a parent here, but this comment does have a parent.
                        // we need to get it
                        comment.Parent = _commentWrapper.Wrap(comment.Comment.Comment.ParentId.Value);
                    }
                    final.Add(comment);
                }
            }

            foreach (var visibleId in wrapped.Keys)
            {
                // this item is already scheduled to have a new link to see all the children
                if (treeContext.MoreRecursion.Contains(visibleId)) continue;

                var children = tree.Tree.ContainsKey(visibleId) ? tree.Tree[visibleId] : new List<Guid>();
                var missingChildren = children.Where(x => !treeContext.Comments.Contains(x)).ToList();

                if (missingChildren.Count > 0)
                {
                    var visibleChildren = children.Where(x => treeContext.Comments.Contains(x)).ToList();
                    var visibleCount = visibleChildren.Sum(x => (treeContext.CommentsChildrenCount[x]) + 1);
                    var missingCount = treeContext.CommentsChildrenCount[visibleId] - visibleCount;
                    var missingDepth = (tree.Depth.ContainsKey(visibleId) ? tree.Depth[visibleId] : 0) + 1 -
                                       treeContext.OffsetDepth;

                    var moreChildren = new MoreChildren();
                    moreChildren.ChildComments.AddRange(missingChildren);
                    moreChildren.MissingCount = missingCount;
                    moreChildren.PostId = tree.PostId;
                    moreChildren.Sort = treeContext.Sort;
                    moreChildren.Depth = missingDepth;
                    wrapped[visibleId].Children.Add(moreChildren);
                }
            }

            if (treeContext.TopLevelCandidates.Count > 0)
            {
                var moreChildren = new MoreChildren();
                moreChildren.ChildComments.AddRange(treeContext.TopLevelCandidates);
                moreChildren.MissingCount = moreChildren.ChildComments.Sum(x => (treeContext.CommentsChildrenCount.ContainsKey(x) ? treeContext.CommentsChildrenCount[x] : 0) + 1);
                moreChildren.PostId = tree.PostId;
                moreChildren.Sort = treeContext.Sort;
                moreChildren.Depth = 0;
                final.Add(moreChildren);
            }

            return final;
        }
Esempio n. 13
0
 public CommentBuilder(CommentTree commentTree)
 {
     _tree = commentTree;
 }