diff options
author | crupest <crupest@outlook.com> | 2020-03-09 00:21:28 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2020-03-09 00:21:28 +0800 |
commit | 893ed4eee63997f2d91d6715d4355d9f767b2c40 (patch) | |
tree | 16c0dc235cfba2ec1fa17e3cb3bfbbead348cb3e | |
parent | 40df655a8d9b85a7f08ab221d5f85aaa20d7272e (diff) | |
download | timeline-893ed4eee63997f2d91d6715d4355d9f767b2c40.tar.gz timeline-893ed4eee63997f2d91d6715d4355d9f767b2c40.tar.bz2 timeline-893ed4eee63997f2d91d6715d4355d9f767b2c40.zip |
...
-rw-r--r-- | Timeline/Resources/Services/TimelineService.Designer.cs | 27 | ||||
-rw-r--r-- | Timeline/Resources/Services/TimelineService.resx | 9 | ||||
-rw-r--r-- | Timeline/Services/TimelinePostNotExistException.cs | 11 | ||||
-rw-r--r-- | Timeline/Services/TimelineService.cs | 55 |
4 files changed, 95 insertions, 7 deletions
diff --git a/Timeline/Resources/Services/TimelineService.Designer.cs b/Timeline/Resources/Services/TimelineService.Designer.cs index f4d41fb8..4c3de1cd 100644 --- a/Timeline/Resources/Services/TimelineService.Designer.cs +++ b/Timeline/Resources/Services/TimelineService.Designer.cs @@ -88,6 +88,24 @@ namespace Timeline.Resources.Services { }
/// <summary>
+ /// Looks up a localized string similar to The data entry of the tag of the image post does not exist..
+ /// </summary>
+ internal static string ExceptionGetDataDataEntryNotExist {
+ get {
+ return ResourceManager.GetString("ExceptionGetDataDataEntryNotExist", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Can't get data of a non-image post..
+ /// </summary>
+ internal static string ExceptionGetDataNonImagePost {
+ get {
+ return ResourceManager.GetString("ExceptionGetDataNonImagePost", resourceCulture);
+ }
+ }
+
+ /// <summary>
/// Looks up a localized string similar to The timeline name is of bad format because {0}..
/// </summary>
internal static string ExceptionTimelineNameBadFormat {
@@ -104,5 +122,14 @@ namespace Timeline.Resources.Services { return ResourceManager.GetString("ExceptionTimelineNameConflict", resourceCulture);
}
}
+
+ /// <summary>
+ /// Looks up a localized string similar to Image format type of the post does not exist in column "extra_content". Normally this couldn't be possible because it should be saved when post was created. However, we now re-detect the format and save it..
+ /// </summary>
+ internal static string LogGetDataNoFormat {
+ get {
+ return ResourceManager.GetString("LogGetDataNoFormat", resourceCulture);
+ }
+ }
}
}
diff --git a/Timeline/Resources/Services/TimelineService.resx b/Timeline/Resources/Services/TimelineService.resx index 7df55fdf..97269943 100644 --- a/Timeline/Resources/Services/TimelineService.resx +++ b/Timeline/Resources/Services/TimelineService.resx @@ -126,10 +126,19 @@ <data name="ExceptionFindTimelineUsernameBadFormat" xml:space="preserve">
<value>The owner username of personal timeline is of bad format.</value>
</data>
+ <data name="ExceptionGetDataDataEntryNotExist" xml:space="preserve">
+ <value>The data entry of the tag of the image post does not exist.</value>
+ </data>
+ <data name="ExceptionGetDataNonImagePost" xml:space="preserve">
+ <value>Can't get data of a non-image post.</value>
+ </data>
<data name="ExceptionTimelineNameBadFormat" xml:space="preserve">
<value>The timeline name is of bad format because {0}.</value>
</data>
<data name="ExceptionTimelineNameConflict" xml:space="preserve">
<value>The timeline with given name already exists.</value>
</data>
+ <data name="LogGetDataNoFormat" xml:space="preserve">
+ <value>Image format type of the post does not exist in column "extra_content". Normally this couldn't be possible because it should be saved when post was created. However, we now re-detect the format and save it.</value>
+ </data>
</root>
\ No newline at end of file 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; }
+ /// <summary>
+ /// True if the post is deleted. False if the post does not exist at all.
+ /// </summary>
+ 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 /// <returns>The data and its type.</returns>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="name"/> is null.</exception>
/// <exception cref="ArgumentException">Thrown when <paramref name="name"/> is illegal. It is not a valid timeline name (for normal timeline service) or a valid username (for personal timeline service).</exception>
- /// <exception cref="TimelinePostNotExistException">Thrown when post of <paramref name="postId"/> does not exist.</exception>
+ /// <exception cref="TimelinePostNotExistException">Thrown when post of <paramref name="postId"/> does not exist or has been deleted.</exception>
/// <exception cref="InvalidOperationException">Thrown when post has no data. See remarks.</exception>
/// <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<BaseTimelineService>();
Clock = clock;
Database = database;
ImageValidator = imageValidator;
@@ -340,6 +342,8 @@ namespace Timeline.Services Mapper = mapper;
}
+ private ILogger<BaseTimelineService> _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<DataWithType> 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<TimelinePostInfo> 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;
}
|