示例#1
0
        public async Task <ISpamOperatorResult <Reply> > UpdateModelAsync(ISpamOperatorContext <Reply> context)
        {
            // Perform validation
            var validation = await ValidateModelAsync(context);

            // Create result
            var result = new SpamOperatorResult <Reply>();

            // Not an operator of interest
            if (validation == null)
            {
                return(result.Success(context.Model));
            }

            // If validation succeeded no need to perform further actions
            if (validation.Succeeded)
            {
                return(result.Success(context.Model));
            }

            // Get reply author
            var user = await BuildUserAsync(context.Model);

            if (user == null)
            {
                return(null);
            }

            // Flag user as SPAM?
            if (context.Operation.FlagAsSpam)
            {
                var bot = await _platoUserStore.GetPlatoBotAsync();

                // Mark user as SPAM
                if (!user.IsSpam)
                {
                    user.IsSpam = true;
                    user.IsSpamUpdatedUserId = bot?.Id ?? 0;
                    user.IsSpamUpdatedDate   = DateTimeOffset.UtcNow;
                    await _platoUserStore.UpdateAsync(user);
                }

                // Mark reply as SPAM
                if (!context.Model.IsSpam)
                {
                    context.Model.IsSpam = true;
                    await _replyStore.UpdateAsync(context.Model);
                }
            }

            // Defer notifications for execution after request completes
            _deferredTaskManager.AddTask(async ctx =>
            {
                await NotifyAsync(context);
            });

            // Return failed with our updated model and operation
            // This provides the calling code with the operation error message
            return(result.Failed(context.Model, context.Operation));
        }
        public async Task <TEntityReply> UpdateAsync(TEntityReply reply)
        {
            // Get aggregate rating
            var aggregateRating = await _entityRatingsAggregateStore.SelectAggregateRating(reply.EntityId, reply.Id);

            // Update entity
            reply.TotalRatings = aggregateRating?.TotalRatings ?? 0;
            reply.SummedRating = aggregateRating?.SummedRating ?? 0;
            reply.MeanRating   = aggregateRating?.MeanRating ?? 0;

            // Update and return updated entity
            return(await _entityStore.UpdateAsync(reply));
        }
示例#3
0
        async Task <IList <int> > SendNotificationsAsync(TEntityReply reply, IList <int> usersToExclude)
        {
            if (reply == null)
            {
                throw new ArgumentNullException(nameof(reply));
            }

            // Compile a list of notified users
            var notifiedUsers = new List <int>();

            // Follow type name
            var name = FollowTypes.Tag.Name;

            // Get follow state for reply
            var state = reply.GetOrCreate <FollowState>();

            // Have notifications already been sent for the reply?
            var follow = state.FollowsSent.FirstOrDefault(f =>
                                                          f.Equals(name, StringComparison.InvariantCultureIgnoreCase));

            if (follow != null)
            {
                return(notifiedUsers);
            }

            // Compile all entity tags ids for the entity
            var tags       = new List <int>();
            var entityTags = await _entityTagStore.GetByEntityReplyIdAsync(reply.Id);

            if (entityTags != null)
            {
                foreach (var entityTag in entityTags)
                {
                    if (!tags.Contains(entityTag.TagId))
                    {
                        tags.Add(entityTag.TagId);
                    }
                }
            }

            // Get follows for all reply tags
            var follows = await _followStore.QueryAsync()
                          .Select <FollowQueryParams>(q =>
            {
                q.Name.Equals(name);
                q.ThingId.IsIn(tags.ToArray());
                if (usersToExclude.Count > 0)
                {
                    q.CreatedUserId.IsNotIn(usersToExclude.ToArray());
                }
            })
                          .ToList();

            // Reduce the users for all found follows
            var users = await ReduceUsersAsync(follows?.Data, reply);

            // No users simply return
            if (users == null)
            {
                return(notifiedUsers);
            }

            // Send notifications
            foreach (var user in users)
            {
                // Email notifications
                if (user.NotificationEnabled(_userNotificationTypeDefaults, EmailNotifications.NewReplyTag))
                {
                    // Track notified
                    if (!notifiedUsers.Contains(user.Id))
                    {
                        notifiedUsers.Add(user.Id);
                    }

                    // Notify
                    await _notificationManager.SendAsync(new Notification(EmailNotifications.NewReplyTag)
                    {
                        To = user,
                    }, reply);
                }

                // Web notifications
                if (user.NotificationEnabled(_userNotificationTypeDefaults, WebNotifications.NewReplyTag))
                {
                    // Track notified
                    if (!notifiedUsers.Contains(user.Id))
                    {
                        notifiedUsers.Add(user.Id);
                    }

                    // Notify
                    await _notificationManager.SendAsync(new Notification(WebNotifications.NewReplyTag)
                    {
                        To   = user,
                        From = new User
                        {
                            Id          = reply.CreatedBy.Id,
                            UserName    = reply.CreatedBy.UserName,
                            DisplayName = reply.CreatedBy.DisplayName,
                            Alias       = reply.CreatedBy.Alias,
                            PhotoUrl    = reply.CreatedBy.PhotoUrl,
                            PhotoColor  = reply.CreatedBy.PhotoColor
                        }
                    }, reply);
                }
            }

            // Update state
            state.AddSent(name);
            reply.AddOrUpdate(state);

            // Persist state
            await _entityReplyStore.UpdateAsync(reply);

            // Return a list of all notified users
            return(notifiedUsers);
        }
示例#4
0
        // -----------

        Task <TEntityReply> SendNotificationsAsync(
            TEntityReply reply,
            IList <int> usersToExclude)
        {
            if (reply == null)
            {
                throw new ArgumentNullException(nameof(reply));
            }

            // The reply always need an entity Id
            if (reply.EntityId <= 0)
            {
                throw new ArgumentNullException(nameof(reply.EntityId));
            }

            // No need to send notifications for hidden replies
            if (reply.IsHidden())
            {
                return(Task.FromResult(reply));
            }

            // Add deferred task
            _deferredTaskManager.AddTask(async context =>
            {
                // Follow type name
                var name = FollowTypes.Idea.Name;

                // Get follow sent state for reply
                var state = reply.GetOrCreate <FollowState>();

                // Have notifications already been sent for the reply?
                var follow = state.FollowsSent.FirstOrDefault(f =>
                                                              f.Equals(name, StringComparison.InvariantCultureIgnoreCase));
                if (follow != null)
                {
                    return;
                }

                // Get entity for reply
                var entity = await _entityStore.GetByIdAsync(reply.EntityId);

                // No need to send notifications if the entity is hidden
                if (entity.IsHidden())
                {
                    return;
                }

                // Get all follows for entity
                var follows = await _followStore.QueryAsync()
                              .Select <FollowQueryParams>(q =>
                {
                    q.ThingId.Equals(reply.EntityId);
                    q.Name.Equals(name);
                    if (usersToExclude.Count > 0)
                    {
                        q.CreatedUserId.IsNotIn(usersToExclude.ToArray());
                    }
                })
                              .ToList();

                // No follows simply return
                if (follows?.Data == null)
                {
                    return;
                }

                // Get users
                var users = await ReduceUsersAsync(follows?.Data, reply);

                // We always need users
                if (users == null)
                {
                    return;
                }

                // Send notifications
                foreach (var user in users)
                {
                    // Email notifications
                    if (user.NotificationEnabled(_userNotificationTypeDefaults, EmailNotifications.NewIdeaComment))
                    {
                        await _notificationManager.SendAsync(new Notification(EmailNotifications.NewIdeaComment)
                        {
                            To = user,
                        }, reply);
                    }

                    // Web notifications
                    if (user.NotificationEnabled(_userNotificationTypeDefaults, WebNotifications.NewIdeaComment))
                    {
                        await _notificationManager.SendAsync(new Notification(WebNotifications.NewIdeaComment)
                        {
                            To   = user,
                            From = new User()
                            {
                                Id          = reply.CreatedBy.Id,
                                UserName    = reply.CreatedBy.UserName,
                                DisplayName = reply.CreatedBy.DisplayName,
                                Alias       = reply.CreatedBy.Alias,
                                PhotoUrl    = reply.CreatedBy.PhotoUrl,
                                PhotoColor  = reply.CreatedBy.PhotoColor
                            }
                        }, reply);
                    }
                }

                // Update sent state
                state.AddSent(name);
                reply.AddOrUpdate(state);

                // Persist state
                await _entityReplyStore.UpdateAsync(reply);
            });

            return(Task.FromResult(reply));
        }
示例#5
0
        // --------------------

        async Task <ICommandResultBase> ApplyLatestHistoryPoint(Idea entity, IdeaComment reply)
        {
            // Get current user
            var user = await _contextFacade.GetAuthenticatedUserAsync();

            // We need to be authenticated to make changes
            if (user == null)
            {
                return(await ResetEditDetails(entity, reply, user));
            }

            // Get newest / most recent history entry
            var histories = await _entityHistoryStore.QueryAsync()
                            .Take(1, false)
                            .Select <EntityHistoryQueryParams>(q =>
            {
                q.EntityId.Equals(entity.Id);
                q.EntityReplyId.Equals(reply?.Id ?? 0);
            })
                            .OrderBy("Id", OrderBy.Desc)
                            .ToList();

            // No history point, return success
            if (histories == null)
            {
                return(await ResetEditDetails(entity, reply, user));
            }

            // No history point, return success
            if (histories.Data == null)
            {
                return(await ResetEditDetails(entity, reply, user));
            }

            // No history point, return success
            if (histories.Data.Count == 0)
            {
                return(await ResetEditDetails(entity, reply, user));
            }

            var history = histories.Data[0];

            // No history available reset edit details
            if (history == null)
            {
                return(await ResetEditDetails(entity, reply, user));
            }

            // Update edit details based on latest history point

            var result = new CommandResultBase();

            if (reply != null)
            {
                reply.ModifiedUserId = user.Id;
                reply.ModifiedDate   = DateTimeOffset.UtcNow;
                reply.EditedUserId   = history.CreatedUserId;
                reply.EditedDate     = history.CreatedDate;

                // Update reply to history point
                var updateResult = await _entityReplyStore.UpdateAsync(reply);

                if (updateResult != null)
                {
                    return(result.Success());
                }
            }
            else
            {
                entity.ModifiedUserId = user.Id;
                entity.ModifiedDate   = DateTimeOffset.UtcNow;
                entity.EditedUserId   = history.CreatedUserId;
                entity.EditedDate     = history.CreatedDate;

                // Update entity to history point
                var updateResult = await _entityStore.UpdateAsync(entity);

                if (updateResult != null)
                {
                    return(result.Success());
                }
            }

            return(result.Success());
        }
示例#6
0
        public async Task <ICommandResult <TReply> > UpdateAsync(TReply reply)
        {
            // Validate
            if (reply == null)
            {
                throw new ArgumentNullException(nameof(reply));
            }

            if (reply.Id <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(reply.Id));
            }

            if (reply.EntityId <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(reply.EntityId));
            }

            if (String.IsNullOrWhiteSpace(reply.Message))
            {
                throw new ArgumentNullException(nameof(reply.Message));
            }

            //if (reply.ModifiedUserId <= 0)
            //{
            //    throw new ArgumentOutOfRangeException(nameof(reply.ModifiedUserId));
            //}

            //if (reply.ModifiedDate == null)
            //{
            //    throw new ArgumentNullException(nameof(reply.ModifiedDate));
            //}

            var result = new CommandResult <TReply>();

            // Ensure entity exists
            var entity = await _entityStore.GetByIdAsync(reply.EntityId);

            if (entity == null)
            {
                return(result.Failed(new CommandError($"An entity with the Id '{reply.EntityId}' could not be found")));
            }

            // Parse Html and message abstract
            reply.Html = await ParseEntityHtml(reply.Message);

            reply.Abstract = await ParseEntityAbstract(reply.Message);

            reply.Urls = await ParseEntityUrls(reply.Html);

            // Raise updating event
            Updating?.Invoke(this, new EntityReplyEventArgs <TReply>(entity, reply));

            // Invoke EntityReplyUpdating subscriptions
            foreach (var handler in _broker.Pub <TReply>(this, "EntityReplyUpdating"))
            {
                reply = await handler.Invoke(new Message <TReply>(reply, this));
            }

            var updatedReply = await _entityReplyStore.UpdateAsync(reply);

            if (updatedReply != null)
            {
                // Raise Updated event
                Updated?.Invoke(this, new EntityReplyEventArgs <TReply>(entity, updatedReply));

                // Invoke EntityReplyUpdated subscriptions
                foreach (var handler in _broker.Pub <TReply>(this, "EntityReplyUpdated"))
                {
                    updatedReply = await handler.Invoke(new Message <TReply>(updatedReply, this));
                }

                return(result.Success(updatedReply));
            }

            return(result.Failed(new CommandError("An unknown error occurred whilst attempting to update the reply.")));
        }