コード例 #1
0
        public static ValidationItemViewModel ValidateMaxPostPayoutRule(CurationDetailsViewModel model, ValidationVariables vars)
        {
            var validationItem = new ValidationItemViewModel();

            ValidationPriority   prio       = ValidationPriority.High;
            ValidationResultType resultType = ValidationResultType.Failure;

            validationItem.Title               = string.Format("Max post payout <= {0} for posts created within {1} days", vars.MaxPostPayoutAmount, vars.MaxPostPayoutDays);
            validationItem.Priority            = prio;
            validationItem.PriorityDescription = prio.ToString();
            validationItem.OrderId             = 20;

            // get posts within given range in MaxReceivedPayoutDays
            var     dateFrom              = DateTime.Now.AddDays(-vars.MaxPostPayoutDays);
            decimal maxPayoutReceived     = 0;
            double  maxPayoutReceivedDays = 0;

            // check if we have sufficient data to run the validation
            if (model.LastRetrievedPostDate > dateFrom)
            {
                resultType = ValidationResultType.Neutral;
                validationItem.ResultMessage = string.Format(Resources.General.DataSetInsufficientWarning, model.LastRetrievedPostDate.ToString("yyyy-MM-dd HH:mm"));
            }
            else
            {
                // get posts within range
                var posts = model.Posts.Where(x => x.CreatedAt >= dateFrom).ToList();

                if (posts != null && posts.Any())
                {
                    // get the post containing max value
                    var maxReceived = posts.OrderByDescending(x => x.PaidOutTotal).Take(1).FirstOrDefault();

                    if (maxReceived != null)
                    {
                        maxPayoutReceived     = maxReceived.PaidOutTotal;
                        maxPayoutReceivedDays = Math.Floor(DateTime.Now.Subtract(maxReceived.CreatedAt).TotalDays);
                    }
                }

                if (maxPayoutReceived > 0 && maxPayoutReceived <= vars.MaxPostPayoutAmount)
                {
                    resultType = ValidationResultType.Success;
                }
                else
                {
                    resultType = ValidationResultType.Failure;
                }
            }

            validationItem.ResultType            = resultType;
            validationItem.ResultTypeDescription = resultType.ToString();

            if (String.IsNullOrEmpty(validationItem.ResultMessage))
            {
                validationItem.ResultMessage = string.Format("${0} is the highest payout for a post created {1} days ago", maxPayoutReceived.ToString("N"), maxPayoutReceivedDays);
            }

            return(validationItem);
        }
コード例 #2
0
        /// <summary>
        /// This method runs all validation rules and returns a summary of the results & rules
        /// </summary>
        /// <param name="model">The model containing already retrieved results like Author details, Post details etc. used to run validation on.</param>
        /// <param name="vars">The validation variables being used to run the validation on the data</param>
        /// <returns>Returns the model containing validation results</returns>
        public ValidationSummaryViewModel RunValidation(CurationDetailsViewModel model, ValidationVariables vars)
        {
            var result = new ValidationSummaryViewModel();

            var validationItems = new List <ValidationItemViewModel>();

            try
            {
                validationItems.Add(ValidationHelper.ValidatePostCreateDateRule(model, vars));
                validationItems.Add(ValidationHelper.ValidatePostMaxPendingPayoutRule(model, vars));
                validationItems.Add(ValidationHelper.ValidateTotalMaxPendingPayoutRule(model, vars));
                validationItems.Add(ValidationHelper.ValidateMaxPostPayoutRule(model, vars));
                validationItems.Add(ValidationHelper.ValidateAuthorReputationRule(model, vars));
                validationItems.Add(ValidationHelper.ValidateMinPostsRule(model, vars));
                validationItems.Add(ValidationHelper.ValidateMinCommentsRule(model, vars));

                var upvoteAccountDetails = GetAccountDetails(vars.UpvoteAccount.Replace("@", ""));
                validationItems.Add(ValidationHelper.ValidateUpvoteAccountMinVPRule(upvoteAccountDetails, vars));

                validationItems.Add(ValidationHelper.ValidateMinDaysSinceLastUpvoteFromUpvoteAccount(model.Author.Details.name, model.UpvoteAccountVotes, vars));
            }
            catch (Exception ex)
            {
                _log.Error(ex);
            }

            result.Items = validationItems;

            return(result);
        }
コード例 #3
0
        public static ValidationItemViewModel ValidateAuthorReputationRule(CurationDetailsViewModel model, ValidationVariables vars)
        {
            ValidationPriority   prio       = ValidationPriority.High;
            ValidationResultType resultType = ValidationResultType.Failure;

            var validationItem = new ValidationItemViewModel();

            validationItem.Title               = string.Format("Author reputation is >= {0} and < {1}", vars.AuthorRepMin, vars.AuthorRepMax);
            validationItem.Priority            = prio;
            validationItem.PriorityDescription = prio.ToString();
            validationItem.OrderId             = 35;

            // Check if the author rep value is within the required range
            if (model.Author.ReputationCalculated >= vars.AuthorRepMin &&
                model.Author.ReputationCalculated < vars.AuthorRepMax)
            {
                resultType = ValidationResultType.Success;
            }
            else
            {
                resultType = ValidationResultType.Failure;
            }

            validationItem.ResultType            = resultType;
            validationItem.ResultTypeDescription = resultType.ToString();
            validationItem.ResultMessage         = string.Format("Author reputation is {0}", model.Author.ReputationCalculated.ToString("N"));

            return(validationItem);
        }
コード例 #4
0
        public static ValidationItemViewModel ValidatePostCreateDateRule(CurationDetailsViewModel model, ValidationVariables vars)
        {
            ValidationPriority   prio       = ValidationPriority.High;
            ValidationResultType resultType = ValidationResultType.Failure;

            var validationItem = new ValidationItemViewModel();

            validationItem.Title               = string.Format("Post creation date is >= {0} minutes and < {1} hours", vars.PostCreatedAtMin, vars.PostCreatedAtMax / 60);
            validationItem.Priority            = prio;
            validationItem.PriorityDescription = prio.ToString();
            validationItem.OrderId             = 10;

            var postCreatedDate = model.BlogPost.Details.created;

            // Check if the post creation date is between the required ranges
            if (DateTime.Now >= postCreatedDate.AddMinutes(vars.PostCreatedAtMin) &&
                DateTime.Now < postCreatedDate.AddMinutes(vars.PostCreatedAtMax))
            {
                resultType = ValidationResultType.Success;
            }
            else
            {
                resultType = ValidationResultType.Failure;
            }

            validationItem.ResultType            = resultType;
            validationItem.ResultTypeDescription = resultType.ToString();

            var span = (TimeSpan)(DateTime.Now - postCreatedDate);

            validationItem.ResultMessage = string.Format("Post created {0} days, {1} hours, {2} minutes ago.", span.Days, span.Hours, span.Minutes);

            return(validationItem);
        }
コード例 #5
0
        public static ValidationItemViewModel ValidatePostMaxPendingPayoutRule(CurationDetailsViewModel model, ValidationVariables vars)
        {
            var validationItem = new ValidationItemViewModel();

            ValidationPriority   prio       = ValidationPriority.High;
            ValidationResultType resultType = ValidationResultType.Failure;

            validationItem.Title               = string.Format("Post max pending payout value < {0}", vars.PostMaxPendingPayout);
            validationItem.Priority            = prio;
            validationItem.PriorityDescription = prio.ToString();
            validationItem.OrderId             = 25;

            decimal postPendingPayoutValue  = 0;
            var     postPendingPayoutString = model.BlogPost.Details.pending_payout_value.Replace("SBD", "").Trim();

            Decimal.TryParse(postPendingPayoutString, out postPendingPayoutValue);

            // check if the pending payout value of the post is less than the max payout setting
            if (postPendingPayoutValue < vars.PostMaxPendingPayout)
            {
                resultType = ValidationResultType.Success;
            }
            else
            {
                resultType = ValidationResultType.Failure;
            }

            validationItem.ResultType            = resultType;
            validationItem.ResultTypeDescription = resultType.ToString();

            validationItem.ResultMessage = string.Format("Post pending payout value = ${0}", postPendingPayoutValue.ToString("N"));

            return(validationItem);
        }
コード例 #6
0
        public static ValidationItemViewModel ValidateTotalMaxPendingPayoutRule(CurationDetailsViewModel model, ValidationVariables vars)
        {
            var validationItem = new ValidationItemViewModel();

            ValidationPriority   prio       = ValidationPriority.High;
            ValidationResultType resultType = ValidationResultType.Failure;

            validationItem.Title               = string.Format("Total max pending payout value < {0}", vars.TotalMaxPendingPayout);
            validationItem.Priority            = prio;
            validationItem.PriorityDescription = prio.ToString();
            validationItem.OrderId             = 30;

            // if the oldest post retrieved is a more recent post than 1 week before current date, we don't have enough data to validate this rule
            var dateCheck = DateTime.Now.AddDays(-7);

            if (model.LastRetrievedPostDate > dateCheck)
            {
                if (model.Author.PendingPostPayout > vars.TotalMaxPendingPayout)
                {
                    resultType = ValidationResultType.Failure;
                }
                else
                {
                    resultType = ValidationResultType.Neutral;
                    validationItem.ResultMessage = string.Format(Resources.General.DataSetInsufficientWarning, model.LastRetrievedPostDate.ToString("yyyy-MM-dd HH:mm"));
                }
            }
            else
            {
                if (model.Author.PendingPostPayout < vars.TotalMaxPendingPayout)
                {
                    resultType = ValidationResultType.Success;
                }
                else
                {
                    resultType = ValidationResultType.Failure;
                }
            }

            validationItem.ResultType            = resultType;
            validationItem.ResultTypeDescription = resultType.ToString();

            if (String.IsNullOrEmpty(validationItem.ResultMessage))
            {
                validationItem.ResultMessage = string.Format("Total pending payout value = ${0}", model.Author.PendingPostPayout.ToString("N"));
            }

            return(validationItem);
        }
コード例 #7
0
        public ActionResult ValidatePost(HomeViewModel model)
        {
            var result = new CurationDetailsViewModel();

            try
            {
                // split link into parts to get account name
                var linkItems   = model.PostLink.Split('/');
                var accountName = linkItems.FirstOrDefault(x => x.Contains("@"));
                var permlink    = linkItems.LastOrDefault();

                accountName = accountName.Replace("@", "");

                // get account details
                result.Author = GetAuthor(accountName);

                // get account history details
                GetAccountHistoryDetails(accountName, result);

                // get_discussion
                result.BlogPost = GetBlogPost(accountName, permlink);

                // get upvote account votes for author
                result.UpvoteAccountVotes = GetLastUpvotesFromUpvoteAccountToAuthor(accountName, model.ValidationVariables);

                if (result.BlogPost != null)
                {
                    // validate data
                    result.ValidationSummary = RunValidation(result, model.ValidationVariables);
                }

                // return only a subset of posts
                result.Posts = result.Posts.Take(ConfigurationHelper.PostTransactionCount).ToList();
            }
            catch (Exception ex)
            {
                _log.Error(ex);
            }

            return(Json(result));
        }
コード例 #8
0
        public static ValidationItemViewModel ValidateMinCommentsRule(CurationDetailsViewModel model, ValidationVariables vars)
        {
            ValidationPriority   prio       = ValidationPriority.High;
            ValidationResultType resultType = ValidationResultType.Failure;

            var validationItem = new ValidationItemViewModel();

            validationItem.Title               = string.Format("Required minimum # comments {0} in last {1} days", vars.CommentsMin, vars.CommentsMinDays);
            validationItem.Priority            = prio;
            validationItem.PriorityDescription = prio.ToString();
            validationItem.OrderId             = 50;

            // get comments within range
            var dateCheck    = DateTime.Now.AddDays(-vars.CommentsMinDays);
            var commentCount = model.Comments.Count(x => x.TimeStamp >= dateCheck);

            if (commentCount >= vars.CommentsMin)
            {
                resultType = ValidationResultType.Success;
                validationItem.ResultMessage = string.Format("Author posted {0} comments in last {1} days.", commentCount, vars.CommentsMinDays);
            }
            else
            {
                if (model.LastTransactionDate > dateCheck)
                {
                    resultType = ValidationResultType.Neutral;
                    validationItem.ResultMessage = string.Format(Resources.General.DataSetInsufficientWarning, model.LastTransactionDate.ToString("yyyy-MM-dd HH:mm"));
                }
                else
                {
                    resultType = ValidationResultType.Failure;
                    validationItem.ResultMessage = string.Format("Author posted {0} comments in last {1} days.", commentCount, vars.CommentsMinDays);
                }
            }

            validationItem.ResultType            = resultType;
            validationItem.ResultTypeDescription = resultType.ToString();

            return(validationItem);
        }
コード例 #9
0
        /// <summary>
        /// This method makes subsequent calls to get_account_history on Steem in order to collect sufficient amount of data to run validation on
        /// The batchSize parameter defines the limit of the transactions we want to be returned from Steem API.
        /// The web.config setting HistoryTransactionLimit contains the max value of transactions we set in order to prevent calling the Steem API a lot of times
        /// Based on the "op" variable in the returned transactions, the values will be mapped to corresponding classes and added to result set to return.
        /// </summary>
        /// <param name="accountName">The name of the account</param>
        /// <param name="result">The result set to be enriched with transaction data</param>
        private void GetAccountHistoryDetails(string accountName, CurationDetailsViewModel result)
        {
            try
            {
                // get posts
                var posts = GetAccountPosts(accountName);
                if (posts != null && posts.Any())
                {
                    result.LastRetrievedPostDate = posts.LastOrDefault().CreatedAt;
                }

                result.Author.PendingPostPayout = CalculationHelper.CalculatePendingPostPayout(accountName, posts);

                result.Posts = posts;

                var  limit     = Convert.ToInt32(ConfigurationHelper.HistoryTransactionLimit);
                uint batchSize = 1000;
                var  start     = -1;

                int transactionsRetrieved = 0;
                _log.Info(string.Format("Batchsize: {0}", batchSize));

                using (var csteemd = new CSteemd(ConfigurationHelper.HostName))
                {
                    // stop if the max amount of transactions are reached!
                    while (transactionsRetrieved < limit)
                    {
                        _log.Info(string.Format("Retrieving next batch...Retrieved transaction count: {0}. Value start: {1}", transactionsRetrieved, start));

                        var responseHistory = csteemd.get_account_history(accountName, start, batchSize);

                        // store last transaction datetime, so that we know until what data time value we got the transactions
                        result.LastTransactionDate = responseHistory[0][1]["timestamp"].ToObject <DateTime>();
                        _log.Info(string.Format("Stored last transaction datetime: {0}", result.LastTransactionDate.ToString("dd-MM-yyyy HH:mm")));

                        var totalCount = responseHistory.Count();
                        // get_account_history returns last result first, but we want most recent first, so we start from the last element of the response to loop
                        for (var i = totalCount - 1; i >= 0; i--)
                        {
                            var el = responseHistory[i];

                            // get the index of the last transaction in the list to make the next call start from this index
                            if (transactionsRetrieved == 0)
                            {
                                var firstIndex = el[0].ToString();
                                Int32.TryParse(firstIndex, out start);
                            }

                            var transaction = el[1].ToObject <TransactionModel>();

                            var operation     = el[1]["op"];
                            var operationType = operation[0].ToString();

                            var actionViewModel = new ActionViewModel();
                            actionViewModel.TimeStamp = el[1]["timestamp"].ToObject <DateTime>();
                            if (operationType == "vote" && result.Votes.Count < ConfigurationHelper.VoteTransactionCount)
                            {
                                var operationModel = operation[1].ToObject <OperationVoteViewModel>();

                                if (operationModel.voter == accountName)
                                {
                                    actionViewModel.Type    = "vote";
                                    actionViewModel.Details = operationModel;

                                    result.Votes.Add(actionViewModel);
                                }
                            }
                            else if (operationType == "comment")
                            {
                                var operationModel = operation[1].ToObject <OperationCommentViewModel>();
                                if (!String.IsNullOrEmpty(operationModel.parent_author)) // post
                                {
                                    actionViewModel.Type    = "comment";
                                    actionViewModel.Details = operationModel;

                                    if (result.Comments.Count < ConfigurationHelper.CommentTransactionCount &&
                                        operationModel.author == accountName)
                                    {
                                        result.Comments.Add(actionViewModel);
                                    }
                                }
                            }

                            // if the required amount of counts are reached, stop
                            if (result.Comments.Count == ConfigurationHelper.CommentTransactionCount)
                            {
                                break;
                            }
                        }

                        transactionsRetrieved += (int)batchSize;
                        start -= (int)batchSize;
                    }
                }
            }
            catch (Exception ex)
            {
                _log.Error(ex);
            }
        }