mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-24 02:02:36 -04:00
Start watchlist implementations
This commit is contained in:
parent
c1ba51b903
commit
4135fc5703
@ -39,5 +39,18 @@ namespace Kyoo.Authentication
|
||||
return user.Claims.FirstOrDefault(x => x.Type == Claims.Permissions)?.Value.Split(',')
|
||||
?? Array.Empty<string>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the id of the current user or null if unlogged or invalid.
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <returns>The id of the user or null.</returns>
|
||||
public static Guid? GetId(this ClaimsPrincipal user)
|
||||
{
|
||||
Claim? value = user.FindFirst(Claims.Id);
|
||||
if (Guid.TryParse(value?.Value, out Guid id))
|
||||
return id;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -19,6 +19,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using EntityFrameworkCore.Projectables;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
using Kyoo.Abstractions.Models.Attributes;
|
||||
using Kyoo.Utils;
|
||||
@ -144,6 +146,17 @@ namespace Kyoo.Abstractions.Models
|
||||
Hls = $"/video/movie/{Slug}/master.m3u8",
|
||||
};
|
||||
|
||||
[SerializeIgnore] public ICollection<WatchInfo> Watched { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Metadata of what an user as started/planned to watch.
|
||||
/// </summary>
|
||||
[Projectable(UseMemberBody = nameof(_WatchInfo), OnlyOnInclude = true)]
|
||||
[LoadableRelation] public WatchInfo? WatchInfo { get; set; }
|
||||
|
||||
// There is a global query filter to filter by user so we just need to do single.
|
||||
private WatchInfo? _WatchInfo => Watched.FirstOrDefault();
|
||||
|
||||
/// <inheritdoc />
|
||||
public void OnMerge(object merged)
|
||||
{
|
||||
|
@ -69,6 +69,12 @@ namespace Kyoo.Abstractions.Models
|
||||
/// </summary>
|
||||
public Image? Logo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The user's watch list.
|
||||
/// </summary>
|
||||
[SerializeIgnore]
|
||||
public ICollection<WatchInfo>? Watchlist { get; set; }
|
||||
|
||||
public User() { }
|
||||
|
||||
[JsonConstructor]
|
||||
|
101
back/src/Kyoo.Abstractions/Models/Resources/WatchInfo.cs
Normal file
101
back/src/Kyoo.Abstractions/Models/Resources/WatchInfo.cs
Normal file
@ -0,0 +1,101 @@
|
||||
// Kyoo - A portable and vast media library solution.
|
||||
// Copyright (c) Kyoo.
|
||||
//
|
||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||
//
|
||||
// Kyoo is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// Kyoo is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// 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 Kyoo.Abstractions.Models.Attributes;
|
||||
|
||||
namespace Kyoo.Abstractions.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Has the user started watching, is it planned?
|
||||
/// </summary>
|
||||
public enum WatchStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// The user has already watched this.
|
||||
/// </summary>
|
||||
Completed,
|
||||
|
||||
/// <summary>
|
||||
/// The user started watching this but has not finished.
|
||||
/// </summary>
|
||||
Watching,
|
||||
|
||||
/// <summary>
|
||||
/// The user does not plan to continue watching.
|
||||
/// </summary>
|
||||
Droped,
|
||||
|
||||
/// <summary>
|
||||
/// The user has not started watching this but plans to.
|
||||
/// </summary>
|
||||
Planned,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Metadata of what an user as started/planned to watch.
|
||||
/// </summary>
|
||||
public class WatchInfo : IAddedDate
|
||||
{
|
||||
/// <summary>
|
||||
/// The ID of the user that started watching this episode.
|
||||
/// </summary>
|
||||
[SerializeIgnore] public Guid UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The user that started watching this episode.
|
||||
/// </summary>
|
||||
[SerializeIgnore] public User User { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The ID of the episode started.
|
||||
/// </summary>
|
||||
[SerializeIgnore] public Guid? EpisodeId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="Episode"/> started.
|
||||
/// </summary>
|
||||
[SerializeIgnore] public Episode? Episode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The ID of the movie started.
|
||||
/// </summary>
|
||||
[SerializeIgnore] public Guid? MovieId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="Movie"/> started.
|
||||
/// </summary>
|
||||
[SerializeIgnore] public Movie? Movie { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
[SerializeIgnore] public DateTime AddedDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Has the user started watching, is it planned?
|
||||
/// </summary>
|
||||
public WatchStatus Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Where the player has stopped watching the episode (in seconds).
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Null if the status is not Watching.
|
||||
/// </remarks>
|
||||
public int? WatchedTime { get; set; }
|
||||
}
|
||||
}
|
@ -27,6 +27,8 @@ using System.Threading.Tasks;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
using Kyoo.Abstractions.Models;
|
||||
using Kyoo.Abstractions.Models.Exceptions;
|
||||
using Kyoo.Authentication;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.ChangeTracking;
|
||||
using Microsoft.EntityFrameworkCore.ValueGeneration;
|
||||
@ -42,6 +44,8 @@ namespace Kyoo.Postgresql
|
||||
/// </remarks>
|
||||
public abstract class DatabaseContext : DbContext
|
||||
{
|
||||
private readonly IHttpContextAccessor _accessor;
|
||||
|
||||
/// <summary>
|
||||
/// Calculate the MD5 of a string, can only be used in database context.
|
||||
/// </summary>
|
||||
@ -49,6 +53,8 @@ namespace Kyoo.Postgresql
|
||||
/// <returns>The hash</returns>
|
||||
public static string MD5(string str) => throw new NotSupportedException();
|
||||
|
||||
public Guid? CurrentUserId => _accessor.HttpContext?.User.GetId();
|
||||
|
||||
/// <summary>
|
||||
/// All collections of Kyoo. See <see cref="Collection"/>.
|
||||
/// </summary>
|
||||
@ -94,6 +100,8 @@ namespace Kyoo.Postgresql
|
||||
// /// </summary>
|
||||
// public DbSet<PeopleRole> PeopleRoles { get; set; }
|
||||
|
||||
public DbSet<WatchInfo> WatchInfo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Add a many to many link between two resources.
|
||||
/// </summary>
|
||||
@ -114,18 +122,16 @@ namespace Kyoo.Postgresql
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The default constructor
|
||||
/// </summary>
|
||||
protected DatabaseContext() { }
|
||||
protected DatabaseContext(IHttpContextAccessor accessor)
|
||||
{
|
||||
_accessor = accessor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new <see cref="DatabaseContext"/> using specific options
|
||||
/// </summary>
|
||||
/// <param name="options">The options to use.</param>
|
||||
protected DatabaseContext(DbContextOptions options)
|
||||
protected DatabaseContext(DbContextOptions options, IHttpContextAccessor accessor)
|
||||
: base(options)
|
||||
{ }
|
||||
{
|
||||
_accessor = accessor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the name of the link table of the two given types.
|
||||
@ -296,6 +302,11 @@ namespace Kyoo.Postgresql
|
||||
|
||||
modelBuilder.Entity<User>().OwnsOne(x => x.Logo);
|
||||
|
||||
modelBuilder.Entity<WatchInfo>()
|
||||
.HasKey(x => new { User = x.UserId, Episode = x.EpisodeId, Movie = x.MovieId });
|
||||
modelBuilder.Entity<WatchInfo>().HasQueryFilter(x => x.UserId == CurrentUserId);
|
||||
modelBuilder.Entity<Movie>().Ignore(x => x.WatchInfo);
|
||||
|
||||
modelBuilder.Entity<Collection>()
|
||||
.HasIndex(x => x.Slug)
|
||||
.IsUnique();
|
||||
|
@ -20,6 +20,8 @@ using System;
|
||||
using System.Globalization;
|
||||
using EFCore.NamingConventions.Internal;
|
||||
using Kyoo.Abstractions.Models;
|
||||
using Kyoo.Utils;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Query.SqlExpressions;
|
||||
using Npgsql;
|
||||
@ -47,29 +49,24 @@ namespace Kyoo.Postgresql
|
||||
{
|
||||
NpgsqlConnection.GlobalTypeMapper.MapEnum<Status>();
|
||||
NpgsqlConnection.GlobalTypeMapper.MapEnum<Genre>();
|
||||
NpgsqlConnection.GlobalTypeMapper.MapEnum<WatchStatus>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A basic constructor that set default values (query tracker behaviors, mapping enums...)
|
||||
/// Design time constructor (dotnet ef migrations add). Do not use
|
||||
/// </summary>
|
||||
public PostgresContext() { }
|
||||
public PostgresContext()
|
||||
: base(null!)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Create a new <see cref="PostgresContext"/> using specific options
|
||||
/// </summary>
|
||||
/// <param name="options">The options to use.</param>
|
||||
public PostgresContext(DbContextOptions options)
|
||||
: base(options)
|
||||
public PostgresContext(DbContextOptions options, IHttpContextAccessor accessor)
|
||||
: base(options, accessor)
|
||||
{
|
||||
_skipConfigure = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A basic constructor that set default values (query tracker behaviors, mapping enums...)
|
||||
/// </summary>
|
||||
/// <param name="connection">The connection string to use</param>
|
||||
/// <param name="debugMode">Is this instance in debug mode?</param>
|
||||
public PostgresContext(string connection, bool debugMode)
|
||||
public PostgresContext(string connection, bool debugMode, IHttpContextAccessor accessor)
|
||||
: base(accessor)
|
||||
{
|
||||
_debugMode = debugMode;
|
||||
}
|
||||
@ -99,6 +96,7 @@ namespace Kyoo.Postgresql
|
||||
{
|
||||
modelBuilder.HasPostgresEnum<Status>();
|
||||
modelBuilder.HasPostgresEnum<Genre>();
|
||||
modelBuilder.HasPostgresEnum<WatchStatus>();
|
||||
|
||||
modelBuilder.HasDbFunction(typeof(DatabaseContext).GetMethod(nameof(MD5))!)
|
||||
.HasTranslation(args =>
|
||||
|
Loading…
x
Reference in New Issue
Block a user