Update watch list code to use guids

This commit is contained in:
Zoe Roux 2023-11-29 02:42:45 +01:00
parent b9932383c6
commit 4139362677
7 changed files with 89 additions and 136 deletions

View File

@ -35,82 +35,23 @@ public interface IWatchStatusRepository
// /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
// public delegate Task ResourceEventHandler(T resource);
/// <summary>
/// Get the watch status of a movie
/// </summary>
/// <param name="where">The movie selector.</param>
/// <param name="userId">The id of the user.</param>
/// <returns>The movie's status</returns>
Task<MovieWatchStatus?> GetMovieStatus(Expression<Func<Movie, bool>> where, int userId);
Task<MovieWatchStatus?> GetMovieStatus(Guid movieId, Guid userId);
Task<MovieWatchStatus?> SetMovieStatus(Guid movieId, Guid userId, WatchStatus status, int? watchedTime);
Task DeleteMovieStatus(Guid movieId, Guid userId);
Task<ShowWatchStatus?> GetShowStatus(Guid showId, Guid userId);
Task<ShowWatchStatus?> SetShowStatus(Guid showId, Guid userId, WatchStatus status);
Task DeleteShowStatus(Guid showId, Guid userId);
Task<EpisodeWatchStatus?> GetEpisodeStatus(Guid episodeId, Guid userId);
/// <summary>
/// Set the watch status of a movie
/// </summary>
/// <param name="movieId">The id of the movie.</param>
/// <param name="userId">The id of the user.</param>
/// <param name="status">The new status.</param>
/// <param name="watchedTime">Where the user has stopped watching. Only usable if Status
/// is <see cref="WatchStatus.Watching"/></param>
/// <returns>The movie's status</returns>
Task<MovieWatchStatus?> SetMovieStatus(int movieId, int userId, WatchStatus status, int? watchedTime);
Task<EpisodeWatchStatus?> SetEpisodeStatus(Guid episodeId, Guid userId, WatchStatus status, int? watchedTime);
/// <summary>
/// Delete the watch status of a movie.
/// </summary>
/// <param name="where">The movie selector.</param>
/// <param name="userId">The id of the user.</param>
/// <returns>Nothing.</returns>
Task DeleteMovieStatus(Expression<Func<Movie, bool>> where, int userId);
/// <summary>
/// Get the watch status of a show.
/// </summary>
/// <param name="where">The show selector.</param>
/// <param name="userId">The id of the user.</param>
/// <returns>The show's status</returns>
Task<ShowWatchStatus?> GetShowStatus(Expression<Func<Show, bool>> where, int userId);
/// <summary>
/// Set the watch status of a show.
/// </summary>
/// <param name="showId">The id of the movie.</param>
/// <param name="userId">The id of the user.</param>
/// <param name="status">The new status.</param>
/// <returns>The shows's status</returns>
Task<ShowWatchStatus?> SetShowStatus(int showId, int userId, WatchStatus status);
/// <summary>
/// Delete the watch status of a show.
/// </summary>
/// <param name="where">The show selector.</param>
/// <param name="userId">The id of the user.</param>
/// <returns>Nothing.</returns>
Task DeleteShowStatus(Expression<Func<Show, bool>> where, int userId);
/// <summary>
/// Get the watch status of an episode.
/// </summary>
/// <param name="where">The episode selector.</param>
/// <param name="userId">The id of the user.</param>
/// <returns>The episode's status</returns>
Task<EpisodeWatchStatus?> GetEpisodeStatus(Expression<Func<Episode, bool>> where, int userId);
/// <summary>
/// Set the watch status of an episode.
/// </summary>
/// <param name="episodeId">The id of the episode.</param>
/// <param name="userId">The id of the user.</param>
/// <param name="status">The new status.</param>
/// <param name="watchedTime">Where the user has stopped watching. Only usable if Status
/// is <see cref="WatchStatus.Watching"/></param>
/// <returns>The episode's status</returns>
Task<EpisodeWatchStatus?> SetEpisodeStatus(int episodeId, int userId, WatchStatus status, int? watchedTime);
/// <summary>
/// Delete the watch status of an episode.
/// </summary>
/// <param name="where">The episode selector.</param>
/// <param name="userId">The id of the user.</param>
/// <returns>Nothing.</returns>
Task DeleteEpisodeStatus(Expression<Func<Episode, bool>> where, int userId);
Task DeleteEpisodeStatus(Guid episodeId, Guid userId);
}

View File

@ -294,10 +294,20 @@ public static class DapperHelper
Func<List<object?>, T> mapper,
Include<T>? include,
Filter<T>? filter,
Sort<T>? sort = null)
Sort<T>? sort = null,
bool reverse = false)
where T : class, IResource, IQuery
{
ICollection<T> ret = await db.Query<T>(command, config, mapper, null!, include, filter, sort, new Pagination(1));
ICollection<T> ret = await db.Query<T>(
command,
config,
mapper,
get: null!,
include,
filter,
sort,
new Pagination(1, reverse: reverse)
);
return ret.FirstOrDefault();
}

View File

@ -128,7 +128,10 @@ public abstract class DapperRepository<T> : IRepository<T>
}
/// <inheritdoc />
public Task<T?> GetOrDefault(Filter<T>? filter, Include<T>? include = null, Sort<T>? sortBy = null)
public Task<T?> GetOrDefault(Filter<T>? filter,
Include<T>? include = null,
Sort<T>? sortBy = null,
bool reverse = false)
{
return Database.QuerySingle<T>(
Sql,

View File

@ -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
}
/// <inheritdoc />
public Task<MovieWatchStatus?> GetMovieStatus(Expression<Func<Movie, bool>> where, int userId)
public Task<MovieWatchStatus?> 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);
}
/// <inheritdoc />
public async Task<MovieWatchStatus?> SetMovieStatus(
int movieId,
int userId,
Guid movieId,
Guid userId,
WatchStatus status,
int? watchedTime)
{
@ -105,28 +103,24 @@ public class WatchStatusRepository : IWatchStatusRepository
/// <inheritdoc />
public async Task DeleteMovieStatus(
Expression<Func<Movie, bool>> 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();
}
/// <inheritdoc />
public Task<ShowWatchStatus?> GetShowStatus(Expression<Func<Show, bool>> where, int userId)
public Task<ShowWatchStatus?> 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);
}
/// <inheritdoc />
public async Task<ShowWatchStatus?> 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<Episode>.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
/// <inheritdoc />
public async Task DeleteShowStatus(
Expression<Func<Show, bool>> 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();
}
/// <inheritdoc />
public Task<EpisodeWatchStatus?> GetEpisodeStatus(Expression<Func<Episode, bool>> where, int userId)
public Task<EpisodeWatchStatus?> 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);
}
/// <inheritdoc />
public async Task<EpisodeWatchStatus?> SetEpisodeStatus(
int episodeId,
int userId,
Guid episodeId,
Guid userId,
WatchStatus status,
int? watchedTime)
{
@ -224,12 +215,11 @@ public class WatchStatusRepository : IWatchStatusRepository
/// <inheritdoc />
public async Task DeleteEpisodeStatus(
Expression<Func<Episode, bool>> 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();
}
}

View File

@ -16,6 +16,7 @@
// You should have received a copy of the GNU General Public License
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
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<EpisodeWatchStatus?> GetWatchStatus(Identifier identifier)
{
return await _libraryManager.WatchStatus.GetEpisodeStatus(
identifier.IsSame<Episode>(),
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);
}
/// <summary>
@ -156,7 +158,7 @@ namespace Kyoo.Core.Api
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<EpisodeWatchStatus?> 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<Episode>(),
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);
}
}
}

View File

@ -16,6 +16,7 @@
// You should have received a copy of the GNU General Public License
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
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<MovieWatchStatus?> GetWatchStatus(Identifier identifier)
{
return await _libraryManager.WatchStatus.GetMovieStatus(
identifier.IsSame<Movie>(),
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);
}
/// <summary>
@ -198,7 +200,7 @@ namespace Kyoo.Core.Api
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<MovieWatchStatus?> 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<Movie>(),
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);
}
}
}

View File

@ -16,6 +16,7 @@
// You should have received a copy of the GNU General Public License
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
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<ShowWatchStatus?> GetWatchStatus(Identifier identifier)
{
return await _libraryManager.WatchStatus.GetShowStatus(
identifier.IsSame<Show>(),
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);
}
/// <summary>
@ -273,7 +275,7 @@ namespace Kyoo.Core.Api
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<ShowWatchStatus?> 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<Show>(),
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);
}
}
}