示例#1
0
        // Async workers
        
        private void GroupsWork(Object sender, DoWorkEventArgs args)
        {
            // Do not access the form's BackgroundWorker reference directly. 
            // Instead, use the reference provided by the sender parameter.
            var bw = sender as BackgroundWorker;

            // Extract the argument.
            var param = args.Argument as GroupPostsParam;
            var groupId = param.gid;
            if (param.from <= param.to)
            {
                postsFromDate = param.from;
                postsToDate = param.to;
            }
            else
            {
                postsFromDate = param.to;
                postsToDate = param.from;
            }

            var context = new VkRestApi.VkRestContext(userId, authToken);
            var sb = new StringBuilder();
            isRunning = true;

            // gather group statistics
            if (param.justStats)
            {

                bw.ReportProgress(1, "Getting group stats");

                sb.Length = 0;
                sb.Append("group_id=").Append(Math.Abs(groupId).ToString()).Append("&");
                sb.Append("date_from=").Append(this.postsFromDate.ToString("yyyy-MM-dd")).Append("&");
                sb.Append("date_to=").Append(this.postsToDate.ToString("yyyy-MM-dd"));
                context.Parameters = sb.ToString();
                Debug.WriteLine("Download parameters: " + context.Parameters);

                // call VK REST API
                vkRestApi.CallVkFunction(VkFunction.StatsGet, context);

                return;
            }

            // create stream writers
            // 1) group posts
            // group posts
            IEntity e = new Post();
            String fileName = Utils.GenerateFileName(WorkingFolderTextBox.Text, groupId, e);
            groupPostsWriter = File.CreateText(fileName);
            Utils.PrintFileHeader(groupPostsWriter, e);

            postsWithComments.Clear(); // reset comments reference list
            likes.Clear(); // reset likes
            posters.Clear(); // reset posters
            posterIds.Clear(); // clear poster ids
            visitorIds.Clear(); // clear visitor ids

            totalCount = 0;
            currentOffset = 0;
            step = 1;

            long timeLastCall = 0;

            // get group posts 100 at a time and store them in the file
            // request group posts
            while (isRunning)
            {
                if (bw.CancellationPending)
                    break;

                if(currentOffset > totalCount)
                {
                    // done
                    break;
                }

                bw.ReportProgress(step, "Getting " + currentOffset + " posts out of " + totalCount);

                sb.Length = 0;
                sb.Append("owner_id=").Append(groupId.ToString()).Append("&");
                sb.Append("offset=").Append(currentOffset).Append("&");
                sb.Append("count=").Append(POSTS_PER_REQUEST).Append("&");
                context.Parameters = sb.ToString();
                Debug.WriteLine("Download parameters: " + context.Parameters);

                context.Cookie = currentOffset.ToString();

                // play nice, sleep for 1/3 sec to stay within 3 requests/second limits
                timeLastCall = Utils.sleepTime(timeLastCall); 
                // call VK REST API
                vkRestApi.CallVkFunction(VkFunction.WallGet, context);

                // wait for the user data
                ReadyEvent.WaitOne();

                currentOffset += POSTS_PER_REQUEST;
            }

            groupPostsWriter.Close();

            if (postsWithComments.Count > 0)
            {
                // group comments
                e = new Comment();
                fileName = Utils.GenerateFileName(WorkingFolderTextBox.Text, groupId, e);
                groupCommentsWriter = File.CreateText(fileName);
                Utils.PrintFileHeader(groupCommentsWriter, e);

                // request group comments
                bw.ReportProgress(-1, "Getting comments");
                step = 10000 / postsWithComments.Count;

                timeLastCall = 0;

                for (var i = 0; i < postsWithComments.Count; i++)
                {
                    isRunning = true;
                    totalCount = 0;
                    currentOffset = 0;

                    bw.ReportProgress(step, "Getting " + (i + 1) + " post comments out of " + postsWithComments.Count);

                    while (isRunning)
                    {
                        if (bw.CancellationPending)
                            break;

                        if (currentOffset > totalCount)
                        {
                            // done
                            break;
                        }

                        sb.Length = 0;
                        sb.Append("owner_id=").Append(groupId.ToString()).Append("&"); // group id
                        sb.Append("post_id=").Append(postsWithComments[i]).Append("&"); // post id
                        sb.Append("need_likes=").Append(1).Append("&"); // request likes info
                        sb.Append("offset=").Append(currentOffset).Append("&");
                        sb.Append("count=").Append(POSTS_PER_REQUEST).Append("&");
                        context.Parameters = sb.ToString();
                        context.Cookie = postsWithComments[i].ToString(); // pass post id as a cookie
                        Debug.WriteLine("Request parameters: " + context.Parameters);

                        // play nice, sleep for 1/3 sec to stay within 3 requests/second limits
                        timeLastCall = Utils.sleepTime(timeLastCall);
                        // call VK REST API
                        vkRestApi.CallVkFunction(VkFunction.WallGetComments, context);

                        // wait for the user data
                        ReadyEvent.WaitOne();

                        currentOffset += POSTS_PER_REQUEST;
                    }
                }

                groupCommentsWriter.Close();
            }

            // process the likers - they will be added to the posters
            if (likes.Count > 0)
            {
                // request likers ids
                bw.ReportProgress(-1, "Getting likers");
                step = 10000 / likes.Count;

                timeLastCall = 0;

                for (int i = 0; i < this.likes.Count; i++)
                {
                    isRunning = true;
                    //this.totalCount = 0;
                    //this.currentOffset = 0;

                    bw.ReportProgress(step, "Getting " + (i + 1) + " likes out of " + this.likes.Count);

                    if (bw.CancellationPending)
                        break;

                    sb.Length = 0;
                    sb.Append("type=").Append(likes[i].type).Append("&"); // group id
                    sb.Append("owner_id=").Append(likes[i].owner_id).Append("&"); // group id
                    sb.Append("item_id=").Append(likes[i].item_id).Append("&"); // post id
                    sb.Append("count=").Append(LIKES_PER_REQUEST).Append("&");
                    context.Parameters = sb.ToString();
                    Debug.WriteLine("Request parameters: " + context.Parameters);

                    // play nice, sleep for 1/3 sec to stay within 3 requests/second limits
                    timeLastCall = Utils.sleepTime(timeLastCall);
                    // call VK REST API
                    vkRestApi.CallVkFunction(VkFunction.LikesGetList, context);

                    // wait for the user data
                    ReadyEvent.WaitOne();
                }
            }

            // now collect visitors (not members, who left a post or a comment or a like) 
            foreach (var p in posterIds)
            {
                if (!memberIds.Contains(p))
                {
                    // this is a visitor poster
                    visitorIds.Add(p);
                }
            }

            if (visitorIds.Count > 0)
            {
                // group visitors profiles
                e = new Profile();
                fileName = Utils.GenerateFileName(this.WorkingFolderTextBox.Text, groupId, e, "visitor");
                groupVisitorsWriter = File.CreateText(fileName);
                Utils.PrintFileHeader(groupVisitorsWriter, e);

                // request visitors info
                bw.ReportProgress(-1, "Getting visitors");
                step = 10000 / visitorIds.Count;

                timeLastCall = 0;

                for (var i = 0; i < visitorIds.Count; i += 100)
                {
                    isRunning = true;
                    //this.totalCount = 0;
                    //this.currentOffset = 0;

                    bw.ReportProgress(step, "Getting " + (i + 1) + " visitors out of " + visitorIds.Count);

                    if (bw.CancellationPending)
                        break;

                    sb.Length = 0;

                    sb.Append("user_ids=");

                    for (var j = i; j < visitorIds.Count && j < i + 100; ++j)
                    {
                        sb.Append(visitorIds[j]).Append(","); // users
                    }

                    sb.Append("&").Append("fields=").Append(PROFILE_FIELDS);

                    context.Parameters = sb.ToString();
                    Debug.WriteLine("Request parameters: " + context.Parameters);

                    // play nice, sleep for 1/3 sec to stay within 3 requests/second limits
                    timeLastCall = Utils.sleepTime(timeLastCall);
                    // call VK REST API
                    vkRestApi.CallVkFunction(VkFunction.UsersGet, context);

                    // wait for the user data
                    ReadyEvent.WaitOne();

                }

                groupVisitorsWriter.Close();
            }

            //args.Result = TimeConsumingOperation(bw, arg);

            // If the operation was canceled by the user,  
            // set the DoWorkEventArgs.Cancel property to true. 
            if (bw.CancellationPending)
            {
                args.Cancel = true;
            }
        }
示例#2
0
        // Async workers
        private void GroupsWork(Object sender, DoWorkEventArgs args)
        {
            // Do not access the form's BackgroundWorker reference directly. 
            // Instead, use the reference provided by the sender parameter.
            var bw = sender as BackgroundWorker;

            // Extract the argument.
            var param = args.Argument as GroupPostsParam;

            if (bw == null ||
                param == null)
            {
                throw new ArgumentException("Illegal arguments for Group Work");
            }

            if (param.From <= param.To)
            {
                postsFromDate = param.From;
                postsToDate = param.To;
            }
            else
            {
                postsFromDate = param.To;
                postsToDate = param.From;
            }

            // working directory
            var workingDir = WorkingFolderTextBox.Text;

            // clear all
            postsWithComments.Clear(); // reset reference list
            likes.Clear(); // reset likes
            posters.Clear(); // reset posters
            posterIds.Clear(); // clear poster ids
            visitorIds.Clear(); // clear visitor ids
            postInfo.Clear(); // clear post infos
            boardPostInfo.Clear(); // reset boards post infos
            topics.Clear(); // clear topics infos
            u2uMatrix.Clear(); // clear u2u matrix

            var context = new VkRestApi.VkRestContext(this.userId, this.authToken);
            var sb = new StringBuilder();
            long timeLastCall = 0;

            networkEntities = param.GroupWall ? "wall" : "";
            networkEntities += param.GroupTopics ? "-topics" : "";

            // gather group statistics
            if (param.JustStats)
            {
                ResetCountersAndGetReady();

                bw.ReportProgress(1, "Getting group stats");

                sb.Length = 0;
                // TODO check if it takes negative number
                sb.Append("group_id=").Append(groupId).Append("&");
                sb.Append("date_from=").Append(this.postsFromDate.ToString("yyyy-MM-dd")).Append("&");
                sb.Append("date_to=").Append(this.postsToDate.ToString("yyyy-MM-dd"));
                context.Parameters = sb.ToString();
                Debug.WriteLine("Download parameters: " + context.Parameters);

                // call VK REST API
                vkRestApi.CallVkFunction(VkFunction.StatsGet, context);
                return;
            }

            IEntity e;
            string fileName;

            if (param.GroupWall)
            {
                // group posts
                e = new Post();
                fileName = Utils.GenerateFileName(workingDir, groupId, e);
                groupPostsWriter = File.CreateText(fileName);
                Utils.PrintFileHeader(groupPostsWriter, e);

                e = new PostCopyHistory(0, null);
                fileName = Utils.GenerateFileName(workingDir, groupId, e);
                groupPostsCopyHistoryWriter = File.CreateText(fileName);
                Utils.PrintFileHeader(groupPostsCopyHistoryWriter, e);

                ResetCountersAndGetReady();

                // request group posts
                bw.ReportProgress(-1, "Getting posts");
                while (ShellContinue(bw))
                {
                    sb.Length = 0;
                    sb.Append("owner_id=").Append(groupId.ToString()).Append("&");
                    sb.Append("offset=").Append(currentOffset).Append("&");
                    sb.Append("count=").Append(POSTS_PER_REQUEST).Append("&");
                    context.Parameters = sb.ToString();
                    Debug.WriteLine("Download parameters: " + context.Parameters);

                    context.Cookie = currentOffset.ToString();

                    // play nice, sleep for 1/3 sec to stay within 3 requests/second limits
                    timeLastCall = Utils.sleepTime(timeLastCall);
                    // call VK REST API
                    vkRestApi.CallVkFunction(VkFunction.WallGet, context);

                    // wait for the user data
                    ReadyEvent.WaitOne();
                    bw.ReportProgress(step, "Getting " + currentOffset + " posts out of " + totalCount);
                }

                groupPostsWriter.Close();
                groupPostsCopyHistoryWriter.Close();

                if (postsWithComments.Count > 0 &&
                    !bw.CancellationPending)
                {
                    // group comments
                    e = new Comment();
                    fileName = Utils.GenerateFileName(workingDir, groupId, e);
                    groupCommentsWriter = File.CreateText(fileName);
                    Utils.PrintFileHeader(groupCommentsWriter, e);

                    // request group comments
                    bw.ReportProgress(-1, "Getting comments");

                    timeLastCall = 0;

                    for (int i = 0; i < postsWithComments.Count && !bw.CancellationPending; i++)
                    {
                        ResetCountersAndGetReady();
                        step = CalcStep(postsWithComments.Count);

                        bw.ReportProgress(step,
                            "Getting " + (i + 1) + " comments out of " + postsWithComments.Count);

                        while (ShellContinue(bw))
                        {
                            sb.Length = 0;
                            sb.Append("owner_id=").Append(groupId).Append("&"); // group id
                            sb.Append("post_id=").Append(postsWithComments[i]).Append("&"); // post id
                            sb.Append("need_likes=").Append(1).Append("&"); // request likes info
                            sb.Append("offset=").Append(currentOffset).Append("&");
                            sb.Append("count=").Append(POSTS_PER_REQUEST).Append("&");
                            context.Parameters = sb.ToString();
                            context.Cookie = postsWithComments[i].ToString(); // pass post id as a cookie
                            Debug.WriteLine("Request parameters: " + context.Parameters);

                            // play nice, sleep for 1/3 sec to stay within 3 requests/second limits
                            timeLastCall = Utils.sleepTime(timeLastCall);
                            // call VK REST API
                            vkRestApi.CallVkFunction(VkFunction.WallGetComments, context);

                            // wait for the user data
                            ReadyEvent.WaitOne();
                        }
                    }

                    groupCommentsWriter.Close();
                }
            }

            if (param.GroupTopics)
            {
                // process group board topics and comments
                e = new BoardTopic();
                fileName = Utils.GenerateFileName(workingDir, groupId, e);
                groupBoardTopicsWriter = File.CreateText(fileName);
                Utils.PrintFileHeader(groupBoardTopicsWriter, e);

                e = new Comment();
                fileName = Utils.GenerateFileName(workingDir, groupId, e, "board");
                groupBoardCommentsWriter = File.CreateText(fileName);
                Utils.PrintFileHeader(groupBoardCommentsWriter, e);

                ResetCountersAndGetReady();

                bw.ReportProgress(-1, "Getting board topics");

                // get group board topics
                while (ShellContinue(bw))
                {
                    sb.Length = 0;
                    sb.Append("group_id=").Append(Math.Abs(groupId)).Append("&");
                    sb.Append("offset=").Append(currentOffset).Append("&");
                    sb.Append("count=").Append(POSTS_PER_REQUEST).Append("&");
                    context.Parameters = sb.ToString();
                    Debug.WriteLine("Download parameters: " + context.Parameters);

                    context.Cookie = currentOffset.ToString();

                    // play nice, sleep for 1/3 sec to stay within 3 requests/second limits
                    timeLastCall = Utils.sleepTime(timeLastCall);
                    // call VK REST API
                    vkRestApi.CallVkFunction(VkFunction.BoardGetTopics, context);

                    // wait for the user data
                    ReadyEvent.WaitOne();
                    bw.ReportProgress(step, "Getting board topics " + currentOffset + " out of " + totalCount);
                }

                bw.ReportProgress(-1, "Getting board comments");

                // collect comments from all board topics
                for (var i = 0; i < topics.Count; i++)
                {
                    if (bw.CancellationPending)
                        break; // canceled

                    if (topics[i].is_closed || topics[i].comments == 0)
                        continue; // empty or closed topic - ignore

                    ResetCountersAndGetReady();
                    step = CalcStep(topics.Count);
                    bw.ReportProgress(step, "Getting comments for board " + i + " / " + topics.Count);

                    while (ShellContinue(bw))
                    {
                        sb.Length = 0;
                        sb.Append("group_id=").Append(Math.Abs(groupId)).Append("&"); // group id
                        sb.Append("topic_id=").Append(topics[i].id).Append("&"); // post id
                        sb.Append("need_likes=").Append(1).Append("&"); // need likes count
                        sb.Append("offset=").Append(currentOffset).Append("&");
                        sb.Append("count=").Append(POSTS_PER_REQUEST).Append("&");
                        context.Parameters = sb.ToString();
                        context.Cookie = topics[i].id.ToString(); // pass topic id as a cookie
                        Debug.WriteLine("Request parameters: " + context.Parameters);

                        // play nice, sleep for 1/3 sec to stay within 3 requests/second limits
                        timeLastCall = Utils.sleepTime(timeLastCall);
                        // call VK REST API
                        vkRestApi.CallVkFunction(VkFunction.BoardGetComments, context);

                        // wait for the user data
                        ReadyEvent.WaitOne();
                        bw.ReportProgress(0,
                            "Getting comments " + currentOffset + " / " + totalCount + " for board " + i + " / " +
                            topics.Count);
                    }
                }

                groupBoardTopicsWriter.Close();
                groupBoardCommentsWriter.Close();
            }

            // process the likes from wall and board topics
            if (likes.Count > 0 &&
                !bw.CancellationPending)
            {
                // request likers ids
                ResetCountersAndGetReady();
                bw.ReportProgress(-1, "Getting likers");

                timeLastCall = 0;
                step = CalcStep(likes.Count);

                for (var i = 0; i < likes.Count; i++)
                {
                    isRunning = true;
                    bw.ReportProgress(step, "Getting likes " + (i + 1) + " / " + likes.Count);

                    if (bw.CancellationPending)
                        break;

                    sb.Length = 0;
                    sb.Append("type=").Append(likes[i].type).Append("&"); // type
                    sb.Append("owner_id=").Append(likes[i].owner_id).Append("&"); // group id
                    sb.Append("item_id=").Append(likes[i].item_id).Append("&"); // post id
                    sb.Append("count=").Append(LIKES_PER_REQUEST).Append("&");
                    context.Parameters = sb.ToString();
                    context.Cookie = likes[i].item_id.ToString(); // pass post/comment id as a cookie
                    Debug.WriteLine("Request parameters: " + context.Parameters);

                    // play nice, sleep for 1/3 sec to stay within 3 requests/second limits
                    timeLastCall = Utils.sleepTime(timeLastCall);
                    // call VK REST API
                    vkRestApi.CallVkFunction(VkFunction.LikesGetList, context);

                    // wait for the user data
                    ReadyEvent.WaitOne();
                }
            }

            // now collect info about posters (users or visitors who left post, comment or like) 
            visitorIds.AddRange(posterIds);

            if (visitorIds.Count > 0 &&
                !bw.CancellationPending)
            {
                // group visitors profiles
                e = new Profile();
                fileName = Utils.GenerateFileName(workingDir, groupId, e, networkEntities);
                groupVisitorsWriter = File.CreateText(fileName);
                Utils.PrintFileHeader(groupVisitorsWriter, e);

                // request visitors info
                bw.ReportProgress(-1, "Getting visitors");
                step = CalcStep(visitorIds.Count, 100);

                timeLastCall = 0;

                for (var i = 0; i < visitorIds.Count; i += 100)
                {
                    isRunning = true;

                    bw.ReportProgress(step, "Getting " + (i + 1) + " visitors out of " + visitorIds.Count);

                    if (bw.CancellationPending)
                        break;

                    sb.Length = 0;

                    sb.Append("user_ids=");

                    for (var j = i; j < visitorIds.Count && j < i + 100; ++j)
                    {
                        sb.Append(visitorIds[j]).Append(","); // users
                    }

                    sb.Append("&").Append("fields=").Append(PROFILE_FIELDS);

                    context.Parameters = sb.ToString();
                    Debug.WriteLine("Request parameters: " + context.Parameters);

                    // play nice, sleep for 1/3 sec to stay within 3 requests/second limits
                    timeLastCall = Utils.sleepTime(timeLastCall);
                    // call VK REST API
                    vkRestApi.CallVkFunction(VkFunction.UsersGet, context);

                    // wait for the user data
                    ReadyEvent.WaitOne();
                }

                groupVisitorsWriter.Close();
            }


            // update group posts/likes count (posted from group id)
            Poster groupPoster;
            if (posters.TryGetValue((long)this.groupId, out groupPoster))
            {
                var attr = dictionaryFromPoster(groupPoster);
                // update poster vertex attributes
                contentNetworkAnalyzer.UpdateVertexAttributes((long)groupId, attr);
            }


            // If the operation was canceled by the user,  
            // set the DoWorkEventArgs.Cancel property to true. 
            args.Cancel = bw.CancellationPending;

            // complete the job
            //args.Result = 
        }
示例#3
0
        // process group comments
        private void OnWallGetComments(JObject data, String cookie)
        {
            if (data[VkRestApi.ResponseBody] == null)
            {
                isRunning = false;
                return;
            }

            if (totalCount == 0)
            {
                totalCount = data[VkRestApi.ResponseBody]["count"].ToObject<long>();
            }
            
            // now calculate items in response
            var count = data[VkRestApi.ResponseBody]["items"].Count();

            var gId = (long)(isGroup ? decimal.Negate(groupId) : groupId);
            var comments = new List<Comment>();

            // process response body
            for (var i = 0; i < count; ++i)
            {
                var postObj = data[VkRestApi.ResponseBody]["items"][i].ToObject<JObject>();
                
                var comment = new Comment();
                comment.id = Utils.getLongField("id", postObj);
                comment.post_id = Convert.ToInt64(cookie); // passed as a cookie
                comment.from_id = Utils.getLongField("from_id", postObj);
                // post date
                comment.date = Utils.getStringDateField("date", postObj);

                comment.reply_to_uid = Utils.getLongField("reply_to_uid", postObj);
                comment.reply_to_cid = Utils.getLongField("reply_to_cid", postObj);
                
                // likes/dislikes
                comment.likes = Utils.getLongField("likes", "count", postObj);
                if (comment.likes > 0)
                {
                    var like = new Like();
                    like.type = "comment";
                    like.owner_id = gId;
                    like.item_id = comment.id;
                    likes.Add(like);
                }
 
                // attachments count
                if (postObj["attachments"] != null)
                {
                    comment.attachments = postObj["attachments"].ToArray().Length;
                }
        
                // post text
                comment.text = Utils.getTextField("text", postObj);

                // update posters
                if (comment.from_id != gId)
                {
                    if (!posters.ContainsKey(comment.from_id))
                    {
                        posters[comment.from_id] = new Poster();
                    }
                    
                    posters[comment.from_id].comments += 1; // increment number of comments
                    posters[comment.from_id].rec_likes += comment.likes;

                    // add to the poster ids
                    posterIds.Add(comment.from_id);
                }

                comments.Add(comment);
            }

            if (comments.Count > 0)
            {
                // save the posts list
                Utils.PrintFileContent(groupCommentsWriter, comments);
            }
        }
示例#4
0
        // process group board topic comments
        private void OnBoardGetComments(JObject data, string cookie)
        {
            if (data[VkRestApi.ResponseBody] == null)
            {
                isRunning = false;
                return;
            }

            if (totalCount == 0)
            {
                totalCount = data[VkRestApi.ResponseBody]["count"].ToObject<int>();
                if (totalCount == 0)
                {
                    isRunning = false;
                    return;
                }
                step = CalcStep(totalCount, POSTS_PER_REQUEST);
            }

            // calculate items in response
            var count = data[VkRestApi.ResponseBody]["items"].Count();

            if (!CheckAndIncrement(count))
                return;
            
            var comments = new List<Comment>();
            var board_id = Convert.ToInt64(cookie); // passed as a cookie

            // process response body
            for (int i = 0; i < count; ++i)
            {
                var postObj = data[VkRestApi.ResponseBody]["items"][i].ToObject<JObject>();

                var comment = new Comment();
                comment.id = Utils.getLongField("id", postObj);
                comment.post_id = board_id;
                comment.from_id = Utils.getLongField("from_id", postObj);
                // post date
                comment.date = Utils.getStringDateField("date", postObj);
                comment.reply_to_uid = Utils.getLongField("reply_to_uid", postObj);
                comment.reply_to_cid = Utils.getLongField("reply_to_cid", postObj);
                comment.likes = Utils.getLongField("likes", "count", postObj);

                // likes
                if (comment.likes > 0)
                {
                    var like = new Like();
                    like.type = "topic_comment";
                    like.owner_id = (long)this.groupId;
                    like.item_id = comment.id;
                    likes.Add(like);
                }

                // attachments count
                if (postObj["attachments"] != null)
                {
                    comment.attachments = postObj["attachments"].ToArray().Length;
                }

                // post text
                comment.text = Utils.getTextField("text", postObj);

                // update posters
                if (!posters.ContainsKey(comment.from_id))
                {
                    posters[comment.from_id] = new Poster();
                }

                posters[comment.from_id].BoardComments += 1; // increment number of board comments
                posters[comment.from_id].RecLikes += comment.likes;

                // add to the poster ids
                if (comment.from_id != this.groupId)
                    posterIds.Add(comment.from_id);
    
                comments.Add(comment);

                // add to board post info
                if (!boardPostInfo.ContainsKey(comment.id))
                {
                    boardPostInfo[comment.id] = new PostInfo(comment.id, comment.from_id);
                }

                // update u2u matrix for replies
                var to = ParseCommentForReplyTo(comment.text);
                if (to > 0)
                {
                    UpdateU2UMatrix(comment.from_id, to, true); // reply is comment
                    posters[comment.from_id].Comments += 1;

                    // there must by a poster down there - update posters
                    if (!posters.ContainsKey(to))
                    {
                        posters[to] = new Poster();
                    }

                    posters[to].RecComments += 1; // increment number of received comments

                }
            }

            // save the board comments
            Utils.PrintFileContent(groupBoardCommentsWriter, comments);
        }