From c3c9618c8493349fb3d6464d69359f7be6e8ce24 Mon Sep 17 00:00:00 2001 From: crupest Date: Mon, 9 Mar 2020 00:21:28 +0800 Subject: ... --- Timeline/Services/TimelinePostNotExistException.cs | 11 +++-- Timeline/Services/TimelineService.cs | 55 ++++++++++++++++++++-- 2 files changed, 59 insertions(+), 7 deletions(-) (limited to 'Timeline/Services') diff --git a/Timeline/Services/TimelinePostNotExistException.cs b/Timeline/Services/TimelinePostNotExistException.cs index 97e5d550..c542e63e 100644 --- a/Timeline/Services/TimelinePostNotExistException.cs +++ b/Timeline/Services/TimelinePostNotExistException.cs @@ -12,12 +12,17 @@ namespace Timeline.Services System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { } - public TimelinePostNotExistException(long id) : base(Resources.Services.Exception.TimelinePostNotExistException) { Id = id; } + public TimelinePostNotExistException(string timelineName, long id, bool isDelete = false) : base(Resources.Services.Exception.TimelinePostNotExistException) { TimelineName = timelineName; Id = id; IsDelete = isDelete; } - public TimelinePostNotExistException(long id, string message) : base(message) { Id = id; } + public TimelinePostNotExistException(string timelineName, long id, bool isDelete, string message) : base(message) { TimelineName = timelineName; Id = id; IsDelete = isDelete; } - public TimelinePostNotExistException(long id, string message, Exception inner) : base(message, inner) { Id = id; } + public TimelinePostNotExistException(string timelineName, long id, bool isDelete, string message, Exception inner) : base(message, inner) { TimelineName = timelineName; Id = id; IsDelete = isDelete; } + public string TimelineName { get; set; } = ""; public long Id { get; set; } + /// + /// True if the post is deleted. False if the post does not exist at all. + /// + public bool IsDelete { get; set; } = false; } } diff --git a/Timeline/Services/TimelineService.cs b/Timeline/Services/TimelineService.cs index ff2532ea..a2b7b5ea 100644 --- a/Timeline/Services/TimelineService.cs +++ b/Timeline/Services/TimelineService.cs @@ -1,6 +1,7 @@ using AutoMapper; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; +using SixLabors.ImageSharp; using System; using System.Collections.Generic; using System.Globalization; @@ -105,7 +106,7 @@ namespace Timeline.Services /// The data and its type. /// Thrown when is null. /// Thrown when is illegal. It is not a valid timeline name (for normal timeline service) or a valid username (for personal timeline service). - /// Thrown when post of does not exist. + /// Thrown when post of does not exist or has been deleted. /// Thrown when post has no data. See remarks. /// /// Use this method to retrieve the image of image post. @@ -332,6 +333,7 @@ namespace Timeline.Services { protected BaseTimelineService(ILoggerFactory loggerFactory, DatabaseContext database, IImageValidator imageValidator, IDataManager dataManager, IUserService userService, IMapper mapper, IClock clock) { + _logger = loggerFactory.CreateLogger(); Clock = clock; Database = database; ImageValidator = imageValidator; @@ -340,6 +342,8 @@ namespace Timeline.Services Mapper = mapper; } + private ILogger _logger; + protected IClock Clock { get; } protected UsernameValidator UsernameValidator { get; } = new UsernameValidator(); @@ -422,7 +426,6 @@ namespace Timeline.Services if (name == null) throw new ArgumentNullException(nameof(name)); - var timelineId = await FindTimelineId(name); var postEntities = await Database.TimelinePosts.OrderBy(p => p.Time).Where(p => p.TimelineId == timelineId && p.Content != null).ToListAsync(); @@ -454,6 +457,50 @@ namespace Timeline.Services } return posts; } + public async Task GetPostData(string name, long postId) + { + if (name == null) + throw new ArgumentNullException(nameof(name)); + + var timelineId = await FindTimelineId(name); + var postEntity = await Database.TimelinePosts.Where(p => p.LocalId == postId).SingleOrDefaultAsync(); + + if (postEntity == null) + throw new TimelinePostNotExistException(name, postId); + + if (postEntity.Content == null) + throw new TimelinePostNotExistException(name, postId, true); + + if (postEntity.ContentType != TimelinePostContentTypes.Image) + throw new InvalidOperationException(ExceptionGetDataNonImagePost); + + var tag = postEntity.Content; + + byte[] data; + + try + { + data = await DataManager.GetEntry(tag); + } + catch (InvalidOperationException e) + { + throw new DatabaseCorruptedException(ExceptionGetDataDataEntryNotExist, e); + } + + if (postEntity.ExtraContent == null) + { + _logger.LogWarning(LogGetDataNoFormat); + var format = Image.DetectFormat(data); + postEntity.ExtraContent = format.DefaultMimeType; + await Database.SaveChangesAsync(); + } + + return new DataWithType + { + Data = data, + Type = postEntity.ExtraContent + }; + } public async Task CreateTextPost(string name, long authorId, string text, DateTime? time) { @@ -552,7 +599,7 @@ namespace Timeline.Services var post = await Database.TimelinePosts.Where(p => p.TimelineId == timelineId && p.LocalId == id).SingleOrDefaultAsync(); if (post == null) - throw new TimelinePostNotExistException(id); + throw new TimelinePostNotExistException(name, id); string? dataTag = null; @@ -721,7 +768,7 @@ namespace Timeline.Services var postEntity = await Database.TimelinePosts.Where(p => p.Id == id).Select(p => new { p.AuthorId }).SingleOrDefaultAsync(); if (postEntity == null) - throw new TimelinePostNotExistException(id); + throw new TimelinePostNotExistException(name, id); return timelineEntity.OwnerId == modifierId || postEntity.AuthorId == modifierId; } -- cgit v1.2.3