Esempio n. 1
0
        public static async Task CheckPostsForAutoReply(List <Subreddit> subreddits)
        {
            List <Post> recentPosts = new List <Post>();

            foreach (Subreddit subreddit in subreddits)
            {
                List <Post> subredditPosts = await RedditHelper.GetPosts(subreddit, 10);

                subredditPosts = BotUtilities.RemoveAlreadySeenPosts(subredditPosts);
                subredditPosts = BotUtilities.RemoveBlacklisted(subredditPosts, new[] { BlacklistLevel.NoPostReplies, BlacklistLevel.OnlyKeywordReplies, BlacklistLevel.Total }); //Remove posts from users who don't want the bot to automatically reply to them

                foreach (Post post in subredditPosts.ToList())
                {
                    if (post.IsSelfPost)
                    {
                        subredditPosts.Remove(post);
                        ConsoleHelper.Write($"\tSkipping {post.Id} (self-post)", ConsoleColor.Red);
                        BotUtilities.LogPostBeenSeen(post, "self-post");
                    }

                    double ageInMin = (DateTime.UtcNow - post.CreatedUTC).TotalMinutes;
                    if (ageInMin > 30)
                    {
                        subredditPosts.Remove(post);
                        ConsoleHelper.Write($"\tSkipping {post.Id} (too old: {Math.Round(ageInMin, 2)} min)", ConsoleColor.Red);
                        BotUtilities.LogPostBeenSeen(post, $"too old ({Math.Round(ageInMin, 2)} min)");
                    }
                }

                recentPosts.AddRange(subredditPosts);
            }

            foreach (Post post in recentPosts)
            {
                try
                {
                    string postTitle = WebUtility.HtmlDecode(post.Title);

                    Console.WriteLine($"\tTrying to get an automatic reply for post (/r/{post.SubredditName}): {postTitle}");

                    SearchResult searchResult = MountainProjectDataSearch.ParseRouteFromString(postTitle);
                    if (!searchResult.IsEmpty())
                    {
                        ApprovalRequest approvalRequest = new ApprovalRequest
                        {
                            RedditPost   = post,
                            SearchResult = searchResult
                        };

                        PostsPendingApproval.TryAdd(post.Id, approvalRequest);

                        BotUtilities.LogPostBeenSeen(post, searchResult.Confidence == 1 ? "auto-replying" : "pending approval");

                        if (!DryRun)
                        {
                            if (searchResult.Confidence == 1)
                            {
                                string reply = BotReply.GetFormattedString(searchResult);
                                reply += Markdown.HRule;
                                reply += BotReply.GetBotLinks(post);

                                Comment botReplyComment = await RedditHelper.CommentOnPost(post, reply);

                                monitoredComments.Add(new CommentMonitor()
                                {
                                    Parent = post, BotResponseComment = botReplyComment
                                });
                                ConsoleHelper.Write($"\n\tAuto-replied to post {post.Id}", ConsoleColor.Green);
                            }
                            else
                            {
                                //Until we are more confident with automatic results, we're going to request for approval for confidence values greater than 1 (less than 100%)
                                ConsoleHelper.Write($"\tRequesting approval for post {post.Id}", ConsoleColor.Yellow);
                                BotUtilities.RequestApproval(approvalRequest);
                            }

                            BotUtilities.LogOrUpdateSpreadsheet(approvalRequest);
                        }
                    }
                    else
                    {
                        Console.WriteLine("\tNothing found");
                        BotUtilities.LogPostBeenSeen(post, "nothing found");
                    }
                }
                catch (RateLimitException)
                {
                    Console.WriteLine("\tRate limit hit. Postponing reply until next iteration");
                }
                catch (Exception e)
                {
                    Console.WriteLine($"\tException occurred with post {RedditHelper.GetFullLink(post.Permalink)}");
                    Console.WriteLine($"\t{e.Message}\n{e.StackTrace}");
                }
            }
        }
Esempio n. 2
0
        public static async Task ReplyToApprovedPosts()
        {
            int removed = 0;

            foreach (string approvalRequestId in PostsPendingApproval.Keys) //Remove approval requests that have "timed out"
            {
                if (PostsPendingApproval[approvalRequestId].Force)
                {
                    continue;
                }

                if ((DateTime.UtcNow - PostsPendingApproval[approvalRequestId].RedditPost.CreatedUTC).TotalMinutes > 30)
                {
                    //Try to remove until we are able (another thread may be accessing it at this time)
                    bool removeSuccess = PostsPendingApproval.TryRemove(approvalRequestId, out _);
                    while (!removeSuccess)
                    {
                        removeSuccess = PostsPendingApproval.TryRemove(approvalRequestId, out _);
                    }

                    removed++;
                }
            }

            if (removed > 0)
            {
                ConsoleHelper.Write($"\tRemoved {removed} pending auto-replies that got too old", ConsoleColor.Red);
            }

            List <ApprovalRequest> approvedPosts = PostsPendingApproval.Where(p => p.Value.IsApproved).Select(p => p.Value).ToList();

            foreach (ApprovalRequest approvalRequest in approvedPosts)
            {
                string reply = "";
                foreach (MPObject mpObject in approvalRequest.ApprovedResults)
                {
                    Area relatedLocation = approvalRequest.RelatedLocation;
                    if (!mpObject.Parents.Contains(approvalRequest.RelatedLocation))
                    {
                        relatedLocation = null;
                    }

                    reply += BotReply.GetFormattedString(new SearchResult(mpObject, relatedLocation));
                    reply += Markdown.HRule;
                }

                reply += BotReply.GetBotLinks(approvalRequest.RedditPost);

                if (!DryRun)
                {
                    Comment botReplyComment = await RedditHelper.CommentOnPost(approvalRequest.RedditPost, reply);

                    monitoredComments.Add(new CommentMonitor()
                    {
                        Parent = approvalRequest.RedditPost, BotResponseComment = botReplyComment
                    });
                    ConsoleHelper.Write($"\tAuto-replied to post {approvalRequest.RedditPost.Id}", ConsoleColor.Green);
                    BotUtilities.LogOrUpdateSpreadsheet(approvalRequest);
                }

                //Try to remove until we are able (another thread may be accessing it at this time)
                bool removeSuccess = PostsPendingApproval.TryRemove(approvalRequest.RedditPost.Id, out _);
                while (!removeSuccess)
                {
                    removeSuccess = PostsPendingApproval.TryRemove(approvalRequest.RedditPost.Id, out _);
                }
            }
        }