Exemplo n.º 1
0
        public async Task <TPrimaryKey> CreateAsync(IFormFileCollection attachments, PostDto dto)
        {
            var isPostingAllowed = await _banService.IsPostingAllowedAsync(dto.ThreadId, dto.UserIpAddress);

            if (!isPostingAllowed.Item1)
            {
                throw new HttpResponseException(HttpStatusCode.Forbidden, isPostingAllowed.Item2);
            }
            else if (attachments == null)
            {
                return(await CreateAsync(dto, (post) =>
                {
                    post.Thread = Context.Threads.FirstOrDefault(thread => thread.Id == dto.ThreadId);
                }));
            }
            else
            {
                var postId = await CreateAsync(dto, (post) =>
                {
                    post.Thread = Context.Threads.FirstOrDefault(thread => thread.Id == dto.ThreadId);
                });

                try
                {
                    var containerName = dto.ThreadId.ToString();
                    if (string.IsNullOrWhiteSpace(containerName))
                    {
                        throw new Exception($"{nameof(containerName)} is null or whitespace");
                    }

                    foreach (var attachment in attachments)
                    {
                        string blobName;

                        var attachmentParentDto = _attachmentCategorizer.CreateAttachmentDto(attachment.FileName);
                        attachmentParentDto.PostId        = postId;
                        attachmentParentDto.FileExtension = Path.GetExtension(attachment.FileName)?.TrimStart('.');
                        attachmentParentDto.FileName      = Path.GetFileNameWithoutExtension(attachment.FileName);
                        attachmentParentDto.Size          = attachment.Length;
                        attachmentParentDto.Hash          = _cryptoService.HashHex(attachment.OpenReadStream());

                        if (attachmentParentDto is AudioDto audioDto)
                        {
                            blobName = (await _audioService.CreateAsync(audioDto, entity =>
                            {
                                entity.Post = Context.Posts.FirstOrDefault(post => post.Id == postId);
                            })).ToString();
                        }
                        else if (attachmentParentDto is PictureDto pictureDto)
                        {
                            if (_attachmentCategorizer.IsPictureExtensionSupported(pictureDto.FileExtension))
                            {
                                // generate thumbnail if such file extension is supported
                                var image = Image.Load(attachment.OpenReadStream());
                                pictureDto.Width  = image.Width;
                                pictureDto.Height = image.Height;
                                blobName          = (await _pictureService.CreateAsync(pictureDto, entity =>
                                {
                                    entity.Post = Context.Posts.FirstOrDefault(post => post.Id == postId);
                                })).ToString();

                                var thumbnail = _thumbnailGenerator.GenerateThumbnail(
                                    image,
                                    _hikkabaConfiguration.ThumbnailsMaxWidth,
                                    _hikkabaConfiguration.ThumbnailsMaxHeight);
                                await _storageProvider.SaveBlobStreamAsync(
                                    containerName + Defaults.ThumbnailPostfix,
                                    blobName,
                                    thumbnail.Image);
                            }
                            else
                            {
                                // otherwise save the same image as thumbnail
                                blobName = (await _pictureService.CreateAsync(pictureDto, entity =>
                                {
                                    entity.Post = Context.Posts.FirstOrDefault(post => post.Id == postId);
                                })).ToString();
                                await _storageProvider.SaveBlobStreamAsync(
                                    containerName + Defaults.ThumbnailPostfix,
                                    blobName,
                                    attachment.OpenReadStream());
                            }
                        }
                        else if (attachmentParentDto is VideoDto videoDto)
                        {
                            blobName = (await _videoService.CreateAsync(videoDto, entity =>
                            {
                                entity.Post = Context.Posts.FirstOrDefault(post => post.Id == postId);
                            })).ToString();
                        }
                        else if (attachmentParentDto is DocumentDto documentDto)
                        {
                            blobName = (await _documentService.CreateAsync(documentDto, entity =>
                            {
                                entity.Post = Context.Posts.FirstOrDefault(post => post.Id == postId);
                            })).ToString();
                        }
                        else
                        {
                            throw new Exception($"Unknown attachment type: {attachmentParentDto.GetType().Name}");
                        }
                        if (string.IsNullOrWhiteSpace(blobName))
                        {
                            throw new Exception($"{nameof(blobName)} is null or whitespace");
                        }
                        await _storageProvider.SaveBlobStreamAsync(containerName, blobName, attachment.OpenReadStream());
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex + $" Post {postId} will be deleted.");
                    await DeleteAsync(postId);

                    throw;
                }

                return(postId);
            }
        }
Exemplo n.º 2
0
        private async Task CreateAttachmentsAsync(string containerName, Post postEntity, IFormFileCollection attachments)
        {
            foreach (var attachment in attachments)
            {
                var extension             = Path.GetExtension(attachment.FileName)?.ToLowerInvariant()?.TrimStart('.');
                var fileName              = Path.GetFileNameWithoutExtension(attachment.FileName);
                var fileNameWithExtension = fileName + "." + extension;
                var attachmentParentDto   = _attachmentCategorizer.CreateAttachmentDto(fileNameWithExtension);
                attachmentParentDto.PostId        = postEntity.Id;
                attachmentParentDto.FileExtension = extension;
                attachmentParentDto.FileName      = fileName;
                attachmentParentDto.Size          = attachment.Length;
                attachmentParentDto.Hash          = _cryptoService.HashHex(attachment.OpenReadStream());
                string blobName;

                switch (attachmentParentDto)
                {
                case AudioDto audioDto:
                {
                    var audioEntity = MapDtoToNewEntity <AudioDto, Audio>(audioDto);
                    audioEntity.Post = postEntity;
                    await _context.Audio.AddAsync(audioEntity);

                    await _context.SaveChangesAsync();

                    blobName = audioEntity.Id.ToString();
                    break;
                }

                case PictureDto pictureDto:
                {
                    if (_attachmentCategorizer.IsPictureExtensionSupported(pictureDto.FileExtension))
                    {
                        using (var image = Image.Load(attachment.OpenReadStream()))
                        {
                            pictureDto.Width  = image.Width;
                            pictureDto.Height = image.Height;

                            var pictureEntity = MapDtoToNewEntity <PictureDto, Picture>(pictureDto);
                            pictureEntity.Post = postEntity;
                            await _context.Pictures.AddAsync(pictureEntity);

                            await _context.SaveChangesAsync();

                            blobName = pictureEntity.Id.ToString();

                            // generate thumbnail
                            var thumbnail = _thumbnailGenerator.GenerateThumbnail(
                                image,
                                _hikkabaConfiguration.ThumbnailsMaxWidth,
                                _hikkabaConfiguration.ThumbnailsMaxHeight);
                            await _storageProvider.SaveBlobStreamAsync(containerName + Defaults.ThumbnailPostfix,
                                                                       blobName,
                                                                       thumbnail.Image);
                        }
                    }
                    else
                    {
                        var pictureEntity = MapDtoToNewEntity <PictureDto, Picture>(pictureDto);
                        pictureEntity.Post = postEntity;
                        await _context.Pictures.AddAsync(pictureEntity);

                        await _context.SaveChangesAsync();

                        blobName = pictureEntity.Id.ToString();

                        // save original image as thumbnail
                        await _storageProvider.SaveBlobStreamAsync(containerName + Defaults.ThumbnailPostfix,
                                                                   blobName,
                                                                   attachment.OpenReadStream());
                    }
                    break;
                }

                case VideoDto videoDto:
                {
                    var videoEntity = MapDtoToNewEntity <VideoDto, Video>(videoDto);
                    videoEntity.Post = postEntity;
                    await _context.Video.AddAsync(videoEntity);

                    await _context.SaveChangesAsync();

                    blobName = videoEntity.Id.ToString();
                    break;
                }

                case DocumentDto documentDto:
                {
                    var documentEntity = MapDtoToNewEntity <DocumentDto, Document>(documentDto);
                    documentEntity.Post = postEntity;
                    await _context.Documents.AddAsync(documentEntity);

                    await _context.SaveChangesAsync();

                    blobName = documentEntity.Id.ToString();
                    break;
                }

                default:
                    throw new Exception($"Unknown attachment type: {attachmentParentDto.GetType().Name}");
                }

                if (string.IsNullOrWhiteSpace(blobName))
                {
                    throw new Exception($"{nameof(blobName)} is null or whitespace");
                }
                await _storageProvider.SaveBlobStreamAsync(containerName, blobName, attachment.OpenReadStream());
            }
        }