mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-31 20:24:27 -04:00
Tranform completed shows in watching state when a new item is added
This commit is contained in:
parent
1178e8fd6c
commit
38cb4c4f28
@ -29,6 +29,7 @@ using Kyoo.Abstractions.Models.Exceptions;
|
|||||||
using Kyoo.Abstractions.Models.Utils;
|
using Kyoo.Abstractions.Models.Utils;
|
||||||
using Kyoo.Postgresql;
|
using Kyoo.Postgresql;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
namespace Kyoo.Core.Controllers;
|
namespace Kyoo.Core.Controllers;
|
||||||
|
|
||||||
@ -52,21 +53,36 @@ public class WatchStatusRepository : IWatchStatusRepository
|
|||||||
// The second one can be converted to sql wherase the first can't (tries to compare WatchStatus with int).
|
// The second one can be converted to sql wherase the first can't (tries to compare WatchStatus with int).
|
||||||
private WatchStatus Watching = WatchStatus.Watching;
|
private WatchStatus Watching = WatchStatus.Watching;
|
||||||
private WatchStatus Completed = WatchStatus.Completed;
|
private WatchStatus Completed = WatchStatus.Completed;
|
||||||
|
private WatchStatus Planned = WatchStatus.Planned;
|
||||||
|
|
||||||
private readonly DatabaseContext _database;
|
private readonly DatabaseContext _database;
|
||||||
private readonly IRepository<Episode> _episodes;
|
|
||||||
private readonly IRepository<Movie> _movies;
|
private readonly IRepository<Movie> _movies;
|
||||||
private readonly DbConnection _db;
|
private readonly DbConnection _db;
|
||||||
private readonly SqlVariableContext _context;
|
private readonly SqlVariableContext _context;
|
||||||
|
|
||||||
|
static WatchStatusRepository()
|
||||||
|
{
|
||||||
|
IRepository<Episode>.OnCreated += async (ep) =>
|
||||||
|
{
|
||||||
|
await using AsyncServiceScope scope = CoreModule.Services.CreateAsyncScope();
|
||||||
|
DatabaseContext db = scope.ServiceProvider.GetRequiredService<DatabaseContext>();
|
||||||
|
WatchStatusRepository repo = scope.ServiceProvider.GetRequiredService<WatchStatusRepository>();
|
||||||
|
List<Guid> users = await db.ShowWatchStatus
|
||||||
|
.IgnoreQueryFilters()
|
||||||
|
.Where(x => x.ShowId == ep.ShowId && x.Status == WatchStatus.Completed)
|
||||||
|
.Select(x => x.UserId)
|
||||||
|
.ToListAsync();
|
||||||
|
foreach (Guid userId in users)
|
||||||
|
await repo._SetShowStatus(ep.ShowId, userId, WatchStatus.Watching, true);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
public WatchStatusRepository(DatabaseContext database,
|
public WatchStatusRepository(DatabaseContext database,
|
||||||
IRepository<Episode> episodes,
|
|
||||||
IRepository<Movie> movies,
|
IRepository<Movie> movies,
|
||||||
DbConnection db,
|
DbConnection db,
|
||||||
SqlVariableContext context)
|
SqlVariableContext context)
|
||||||
{
|
{
|
||||||
_database = database;
|
_database = database;
|
||||||
_episodes = episodes;
|
|
||||||
_movies = movies;
|
_movies = movies;
|
||||||
_db = db;
|
_db = db;
|
||||||
_context = context;
|
_context = context;
|
||||||
@ -260,39 +276,70 @@ public class WatchStatusRepository : IWatchStatusRepository
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public async Task<ShowWatchStatus?> SetShowStatus(
|
public Task<ShowWatchStatus?> SetShowStatus(
|
||||||
Guid showId,
|
Guid showId,
|
||||||
Guid userId,
|
Guid userId,
|
||||||
WatchStatus status)
|
WatchStatus status
|
||||||
|
) => _SetShowStatus(showId, userId, status);
|
||||||
|
|
||||||
|
private async Task<ShowWatchStatus?> _SetShowStatus(
|
||||||
|
Guid showId,
|
||||||
|
Guid userId,
|
||||||
|
WatchStatus status,
|
||||||
|
bool newEpisode = false)
|
||||||
{
|
{
|
||||||
int unseenEpisodeCount = await _database.Episodes
|
int unseenEpisodeCount = status != WatchStatus.Completed
|
||||||
.Where(x => x.ShowId == showId)
|
? await _database.Episodes
|
||||||
.Where(x => x.WatchStatus!.Status != WatchStatus.Completed)
|
.Where(x => x.ShowId == showId)
|
||||||
.CountAsync();
|
.Where(x => x.Watched!.First(x => x.UserId == userId)!.Status != WatchStatus.Completed)
|
||||||
|
.CountAsync()
|
||||||
|
: 0;
|
||||||
if (unseenEpisodeCount == 0)
|
if (unseenEpisodeCount == 0)
|
||||||
status = WatchStatus.Completed;
|
status = WatchStatus.Completed;
|
||||||
|
|
||||||
Episode? cursor = null;
|
EpisodeWatchStatus? cursorWatchStatus = null;
|
||||||
Guid? nextEpisodeId = null;
|
Guid? nextEpisodeId = null;
|
||||||
if (status == WatchStatus.Watching)
|
if (status == WatchStatus.Watching)
|
||||||
{
|
{
|
||||||
cursor = await _episodes.GetOrDefault(
|
var cursor = await _database.Episodes
|
||||||
new Filter<Episode>.Lambda(
|
.IgnoreQueryFilters()
|
||||||
x => x.ShowId == showId
|
.Where(x => x.ShowId == showId)
|
||||||
&& (x.WatchStatus!.Status == WatchStatus.Completed
|
.OrderByDescending(x => x.AbsoluteNumber)
|
||||||
|| x.WatchStatus.Status == WatchStatus.Watching)
|
.OrderByDescending(x => x.SeasonNumber)
|
||||||
),
|
.OrderByDescending(x => x.EpisodeNumber)
|
||||||
new Include<Episode>(nameof(Episode.WatchStatus)),
|
.Select(x => new { x.Id, Status = x.Watched!.First(x => x.UserId == userId) })
|
||||||
reverse: true
|
.FirstOrDefaultAsync(x => x.Status.Status == WatchStatus.Completed || x.Status.Status == WatchStatus.Watching);
|
||||||
);
|
cursorWatchStatus = cursor?.Status;
|
||||||
nextEpisodeId = cursor?.WatchStatus?.Status == WatchStatus.Watching
|
nextEpisodeId = cursor?.Status.Status == WatchStatus.Watching
|
||||||
? cursor.Id
|
? cursor.Id
|
||||||
: ((await _episodes.GetOrDefault(
|
: await _database.Episodes
|
||||||
new Filter<Episode>.Lambda(
|
.IgnoreQueryFilters()
|
||||||
x => x.ShowId == showId && x.WatchStatus!.Status != WatchStatus.Completed
|
.Where(x => x.ShowId == showId)
|
||||||
),
|
.OrderByDescending(x => x.AbsoluteNumber)
|
||||||
afterId: cursor?.Id
|
.OrderByDescending(x => x.SeasonNumber)
|
||||||
))?.Id);
|
.OrderByDescending(x => x.EpisodeNumber)
|
||||||
|
.Select(x => new { x.Id, Status = x.Watched!.FirstOrDefault(x => x.UserId == userId) })
|
||||||
|
.Where(x => x.Status == null || x.Status.Status != WatchStatus.Completed)
|
||||||
|
.Select(x => x.Id)
|
||||||
|
.FirstOrDefaultAsync();
|
||||||
|
}
|
||||||
|
else if (status == WatchStatus.Completed)
|
||||||
|
{
|
||||||
|
List<Guid> episodes = await _database.Episodes
|
||||||
|
.Where(x => x.ShowId == showId)
|
||||||
|
.Select(x => x.Id)
|
||||||
|
.ToListAsync();
|
||||||
|
await _database.EpisodeWatchStatus
|
||||||
|
.UpsertRange(episodes.Select(episodeId => new EpisodeWatchStatus
|
||||||
|
{
|
||||||
|
UserId = userId,
|
||||||
|
EpisodeId = episodeId,
|
||||||
|
Status = WatchStatus.Completed,
|
||||||
|
AddedDate = DateTime.UtcNow,
|
||||||
|
PlayedDate = DateTime.UtcNow
|
||||||
|
}))
|
||||||
|
.UpdateIf(x => x.Status == Watching || x.Status == Planned)
|
||||||
|
.RunAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
ShowWatchStatus ret = new()
|
ShowWatchStatus ret = new()
|
||||||
@ -302,17 +349,17 @@ public class WatchStatusRepository : IWatchStatusRepository
|
|||||||
Status = status,
|
Status = status,
|
||||||
AddedDate = DateTime.UtcNow,
|
AddedDate = DateTime.UtcNow,
|
||||||
NextEpisodeId = nextEpisodeId,
|
NextEpisodeId = nextEpisodeId,
|
||||||
WatchedTime = cursor?.WatchStatus?.Status == WatchStatus.Watching
|
WatchedTime = cursorWatchStatus?.Status == WatchStatus.Watching
|
||||||
? cursor.WatchStatus.WatchedTime
|
? cursorWatchStatus.WatchedTime
|
||||||
: null,
|
: null,
|
||||||
WatchedPercent = cursor?.WatchStatus?.Status == WatchStatus.Watching
|
WatchedPercent = cursorWatchStatus?.Status == WatchStatus.Watching
|
||||||
? cursor.WatchStatus.WatchedPercent
|
? cursorWatchStatus.WatchedPercent
|
||||||
: null,
|
: null,
|
||||||
UnseenEpisodesCount = unseenEpisodeCount,
|
UnseenEpisodesCount = unseenEpisodeCount,
|
||||||
PlayedDate = status == WatchStatus.Completed ? DateTime.UtcNow : null,
|
PlayedDate = status == WatchStatus.Completed ? DateTime.UtcNow : null,
|
||||||
};
|
};
|
||||||
await _database.ShowWatchStatus.Upsert(ret)
|
await _database.ShowWatchStatus.Upsert(ret)
|
||||||
.UpdateIf(x => status != Watching || x.Status != Completed)
|
.UpdateIf(x => status != Watching || x.Status != Completed || newEpisode)
|
||||||
.RunAsync();
|
.RunAsync();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -344,7 +391,7 @@ public class WatchStatusRepository : IWatchStatusRepository
|
|||||||
WatchStatus status,
|
WatchStatus status,
|
||||||
int? watchedTime)
|
int? watchedTime)
|
||||||
{
|
{
|
||||||
Episode episode = await _episodes.Get(episodeId);
|
Episode episode = await _database.Episodes.FirstAsync(x => x.Id == episodeId);
|
||||||
int? percent = watchedTime != null && episode.Runtime > 0
|
int? percent = watchedTime != null && episode.Runtime > 0
|
||||||
? (int)Math.Round(watchedTime.Value / (episode.Runtime * 60f) * 100f)
|
? (int)Math.Round(watchedTime.Value / (episode.Runtime * 60f) * 100f)
|
||||||
: null;
|
: null;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user