public async Task <TimelinePostEntity> CreatePostAsync(long timelineId, long authorId, TimelinePostCreateRequest request) { if (request is null) { throw new ArgumentNullException(nameof(request)); } if (request.Color is not null) { CheckColor(request.Color, nameof(request)); } if (request.DataList is null) { throw new ArgumentException(Resource.ExceptionDataListNull, nameof(request)); } if (request.DataList.Count == 0) { throw new ArgumentException(Resource.ExceptionDataListEmpty, nameof(request)); } if (request.DataList.Count > 100) { throw new ArgumentException(Resource.ExceptionDataListTooLarge, nameof(request)); } for (int index = 0; index < request.DataList.Count; index++) { var data = request.DataList[index]; switch (data.ContentType) { case MimeTypes.ImageGif: case MimeTypes.ImageJpeg: case MimeTypes.ImagePng: case MimeTypes.ImageWebp: try { await _imageValidator.ValidateAsync(data.Data, data.ContentType); } catch (ImageException e) { throw new TimelinePostCreateDataException(index, Resource.ExceptionPostDataImageInvalid, e); } break; case MimeTypes.TextPlain: case MimeTypes.TextMarkdown: try { new UTF8Encoding(false, true).GetString(data.Data); } catch (DecoderFallbackException e) { throw new TimelinePostCreateDataException(index, Resource.ExceptionPostDataNotValidUtf8, e); } break; default: throw new TimelinePostCreateDataException(index, Resource.ExceptionPostDataUnsupportedType); } } request.Time = request.Time?.MyToUtc(); await _basicTimelineService.ThrowIfTimelineNotExist(timelineId); await _basicUserService.ThrowIfUserNotExist(authorId); var currentTime = _clock.GetCurrentTime(); var finalTime = request.Time ?? currentTime; await using var transaction = await _database.Database.BeginTransactionAsync(); var postEntity = new TimelinePostEntity { AuthorId = authorId, TimelineId = timelineId, Time = finalTime, LastUpdated = currentTime, Color = request.Color }; var timelineEntity = await _database.Timelines.Where(t => t.Id == timelineId).SingleAsync(); timelineEntity.CurrentPostLocalId += 1; postEntity.LocalId = timelineEntity.CurrentPostLocalId; _database.TimelinePosts.Add(postEntity); await _database.SaveChangesAsync(); List <string> dataTags = new List <string>(); for (int index = 0; index < request.DataList.Count; index++) { var data = request.DataList[index]; var tag = await _dataManager.RetainEntryAsync(data.Data); _database.TimelinePostData.Add(new TimelinePostDataEntity { DataTag = tag, Kind = data.ContentType, Index = index, PostId = postEntity.Id, LastUpdated = currentTime, }); } await _database.SaveChangesAsync(); await transaction.CommitAsync(); _logger.LogInformation(Resource.LogTimelinePostCreated, timelineId, postEntity.Id); return(postEntity); }
private Task <HttpTimelinePost> Map(TimelinePostEntity post) { return(_mapper.MapAsync <HttpTimelinePost>(post, Url, User)); }