diff options
author | crupest <crupest@outlook.com> | 2021-04-27 19:37:11 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2021-04-27 19:37:11 +0800 |
commit | e619eac394b4e1c7a3cb0c5902b2776314c7b979 (patch) | |
tree | 8f082eedd694d74a1e9944e30ca9d1b3b6ec3f5a /BackEnd/Timeline/Services/User | |
parent | a665f5d894539cae5f4188e4a72ea9634b8c4ed0 (diff) | |
download | timeline-e619eac394b4e1c7a3cb0c5902b2776314c7b979.tar.gz timeline-e619eac394b4e1c7a3cb0c5902b2776314c7b979.tar.bz2 timeline-e619eac394b4e1c7a3cb0c5902b2776314c7b979.zip |
refactor: ...
Diffstat (limited to 'BackEnd/Timeline/Services/User')
-rw-r--r-- | BackEnd/Timeline/Services/User/Avatar/DefaultUserAvatarProvider.cs | 51 | ||||
-rw-r--r-- | BackEnd/Timeline/Services/User/Avatar/IDefaultUserAvatarProvider.cs | 27 | ||||
-rw-r--r-- | BackEnd/Timeline/Services/User/Avatar/IUserAvatarService.cs | 45 | ||||
-rw-r--r-- | BackEnd/Timeline/Services/User/Avatar/UserAvatarService.cs (renamed from BackEnd/Timeline/Services/User/UserAvatarService.cs) | 124 | ||||
-rw-r--r-- | BackEnd/Timeline/Services/User/Avatar/UserAvatarServicesServiceCollectionExtensions.cs | 14 | ||||
-rw-r--r-- | BackEnd/Timeline/Services/User/UserServicesServiceCollectionExtensions.cs | 26 |
6 files changed, 169 insertions, 118 deletions
diff --git a/BackEnd/Timeline/Services/User/Avatar/DefaultUserAvatarProvider.cs b/BackEnd/Timeline/Services/User/Avatar/DefaultUserAvatarProvider.cs new file mode 100644 index 00000000..9f8f1c62 --- /dev/null +++ b/BackEnd/Timeline/Services/User/Avatar/DefaultUserAvatarProvider.cs @@ -0,0 +1,51 @@ +using Microsoft.AspNetCore.Hosting;
+using SixLabors.ImageSharp;
+using System.IO;
+using System.Threading.Tasks;
+using Timeline.Helpers.Cache;
+using Timeline.Models;
+using Timeline.Services.Data;
+
+namespace Timeline.Services.User.Avatar
+{
+ // TODO! : Make this configurable.
+ public class DefaultUserAvatarProvider : IDefaultUserAvatarProvider
+ {
+ private readonly IETagGenerator _eTagGenerator;
+
+ private readonly string _avatarPath;
+
+ private CacheableDataDigest? _cacheDigest;
+ private ByteData? _cacheData;
+
+ public DefaultUserAvatarProvider(IWebHostEnvironment environment, IETagGenerator eTagGenerator)
+ {
+ _avatarPath = Path.Combine(environment.ContentRootPath, "default-avatar.png");
+ _eTagGenerator = eTagGenerator;
+ }
+
+ private async Task CheckAndInit()
+ {
+ var path = _avatarPath;
+ if (_cacheData == null || File.GetLastWriteTime(path) > _cacheDigest!.LastModified)
+ {
+ var data = await File.ReadAllBytesAsync(path);
+ _cacheDigest = new CacheableDataDigest(await _eTagGenerator.GenerateETagAsync(data), File.GetLastWriteTime(path));
+ Image.Identify(data, out var format);
+ _cacheData = new ByteData(data, format.DefaultMimeType);
+ }
+ }
+
+ public async Task<ICacheableDataDigest> GetDefaultAvatarDigest()
+ {
+ await CheckAndInit();
+ return _cacheDigest!;
+ }
+
+ public async Task<ByteData> GetDefaultAvatar()
+ {
+ await CheckAndInit();
+ return _cacheData!;
+ }
+ }
+}
diff --git a/BackEnd/Timeline/Services/User/Avatar/IDefaultUserAvatarProvider.cs b/BackEnd/Timeline/Services/User/Avatar/IDefaultUserAvatarProvider.cs new file mode 100644 index 00000000..50c9ac91 --- /dev/null +++ b/BackEnd/Timeline/Services/User/Avatar/IDefaultUserAvatarProvider.cs @@ -0,0 +1,27 @@ +using System.Threading.Tasks;
+using Timeline.Helpers.Cache;
+using Timeline.Models;
+
+namespace Timeline.Services.User.Avatar
+{
+ /// <summary>
+ /// Provider for default user avatar.
+ /// </summary>
+ /// <remarks>
+ /// Mainly for unit tests.
+ /// </remarks>
+ public interface IDefaultUserAvatarProvider
+ {
+ /// <summary>
+ /// Get the digest of default avatar.
+ /// </summary>
+ /// <returns>The digest.</returns>
+ Task<ICacheableDataDigest> GetDefaultAvatarDigest();
+
+ /// <summary>
+ /// Get the default avatar.
+ /// </summary>
+ /// <returns>The avatar.</returns>
+ Task<ByteData> GetDefaultAvatar();
+ }
+}
diff --git a/BackEnd/Timeline/Services/User/Avatar/IUserAvatarService.cs b/BackEnd/Timeline/Services/User/Avatar/IUserAvatarService.cs new file mode 100644 index 00000000..fda35aac --- /dev/null +++ b/BackEnd/Timeline/Services/User/Avatar/IUserAvatarService.cs @@ -0,0 +1,45 @@ +using System;
+using System.Threading.Tasks;
+using Timeline.Helpers.Cache;
+using Timeline.Models;
+using Timeline.Services.Imaging;
+
+namespace Timeline.Services.User.Avatar
+{
+ public interface IUserAvatarService
+ {
+ /// <summary>
+ /// Get avatar digest of a user.
+ /// </summary>
+ /// <param name="userId">User id.</param>
+ /// <returns>The avatar digest.</returns>
+ /// <exception cref="UserNotExistException">Thrown when user does not exist.</exception>
+ Task<ICacheableDataDigest> GetAvatarDigest(long userId);
+
+ /// <summary>
+ /// Get avatar of a user. If the user has no avatar set, a default one is returned.
+ /// </summary>
+ /// <param name="userId">User id.</param>
+ /// <returns>The avatar.</returns>
+ /// <exception cref="UserNotExistException">Thrown when user does not exist.</exception>
+ Task<ByteData> GetAvatar(long userId);
+
+ /// <summary>
+ /// Set avatar for a user.
+ /// </summary>
+ /// <param name="userId">User id.</param>
+ /// <param name="avatar">The new avatar data.</param>
+ /// <returns>The digest of the avatar.</returns>
+ /// <exception cref="ArgumentNullException">Thrown if <paramref name="avatar"/> is null.</exception>
+ /// <exception cref="UserNotExistException">Thrown when user does not exist.</exception>
+ /// <exception cref="ImageException">Thrown if avatar is of bad format.</exception>
+ Task<ICacheableDataDigest> SetAvatar(long userId, ByteData avatar);
+
+ /// <summary>
+ /// Remove avatar of a user.
+ /// </summary>
+ /// <param name="userId">User id.</param>
+ /// <exception cref="UserNotExistException">Thrown when user does not exist.</exception>
+ Task DeleteAvatar(long userId);
+ }
+}
diff --git a/BackEnd/Timeline/Services/User/UserAvatarService.cs b/BackEnd/Timeline/Services/User/Avatar/UserAvatarService.cs index 9f59624d..4f943e3a 100644 --- a/BackEnd/Timeline/Services/User/UserAvatarService.cs +++ b/BackEnd/Timeline/Services/User/Avatar/UserAvatarService.cs @@ -1,10 +1,6 @@ -using Microsoft.AspNetCore.Hosting;
-using Microsoft.EntityFrameworkCore;
-using Microsoft.Extensions.DependencyInjection;
+using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
-using SixLabors.ImageSharp;
using System;
-using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Timeline.Entities;
@@ -13,114 +9,15 @@ using Timeline.Models; using Timeline.Services.Data;
using Timeline.Services.Imaging;
-namespace Timeline.Services.User
+namespace Timeline.Services.User.Avatar
{
- /// <summary>
- /// Provider for default user avatar.
- /// </summary>
- /// <remarks>
- /// Mainly for unit tests.
- /// </remarks>
- public interface IDefaultUserAvatarProvider
- {
- /// <summary>
- /// Get the digest of default avatar.
- /// </summary>
- /// <returns>The digest.</returns>
- Task<ICacheableDataDigest> GetDefaultAvatarDigest();
-
- /// <summary>
- /// Get the default avatar.
- /// </summary>
- /// <returns>The avatar.</returns>
- Task<ByteData> GetDefaultAvatar();
- }
-
- public interface IUserAvatarService
- {
- /// <summary>
- /// Get avatar digest of a user.
- /// </summary>
- /// <param name="userId">User id.</param>
- /// <returns>The avatar digest.</returns>
- /// <exception cref="UserNotExistException">Thrown when user does not exist.</exception>
- Task<ICacheableDataDigest> GetAvatarDigest(long userId);
-
- /// <summary>
- /// Get avatar of a user. If the user has no avatar set, a default one is returned.
- /// </summary>
- /// <param name="userId">User id.</param>
- /// <returns>The avatar.</returns>
- /// <exception cref="UserNotExistException">Thrown when user does not exist.</exception>
- Task<ByteData> GetAvatar(long userId);
-
- /// <summary>
- /// Set avatar for a user.
- /// </summary>
- /// <param name="userId">User id.</param>
- /// <param name="avatar">The new avatar data.</param>
- /// <returns>The digest of the avatar.</returns>
- /// <exception cref="ArgumentNullException">Thrown if <paramref name="avatar"/> is null.</exception>
- /// <exception cref="UserNotExistException">Thrown when user does not exist.</exception>
- /// <exception cref="ImageException">Thrown if avatar is of bad format.</exception>
- Task<ICacheableDataDigest> SetAvatar(long userId, ByteData avatar);
-
- /// <summary>
- /// Remove avatar of a user.
- /// </summary>
- /// <param name="userId">User id.</param>
- /// <exception cref="UserNotExistException">Thrown when user does not exist.</exception>
- Task DeleteAvatar(long userId);
- }
-
- // TODO! : Make this configurable.
- public class DefaultUserAvatarProvider : IDefaultUserAvatarProvider
- {
- private readonly IETagGenerator _eTagGenerator;
-
- private readonly string _avatarPath;
-
- private CacheableDataDigest? _cacheDigest;
- private ByteData? _cacheData;
-
- public DefaultUserAvatarProvider(IWebHostEnvironment environment, IETagGenerator eTagGenerator)
- {
- _avatarPath = Path.Combine(environment.ContentRootPath, "default-avatar.png");
- _eTagGenerator = eTagGenerator;
- }
-
- private async Task CheckAndInit()
- {
- var path = _avatarPath;
- if (_cacheData == null || File.GetLastWriteTime(path) > _cacheDigest!.LastModified)
- {
- var data = await File.ReadAllBytesAsync(path);
- _cacheDigest = new CacheableDataDigest(await _eTagGenerator.GenerateETagAsync(data), File.GetLastWriteTime(path));
- Image.Identify(data, out var format);
- _cacheData = new ByteData(data, format.DefaultMimeType);
- }
- }
-
- public async Task<ICacheableDataDigest> GetDefaultAvatarDigest()
- {
- await CheckAndInit();
- return _cacheDigest!;
- }
-
- public async Task<ByteData> GetDefaultAvatar()
- {
- await CheckAndInit();
- return _cacheData!;
- }
- }
-
public class UserAvatarService : IUserAvatarService
{
private readonly ILogger<UserAvatarService> _logger;
private readonly DatabaseContext _database;
private readonly IBasicUserService _basicUserService;
private readonly IDefaultUserAvatarProvider _defaultUserAvatarProvider;
- private readonly IImageService _imageValidator;
+ private readonly IImageService _imageService;
private readonly IDataManager _dataManager;
private readonly IClock _clock;
@@ -137,7 +34,7 @@ namespace Timeline.Services.User _database = database;
_basicUserService = basicUserService;
_defaultUserAvatarProvider = defaultUserAvatarProvider;
- _imageValidator = imageValidator;
+ _imageService = imageValidator;
_dataManager = dataManager;
_clock = clock;
}
@@ -179,7 +76,7 @@ namespace Timeline.Services.User if (entity.Type is null)
{
- Image.Identify(data, out var format);
+ var format = await _imageService.DetectFormatAsync(data);
entity.Type = format.DefaultMimeType;
await _database.SaveChangesAsync();
}
@@ -192,7 +89,7 @@ namespace Timeline.Services.User if (avatar is null)
throw new ArgumentNullException(nameof(avatar));
- await _imageValidator.ValidateAsync(avatar.Data, avatar.ContentType, true);
+ await _imageService.ValidateAsync(avatar.Data, avatar.ContentType, true);
await _basicUserService.ThrowIfUserNotExist(userId);
@@ -254,13 +151,4 @@ namespace Timeline.Services.User await transaction.CommitAsync();
}
}
-
- public static class UserAvatarServiceCollectionExtensions
- {
- public static void AddUserAvatarService(this IServiceCollection services)
- {
- services.AddScoped<IUserAvatarService, UserAvatarService>();
- services.AddScoped<IDefaultUserAvatarProvider, DefaultUserAvatarProvider>();
- }
- }
}
diff --git a/BackEnd/Timeline/Services/User/Avatar/UserAvatarServicesServiceCollectionExtensions.cs b/BackEnd/Timeline/Services/User/Avatar/UserAvatarServicesServiceCollectionExtensions.cs new file mode 100644 index 00000000..57279855 --- /dev/null +++ b/BackEnd/Timeline/Services/User/Avatar/UserAvatarServicesServiceCollectionExtensions.cs @@ -0,0 +1,14 @@ +using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.DependencyInjection.Extensions;
+
+namespace Timeline.Services.User.Avatar
+{
+ public static class UserAvatarServicesServiceCollectionExtensions
+ {
+ public static void AddUserAvatarServices(this IServiceCollection services)
+ {
+ services.TryAddScoped<IUserAvatarService, UserAvatarService>();
+ services.TryAddScoped<IDefaultUserAvatarProvider, DefaultUserAvatarProvider>();
+ }
+ }
+}
diff --git a/BackEnd/Timeline/Services/User/UserServicesServiceCollectionExtensions.cs b/BackEnd/Timeline/Services/User/UserServicesServiceCollectionExtensions.cs new file mode 100644 index 00000000..6320b608 --- /dev/null +++ b/BackEnd/Timeline/Services/User/UserServicesServiceCollectionExtensions.cs @@ -0,0 +1,26 @@ +using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.DependencyInjection.Extensions;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Timeline.Services.User.Avatar;
+
+namespace Timeline.Services.User
+{
+ public static class UserServicesServiceCollectionExtensions
+ {
+ public static IServiceCollection AddUserServices(this IServiceCollection services)
+ {
+ services.TryAddTransient<IPasswordService, PasswordService>();
+ services.TryAddScoped<IBasicUserService, BasicUserService>();
+ services.TryAddScoped<IUserService, UserService>();
+ services.TryAddScoped<IUserDeleteService, UserDeleteService>();
+ services.TryAddScoped<IUserPermissionService, UserPermissionService>();
+
+ services.AddUserAvatarServices();
+
+ return services;
+ }
+ }
+}
|