コード例 #1
0
        private async Task AddPoolsAsync()
        {
            List <long> poolIds = new List <long> {
                1000, 1001, 1002, 1003
            };
            var usersIds = poolIds.Select(id => new UserIdentificator {
                IsUsed = false, UserId = id
            });
            var chatsIds = poolIds.Select(id => new ChatIdentificator {
                IsUsed = false, ChatId = id
            });
            var channelsIds = poolIds.Select(id => new ChannelIdentificator {
                IsUsed = false, ChannelId = id
            });
            var filesIds = poolIds.Select(id => new FileIdentificator {
                IsUsed = false, FileId = id
            });
            await _context.AddRangeAsync(usersIds);

            await _context.AddRangeAsync(chatsIds);

            await _context.AddRangeAsync(channelsIds);

            await _context.AddRangeAsync(filesIds);

            await _context.SaveChangesAsync();
        }
コード例 #2
0
        private async Task <List <MessageDto> > SaveChannelMessagesAsync(IEnumerable <MessageDto> messages)
        {
            using (MessengerDbContext context = contextFactory.Create())
            {
                var messagesCondition = PredicateBuilder.New <Message>();
                messagesCondition = messages.Aggregate(messagesCondition,
                                                       (current, value) => current.Or(opt => opt.ChannelId == value.ConversationId && opt.GlobalId == value.GlobalId).Expand());
                List <Message> existingMessages = await context.Messages.Where(messagesCondition).ToListAsync().ConfigureAwait(false);

                IEnumerable <MessageDto> nonExistingMessages = messages.Where(opt => !existingMessages.Any(p => p.GlobalId == opt.GlobalId && p.ChannelId == opt.ConversationId));
                var newMessages = MessageConverter.GetMessages(nonExistingMessages);
                await context.AddRangeAsync(newMessages.OrderBy(opt => opt.SendingTime)).ConfigureAwait(false);

                await context.SaveChangesAsync().ConfigureAwait(false);

                var groupedMessages = newMessages.GroupBy(opt => opt.ChannelId.GetValueOrDefault());
                foreach (var group in groupedMessages)
                {
                    var lastMessage = group.OrderByDescending(opt => opt.SendingTime).FirstOrDefault();
                    if (lastMessage != null)
                    {
                        ConversationsService.UpdateConversationLastMessageId(group.Key, ConversationType.Channel, lastMessage.GlobalId);
                    }
                }
                return(messages.ToList());
            }
        }
コード例 #3
0
        public async Task <List <ChannelDto> > CreateOrUpdateUserChannelsAsync(List <ChannelDto> channels)
        {
            using (MessengerDbContext context = contextFactory.Create())
            {
                var channelsCondition = PredicateBuilder.New <Channel>();
                channelsCondition = channels.Aggregate(channelsCondition,
                                                       (current, value) => current.Or(opt => opt.ChannelId == value.ChannelId).Expand());
                List <Channel> existingChannels = await context.Channels
                                                  .Include(opt => opt.ChannelUsers)
                                                  .Where(channelsCondition)
                                                  .ToListAsync()
                                                  .ConfigureAwait(false);

                for (int i = 0; i < existingChannels.Count; i++)
                {
                    ChannelDto editedChannel = channels.FirstOrDefault(opt => opt.ChannelId == existingChannels[i].ChannelId);
                    existingChannels[i] = ChannelConverter.GetChannel(existingChannels[i], editedChannel);
                    if (!editedChannel.ChannelUsers.IsNullOrEmpty())
                    {
                        existingChannels[i].ChannelUsers = ChannelConverter.GetChannelUsers(editedChannel.ChannelUsers).ToList();
                    }
                }
                context.UpdateRange(existingChannels);
                List <ChannelDto> nonExistingChannels = channels.Where(channelDto => !existingChannels.Any(channel => channelDto.ChannelId == channel.ChannelId))?.ToList();
                List <Channel>    newChannels         = ChannelConverter.GetChannels(nonExistingChannels);
                await context.AddRangeAsync(newChannels).ConfigureAwait(false);

                await context.SaveChangesAsync().ConfigureAwait(false);

                return(ChannelConverter.GetChannelsDto(newChannels.Concat(existingChannels)));
            }
        }
コード例 #4
0
        public async Task <MessageDto> EditMessageAsync(MessageDto message, long editorId)
        {
            using (MessengerDbContext context = contextFactory.Create())
            {
                var messageQuery = context.Messages
                                   .Include(opt => opt.Attachments)
                                   .Where(opt =>
                                          !opt.Deleted &&
                                          opt.SenderId == message.SenderId &&
                                          opt.ReceiverId == message.ReceiverId &&
                                          opt.GlobalId == message.GlobalId);
                switch (message.ConversationType)
                {
                case ConversationType.Dialog:
                {
                    messageQuery = messageQuery.Where(opt => opt.SenderId == editorId);
                }
                break;

                case ConversationType.Chat:
                {
                    messageQuery = messageQuery.Where(opt => opt.ChatId == message.ConversationId && opt.SenderId == editorId);
                }
                break;

                case ConversationType.Channel:
                {
                    messageQuery = messageQuery.Where(opt => opt.ChannelId == message.ConversationId)
                                   .Where(opt => opt.Channel.ChannelUsers
                                          .Any(channelUser => channelUser.UserId == editorId && channelUser.ChannelUserRole > ChannelUserRole.Subscriber));
                }
                break;
                }
                var editableMessages = await messageQuery.ToListAsync().ConfigureAwait(false);

                if (!editableMessages.Any())
                {
                    throw new ObjectDoesNotExistsException();
                }

                var editedMessages = new List <EditedMessage>();
                editedMessages = editableMessages.Select(opt => new EditedMessage(opt, editorId)).ToList();
                long updatedTime = DateTime.UtcNow.ToUnixTime();
                foreach (var edited in editableMessages)
                {
                    edited.Text      = message.Text;
                    edited.UpdatedAt = updatedTime;
                    if (message.Attachments != null)
                    {
                        edited.Attachments = AttachmentConverter.GetAttachments(message.Attachments, edited.Id);
                    }
                }
                context.UpdateRange(editableMessages);
                await context.AddRangeAsync(editedMessages).ConfigureAwait(false);

                await context.SaveChangesAsync().ConfigureAwait(false);

                return(MessageConverter.GetMessageDto(editableMessages.FirstOrDefault()));
            }
        }
コード例 #5
0
        public async Task CreateNewUsersAsync(List <UserVm> users)
        {
            try
            {
                var usersCondition = PredicateBuilder.New <User>();
                usersCondition = users.Aggregate(usersCondition,
                                                 (current, value) => current.Or(opt => opt.Id == value.Id).Expand());
                using (MessengerDbContext context = contextFactory.Create())
                {
                    List <User> existingUsers = await context.Users.Where(usersCondition).ToListAsync().ConfigureAwait(false);

                    List <UserVm> nonExistingUsers = users.Where(opt => !existingUsers.Any(p => p.Id == opt.Id)).ToList();
                    List <User>   newUsers         = nonExistingUsers.Select(user => new User
                    {
                        Id        = user.Id.GetValueOrDefault(),
                        Tag       = user.Tag,
                        NameFirst = user.NameFirst,
                        NodeId    = user.NodeId.GetValueOrDefault(),
                        Confirmed = true
                    }).ToList();
                    await context.AddRangeAsync(newUsers).ConfigureAwait(false);

                    await context.SaveChangesAsync().ConfigureAwait(false);
                }
            }
            catch (Exception ex)
            {
                Logger.WriteLog(ex);
            }
        }
コード例 #6
0
ファイル: PoolsService.cs プロジェクト: Ymessenger/ymessenger
        public async Task SaveNodePoolsAsync(NodePools nodePools)
        {
            var usersIdentificators = nodePools.UsersIds?.Select(userId => new UserIdentificator
            {
                UserId = userId
            });
            var chatsIdentificators = nodePools.ChatsIds?.Select(chatId => new ChatIdentificator
            {
                ChatId = chatId
            });
            var channelsIdentificators = nodePools.ChannelsIds?.Select(channelId => new ChannelIdentificator
            {
                ChannelId = channelId
            });
            var filesIdentificators = nodePools.FilesIds?.Select(fileId => new FileIdentificator
            {
                FileId = fileId
            });

            using (MessengerDbContext context = contextFactory.Create())
            {
                if (usersIdentificators != null)
                {
                    await context.AddRangeAsync(usersIdentificators).ConfigureAwait(false);
                }
                if (chatsIdentificators != null)
                {
                    await context.AddRangeAsync(chatsIdentificators).ConfigureAwait(false);
                }
                if (channelsIdentificators != null)
                {
                    await context.AddRangeAsync(channelsIdentificators).ConfigureAwait(false);
                }
                if (filesIdentificators != null)
                {
                    await context.AddRangeAsync(filesIdentificators).ConfigureAwait(false);
                }
                await context.SaveChangesAsync().ConfigureAwait(false);
            }
        }
コード例 #7
0
        public async Task AddUsersToChatAsync(long chatId, IEnumerable <long> usersId, long requestorId)
        {
            try
            {
                List <ChatUser> chatUsers = new List <ChatUser>();
                foreach (long userId in usersId)
                {
                    chatUsers.Add(ChatUserConverter.GetNewChatUser(chatId, userId, requestorId));
                }
                using (MessengerDbContext context = contextFactory.Create())
                {
                    await context.AddRangeAsync(chatUsers).ConfigureAwait(false);

                    await context.SaveChangesAsync().ConfigureAwait(false);
                }
            }
            catch (Exception ex)
            {
                Logger.WriteLog(ex);
            }
        }
コード例 #8
0
        public async void DownloadMessageHistoryAsync(long nodeId, long conversationId, ConversationType conversationType, Guid?messageId, bool direction = true, int length = 1000)
        {
            try
            {
                using (MessengerDbContext context = contextFactory.Create())
                {
                    var nodeConnection = NodeData.ConnectionsService.GetNodeConnection(nodeId);
                    if (nodeConnection != null)
                    {
                        List <MessageDto> loadedMessages = await NodeRequestSender.GetMessagesAsync(nodeConnection, conversationId, conversationType, messageId, null, direction, length)
                                                           .ConfigureAwait(false);

                        while (loadedMessages.Any())
                        {
                            IEnumerable <Message> messages = MessageConverter.GetMessages(loadedMessages);
                            var messagesCondition          = PredicateBuilder.New <Message>();
                            messagesCondition = messages.Aggregate(messagesCondition,
                                                                   (current, value) => current.Or(opt => opt.GlobalId == value.GlobalId).Expand());
                            List <Message> existingMessages = await context.Messages.Where(messagesCondition).ToListAsync().ConfigureAwait(false);

                            messages = messages.Where(opt => existingMessages.All(p => p.GlobalId != opt.GlobalId));
                            var navigationMessage = direction ? messages.LastOrDefault() : messages.FirstOrDefault();
                            loadedMessages = await NodeRequestSender.GetMessagesAsync(nodeConnection, conversationId, conversationType, navigationMessage.GlobalId, null, direction, length).ConfigureAwait(false);

                            await context.AddRangeAsync(messages).ConfigureAwait(false);

                            await context.SaveChangesAsync().ConfigureAwait(false);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.WriteLog(ex);
            }
        }
コード例 #9
0
        private async Task <List <MessageDto> > SaveDialogMessagesAsync(List <MessageDto> messages, long messagesOwnerId)
        {
            using (MessengerDbContext context = contextFactory.Create())
            {
                using (var transaction = context.Database.BeginTransaction())
                {
                    try
                    {
                        List <Dialog> userDialogs = await context.Dialogs
                                                    .Where(opt => opt.FirstUID == messagesOwnerId)
                                                    .ToListAsync()
                                                    .ConfigureAwait(false);

                        List <MessageDto> newDialogsMessages     = new List <MessageDto>();
                        List <MessageDto> existingDialogMessages = new List <MessageDto>();
                        List <long>       nonExistingUsersId     = new List <long>();
                        List <Dialog>     newDialogs             = new List <Dialog>();
                        List <Message>    newMessages            = new List <Message>();
                        foreach (var message in messages)
                        {
                            if (!message.Deleted)
                            {
                                Dialog dialog = userDialogs.FirstOrDefault(opt =>
                                                                           (opt.FirstUID == message.SenderId && opt.SecondUID == message.ReceiverId) ||
                                                                           (opt.SecondUID == message.SenderId && opt.FirstUID == message.ReceiverId));
                                if (dialog == null)
                                {
                                    newDialogsMessages.Add(message);
                                    if (message.SenderId == messagesOwnerId && !nonExistingUsersId.Contains(message.ReceiverId.GetValueOrDefault()))
                                    {
                                        nonExistingUsersId.Add(message.ReceiverId.GetValueOrDefault());
                                    }
                                    else if (message.ReceiverId == messagesOwnerId && !nonExistingUsersId.Contains(message.SenderId.GetValueOrDefault()))
                                    {
                                        nonExistingUsersId.Add(message.SenderId.GetValueOrDefault());
                                    }
                                }
                                else
                                {
                                    message.ConversationId = dialog.Id;
                                    existingDialogMessages.Add(message);
                                }
                            }
                        }
                        if (existingDialogMessages.Any())
                        {
                            var messagesCondition = PredicateBuilder.New <Message>();
                            messagesCondition = existingDialogMessages.Aggregate(messagesCondition,
                                                                                 (current, value) => current.Or(opt => opt.GlobalId == value.GlobalId && opt.DialogId == value.ConversationId).Expand());
                            List <Message> existingMessages = await context.Messages.Where(messagesCondition).ToListAsync().ConfigureAwait(false);

                            var additionalMessages = MessageConverter.GetMessages(
                                existingDialogMessages.Where(
                                    messageDto => !existingMessages.Any(existing => messageDto.GlobalId == existing.GlobalId &&
                                                                        messageDto.ConversationId == existing.DialogId)));
                            newMessages.AddRange(additionalMessages);
                        }
                        foreach (long userId in nonExistingUsersId)
                        {
                            newDialogs.Add(new Dialog
                            {
                                FirstUID  = messagesOwnerId,
                                SecondUID = userId
                            });
                            if (messagesOwnerId != userId)
                            {
                                newDialogs.Add(new Dialog
                                {
                                    FirstUID  = userId,
                                    SecondUID = messagesOwnerId
                                });
                            }
                        }
                        await context.AddRangeAsync(newDialogs).ConfigureAwait(false);

                        await context.SaveChangesAsync().ConfigureAwait(false);

                        foreach (var message in newDialogsMessages)
                        {
                            Dialog ownerDialog = newDialogs.FirstOrDefault(opt =>
                                                                           opt.FirstUID == messagesOwnerId &&
                                                                           ((opt.FirstUID == message.SenderId && opt.SecondUID == message.ReceiverId) ||
                                                                            (opt.SecondUID == message.SenderId && opt.FirstUID == message.ReceiverId)));
                            message.ConversationId = ownerDialog.Id;
                        }
                        newMessages.AddRange(MessageConverter.GetMessages(newDialogsMessages));
                        await context.AddRangeAsync(newMessages.OrderBy(opt => opt.SendingTime)).ConfigureAwait(false);

                        await context.SaveChangesAsync().ConfigureAwait(false);

                        transaction.Commit();
                        var groupedMessages = newMessages.GroupBy(opt => opt.DialogId.GetValueOrDefault());
                        foreach (var group in groupedMessages)
                        {
                            var lastMessage = group.OrderByDescending(opt => opt.SendingTime).FirstOrDefault();
                            if (lastMessage != null)
                            {
                                ConversationsService.UpdateConversationLastMessageId(group.Key, ConversationType.Dialog, lastMessage.GlobalId);
                            }
                        }
                        return(MessageConverter.GetMessagesDto(newMessages));
                    }
                    catch (Exception ex)
                    {
                        transaction.Rollback();
                        throw new MessageException("Save messages error.", ex);
                    }
                }
            }
        }
コード例 #10
0
        public async Task <List <ChannelUserVm> > CreateOrEditChannelUsersAsync(List <ChannelUserVm> channelUsers, long requestorId)
        {
            try
            {
                using (MessengerDbContext context = contextFactory.Create())
                {
                    var channelUsersCondition = PredicateBuilder.New <ChannelUser>();
                    channelUsersCondition = channelUsers.Aggregate(channelUsersCondition,
                                                                   (current, value) => current.Or(opt => opt.ChannelId == value.ChannelId && opt.UserId == value.UserId).Expand());
                    List <ChannelUserVm> result = new List <ChannelUserVm>();
                    var existingChannelsUsers   = ChannelConverter.GetChannelUsers(await context.ChannelUsers.Where(channelUsersCondition).ToListAsync().ConfigureAwait(false));
                    List <ChannelUserVm> nonExistingChannelUsers = new List <ChannelUserVm>();
                    if (existingChannelsUsers?.Any() ?? false)
                    {
                        var groups = existingChannelsUsers.GroupBy(opt => opt.ChannelId);
                        foreach (var group in groups)
                        {
                            var edited = channelUsers.Where(opt => group.Any(p => p.ChannelId == opt.ChannelId && p.UserId == opt.UserId)).ToList();
                            result.AddRange(await updateChannelsService.EditChannelUsersAsync(edited, requestorId, group.Key.GetValueOrDefault()).ConfigureAwait(false));
                        }
                        nonExistingChannelUsers = channelUsers.Where(opt => !existingChannelsUsers.Any(p => p.ChannelId == opt.ChannelId && p.UserId == opt.UserId)).ToList();
                    }
                    else
                    {
                        nonExistingChannelUsers = channelUsers;
                    }
                    if (nonExistingChannelUsers?.Any() ?? false)
                    {
                        var newChannelUsers = ChannelConverter.GetChannelUsers(nonExistingChannelUsers).ToList();
                        await context.AddRangeAsync(newChannelUsers).ConfigureAwait(false);

                        result.AddRange(ChannelConverter.GetChannelUsers(newChannelUsers));
                    }
                    var channelGroups = channelUsers.GroupBy(opt => opt.ChannelId);
                    foreach (var group in channelGroups)
                    {
                        var channelsNodesIds = await context.ChannelUsers
                                               .Where(opt => opt.ChannelId == group.Key)
                                               .Include(opt => opt.User)
                                               .Select(opt => opt.User.NodeId)
                                               .ToArrayAsync()
                                               .ConfigureAwait(false);

                        var channel = await context.Channels.FindAsync(group.Key).ConfigureAwait(false);

                        channel.NodesId = channelsNodesIds.Select(id => id.GetValueOrDefault()).Distinct().ToArray();
                        context.Channels.Update(channel);
                    }
                    await context.SaveChangesAsync().ConfigureAwait(false);

                    return(result);
                }
            }
            catch (DbUpdateException ex)
            {
                if (ex.InnerException is PostgresException postgresException)
                {
                    if (postgresException.ConstraintName == "FK_ChannelUsers_Channels_ChannelId")
                    {
                        throw new ConversationNotFoundException();
                    }

                    if (postgresException.ConstraintName == "FK_ChannelUsers_Users_UserId")
                    {
                        throw new UserNotFoundException();
                    }
                }
                throw new AddOrRemoveChannelUsersException();
            }
        }
コード例 #11
0
        public async Task <List <ChannelUserVm> > AddUsersToChannelAsync(List <long> usersId, long channelId, long requestorId)
        {
            using (MessengerDbContext context = contextFactory.Create())
            {
                var usersCondition = PredicateBuilder.New <ChannelUser>();
                usersCondition = usersId.Aggregate(usersCondition,
                                                   (current, value) => current.Or(opt => opt.UserId == value).Expand());
                var requestorUser = await context.ChannelUsers
                                    .FirstOrDefaultAsync(opt =>
                                                         opt.ChannelUserRole >= ChannelUserRole.Administrator &&
                                                         opt.ChannelId == channelId &&
                                                         opt.UserId == requestorId &&
                                                         opt.Channel.Deleted == false)
                                    .ConfigureAwait(false);

                if (requestorUser == null && (usersId.Count() > 1 || (usersId.Count() == 1 && usersId.ElementAt(0) != requestorId)))
                {
                    throw new AddUserToChannelException();
                }

                List <ChannelUser> existingUsers = await context.ChannelUsers
                                                   .Where(usersCondition)
                                                   .Where(opt => opt.ChannelId == channelId)
                                                   .ToListAsync()
                                                   .ConfigureAwait(false);

                List <long> nonExistingUsersId;
                if (existingUsers?.Any() ?? false)
                {
                    nonExistingUsersId = usersId.Where(id => !existingUsers.Any(opt => opt.UserId == id)).ToList();
                }
                else
                {
                    nonExistingUsersId = usersId;
                }

                List <ChannelUser> newChannelUsers = nonExistingUsersId.Select(id => new ChannelUser
                {
                    ChannelId       = channelId,
                    ChannelUserRole = ChannelUserRole.Subscriber,
                    SubscribedTime  = DateTime.UtcNow.ToUnixTime(),
                    UserId          = id
                }).ToList();
                var users = await loadUsersService.GetUsersByIdAsync(nonExistingUsersId).ConfigureAwait(false);

                Channel channel = await context.Channels.FirstOrDefaultAsync(opt => opt.ChannelId == channelId).ConfigureAwait(false);

                channel.NodesId = channel.NodesId.Concat(users.Select(opt => opt.NodeId.GetValueOrDefault())).Distinct().ToArray();
                context.Update(channel);
                var updatedUsers = new List <ChannelUser>();
                if (existingUsers != null)
                {
                    existingUsers.ForEach(channelUser =>
                    {
                        if (!channelUser.Banned && channelUser.Deleted)
                        {
                            channelUser.Deleted = false;
                            updatedUsers.Add(channelUser);
                        }
                    });
                    context.UpdateRange(existingUsers);
                }
                await context.AddRangeAsync(newChannelUsers).ConfigureAwait(false);

                await context.SaveChangesAsync().ConfigureAwait(false);

                return(ChannelConverter.GetChannelUsers(newChannelUsers.Concat(updatedUsers)));
            }
        }