Fix watch status message payload

This commit is contained in:
Zoe Roux 2024-03-20 19:34:55 +01:00
parent 6937a982d4
commit 1f3a985d3a
No known key found for this signature in database
5 changed files with 107 additions and 40 deletions

View File

@ -47,8 +47,8 @@ public interface IWatchStatusRepository
int? percent
);
static event ResourceEventHandler<MovieWatchStatus> OnMovieStatusChangedHandler;
protected static Task OnMovieStatusChanged(MovieWatchStatus obj) =>
static event ResourceEventHandler<WatchStatus<Movie>> OnMovieStatusChangedHandler;
protected static Task OnMovieStatusChanged(WatchStatus<Movie> obj) =>
OnMovieStatusChangedHandler?.Invoke(obj) ?? Task.CompletedTask;
Task DeleteMovieStatus(Guid movieId, Guid userId);
@ -57,8 +57,8 @@ public interface IWatchStatusRepository
Task<ShowWatchStatus?> SetShowStatus(Guid showId, Guid userId, WatchStatus status);
static event ResourceEventHandler<ShowWatchStatus> OnShowStatusChangedHandler;
protected static Task OnShowStatusChanged(ShowWatchStatus obj) =>
static event ResourceEventHandler<WatchStatus<Show>> OnShowStatusChangedHandler;
protected static Task OnShowStatusChanged(WatchStatus<Show> obj) =>
OnShowStatusChangedHandler?.Invoke(obj) ?? Task.CompletedTask;
Task DeleteShowStatus(Guid showId, Guid userId);
@ -75,8 +75,8 @@ public interface IWatchStatusRepository
int? percent
);
static event ResourceEventHandler<EpisodeWatchStatus> OnEpisodeStatusChangedHandler;
protected static Task OnEpisodeStatusChanged(EpisodeWatchStatus obj) =>
static event ResourceEventHandler<WatchStatus<Episode>> OnEpisodeStatusChangedHandler;
protected static Task OnEpisodeStatusChanged(WatchStatus<Episode> obj) =>
OnEpisodeStatusChangedHandler?.Invoke(obj) ?? Task.CompletedTask;
Task DeleteEpisodeStatus(Guid episodeId, Guid userId);

View File

@ -53,20 +53,11 @@ public enum WatchStatus
Deleted,
}
public interface IWatchStatus
{
/// <summary>
/// Has the user started watching, is it planned?
/// </summary>
public WatchStatus Status { get; set; }
}
/// <summary>
/// Metadata of what an user as started/planned to watch.
/// </summary>
[SqlFirstColumn(nameof(UserId))]
public class MovieWatchStatus : IAddedDate, IWatchStatus
public class MovieWatchStatus : IAddedDate
{
/// <summary>
/// The ID of the user that started watching this episode.
@ -121,7 +112,7 @@ public class MovieWatchStatus : IAddedDate, IWatchStatus
}
[SqlFirstColumn(nameof(UserId))]
public class EpisodeWatchStatus : IAddedDate, IWatchStatus
public class EpisodeWatchStatus : IAddedDate
{
/// <summary>
/// The ID of the user that started watching this episode.
@ -176,7 +167,7 @@ public class EpisodeWatchStatus : IAddedDate, IWatchStatus
}
[SqlFirstColumn(nameof(UserId))]
public class ShowWatchStatus : IAddedDate, IWatchStatus
public class ShowWatchStatus : IAddedDate
{
/// <summary>
/// The ID of the user that started watching this episode.
@ -244,3 +235,45 @@ public class ShowWatchStatus : IAddedDate, IWatchStatus
/// </remarks>
public int? WatchedPercent { get; set; }
}
public class WatchStatus<T> : IAddedDate
{
/// <summary>
/// Has the user started watching, is it planned?
/// </summary>
public required WatchStatus Status { get; set; }
/// <inheritdoc/>
public DateTime AddedDate { get; set; }
/// <summary>
/// The date at which this item was played.
/// </summary>
public DateTime? PlayedDate { get; set; }
/// <summary>
/// Where the player has stopped watching the episode (in seconds).
/// </summary>
/// <remarks>
/// Null if the status is not Watching or if the next episode is not started.
/// </remarks>
public int? WatchedTime { get; set; }
/// <summary>
/// Where the player has stopped watching the episode (in percentage between 0 and 100).
/// </summary>
/// <remarks>
/// Null if the status is not Watching or if the next episode is not started.
/// </remarks>
public int? WatchedPercent { get; set; }
/// <summary>
/// The user that started watching this episode.
/// </summary>
public required User User { get; set; }
/// <summary>
/// The episode/show/movie whose status changed
/// </summary>
public required T Resource { get; set; }
}

View File

@ -36,6 +36,9 @@ namespace Kyoo.Core.Controllers;
public class WatchStatusRepository(
DatabaseContext database,
IRepository<Movie> movies,
IRepository<Show> shows,
IRepository<Episode> episodes,
IRepository<User> users,
DbConnection db,
SqlVariableContext context
) : IWatchStatusRepository
@ -265,7 +268,18 @@ public class WatchStatusRepository(
.MovieWatchStatus.Upsert(ret)
.UpdateIf(x => status != Watching || x.Status != Completed)
.RunAsync();
await IWatchStatusRepository.OnMovieStatusChanged(ret);
await IWatchStatusRepository.OnMovieStatusChanged(
new()
{
User = await users.Get(ret.UserId),
Resource = await movies.Get(ret.MovieId),
Status = ret.Status,
WatchedTime = ret.WatchedTime,
WatchedPercent = ret.WatchedPercent,
AddedDate = ret.AddedDate,
PlayedDate = ret.PlayedDate,
}
);
return ret;
}
@ -278,8 +292,8 @@ public class WatchStatusRepository(
await IWatchStatusRepository.OnMovieStatusChanged(
new()
{
UserId = userId,
MovieId = movieId,
User = await users.Get(userId),
Resource = await movies.Get(movieId),
AddedDate = DateTime.UtcNow,
Status = WatchStatus.Deleted,
}
@ -413,7 +427,18 @@ public class WatchStatusRepository(
.ShowWatchStatus.Upsert(ret)
.UpdateIf(x => status != Watching || x.Status != Completed || newEpisode)
.RunAsync();
await IWatchStatusRepository.OnShowStatusChanged(ret);
await IWatchStatusRepository.OnShowStatusChanged(
new()
{
User = await users.Get(ret.UserId),
Resource = await shows.Get(ret.ShowId),
Status = ret.Status,
WatchedTime = ret.WatchedTime,
WatchedPercent = ret.WatchedPercent,
AddedDate = ret.AddedDate,
PlayedDate = ret.PlayedDate,
}
);
return ret;
}
@ -430,8 +455,8 @@ public class WatchStatusRepository(
await IWatchStatusRepository.OnShowStatusChanged(
new()
{
UserId = userId,
ShowId = showId,
User = await users.Get(userId),
Resource = await shows.Get(showId),
AddedDate = DateTime.UtcNow,
Status = WatchStatus.Deleted,
}
@ -495,7 +520,18 @@ public class WatchStatusRepository(
.EpisodeWatchStatus.Upsert(ret)
.UpdateIf(x => status != Watching || x.Status != Completed)
.RunAsync();
await IWatchStatusRepository.OnEpisodeStatusChanged(ret);
await IWatchStatusRepository.OnEpisodeStatusChanged(
new()
{
User = await users.Get(ret.UserId),
Resource = await episodes.Get(ret.EpisodeId),
Status = ret.Status,
WatchedTime = ret.WatchedTime,
WatchedPercent = ret.WatchedPercent,
AddedDate = ret.AddedDate,
PlayedDate = ret.PlayedDate,
}
);
await SetShowStatus(episode.ShowId, userId, WatchStatus.Watching);
return ret;
}
@ -509,8 +545,8 @@ public class WatchStatusRepository(
await IWatchStatusRepository.OnEpisodeStatusChanged(
new()
{
UserId = userId,
EpisodeId = episodeId,
User = await users.Get(userId),
Resource = await episodes.Get(episodeId),
AddedDate = DateTime.UtcNow,
Status = WatchStatus.Deleted,
}

View File

@ -21,11 +21,11 @@ using System.Text.Json;
namespace Kyoo.RabbitMq;
public class Message
public class Message<T>
{
public string Action { get; set; }
public string Type { get; set; }
public object Value { get; set; }
public T Value { get; set; }
public string AsRoutingKey()
{

View File

@ -40,14 +40,11 @@ public class RabbitProducer
_ListenResourceEvents<User>("events.resource");
_channel.ExchangeDeclare("events.watched", ExchangeType.Topic);
IWatchStatusRepository.OnMovieStatusChangedHandler += _PublishWatchStatus<MovieWatchStatus>(
"movie"
IWatchStatusRepository.OnMovieStatusChangedHandler += _PublishWatchStatus<Movie>("movie");
IWatchStatusRepository.OnShowStatusChangedHandler += _PublishWatchStatus<Show>("show");
IWatchStatusRepository.OnEpisodeStatusChangedHandler += _PublishWatchStatus<Episode>(
"episode"
);
IWatchStatusRepository.OnShowStatusChangedHandler += _PublishWatchStatus<ShowWatchStatus>(
"show"
);
IWatchStatusRepository.OnEpisodeStatusChangedHandler +=
_PublishWatchStatus<EpisodeWatchStatus>("episode");
}
private void _ListenResourceEvents<T>(string exchange)
@ -69,7 +66,7 @@ public class RabbitProducer
{
return (T resource) =>
{
Message message =
Message<T> message =
new()
{
Action = action,
@ -85,12 +82,13 @@ public class RabbitProducer
};
}
private IWatchStatusRepository.ResourceEventHandler<T> _PublishWatchStatus<T>(string resource)
where T : IWatchStatus
private IWatchStatusRepository.ResourceEventHandler<WatchStatus<T>> _PublishWatchStatus<T>(
string resource
)
{
return (status) =>
{
Message message =
Message<WatchStatus<T>> message =
new()
{
Type = resource,