public static async Task SendUserMentionNotification(string user, Submission submission, Action<string> onSuccess) { if (submission != null) { if (!UserHelper.UserExists(user)) { return; } try { string recipient = UserHelper.OriginalUsername(user); var commentReplyNotification = new CommentReplyNotification(); using (var _db = new voatEntities()) { var subverse = DataCache.Subverse.Retrieve(submission.Subverse); commentReplyNotification.SubmissionID = submission.ID; commentReplyNotification.Recipient = recipient; if (submission.IsAnonymized || subverse.IsAnonymized) { commentReplyNotification.Sender = (new Random()).Next(10000, 20000).ToString(CultureInfo.InvariantCulture); } else { commentReplyNotification.Sender = submission.UserName; } commentReplyNotification.Body = submission.Content; commentReplyNotification.Subverse = subverse.Name; commentReplyNotification.IsUnread = true; commentReplyNotification.CreationDate = DateTime.Now; commentReplyNotification.Subject = String.Format("@{0} mentioned you in post '{1}'", submission.UserName, submission.Title); _db.CommentReplyNotifications.Add(commentReplyNotification); await _db.SaveChangesAsync(); } if (onSuccess != null) { onSuccess(recipient); } } catch (Exception ex) { throw ex; } } }
/// <summary> /// </summary> /// <param name="submissionID">Using Nullable because everything seems to be nullable in this entire project</param> /// <returns></returns> public static Voat.Data.Models.Submission Retrieve(int?submissionID) { if (submissionID.HasValue && submissionID.Value > 0) { string cacheKey = CacheHandler.Keys.Submission(submissionID.Value); Voat.Data.Models.Submission submission = CacheHandler.Register <Voat.Data.Models.Submission>(cacheKey, new Func <Voat.Data.Models.Submission>(() => { using (voatEntities db = new voatEntities()) { return(db.Submissions.Where(x => x.ID == submissionID).FirstOrDefault()); } }), TimeSpan.FromMinutes(30), -1); return(submission); } return(null); }
/// <summary> /// </summary> /// <param name="submissionID">Using Nullable because everything seems to be nullable in this entire project</param> /// <returns></returns> public static Voat.Data.Models.Submission Retrieve(int?submissionID) { if (submissionID.HasValue && submissionID.Value > 0) { string cacheKey = DataCache.Keys.Submission(submissionID.Value); Voat.Data.Models.Submission submission = CacheHandler.Instance.Register <Voat.Data.Models.Submission>(cacheKey, new Func <Voat.Data.Models.Submission>(() => { using (var repo = new Repository()) { return(repo.GetSubmission(submissionID.Value)); } }), TimeSpan.FromMinutes(30), -1); return(submission); } return(null); }
public static void RerankSubmission(Submission submission) { double currentScore = submission.UpCount - submission.DownCount; double submissionAge = Submissions.CalcSubmissionAgeDouble(submission.CreationDate); double newRank = CalculateNewRank(submission.Rank, submissionAge, currentScore); submission.Rank = newRank; // calculate relative rank var subCtr = GetSubverseHighestRanking(submission.Subverse); var relRank = CalculateNewRelativeRank(newRank, subCtr); if (relRank != null) { submission.RelativeRank = relRank.Value; } //update cache if higher rank that what's in there already UpdateSubverseHighestRanking(submission.Subverse, newRank); }
// various spam checks, to be replaced with new rule engine public static async Task<string> PreAddSubmissionCheck(Submission submissionModel, HttpRequestBase request, string userName, Subverse targetSubverse, Func<HttpRequestBase, Task<bool>> captchaValidator) { // TODO: reject if a submission with this title was posted in the last 60 minutes // check posting quotas if user is posting to subs they do not moderate if (!UserHelper.IsUserSubverseModerator(userName, submissionModel.Subverse)) { // reject if user has reached global daily submission quota if (UserHelper.UserDailyGlobalPostingQuotaUsed(userName)) { return ("You have reached your daily global submission quota."); } // reject if user has reached global hourly submission quota if (UserHelper.UserHourlyGlobalPostingQuotaUsed(userName)) { return ("You have reached your hourly global submission quota."); } // check if user has reached hourly posting quota for target subverse if (UserHelper.UserHourlyPostingQuotaForSubUsed(userName, submissionModel.Subverse)) { return ("You have reached your hourly submission quota for this subverse."); } // check if user has reached daily posting quota for target subverse if (UserHelper.UserDailyPostingQuotaForSubUsed(userName, submissionModel.Subverse)) { return ("You have reached your daily submission quota for this subverse."); } } // verify recaptcha if user has less than 25 CCP var userCcp = Karma.CommentKarma(userName); if (userCcp < 25) { bool isCaptchaCodeValid = await captchaValidator(request); if (!isCaptchaCodeValid) { // TODO: SET PREVENT SPAM DELAY TO 0 return ("Incorrect recaptcha answer."); } } // if user CCP or SCP is less than -50, allow only X submissions per 24 hours var userScp = Karma.LinkKarma(userName); if (userCcp <= -50 || userScp <= -50) { var quotaUsed = UserHelper.UserDailyPostingQuotaForNegativeScoreUsed(userName); if (quotaUsed) { return ("You have reached your daily submission quota. Your current quota is " + Settings.DailyPostingQuotaForNegativeScore + " submission(s) per 24 hours."); } } // check if subverse has "authorized_submitters_only" set and dissalow submission if user is not allowed submitter if (targetSubverse.IsAuthorizedOnly) { if (!UserHelper.IsUserSubverseModerator(userName, targetSubverse.Name)) { return ("You are not authorized to submit links or start discussions in this subverse. Please contact subverse moderators for authorization."); } } // null is returned if all checks have passed return null; }
// add new submission public static async Task<string> AddNewSubmission(Submission submissionModel, Subverse targetSubverse, string userName) { using (var db = new voatEntities()) { // LINK TYPE SUBMISSION if (submissionModel.Type == 2) { // strip unicode if title contains unicode if (ContainsUnicode(submissionModel.LinkDescription)) { submissionModel.LinkDescription = StripUnicode(submissionModel.LinkDescription); } // reject if title is whitespace or < than 5 characters if (submissionModel.LinkDescription.Length < 5 || String.IsNullOrWhiteSpace(submissionModel.LinkDescription)) { return ("The title may not be less than 5 characters."); } // make sure the input URI is valid if (!UrlUtility.IsUriValid(submissionModel.Content)) { // ABORT return ("The URI you are trying to submit is invalid."); } // check if target subvere allows submissions from globally banned hostnames if (!targetSubverse.ExcludeSitewideBans) { // check if hostname is banned before accepting submission var domain = UrlUtility.GetDomainFromUri(submissionModel.Content); if (BanningUtility.IsDomainBanned(domain)) { // ABORT return ("The domain you are trying to submit is banned."); } } // check if user has reached daily crossposting quota if (UserHelper.DailyCrossPostingQuotaUsed(userName, submissionModel.Content)) { // ABORT return ("You have reached your daily crossposting quota for this URL."); } // check if target subverse has thumbnails setting enabled before generating a thumbnail if (targetSubverse.IsThumbnailEnabled) { // try to generate and assign a thumbnail to submission model submissionModel.Thumbnail = await ThumbGenerator.ThumbnailFromSubmissionModel(submissionModel); } // flag the submission as anonymized if it was submitted to a subverse with active anonymized_mode submissionModel.IsAnonymized = targetSubverse.IsAnonymized; submissionModel.UserName = userName; submissionModel.Subverse = targetSubverse.Name; submissionModel.UpCount = 1; db.Submissions.Add(submissionModel); await db.SaveChangesAsync(); } else // MESSAGE TYPE SUBMISSION { // strip unicode if submission contains unicode if (ContainsUnicode(submissionModel.Title)) { submissionModel.Title = StripUnicode(submissionModel.Title); } // reject if title is whitespace or less than 5 characters if (submissionModel.Title.Length < 5 || String.IsNullOrWhiteSpace(submissionModel.Title)) { return ("Sorry, submission title may not be less than 5 characters."); } // grab server timestamp and modify submission timestamp to have posting time instead of "started writing submission" time submissionModel.IsAnonymized = targetSubverse.IsAnonymized; submissionModel.UserName = userName; submissionModel.Subverse = targetSubverse.Name; submissionModel.CreationDate = DateTime.Now; submissionModel.UpCount = 1; db.Submissions.Add(submissionModel); if (ContentProcessor.Instance.HasStage(ProcessingStage.InboundPreSave)) { submissionModel.Content = ContentProcessor.Instance.Process(submissionModel.Content, ProcessingStage.InboundPreSave, submissionModel); } await db.SaveChangesAsync(); if (ContentProcessor.Instance.HasStage(ProcessingStage.InboundPostSave)) { ContentProcessor.Instance.Process(submissionModel.Content, ProcessingStage.InboundPostSave, submissionModel); } } } // null is returned if no errors were raised return null; }