-
Notifications
You must be signed in to change notification settings - Fork 77
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: add abstract user services
- Added a new `IUserService` to allow plugins to query for users. We may or may not expose some events in the future, if the need arises for any plugins to react to user added/updated/removed events. - Added a new `IUserDataService` to allow plugins to read `IVideoUserData`s and write `VideoUserDataUpdate`s, and to react to user data save events. - Removed the `WatchedStatusService` in favour of the `IUserDataService`, and moved all usage of it onto the new abstraction service.
- Loading branch information
Showing
28 changed files
with
959 additions
and
574 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
using System; | ||
using Shoko.Plugin.Abstractions.DataModels.Shoko; | ||
|
||
namespace Shoko.Plugin.Abstractions.DataModels; | ||
|
||
/// <summary> | ||
/// Represents user-specific data. | ||
/// </summary> | ||
public interface IUserData | ||
{ | ||
/// <summary> | ||
/// Gets the ID of the user. | ||
/// </summary> | ||
int UserID { get; } | ||
|
||
/// <summary> | ||
/// Gets the date and time when the user data was last updated. | ||
/// </summary> | ||
DateTime LastUpdatedAt { get; } | ||
|
||
/// <summary> | ||
/// Gets the user associated with this video data. | ||
/// </summary> | ||
IShokoUser User { get; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
using System; | ||
|
||
namespace Shoko.Plugin.Abstractions.DataModels; | ||
|
||
/// <summary> | ||
/// Represents user-specific data associated with a video. | ||
/// </summary> | ||
public interface IVideoUserData : IUserData | ||
{ | ||
/// <summary> | ||
/// Gets the ID of the video. | ||
/// </summary> | ||
int VideoID { get; } | ||
|
||
/// <summary> | ||
/// Gets the number of times the video has been played. | ||
/// </summary> | ||
int PlaybackCount { get; } | ||
|
||
/// <summary> | ||
/// Gets the position in the video where playback was last resumed. | ||
/// </summary> | ||
TimeSpan ResumePosition { get; } | ||
|
||
/// <summary> | ||
/// Gets the date and time when the video was last played. | ||
/// </summary> | ||
DateTime? LastPlayedAt { get; } | ||
|
||
/// <summary> | ||
/// Gets the video associated with this user data. | ||
/// </summary> | ||
IVideo Video { get; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
namespace Shoko.Plugin.Abstractions.DataModels.Shoko; | ||
|
||
/// <summary> | ||
/// Shoko user. | ||
/// </summary> | ||
public interface IShokoUser | ||
{ | ||
/// <summary> | ||
/// Unique ID. | ||
/// </summary> | ||
int ID { get; } | ||
|
||
/// <summary> | ||
/// Username. | ||
/// </summary> | ||
string Username { get; } | ||
} |
31 changes: 31 additions & 0 deletions
31
Shoko.Plugin.Abstractions/DataModels/VideoUserDataUpdate.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
using System; | ||
|
||
namespace Shoko.Plugin.Abstractions.DataModels; | ||
|
||
/// <summary> | ||
/// Input data for updating a <see cref="IVideoUserData"/>. | ||
/// </summary> | ||
/// <param name="userData">An existing <see cref="IVideoUserData"/> to derive data from.</param> | ||
public class VideoUserDataUpdate(IVideoUserData? userData = null) | ||
{ | ||
/// <summary> | ||
/// Override or set the number of times the video has been played. | ||
/// </summary> | ||
public int? PlaybackCount { get; set; } = userData?.PlaybackCount; | ||
|
||
/// <summary> | ||
/// Override or set the position at which the video should be resumed. | ||
/// </summary> | ||
public TimeSpan? ResumePosition { get; set; } = userData?.ResumePosition; | ||
|
||
/// <summary> | ||
/// Override or set the date and time the video was last played. | ||
/// </summary> | ||
public DateTime? LastPlayedAt { get; set; } = userData?.LastPlayedAt; | ||
|
||
/// <summary> | ||
/// Override when the data was last updated. If not set, then the current | ||
/// time will be used. | ||
/// </summary> | ||
public DateTime? LastUpdatedAt { get; set; } = userData?.LastUpdatedAt; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
|
||
namespace Shoko.Plugin.Abstractions.Enums; | ||
|
||
/// <summary> | ||
/// The reason the user data is being saved. | ||
/// </summary> | ||
public enum UserDataSaveReason | ||
{ | ||
/// <summary> | ||
/// The user data is being saved for no specific reason. | ||
/// </summary> | ||
None = 0, | ||
|
||
/// <summary> | ||
/// The user data is being saved because of user interaction. | ||
/// </summary> | ||
UserInteraction, | ||
|
||
/// <summary> | ||
/// The user data is being saved when playback of a video started. | ||
/// </summary> | ||
PlaybackStart, | ||
|
||
/// <summary> | ||
/// The user data is being saved when playback of a video was paused. | ||
/// </summary> | ||
PlaybackPause, | ||
|
||
/// <summary> | ||
/// The user data is being saved when playback of a video was resumed. | ||
/// </summary> | ||
PlaybackResume, | ||
|
||
/// <summary> | ||
/// The user data is being saved when playback of a video progressed. | ||
/// </summary> | ||
PlaybackProgress, | ||
|
||
/// <summary> | ||
/// The user data is being saved when playback of a video ended. | ||
/// </summary> | ||
PlaybackEnd, | ||
|
||
/// <summary> | ||
/// The user data is being saved during an import from AniDB. | ||
/// </summary> | ||
AnidbImport, | ||
} |
47 changes: 47 additions & 0 deletions
47
Shoko.Plugin.Abstractions/Events/VideoUserDataSavedEventArgs.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
|
||
using Shoko.Plugin.Abstractions.DataModels; | ||
using Shoko.Plugin.Abstractions.DataModels.Shoko; | ||
using Shoko.Plugin.Abstractions.Enums; | ||
|
||
namespace Shoko.Plugin.Abstractions.Events; | ||
|
||
/// <summary> | ||
/// Dispatched when video user data was updated. | ||
/// </summary> | ||
public class VideoUserDataSavedEventArgs | ||
{ | ||
/// <summary> | ||
/// The reason why the user data was updated. | ||
/// </summary> | ||
public UserDataSaveReason Reason { get; } | ||
|
||
/// <summary> | ||
/// The user which had their data updated. | ||
/// </summary> | ||
public IShokoUser User { get; } | ||
|
||
/// <summary> | ||
/// The video which had its user data updated. | ||
/// </summary> | ||
public IVideo Video { get; } | ||
|
||
/// <summary> | ||
/// The updated video user data. | ||
/// </summary> | ||
public IVideoUserData UserData { get; } | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="VideoUserDataSavedEventArgs"/> class. | ||
/// </summary> | ||
/// <param name="reason">The reason why the user data was updated.</param> | ||
/// <param name="user">The user which had their data updated.</param> | ||
/// <param name="video">The video which had its user data updated.</param> | ||
/// <param name="userData">The updated video user data.</param> | ||
public VideoUserDataSavedEventArgs(UserDataSaveReason reason, IShokoUser user, IVideo video, IVideoUserData userData) | ||
{ | ||
Reason = reason; | ||
User = user; | ||
Video = video; | ||
UserData = userData; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
|
||
|
||
using System; | ||
using System.Collections.Generic; | ||
using System.Threading.Tasks; | ||
using Shoko.Plugin.Abstractions.DataModels; | ||
using Shoko.Plugin.Abstractions.DataModels.Shoko; | ||
using Shoko.Plugin.Abstractions.Enums; | ||
using Shoko.Plugin.Abstractions.Events; | ||
|
||
namespace Shoko.Plugin.Abstractions.Services; | ||
/// <summary> | ||
/// User data service. | ||
/// </summary> | ||
public interface IUserDataService | ||
{ | ||
#region Video User Data | ||
|
||
/// <summary> | ||
/// Dispatched when video user data is saved. | ||
/// </summary> | ||
event EventHandler<VideoUserDataSavedEventArgs> VideoUserDataSaved; | ||
|
||
/// <summary> | ||
/// Gets user video data for the given user and video. | ||
/// </summary> | ||
/// <param name="userID">The user ID.</param> | ||
/// <param name="videoID">The video ID.</param> | ||
/// <returns>The user video data.</returns> | ||
IVideoUserData? GetVideoUserData(int userID, int videoID); | ||
|
||
/// <summary> | ||
/// Gets all user video data for the given user. | ||
/// </summary> | ||
/// <param name="userID">The user ID.</param> | ||
/// <returns>The user video data.</returns> | ||
IReadOnlyList<IVideoUserData> GetVideoUserDataForUser(int userID); | ||
|
||
/// <summary> | ||
/// Gets all user video data for the given video. | ||
/// </summary> | ||
/// <param name="videoID">The video ID.</param> | ||
/// <returns>A list of user video data.</returns> | ||
IReadOnlyList<IVideoUserData> GetVideoUserDataForVideo(int videoID); | ||
|
||
/// <summary> | ||
/// Sets the video watch status. | ||
/// </summary> | ||
/// <param name="user">The user.</param> | ||
/// <param name="video">The video.</param> | ||
/// <param name="watched">Optional. If set to <c>true</c> the video is watched; otherwise, <c>false</c>.</param> | ||
/// <param name="watchedAt">Optional. The watched at.</param> | ||
/// <param name="reason">Optional. The reason why the video watch status was updated.</param> | ||
/// <param name="updateStatsNow">if set to <c>true</c> will update the series stats immediately after saving.</param> | ||
/// <exception cref="ArgumentNullException">The <paramref name="user"/> is null.</exception> | ||
/// <exception cref="ArgumentNullException">The <paramref name="video"/> is null.</exception> | ||
/// <returns>A task.</returns> | ||
Task SetVideoWatchedStatus(IShokoUser user, IVideo video, bool watched = true, DateTime? watchedAt = null, UserDataSaveReason reason = UserDataSaveReason.None, bool updateStatsNow = true); | ||
|
||
/// <summary> | ||
/// Saves the video user data. | ||
/// </summary> | ||
/// <param name="user">The user.</param> | ||
/// <param name="video">The video.</param> | ||
/// <param name="userDataUpdate">The user data update.</param> | ||
/// <param name="reason">The reason why the user data was updated.</param> | ||
/// <param name="updateStatsNow">if set to <c>true</c> will update the series stats immediately after saving.</param> | ||
/// <exception cref="ArgumentNullException">The <paramref name="user"/> is null.</exception> | ||
/// <exception cref="ArgumentNullException">The <paramref name="video"/> is null.</exception> | ||
/// <returns>The task containing the new or updated user video data.</returns> | ||
Task<IVideoUserData> SaveVideoUserData(IShokoUser user, IVideo video, VideoUserDataUpdate userDataUpdate, UserDataSaveReason reason = UserDataSaveReason.None, bool updateStatsNow = true); | ||
|
||
#endregion | ||
|
||
#region Episode User Data | ||
|
||
/// <summary> | ||
/// Sets the episode watch status. | ||
/// </summary> | ||
/// <remarks> | ||
/// Attempting to set the episode watch status for an episode without files will result in a no-op. | ||
/// </remarks> | ||
/// <param name="user">The user.</param> | ||
/// <param name="episode">The episode.</param> | ||
/// <param name="watched">Optional. If set to <c>true</c> the episode is watched; otherwise, <c>false</c>.</param> | ||
/// <param name="watchedAt">Optional. The watched at.</param> | ||
/// <param name="reason">Optional. The reason why the episode watch status was updated.</param> | ||
/// <param name="updateStatsNow">if set to <c>true</c> will update the series stats immediately after saving.</param> | ||
/// <exception cref="ArgumentNullException">The <paramref name="user"/> is null.</exception> | ||
/// <exception cref="ArgumentNullException">The <paramref name="episode"/> is null.</exception> | ||
/// <returns>The task containing the result if the episode watch status was updated.</returns> | ||
Task<bool> SetEpisodeWatchedStatus(IShokoUser user, IShokoEpisode episode, bool watched = true, DateTime? watchedAt = null, UserDataSaveReason reason = UserDataSaveReason.None, bool updateStatsNow = true); | ||
|
||
#endregion | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
using System.Linq; | ||
using Shoko.Plugin.Abstractions.DataModels.Shoko; | ||
|
||
namespace Shoko.Plugin.Abstractions.Services; | ||
|
||
/// <summary> | ||
/// User manager. | ||
/// </summary> | ||
public interface IUserService | ||
{ | ||
/// <summary> | ||
/// Get all users as a queryable list. | ||
/// </summary> | ||
/// <returns>The users.</returns> | ||
IQueryable<IShokoUser> GetUsers(); | ||
|
||
/// <summary> | ||
/// Get a user by ID. | ||
/// </summary> | ||
/// <param name="id">The ID.</param> | ||
/// <returns>The user.</returns> | ||
IShokoUser? GetUserByID(int id); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.