diff --git a/back/src/Kyoo.Abstractions/Controllers/IWatchStatusRepository.cs b/back/src/Kyoo.Abstractions/Controllers/IWatchStatusRepository.cs index a4b7fa3f..ca653c53 100644 --- a/back/src/Kyoo.Abstractions/Controllers/IWatchStatusRepository.cs +++ b/back/src/Kyoo.Abstractions/Controllers/IWatchStatusRepository.cs @@ -35,82 +35,23 @@ public interface IWatchStatusRepository // /// A representing the asynchronous operation. // public delegate Task ResourceEventHandler(T resource); - /// - /// Get the watch status of a movie - /// - /// The movie selector. - /// The id of the user. - /// The movie's status - Task GetMovieStatus(Expression> where, int userId); + Task GetMovieStatus(Guid movieId, Guid userId); + + Task SetMovieStatus(Guid movieId, Guid userId, WatchStatus status, int? watchedTime); + + Task DeleteMovieStatus(Guid movieId, Guid userId); + + Task GetShowStatus(Guid showId, Guid userId); + + Task SetShowStatus(Guid showId, Guid userId, WatchStatus status); + + Task DeleteShowStatus(Guid showId, Guid userId); + + Task GetEpisodeStatus(Guid episodeId, Guid userId); - /// - /// Set the watch status of a movie - /// - /// The id of the movie. - /// The id of the user. - /// The new status. /// Where the user has stopped watching. Only usable if Status /// is - /// The movie's status - Task SetMovieStatus(int movieId, int userId, WatchStatus status, int? watchedTime); + Task SetEpisodeStatus(Guid episodeId, Guid userId, WatchStatus status, int? watchedTime); - /// - /// Delete the watch status of a movie. - /// - /// The movie selector. - /// The id of the user. - /// Nothing. - Task DeleteMovieStatus(Expression> where, int userId); - - /// - /// Get the watch status of a show. - /// - /// The show selector. - /// The id of the user. - /// The show's status - Task GetShowStatus(Expression> where, int userId); - - /// - /// Set the watch status of a show. - /// - /// The id of the movie. - /// The id of the user. - /// The new status. - /// The shows's status - Task SetShowStatus(int showId, int userId, WatchStatus status); - - /// - /// Delete the watch status of a show. - /// - /// The show selector. - /// The id of the user. - /// Nothing. - Task DeleteShowStatus(Expression> where, int userId); - - /// - /// Get the watch status of an episode. - /// - /// The episode selector. - /// The id of the user. - /// The episode's status - Task GetEpisodeStatus(Expression> where, int userId); - - /// - /// Set the watch status of an episode. - /// - /// The id of the episode. - /// The id of the user. - /// The new status. - /// Where the user has stopped watching. Only usable if Status - /// is - /// The episode's status - Task SetEpisodeStatus(int episodeId, int userId, WatchStatus status, int? watchedTime); - - /// - /// Delete the watch status of an episode. - /// - /// The episode selector. - /// The id of the user. - /// Nothing. - Task DeleteEpisodeStatus(Expression> where, int userId); + Task DeleteEpisodeStatus(Guid episodeId, Guid userId); } diff --git a/back/src/Kyoo.Core/Controllers/Repositories/DapperHelper.cs b/back/src/Kyoo.Core/Controllers/Repositories/DapperHelper.cs index e0d55f50..72d11011 100644 --- a/back/src/Kyoo.Core/Controllers/Repositories/DapperHelper.cs +++ b/back/src/Kyoo.Core/Controllers/Repositories/DapperHelper.cs @@ -294,10 +294,20 @@ public static class DapperHelper Func, T> mapper, Include? include, Filter? filter, - Sort? sort = null) + Sort? sort = null, + bool reverse = false) where T : class, IResource, IQuery { - ICollection ret = await db.Query(command, config, mapper, null!, include, filter, sort, new Pagination(1)); + ICollection ret = await db.Query( + command, + config, + mapper, + get: null!, + include, + filter, + sort, + new Pagination(1, reverse: reverse) + ); return ret.FirstOrDefault(); } diff --git a/back/src/Kyoo.Core/Controllers/Repositories/DapperRepository.cs b/back/src/Kyoo.Core/Controllers/Repositories/DapperRepository.cs index 9de53105..27c30c11 100644 --- a/back/src/Kyoo.Core/Controllers/Repositories/DapperRepository.cs +++ b/back/src/Kyoo.Core/Controllers/Repositories/DapperRepository.cs @@ -128,7 +128,10 @@ public abstract class DapperRepository : IRepository } /// - public Task GetOrDefault(Filter? filter, Include? include = null, Sort? sortBy = null) + public Task GetOrDefault(Filter? filter, + Include? include = null, + Sort? sortBy = null, + bool reverse = false) { return Database.QuerySingle( Sql, diff --git a/back/src/Kyoo.Core/Controllers/Repositories/WatchStatusRepository.cs b/back/src/Kyoo.Core/Controllers/Repositories/WatchStatusRepository.cs index 077d8260..c546b6ce 100644 --- a/back/src/Kyoo.Core/Controllers/Repositories/WatchStatusRepository.cs +++ b/back/src/Kyoo.Core/Controllers/Repositories/WatchStatusRepository.cs @@ -23,6 +23,7 @@ using System.Linq.Expressions; using System.Threading.Tasks; using Kyoo.Abstractions.Controllers; using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Utils; using Kyoo.Postgresql; using Microsoft.EntityFrameworkCore; @@ -57,18 +58,15 @@ public class WatchStatusRepository : IWatchStatusRepository } /// - public Task GetMovieStatus(Expression> where, int userId) + public Task GetMovieStatus(Guid movieId, Guid userId) { - return _database.MovieWatchStatus.FirstOrDefaultAsync(x => - x.Movie == _database.Movies.FirstOrDefault(where) - && x.UserId == userId - ); + return _database.MovieWatchStatus.FirstOrDefaultAsync(x => x.MovieId == movieId && x.UserId == userId); } /// public async Task SetMovieStatus( - int movieId, - int userId, + Guid movieId, + Guid userId, WatchStatus status, int? watchedTime) { @@ -105,28 +103,24 @@ public class WatchStatusRepository : IWatchStatusRepository /// public async Task DeleteMovieStatus( - Expression> where, - int userId) + Guid movieId, + Guid userId) { await _database.MovieWatchStatus - .Where(x => x.Movie == _database.Movies.FirstOrDefault(where) - && x.UserId == userId) + .Where(x => x.MovieId == movieId && x.UserId == userId) .ExecuteDeleteAsync(); } /// - public Task GetShowStatus(Expression> where, int userId) + public Task GetShowStatus(Guid showId, Guid userId) { - return _database.ShowWatchStatus.FirstOrDefaultAsync(x => - x.Show == _database.Shows.FirstOrDefault(where) - && x.UserId == userId - ); + return _database.ShowWatchStatus.FirstOrDefaultAsync(x => x.ShowId == showId && x.UserId == userId); } /// public async Task SetShowStatus( - int showId, - int userId, + Guid showId, + Guid userId, WatchStatus status) { int unseenEpisodeCount = await _database.Episodes @@ -143,9 +137,11 @@ public class WatchStatusRepository : IWatchStatusRepository Status = status, NextEpisode = status == WatchStatus.Watching ? await _episodes.GetOrDefault( - where: x => x.ShowId == showId - && (x.WatchStatus!.Status == WatchStatus.Watching - || x.WatchStatus.Status == WatchStatus.Completed), + new Filter.Lambda( + x => x.ShowId == showId + && (x.WatchStatus!.Status == WatchStatus.Watching + || x.WatchStatus.Status == WatchStatus.Completed) + ), reverse: true ) : null, @@ -160,32 +156,27 @@ public class WatchStatusRepository : IWatchStatusRepository /// public async Task DeleteShowStatus( - Expression> where, - int userId) + Guid showId, + Guid userId) { await _database.ShowWatchStatus - .Where(x => x.Show == _database.Shows.FirstOrDefault(where) - && x.UserId == userId) + .Where(x => x.ShowId == showId && x.UserId == userId) .ExecuteDeleteAsync(); await _database.EpisodeWatchStatus - .Where(x => x.Episode.Show == _database.Shows.FirstOrDefault(where) - && x.UserId == userId) + .Where(x => x.Episode.ShowId == showId && x.UserId == userId) .ExecuteDeleteAsync(); } /// - public Task GetEpisodeStatus(Expression> where, int userId) + public Task GetEpisodeStatus(Guid episodeId, Guid userId) { - return _database.EpisodeWatchStatus.FirstOrDefaultAsync(x => - x.Episode == _database.Episodes.FirstOrDefault(where) - && x.UserId == userId - ); + return _database.EpisodeWatchStatus.FirstOrDefaultAsync(x => x.EpisodeId == episodeId && x.UserId == userId); } /// public async Task SetEpisodeStatus( - int episodeId, - int userId, + Guid episodeId, + Guid userId, WatchStatus status, int? watchedTime) { @@ -224,12 +215,11 @@ public class WatchStatusRepository : IWatchStatusRepository /// public async Task DeleteEpisodeStatus( - Expression> where, - int userId) + Guid episodeId, + Guid userId) { await _database.EpisodeWatchStatus - .Where(x => x.Episode == _database.Episodes.FirstOrDefault(where) - && x.UserId == userId) + .Where(x => x.EpisodeId == episodeId && x.UserId == userId) .ExecuteDeleteAsync(); } } diff --git a/back/src/Kyoo.Core/Views/Resources/EpisodeApi.cs b/back/src/Kyoo.Core/Views/Resources/EpisodeApi.cs index a91db99e..ed92e82d 100644 --- a/back/src/Kyoo.Core/Views/Resources/EpisodeApi.cs +++ b/back/src/Kyoo.Core/Views/Resources/EpisodeApi.cs @@ -16,6 +16,7 @@ // You should have received a copy of the GNU General Public License // along with Kyoo. If not, see . +using System; using System.Threading.Tasks; using Kyoo.Abstractions.Controllers; using Kyoo.Abstractions.Models; @@ -128,10 +129,11 @@ namespace Kyoo.Core.Api [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task GetWatchStatus(Identifier identifier) { - return await _libraryManager.WatchStatus.GetEpisodeStatus( - identifier.IsSame(), - User.GetId()!.Value + Guid id = await identifier.Match( + id => Task.FromResult(id), + async slug => (await _libraryManager.Episodes.Get(slug)).Id ); + return await _libraryManager.WatchStatus.GetEpisodeStatus(id, User.GetId()!.Value); } /// @@ -156,7 +158,7 @@ namespace Kyoo.Core.Api [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task SetWatchStatus(Identifier identifier, WatchStatus status, int? watchedTime) { - int id = await identifier.Match( + Guid id = await identifier.Match( id => Task.FromResult(id), async slug => (await _libraryManager.Episodes.Get(slug)).Id ); @@ -185,10 +187,11 @@ namespace Kyoo.Core.Api [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task DeleteWatchStatus(Identifier identifier) { - await _libraryManager.WatchStatus.DeleteEpisodeStatus( - identifier.IsSame(), - User.GetId()!.Value + Guid id = await identifier.Match( + id => Task.FromResult(id), + async slug => (await _libraryManager.Episodes.Get(slug)).Id ); + await _libraryManager.WatchStatus.DeleteEpisodeStatus(id, User.GetId()!.Value); } } } diff --git a/back/src/Kyoo.Core/Views/Resources/MovieApi.cs b/back/src/Kyoo.Core/Views/Resources/MovieApi.cs index 75b21b44..d42226f3 100644 --- a/back/src/Kyoo.Core/Views/Resources/MovieApi.cs +++ b/back/src/Kyoo.Core/Views/Resources/MovieApi.cs @@ -16,6 +16,7 @@ // You should have received a copy of the GNU General Public License // along with Kyoo. If not, see . +using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; @@ -169,10 +170,11 @@ namespace Kyoo.Core.Api [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task GetWatchStatus(Identifier identifier) { - return await _libraryManager.WatchStatus.GetMovieStatus( - identifier.IsSame(), - User.GetId()!.Value + Guid id = await identifier.Match( + id => Task.FromResult(id), + async slug => (await _libraryManager.Movies.Get(slug)).Id ); + return await _libraryManager.WatchStatus.GetMovieStatus(id, User.GetId()!.Value); } /// @@ -198,7 +200,7 @@ namespace Kyoo.Core.Api [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task SetWatchStatus(Identifier identifier, WatchStatus status, int? watchedTime) { - int id = await identifier.Match( + Guid id = await identifier.Match( id => Task.FromResult(id), async slug => (await _libraryManager.Movies.Get(slug)).Id ); @@ -227,10 +229,11 @@ namespace Kyoo.Core.Api [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task DeleteWatchStatus(Identifier identifier) { - await _libraryManager.WatchStatus.DeleteMovieStatus( - identifier.IsSame(), - User.GetId()!.Value + Guid id = await identifier.Match( + id => Task.FromResult(id), + async slug => (await _libraryManager.Movies.Get(slug)).Id ); + await _libraryManager.WatchStatus.DeleteMovieStatus(id, User.GetId()!.Value); } } } diff --git a/back/src/Kyoo.Core/Views/Resources/ShowApi.cs b/back/src/Kyoo.Core/Views/Resources/ShowApi.cs index 98f11a78..46a03639 100644 --- a/back/src/Kyoo.Core/Views/Resources/ShowApi.cs +++ b/back/src/Kyoo.Core/Views/Resources/ShowApi.cs @@ -16,6 +16,7 @@ // You should have received a copy of the GNU General Public License // along with Kyoo. If not, see . +using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; @@ -246,10 +247,11 @@ namespace Kyoo.Core.Api [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task GetWatchStatus(Identifier identifier) { - return await _libraryManager.WatchStatus.GetShowStatus( - identifier.IsSame(), - User.GetId()!.Value + Guid id = await identifier.Match( + id => Task.FromResult(id), + async slug => (await _libraryManager.Shows.Get(slug)).Id ); + return await _libraryManager.WatchStatus.GetShowStatus(id, User.GetId()!.Value); } /// @@ -273,7 +275,7 @@ namespace Kyoo.Core.Api [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task SetWatchStatus(Identifier identifier, WatchStatus status) { - int id = await identifier.Match( + Guid id = await identifier.Match( id => Task.FromResult(id), async slug => (await _libraryManager.Shows.Get(slug)).Id ); @@ -301,10 +303,11 @@ namespace Kyoo.Core.Api [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task DeleteWatchStatus(Identifier identifier) { - await _libraryManager.WatchStatus.DeleteShowStatus( - identifier.IsSame(), - User.GetId()!.Value + Guid id = await identifier.Match( + id => Task.FromResult(id), + async slug => (await _libraryManager.Shows.Get(slug)).Id ); + await _libraryManager.WatchStatus.DeleteShowStatus(id, User.GetId()!.Value); } } }