mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-24 02:02:36 -04:00
Split movies and shows, enable nullable handling (wip)
This commit is contained in:
parent
386c6bf268
commit
19ae15f53f
@ -33,10 +33,11 @@
|
|||||||
<Rule Id="SA1513" Action="None"/> <!-- ClosingBraceMustBeFollowedByBlankLine -->
|
<Rule Id="SA1513" Action="None"/> <!-- ClosingBraceMustBeFollowedByBlankLine -->
|
||||||
</Rules>
|
</Rules>
|
||||||
<Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.CSharp.DocumentationRules">
|
<Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.CSharp.DocumentationRules">
|
||||||
|
<Rule Id="SA1600" Action="None" /> <!-- Elements Shuld be Documented -->
|
||||||
|
<Rule Id="SA1602" Action="None" /> <!-- Enums should be documented -->
|
||||||
<Rule Id="SA1642" Action="None" /> <!-- ConstructorSummaryDocumentationMustBeginWithStandardText -->
|
<Rule Id="SA1642" Action="None" /> <!-- ConstructorSummaryDocumentationMustBeginWithStandardText -->
|
||||||
<Rule Id="SA1643" Action="None" /> <!-- DestructorSummaryDocumentationMustBeginWithStandardText -->
|
<Rule Id="SA1643" Action="None" /> <!-- DestructorSummaryDocumentationMustBeginWithStandardText -->
|
||||||
<Rule Id="SA1623" Action="None" /> <!-- PropertySummaryDocumentationMustMatchAccessors -->
|
<Rule Id="SA1623" Action="None" /> <!-- PropertySummaryDocumentationMustMatchAccessors -->
|
||||||
<Rule Id="SA1629" Action="None" /> <!-- DocumentationTextMustEndWithAPeriod -->
|
<Rule Id="SA1629" Action="None" /> <!-- DocumentationTextMustEndWithAPeriod -->
|
||||||
<Rule Id="SA1600" Action="None" /> <!-- Elements Shuld be Documented -->
|
|
||||||
</Rules>
|
</Rules>
|
||||||
</RuleSet>
|
</RuleSet>
|
||||||
|
@ -20,7 +20,6 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using JetBrains.Annotations;
|
|
||||||
using Kyoo.Abstractions.Models;
|
using Kyoo.Abstractions.Models;
|
||||||
using Kyoo.Abstractions.Models.Exceptions;
|
using Kyoo.Abstractions.Models.Exceptions;
|
||||||
|
|
||||||
@ -40,11 +39,6 @@ namespace Kyoo.Abstractions.Controllers
|
|||||||
IRepository<T> GetRepository<T>()
|
IRepository<T> GetRepository<T>()
|
||||||
where T : class, IResource;
|
where T : class, IResource;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The repository that handle libraries.
|
|
||||||
/// </summary>
|
|
||||||
ILibraryRepository LibraryRepository { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The repository that handle libraries items (a wrapper around shows and collections).
|
/// The repository that handle libraries items (a wrapper around shows and collections).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -55,6 +49,11 @@ namespace Kyoo.Abstractions.Controllers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
ICollectionRepository CollectionRepository { get; }
|
ICollectionRepository CollectionRepository { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The repository that handle shows.
|
||||||
|
/// </summary>
|
||||||
|
IMovieRepository MovieRepository { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The repository that handle shows.
|
/// The repository that handle shows.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -80,11 +79,6 @@ namespace Kyoo.Abstractions.Controllers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
IStudioRepository StudioRepository { get; }
|
IStudioRepository StudioRepository { get; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The repository that handle genres.
|
|
||||||
/// </summary>
|
|
||||||
IGenreRepository GenreRepository { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The repository that handle users.
|
/// The repository that handle users.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -97,7 +91,6 @@ namespace Kyoo.Abstractions.Controllers
|
|||||||
/// <typeparam name="T">The type of the resource</typeparam>
|
/// <typeparam name="T">The type of the resource</typeparam>
|
||||||
/// <exception cref="ItemNotFoundException">If the item is not found</exception>
|
/// <exception cref="ItemNotFoundException">If the item is not found</exception>
|
||||||
/// <returns>The resource found</returns>
|
/// <returns>The resource found</returns>
|
||||||
[ItemNotNull]
|
|
||||||
Task<T> Get<T>(int id)
|
Task<T> Get<T>(int id)
|
||||||
where T : class, IResource;
|
where T : class, IResource;
|
||||||
|
|
||||||
@ -108,7 +101,6 @@ namespace Kyoo.Abstractions.Controllers
|
|||||||
/// <typeparam name="T">The type of the resource</typeparam>
|
/// <typeparam name="T">The type of the resource</typeparam>
|
||||||
/// <exception cref="ItemNotFoundException">If the item is not found</exception>
|
/// <exception cref="ItemNotFoundException">If the item is not found</exception>
|
||||||
/// <returns>The resource found</returns>
|
/// <returns>The resource found</returns>
|
||||||
[ItemNotNull]
|
|
||||||
Task<T> Get<T>(string slug)
|
Task<T> Get<T>(string slug)
|
||||||
where T : class, IResource;
|
where T : class, IResource;
|
||||||
|
|
||||||
@ -119,7 +111,6 @@ namespace Kyoo.Abstractions.Controllers
|
|||||||
/// <typeparam name="T">The type of the resource</typeparam>
|
/// <typeparam name="T">The type of the resource</typeparam>
|
||||||
/// <exception cref="ItemNotFoundException">If the item is not found</exception>
|
/// <exception cref="ItemNotFoundException">If the item is not found</exception>
|
||||||
/// <returns>The first resource found that match the where function</returns>
|
/// <returns>The first resource found that match the where function</returns>
|
||||||
[ItemNotNull]
|
|
||||||
Task<T> Get<T>(Expression<Func<T, bool>> where)
|
Task<T> Get<T>(Expression<Func<T, bool>> where)
|
||||||
where T : class, IResource;
|
where T : class, IResource;
|
||||||
|
|
||||||
@ -130,7 +121,6 @@ namespace Kyoo.Abstractions.Controllers
|
|||||||
/// <param name="seasonNumber">The season's number</param>
|
/// <param name="seasonNumber">The season's number</param>
|
||||||
/// <exception cref="ItemNotFoundException">If the item is not found</exception>
|
/// <exception cref="ItemNotFoundException">If the item is not found</exception>
|
||||||
/// <returns>The season found</returns>
|
/// <returns>The season found</returns>
|
||||||
[ItemNotNull]
|
|
||||||
Task<Season> Get(int showID, int seasonNumber);
|
Task<Season> Get(int showID, int seasonNumber);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -140,7 +130,6 @@ namespace Kyoo.Abstractions.Controllers
|
|||||||
/// <param name="seasonNumber">The season's number</param>
|
/// <param name="seasonNumber">The season's number</param>
|
||||||
/// <exception cref="ItemNotFoundException">If the item is not found</exception>
|
/// <exception cref="ItemNotFoundException">If the item is not found</exception>
|
||||||
/// <returns>The season found</returns>
|
/// <returns>The season found</returns>
|
||||||
[ItemNotNull]
|
|
||||||
Task<Season> Get(string showSlug, int seasonNumber);
|
Task<Season> Get(string showSlug, int seasonNumber);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -151,7 +140,6 @@ namespace Kyoo.Abstractions.Controllers
|
|||||||
/// <param name="episodeNumber">The episode's number</param>
|
/// <param name="episodeNumber">The episode's number</param>
|
||||||
/// <exception cref="ItemNotFoundException">If the item is not found</exception>
|
/// <exception cref="ItemNotFoundException">If the item is not found</exception>
|
||||||
/// <returns>The episode found</returns>
|
/// <returns>The episode found</returns>
|
||||||
[ItemNotNull]
|
|
||||||
Task<Episode> Get(int showID, int seasonNumber, int episodeNumber);
|
Task<Episode> Get(int showID, int seasonNumber, int episodeNumber);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -162,7 +150,6 @@ namespace Kyoo.Abstractions.Controllers
|
|||||||
/// <param name="episodeNumber">The episode's number</param>
|
/// <param name="episodeNumber">The episode's number</param>
|
||||||
/// <exception cref="ItemNotFoundException">If the item is not found</exception>
|
/// <exception cref="ItemNotFoundException">If the item is not found</exception>
|
||||||
/// <returns>The episode found</returns>
|
/// <returns>The episode found</returns>
|
||||||
[ItemNotNull]
|
|
||||||
Task<Episode> Get(string showSlug, int seasonNumber, int episodeNumber);
|
Task<Episode> Get(string showSlug, int seasonNumber, int episodeNumber);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -171,8 +158,7 @@ namespace Kyoo.Abstractions.Controllers
|
|||||||
/// <param name="id">The id of the resource</param>
|
/// <param name="id">The id of the resource</param>
|
||||||
/// <typeparam name="T">The type of the resource</typeparam>
|
/// <typeparam name="T">The type of the resource</typeparam>
|
||||||
/// <returns>The resource found</returns>
|
/// <returns>The resource found</returns>
|
||||||
[ItemCanBeNull]
|
Task<T?> GetOrDefault<T>(int id)
|
||||||
Task<T> GetOrDefault<T>(int id)
|
|
||||||
where T : class, IResource;
|
where T : class, IResource;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -181,8 +167,7 @@ namespace Kyoo.Abstractions.Controllers
|
|||||||
/// <param name="slug">The slug of the resource</param>
|
/// <param name="slug">The slug of the resource</param>
|
||||||
/// <typeparam name="T">The type of the resource</typeparam>
|
/// <typeparam name="T">The type of the resource</typeparam>
|
||||||
/// <returns>The resource found</returns>
|
/// <returns>The resource found</returns>
|
||||||
[ItemCanBeNull]
|
Task<T?> GetOrDefault<T>(string slug)
|
||||||
Task<T> GetOrDefault<T>(string slug)
|
|
||||||
where T : class, IResource;
|
where T : class, IResource;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -192,8 +177,7 @@ namespace Kyoo.Abstractions.Controllers
|
|||||||
/// <param name="sortBy">A custom sort method to handle cases where multiples items match the filters.</param>
|
/// <param name="sortBy">A custom sort method to handle cases where multiples items match the filters.</param>
|
||||||
/// <typeparam name="T">The type of the resource</typeparam>
|
/// <typeparam name="T">The type of the resource</typeparam>
|
||||||
/// <returns>The first resource found that match the where function</returns>
|
/// <returns>The first resource found that match the where function</returns>
|
||||||
[ItemCanBeNull]
|
Task<T?> GetOrDefault<T>(Expression<Func<T, bool>> where, Sort<T>? sortBy = default)
|
||||||
Task<T> GetOrDefault<T>(Expression<Func<T, bool>> where, Sort<T> sortBy = default)
|
|
||||||
where T : class, IResource;
|
where T : class, IResource;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -202,8 +186,7 @@ namespace Kyoo.Abstractions.Controllers
|
|||||||
/// <param name="showID">The id of the show</param>
|
/// <param name="showID">The id of the show</param>
|
||||||
/// <param name="seasonNumber">The season's number</param>
|
/// <param name="seasonNumber">The season's number</param>
|
||||||
/// <returns>The season found</returns>
|
/// <returns>The season found</returns>
|
||||||
[ItemCanBeNull]
|
Task<Season?> GetOrDefault(int showID, int seasonNumber);
|
||||||
Task<Season> GetOrDefault(int showID, int seasonNumber);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get a season from it's show slug and it's seasonNumber or null if it is not found.
|
/// Get a season from it's show slug and it's seasonNumber or null if it is not found.
|
||||||
@ -211,8 +194,7 @@ namespace Kyoo.Abstractions.Controllers
|
|||||||
/// <param name="showSlug">The slug of the show</param>
|
/// <param name="showSlug">The slug of the show</param>
|
||||||
/// <param name="seasonNumber">The season's number</param>
|
/// <param name="seasonNumber">The season's number</param>
|
||||||
/// <returns>The season found</returns>
|
/// <returns>The season found</returns>
|
||||||
[ItemCanBeNull]
|
Task<Season?> GetOrDefault(string showSlug, int seasonNumber);
|
||||||
Task<Season> GetOrDefault(string showSlug, int seasonNumber);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get a episode from it's showID, it's seasonNumber and it's episode number or null if it is not found.
|
/// Get a episode from it's showID, it's seasonNumber and it's episode number or null if it is not found.
|
||||||
@ -221,8 +203,7 @@ namespace Kyoo.Abstractions.Controllers
|
|||||||
/// <param name="seasonNumber">The season's number</param>
|
/// <param name="seasonNumber">The season's number</param>
|
||||||
/// <param name="episodeNumber">The episode's number</param>
|
/// <param name="episodeNumber">The episode's number</param>
|
||||||
/// <returns>The episode found</returns>
|
/// <returns>The episode found</returns>
|
||||||
[ItemCanBeNull]
|
Task<Episode?> GetOrDefault(int showID, int seasonNumber, int episodeNumber);
|
||||||
Task<Episode> GetOrDefault(int showID, int seasonNumber, int episodeNumber);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get a episode from it's show slug, it's seasonNumber and it's episode number or null if it is not found.
|
/// Get a episode from it's show slug, it's seasonNumber and it's episode number or null if it is not found.
|
||||||
@ -231,8 +212,7 @@ namespace Kyoo.Abstractions.Controllers
|
|||||||
/// <param name="seasonNumber">The season's number</param>
|
/// <param name="seasonNumber">The season's number</param>
|
||||||
/// <param name="episodeNumber">The episode's number</param>
|
/// <param name="episodeNumber">The episode's number</param>
|
||||||
/// <returns>The episode found</returns>
|
/// <returns>The episode found</returns>
|
||||||
[ItemCanBeNull]
|
Task<Episode?> GetOrDefault(string showSlug, int seasonNumber, int episodeNumber);
|
||||||
Task<Episode> GetOrDefault(string showSlug, int seasonNumber, int episodeNumber);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Load a related resource
|
/// Load a related resource
|
||||||
@ -248,7 +228,7 @@ namespace Kyoo.Abstractions.Controllers
|
|||||||
/// <seealso cref="Load{T,T2}(T, Expression{Func{T,ICollection{T2}}}, bool)"/>
|
/// <seealso cref="Load{T,T2}(T, Expression{Func{T,ICollection{T2}}}, bool)"/>
|
||||||
/// <seealso cref="Load{T}(T, string, bool)"/>
|
/// <seealso cref="Load{T}(T, string, bool)"/>
|
||||||
/// <seealso cref="Load(IResource, string, bool)"/>
|
/// <seealso cref="Load(IResource, string, bool)"/>
|
||||||
Task<T> Load<T, T2>([NotNull] T obj, Expression<Func<T, T2>> member, bool force = false)
|
Task<T> Load<T, T2>(T obj, Expression<Func<T, T2>> member, bool force = false)
|
||||||
where T : class, IResource
|
where T : class, IResource
|
||||||
where T2 : class, IResource;
|
where T2 : class, IResource;
|
||||||
|
|
||||||
@ -266,7 +246,7 @@ namespace Kyoo.Abstractions.Controllers
|
|||||||
/// <seealso cref="Load{T,T2}(T, Expression{Func{T,T2}}, bool)"/>
|
/// <seealso cref="Load{T,T2}(T, Expression{Func{T,T2}}, bool)"/>
|
||||||
/// <seealso cref="Load{T}(T, string, bool)"/>
|
/// <seealso cref="Load{T}(T, string, bool)"/>
|
||||||
/// <seealso cref="Load(IResource, string, bool)"/>
|
/// <seealso cref="Load(IResource, string, bool)"/>
|
||||||
Task<T> Load<T, T2>([NotNull] T obj, Expression<Func<T, ICollection<T2>>> member, bool force = false)
|
Task<T> Load<T, T2>(T obj, Expression<Func<T, ICollection<T2>>> member, bool force = false)
|
||||||
where T : class, IResource
|
where T : class, IResource
|
||||||
where T2 : class;
|
where T2 : class;
|
||||||
|
|
||||||
@ -283,7 +263,7 @@ namespace Kyoo.Abstractions.Controllers
|
|||||||
/// <seealso cref="Load{T,T2}(T, Expression{Func{T,T2}}, bool)"/>
|
/// <seealso cref="Load{T,T2}(T, Expression{Func{T,T2}}, bool)"/>
|
||||||
/// <seealso cref="Load{T,T2}(T, Expression{Func{T,ICollection{T2}}}, bool)"/>
|
/// <seealso cref="Load{T,T2}(T, Expression{Func{T,ICollection{T2}}}, bool)"/>
|
||||||
/// <seealso cref="Load(IResource, string, bool)"/>
|
/// <seealso cref="Load(IResource, string, bool)"/>
|
||||||
Task<T> Load<T>([NotNull] T obj, string memberName, bool force = false)
|
Task<T> Load<T>(T obj, string memberName, bool force = false)
|
||||||
where T : class, IResource;
|
where T : class, IResource;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -298,35 +278,7 @@ namespace Kyoo.Abstractions.Controllers
|
|||||||
/// <seealso cref="Load{T,T2}(T, Expression{Func{T,ICollection{T2}}}, bool)"/>
|
/// <seealso cref="Load{T,T2}(T, Expression{Func{T,ICollection{T2}}}, bool)"/>
|
||||||
/// <seealso cref="Load{T}(T, string, bool)"/>
|
/// <seealso cref="Load{T}(T, string, bool)"/>
|
||||||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
||||||
Task Load([NotNull] IResource obj, string memberName, bool force = false);
|
Task Load(IResource obj, string memberName, bool force = false);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get items (A wrapper around shows or collections) from a library.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="id">The ID of the library</param>
|
|
||||||
/// <param name="where">A filter function</param>
|
|
||||||
/// <param name="sort">Sort information (sort order and sort by)</param>
|
|
||||||
/// <param name="limit">How many items to return and where to start</param>
|
|
||||||
/// <exception cref="ItemNotFoundException">No library exist with the given ID.</exception>
|
|
||||||
/// <returns>A list of items that match every filters</returns>
|
|
||||||
Task<ICollection<LibraryItem>> GetItemsFromLibrary(int id,
|
|
||||||
Expression<Func<LibraryItem, bool>> where = null,
|
|
||||||
Sort<LibraryItem> sort = default,
|
|
||||||
Pagination limit = default);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get items (A wrapper around shows or collections) from a library.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="slug">The slug of the library</param>
|
|
||||||
/// <param name="where">A filter function</param>
|
|
||||||
/// <param name="sort">Sort information (sort order and sort by)</param>
|
|
||||||
/// <param name="limit">How many items to return and where to start</param>
|
|
||||||
/// <exception cref="ItemNotFoundException">No library exist with the given slug.</exception>
|
|
||||||
/// <returns>A list of items that match every filters</returns>
|
|
||||||
Task<ICollection<LibraryItem>> GetItemsFromLibrary(string slug,
|
|
||||||
Expression<Func<LibraryItem, bool>> where = null,
|
|
||||||
Sort<LibraryItem> sort = default,
|
|
||||||
Pagination limit = default);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get people's roles from a show.
|
/// Get people's roles from a show.
|
||||||
@ -338,9 +290,9 @@ namespace Kyoo.Abstractions.Controllers
|
|||||||
/// <exception cref="ItemNotFoundException">No <see cref="Show"/> exist with the given ID.</exception>
|
/// <exception cref="ItemNotFoundException">No <see cref="Show"/> exist with the given ID.</exception>
|
||||||
/// <returns>A list of items that match every filters</returns>
|
/// <returns>A list of items that match every filters</returns>
|
||||||
Task<ICollection<PeopleRole>> GetPeopleFromShow(int showID,
|
Task<ICollection<PeopleRole>> GetPeopleFromShow(int showID,
|
||||||
Expression<Func<PeopleRole, bool>> where = null,
|
Expression<Func<PeopleRole, bool>>? where = null,
|
||||||
Sort<PeopleRole> sort = default,
|
Sort<PeopleRole>? sort = default,
|
||||||
Pagination limit = default);
|
Pagination? limit = default);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get people's roles from a show.
|
/// Get people's roles from a show.
|
||||||
@ -352,9 +304,9 @@ namespace Kyoo.Abstractions.Controllers
|
|||||||
/// <exception cref="ItemNotFoundException">No <see cref="Show"/> exist with the given slug.</exception>
|
/// <exception cref="ItemNotFoundException">No <see cref="Show"/> exist with the given slug.</exception>
|
||||||
/// <returns>A list of items that match every filters</returns>
|
/// <returns>A list of items that match every filters</returns>
|
||||||
Task<ICollection<PeopleRole>> GetPeopleFromShow(string showSlug,
|
Task<ICollection<PeopleRole>> GetPeopleFromShow(string showSlug,
|
||||||
Expression<Func<PeopleRole, bool>> where = null,
|
Expression<Func<PeopleRole, bool>>? where = null,
|
||||||
Sort<PeopleRole> sort = default,
|
Sort<PeopleRole>? sort = default,
|
||||||
Pagination limit = default);
|
Pagination? limit = default);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get people's roles from a person.
|
/// Get people's roles from a person.
|
||||||
@ -366,9 +318,9 @@ namespace Kyoo.Abstractions.Controllers
|
|||||||
/// <exception cref="ItemNotFoundException">No <see cref="People"/> exist with the given ID.</exception>
|
/// <exception cref="ItemNotFoundException">No <see cref="People"/> exist with the given ID.</exception>
|
||||||
/// <returns>A list of items that match every filters</returns>
|
/// <returns>A list of items that match every filters</returns>
|
||||||
Task<ICollection<PeopleRole>> GetRolesFromPeople(int id,
|
Task<ICollection<PeopleRole>> GetRolesFromPeople(int id,
|
||||||
Expression<Func<PeopleRole, bool>> where = null,
|
Expression<Func<PeopleRole, bool>>? where = null,
|
||||||
Sort<PeopleRole> sort = default,
|
Sort<PeopleRole>? sort = default,
|
||||||
Pagination limit = default);
|
Pagination? limit = default);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get people's roles from a person.
|
/// Get people's roles from a person.
|
||||||
@ -380,27 +332,9 @@ namespace Kyoo.Abstractions.Controllers
|
|||||||
/// <exception cref="ItemNotFoundException">No <see cref="People"/> exist with the given slug.</exception>
|
/// <exception cref="ItemNotFoundException">No <see cref="People"/> exist with the given slug.</exception>
|
||||||
/// <returns>A list of items that match every filters</returns>
|
/// <returns>A list of items that match every filters</returns>
|
||||||
Task<ICollection<PeopleRole>> GetRolesFromPeople(string slug,
|
Task<ICollection<PeopleRole>> GetRolesFromPeople(string slug,
|
||||||
Expression<Func<PeopleRole, bool>> where = null,
|
Expression<Func<PeopleRole, bool>>? where = null,
|
||||||
Sort<PeopleRole> sort = default,
|
Sort<PeopleRole>? sort = default,
|
||||||
Pagination limit = default);
|
Pagination? limit = default);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Setup relations between a show, a library and a collection
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="showID">The show's ID to setup relations with</param>
|
|
||||||
/// <param name="libraryID">The library's ID to setup relations with (optional)</param>
|
|
||||||
/// <param name="collectionID">The collection's ID to setup relations with (optional)</param>
|
|
||||||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
|
||||||
Task AddShowLink(int showID, int? libraryID, int? collectionID);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Setup relations between a show, a library and a collection
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="show">The show to setup relations with</param>
|
|
||||||
/// <param name="library">The library to setup relations with (optional)</param>
|
|
||||||
/// <param name="collection">The collection to setup relations with (optional)</param>
|
|
||||||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
|
||||||
Task AddShowLink([NotNull] Show show, Library library, Collection collection);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get all resources with filters
|
/// Get all resources with filters
|
||||||
@ -410,9 +344,9 @@ namespace Kyoo.Abstractions.Controllers
|
|||||||
/// <param name="limit">How many items to return and where to start</param>
|
/// <param name="limit">How many items to return and where to start</param>
|
||||||
/// <typeparam name="T">The type of resources to load</typeparam>
|
/// <typeparam name="T">The type of resources to load</typeparam>
|
||||||
/// <returns>A list of resources that match every filters</returns>
|
/// <returns>A list of resources that match every filters</returns>
|
||||||
Task<ICollection<T>> GetAll<T>(Expression<Func<T, bool>> where = null,
|
Task<ICollection<T>> GetAll<T>(Expression<Func<T, bool>>? where = null,
|
||||||
Sort<T> sort = default,
|
Sort<T>? sort = default,
|
||||||
Pagination limit = default)
|
Pagination? limit = default)
|
||||||
where T : class, IResource;
|
where T : class, IResource;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -421,7 +355,7 @@ namespace Kyoo.Abstractions.Controllers
|
|||||||
/// <param name="where">A filter function</param>
|
/// <param name="where">A filter function</param>
|
||||||
/// <typeparam name="T">The type of resources to load</typeparam>
|
/// <typeparam name="T">The type of resources to load</typeparam>
|
||||||
/// <returns>A list of resources that match every filters</returns>
|
/// <returns>A list of resources that match every filters</returns>
|
||||||
Task<int> GetCount<T>(Expression<Func<T, bool>> where = null)
|
Task<int> GetCount<T>(Expression<Func<T, bool>>? where = null)
|
||||||
where T : class, IResource;
|
where T : class, IResource;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -439,7 +373,7 @@ namespace Kyoo.Abstractions.Controllers
|
|||||||
/// <param name="item">The item to register</param>
|
/// <param name="item">The item to register</param>
|
||||||
/// <typeparam name="T">The type of resource</typeparam>
|
/// <typeparam name="T">The type of resource</typeparam>
|
||||||
/// <returns>The resource registers and completed by database's information (related items and so on)</returns>
|
/// <returns>The resource registers and completed by database's information (related items and so on)</returns>
|
||||||
Task<T> Create<T>([NotNull] T item)
|
Task<T> Create<T>(T item)
|
||||||
where T : class, IResource;
|
where T : class, IResource;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -448,7 +382,7 @@ namespace Kyoo.Abstractions.Controllers
|
|||||||
/// <param name="item">The item to register</param>
|
/// <param name="item">The item to register</param>
|
||||||
/// <typeparam name="T">The type of resource</typeparam>
|
/// <typeparam name="T">The type of resource</typeparam>
|
||||||
/// <returns>The newly created item or the existing value if it existed.</returns>
|
/// <returns>The newly created item or the existing value if it existed.</returns>
|
||||||
Task<T> CreateIfNotExists<T>([NotNull] T item)
|
Task<T> CreateIfNotExists<T>(T item)
|
||||||
where T : class, IResource;
|
where T : class, IResource;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -20,7 +20,6 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using JetBrains.Annotations;
|
|
||||||
using Kyoo.Abstractions.Models;
|
using Kyoo.Abstractions.Models;
|
||||||
using Kyoo.Abstractions.Models.Exceptions;
|
using Kyoo.Abstractions.Models.Exceptions;
|
||||||
|
|
||||||
@ -45,7 +44,6 @@ namespace Kyoo.Abstractions.Controllers
|
|||||||
/// <param name="id">The id of the resource</param>
|
/// <param name="id">The id of the resource</param>
|
||||||
/// <exception cref="ItemNotFoundException">If the item could not be found.</exception>
|
/// <exception cref="ItemNotFoundException">If the item could not be found.</exception>
|
||||||
/// <returns>The resource found</returns>
|
/// <returns>The resource found</returns>
|
||||||
[ItemNotNull]
|
|
||||||
Task<T> Get(int id);
|
Task<T> Get(int id);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -54,7 +52,6 @@ namespace Kyoo.Abstractions.Controllers
|
|||||||
/// <param name="slug">The slug of the resource</param>
|
/// <param name="slug">The slug of the resource</param>
|
||||||
/// <exception cref="ItemNotFoundException">If the item could not be found.</exception>
|
/// <exception cref="ItemNotFoundException">If the item could not be found.</exception>
|
||||||
/// <returns>The resource found</returns>
|
/// <returns>The resource found</returns>
|
||||||
[ItemNotNull]
|
|
||||||
Task<T> Get(string slug);
|
Task<T> Get(string slug);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -63,7 +60,6 @@ namespace Kyoo.Abstractions.Controllers
|
|||||||
/// <param name="where">A predicate to filter the resource.</param>
|
/// <param name="where">A predicate to filter the resource.</param>
|
||||||
/// <exception cref="ItemNotFoundException">If the item could not be found.</exception>
|
/// <exception cref="ItemNotFoundException">If the item could not be found.</exception>
|
||||||
/// <returns>The resource found</returns>
|
/// <returns>The resource found</returns>
|
||||||
[ItemNotNull]
|
|
||||||
Task<T> Get(Expression<Func<T, bool>> where);
|
Task<T> Get(Expression<Func<T, bool>> where);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -71,16 +67,14 @@ namespace Kyoo.Abstractions.Controllers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="id">The id of the resource</param>
|
/// <param name="id">The id of the resource</param>
|
||||||
/// <returns>The resource found</returns>
|
/// <returns>The resource found</returns>
|
||||||
[ItemCanBeNull]
|
Task<T?> GetOrDefault(int id);
|
||||||
Task<T> GetOrDefault(int id);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get a resource from it's slug or null if it is not found.
|
/// Get a resource from it's slug or null if it is not found.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="slug">The slug of the resource</param>
|
/// <param name="slug">The slug of the resource</param>
|
||||||
/// <returns>The resource found</returns>
|
/// <returns>The resource found</returns>
|
||||||
[ItemCanBeNull]
|
Task<T?> GetOrDefault(string slug);
|
||||||
Task<T> GetOrDefault(string slug);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get the first resource that match the predicate or null if it is not found.
|
/// Get the first resource that match the predicate or null if it is not found.
|
||||||
@ -88,15 +82,13 @@ namespace Kyoo.Abstractions.Controllers
|
|||||||
/// <param name="where">A predicate to filter the resource.</param>
|
/// <param name="where">A predicate to filter the resource.</param>
|
||||||
/// <param name="sortBy">A custom sort method to handle cases where multiples items match the filters.</param>
|
/// <param name="sortBy">A custom sort method to handle cases where multiples items match the filters.</param>
|
||||||
/// <returns>The resource found</returns>
|
/// <returns>The resource found</returns>
|
||||||
[ItemCanBeNull]
|
Task<T?> GetOrDefault(Expression<Func<T, bool>> where, Sort<T>? sortBy = default);
|
||||||
Task<T> GetOrDefault(Expression<Func<T, bool>> where, Sort<T> sortBy = default);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Search for resources.
|
/// Search for resources.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="query">The query string.</param>
|
/// <param name="query">The query string.</param>
|
||||||
/// <returns>A list of resources found</returns>
|
/// <returns>A list of resources found</returns>
|
||||||
[ItemNotNull]
|
|
||||||
Task<ICollection<T>> Search(string query);
|
Task<ICollection<T>> Search(string query);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -106,33 +98,30 @@ namespace Kyoo.Abstractions.Controllers
|
|||||||
/// <param name="sort">Sort information about the query (sort by, sort order)</param>
|
/// <param name="sort">Sort information about the query (sort by, sort order)</param>
|
||||||
/// <param name="limit">How pagination should be done (where to start and how many to return)</param>
|
/// <param name="limit">How pagination should be done (where to start and how many to return)</param>
|
||||||
/// <returns>A list of resources that match every filters</returns>
|
/// <returns>A list of resources that match every filters</returns>
|
||||||
[ItemNotNull]
|
Task<ICollection<T>> GetAll(Expression<Func<T, bool>>? where = null,
|
||||||
Task<ICollection<T>> GetAll(Expression<Func<T, bool>> where = null,
|
Sort<T>? sort = default,
|
||||||
Sort<T> sort = default,
|
Pagination? limit = default);
|
||||||
Pagination limit = default);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get the number of resources that match the filter's predicate.
|
/// Get the number of resources that match the filter's predicate.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="where">A filter predicate</param>
|
/// <param name="where">A filter predicate</param>
|
||||||
/// <returns>How many resources matched that filter</returns>
|
/// <returns>How many resources matched that filter</returns>
|
||||||
Task<int> GetCount(Expression<Func<T, bool>> where = null);
|
Task<int> GetCount(Expression<Func<T, bool>>? where = null);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a new resource.
|
/// Create a new resource.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="obj">The item to register</param>
|
/// <param name="obj">The item to register</param>
|
||||||
/// <returns>The resource registers and completed by database's information (related items and so on)</returns>
|
/// <returns>The resource registers and completed by database's information (related items and so on)</returns>
|
||||||
[ItemNotNull]
|
Task<T> Create(T obj);
|
||||||
Task<T> Create([NotNull] T obj);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a new resource if it does not exist already. If it does, the existing value is returned instead.
|
/// Create a new resource if it does not exist already. If it does, the existing value is returned instead.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="obj">The object to create</param>
|
/// <param name="obj">The object to create</param>
|
||||||
/// <returns>The newly created item or the existing value if it existed.</returns>
|
/// <returns>The newly created item or the existing value if it existed.</returns>
|
||||||
[ItemNotNull]
|
Task<T> CreateIfNotExists(T obj);
|
||||||
Task<T> CreateIfNotExists([NotNull] T obj);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called when a resource has been created.
|
/// Called when a resource has been created.
|
||||||
@ -146,8 +135,7 @@ namespace Kyoo.Abstractions.Controllers
|
|||||||
/// <param name="resetOld">Should old properties of the resource be discarded or should null values considered as not changed?</param>
|
/// <param name="resetOld">Should old properties of the resource be discarded or should null values considered as not changed?</param>
|
||||||
/// <exception cref="ItemNotFoundException">If the item is not found</exception>
|
/// <exception cref="ItemNotFoundException">If the item is not found</exception>
|
||||||
/// <returns>The resource edited and completed by database's information (related items and so on)</returns>
|
/// <returns>The resource edited and completed by database's information (related items and so on)</returns>
|
||||||
[ItemNotNull]
|
Task<T> Edit(T edited, bool resetOld);
|
||||||
Task<T> Edit([NotNull] T edited, bool resetOld);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called when a resource has been edited.
|
/// Called when a resource has been edited.
|
||||||
@ -176,14 +164,14 @@ namespace Kyoo.Abstractions.Controllers
|
|||||||
/// <param name="obj">The resource to delete</param>
|
/// <param name="obj">The resource to delete</param>
|
||||||
/// <exception cref="ItemNotFoundException">If the item is not found</exception>
|
/// <exception cref="ItemNotFoundException">If the item is not found</exception>
|
||||||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
||||||
Task Delete([NotNull] T obj);
|
Task Delete(T obj);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Delete all resources that match the predicate.
|
/// Delete all resources that match the predicate.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="where">A predicate to filter resources to delete. Every resource that match this will be deleted.</param>
|
/// <param name="where">A predicate to filter resources to delete. Every resource that match this will be deleted.</param>
|
||||||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
||||||
Task DeleteAll([NotNull] Expression<Func<T, bool>> where);
|
Task DeleteAll(Expression<Func<T, bool>> where);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called when a resource has been edited.
|
/// Called when a resource has been edited.
|
||||||
@ -202,21 +190,16 @@ namespace Kyoo.Abstractions.Controllers
|
|||||||
Type RepositoryType { get; }
|
Type RepositoryType { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A repository to handle shows.
|
||||||
|
/// </summary>
|
||||||
|
public interface IMovieRepository : IRepository<Movie> { }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A repository to handle shows.
|
/// A repository to handle shows.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IShowRepository : IRepository<Show>
|
public interface IShowRepository : IRepository<Show>
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Link a show to a collection and/or a library. The given show is now part of those containers.
|
|
||||||
/// If both a library and a collection are given, the collection is added to the library too.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="showID">The ID of the show</param>
|
|
||||||
/// <param name="libraryID">The ID of the library (optional)</param>
|
|
||||||
/// <param name="collectionID">The ID of the collection (optional)</param>
|
|
||||||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
|
||||||
Task AddShowLink(int showID, int? libraryID, int? collectionID);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get a show's slug from it's ID.
|
/// Get a show's slug from it's ID.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -330,55 +313,16 @@ namespace Kyoo.Abstractions.Controllers
|
|||||||
Task<Episode> GetAbsolute(string showSlug, int absoluteNumber);
|
Task<Episode> GetAbsolute(string showSlug, int absoluteNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A repository to handle libraries.
|
|
||||||
/// </summary>
|
|
||||||
public interface ILibraryRepository : IRepository<Library> { }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A repository to handle library items (A wrapper around shows and collections).
|
/// A repository to handle library items (A wrapper around shows and collections).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface ILibraryItemRepository : IRepository<LibraryItem>
|
public interface ILibraryItemRepository : IRepository<ILibraryItem> { }
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Get items (A wrapper around shows or collections) from a library.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="id">The ID of the library</param>
|
|
||||||
/// <param name="where">A filter function</param>
|
|
||||||
/// <param name="sort">Sort information (sort order and sort by)</param>
|
|
||||||
/// <param name="limit">How many items to return and where to start</param>
|
|
||||||
/// <exception cref="ItemNotFoundException">No library exist with the given ID.</exception>
|
|
||||||
/// <returns>A list of items that match every filters</returns>
|
|
||||||
public Task<ICollection<LibraryItem>> GetFromLibrary(int id,
|
|
||||||
Expression<Func<LibraryItem, bool>> where = null,
|
|
||||||
Sort<LibraryItem> sort = default,
|
|
||||||
Pagination limit = default);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get items (A wrapper around shows or collections) from a library.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="slug">The slug of the library</param>
|
|
||||||
/// <param name="where">A filter function</param>
|
|
||||||
/// <param name="sort">Sort information (sort order and sort by)</param>
|
|
||||||
/// <param name="limit">How many items to return and where to start</param>
|
|
||||||
/// <exception cref="ItemNotFoundException">No library exist with the given slug.</exception>
|
|
||||||
/// <returns>A list of items that match every filters</returns>
|
|
||||||
public Task<ICollection<LibraryItem>> GetFromLibrary(string slug,
|
|
||||||
Expression<Func<LibraryItem, bool>> where = null,
|
|
||||||
Sort<LibraryItem> sort = default,
|
|
||||||
Pagination limit = default);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A repository for collections
|
/// A repository for collections
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface ICollectionRepository : IRepository<Collection> { }
|
public interface ICollectionRepository : IRepository<Collection> { }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A repository for genres.
|
|
||||||
/// </summary>
|
|
||||||
public interface IGenreRepository : IRepository<Genre> { }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A repository for studios.
|
/// A repository for studios.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -399,9 +343,9 @@ namespace Kyoo.Abstractions.Controllers
|
|||||||
/// <exception cref="ItemNotFoundException">No <see cref="Show"/> exist with the given ID.</exception>
|
/// <exception cref="ItemNotFoundException">No <see cref="Show"/> exist with the given ID.</exception>
|
||||||
/// <returns>A list of items that match every filters</returns>
|
/// <returns>A list of items that match every filters</returns>
|
||||||
Task<ICollection<PeopleRole>> GetFromShow(int showID,
|
Task<ICollection<PeopleRole>> GetFromShow(int showID,
|
||||||
Expression<Func<PeopleRole, bool>> where = null,
|
Expression<Func<PeopleRole, bool>>? where = null,
|
||||||
Sort<PeopleRole> sort = default,
|
Sort<PeopleRole>? sort = default,
|
||||||
Pagination limit = default);
|
Pagination? limit = default);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get people's roles from a show.
|
/// Get people's roles from a show.
|
||||||
@ -413,9 +357,9 @@ namespace Kyoo.Abstractions.Controllers
|
|||||||
/// <exception cref="ItemNotFoundException">No <see cref="Show"/> exist with the given slug.</exception>
|
/// <exception cref="ItemNotFoundException">No <see cref="Show"/> exist with the given slug.</exception>
|
||||||
/// <returns>A list of items that match every filters</returns>
|
/// <returns>A list of items that match every filters</returns>
|
||||||
Task<ICollection<PeopleRole>> GetFromShow(string showSlug,
|
Task<ICollection<PeopleRole>> GetFromShow(string showSlug,
|
||||||
Expression<Func<PeopleRole, bool>> where = null,
|
Expression<Func<PeopleRole, bool>>? where = null,
|
||||||
Sort<PeopleRole> sort = default,
|
Sort<PeopleRole>? sort = default,
|
||||||
Pagination limit = default);
|
Pagination? limit = default);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get people's roles from a person.
|
/// Get people's roles from a person.
|
||||||
@ -427,9 +371,9 @@ namespace Kyoo.Abstractions.Controllers
|
|||||||
/// <exception cref="ItemNotFoundException">No <see cref="People"/> exist with the given ID.</exception>
|
/// <exception cref="ItemNotFoundException">No <see cref="People"/> exist with the given ID.</exception>
|
||||||
/// <returns>A list of items that match every filters</returns>
|
/// <returns>A list of items that match every filters</returns>
|
||||||
Task<ICollection<PeopleRole>> GetFromPeople(int id,
|
Task<ICollection<PeopleRole>> GetFromPeople(int id,
|
||||||
Expression<Func<PeopleRole, bool>> where = null,
|
Expression<Func<PeopleRole, bool>>? where = null,
|
||||||
Sort<PeopleRole> sort = default,
|
Sort<PeopleRole>? sort = default,
|
||||||
Pagination limit = default);
|
Pagination? limit = default);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get people's roles from a person.
|
/// Get people's roles from a person.
|
||||||
@ -441,9 +385,9 @@ namespace Kyoo.Abstractions.Controllers
|
|||||||
/// <exception cref="ItemNotFoundException">No <see cref="People"/> exist with the given slug.</exception>
|
/// <exception cref="ItemNotFoundException">No <see cref="People"/> exist with the given slug.</exception>
|
||||||
/// <returns>A list of items that match every filters</returns>
|
/// <returns>A list of items that match every filters</returns>
|
||||||
Task<ICollection<PeopleRole>> GetFromPeople(string slug,
|
Task<ICollection<PeopleRole>> GetFromPeople(string slug,
|
||||||
Expression<Func<PeopleRole, bool>> where = null,
|
Expression<Func<PeopleRole, bool>>? where = null,
|
||||||
Sort<PeopleRole> sort = default,
|
Sort<PeopleRole>? sort = default,
|
||||||
Pagination limit = default);
|
Pagination? limit = default);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
<Title>Kyoo.Abstractions</Title>
|
<Title>Kyoo.Abstractions</Title>
|
||||||
<Description>Base package to create plugins for Kyoo.</Description>
|
<Description>Base package to create plugins for Kyoo.</Description>
|
||||||
<RootNamespace>Kyoo.Abstractions</RootNamespace>
|
<RootNamespace>Kyoo.Abstractions</RootNamespace>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -32,7 +32,7 @@ namespace Kyoo.Abstractions.Models.Attributes
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The public name of this api.
|
/// The public name of this api.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[NotNull] public string Name { get; }
|
public string Name { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The name of the group in witch this API is. You can also specify a custom sort order using the following
|
/// The name of the group in witch this API is. You can also specify a custom sort order using the following
|
||||||
@ -45,7 +45,7 @@ namespace Kyoo.Abstractions.Models.Attributes
|
|||||||
/// Create a new <see cref="ApiDefinitionAttribute"/>.
|
/// Create a new <see cref="ApiDefinitionAttribute"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name">The name of the api that will be used on the documentation page.</param>
|
/// <param name="name">The name of the api that will be used on the documentation page.</param>
|
||||||
public ApiDefinitionAttribute([NotNull] string name)
|
public ApiDefinitionAttribute(string name)
|
||||||
{
|
{
|
||||||
if (name == null)
|
if (name == null)
|
||||||
throw new ArgumentNullException(nameof(name));
|
throw new ArgumentNullException(nameof(name));
|
||||||
|
@ -60,7 +60,7 @@ namespace Kyoo.Abstractions.Models
|
|||||||
/// </param>
|
/// </param>
|
||||||
/// <param name="type">The type of the object</param>
|
/// <param name="type">The type of the object</param>
|
||||||
/// <returns>The list of configuration reference a type has.</returns>
|
/// <returns>The list of configuration reference a type has.</returns>
|
||||||
public static IEnumerable<ConfigurationReference> CreateReference(string path, [NotNull] Type type)
|
public static IEnumerable<ConfigurationReference> CreateReference(string path, Type type)
|
||||||
{
|
{
|
||||||
if (type == null)
|
if (type == null)
|
||||||
throw new ArgumentNullException(nameof(type));
|
throw new ArgumentNullException(nameof(type));
|
||||||
|
@ -36,7 +36,7 @@ namespace Kyoo.Abstractions.Models.Exceptions
|
|||||||
/// Create a new <see cref="DuplicatedItemException"/> with the default message.
|
/// Create a new <see cref="DuplicatedItemException"/> with the default message.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="existing">The existing object.</param>
|
/// <param name="existing">The existing object.</param>
|
||||||
public DuplicatedItemException(object existing = null)
|
public DuplicatedItemException(object? existing = null)
|
||||||
: base("Already exists in the database.")
|
: base("Already exists in the database.")
|
||||||
{
|
{
|
||||||
Existing = existing;
|
Existing = existing;
|
||||||
|
@ -19,13 +19,27 @@
|
|||||||
namespace Kyoo.Abstractions.Models
|
namespace Kyoo.Abstractions.Models
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// An interface to represent resources that should have a link field in their return values (like videos).
|
/// A genre that allow one to specify categories for shows.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface ILink
|
public enum Genre
|
||||||
{
|
{
|
||||||
/// <summary>
|
Action,
|
||||||
/// The link to return, in most cases this should be a string.
|
Adventure,
|
||||||
/// </summary>
|
Animation,
|
||||||
public object Link { get; }
|
Comedy,
|
||||||
|
Crime,
|
||||||
|
Documentary,
|
||||||
|
Drama,
|
||||||
|
Family,
|
||||||
|
Fantasy,
|
||||||
|
History,
|
||||||
|
Horror,
|
||||||
|
Music,
|
||||||
|
Mystery,
|
||||||
|
Romance,
|
||||||
|
ScienceFiction,
|
||||||
|
Thriller,
|
||||||
|
War,
|
||||||
|
Western,
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -17,16 +17,13 @@
|
|||||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Linq.Expressions;
|
|
||||||
|
|
||||||
namespace Kyoo.Abstractions.Models
|
namespace Kyoo.Abstractions.Models
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The type of item, ether a show, a movie or a collection.
|
/// The type of item, ether a show, a movie or a collection.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public enum ItemType
|
public enum ItemKind
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The <see cref="LibraryItem"/> is a <see cref="Show"/>.
|
/// The <see cref="LibraryItem"/> is a <see cref="Show"/>.
|
||||||
@ -49,138 +46,67 @@ namespace Kyoo.Abstractions.Models
|
|||||||
/// A type union between <see cref="Show"/> and <see cref="Collection"/>.
|
/// A type union between <see cref="Show"/> and <see cref="Collection"/>.
|
||||||
/// This is used to list content put inside a library.
|
/// This is used to list content put inside a library.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class LibraryItem : CustomTypeDescriptor, IResource, IThumbnails
|
public interface ILibraryItem : IResource
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <summary>
|
||||||
|
/// Is the item a collection, a movie or a show?
|
||||||
|
/// </summary>
|
||||||
|
public ItemKind Kind { get; }
|
||||||
|
|
||||||
|
public string Name { get; }
|
||||||
|
|
||||||
|
public DateTime? AirDate { get; }
|
||||||
|
|
||||||
|
public Image Poster { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class BagItem : ILibraryItem
|
||||||
|
{
|
||||||
|
public ItemKind Kind { get; }
|
||||||
|
|
||||||
public int ID { get; set; }
|
public int ID { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public string Slug { get; set; }
|
public string Slug { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
public string Name { get; set; }
|
||||||
/// The title of the show or collection.
|
|
||||||
/// </summary>
|
|
||||||
public string Title { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
public DateTime? AirDate { get; set; }
|
||||||
/// The summary of the show or collection.
|
|
||||||
/// </summary>
|
|
||||||
public string Overview { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Is this show airing, not aired yet or finished? This is only applicable for shows.
|
|
||||||
/// </summary>
|
|
||||||
public Status? Status { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The date this show or collection started airing. It can be null if this is unknown.
|
|
||||||
/// </summary>
|
|
||||||
public DateTime? StartAir { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The date this show or collection finished airing.
|
|
||||||
/// It must be after the <see cref="StartAir"/> but can be the same (example: for movies).
|
|
||||||
/// It can also be null if this is unknown.
|
|
||||||
/// </summary>
|
|
||||||
public DateTime? EndAir { get; set; }
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public Image Poster { get; set; }
|
public Image Poster { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
public object Rest { get; set; }
|
||||||
public Image Thumbnail { get; set; }
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
public ILibraryItem ToItem()
|
||||||
public Image Logo { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The type of this item (ether a collection, a show or a movie).
|
|
||||||
/// </summary>
|
|
||||||
public ItemType Type { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create a new, empty <see cref="LibraryItem"/>.
|
|
||||||
/// </summary>
|
|
||||||
public LibraryItem() { }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create a <see cref="LibraryItem"/> from a show.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="show">The show that this library item should represent.</param>
|
|
||||||
public LibraryItem(Show show)
|
|
||||||
{
|
{
|
||||||
ID = show.ID;
|
return Kind switch
|
||||||
Slug = show.Slug;
|
|
||||||
Title = show.Title;
|
|
||||||
Overview = show.Overview;
|
|
||||||
Status = show.Status;
|
|
||||||
StartAir = show.StartAir;
|
|
||||||
EndAir = show.EndAir;
|
|
||||||
Poster = show.Poster;
|
|
||||||
Thumbnail = show.Thumbnail;
|
|
||||||
Logo = show.Logo;
|
|
||||||
Type = show.IsMovie ? ItemType.Movie : ItemType.Show;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create a <see cref="LibraryItem"/> from a collection
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="collection">The collection that this library item should represent.</param>
|
|
||||||
public LibraryItem(Collection collection)
|
|
||||||
{
|
{
|
||||||
ID = -collection.ID;
|
ItemKind.Movie => Rest as MovieItem,
|
||||||
Slug = collection.Slug;
|
ItemKind.Show => Rest as ShowItem,
|
||||||
Title = collection.Name;
|
ItemKind.Collection => Rest as CollectionItem,
|
||||||
Overview = collection.Overview;
|
|
||||||
Status = Models.Status.Unknown;
|
|
||||||
StartAir = null;
|
|
||||||
EndAir = null;
|
|
||||||
Poster = collection.Poster;
|
|
||||||
Thumbnail = collection.Thumbnail;
|
|
||||||
Logo = collection.Logo;
|
|
||||||
Type = ItemType.Collection;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// An expression to create a <see cref="LibraryItem"/> representing a show.
|
|
||||||
/// </summary>
|
|
||||||
public static Expression<Func<Show, LibraryItem>> FromShow => x => new LibraryItem
|
|
||||||
{
|
|
||||||
ID = x.ID,
|
|
||||||
Slug = x.Slug,
|
|
||||||
Title = x.Title,
|
|
||||||
Overview = x.Overview,
|
|
||||||
Status = x.Status,
|
|
||||||
StartAir = x.StartAir,
|
|
||||||
EndAir = x.EndAir,
|
|
||||||
Poster = x.Poster,
|
|
||||||
Thumbnail = x.Thumbnail,
|
|
||||||
Logo = x.Logo,
|
|
||||||
Type = x.IsMovie ? ItemType.Movie : ItemType.Show
|
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
public sealed class ShowItem : Show, ILibraryItem
|
||||||
/// An expression to create a <see cref="LibraryItem"/> representing a collection.
|
|
||||||
/// </summary>
|
|
||||||
public static Expression<Func<Collection, LibraryItem>> FromCollection => x => new LibraryItem
|
|
||||||
{
|
{
|
||||||
ID = -x.ID,
|
|
||||||
Slug = x.Slug,
|
|
||||||
Title = x.Name,
|
|
||||||
Overview = x.Overview,
|
|
||||||
Status = Models.Status.Unknown,
|
|
||||||
StartAir = null,
|
|
||||||
EndAir = null,
|
|
||||||
Poster = x.Poster,
|
|
||||||
Thumbnail = x.Thumbnail,
|
|
||||||
Logo = x.Logo,
|
|
||||||
Type = ItemType.Collection
|
|
||||||
};
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override string GetClassName()
|
public ItemKind Kind => ItemKind.Show;
|
||||||
|
|
||||||
|
public DateTime? AirDate => StartAir;
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class MovieItem : Movie, ILibraryItem
|
||||||
{
|
{
|
||||||
return Type.ToString();
|
/// <inheritdoc/>
|
||||||
|
public ItemKind Kind => ItemKind.Movie;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public sealed class CollectionItem : Collection, ILibraryItem
|
||||||
|
{
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public ItemKind Kind => ItemKind.Collection;
|
||||||
|
|
||||||
|
public DateTime? AirDate => null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -53,12 +53,16 @@ namespace Kyoo.Abstractions.Models
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The ID of the Show where the People playing in.
|
/// The ID of the Show where the People playing in.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int ShowID { get; set; }
|
public int? ShowID { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The show where the People played in.
|
/// The show where the People played in.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Show Show { get; set; }
|
public Show? Show { get; set; }
|
||||||
|
|
||||||
|
public int? MovieID { get; set; }
|
||||||
|
|
||||||
|
public Movie? Movie { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The type of work the person has done for the show.
|
/// The type of work the person has done for the show.
|
||||||
|
@ -17,7 +17,10 @@
|
|||||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
using Kyoo.Abstractions.Models.Attributes;
|
using Kyoo.Abstractions.Models.Attributes;
|
||||||
|
using Kyoo.Utils;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Kyoo.Abstractions.Models
|
namespace Kyoo.Abstractions.Models
|
||||||
{
|
{
|
||||||
@ -31,7 +34,7 @@ namespace Kyoo.Abstractions.Models
|
|||||||
public int ID { get; set; }
|
public int ID { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public string Slug { get; set; }
|
[MaxLength(256)] public string Slug { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The name of this collection.
|
/// The name of this collection.
|
||||||
@ -39,30 +42,39 @@ namespace Kyoo.Abstractions.Models
|
|||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public Image Poster { get; set; }
|
public Image? Poster { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public Image Thumbnail { get; set; }
|
public Image? Thumbnail { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public Image Logo { get; set; }
|
public Image? Logo { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The description of this collection.
|
/// The description of this collection.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Overview { get; set; }
|
public string? Overview { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The list of movies contained in this collection.
|
||||||
|
/// </summary>
|
||||||
|
[LoadableRelation] public ICollection<Movie>? Movies { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The list of shows contained in this collection.
|
/// The list of shows contained in this collection.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[LoadableRelation] public ICollection<Show> Shows { get; set; }
|
[LoadableRelation] public ICollection<Show>? Shows { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The list of libraries that contains this collection.
|
|
||||||
/// </summary>
|
|
||||||
[LoadableRelation] public ICollection<Library> Libraries { get; set; }
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public Dictionary<string, MetadataID> ExternalId { get; set; }
|
public Dictionary<string, MetadataID> ExternalId { get; set; } = new();
|
||||||
|
|
||||||
|
public Collection() { }
|
||||||
|
|
||||||
|
[JsonConstructor]
|
||||||
|
public Collection(string name)
|
||||||
|
{
|
||||||
|
Slug = Utility.ToSlug(name);
|
||||||
|
Name = name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Kyoo.Abstractions.Controllers;
|
using Kyoo.Abstractions.Controllers;
|
||||||
@ -35,24 +36,19 @@ namespace Kyoo.Abstractions.Models
|
|||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
[Computed]
|
[Computed]
|
||||||
|
[MaxLength(256)]
|
||||||
public string Slug
|
public string Slug
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (ShowSlug != null || Show?.Slug != null)
|
if (ShowSlug != null || Show?.Slug != null)
|
||||||
return GetSlug(ShowSlug ?? Show.Slug, SeasonNumber, EpisodeNumber, AbsoluteNumber);
|
return GetSlug(ShowSlug ?? Show.Slug, SeasonNumber, EpisodeNumber, AbsoluteNumber);
|
||||||
return ShowID != 0
|
return GetSlug(ShowID.ToString(), SeasonNumber, EpisodeNumber, AbsoluteNumber);
|
||||||
? GetSlug(ShowID.ToString(), SeasonNumber, EpisodeNumber, AbsoluteNumber)
|
|
||||||
: null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[UsedImplicitly]
|
[UsedImplicitly]
|
||||||
[NotNull]
|
|
||||||
private set
|
private set
|
||||||
{
|
{
|
||||||
if (value == null)
|
|
||||||
throw new ArgumentNullException(nameof(value));
|
|
||||||
|
|
||||||
Match match = Regex.Match(value, @"(?<show>.+)-s(?<season>\d+)e(?<episode>\d+)");
|
Match match = Regex.Match(value, @"(?<show>.+)-s(?<season>\d+)e(?<episode>\d+)");
|
||||||
|
|
||||||
if (match.Success)
|
if (match.Success)
|
||||||
@ -80,7 +76,7 @@ namespace Kyoo.Abstractions.Models
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The slug of the Show that contain this episode. If this is not set, this episode is ill-formed.
|
/// The slug of the Show that contain this episode. If this is not set, this episode is ill-formed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[SerializeIgnore] public string ShowSlug { private get; set; }
|
[SerializeIgnore] public string? ShowSlug { private get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The ID of the Show containing this episode.
|
/// The ID of the Show containing this episode.
|
||||||
@ -90,7 +86,7 @@ namespace Kyoo.Abstractions.Models
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The show that contains this episode. This must be explicitly loaded via a call to <see cref="ILibraryManager.Load"/>.
|
/// The show that contains this episode. This must be explicitly loaded via a call to <see cref="ILibraryManager.Load"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[LoadableRelation(nameof(ShowID))] public Show Show { get; set; }
|
[LoadableRelation(nameof(ShowID))] public Show? Show { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The ID of the Season containing this episode.
|
/// The ID of the Season containing this episode.
|
||||||
@ -105,7 +101,7 @@ namespace Kyoo.Abstractions.Models
|
|||||||
/// This can be null if the season is unknown and the episode is only identified
|
/// This can be null if the season is unknown and the episode is only identified
|
||||||
/// by it's <see cref="AbsoluteNumber"/>.
|
/// by it's <see cref="AbsoluteNumber"/>.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[LoadableRelation(nameof(SeasonID))] public Season Season { get; set; }
|
[LoadableRelation(nameof(SeasonID))] public Season? Season { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The season in witch this episode is in.
|
/// The season in witch this episode is in.
|
||||||
@ -130,12 +126,12 @@ namespace Kyoo.Abstractions.Models
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The title of this episode.
|
/// The title of this episode.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Title { get; set; }
|
public string? Name { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The overview of this episode.
|
/// The overview of this episode.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Overview { get; set; }
|
public string? Overview { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The release date of this episode. It can be null if unknown.
|
/// The release date of this episode. It can be null if unknown.
|
||||||
@ -143,16 +139,16 @@ namespace Kyoo.Abstractions.Models
|
|||||||
public DateTime? ReleaseDate { get; set; }
|
public DateTime? ReleaseDate { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public Image Poster { get; set; }
|
public Image? Poster { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public Image Thumbnail { get; set; }
|
public Image? Thumbnail { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public Image Logo { get; set; }
|
public Image? Logo { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public Dictionary<string, MetadataID> ExternalId { get; set; }
|
public Dictionary<string, MetadataID> ExternalId { get; set; } = new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get the slug of an episode.
|
/// Get the slug of an episode.
|
||||||
@ -172,7 +168,7 @@ namespace Kyoo.Abstractions.Models
|
|||||||
/// </param>
|
/// </param>
|
||||||
/// <returns>The slug corresponding to the given arguments</returns>
|
/// <returns>The slug corresponding to the given arguments</returns>
|
||||||
/// <exception cref="ArgumentNullException">The given show slug was null.</exception>
|
/// <exception cref="ArgumentNullException">The given show slug was null.</exception>
|
||||||
public static string GetSlug([NotNull] string showSlug,
|
public static string GetSlug(string showSlug,
|
||||||
int? seasonNumber,
|
int? seasonNumber,
|
||||||
int? episodeNumber,
|
int? episodeNumber,
|
||||||
int? absoluteNumber = null)
|
int? absoluteNumber = null)
|
||||||
|
@ -1,62 +0,0 @@
|
|||||||
// 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.Collections.Generic;
|
|
||||||
using Kyoo.Abstractions.Models.Attributes;
|
|
||||||
using Kyoo.Utils;
|
|
||||||
|
|
||||||
namespace Kyoo.Abstractions.Models
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// A genre that allow one to specify categories for shows.
|
|
||||||
/// </summary>
|
|
||||||
public class Genre : IResource
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
public int ID { get; set; }
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public string Slug { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The name of this genre.
|
|
||||||
/// </summary>
|
|
||||||
public string Name { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The list of shows that have this genre.
|
|
||||||
/// </summary>
|
|
||||||
[LoadableRelation] public ICollection<Show> Shows { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create a new, empty <see cref="Genre"/>.
|
|
||||||
/// </summary>
|
|
||||||
public Genre() { }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create a new <see cref="Genre"/> and specify it's <see cref="Name"/>.
|
|
||||||
/// The <see cref="Slug"/> is automatically calculated from it's name.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="name">The name of this genre.</param>
|
|
||||||
public Genre(string name)
|
|
||||||
{
|
|
||||||
Slug = Utility.ToSlug(name);
|
|
||||||
Name = name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -16,6 +16,7 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
using Kyoo.Abstractions.Controllers;
|
using Kyoo.Abstractions.Controllers;
|
||||||
|
|
||||||
namespace Kyoo.Abstractions.Models
|
namespace Kyoo.Abstractions.Models
|
||||||
@ -42,6 +43,7 @@ namespace Kyoo.Abstractions.Models
|
|||||||
/// There is no setter for a slug since it can be computed from other fields.
|
/// There is no setter for a slug since it can be computed from other fields.
|
||||||
/// For example, a season slug is {ShowSlug}-s{SeasonNumber}.
|
/// For example, a season slug is {ShowSlug}-s{SeasonNumber}.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
|
[MaxLength(256)]
|
||||||
public string Slug { get; }
|
public string Slug { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,18 +28,18 @@ namespace Kyoo.Abstractions.Models
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// A poster is a 9/16 format image with the cover of the resource.
|
/// A poster is a 9/16 format image with the cover of the resource.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Image Poster { get; set; }
|
public Image? Poster { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A thumbnail is a 16/9 format image, it could ether be used as a background or as a preview but it usually
|
/// A thumbnail is a 16/9 format image, it could ether be used as a background or as a preview but it usually
|
||||||
/// is not an official image.
|
/// is not an official image.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Image Thumbnail { get; set; }
|
public Image? Thumbnail { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A logo is a small image representing the resource.
|
/// A logo is a small image representing the resource.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Image Logo { get; set; }
|
public Image? Logo { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Image
|
public class Image
|
||||||
|
140
back/src/Kyoo.Abstractions/Models/Resources/Movie.cs
Normal file
140
back/src/Kyoo.Abstractions/Models/Resources/Movie.cs
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
// 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 System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using Kyoo.Abstractions.Controllers;
|
||||||
|
using Kyoo.Abstractions.Models.Attributes;
|
||||||
|
using Kyoo.Utils;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace Kyoo.Abstractions.Models
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A series or a movie.
|
||||||
|
/// </summary>
|
||||||
|
public class Movie : IResource, IMetadata, IOnMerge, IThumbnails
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public int ID { get; set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[MaxLength(256)]
|
||||||
|
public string Slug { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The title of this show.
|
||||||
|
/// </summary>
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A catchphrase for this movie.
|
||||||
|
/// </summary>
|
||||||
|
public string? Tagline { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The list of alternative titles of this show.
|
||||||
|
/// </summary>
|
||||||
|
public string[] Aliases { get; set; } = Array.Empty<string>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The path of the movie video file.
|
||||||
|
/// </summary>
|
||||||
|
public string Path { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The summary of this show.
|
||||||
|
/// </summary>
|
||||||
|
public string? Overview { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A list of tags that match this movie.
|
||||||
|
/// </summary>
|
||||||
|
public string[] Tags { get; set; } = Array.Empty<string>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The list of genres (themes) this show has.
|
||||||
|
/// </summary>
|
||||||
|
public Genre[] Genres { get; set; } = Array.Empty<Genre>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Is this show airing, not aired yet or finished?
|
||||||
|
/// </summary>
|
||||||
|
public Status Status { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The date this movie aired.
|
||||||
|
/// </summary>
|
||||||
|
public DateTime? AirDate { get; set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public Image? Poster { get; set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public Image? Thumbnail { get; set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public Image? Logo { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A video of a few minutes that tease the content.
|
||||||
|
/// </summary>
|
||||||
|
public string? Trailer { get; set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public Dictionary<string, MetadataID> ExternalId { get; set; } = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The ID of the Studio that made this show.
|
||||||
|
/// </summary>
|
||||||
|
[SerializeIgnore] public int? StudioID { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The Studio that made this show.
|
||||||
|
/// This must be explicitly loaded via a call to <see cref="ILibraryManager.Load"/>.
|
||||||
|
/// </summary>
|
||||||
|
[LoadableRelation(nameof(StudioID))][EditableRelation] public Studio? Studio { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The list of people that made this show.
|
||||||
|
/// </summary>
|
||||||
|
[LoadableRelation][EditableRelation] public ICollection<PeopleRole>? People { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The list of collections that contains this show.
|
||||||
|
/// </summary>
|
||||||
|
[LoadableRelation] public ICollection<Collection>? Collections { get; set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void OnMerge(object merged)
|
||||||
|
{
|
||||||
|
foreach (PeopleRole link in People)
|
||||||
|
link.Movie = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Movie() { }
|
||||||
|
|
||||||
|
[JsonConstructor]
|
||||||
|
public Movie(string name)
|
||||||
|
{
|
||||||
|
Slug = Utility.ToSlug(name);
|
||||||
|
Name = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -17,7 +17,10 @@
|
|||||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
using Kyoo.Abstractions.Models.Attributes;
|
using Kyoo.Abstractions.Models.Attributes;
|
||||||
|
using Kyoo.Utils;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Kyoo.Abstractions.Models
|
namespace Kyoo.Abstractions.Models
|
||||||
{
|
{
|
||||||
@ -30,6 +33,7 @@ namespace Kyoo.Abstractions.Models
|
|||||||
public int ID { get; set; }
|
public int ID { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
[MaxLength(256)]
|
||||||
public string Slug { get; set; }
|
public string Slug { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -38,20 +42,29 @@ namespace Kyoo.Abstractions.Models
|
|||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public Image Poster { get; set; }
|
public Image? Poster { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public Image Thumbnail { get; set; }
|
public Image? Thumbnail { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public Image Logo { get; set; }
|
public Image? Logo { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public Dictionary<string, MetadataID> ExternalId { get; set; }
|
public Dictionary<string, MetadataID> ExternalId { get; set; } = new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The list of roles this person has played in. See <see cref="PeopleRole"/> for more information.
|
/// The list of roles this person has played in. See <see cref="PeopleRole"/> for more information.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[EditableRelation][LoadableRelation] public ICollection<PeopleRole> Roles { get; set; }
|
[EditableRelation][LoadableRelation] public ICollection<PeopleRole>? Roles { get; set; }
|
||||||
|
|
||||||
|
public People() { }
|
||||||
|
|
||||||
|
[JsonConstructor]
|
||||||
|
public People(string name)
|
||||||
|
{
|
||||||
|
Slug = Utility.ToSlug(name);
|
||||||
|
Name = name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Kyoo.Abstractions.Controllers;
|
using Kyoo.Abstractions.Controllers;
|
||||||
@ -35,6 +36,7 @@ namespace Kyoo.Abstractions.Models
|
|||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
[Computed]
|
[Computed]
|
||||||
|
[MaxLength(256)]
|
||||||
public string Slug
|
public string Slug
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@ -48,7 +50,7 @@ namespace Kyoo.Abstractions.Models
|
|||||||
[NotNull]
|
[NotNull]
|
||||||
private set
|
private set
|
||||||
{
|
{
|
||||||
Match match = Regex.Match(value ?? string.Empty, @"(?<show>.+)-s(?<season>\d+)");
|
Match match = Regex.Match(value, @"(?<show>.+)-s(?<season>\d+)");
|
||||||
|
|
||||||
if (!match.Success)
|
if (!match.Success)
|
||||||
throw new ArgumentException("Invalid season slug. Format: {showSlug}-s{seasonNumber}");
|
throw new ArgumentException("Invalid season slug. Format: {showSlug}-s{seasonNumber}");
|
||||||
@ -60,7 +62,7 @@ namespace Kyoo.Abstractions.Models
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The slug of the Show that contain this episode. If this is not set, this season is ill-formed.
|
/// The slug of the Show that contain this episode. If this is not set, this season is ill-formed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[SerializeIgnore] public string ShowSlug { private get; set; }
|
[SerializeIgnore] public string? ShowSlug { private get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The ID of the Show containing this season.
|
/// The ID of the Show containing this season.
|
||||||
@ -71,7 +73,7 @@ namespace Kyoo.Abstractions.Models
|
|||||||
/// The show that contains this season.
|
/// The show that contains this season.
|
||||||
/// This must be explicitly loaded via a call to <see cref="ILibraryManager.Load"/>.
|
/// This must be explicitly loaded via a call to <see cref="ILibraryManager.Load"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[LoadableRelation(nameof(ShowID))] public Show Show { get; set; }
|
[LoadableRelation(nameof(ShowID))] public Show? Show { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The number of this season. This can be set to 0 to indicate specials.
|
/// The number of this season. This can be set to 0 to indicate specials.
|
||||||
@ -81,12 +83,12 @@ namespace Kyoo.Abstractions.Models
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The title of this season.
|
/// The title of this season.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Title { get; set; }
|
public string? Name { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A quick overview of this season.
|
/// A quick overview of this season.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Overview { get; set; }
|
public string? Overview { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The starting air date of this season.
|
/// The starting air date of this season.
|
||||||
@ -99,20 +101,20 @@ namespace Kyoo.Abstractions.Models
|
|||||||
public DateTime? EndDate { get; set; }
|
public DateTime? EndDate { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public Image Poster { get; set; }
|
public Image? Poster { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public Image Thumbnail { get; set; }
|
public Image? Thumbnail { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public Image Logo { get; set; }
|
public Image? Logo { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public Dictionary<string, MetadataID> ExternalId { get; set; }
|
public Dictionary<string, MetadataID> ExternalId { get; set; } = new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The list of episodes that this season contains.
|
/// The list of episodes that this season contains.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[LoadableRelation] public ICollection<Episode> Episodes { get; set; }
|
[LoadableRelation] public ICollection<Episode>? Episodes { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,8 +18,11 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
using Kyoo.Abstractions.Controllers;
|
using Kyoo.Abstractions.Controllers;
|
||||||
using Kyoo.Abstractions.Models.Attributes;
|
using Kyoo.Abstractions.Models.Attributes;
|
||||||
|
using Kyoo.Utils;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Kyoo.Abstractions.Models
|
namespace Kyoo.Abstractions.Models
|
||||||
{
|
{
|
||||||
@ -32,27 +35,38 @@ namespace Kyoo.Abstractions.Models
|
|||||||
public int ID { get; set; }
|
public int ID { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
[MaxLength(256)]
|
||||||
public string Slug { get; set; }
|
public string Slug { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The title of this show.
|
/// The title of this show.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Title { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A catchphrase for this show.
|
||||||
|
/// </summary>
|
||||||
|
public string? Tagline { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The list of alternative titles of this show.
|
/// The list of alternative titles of this show.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[EditableRelation] public string[] Aliases { get; set; }
|
public string[] Aliases { get; set; } = Array.Empty<string>();
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The path of the root directory of this show.
|
|
||||||
/// </summary>
|
|
||||||
[SerializeIgnore] public string Path { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The summary of this show.
|
/// The summary of this show.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Overview { get; set; }
|
public string? Overview { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A list of tags that match this movie.
|
||||||
|
/// </summary>
|
||||||
|
public string[] Tags { get; set; } = Array.Empty<string>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The list of genres (themes) this show has.
|
||||||
|
/// </summary>
|
||||||
|
public Genre[] Genres { get; set; } = Array.Empty<Genre>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Is this show airing, not aired yet or finished?
|
/// Is this show airing, not aired yet or finished?
|
||||||
@ -71,27 +85,22 @@ namespace Kyoo.Abstractions.Models
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTime? EndAir { get; set; }
|
public DateTime? EndAir { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc />
|
||||||
/// True if this show represent a movie, false otherwise.
|
public Image? Poster { get; set; }
|
||||||
/// </summary>
|
|
||||||
public bool IsMovie { get; set; }
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public Image Poster { get; set; }
|
public Image? Thumbnail { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public Image Thumbnail { get; set; }
|
public Image? Logo { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public Image Logo { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A video of a few minutes that tease the content.
|
/// A video of a few minutes that tease the content.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Trailer { get; set; }
|
public string? Trailer { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public Dictionary<string, MetadataID> ExternalId { get; set; }
|
public Dictionary<string, MetadataID> ExternalId { get; set; } = new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The ID of the Studio that made this show.
|
/// The ID of the Studio that made this show.
|
||||||
@ -102,39 +111,29 @@ namespace Kyoo.Abstractions.Models
|
|||||||
/// The Studio that made this show.
|
/// The Studio that made this show.
|
||||||
/// This must be explicitly loaded via a call to <see cref="ILibraryManager.Load"/>.
|
/// This must be explicitly loaded via a call to <see cref="ILibraryManager.Load"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[LoadableRelation(nameof(StudioID))][EditableRelation] public Studio Studio { get; set; }
|
[LoadableRelation(nameof(StudioID))][EditableRelation] public Studio? Studio { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The list of genres (themes) this show has.
|
|
||||||
/// </summary>
|
|
||||||
[LoadableRelation][EditableRelation] public ICollection<Genre> Genres { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The list of people that made this show.
|
/// The list of people that made this show.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[LoadableRelation][EditableRelation] public ICollection<PeopleRole> People { get; set; }
|
[LoadableRelation][EditableRelation] public ICollection<PeopleRole>? People { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The different seasons in this show. If this is a movie, this list is always null or empty.
|
/// The different seasons in this show. If this is a movie, this list is always null or empty.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[LoadableRelation] public ICollection<Season> Seasons { get; set; }
|
[LoadableRelation] public ICollection<Season>? Seasons { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The list of episodes in this show.
|
/// The list of episodes in this show.
|
||||||
/// If this is a movie, there will be a unique episode (with the seasonNumber and episodeNumber set to null).
|
/// If this is a movie, there will be a unique episode (with the seasonNumber and episodeNumber set to null).
|
||||||
/// Having an episode is necessary to store metadata and tracks.
|
/// Having an episode is necessary to store metadata and tracks.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[LoadableRelation] public ICollection<Episode> Episodes { get; set; }
|
[LoadableRelation] public ICollection<Episode>? Episodes { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The list of libraries that contains this show.
|
|
||||||
/// </summary>
|
|
||||||
[LoadableRelation] public ICollection<Library> Libraries { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The list of collections that contains this show.
|
/// The list of collections that contains this show.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[LoadableRelation] public ICollection<Collection> Collections { get; set; }
|
[LoadableRelation] public ICollection<Collection>? Collections { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void OnMerge(object merged)
|
public void OnMerge(object merged)
|
||||||
@ -157,6 +156,15 @@ namespace Kyoo.Abstractions.Models
|
|||||||
episode.Show = this;
|
episode.Show = this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Show() { }
|
||||||
|
|
||||||
|
[JsonConstructor]
|
||||||
|
public Show(string name)
|
||||||
|
{
|
||||||
|
Slug = Utility.ToSlug(name);
|
||||||
|
Name = name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -17,8 +17,10 @@
|
|||||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
using Kyoo.Abstractions.Models.Attributes;
|
using Kyoo.Abstractions.Models.Attributes;
|
||||||
using Kyoo.Utils;
|
using Kyoo.Utils;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Kyoo.Abstractions.Models
|
namespace Kyoo.Abstractions.Models
|
||||||
{
|
{
|
||||||
@ -31,6 +33,7 @@ namespace Kyoo.Abstractions.Models
|
|||||||
public int ID { get; set; }
|
public int ID { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
[MaxLength(256)]
|
||||||
public string Slug { get; set; }
|
public string Slug { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -41,10 +44,15 @@ namespace Kyoo.Abstractions.Models
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The list of shows that are made by this studio.
|
/// The list of shows that are made by this studio.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[LoadableRelation] public ICollection<Show> Shows { get; set; }
|
[LoadableRelation] public ICollection<Show>? Shows { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The list of movies that are made by this studio.
|
||||||
|
/// </summary>
|
||||||
|
[LoadableRelation] public ICollection<Movie>? Movies { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public Dictionary<string, MetadataID> ExternalId { get; set; }
|
public Dictionary<string, MetadataID> ExternalId { get; set; } = new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a new, empty, <see cref="Studio"/>.
|
/// Create a new, empty, <see cref="Studio"/>.
|
||||||
@ -55,6 +63,7 @@ namespace Kyoo.Abstractions.Models
|
|||||||
/// Create a new <see cref="Studio"/> with a specific name, the slug is calculated automatically.
|
/// Create a new <see cref="Studio"/> with a specific name, the slug is calculated automatically.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name">The name of the studio.</param>
|
/// <param name="name">The name of the studio.</param>
|
||||||
|
[JsonConstructor]
|
||||||
public Studio(string name)
|
public Studio(string name)
|
||||||
{
|
{
|
||||||
Slug = Utility.ToSlug(name);
|
Slug = Utility.ToSlug(name);
|
||||||
|
@ -17,7 +17,10 @@
|
|||||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
using Kyoo.Abstractions.Models.Attributes;
|
using Kyoo.Abstractions.Models.Attributes;
|
||||||
|
using Kyoo.Utils;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Kyoo.Abstractions.Models
|
namespace Kyoo.Abstractions.Models
|
||||||
{
|
{
|
||||||
@ -30,6 +33,7 @@ namespace Kyoo.Abstractions.Models
|
|||||||
public int ID { get; set; }
|
public int ID { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
[MaxLength(256)]
|
||||||
public string Slug { get; set; }
|
public string Slug { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -53,27 +57,30 @@ namespace Kyoo.Abstractions.Models
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string[] Permissions { get; set; }
|
public string[] Permissions { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Arbitrary extra data that can be used by specific authentication implementations.
|
|
||||||
/// </summary>
|
|
||||||
[SerializeIgnore]
|
|
||||||
public Dictionary<string, string> ExtraData { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A logo is a small image representing the resource.
|
/// A logo is a small image representing the resource.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Image Logo { get; set; }
|
public Image? Logo { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The list of shows the user has finished.
|
/// The list of shows the user has finished.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[SerializeIgnore]
|
[SerializeIgnore]
|
||||||
public ICollection<Show> Watched { get; set; }
|
public ICollection<Show>? Watched { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The list of episodes the user is watching (stopped in progress or the next episode of the show)
|
/// The list of episodes the user is watching (stopped in progress or the next episode of the show)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[SerializeIgnore]
|
[SerializeIgnore]
|
||||||
public ICollection<WatchedEpisode> CurrentlyWatching { get; set; }
|
public ICollection<WatchedEpisode>? CurrentlyWatching { get; set; }
|
||||||
|
|
||||||
|
public User() { }
|
||||||
|
|
||||||
|
[JsonConstructor]
|
||||||
|
public User(string username)
|
||||||
|
{
|
||||||
|
Slug = Utility.ToSlug(username);
|
||||||
|
Username = username;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ namespace Kyoo.Abstractions.Models
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The <see cref="Episode"/> started.
|
/// The <see cref="Episode"/> started.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Episode Episode { get; set; }
|
public Episode? Episode { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Where the player has stopped watching the episode (between 0 and 100).
|
/// Where the player has stopped watching the episode (between 0 and 100).
|
||||||
|
@ -58,7 +58,7 @@ namespace Kyoo.Abstractions.Models.Utils
|
|||||||
/// Create a new <see cref="Identifier"/> for the given slug.
|
/// Create a new <see cref="Identifier"/> for the given slug.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="slug">The slug of the resource.</param>
|
/// <param name="slug">The slug of the resource.</param>
|
||||||
public Identifier([NotNull] string slug)
|
public Identifier(string slug)
|
||||||
{
|
{
|
||||||
if (slug == null)
|
if (slug == null)
|
||||||
throw new ArgumentNullException(nameof(slug));
|
throw new ArgumentNullException(nameof(slug));
|
||||||
|
@ -31,13 +31,13 @@ namespace Kyoo.Abstractions.Models.Utils
|
|||||||
/// The list of errors that where made in the request.
|
/// The list of errors that where made in the request.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <example><c>["InvalidFilter: no field 'startYear' on a collection"]</c></example>
|
/// <example><c>["InvalidFilter: no field 'startYear' on a collection"]</c></example>
|
||||||
[NotNull] public string[] Errors { get; set; }
|
public string[] Errors { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a new <see cref="RequestError"/> with one error.
|
/// Create a new <see cref="RequestError"/> with one error.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="error">The error to specify in the response.</param>
|
/// <param name="error">The error to specify in the response.</param>
|
||||||
public RequestError([NotNull] string error)
|
public RequestError(string error)
|
||||||
{
|
{
|
||||||
if (error == null)
|
if (error == null)
|
||||||
throw new ArgumentNullException(nameof(error));
|
throw new ArgumentNullException(nameof(error));
|
||||||
@ -48,7 +48,7 @@ namespace Kyoo.Abstractions.Models.Utils
|
|||||||
/// Create a new <see cref="RequestError"/> with multiple errors.
|
/// Create a new <see cref="RequestError"/> with multiple errors.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="errors">The errors to specify in the response.</param>
|
/// <param name="errors">The errors to specify in the response.</param>
|
||||||
public RequestError([NotNull] string[] errors)
|
public RequestError(string[] errors)
|
||||||
{
|
{
|
||||||
if (errors == null || !errors.Any())
|
if (errors == null || !errors.Any())
|
||||||
throw new ArgumentException("Errors must be non null and not empty", nameof(errors));
|
throw new ArgumentException("Errors must be non null and not empty", nameof(errors));
|
||||||
|
@ -1,194 +0,0 @@
|
|||||||
// 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 System.Collections.Generic;
|
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Kyoo.Abstractions.Controllers;
|
|
||||||
using Kyoo.Abstractions.Models.Attributes;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Kyoo.Abstractions.Models
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// A watch item give information useful for playback.
|
|
||||||
/// Information about tracks and display information that could be used by the player.
|
|
||||||
/// This contains mostly data from an <see cref="Episode"/> with another form.
|
|
||||||
/// </summary>
|
|
||||||
public class WatchItem : CustomTypeDescriptor, IThumbnails, ILink
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The ID of the episode associated with this item.
|
|
||||||
/// </summary>
|
|
||||||
public int EpisodeID { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The slug of this episode.
|
|
||||||
/// </summary>
|
|
||||||
public string Slug { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The title of the show containing this episode.
|
|
||||||
/// </summary>
|
|
||||||
public string ShowTitle { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The slug of the show containing this episode
|
|
||||||
/// </summary>
|
|
||||||
public string ShowSlug { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The season in witch this episode is in.
|
|
||||||
/// </summary>
|
|
||||||
public int? SeasonNumber { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The number of this episode is it's season.
|
|
||||||
/// </summary>
|
|
||||||
public int? EpisodeNumber { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The absolute number of this episode. It's an episode number that is not reset to 1 after a new season.
|
|
||||||
/// </summary>
|
|
||||||
public int? AbsoluteNumber { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The title of this episode.
|
|
||||||
/// </summary>
|
|
||||||
public string Title { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The summary of this episode.
|
|
||||||
/// </summary>
|
|
||||||
public string Overview { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The release date of this episode. It can be null if unknown.
|
|
||||||
/// </summary>
|
|
||||||
public DateTime? ReleaseDate { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The episode that come before this one if you follow usual watch orders.
|
|
||||||
/// If this is the first episode or this is a movie, it will be null.
|
|
||||||
/// </summary>
|
|
||||||
public Episode PreviousEpisode { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The episode that come after this one if you follow usual watch orders.
|
|
||||||
/// If this is the last aired episode or this is a movie, it will be null.
|
|
||||||
/// </summary>
|
|
||||||
public Episode NextEpisode { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// <c>true</c> if this is a movie, <c>false</c> otherwise.
|
|
||||||
/// </summary>
|
|
||||||
public bool IsMovie { get; set; }
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public Image Poster { get; set; }
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public Image Thumbnail { get; set; }
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public Image Logo { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The transcoder's info for this item. This include subtitles, fonts, chapters...
|
|
||||||
/// </summary>
|
|
||||||
public object Info { get; set; }
|
|
||||||
|
|
||||||
[SerializeIgnore]
|
|
||||||
private string _Type => IsMovie ? "movie" : "episode";
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
public object Link => new
|
|
||||||
{
|
|
||||||
Direct = $"/video/{_Type}/{Slug}/direct",
|
|
||||||
Hls = $"/video/{_Type}/{Slug}/master.m3u8",
|
|
||||||
};
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create a <see cref="WatchItem"/> from an <see cref="Episode"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="ep">The episode to transform.</param>
|
|
||||||
/// <param name="library">
|
|
||||||
/// A library manager to retrieve the next and previous episode and load the show and tracks of the episode.
|
|
||||||
/// </param>
|
|
||||||
/// <param name="client">A http client to reach the transcoder.</param>
|
|
||||||
/// <returns>A new WatchItem representing the given episode.</returns>
|
|
||||||
public static async Task<WatchItem> FromEpisode(Episode ep, ILibraryManager library, HttpClient client)
|
|
||||||
{
|
|
||||||
await library.Load(ep, x => x.Show);
|
|
||||||
|
|
||||||
return new WatchItem
|
|
||||||
{
|
|
||||||
EpisodeID = ep.ID,
|
|
||||||
Slug = ep.Slug,
|
|
||||||
ShowSlug = ep.Show.Slug,
|
|
||||||
ShowTitle = ep.Show.Title,
|
|
||||||
SeasonNumber = ep.SeasonNumber,
|
|
||||||
EpisodeNumber = ep.EpisodeNumber,
|
|
||||||
AbsoluteNumber = ep.AbsoluteNumber,
|
|
||||||
Title = ep.Title,
|
|
||||||
Overview = ep.Overview,
|
|
||||||
ReleaseDate = ep.ReleaseDate,
|
|
||||||
Poster = ep.Poster,
|
|
||||||
Thumbnail = ep.Thumbnail,
|
|
||||||
Logo = ep.Logo,
|
|
||||||
PreviousEpisode = ep.Show.IsMovie
|
|
||||||
? null
|
|
||||||
: (await library.GetAll<Episode>(
|
|
||||||
where: x => x.ShowID == ep.ShowID,
|
|
||||||
limit: new Pagination(1, ep.ID, true)
|
|
||||||
)).FirstOrDefault(),
|
|
||||||
NextEpisode = ep.Show.IsMovie
|
|
||||||
? null
|
|
||||||
: (await library.GetAll<Episode>(
|
|
||||||
where: x => x.ShowID == ep.ShowID,
|
|
||||||
limit: new Pagination(1, ep.ID)
|
|
||||||
)).FirstOrDefault(),
|
|
||||||
IsMovie = ep.Show.IsMovie,
|
|
||||||
Info = await _GetInfo(ep, client),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private static async Task<object> _GetInfo(Episode ep, HttpClient client)
|
|
||||||
{
|
|
||||||
HttpResponseMessage ret = await client.GetAsync($"http://transcoder:7666/{(ep.Show.IsMovie ? "movie" : "episode")}/{ep.Slug}/info");
|
|
||||||
ret.EnsureSuccessStatusCode();
|
|
||||||
string content = await ret.Content.ReadAsStringAsync();
|
|
||||||
return JsonConvert.DeserializeObject<object>(content);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override string GetClassName()
|
|
||||||
{
|
|
||||||
return nameof(Show);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override string GetComponentName()
|
|
||||||
{
|
|
||||||
return ShowSlug;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -39,8 +39,8 @@ namespace Kyoo.Utils
|
|||||||
/// <returns>The list mapped.</returns>
|
/// <returns>The list mapped.</returns>
|
||||||
/// <exception cref="ArgumentNullException">The list or the mapper can't be null</exception>
|
/// <exception cref="ArgumentNullException">The list or the mapper can't be null</exception>
|
||||||
[LinqTunnel]
|
[LinqTunnel]
|
||||||
public static IEnumerable<T2> Map<T, T2>([NotNull] this IEnumerable<T> self,
|
public static IEnumerable<T2> Map<T, T2>(this IEnumerable<T> self,
|
||||||
[NotNull] Func<T, int, T2> mapper)
|
Func<T, int, T2> mapper)
|
||||||
{
|
{
|
||||||
if (self == null)
|
if (self == null)
|
||||||
throw new ArgumentNullException(nameof(self));
|
throw new ArgumentNullException(nameof(self));
|
||||||
@ -72,8 +72,8 @@ namespace Kyoo.Utils
|
|||||||
/// <returns>The list mapped as an AsyncEnumerable.</returns>
|
/// <returns>The list mapped as an AsyncEnumerable.</returns>
|
||||||
/// <exception cref="ArgumentNullException">The list or the mapper can't be null.</exception>
|
/// <exception cref="ArgumentNullException">The list or the mapper can't be null.</exception>
|
||||||
[LinqTunnel]
|
[LinqTunnel]
|
||||||
public static IAsyncEnumerable<T2> MapAsync<T, T2>([NotNull] this IEnumerable<T> self,
|
public static IAsyncEnumerable<T2> MapAsync<T, T2>(this IEnumerable<T> self,
|
||||||
[NotNull] Func<T, int, Task<T2>> mapper)
|
Func<T, int, Task<T2>> mapper)
|
||||||
{
|
{
|
||||||
if (self == null)
|
if (self == null)
|
||||||
throw new ArgumentNullException(nameof(self));
|
throw new ArgumentNullException(nameof(self));
|
||||||
@ -105,8 +105,8 @@ namespace Kyoo.Utils
|
|||||||
/// <returns>The list mapped as an AsyncEnumerable</returns>
|
/// <returns>The list mapped as an AsyncEnumerable</returns>
|
||||||
/// <exception cref="ArgumentNullException">The list or the mapper can't be null</exception>
|
/// <exception cref="ArgumentNullException">The list or the mapper can't be null</exception>
|
||||||
[LinqTunnel]
|
[LinqTunnel]
|
||||||
public static IAsyncEnumerable<T2> SelectAsync<T, T2>([NotNull] this IEnumerable<T> self,
|
public static IAsyncEnumerable<T2> SelectAsync<T, T2>(this IEnumerable<T> self,
|
||||||
[NotNull] Func<T, Task<T2>> mapper)
|
Func<T, Task<T2>> mapper)
|
||||||
{
|
{
|
||||||
if (self == null)
|
if (self == null)
|
||||||
throw new ArgumentNullException(nameof(self));
|
throw new ArgumentNullException(nameof(self));
|
||||||
@ -132,7 +132,7 @@ namespace Kyoo.Utils
|
|||||||
/// <returns>A task that will return a simple list</returns>
|
/// <returns>A task that will return a simple list</returns>
|
||||||
/// <exception cref="ArgumentNullException">The list can't be null</exception>
|
/// <exception cref="ArgumentNullException">The list can't be null</exception>
|
||||||
[LinqTunnel]
|
[LinqTunnel]
|
||||||
public static Task<List<T>> ToListAsync<T>([NotNull] this IAsyncEnumerable<T> self)
|
public static Task<List<T>> ToListAsync<T>(this IAsyncEnumerable<T> self)
|
||||||
{
|
{
|
||||||
if (self == null)
|
if (self == null)
|
||||||
throw new ArgumentNullException(nameof(self));
|
throw new ArgumentNullException(nameof(self));
|
||||||
@ -157,7 +157,7 @@ namespace Kyoo.Utils
|
|||||||
/// <exception cref="ArgumentNullException">The iterable and the action can't be null.</exception>
|
/// <exception cref="ArgumentNullException">The iterable and the action can't be null.</exception>
|
||||||
/// <returns>The iterator proxied, there is no dual iterations.</returns>
|
/// <returns>The iterator proxied, there is no dual iterations.</returns>
|
||||||
[LinqTunnel]
|
[LinqTunnel]
|
||||||
public static IEnumerable<T> IfEmpty<T>([NotNull] this IEnumerable<T> self, [NotNull] Action action)
|
public static IEnumerable<T> IfEmpty<T>(this IEnumerable<T> self, Action action)
|
||||||
{
|
{
|
||||||
if (self == null)
|
if (self == null)
|
||||||
throw new ArgumentNullException(nameof(self));
|
throw new ArgumentNullException(nameof(self));
|
||||||
@ -190,7 +190,7 @@ namespace Kyoo.Utils
|
|||||||
/// <param name="self">The list to enumerate. If this is null, the function result in a no-op</param>
|
/// <param name="self">The list to enumerate. If this is null, the function result in a no-op</param>
|
||||||
/// <param name="action">The action to execute for each arguments</param>
|
/// <param name="action">The action to execute for each arguments</param>
|
||||||
/// <typeparam name="T">The type of items in the list</typeparam>
|
/// <typeparam name="T">The type of items in the list</typeparam>
|
||||||
public static void ForEach<T>([CanBeNull] this IEnumerable<T> self, Action<T> action)
|
public static void ForEach<T>(this IEnumerable<T>? self, Action<T> action)
|
||||||
{
|
{
|
||||||
if (self == null)
|
if (self == null)
|
||||||
return;
|
return;
|
||||||
@ -203,7 +203,7 @@ namespace Kyoo.Utils
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="self">The list to enumerate. If this is null, the function result in a no-op</param>
|
/// <param name="self">The list to enumerate. If this is null, the function result in a no-op</param>
|
||||||
/// <param name="action">The action to execute for each arguments</param>
|
/// <param name="action">The action to execute for each arguments</param>
|
||||||
public static void ForEach([CanBeNull] this IEnumerable self, Action<object> action)
|
public static void ForEach(this IEnumerable? self, Action<object> action)
|
||||||
{
|
{
|
||||||
if (self == null)
|
if (self == null)
|
||||||
return;
|
return;
|
||||||
@ -217,7 +217,7 @@ namespace Kyoo.Utils
|
|||||||
/// <param name="self">The list to enumerate. If this is null, the function result in a no-op</param>
|
/// <param name="self">The list to enumerate. If this is null, the function result in a no-op</param>
|
||||||
/// <param name="action">The action to execute for each arguments</param>
|
/// <param name="action">The action to execute for each arguments</param>
|
||||||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
||||||
public static async Task ForEachAsync([CanBeNull] this IEnumerable self, Func<object, Task> action)
|
public static async Task ForEachAsync(this IEnumerable? self, Func<object, Task> action)
|
||||||
{
|
{
|
||||||
if (self == null)
|
if (self == null)
|
||||||
return;
|
return;
|
||||||
@ -232,7 +232,7 @@ namespace Kyoo.Utils
|
|||||||
/// <param name="action">The asynchronous action to execute for each arguments</param>
|
/// <param name="action">The asynchronous action to execute for each arguments</param>
|
||||||
/// <typeparam name="T">The type of items in the list.</typeparam>
|
/// <typeparam name="T">The type of items in the list.</typeparam>
|
||||||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
||||||
public static async Task ForEachAsync<T>([CanBeNull] this IEnumerable<T> self, Func<T, Task> action)
|
public static async Task ForEachAsync<T>(this IEnumerable<T>? self, Func<T, Task> action)
|
||||||
{
|
{
|
||||||
if (self == null)
|
if (self == null)
|
||||||
return;
|
return;
|
||||||
@ -247,7 +247,7 @@ namespace Kyoo.Utils
|
|||||||
/// <param name="action">The action to execute for each arguments</param>
|
/// <param name="action">The action to execute for each arguments</param>
|
||||||
/// <typeparam name="T">The type of items in the list.</typeparam>
|
/// <typeparam name="T">The type of items in the list.</typeparam>
|
||||||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
||||||
public static async Task ForEachAsync<T>([CanBeNull] this IAsyncEnumerable<T> self, Action<T> action)
|
public static async Task ForEachAsync<T>(this IAsyncEnumerable<T>? self, Action<T> action)
|
||||||
{
|
{
|
||||||
if (self == null)
|
if (self == null)
|
||||||
return;
|
return;
|
||||||
|
@ -42,9 +42,9 @@ namespace Kyoo.Utils
|
|||||||
/// <typeparam name="T">The type of items in the lists to merge.</typeparam>
|
/// <typeparam name="T">The type of items in the lists to merge.</typeparam>
|
||||||
/// <returns>The two list merged as an array</returns>
|
/// <returns>The two list merged as an array</returns>
|
||||||
[ContractAnnotation("first:notnull => notnull; second:notnull => notnull", true)]
|
[ContractAnnotation("first:notnull => notnull; second:notnull => notnull", true)]
|
||||||
public static T[] MergeLists<T>([CanBeNull] IEnumerable<T> first,
|
public static T[] MergeLists<T>(IEnumerable<T>? first,
|
||||||
[CanBeNull] IEnumerable<T> second,
|
IEnumerable<T>? second,
|
||||||
[CanBeNull] Func<T, T, bool> isEqual = null)
|
Func<T, T, bool>? isEqual = null)
|
||||||
{
|
{
|
||||||
if (first == null)
|
if (first == null)
|
||||||
return second?.ToArray();
|
return second?.ToArray();
|
||||||
@ -66,8 +66,8 @@ namespace Kyoo.Utils
|
|||||||
/// <returns>The first dictionary with the missing elements of <paramref name="second"/>.</returns>
|
/// <returns>The first dictionary with the missing elements of <paramref name="second"/>.</returns>
|
||||||
/// <seealso cref="MergeDictionaries{T,T2}(System.Collections.Generic.IDictionary{T,T2},System.Collections.Generic.IDictionary{T,T2},out bool)"/>
|
/// <seealso cref="MergeDictionaries{T,T2}(System.Collections.Generic.IDictionary{T,T2},System.Collections.Generic.IDictionary{T,T2},out bool)"/>
|
||||||
[ContractAnnotation("first:notnull => notnull; second:notnull => notnull", true)]
|
[ContractAnnotation("first:notnull => notnull; second:notnull => notnull", true)]
|
||||||
public static IDictionary<T, T2> MergeDictionaries<T, T2>([CanBeNull] IDictionary<T, T2> first,
|
public static IDictionary<T, T2> MergeDictionaries<T, T2>(IDictionary<T, T2>? first,
|
||||||
[CanBeNull] IDictionary<T, T2> second)
|
IDictionary<T, T2>? second)
|
||||||
{
|
{
|
||||||
return MergeDictionaries(first, second, out bool _);
|
return MergeDictionaries(first, second, out bool _);
|
||||||
}
|
}
|
||||||
@ -84,8 +84,8 @@ namespace Kyoo.Utils
|
|||||||
/// <typeparam name="T2">The type of values in the dictionaries</typeparam>
|
/// <typeparam name="T2">The type of values in the dictionaries</typeparam>
|
||||||
/// <returns>The first dictionary with the missing elements of <paramref name="second"/>.</returns>
|
/// <returns>The first dictionary with the missing elements of <paramref name="second"/>.</returns>
|
||||||
[ContractAnnotation("first:notnull => notnull; second:notnull => notnull", true)]
|
[ContractAnnotation("first:notnull => notnull; second:notnull => notnull", true)]
|
||||||
public static IDictionary<T, T2> MergeDictionaries<T, T2>([CanBeNull] IDictionary<T, T2> first,
|
public static IDictionary<T, T2> MergeDictionaries<T, T2>(IDictionary<T, T2>? first,
|
||||||
[CanBeNull] IDictionary<T, T2> second,
|
IDictionary<T, T2>? second,
|
||||||
out bool hasChanged)
|
out bool hasChanged)
|
||||||
{
|
{
|
||||||
if (first == null)
|
if (first == null)
|
||||||
@ -138,8 +138,8 @@ namespace Kyoo.Utils
|
|||||||
/// set to those of <paramref name="first"/>.
|
/// set to those of <paramref name="first"/>.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
[ContractAnnotation("first:notnull => notnull; second:notnull => notnull", true)]
|
[ContractAnnotation("first:notnull => notnull; second:notnull => notnull", true)]
|
||||||
public static IDictionary<T, T2> CompleteDictionaries<T, T2>([CanBeNull] IDictionary<T, T2> first,
|
public static IDictionary<T, T2> CompleteDictionaries<T, T2>(IDictionary<T, T2>? first,
|
||||||
[CanBeNull] IDictionary<T, T2> second,
|
IDictionary<T, T2>? second,
|
||||||
out bool hasChanged)
|
out bool hasChanged)
|
||||||
{
|
{
|
||||||
if (first == null)
|
if (first == null)
|
||||||
@ -157,32 +157,6 @@ namespace Kyoo.Utils
|
|||||||
return second;
|
return second;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Set every fields of first to those of second. Ignore fields marked with the <see cref="NotMergeableAttribute"/> attribute
|
|
||||||
/// At the end, the OnMerge method of first will be called if first is a <see cref="IOnMerge"/>
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="first">The object to assign</param>
|
|
||||||
/// <param name="second">The object containing new values</param>
|
|
||||||
/// <typeparam name="T">Fields of T will be used</typeparam>
|
|
||||||
/// <returns><paramref name="first"/></returns>
|
|
||||||
public static T Assign<T>(T first, T second)
|
|
||||||
{
|
|
||||||
Type type = typeof(T);
|
|
||||||
IEnumerable<PropertyInfo> properties = type.GetProperties()
|
|
||||||
.Where(x => x.CanRead && x.CanWrite
|
|
||||||
&& Attribute.GetCustomAttribute(x, typeof(NotMergeableAttribute)) == null);
|
|
||||||
|
|
||||||
foreach (PropertyInfo property in properties)
|
|
||||||
{
|
|
||||||
object value = property.GetValue(second);
|
|
||||||
property.SetValue(first, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (first is IOnMerge merge)
|
|
||||||
merge.OnMerge(second);
|
|
||||||
return first;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set every non-default values of seconds to the corresponding property of second.
|
/// Set every non-default values of seconds to the corresponding property of second.
|
||||||
/// Dictionaries are handled like anonymous objects with a property per key/pair value
|
/// Dictionaries are handled like anonymous objects with a property per key/pair value
|
||||||
@ -210,8 +184,8 @@ namespace Kyoo.Utils
|
|||||||
/// <returns><paramref name="first"/></returns>
|
/// <returns><paramref name="first"/></returns>
|
||||||
/// <exception cref="ArgumentNullException">If first is null</exception>
|
/// <exception cref="ArgumentNullException">If first is null</exception>
|
||||||
public static T Complete<T>([NotNull] T first,
|
public static T Complete<T>([NotNull] T first,
|
||||||
[CanBeNull] T second,
|
T? second,
|
||||||
[InstantHandle] Func<PropertyInfo, bool> where = null)
|
[InstantHandle] Func<PropertyInfo, bool>? where = null)
|
||||||
{
|
{
|
||||||
if (first == null)
|
if (first == null)
|
||||||
throw new ArgumentNullException(nameof(first));
|
throw new ArgumentNullException(nameof(first));
|
||||||
@ -281,9 +255,9 @@ namespace Kyoo.Utils
|
|||||||
/// <typeparam name="T">Fields of T will be merged</typeparam>
|
/// <typeparam name="T">Fields of T will be merged</typeparam>
|
||||||
/// <returns><paramref name="first"/></returns>
|
/// <returns><paramref name="first"/></returns>
|
||||||
[ContractAnnotation("first:notnull => notnull; second:notnull => notnull", true)]
|
[ContractAnnotation("first:notnull => notnull; second:notnull => notnull", true)]
|
||||||
public static T Merge<T>([CanBeNull] T first,
|
public static T Merge<T>(T? first,
|
||||||
[CanBeNull] T second,
|
T? second,
|
||||||
[InstantHandle] Func<PropertyInfo, bool> where = null)
|
[InstantHandle] Func<PropertyInfo, bool>? where = null)
|
||||||
{
|
{
|
||||||
if (first == null)
|
if (first == null)
|
||||||
return second;
|
return second;
|
||||||
|
@ -77,8 +77,7 @@ namespace Kyoo.Utils
|
|||||||
/// <param name="value">The initial task</param>
|
/// <param name="value">The initial task</param>
|
||||||
/// <typeparam name="T">The type that the task will return</typeparam>
|
/// <typeparam name="T">The type that the task will return</typeparam>
|
||||||
/// <returns>A non-null task.</returns>
|
/// <returns>A non-null task.</returns>
|
||||||
[NotNull]
|
public static Task<T> DefaultIfNull<T>(Task<T>? value)
|
||||||
public static Task<T> DefaultIfNull<T>([CanBeNull] Task<T> value)
|
|
||||||
{
|
{
|
||||||
return value ?? Task.FromResult<T>(default);
|
return value ?? Task.FromResult<T>(default);
|
||||||
}
|
}
|
||||||
|
@ -63,34 +63,12 @@ namespace Kyoo.Utils
|
|||||||
return member!.Member.Name;
|
return member!.Member.Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get the value of a member (property or field)
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="member">The member value</param>
|
|
||||||
/// <param name="obj">The owner of this member</param>
|
|
||||||
/// <returns>The value boxed as an object</returns>
|
|
||||||
/// <exception cref="ArgumentNullException">if <paramref name="member"/> or <paramref name="obj"/> is null.</exception>
|
|
||||||
/// <exception cref="ArgumentException">The member is not a field or a property.</exception>
|
|
||||||
public static object GetValue([NotNull] this MemberInfo member, [NotNull] object obj)
|
|
||||||
{
|
|
||||||
if (member == null)
|
|
||||||
throw new ArgumentNullException(nameof(member));
|
|
||||||
if (obj == null)
|
|
||||||
throw new ArgumentNullException(nameof(obj));
|
|
||||||
return member switch
|
|
||||||
{
|
|
||||||
PropertyInfo property => property.GetValue(obj),
|
|
||||||
FieldInfo field => field.GetValue(obj),
|
|
||||||
_ => throw new ArgumentException($"Can't get value of a non property/field (member: {member}).")
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Slugify a string (Replace spaces by -, Uniformize accents)
|
/// Slugify a string (Replace spaces by -, Uniformize accents)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="str">The string to slugify</param>
|
/// <param name="str">The string to slugify</param>
|
||||||
/// <returns>The slug version of the given string</returns>
|
/// <returns>The slug version of the given string</returns>
|
||||||
public static string ToSlug([CanBeNull] string str)
|
public static string ToSlug(string? str)
|
||||||
{
|
{
|
||||||
if (str == null)
|
if (str == null)
|
||||||
return null;
|
return null;
|
||||||
@ -132,7 +110,7 @@ namespace Kyoo.Utils
|
|||||||
/// <param name="type">The starting type</param>
|
/// <param name="type">The starting type</param>
|
||||||
/// <returns>A list of types</returns>
|
/// <returns>A list of types</returns>
|
||||||
/// <exception cref="ArgumentNullException"><paramref name="type"/> can't be null</exception>
|
/// <exception cref="ArgumentNullException"><paramref name="type"/> can't be null</exception>
|
||||||
public static IEnumerable<Type> GetInheritanceTree([NotNull] this Type type)
|
public static IEnumerable<Type> GetInheritanceTree(this Type type)
|
||||||
{
|
{
|
||||||
if (type == null)
|
if (type == null)
|
||||||
throw new ArgumentNullException(nameof(type));
|
throw new ArgumentNullException(nameof(type));
|
||||||
@ -140,20 +118,6 @@ namespace Kyoo.Utils
|
|||||||
yield return type;
|
yield return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Check if <paramref name="obj"/> inherit from a generic type <paramref name="genericType"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="obj">Does this object's type is a <paramref name="genericType"/></param>
|
|
||||||
/// <param name="genericType">The generic type to check against (Only generic types are supported like typeof(IEnumerable<>).</param>
|
|
||||||
/// <returns>True if obj inherit from genericType. False otherwise</returns>
|
|
||||||
/// <exception cref="ArgumentNullException">obj and genericType can't be null</exception>
|
|
||||||
public static bool IsOfGenericType([NotNull] object obj, [NotNull] Type genericType)
|
|
||||||
{
|
|
||||||
if (obj == null)
|
|
||||||
throw new ArgumentNullException(nameof(obj));
|
|
||||||
return IsOfGenericType(obj.GetType(), genericType);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Check if <paramref name="type"/> inherit from a generic type <paramref name="genericType"/>.
|
/// Check if <paramref name="type"/> inherit from a generic type <paramref name="genericType"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -161,7 +125,7 @@ namespace Kyoo.Utils
|
|||||||
/// <param name="genericType">The generic type to check against (Only generic types are supported like typeof(IEnumerable<>).</param>
|
/// <param name="genericType">The generic type to check against (Only generic types are supported like typeof(IEnumerable<>).</param>
|
||||||
/// <returns>True if obj inherit from genericType. False otherwise</returns>
|
/// <returns>True if obj inherit from genericType. False otherwise</returns>
|
||||||
/// <exception cref="ArgumentNullException">obj and genericType can't be null</exception>
|
/// <exception cref="ArgumentNullException">obj and genericType can't be null</exception>
|
||||||
public static bool IsOfGenericType([NotNull] Type type, [NotNull] Type genericType)
|
public static bool IsOfGenericType(Type type, Type genericType)
|
||||||
{
|
{
|
||||||
if (type == null)
|
if (type == null)
|
||||||
throw new ArgumentNullException(nameof(type));
|
throw new ArgumentNullException(nameof(type));
|
||||||
@ -186,7 +150,7 @@ namespace Kyoo.Utils
|
|||||||
/// <returns>The generic definition of genericType that type inherit or null if type does not implement the generic type.</returns>
|
/// <returns>The generic definition of genericType that type inherit or null if type does not implement the generic type.</returns>
|
||||||
/// <exception cref="ArgumentNullException"><paramref name="type"/> and <paramref name="genericType"/> can't be null</exception>
|
/// <exception cref="ArgumentNullException"><paramref name="type"/> and <paramref name="genericType"/> can't be null</exception>
|
||||||
/// <exception cref="ArgumentException"><paramref name="genericType"/> must be a generic type</exception>
|
/// <exception cref="ArgumentException"><paramref name="genericType"/> must be a generic type</exception>
|
||||||
public static Type GetGenericDefinition([NotNull] Type type, [NotNull] Type genericType)
|
public static Type GetGenericDefinition(Type type, Type genericType)
|
||||||
{
|
{
|
||||||
if (type == null)
|
if (type == null)
|
||||||
throw new ArgumentNullException(nameof(type));
|
throw new ArgumentNullException(nameof(type));
|
||||||
@ -224,12 +188,11 @@ namespace Kyoo.Utils
|
|||||||
/// <exception cref="ArgumentException">No method match the given constraints.</exception>
|
/// <exception cref="ArgumentException">No method match the given constraints.</exception>
|
||||||
/// <returns>The method handle of the matching method.</returns>
|
/// <returns>The method handle of the matching method.</returns>
|
||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
[NotNull]
|
public static MethodInfo GetMethod(Type type,
|
||||||
public static MethodInfo GetMethod([NotNull] Type type,
|
|
||||||
BindingFlags flag,
|
BindingFlags flag,
|
||||||
string name,
|
string name,
|
||||||
[NotNull] Type[] generics,
|
Type[] generics,
|
||||||
[NotNull] object[] args)
|
object[] args)
|
||||||
{
|
{
|
||||||
if (type == null)
|
if (type == null)
|
||||||
throw new ArgumentNullException(nameof(type));
|
throw new ArgumentNullException(nameof(type));
|
||||||
@ -297,9 +260,9 @@ namespace Kyoo.Utils
|
|||||||
/// <seealso cref="RunGenericMethod{T}(object,string,System.Type,object[])"/>
|
/// <seealso cref="RunGenericMethod{T}(object,string,System.Type,object[])"/>
|
||||||
/// <seealso cref="RunGenericMethod{T}(System.Type,string,System.Type[],object[])"/>
|
/// <seealso cref="RunGenericMethod{T}(System.Type,string,System.Type[],object[])"/>
|
||||||
public static T RunGenericMethod<T>(
|
public static T RunGenericMethod<T>(
|
||||||
[NotNull] Type owner,
|
Type owner,
|
||||||
[NotNull] string methodName,
|
string methodName,
|
||||||
[NotNull] Type type,
|
Type type,
|
||||||
params object[] args)
|
params object[] args)
|
||||||
{
|
{
|
||||||
return RunGenericMethod<T>(owner, methodName, new[] { type }, args);
|
return RunGenericMethod<T>(owner, methodName, new[] { type }, args);
|
||||||
@ -334,9 +297,9 @@ namespace Kyoo.Utils
|
|||||||
/// <seealso cref="RunGenericMethod{T}(System.Type,string,System.Type,object[])"/>
|
/// <seealso cref="RunGenericMethod{T}(System.Type,string,System.Type,object[])"/>
|
||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public static T RunGenericMethod<T>(
|
public static T RunGenericMethod<T>(
|
||||||
[NotNull] Type owner,
|
Type owner,
|
||||||
[NotNull] string methodName,
|
string methodName,
|
||||||
[NotNull] Type[] types,
|
Type[] types,
|
||||||
params object[] args)
|
params object[] args)
|
||||||
{
|
{
|
||||||
if (owner == null)
|
if (owner == null)
|
||||||
@ -351,83 +314,6 @@ namespace Kyoo.Utils
|
|||||||
return (T)method.MakeGenericMethod(types).Invoke(null, args);
|
return (T)method.MakeGenericMethod(types).Invoke(null, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Run a generic method for a runtime <see cref="Type"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <example>
|
|
||||||
/// To run <see cref="Merger.MergeLists{T}"/> for a List where you don't know the type at compile type,
|
|
||||||
/// you could do:
|
|
||||||
/// <code>
|
|
||||||
/// Utility.RunGenericMethod<object>(
|
|
||||||
/// typeof(Utility),
|
|
||||||
/// nameof(MergeLists),
|
|
||||||
/// enumerableType,
|
|
||||||
/// oldValue, newValue, equalityComparer)
|
|
||||||
/// </code>
|
|
||||||
/// </example>
|
|
||||||
/// <param name="instance">The <c>this</c> of the method to run.</param>
|
|
||||||
/// <param name="methodName">The name of the method. You should use the <c>nameof</c> keyword.</param>
|
|
||||||
/// <param name="type">The generic type to run the method with.</param>
|
|
||||||
/// <param name="args">The list of arguments of the method</param>
|
|
||||||
/// <typeparam name="T">
|
|
||||||
/// The return type of the method. You can put <see cref="object"/> for an unknown one.
|
|
||||||
/// </typeparam>
|
|
||||||
/// <exception cref="ArgumentException">No method match the given constraints.</exception>
|
|
||||||
/// <returns>The return of the method you wanted to run.</returns>
|
|
||||||
/// <seealso cref="RunGenericMethod{T}(object,string,System.Type,object[])"/>
|
|
||||||
/// <seealso cref="RunGenericMethod{T}(System.Type,string,System.Type[],object[])"/>
|
|
||||||
public static T RunGenericMethod<T>(
|
|
||||||
[NotNull] object instance,
|
|
||||||
[NotNull] string methodName,
|
|
||||||
[NotNull] Type type,
|
|
||||||
params object[] args)
|
|
||||||
{
|
|
||||||
return RunGenericMethod<T>(instance, methodName, new[] { type }, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Run a generic method for a multiple runtime <see cref="Type"/>.
|
|
||||||
/// If your generic method only needs one type, see
|
|
||||||
/// <see cref="RunGenericMethod{T}(object,string,System.Type,object[])"/>
|
|
||||||
/// </summary>
|
|
||||||
/// <example>
|
|
||||||
/// To run <see cref="Merger.MergeLists{T}"/> for a List where you don't know the type at compile type,
|
|
||||||
/// you could do:
|
|
||||||
/// <code>
|
|
||||||
/// Utility.RunGenericMethod<object>(
|
|
||||||
/// typeof(Utility),
|
|
||||||
/// nameof(MergeLists),
|
|
||||||
/// enumerableType,
|
|
||||||
/// oldValue, newValue, equalityComparer)
|
|
||||||
/// </code>
|
|
||||||
/// </example>
|
|
||||||
/// <param name="instance">The <c>this</c> of the method to run.</param>
|
|
||||||
/// <param name="methodName">The name of the method. You should use the <c>nameof</c> keyword.</param>
|
|
||||||
/// <param name="types">The list of generic types to run the method with.</param>
|
|
||||||
/// <param name="args">The list of arguments of the method</param>
|
|
||||||
/// <typeparam name="T">
|
|
||||||
/// The return type of the method. You can put <see cref="object"/> for an unknown one.
|
|
||||||
/// </typeparam>
|
|
||||||
/// <exception cref="ArgumentException">No method match the given constraints.</exception>
|
|
||||||
/// <returns>The return of the method you wanted to run.</returns>
|
|
||||||
/// <seealso cref="RunGenericMethod{T}(object,string,System.Type[],object[])"/>
|
|
||||||
/// <seealso cref="RunGenericMethod{T}(System.Type,string,System.Type,object[])"/>
|
|
||||||
public static T RunGenericMethod<T>(
|
|
||||||
[NotNull] object instance,
|
|
||||||
[NotNull] string methodName,
|
|
||||||
[NotNull] Type[] types,
|
|
||||||
params object[] args)
|
|
||||||
{
|
|
||||||
if (instance == null)
|
|
||||||
throw new ArgumentNullException(nameof(instance));
|
|
||||||
if (methodName == null)
|
|
||||||
throw new ArgumentNullException(nameof(methodName));
|
|
||||||
if (types == null || types.Length == 0)
|
|
||||||
throw new ArgumentNullException(nameof(types));
|
|
||||||
MethodInfo method = GetMethod(instance.GetType(), BindingFlags.Instance, methodName, types, args);
|
|
||||||
return (T)method.MakeGenericMethod(types).Invoke(instance, args.ToArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Convert a dictionary to a query string.
|
/// Convert a dictionary to a query string.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -446,25 +332,11 @@ namespace Kyoo.Utils
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ex">The exception to rethrow.</param>
|
/// <param name="ex">The exception to rethrow.</param>
|
||||||
[System.Diagnostics.CodeAnalysis.DoesNotReturn]
|
[System.Diagnostics.CodeAnalysis.DoesNotReturn]
|
||||||
public static void ReThrow([NotNull] this Exception ex)
|
public static void ReThrow(this Exception ex)
|
||||||
{
|
{
|
||||||
if (ex == null)
|
if (ex == null)
|
||||||
throw new ArgumentNullException(nameof(ex));
|
throw new ArgumentNullException(nameof(ex));
|
||||||
ExceptionDispatchInfo.Capture(ex).Throw();
|
ExceptionDispatchInfo.Capture(ex).Throw();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get a friendly type name (supporting generics)
|
|
||||||
/// For example a list of string will be displayed as List<string> and not as List`1.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="type">The type to use</param>
|
|
||||||
/// <returns>The friendly name of the type</returns>
|
|
||||||
public static string FriendlyName(this Type type)
|
|
||||||
{
|
|
||||||
if (!type.IsGenericType)
|
|
||||||
return type.Name;
|
|
||||||
string generics = string.Join(", ", type.GetGenericArguments().Select(x => x.FriendlyName()));
|
|
||||||
return $"{type.Name[..type.Name.IndexOf('`')]}<{generics}>";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,6 @@ namespace Kyoo.Authentication.Models.DTO
|
|||||||
Username = Username,
|
Username = Username,
|
||||||
Password = BCryptNet.HashPassword(Password),
|
Password = BCryptNet.HashPassword(Password),
|
||||||
Email = Email,
|
Email = Email,
|
||||||
ExtraData = new Dictionary<string, string>()
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,15 +39,15 @@ namespace Kyoo.Core.Controllers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly IBaseRepository[] _repositories;
|
private readonly IBaseRepository[] _repositories;
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public ILibraryRepository LibraryRepository { get; }
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public ILibraryItemRepository LibraryItemRepository { get; }
|
public ILibraryItemRepository LibraryItemRepository { get; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public ICollectionRepository CollectionRepository { get; }
|
public ICollectionRepository CollectionRepository { get; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public IMovieRepository MovieRepository { get; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public IShowRepository ShowRepository { get; }
|
public IShowRepository ShowRepository { get; }
|
||||||
|
|
||||||
@ -63,9 +63,6 @@ namespace Kyoo.Core.Controllers
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public IStudioRepository StudioRepository { get; }
|
public IStudioRepository StudioRepository { get; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public IGenreRepository GenreRepository { get; }
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public IUserRepository UserRepository { get; }
|
public IUserRepository UserRepository { get; }
|
||||||
|
|
||||||
@ -77,15 +74,14 @@ namespace Kyoo.Core.Controllers
|
|||||||
public LibraryManager(IEnumerable<IBaseRepository> repositories)
|
public LibraryManager(IEnumerable<IBaseRepository> repositories)
|
||||||
{
|
{
|
||||||
_repositories = repositories.ToArray();
|
_repositories = repositories.ToArray();
|
||||||
LibraryRepository = GetRepository<Library>() as ILibraryRepository;
|
LibraryItemRepository = GetRepository<ILibraryItem>() as ILibraryItemRepository;
|
||||||
LibraryItemRepository = GetRepository<LibraryItem>() as ILibraryItemRepository;
|
|
||||||
CollectionRepository = GetRepository<Collection>() as ICollectionRepository;
|
CollectionRepository = GetRepository<Collection>() as ICollectionRepository;
|
||||||
|
MovieRepository = GetRepository<Movie>() as IMovieRepository;
|
||||||
ShowRepository = GetRepository<Show>() as IShowRepository;
|
ShowRepository = GetRepository<Show>() as IShowRepository;
|
||||||
SeasonRepository = GetRepository<Season>() as ISeasonRepository;
|
SeasonRepository = GetRepository<Season>() as ISeasonRepository;
|
||||||
EpisodeRepository = GetRepository<Episode>() as IEpisodeRepository;
|
EpisodeRepository = GetRepository<Episode>() as IEpisodeRepository;
|
||||||
PeopleRepository = GetRepository<People>() as IPeopleRepository;
|
PeopleRepository = GetRepository<People>() as IPeopleRepository;
|
||||||
StudioRepository = GetRepository<Studio>() as IStudioRepository;
|
StudioRepository = GetRepository<Studio>() as IStudioRepository;
|
||||||
GenreRepository = GetRepository<Genre>() as IGenreRepository;
|
|
||||||
UserRepository = GetRepository<User>() as IUserRepository;
|
UserRepository = GetRepository<User>() as IUserRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -255,28 +251,10 @@ namespace Kyoo.Core.Controllers
|
|||||||
|
|
||||||
return (obj, member: memberName) switch
|
return (obj, member: memberName) switch
|
||||||
{
|
{
|
||||||
(Library l, nameof(Library.Shows)) => ShowRepository
|
|
||||||
.GetAll(x => x.Libraries.Any(y => y.ID == obj.ID))
|
|
||||||
.Then(x => l.Shows = x),
|
|
||||||
|
|
||||||
(Library l, nameof(Library.Collections)) => CollectionRepository
|
|
||||||
.GetAll(x => x.Libraries.Any(y => y.ID == obj.ID))
|
|
||||||
.Then(x => l.Collections = x),
|
|
||||||
|
|
||||||
|
|
||||||
(Collection c, nameof(Collection.Shows)) => ShowRepository
|
(Collection c, nameof(Collection.Shows)) => ShowRepository
|
||||||
.GetAll(x => x.Collections.Any(y => y.ID == obj.ID))
|
.GetAll(x => x.Collections.Any(y => y.ID == obj.ID))
|
||||||
.Then(x => c.Shows = x),
|
.Then(x => c.Shows = x),
|
||||||
|
|
||||||
(Collection c, nameof(Collection.Libraries)) => LibraryRepository
|
|
||||||
.GetAll(x => x.Collections.Any(y => y.ID == obj.ID))
|
|
||||||
.Then(x => c.Libraries = x),
|
|
||||||
|
|
||||||
|
|
||||||
(Show s, nameof(Show.Genres)) => GenreRepository
|
|
||||||
.GetAll(x => x.Shows.Any(y => y.ID == obj.ID))
|
|
||||||
.Then(x => s.Genres = x),
|
|
||||||
|
|
||||||
(Show s, nameof(Show.People)) => PeopleRepository
|
(Show s, nameof(Show.People)) => PeopleRepository
|
||||||
.GetFromShow(obj.ID)
|
.GetFromShow(obj.ID)
|
||||||
.Then(x => s.People = x),
|
.Then(x => s.People = x),
|
||||||
@ -291,10 +269,6 @@ namespace Kyoo.Core.Controllers
|
|||||||
(x, y) => x.Episodes = y,
|
(x, y) => x.Episodes = y,
|
||||||
(x, y) => { x.Show = y; x.ShowID = y.ID; }),
|
(x, y) => { x.Show = y; x.ShowID = y.ID; }),
|
||||||
|
|
||||||
(Show s, nameof(Show.Libraries)) => LibraryRepository
|
|
||||||
.GetAll(x => x.Shows.Any(y => y.ID == obj.ID))
|
|
||||||
.Then(x => s.Libraries = x),
|
|
||||||
|
|
||||||
(Show s, nameof(Show.Collections)) => CollectionRepository
|
(Show s, nameof(Show.Collections)) => CollectionRepository
|
||||||
.GetAll(x => x.Shows.Any(y => y.ID == obj.ID))
|
.GetAll(x => x.Shows.Any(y => y.ID == obj.ID))
|
||||||
.Then(x => s.Collections = x),
|
.Then(x => s.Collections = x),
|
||||||
@ -339,11 +313,6 @@ namespace Kyoo.Core.Controllers
|
|||||||
}),
|
}),
|
||||||
|
|
||||||
|
|
||||||
(Genre g, nameof(Genre.Shows)) => ShowRepository
|
|
||||||
.GetAll(x => x.Genres.Any(y => y.ID == obj.ID))
|
|
||||||
.Then(x => g.Shows = x),
|
|
||||||
|
|
||||||
|
|
||||||
(Studio s, nameof(Studio.Shows)) => ShowRepository
|
(Studio s, nameof(Studio.Shows)) => ShowRepository
|
||||||
.GetAll(x => x.Studio.ID == obj.ID)
|
.GetAll(x => x.Studio.ID == obj.ID)
|
||||||
.Then(x => s.Shows = x),
|
.Then(x => s.Shows = x),
|
||||||
@ -356,24 +325,6 @@ namespace Kyoo.Core.Controllers
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public Task<ICollection<LibraryItem>> GetItemsFromLibrary(int id,
|
|
||||||
Expression<Func<LibraryItem, bool>> where = null,
|
|
||||||
Sort<LibraryItem> sort = default,
|
|
||||||
Pagination limit = default)
|
|
||||||
{
|
|
||||||
return LibraryItemRepository.GetFromLibrary(id, where, sort, limit);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public Task<ICollection<LibraryItem>> GetItemsFromLibrary(string slug,
|
|
||||||
Expression<Func<LibraryItem, bool>> where = null,
|
|
||||||
Sort<LibraryItem> sort = default,
|
|
||||||
Pagination limit = default)
|
|
||||||
{
|
|
||||||
return LibraryItemRepository.GetFromLibrary(slug, where, sort, limit);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public Task<ICollection<PeopleRole>> GetPeopleFromShow(int showID,
|
public Task<ICollection<PeopleRole>> GetPeopleFromShow(int showID,
|
||||||
Expression<Func<PeopleRole, bool>> where = null,
|
Expression<Func<PeopleRole, bool>> where = null,
|
||||||
@ -410,20 +361,6 @@ namespace Kyoo.Core.Controllers
|
|||||||
return PeopleRepository.GetFromPeople(slug, where, sort, limit);
|
return PeopleRepository.GetFromPeople(slug, where, sort, limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public Task AddShowLink(int showID, int? libraryID, int? collectionID)
|
|
||||||
{
|
|
||||||
return ShowRepository.AddShowLink(showID, libraryID, collectionID);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public Task AddShowLink(Show show, Library library, Collection collection)
|
|
||||||
{
|
|
||||||
if (show == null)
|
|
||||||
throw new ArgumentNullException(nameof(show));
|
|
||||||
return ShowRepository.AddShowLink(show.ID, library?.ID, collection?.ID);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public Task<ICollection<T>> GetAll<T>(Expression<Func<T, bool>> where = null,
|
public Task<ICollection<T>> GetAll<T>(Expression<Func<T, bool>> where = null,
|
||||||
Sort<T> sort = default,
|
Sort<T> sort = default,
|
||||||
|
@ -129,7 +129,7 @@ namespace Kyoo.Core.Controllers
|
|||||||
_database.Episodes
|
_database.Episodes
|
||||||
.Include(x => x.Show)
|
.Include(x => x.Show)
|
||||||
.Where(x => x.EpisodeNumber != null || x.AbsoluteNumber != null)
|
.Where(x => x.EpisodeNumber != null || x.AbsoluteNumber != null)
|
||||||
.Where(_database.Like<Episode>(x => x.Title, $"%{query}%"))
|
.Where(_database.Like<Episode>(x => x.Name, $"%{query}%"))
|
||||||
)
|
)
|
||||||
.Take(20)
|
.Take(20)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
@ -1,93 +0,0 @@
|
|||||||
// 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 System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Kyoo.Abstractions.Controllers;
|
|
||||||
using Kyoo.Abstractions.Models;
|
|
||||||
using Kyoo.Postgresql;
|
|
||||||
using Kyoo.Utils;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
|
|
||||||
namespace Kyoo.Core.Controllers
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// A local repository for genres.
|
|
||||||
/// </summary>
|
|
||||||
public class GenreRepository : LocalRepository<Genre>, IGenreRepository
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The database handle
|
|
||||||
/// </summary>
|
|
||||||
private readonly DatabaseContext _database;
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override Sort<Genre> DefaultSort => new Sort<Genre>.By(x => x.Slug);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create a new <see cref="GenreRepository"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="database">The database handle</param>
|
|
||||||
public GenreRepository(DatabaseContext database)
|
|
||||||
: base(database)
|
|
||||||
{
|
|
||||||
_database = database;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override async Task<ICollection<Genre>> Search(string query)
|
|
||||||
{
|
|
||||||
return await Sort(
|
|
||||||
_database.Genres
|
|
||||||
.Where(_database.Like<Genre>(x => x.Name, $"%{query}%"))
|
|
||||||
)
|
|
||||||
.Take(20)
|
|
||||||
.ToListAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override async Task Validate(Genre resource)
|
|
||||||
{
|
|
||||||
resource.Slug ??= Utility.ToSlug(resource.Name);
|
|
||||||
await base.Validate(resource);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override async Task<Genre> Create(Genre obj)
|
|
||||||
{
|
|
||||||
await base.Create(obj);
|
|
||||||
_database.Entry(obj).State = EntityState.Added;
|
|
||||||
await _database.SaveChangesAsync(() => Get(obj.Slug));
|
|
||||||
OnResourceCreated(obj);
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override async Task Delete(Genre obj)
|
|
||||||
{
|
|
||||||
if (obj == null)
|
|
||||||
throw new ArgumentNullException(nameof(obj));
|
|
||||||
|
|
||||||
_database.Entry(obj).State = EntityState.Deleted;
|
|
||||||
await _database.SaveChangesAsync();
|
|
||||||
await base.Delete(obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -23,7 +23,6 @@ using System.Linq.Expressions;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Kyoo.Abstractions.Controllers;
|
using Kyoo.Abstractions.Controllers;
|
||||||
using Kyoo.Abstractions.Models;
|
using Kyoo.Abstractions.Models;
|
||||||
using Kyoo.Abstractions.Models.Exceptions;
|
|
||||||
using Kyoo.Postgresql;
|
using Kyoo.Postgresql;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
@ -32,84 +31,80 @@ namespace Kyoo.Core.Controllers
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// A local repository to handle library items.
|
/// A local repository to handle library items.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class LibraryItemRepository : LocalRepository<LibraryItem>, ILibraryItemRepository
|
public class LibraryItemRepository : LocalRepository<ILibraryItem>, ILibraryItemRepository
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The database handle
|
/// The database handle
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly DatabaseContext _database;
|
private readonly DatabaseContext _database;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A lazy loaded library repository to validate queries (check if a library does exist)
|
|
||||||
/// </summary>
|
|
||||||
private readonly Lazy<ILibraryRepository> _libraries;
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override Sort<LibraryItem> DefaultSort => new Sort<LibraryItem>.By(x => x.Title);
|
protected override Sort<ILibraryItem> DefaultSort => new Sort<ILibraryItem>.By(x => x.Name);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a new <see cref="LibraryItemRepository"/>.
|
/// Create a new <see cref="ILibraryItemRepository"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="database">The database instance</param>
|
/// <param name="database">The database instance</param>
|
||||||
/// <param name="libraries">A lazy loaded library repository</param>
|
public LibraryItemRepository(DatabaseContext database)
|
||||||
public LibraryItemRepository(DatabaseContext database,
|
|
||||||
Lazy<ILibraryRepository> libraries)
|
|
||||||
: base(database)
|
: base(database)
|
||||||
{
|
{
|
||||||
_database = database;
|
_database = database;
|
||||||
_libraries = libraries;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override Task<LibraryItem> GetOrDefault(int id)
|
public override async Task<ILibraryItem> GetOrDefault(int id)
|
||||||
{
|
{
|
||||||
return _database.LibraryItems.FirstOrDefaultAsync(x => x.ID == id);
|
return (await _database.LibraryItems.FirstOrDefaultAsync(x => x.ID == id)).ToItem();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override Task<LibraryItem> GetOrDefault(string slug)
|
public override async Task<ILibraryItem> GetOrDefault(string slug)
|
||||||
{
|
{
|
||||||
return _database.LibraryItems.SingleOrDefaultAsync(x => x.Slug == slug);
|
return (await _database.LibraryItems.SingleOrDefaultAsync(x => x.Slug == slug)).ToItem();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override Task<ICollection<LibraryItem>> GetAll(Expression<Func<LibraryItem, bool>> where = null,
|
public override async Task<ICollection<ILibraryItem>> GetAll(Expression<Func<ILibraryItem, bool>> where = null,
|
||||||
Sort<LibraryItem> sort = default,
|
Sort<ILibraryItem> sort = default,
|
||||||
Pagination limit = default)
|
Pagination limit = default)
|
||||||
{
|
{
|
||||||
return ApplyFilters(_database.LibraryItems, where, sort, limit);
|
return (await ApplyFilters(_database.LibraryItems, where, sort, limit))
|
||||||
|
.Select(x => (x as BagItem)!.ToItem())
|
||||||
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override Task<int> GetCount(Expression<Func<LibraryItem, bool>> where = null)
|
public override Task<int> GetCount(Expression<Func<ILibraryItem, bool>> where = null)
|
||||||
{
|
{
|
||||||
IQueryable<LibraryItem> query = _database.LibraryItems;
|
IQueryable<ILibraryItem> query = _database.LibraryItems;
|
||||||
if (where != null)
|
if (where != null)
|
||||||
query = query.Where(where);
|
query = query.Where(where);
|
||||||
return query.CountAsync();
|
return query.CountAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override async Task<ICollection<LibraryItem>> Search(string query)
|
public override async Task<ICollection<ILibraryItem>> Search(string query)
|
||||||
{
|
{
|
||||||
return await Sort(
|
return (await Sort(
|
||||||
_database.LibraryItems
|
_database.LibraryItems
|
||||||
.Where(_database.Like<LibraryItem>(x => x.Title, $"%{query}%"))
|
.Where(_database.Like<ILibraryItem>(x => x.Name, $"%{query}%"))
|
||||||
)
|
)
|
||||||
.Take(20)
|
.Take(20)
|
||||||
.ToListAsync();
|
.ToListAsync())
|
||||||
|
.Select(x => (x as BagItem)!.ToItem())
|
||||||
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override Task<LibraryItem> Create(LibraryItem obj)
|
public override Task<ILibraryItem> Create(ILibraryItem obj)
|
||||||
=> throw new InvalidOperationException();
|
=> throw new InvalidOperationException();
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override Task<LibraryItem> CreateIfNotExists(LibraryItem obj)
|
public override Task<ILibraryItem> CreateIfNotExists(ILibraryItem obj)
|
||||||
=> throw new InvalidOperationException();
|
=> throw new InvalidOperationException();
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override Task<LibraryItem> Edit(LibraryItem obj, bool resetOld)
|
public override Task<ILibraryItem> Edit(ILibraryItem obj, bool resetOld)
|
||||||
=> throw new InvalidOperationException();
|
=> throw new InvalidOperationException();
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@ -121,58 +116,7 @@ namespace Kyoo.Core.Controllers
|
|||||||
=> throw new InvalidOperationException();
|
=> throw new InvalidOperationException();
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override Task Delete(LibraryItem obj)
|
public override Task Delete(ILibraryItem obj)
|
||||||
=> throw new InvalidOperationException();
|
=> throw new InvalidOperationException();
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get a basic queryable for a library with the right mapping from shows and collections.
|
|
||||||
/// Shows contained in a collection are excluded.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="selector">Only items that are part of a library that match this predicate will be returned.</param>
|
|
||||||
/// <returns>A queryable containing items that are part of a library matching the selector.</returns>
|
|
||||||
private IQueryable<LibraryItem> _LibraryRelatedQuery(Expression<Func<Library, bool>> selector)
|
|
||||||
=> _database.Libraries
|
|
||||||
.Where(selector)
|
|
||||||
.SelectMany(x => x.Shows)
|
|
||||||
.Where(x => !x.Collections.Any())
|
|
||||||
.Select(LibraryItem.FromShow)
|
|
||||||
.Concat(_database.Libraries
|
|
||||||
.Where(selector)
|
|
||||||
.SelectMany(x => x.Collections)
|
|
||||||
.Select(LibraryItem.FromCollection));
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public async Task<ICollection<LibraryItem>> GetFromLibrary(int id,
|
|
||||||
Expression<Func<LibraryItem, bool>> where = null,
|
|
||||||
Sort<LibraryItem> sort = default,
|
|
||||||
Pagination limit = default)
|
|
||||||
{
|
|
||||||
ICollection<LibraryItem> items = await ApplyFilters(
|
|
||||||
_LibraryRelatedQuery(x => x.ID == id),
|
|
||||||
where,
|
|
||||||
sort,
|
|
||||||
limit
|
|
||||||
);
|
|
||||||
if (!items.Any() && await _libraries.Value.GetOrDefault(id) == null)
|
|
||||||
throw new ItemNotFoundException();
|
|
||||||
return items;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public async Task<ICollection<LibraryItem>> GetFromLibrary(string slug,
|
|
||||||
Expression<Func<LibraryItem, bool>> where = null,
|
|
||||||
Sort<LibraryItem> sort = default,
|
|
||||||
Pagination limit = default)
|
|
||||||
{
|
|
||||||
ICollection<LibraryItem> items = await ApplyFilters(
|
|
||||||
_LibraryRelatedQuery(x => x.Slug == slug),
|
|
||||||
where,
|
|
||||||
sort,
|
|
||||||
limit
|
|
||||||
);
|
|
||||||
if (!items.Any() && await _libraries.Value.GetOrDefault(slug) == null)
|
|
||||||
throw new ItemNotFoundException();
|
|
||||||
return items;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,99 +0,0 @@
|
|||||||
// 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 System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Kyoo.Abstractions.Controllers;
|
|
||||||
using Kyoo.Abstractions.Models;
|
|
||||||
using Kyoo.Postgresql;
|
|
||||||
using Kyoo.Utils;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
|
|
||||||
namespace Kyoo.Core.Controllers
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// A local repository to handle libraries.
|
|
||||||
/// </summary>
|
|
||||||
public class LibraryRepository : LocalRepository<Library>, ILibraryRepository
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The database handle
|
|
||||||
/// </summary>
|
|
||||||
private readonly DatabaseContext _database;
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override Sort<Library> DefaultSort => new Sort<Library>.By(x => x.ID);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create a new <see cref="LibraryRepository"/> instance.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="database">The database handle</param>
|
|
||||||
public LibraryRepository(DatabaseContext database)
|
|
||||||
: base(database)
|
|
||||||
{
|
|
||||||
_database = database;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override async Task<ICollection<Library>> Search(string query)
|
|
||||||
{
|
|
||||||
return await Sort(
|
|
||||||
_database.Libraries
|
|
||||||
.Where(_database.Like<Library>(x => x.Name + " " + x.Slug, $"%{query}%"))
|
|
||||||
)
|
|
||||||
.Take(20)
|
|
||||||
.ToListAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override async Task<Library> Create(Library obj)
|
|
||||||
{
|
|
||||||
await base.Create(obj);
|
|
||||||
_database.Entry(obj).State = EntityState.Added;
|
|
||||||
await _database.SaveChangesAsync(() => Get(obj.Slug));
|
|
||||||
OnResourceCreated(obj);
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override async Task Validate(Library resource)
|
|
||||||
{
|
|
||||||
await base.Validate(resource);
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(resource.Slug))
|
|
||||||
throw new ArgumentException("The library's slug must be set and not empty");
|
|
||||||
if (string.IsNullOrEmpty(resource.Name))
|
|
||||||
throw new ArgumentException("The library's name must be set and not empty");
|
|
||||||
if (resource.Paths == null || !resource.Paths.Any())
|
|
||||||
throw new ArgumentException("The library should have a least one path.");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override async Task Delete(Library obj)
|
|
||||||
{
|
|
||||||
if (obj == null)
|
|
||||||
throw new ArgumentNullException(nameof(obj));
|
|
||||||
|
|
||||||
_database.Entry(obj).State = EntityState.Deleted;
|
|
||||||
await _database.SaveChangesAsync();
|
|
||||||
await base.Delete(obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
139
back/src/Kyoo.Core/Controllers/Repositories/MovieRepository.cs
Normal file
139
back/src/Kyoo.Core/Controllers/Repositories/MovieRepository.cs
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
// 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.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Kyoo.Abstractions.Controllers;
|
||||||
|
using Kyoo.Abstractions.Models;
|
||||||
|
using Kyoo.Postgresql;
|
||||||
|
using Kyoo.Utils;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace Kyoo.Core.Controllers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A local repository to handle shows
|
||||||
|
/// </summary>
|
||||||
|
public class MovieRepository : LocalRepository<Movie>, IMovieRepository
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The database handle
|
||||||
|
/// </summary>
|
||||||
|
private readonly DatabaseContext _database;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A studio repository to handle creation/validation of related studios.
|
||||||
|
/// </summary>
|
||||||
|
private readonly IStudioRepository _studios;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A people repository to handle creation/validation of related people.
|
||||||
|
/// </summary>
|
||||||
|
private readonly IPeopleRepository _people;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override Sort<Movie> DefaultSort => new Sort<Movie>.By(x => x.Name);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a new <see cref="MovieRepository"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="database">The database handle to use</param>
|
||||||
|
/// <param name="studios">A studio repository</param>
|
||||||
|
/// <param name="people">A people repository</param>
|
||||||
|
public MovieRepository(DatabaseContext database,
|
||||||
|
IStudioRepository studios,
|
||||||
|
IPeopleRepository people)
|
||||||
|
: base(database)
|
||||||
|
{
|
||||||
|
_database = database;
|
||||||
|
_studios = studios;
|
||||||
|
_people = people;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override async Task<ICollection<Movie>> Search(string query)
|
||||||
|
{
|
||||||
|
query = $"%{query}%";
|
||||||
|
return await Sort(
|
||||||
|
_database.Movies
|
||||||
|
.Where(_database.Like<Movie>(x => x.Name + " " + x.Slug, query))
|
||||||
|
)
|
||||||
|
.Take(20)
|
||||||
|
.ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override async Task<Movie> Create(Movie obj)
|
||||||
|
{
|
||||||
|
await base.Create(obj);
|
||||||
|
_database.Entry(obj).State = EntityState.Added;
|
||||||
|
await _database.SaveChangesAsync(() => Get(obj.Slug));
|
||||||
|
OnResourceCreated(obj);
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override async Task Validate(Movie resource)
|
||||||
|
{
|
||||||
|
await base.Validate(resource);
|
||||||
|
if (resource.Studio != null)
|
||||||
|
{
|
||||||
|
resource.Studio = await _studios.CreateIfNotExists(resource.Studio);
|
||||||
|
resource.StudioID = resource.Studio.ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resource.People != null)
|
||||||
|
{
|
||||||
|
foreach (PeopleRole role in resource.People)
|
||||||
|
{
|
||||||
|
role.People = _database.LocalEntity<People>(role.People.Slug)
|
||||||
|
?? await _people.CreateIfNotExists(role.People);
|
||||||
|
role.PeopleID = role.People.ID;
|
||||||
|
_database.Entry(role).State = EntityState.Added;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override async Task EditRelations(Movie resource, Movie changed, bool resetOld)
|
||||||
|
{
|
||||||
|
await Validate(changed);
|
||||||
|
|
||||||
|
if (changed.Studio != null || resetOld)
|
||||||
|
{
|
||||||
|
await Database.Entry(resource).Reference(x => x.Studio).LoadAsync();
|
||||||
|
resource.Studio = changed.Studio;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changed.People != null || resetOld)
|
||||||
|
{
|
||||||
|
await Database.Entry(resource).Collection(x => x.People).LoadAsync();
|
||||||
|
resource.People = changed.People;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override async Task Delete(Movie obj)
|
||||||
|
{
|
||||||
|
_database.Remove(obj);
|
||||||
|
await _database.SaveChangesAsync();
|
||||||
|
await base.Delete(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -102,7 +102,7 @@ namespace Kyoo.Core.Controllers
|
|||||||
{
|
{
|
||||||
return await Sort(
|
return await Sort(
|
||||||
_database.Seasons
|
_database.Seasons
|
||||||
.Where(_database.Like<Season>(x => x.Title, $"%{query}%"))
|
.Where(_database.Like<Season>(x => x.Name, $"%{query}%"))
|
||||||
)
|
)
|
||||||
.Take(20)
|
.Take(20)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
@ -47,13 +47,8 @@ namespace Kyoo.Core.Controllers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly IPeopleRepository _people;
|
private readonly IPeopleRepository _people;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A genres repository to handle creation/validation of related genres.
|
|
||||||
/// </summary>
|
|
||||||
private readonly IGenreRepository _genres;
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override Sort<Show> DefaultSort => new Sort<Show>.By(x => x.Title);
|
protected override Sort<Show> DefaultSort => new Sort<Show>.By(x => x.Name);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a new <see cref="ShowRepository"/>.
|
/// Create a new <see cref="ShowRepository"/>.
|
||||||
@ -61,17 +56,14 @@ namespace Kyoo.Core.Controllers
|
|||||||
/// <param name="database">The database handle to use</param>
|
/// <param name="database">The database handle to use</param>
|
||||||
/// <param name="studios">A studio repository</param>
|
/// <param name="studios">A studio repository</param>
|
||||||
/// <param name="people">A people repository</param>
|
/// <param name="people">A people repository</param>
|
||||||
/// <param name="genres">A genres repository</param>
|
|
||||||
public ShowRepository(DatabaseContext database,
|
public ShowRepository(DatabaseContext database,
|
||||||
IStudioRepository studios,
|
IStudioRepository studios,
|
||||||
IPeopleRepository people,
|
IPeopleRepository people)
|
||||||
IGenreRepository genres)
|
|
||||||
: base(database)
|
: base(database)
|
||||||
{
|
{
|
||||||
_database = database;
|
_database = database;
|
||||||
_studios = studios;
|
_studios = studios;
|
||||||
_people = people;
|
_people = people;
|
||||||
_genres = genres;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@ -80,7 +72,7 @@ namespace Kyoo.Core.Controllers
|
|||||||
query = $"%{query}%";
|
query = $"%{query}%";
|
||||||
return await Sort(
|
return await Sort(
|
||||||
_database.Shows
|
_database.Shows
|
||||||
.Where(_database.Like<Show>(x => x.Title + " " + x.Slug, query))
|
.Where(_database.Like<Show>(x => x.Name + " " + x.Slug, query))
|
||||||
)
|
)
|
||||||
.Take(20)
|
.Take(20)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
@ -99,7 +91,7 @@ namespace Kyoo.Core.Controllers
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override async Task Validate(Show resource)
|
protected override async Task Validate(Show resource)
|
||||||
{
|
{
|
||||||
resource.Slug ??= Utility.ToSlug(resource.Title);
|
resource.Slug ??= Utility.ToSlug(resource.Name);
|
||||||
|
|
||||||
await base.Validate(resource);
|
await base.Validate(resource);
|
||||||
if (resource.Studio != null)
|
if (resource.Studio != null)
|
||||||
@ -108,14 +100,6 @@ namespace Kyoo.Core.Controllers
|
|||||||
resource.StudioID = resource.Studio.ID;
|
resource.StudioID = resource.Studio.ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resource.Genres != null)
|
|
||||||
{
|
|
||||||
resource.Genres = await resource.Genres
|
|
||||||
.SelectAsync(x => _genres.CreateIfNotExists(x))
|
|
||||||
.ToListAsync();
|
|
||||||
_database.AttachRange(resource.Genres);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resource.People != null)
|
if (resource.People != null)
|
||||||
{
|
{
|
||||||
foreach (PeopleRole role in resource.People)
|
foreach (PeopleRole role in resource.People)
|
||||||
@ -133,21 +117,12 @@ namespace Kyoo.Core.Controllers
|
|||||||
{
|
{
|
||||||
await Validate(changed);
|
await Validate(changed);
|
||||||
|
|
||||||
if (changed.Aliases != null || resetOld)
|
|
||||||
resource.Aliases = changed.Aliases;
|
|
||||||
|
|
||||||
if (changed.Studio != null || resetOld)
|
if (changed.Studio != null || resetOld)
|
||||||
{
|
{
|
||||||
await Database.Entry(resource).Reference(x => x.Studio).LoadAsync();
|
await Database.Entry(resource).Reference(x => x.Studio).LoadAsync();
|
||||||
resource.Studio = changed.Studio;
|
resource.Studio = changed.Studio;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (changed.Genres != null || resetOld)
|
|
||||||
{
|
|
||||||
await Database.Entry(resource).Collection(x => x.Genres).LoadAsync();
|
|
||||||
resource.Genres = changed.Genres;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (changed.People != null || resetOld)
|
if (changed.People != null || resetOld)
|
||||||
{
|
{
|
||||||
await Database.Entry(resource).Collection(x => x.People).LoadAsync();
|
await Database.Entry(resource).Collection(x => x.People).LoadAsync();
|
||||||
@ -155,27 +130,6 @@ namespace Kyoo.Core.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public async Task AddShowLink(int showID, int? libraryID, int? collectionID)
|
|
||||||
{
|
|
||||||
if (collectionID != null)
|
|
||||||
{
|
|
||||||
await _database.AddLinks<Collection, Show>(collectionID.Value, showID);
|
|
||||||
await _database.SaveIfNoDuplicates();
|
|
||||||
|
|
||||||
if (libraryID != null)
|
|
||||||
{
|
|
||||||
await _database.AddLinks<Library, Collection>(libraryID.Value, collectionID.Value);
|
|
||||||
await _database.SaveIfNoDuplicates();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (libraryID != null)
|
|
||||||
{
|
|
||||||
await _database.AddLinks<Library, Show>(libraryID.Value, showID);
|
|
||||||
await _database.SaveIfNoDuplicates();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public Task<string> GetSlug(int showID)
|
public Task<string> GetSlug(int showID)
|
||||||
{
|
{
|
||||||
|
@ -98,9 +98,9 @@ namespace Kyoo.Core.Controllers
|
|||||||
throw new ArgumentNullException(nameof(item));
|
throw new ArgumentNullException(nameof(item));
|
||||||
|
|
||||||
string name = item is IResource res ? res.Slug : "???";
|
string name = item is IResource res ? res.Slug : "???";
|
||||||
await _DownloadImage(item.Poster.Source, _GetBaseImagePath(item, "poster"), $"The poster of {name}");
|
await _DownloadImage(item.Poster?.Source, _GetBaseImagePath(item, "poster"), $"The poster of {name}");
|
||||||
await _DownloadImage(item.Thumbnail.Source, _GetBaseImagePath(item, "thumbnail"), $"The poster of {name}");
|
await _DownloadImage(item.Thumbnail?.Source, _GetBaseImagePath(item, "thumbnail"), $"The poster of {name}");
|
||||||
await _DownloadImage(item.Logo.Source, _GetBaseImagePath(item, "logo"), $"The poster of {name}");
|
await _DownloadImage(item.Logo?.Source, _GetBaseImagePath(item, "logo"), $"The poster of {name}");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string _GetBaseImagePath<T>(T item, string image)
|
private static string _GetBaseImagePath<T>(T item, string image)
|
||||||
|
@ -30,6 +30,7 @@ using Microsoft.AspNetCore.Routing;
|
|||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Converters;
|
||||||
using JsonOptions = Kyoo.Core.Api.JsonOptions;
|
using JsonOptions = Kyoo.Core.Api.JsonOptions;
|
||||||
|
|
||||||
namespace Kyoo.Core
|
namespace Kyoo.Core
|
||||||
@ -48,15 +49,14 @@ namespace Kyoo.Core
|
|||||||
builder.RegisterType<ThumbnailsManager>().As<IThumbnailsManager>().InstancePerLifetimeScope();
|
builder.RegisterType<ThumbnailsManager>().As<IThumbnailsManager>().InstancePerLifetimeScope();
|
||||||
builder.RegisterType<LibraryManager>().As<ILibraryManager>().InstancePerLifetimeScope();
|
builder.RegisterType<LibraryManager>().As<ILibraryManager>().InstancePerLifetimeScope();
|
||||||
|
|
||||||
builder.RegisterRepository<ILibraryRepository, LibraryRepository>();
|
|
||||||
builder.RegisterRepository<ILibraryItemRepository, LibraryItemRepository>();
|
builder.RegisterRepository<ILibraryItemRepository, LibraryItemRepository>();
|
||||||
builder.RegisterRepository<ICollectionRepository, CollectionRepository>();
|
builder.RegisterRepository<ICollectionRepository, CollectionRepository>();
|
||||||
|
builder.RegisterRepository<IMovieRepository, MovieRepository>();
|
||||||
builder.RegisterRepository<IShowRepository, ShowRepository>();
|
builder.RegisterRepository<IShowRepository, ShowRepository>();
|
||||||
builder.RegisterRepository<ISeasonRepository, SeasonRepository>();
|
builder.RegisterRepository<ISeasonRepository, SeasonRepository>();
|
||||||
builder.RegisterRepository<IEpisodeRepository, EpisodeRepository>();
|
builder.RegisterRepository<IEpisodeRepository, EpisodeRepository>();
|
||||||
builder.RegisterRepository<IPeopleRepository, PeopleRepository>();
|
builder.RegisterRepository<IPeopleRepository, PeopleRepository>();
|
||||||
builder.RegisterRepository<IStudioRepository, StudioRepository>();
|
builder.RegisterRepository<IStudioRepository, StudioRepository>();
|
||||||
builder.RegisterRepository<IGenreRepository, GenreRepository>();
|
|
||||||
builder.RegisterRepository<IUserRepository, UserRepository>();
|
builder.RegisterRepository<IUserRepository, UserRepository>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,6 +73,7 @@ namespace Kyoo.Core
|
|||||||
.AddNewtonsoftJson(x =>
|
.AddNewtonsoftJson(x =>
|
||||||
{
|
{
|
||||||
x.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
|
x.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
|
||||||
|
x.SerializerSettings.Converters.Add(new StringEnumConverter());
|
||||||
})
|
})
|
||||||
.AddDataAnnotations()
|
.AddDataAnnotations()
|
||||||
.AddControllersAsServices()
|
.AddControllersAsServices()
|
||||||
|
@ -16,40 +16,31 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Kyoo.Abstractions.Models.Attributes;
|
using Kyoo.Abstractions.Models;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
namespace Kyoo.Abstractions.Models
|
namespace Kyoo.Core.Api
|
||||||
{
|
{
|
||||||
/// <summary>
|
public class ImageConverter : JsonConverter<Image>
|
||||||
/// A library containing <see cref="Show"/> and <see cref="Collection"/>.
|
|
||||||
/// </summary>
|
|
||||||
public class Library : IResource
|
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public int ID { get; set; }
|
public override void WriteJson(JsonWriter writer, Image value, JsonSerializer serializer)
|
||||||
|
{
|
||||||
|
JObject obj = JObject.FromObject(value, serializer);
|
||||||
|
obj.WriteTo(writer);
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public string Slug { get; set; }
|
public override Image ReadJson(JsonReader reader,
|
||||||
|
Type objectType,
|
||||||
/// <summary>
|
Image existingValue,
|
||||||
/// The name of this library.
|
bool hasExistingValue,
|
||||||
/// </summary>
|
JsonSerializer serializer)
|
||||||
public string Name { get; set; }
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
/// <summary>
|
}
|
||||||
/// The list of paths that this library is responsible for. This is mainly used by the Scan task.
|
|
||||||
/// </summary>
|
|
||||||
public string[] Paths { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The list of shows in this library.
|
|
||||||
/// </summary>
|
|
||||||
[LoadableRelation] public ICollection<Show> Shows { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The list of collections in this library.
|
|
||||||
/// </summary>
|
|
||||||
[LoadableRelation] public ICollection<Collection> Collections { get; set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -18,7 +18,6 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Kyoo.Abstractions.Models;
|
using Kyoo.Abstractions.Models;
|
||||||
using Kyoo.Abstractions.Models.Attributes;
|
using Kyoo.Abstractions.Models.Attributes;
|
||||||
|
@ -1,95 +0,0 @@
|
|||||||
// 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.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Kyoo.Abstractions.Controllers;
|
|
||||||
using Kyoo.Abstractions.Models;
|
|
||||||
using Kyoo.Abstractions.Models.Attributes;
|
|
||||||
using Kyoo.Abstractions.Models.Permissions;
|
|
||||||
using Kyoo.Abstractions.Models.Utils;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using static Kyoo.Abstractions.Models.Utils.Constants;
|
|
||||||
|
|
||||||
namespace Kyoo.Core.Api
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Information about one or multiple <see cref="Genre"/>.
|
|
||||||
/// </summary>
|
|
||||||
[Route("genres")]
|
|
||||||
[Route("genre", Order = AlternativeRoute)]
|
|
||||||
[ApiController]
|
|
||||||
[PartialPermission(nameof(Genre))]
|
|
||||||
[ApiDefinition("Genres", Group = MetadataGroup)]
|
|
||||||
public class GenreApi : CrudApi<Genre>
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The library manager used to modify or retrieve information about the data store.
|
|
||||||
/// </summary>
|
|
||||||
private readonly ILibraryManager _libraryManager;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create a new <see cref="GenreApi"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="libraryManager">
|
|
||||||
/// The library manager used to modify or retrieve information about the data store.
|
|
||||||
/// </param>
|
|
||||||
public GenreApi(ILibraryManager libraryManager)
|
|
||||||
: base(libraryManager.GenreRepository)
|
|
||||||
{
|
|
||||||
_libraryManager = libraryManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get shows with genre
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// Lists the shows that have the selected genre.
|
|
||||||
/// </remarks>
|
|
||||||
/// <param name="identifier">The ID or slug of the <see cref="Genre"/>.</param>
|
|
||||||
/// <param name="sortBy">A key to sort shows by.</param>
|
|
||||||
/// <param name="where">An optional list of filters.</param>
|
|
||||||
/// <param name="pagination">The number of shows to return and where to start.</param>
|
|
||||||
/// <returns>A page of shows.</returns>
|
|
||||||
/// <response code="400">The filters or the sort parameters are invalid.</response>
|
|
||||||
/// <response code="404">No genre with the given ID could be found.</response>
|
|
||||||
[HttpGet("{identifier:id}/shows")]
|
|
||||||
[HttpGet("{identifier:id}/show", Order = AlternativeRoute)]
|
|
||||||
[PartialPermission(Kind.Read)]
|
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
||||||
[ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(RequestError))]
|
|
||||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
|
||||||
public async Task<ActionResult<Page<Show>>> GetShows(Identifier identifier,
|
|
||||||
[FromQuery] string sortBy,
|
|
||||||
[FromQuery] Dictionary<string, string> where,
|
|
||||||
[FromQuery] Pagination pagination)
|
|
||||||
{
|
|
||||||
ICollection<Show> resources = await _libraryManager.GetAll(
|
|
||||||
ApiHelper.ParseWhere(where, identifier.IsContainedIn<Show, Genre>(x => x.Genres)),
|
|
||||||
Sort<Show>.From(sortBy),
|
|
||||||
pagination
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!resources.Any() && await _libraryManager.GetOrDefault(identifier.IsSame<Genre>()) == null)
|
|
||||||
return NotFound();
|
|
||||||
return Page(resources, pagination.Limit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -93,40 +93,5 @@ namespace Kyoo.Core.Api
|
|||||||
return NotFound();
|
return NotFound();
|
||||||
return Page(resources, pagination.Limit);
|
return Page(resources, pagination.Limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get libraries containing this collection
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// Lists the libraries that contain the collection with the given id or slug.
|
|
||||||
/// </remarks>
|
|
||||||
/// <param name="identifier">The ID or slug of the <see cref="Collection"/>.</param>
|
|
||||||
/// <param name="sortBy">A key to sort libraries by.</param>
|
|
||||||
/// <param name="where">An optional list of filters.</param>
|
|
||||||
/// <param name="pagination">The number of libraries to return.</param>
|
|
||||||
/// <returns>A page of libraries.</returns>
|
|
||||||
/// <response code="400">The filters or the sort parameters are invalid.</response>
|
|
||||||
/// <response code="404">No collection with the given ID or slug could be found.</response>
|
|
||||||
[HttpGet("{identifier:id}/libraries")]
|
|
||||||
[HttpGet("{identifier:id}/library", Order = AlternativeRoute)]
|
|
||||||
[PartialPermission(Kind.Read)]
|
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
||||||
[ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(RequestError))]
|
|
||||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
|
||||||
public async Task<ActionResult<Page<Library>>> GetLibraries(Identifier identifier,
|
|
||||||
[FromQuery] string sortBy,
|
|
||||||
[FromQuery] Dictionary<string, string> where,
|
|
||||||
[FromQuery] Pagination pagination)
|
|
||||||
{
|
|
||||||
ICollection<Library> resources = await _libraryManager.GetAll(
|
|
||||||
ApiHelper.ParseWhere(where, identifier.IsContainedIn<Library, Collection>(x => x.Collections)),
|
|
||||||
Sort<Library>.From(sortBy),
|
|
||||||
pagination
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!resources.Any() && await _libraryManager.GetOrDefault(identifier.IsSame<Collection>()) == null)
|
|
||||||
return NotFound();
|
|
||||||
return Page(resources, pagination.Limit);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,171 +0,0 @@
|
|||||||
// 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 System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Linq.Expressions;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Kyoo.Abstractions.Controllers;
|
|
||||||
using Kyoo.Abstractions.Models;
|
|
||||||
using Kyoo.Abstractions.Models.Attributes;
|
|
||||||
using Kyoo.Abstractions.Models.Permissions;
|
|
||||||
using Kyoo.Abstractions.Models.Utils;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using static Kyoo.Abstractions.Models.Utils.Constants;
|
|
||||||
|
|
||||||
namespace Kyoo.Core.Api
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Information about one or multiple <see cref="Library"/>.
|
|
||||||
/// </summary>
|
|
||||||
[Route("libraries")]
|
|
||||||
[Route("library", Order = AlternativeRoute)]
|
|
||||||
[ApiController]
|
|
||||||
[ResourceView]
|
|
||||||
[PartialPermission(nameof(Library), Group = Group.Admin)]
|
|
||||||
[ApiDefinition("Library", Group = ResourcesGroup)]
|
|
||||||
public class LibraryApi : CrudApi<Library>
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The library manager used to modify or retrieve information in the data store.
|
|
||||||
/// </summary>
|
|
||||||
private readonly ILibraryManager _libraryManager;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create a new <see cref="EpisodeApi"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="libraryManager">
|
|
||||||
/// The library manager used to modify or retrieve information in the data store.
|
|
||||||
/// </param>
|
|
||||||
public LibraryApi(ILibraryManager libraryManager)
|
|
||||||
: base(libraryManager.LibraryRepository)
|
|
||||||
{
|
|
||||||
_libraryManager = libraryManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get shows
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// List the shows that are part of this library.
|
|
||||||
/// </remarks>
|
|
||||||
/// <param name="identifier">The ID or slug of the <see cref="Library"/>.</param>
|
|
||||||
/// <param name="sortBy">A key to sort shows by.</param>
|
|
||||||
/// <param name="where">An optional list of filters.</param>
|
|
||||||
/// <param name="pagination">The number of shows to return.</param>
|
|
||||||
/// <returns>A page of shows.</returns>
|
|
||||||
/// <response code="400">The filters or the sort parameters are invalid.</response>
|
|
||||||
/// <response code="404">No library with the given ID or slug could be found.</response>
|
|
||||||
[HttpGet("{identifier:id}/shows")]
|
|
||||||
[HttpGet("{identifier:id}/show", Order = AlternativeRoute)]
|
|
||||||
[PartialPermission(Kind.Read)]
|
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
||||||
[ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(RequestError))]
|
|
||||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
|
||||||
public async Task<ActionResult<Page<Show>>> GetShows(Identifier identifier,
|
|
||||||
[FromQuery] string sortBy,
|
|
||||||
[FromQuery] Dictionary<string, string> where,
|
|
||||||
[FromQuery] Pagination pagination)
|
|
||||||
{
|
|
||||||
ICollection<Show> resources = await _libraryManager.GetAll(
|
|
||||||
ApiHelper.ParseWhere(where, identifier.IsContainedIn<Show, Library>(x => x.Libraries)),
|
|
||||||
Sort<Show>.From(sortBy),
|
|
||||||
pagination
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!resources.Any() && await _libraryManager.GetOrDefault(identifier.IsSame<Library>()) == null)
|
|
||||||
return NotFound();
|
|
||||||
return Page(resources, pagination.Limit);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get collections
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// List the collections that are part of this library.
|
|
||||||
/// </remarks>
|
|
||||||
/// <param name="identifier">The ID or slug of the <see cref="Library"/>.</param>
|
|
||||||
/// <param name="sortBy">A key to sort collections by.</param>
|
|
||||||
/// <param name="where">An optional list of filters.</param>
|
|
||||||
/// <param name="pagination">The number of collections to return.</param>
|
|
||||||
/// <returns>A page of collections.</returns>
|
|
||||||
/// <response code="400">The filters or the sort parameters are invalid.</response>
|
|
||||||
/// <response code="404">No library with the given ID or slug could be found.</response>
|
|
||||||
[HttpGet("{identifier:id}/collections")]
|
|
||||||
[HttpGet("{identifier:id}/collection", Order = AlternativeRoute)]
|
|
||||||
[PartialPermission(Kind.Read)]
|
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
||||||
[ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(RequestError))]
|
|
||||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
|
||||||
public async Task<ActionResult<Page<Collection>>> GetCollections(Identifier identifier,
|
|
||||||
[FromQuery] string sortBy,
|
|
||||||
[FromQuery] Dictionary<string, string> where,
|
|
||||||
[FromQuery] Pagination pagination)
|
|
||||||
{
|
|
||||||
ICollection<Collection> resources = await _libraryManager.GetAll(
|
|
||||||
ApiHelper.ParseWhere(where, identifier.IsContainedIn<Collection, Library>(x => x.Libraries)),
|
|
||||||
Sort<Collection>.From(sortBy),
|
|
||||||
pagination
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!resources.Any() && await _libraryManager.GetOrDefault(identifier.IsSame<Library>()) == null)
|
|
||||||
return NotFound();
|
|
||||||
return Page(resources, pagination.Limit);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get items
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// List all items of this library.
|
|
||||||
/// An item can ether represent a collection or a show.
|
|
||||||
/// This endpoint allow one to retrieve all collections and shows that are not contained in a collection.
|
|
||||||
/// This is what is displayed on the /browse/library page of the webapp.
|
|
||||||
/// </remarks>
|
|
||||||
/// <param name="identifier">The ID or slug of the <see cref="Library"/>.</param>
|
|
||||||
/// <param name="sortBy">A key to sort items by.</param>
|
|
||||||
/// <param name="where">An optional list of filters.</param>
|
|
||||||
/// <param name="pagination">The number of items to return.</param>
|
|
||||||
/// <returns>A page of items.</returns>
|
|
||||||
/// <response code="400">The filters or the sort parameters are invalid.</response>
|
|
||||||
/// <response code="404">No library with the given ID or slug could be found.</response>
|
|
||||||
[HttpGet("{identifier:id}/items")]
|
|
||||||
[HttpGet("{identifier:id}/item", Order = AlternativeRoute)]
|
|
||||||
[PartialPermission(Kind.Read)]
|
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
||||||
[ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(RequestError))]
|
|
||||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
|
||||||
public async Task<ActionResult<Page<LibraryItem>>> GetItems(Identifier identifier,
|
|
||||||
[FromQuery] string sortBy,
|
|
||||||
[FromQuery] Dictionary<string, string> where,
|
|
||||||
[FromQuery] Pagination pagination)
|
|
||||||
{
|
|
||||||
Expression<Func<LibraryItem, bool>> whereQuery = ApiHelper.ParseWhere<LibraryItem>(where);
|
|
||||||
Sort<LibraryItem> sort = Sort<LibraryItem>.From(sortBy);
|
|
||||||
|
|
||||||
ICollection<LibraryItem> resources = await identifier.Match(
|
|
||||||
id => _libraryManager.GetItemsFromLibrary(id, whereQuery, sort, pagination),
|
|
||||||
slug => _libraryManager.GetItemsFromLibrary(slug, whereQuery, sort, pagination)
|
|
||||||
);
|
|
||||||
|
|
||||||
return Page(resources, pagination.Limit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -16,7 +16,6 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Kyoo.Abstractions.Controllers;
|
using Kyoo.Abstractions.Controllers;
|
||||||
@ -38,7 +37,7 @@ namespace Kyoo.Core.Api
|
|||||||
[Route("item", Order = AlternativeRoute)]
|
[Route("item", Order = AlternativeRoute)]
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[ResourceView]
|
[ResourceView]
|
||||||
[PartialPermission(nameof(LibraryItem))]
|
[PartialPermission("LibraryItem")]
|
||||||
[ApiDefinition("Items", Group = ResourcesGroup)]
|
[ApiDefinition("Items", Group = ResourcesGroup)]
|
||||||
public class LibraryItemApi : BaseApi
|
public class LibraryItemApi : BaseApi
|
||||||
{
|
{
|
||||||
@ -78,14 +77,14 @@ namespace Kyoo.Core.Api
|
|||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
[ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(RequestError))]
|
[ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(RequestError))]
|
||||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
public async Task<ActionResult<Page<LibraryItem>>> GetAll(
|
public async Task<ActionResult<Page<ILibraryItem>>> GetAll(
|
||||||
[FromQuery] string sortBy,
|
[FromQuery] string sortBy,
|
||||||
[FromQuery] Dictionary<string, string> where,
|
[FromQuery] Dictionary<string, string> where,
|
||||||
[FromQuery] Pagination pagination)
|
[FromQuery] Pagination pagination)
|
||||||
{
|
{
|
||||||
ICollection<LibraryItem> resources = await _libraryItems.GetAll(
|
ICollection<ILibraryItem> resources = await _libraryItems.GetAll(
|
||||||
ApiHelper.ParseWhere<LibraryItem>(where),
|
ApiHelper.ParseWhere<ILibraryItem>(where),
|
||||||
Sort<LibraryItem>.From(sortBy),
|
Sort<ILibraryItem>.From(sortBy),
|
||||||
pagination
|
pagination
|
||||||
);
|
);
|
||||||
|
|
||||||
|
149
back/src/Kyoo.Core/Views/Resources/MovieApi.cs
Normal file
149
back/src/Kyoo.Core/Views/Resources/MovieApi.cs
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
// 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.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Kyoo.Abstractions.Controllers;
|
||||||
|
using Kyoo.Abstractions.Models;
|
||||||
|
using Kyoo.Abstractions.Models.Attributes;
|
||||||
|
using Kyoo.Abstractions.Models.Permissions;
|
||||||
|
using Kyoo.Abstractions.Models.Utils;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using static Kyoo.Abstractions.Models.Utils.Constants;
|
||||||
|
|
||||||
|
namespace Kyoo.Core.Api
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Information about one or multiple <see cref="Movie"/>.
|
||||||
|
/// </summary>
|
||||||
|
[Route("movies")]
|
||||||
|
[Route("movie", Order = AlternativeRoute)]
|
||||||
|
[ApiController]
|
||||||
|
[PartialPermission(nameof(Show))]
|
||||||
|
[ApiDefinition("Shows", Group = ResourcesGroup)]
|
||||||
|
public class MovieApi : CrudThumbsApi<Movie>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The library manager used to modify or retrieve information in the data store.
|
||||||
|
/// </summary>
|
||||||
|
private readonly ILibraryManager _libraryManager;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a new <see cref="ShowApi"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="libraryManager">
|
||||||
|
/// The library manager used to modify or retrieve information about the data store.
|
||||||
|
/// </param>
|
||||||
|
/// <param name="thumbs">The thumbnail manager used to retrieve images paths.</param>
|
||||||
|
public MovieApi(ILibraryManager libraryManager,
|
||||||
|
IThumbnailsManager thumbs)
|
||||||
|
: base(libraryManager.MovieRepository, thumbs)
|
||||||
|
{
|
||||||
|
_libraryManager = libraryManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
// /// <summary>
|
||||||
|
// /// Get staff
|
||||||
|
// /// </summary>
|
||||||
|
// /// <remarks>
|
||||||
|
// /// List staff members that made this show.
|
||||||
|
// /// </remarks>
|
||||||
|
// /// <param name="identifier">The ID or slug of the <see cref="Show"/>.</param>
|
||||||
|
// /// <param name="sortBy">A key to sort staff members by.</param>
|
||||||
|
// /// <param name="where">An optional list of filters.</param>
|
||||||
|
// /// <param name="pagination">The number of people to return.</param>
|
||||||
|
// /// <returns>A page of people.</returns>
|
||||||
|
// /// <response code="400">The filters or the sort parameters are invalid.</response>
|
||||||
|
// /// <response code="404">No show with the given ID or slug could be found.</response>
|
||||||
|
// [HttpGet("{identifier:id}/staff")]
|
||||||
|
// [HttpGet("{identifier:id}/people", Order = AlternativeRoute)]
|
||||||
|
// [PartialPermission(Kind.Read)]
|
||||||
|
// [ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
|
// [ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(RequestError))]
|
||||||
|
// [ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
|
// public async Task<ActionResult<Page<PeopleRole>>> GetPeople(Identifier identifier,
|
||||||
|
// [FromQuery] string sortBy,
|
||||||
|
// [FromQuery] Dictionary<string, string> where,
|
||||||
|
// [FromQuery] Pagination pagination)
|
||||||
|
// {
|
||||||
|
// Expression<Func<PeopleRole, bool>> whereQuery = ApiHelper.ParseWhere<PeopleRole>(where);
|
||||||
|
// Sort<PeopleRole> sort = Sort<PeopleRole>.From(sortBy);
|
||||||
|
//
|
||||||
|
// ICollection<PeopleRole> resources = await identifier.Match(
|
||||||
|
// id => _libraryManager.GetPeopleFromShow(id, whereQuery, sort, pagination),
|
||||||
|
// slug => _libraryManager.GetPeopleFromShow(slug, whereQuery, sort, pagination)
|
||||||
|
// );
|
||||||
|
// return Page(resources, pagination.Limit);
|
||||||
|
// }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get studio that made the show
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Get the studio that made the show.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="identifier">The ID or slug of the <see cref="Show"/>.</param>
|
||||||
|
/// <returns>The studio that made the show.</returns>
|
||||||
|
/// <response code="404">No show with the given ID or slug could be found.</response>
|
||||||
|
[HttpGet("{identifier:id}/studio")]
|
||||||
|
[PartialPermission(Kind.Read)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
|
public async Task<ActionResult<Studio>> GetStudio(Identifier identifier)
|
||||||
|
{
|
||||||
|
return await _libraryManager.Get(identifier.IsContainedIn<Studio, Movie>(x => x.Movies));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get collections containing this show
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// List the collections that contain this show.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="identifier">The ID or slug of the <see cref="Show"/>.</param>
|
||||||
|
/// <param name="sortBy">A key to sort collections by.</param>
|
||||||
|
/// <param name="where">An optional list of filters.</param>
|
||||||
|
/// <param name="pagination">The number of collections to return.</param>
|
||||||
|
/// <returns>A page of collections.</returns>
|
||||||
|
/// <response code="400">The filters or the sort parameters are invalid.</response>
|
||||||
|
/// <response code="404">No show with the given ID or slug could be found.</response>
|
||||||
|
[HttpGet("{identifier:id}/collections")]
|
||||||
|
[HttpGet("{identifier:id}/collection", Order = AlternativeRoute)]
|
||||||
|
[PartialPermission(Kind.Read)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(RequestError))]
|
||||||
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
|
public async Task<ActionResult<Page<Collection>>> GetCollections(Identifier identifier,
|
||||||
|
[FromQuery] string sortBy,
|
||||||
|
[FromQuery] Dictionary<string, string> where,
|
||||||
|
[FromQuery] Pagination pagination)
|
||||||
|
{
|
||||||
|
ICollection<Collection> resources = await _libraryManager.GetAll(
|
||||||
|
ApiHelper.ParseWhere(where, identifier.IsContainedIn<Collection, Movie>(x => x.Movies)),
|
||||||
|
Sort<Collection>.From(sortBy),
|
||||||
|
pagination
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!resources.Any() && await _libraryManager.GetOrDefault(identifier.IsSame<Movie>()) == null)
|
||||||
|
return NotFound();
|
||||||
|
return Page(resources, pagination.Limit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -79,7 +79,6 @@ namespace Kyoo.Core.Api
|
|||||||
Shows = await _libraryManager.Search<Show>(query),
|
Shows = await _libraryManager.Search<Show>(query),
|
||||||
Episodes = await _libraryManager.Search<Episode>(query),
|
Episodes = await _libraryManager.Search<Episode>(query),
|
||||||
People = await _libraryManager.Search<People>(query),
|
People = await _libraryManager.Search<People>(query),
|
||||||
Genres = await _libraryManager.Search<Genre>(query),
|
|
||||||
Studios = await _libraryManager.Search<Studio>(query)
|
Studios = await _libraryManager.Search<Studio>(query)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -133,9 +132,9 @@ namespace Kyoo.Core.Api
|
|||||||
[Permission(nameof(Show), Kind.Read)]
|
[Permission(nameof(Show), Kind.Read)]
|
||||||
[ApiDefinition("Items")]
|
[ApiDefinition("Items")]
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
public Task<ICollection<LibraryItem>> SearchItems(string query)
|
public Task<ICollection<ILibraryItem>> SearchItems(string query)
|
||||||
{
|
{
|
||||||
return _libraryManager.Search<LibraryItem>(query);
|
return _libraryManager.Search<ILibraryItem>(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -175,24 +174,6 @@ namespace Kyoo.Core.Api
|
|||||||
return _libraryManager.Search<People>(query);
|
return _libraryManager.Search<People>(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Search genres
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// Search for genres
|
|
||||||
/// </remarks>
|
|
||||||
/// <param name="query">The query to search for.</param>
|
|
||||||
/// <returns>A list of genres found for the specified query.</returns>
|
|
||||||
[HttpGet("genres")]
|
|
||||||
[HttpGet("genre", Order = AlternativeRoute)]
|
|
||||||
[Permission(nameof(Genre), Kind.Read)]
|
|
||||||
[ApiDefinition("Genres")]
|
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
||||||
public Task<ICollection<Genre>> SearchGenres(string query)
|
|
||||||
{
|
|
||||||
return _libraryManager.Search<Genre>(query);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Search studios
|
/// Search studios
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -37,8 +37,6 @@ namespace Kyoo.Core.Api
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[Route("shows")]
|
[Route("shows")]
|
||||||
[Route("show", Order = AlternativeRoute)]
|
[Route("show", Order = AlternativeRoute)]
|
||||||
[Route("movie", Order = AlternativeRoute)]
|
|
||||||
[Route("movies", Order = AlternativeRoute)]
|
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[PartialPermission(nameof(Show))]
|
[PartialPermission(nameof(Show))]
|
||||||
[ApiDefinition("Shows", Group = ResourcesGroup)]
|
[ApiDefinition("Shows", Group = ResourcesGroup)]
|
||||||
@ -63,24 +61,6 @@ namespace Kyoo.Core.Api
|
|||||||
_libraryManager = libraryManager;
|
_libraryManager = libraryManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
public override async Task<ActionResult<Show>> Create([FromBody] Show resource)
|
|
||||||
{
|
|
||||||
ActionResult<Show> ret = await base.Create(resource);
|
|
||||||
if (ret.Value.IsMovie)
|
|
||||||
{
|
|
||||||
Episode episode = new()
|
|
||||||
{
|
|
||||||
Show = ret.Value,
|
|
||||||
Title = ret.Value.Title,
|
|
||||||
Path = ret.Value.Path
|
|
||||||
};
|
|
||||||
|
|
||||||
await _libraryManager.Create(episode);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get seasons of this show
|
/// Get seasons of this show
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -185,41 +165,6 @@ namespace Kyoo.Core.Api
|
|||||||
return Page(resources, pagination.Limit);
|
return Page(resources, pagination.Limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get genres of this show
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// List the genres that represent this show.
|
|
||||||
/// </remarks>
|
|
||||||
/// <param name="identifier">The ID or slug of the <see cref="Show"/>.</param>
|
|
||||||
/// <param name="sortBy">A key to sort genres by.</param>
|
|
||||||
/// <param name="where">An optional list of filters.</param>
|
|
||||||
/// <param name="pagination">The number of genres to return.</param>
|
|
||||||
/// <returns>A page of genres.</returns>
|
|
||||||
/// <response code="400">The filters or the sort parameters are invalid.</response>
|
|
||||||
/// <response code="404">No show with the given ID or slug could be found.</response>
|
|
||||||
[HttpGet("{identifier:id}/genres")]
|
|
||||||
[HttpGet("{identifier:id}/genre", Order = AlternativeRoute)]
|
|
||||||
[PartialPermission(Kind.Read)]
|
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
||||||
[ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(RequestError))]
|
|
||||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
|
||||||
public async Task<ActionResult<Page<Genre>>> GetGenres(Identifier identifier,
|
|
||||||
[FromQuery] string sortBy,
|
|
||||||
[FromQuery] Dictionary<string, string> where,
|
|
||||||
[FromQuery] Pagination pagination)
|
|
||||||
{
|
|
||||||
ICollection<Genre> resources = await _libraryManager.GetAll(
|
|
||||||
ApiHelper.ParseWhere(where, identifier.IsContainedIn<Genre, Show>(x => x.Shows)),
|
|
||||||
Sort<Genre>.From(sortBy),
|
|
||||||
pagination
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!resources.Any() && await _libraryManager.GetOrDefault(identifier.IsSame<Show>()) == null)
|
|
||||||
return NotFound();
|
|
||||||
return Page(resources, pagination.Limit);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get studio that made the show
|
/// Get studio that made the show
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -238,42 +183,6 @@ namespace Kyoo.Core.Api
|
|||||||
return await _libraryManager.Get(identifier.IsContainedIn<Studio, Show>(x => x.Shows));
|
return await _libraryManager.Get(identifier.IsContainedIn<Studio, Show>(x => x.Shows));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get libraries containing this show
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// List the libraries that contain this show. If this show is contained in a collection that is contained in
|
|
||||||
/// a library, this library will be returned too.
|
|
||||||
/// </remarks>
|
|
||||||
/// <param name="identifier">The ID or slug of the <see cref="Show"/>.</param>
|
|
||||||
/// <param name="sortBy">A key to sort libraries by.</param>
|
|
||||||
/// <param name="where">An optional list of filters.</param>
|
|
||||||
/// <param name="pagination">The number of libraries to return.</param>
|
|
||||||
/// <returns>A page of libraries.</returns>
|
|
||||||
/// <response code="400">The filters or the sort parameters are invalid.</response>
|
|
||||||
/// <response code="404">No show with the given ID or slug could be found.</response>
|
|
||||||
[HttpGet("{identifier:id}/libraries")]
|
|
||||||
[HttpGet("{identifier:id}/library", Order = AlternativeRoute)]
|
|
||||||
[PartialPermission(Kind.Read)]
|
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
||||||
[ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(RequestError))]
|
|
||||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
|
||||||
public async Task<ActionResult<Page<Library>>> GetLibraries(Identifier identifier,
|
|
||||||
[FromQuery] string sortBy,
|
|
||||||
[FromQuery] Dictionary<string, string> where,
|
|
||||||
[FromQuery] Pagination pagination)
|
|
||||||
{
|
|
||||||
ICollection<Library> resources = await _libraryManager.GetAll(
|
|
||||||
ApiHelper.ParseWhere(where, identifier.IsContainedIn<Library, Show>(x => x.Shows)),
|
|
||||||
Sort<Library>.From(sortBy),
|
|
||||||
pagination
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!resources.Any() && await _libraryManager.GetOrDefault(identifier.IsSame<Show>()) == null)
|
|
||||||
return NotFound();
|
|
||||||
return Page(resources, pagination.Limit);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get collections containing this show
|
/// Get collections containing this show
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -1,91 +0,0 @@
|
|||||||
// 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.Net.Http;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Kyoo.Abstractions.Controllers;
|
|
||||||
using Kyoo.Abstractions.Models;
|
|
||||||
using Kyoo.Abstractions.Models.Attributes;
|
|
||||||
using Kyoo.Abstractions.Models.Permissions;
|
|
||||||
using Kyoo.Abstractions.Models.Utils;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using static Kyoo.Abstractions.Models.Utils.Constants;
|
|
||||||
|
|
||||||
namespace Kyoo.Core.Api
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Retrieve information of an <see cref="Episode"/> as a <see cref="WatchItem"/>.
|
|
||||||
/// A watch item is another representation of an episode in a form easier to read and display for playback.
|
|
||||||
/// It contains streams (video, audio, subtitles) information, chapters, next and previous episodes and a bit of
|
|
||||||
/// information of the show.
|
|
||||||
/// </summary>
|
|
||||||
[Route("watch")]
|
|
||||||
[Route("watchitem", Order = AlternativeRoute)]
|
|
||||||
[ApiController]
|
|
||||||
[ApiDefinition("Watch Items", Group = WatchGroup)]
|
|
||||||
public class WatchApi : ControllerBase
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The library manager used to modify or retrieve information in the data store.
|
|
||||||
/// </summary>
|
|
||||||
private readonly ILibraryManager _libraryManager;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The http client to reach transcoder.
|
|
||||||
/// </summary>
|
|
||||||
private readonly HttpClient _client;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create a new <see cref="WatchApi"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="libraryManager">
|
|
||||||
/// The library manager used to modify or retrieve information in the data store.
|
|
||||||
/// </param>
|
|
||||||
/// <param name="client">The http client to reach transcoder.</param>
|
|
||||||
public WatchApi(ILibraryManager libraryManager, HttpClient client)
|
|
||||||
{
|
|
||||||
_libraryManager = libraryManager;
|
|
||||||
_client = client;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get a watch item
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// Retrieve a watch item of an episode.
|
|
||||||
/// </remarks>
|
|
||||||
/// <param name="identifier">The ID or slug of the <see cref="Episode"/>.</param>
|
|
||||||
/// <returns>A page of items.</returns>
|
|
||||||
/// <response code="404">No episode with the given ID or slug could be found.</response>
|
|
||||||
[HttpGet("{identifier:id}")]
|
|
||||||
[Permission("watch", Kind.Read)]
|
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
||||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
|
||||||
public async Task<ActionResult<WatchItem>> GetWatchItem(Identifier identifier)
|
|
||||||
{
|
|
||||||
Episode item = await identifier.Match(
|
|
||||||
id => _libraryManager.GetOrDefault<Episode>(id),
|
|
||||||
slug => _libraryManager.GetOrDefault<Episode>(slug)
|
|
||||||
);
|
|
||||||
if (item == null)
|
|
||||||
return NotFound();
|
|
||||||
return await WatchItem.FromEpisode(item, _libraryManager, _client);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -41,16 +41,16 @@ namespace Kyoo.Postgresql
|
|||||||
/// </remarks>
|
/// </remarks>
|
||||||
public abstract class DatabaseContext : DbContext
|
public abstract class DatabaseContext : DbContext
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// All libraries of Kyoo. See <see cref="Library"/>.
|
|
||||||
/// </summary>
|
|
||||||
public DbSet<Library> Libraries { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// All collections of Kyoo. See <see cref="Collection"/>.
|
/// All collections of Kyoo. See <see cref="Collection"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DbSet<Collection> Collections { get; set; }
|
public DbSet<Collection> Collections { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// All movies of Kyoo. See <see cref="Movie"/>.
|
||||||
|
/// </summary>
|
||||||
|
public DbSet<Movie> Movies { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// All shows of Kyoo. See <see cref="Show"/>.
|
/// All shows of Kyoo. See <see cref="Show"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -66,11 +66,6 @@ namespace Kyoo.Postgresql
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public DbSet<Episode> Episodes { get; set; }
|
public DbSet<Episode> Episodes { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// All genres of Kyoo. See <see cref="Genres"/>.
|
|
||||||
/// </summary>
|
|
||||||
public DbSet<Genre> Genres { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// All people of Kyoo. See <see cref="People"/>.
|
/// All people of Kyoo. See <see cref="People"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -91,18 +86,38 @@ namespace Kyoo.Postgresql
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public DbSet<PeopleRole> PeopleRoles { get; set; }
|
public DbSet<PeopleRole> PeopleRoles { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Episodes with a watch percentage. See <see cref="WatchedEpisode"/>.
|
|
||||||
/// </summary>
|
|
||||||
public DbSet<WatchedEpisode> WatchedEpisodes { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The list of library items (shows and collections that are part of a library - or the global one).
|
/// The list of library items (shows and collections that are part of a library - or the global one).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// This set is ready only, on most database this will be a view.
|
/// This set is ready only, on most database this will be a view.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public DbSet<LibraryItem> LibraryItems { get; set; }
|
public IQueryable<BagItem> LibraryItems =>
|
||||||
|
Shows.Select(x => new BagItem
|
||||||
|
{
|
||||||
|
ID = x.ID,
|
||||||
|
Slug = x.Slug,
|
||||||
|
Name = x.Name,
|
||||||
|
AirDate = x.StartAir,
|
||||||
|
Poster = x.Poster,
|
||||||
|
Rest = x
|
||||||
|
}).Union(Movies.Select(x => new BagItem
|
||||||
|
{
|
||||||
|
ID = x.ID,
|
||||||
|
Slug = x.Slug,
|
||||||
|
Name = x.Name,
|
||||||
|
AirDate = x.AirDate,
|
||||||
|
Poster = x.Poster,
|
||||||
|
Rest = x
|
||||||
|
})).Union(Collections.Select(x => new BagItem
|
||||||
|
{
|
||||||
|
ID = x.ID,
|
||||||
|
Slug = x.Slug,
|
||||||
|
Name = x.Name,
|
||||||
|
AirDate = null,
|
||||||
|
Poster = x.Poster,
|
||||||
|
Rest = x
|
||||||
|
}));
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Add a many to many link between two resources.
|
/// Add a many to many link between two resources.
|
||||||
@ -138,14 +153,6 @@ namespace Kyoo.Postgresql
|
|||||||
: base(options)
|
: base(options)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get the name of the metadata table of the given type.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">The type related to the metadata</typeparam>
|
|
||||||
/// <returns>The name of the table containing the metadata.</returns>
|
|
||||||
protected abstract string MetadataName<T>()
|
|
||||||
where T : IMetadata;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get the name of the link table of the two given types.
|
/// Get the name of the link table of the two given types.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -265,15 +272,16 @@ namespace Kyoo.Postgresql
|
|||||||
.WithOne(x => x.Season)
|
.WithOne(x => x.Season)
|
||||||
.OnDelete(DeleteBehavior.Cascade);
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
modelBuilder.Entity<Movie>()
|
||||||
|
.HasOne(x => x.Studio)
|
||||||
|
.WithMany(x => x.Movies)
|
||||||
|
.OnDelete(DeleteBehavior.SetNull);
|
||||||
modelBuilder.Entity<Show>()
|
modelBuilder.Entity<Show>()
|
||||||
.HasOne(x => x.Studio)
|
.HasOne(x => x.Studio)
|
||||||
.WithMany(x => x.Shows)
|
.WithMany(x => x.Shows)
|
||||||
.OnDelete(DeleteBehavior.SetNull);
|
.OnDelete(DeleteBehavior.SetNull);
|
||||||
|
|
||||||
_HasManyToMany<Library, Collection>(modelBuilder, x => x.Collections, x => x.Libraries);
|
|
||||||
_HasManyToMany<Library, Show>(modelBuilder, x => x.Shows, x => x.Libraries);
|
|
||||||
_HasManyToMany<Collection, Show>(modelBuilder, x => x.Shows, x => x.Collections);
|
_HasManyToMany<Collection, Show>(modelBuilder, x => x.Shows, x => x.Collections);
|
||||||
_HasManyToMany<Show, Genre>(modelBuilder, x => x.Genres, x => x.Shows);
|
|
||||||
|
|
||||||
modelBuilder.Entity<User>()
|
modelBuilder.Entity<User>()
|
||||||
.HasMany(x => x.Watched)
|
.HasMany(x => x.Watched)
|
||||||
@ -281,14 +289,15 @@ namespace Kyoo.Postgresql
|
|||||||
.UsingEntity(x => x.ToTable(LinkName<User, Show>()));
|
.UsingEntity(x => x.ToTable(LinkName<User, Show>()));
|
||||||
|
|
||||||
_HasMetadata<Collection>(modelBuilder);
|
_HasMetadata<Collection>(modelBuilder);
|
||||||
|
_HasMetadata<Movie>(modelBuilder);
|
||||||
_HasMetadata<Show>(modelBuilder);
|
_HasMetadata<Show>(modelBuilder);
|
||||||
_HasMetadata<Season>(modelBuilder);
|
_HasMetadata<Season>(modelBuilder);
|
||||||
_HasMetadata<Episode>(modelBuilder);
|
_HasMetadata<Episode>(modelBuilder);
|
||||||
_HasMetadata<People>(modelBuilder);
|
_HasMetadata<People>(modelBuilder);
|
||||||
_HasMetadata<Studio>(modelBuilder);
|
_HasMetadata<Studio>(modelBuilder);
|
||||||
|
|
||||||
_HasImages<LibraryItem>(modelBuilder);
|
|
||||||
_HasImages<Collection>(modelBuilder);
|
_HasImages<Collection>(modelBuilder);
|
||||||
|
_HasImages<Movie>(modelBuilder);
|
||||||
_HasImages<Show>(modelBuilder);
|
_HasImages<Show>(modelBuilder);
|
||||||
_HasImages<Season>(modelBuilder);
|
_HasImages<Season>(modelBuilder);
|
||||||
_HasImages<Episode>(modelBuilder);
|
_HasImages<Episode>(modelBuilder);
|
||||||
@ -299,28 +308,15 @@ namespace Kyoo.Postgresql
|
|||||||
modelBuilder.Entity<WatchedEpisode>()
|
modelBuilder.Entity<WatchedEpisode>()
|
||||||
.HasKey(x => new { User = x.UserID, Episode = x.EpisodeID });
|
.HasKey(x => new { User = x.UserID, Episode = x.EpisodeID });
|
||||||
|
|
||||||
modelBuilder.Entity<Collection>().Property(x => x.Slug).IsRequired();
|
|
||||||
modelBuilder.Entity<Genre>().Property(x => x.Slug).IsRequired();
|
|
||||||
modelBuilder.Entity<Library>().Property(x => x.Slug).IsRequired();
|
|
||||||
modelBuilder.Entity<People>().Property(x => x.Slug).IsRequired();
|
|
||||||
modelBuilder.Entity<Show>().Property(x => x.Slug).IsRequired();
|
|
||||||
modelBuilder.Entity<Season>().Property(x => x.Slug).IsRequired();
|
|
||||||
modelBuilder.Entity<Episode>().Property(x => x.Slug).IsRequired();
|
|
||||||
modelBuilder.Entity<Studio>().Property(x => x.Slug).IsRequired();
|
|
||||||
modelBuilder.Entity<User>().Property(x => x.Slug).IsRequired();
|
|
||||||
|
|
||||||
modelBuilder.Entity<Collection>()
|
modelBuilder.Entity<Collection>()
|
||||||
.HasIndex(x => x.Slug)
|
.HasIndex(x => x.Slug)
|
||||||
.IsUnique();
|
.IsUnique();
|
||||||
modelBuilder.Entity<Genre>()
|
|
||||||
.HasIndex(x => x.Slug)
|
|
||||||
.IsUnique();
|
|
||||||
modelBuilder.Entity<Library>()
|
|
||||||
.HasIndex(x => x.Slug)
|
|
||||||
.IsUnique();
|
|
||||||
modelBuilder.Entity<People>()
|
modelBuilder.Entity<People>()
|
||||||
.HasIndex(x => x.Slug)
|
.HasIndex(x => x.Slug)
|
||||||
.IsUnique();
|
.IsUnique();
|
||||||
|
modelBuilder.Entity<Movie>()
|
||||||
|
.HasIndex(x => x.Slug)
|
||||||
|
.IsUnique();
|
||||||
modelBuilder.Entity<Show>()
|
modelBuilder.Entity<Show>()
|
||||||
.HasIndex(x => x.Slug)
|
.HasIndex(x => x.Slug)
|
||||||
.IsUnique();
|
.IsUnique();
|
||||||
@ -342,9 +338,6 @@ namespace Kyoo.Postgresql
|
|||||||
modelBuilder.Entity<User>()
|
modelBuilder.Entity<User>()
|
||||||
.HasIndex(x => x.Slug)
|
.HasIndex(x => x.Slug)
|
||||||
.IsUnique();
|
.IsUnique();
|
||||||
|
|
||||||
modelBuilder.Entity<LibraryItem>()
|
|
||||||
.ToView("library_items");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -18,4 +18,8 @@
|
|||||||
<ProjectReference Include="../Kyoo.Abstractions/Kyoo.Abstractions.csproj" />
|
<ProjectReference Include="../Kyoo.Abstractions/Kyoo.Abstractions.csproj" />
|
||||||
<FrameworkReference Include="Microsoft.AspNetCore.App" />
|
<FrameworkReference Include="Microsoft.AspNetCore.App" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Migrations\" />
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -1,872 +0,0 @@
|
|||||||
// 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 System.Collections.Generic;
|
|
||||||
using Kyoo.Abstractions.Models;
|
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
|
||||||
|
|
||||||
namespace Kyoo.Postgresql.Migrations
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The initial migration that build most of the database.
|
|
||||||
/// </summary>
|
|
||||||
[DbContext(typeof(PostgresContext))]
|
|
||||||
[Migration("20210801171613_Initial")]
|
|
||||||
public partial class Initial : Migration
|
|
||||||
{
|
|
||||||
/// <inheritdoc/>
|
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.AlterDatabase()
|
|
||||||
.Annotation("Npgsql:Enum:item_type", "show,movie,collection")
|
|
||||||
.Annotation("Npgsql:Enum:status", "unknown,finished,airing,planned")
|
|
||||||
.Annotation("Npgsql:Enum:stream_type", "unknown,video,audio,subtitle,attachment");
|
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "collections",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
id = table.Column<int>(type: "integer", nullable: false)
|
|
||||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
|
||||||
slug = table.Column<string>(type: "text", nullable: false),
|
|
||||||
name = table.Column<string>(type: "text", nullable: true),
|
|
||||||
images = table.Column<Dictionary<int, string>>(type: "jsonb", nullable: true),
|
|
||||||
overview = table.Column<string>(type: "text", nullable: true)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("pk_collections", x => x.id);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "genres",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
id = table.Column<int>(type: "integer", nullable: false)
|
|
||||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
|
||||||
slug = table.Column<string>(type: "text", nullable: false),
|
|
||||||
name = table.Column<string>(type: "text", nullable: true)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("pk_genres", x => x.id);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "libraries",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
id = table.Column<int>(type: "integer", nullable: false)
|
|
||||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
|
||||||
slug = table.Column<string>(type: "text", nullable: false),
|
|
||||||
name = table.Column<string>(type: "text", nullable: true),
|
|
||||||
paths = table.Column<string[]>(type: "text[]", nullable: true)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("pk_libraries", x => x.id);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "people",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
id = table.Column<int>(type: "integer", nullable: false)
|
|
||||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
|
||||||
slug = table.Column<string>(type: "text", nullable: false),
|
|
||||||
name = table.Column<string>(type: "text", nullable: true),
|
|
||||||
images = table.Column<Dictionary<int, string>>(type: "jsonb", nullable: true)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("pk_people", x => x.id);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "providers",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
id = table.Column<int>(type: "integer", nullable: false)
|
|
||||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
|
||||||
slug = table.Column<string>(type: "text", nullable: false),
|
|
||||||
name = table.Column<string>(type: "text", nullable: true),
|
|
||||||
images = table.Column<Dictionary<int, string>>(type: "jsonb", nullable: true)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("pk_providers", x => x.id);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "studios",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
id = table.Column<int>(type: "integer", nullable: false)
|
|
||||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
|
||||||
slug = table.Column<string>(type: "text", nullable: false),
|
|
||||||
name = table.Column<string>(type: "text", nullable: true)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("pk_studios", x => x.id);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "users",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
id = table.Column<int>(type: "integer", nullable: false)
|
|
||||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
|
||||||
slug = table.Column<string>(type: "text", nullable: false),
|
|
||||||
username = table.Column<string>(type: "text", nullable: true),
|
|
||||||
email = table.Column<string>(type: "text", nullable: true),
|
|
||||||
password = table.Column<string>(type: "text", nullable: true),
|
|
||||||
permissions = table.Column<string[]>(type: "text[]", nullable: true),
|
|
||||||
extra_data = table.Column<Dictionary<string, string>>(type: "jsonb", nullable: true),
|
|
||||||
images = table.Column<Dictionary<int, string>>(type: "jsonb", nullable: true)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("pk_users", x => x.id);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "link_library_collection",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
collection_id = table.Column<int>(type: "integer", nullable: false),
|
|
||||||
library_id = table.Column<int>(type: "integer", nullable: false)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("pk_link_library_collection", x => new { x.collection_id, x.library_id });
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "fk_link_library_collection_collections_collection_id",
|
|
||||||
column: x => x.collection_id,
|
|
||||||
principalTable: "collections",
|
|
||||||
principalColumn: "id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "fk_link_library_collection_libraries_library_id",
|
|
||||||
column: x => x.library_id,
|
|
||||||
principalTable: "libraries",
|
|
||||||
principalColumn: "id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "collection_metadata_id",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
resource_id = table.Column<int>(type: "integer", nullable: false),
|
|
||||||
provider_id = table.Column<int>(type: "integer", nullable: false),
|
|
||||||
data_id = table.Column<string>(type: "text", nullable: true),
|
|
||||||
link = table.Column<string>(type: "text", nullable: true)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("pk_collection_metadata_id", x => new { x.resource_id, x.provider_id });
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "fk_collection_metadata_id_collections_collection_id",
|
|
||||||
column: x => x.resource_id,
|
|
||||||
principalTable: "collections",
|
|
||||||
principalColumn: "id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "fk_collection_metadata_id_providers_provider_id",
|
|
||||||
column: x => x.provider_id,
|
|
||||||
principalTable: "providers",
|
|
||||||
principalColumn: "id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "link_library_provider",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
library_id = table.Column<int>(type: "integer", nullable: false),
|
|
||||||
provider_id = table.Column<int>(type: "integer", nullable: false)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("pk_link_library_provider", x => new { x.library_id, x.provider_id });
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "fk_link_library_provider_libraries_library_id",
|
|
||||||
column: x => x.library_id,
|
|
||||||
principalTable: "libraries",
|
|
||||||
principalColumn: "id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "fk_link_library_provider_providers_provider_id",
|
|
||||||
column: x => x.provider_id,
|
|
||||||
principalTable: "providers",
|
|
||||||
principalColumn: "id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "people_metadata_id",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
resource_id = table.Column<int>(type: "integer", nullable: false),
|
|
||||||
provider_id = table.Column<int>(type: "integer", nullable: false),
|
|
||||||
data_id = table.Column<string>(type: "text", nullable: true),
|
|
||||||
link = table.Column<string>(type: "text", nullable: true)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("pk_people_metadata_id", x => new { x.resource_id, x.provider_id });
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "fk_people_metadata_id_people_people_id",
|
|
||||||
column: x => x.resource_id,
|
|
||||||
principalTable: "people",
|
|
||||||
principalColumn: "id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "fk_people_metadata_id_providers_provider_id",
|
|
||||||
column: x => x.provider_id,
|
|
||||||
principalTable: "providers",
|
|
||||||
principalColumn: "id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "shows",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
id = table.Column<int>(type: "integer", nullable: false)
|
|
||||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
|
||||||
slug = table.Column<string>(type: "text", nullable: false),
|
|
||||||
title = table.Column<string>(type: "text", nullable: true),
|
|
||||||
aliases = table.Column<string[]>(type: "text[]", nullable: true),
|
|
||||||
path = table.Column<string>(type: "text", nullable: true),
|
|
||||||
overview = table.Column<string>(type: "text", nullable: true),
|
|
||||||
status = table.Column<Status>(type: "status", nullable: false),
|
|
||||||
start_air = table.Column<DateTime>(type: "timestamp without time zone", nullable: true),
|
|
||||||
end_air = table.Column<DateTime>(type: "timestamp without time zone", nullable: true),
|
|
||||||
images = table.Column<Dictionary<int, string>>(type: "jsonb", nullable: true),
|
|
||||||
is_movie = table.Column<bool>(type: "boolean", nullable: false),
|
|
||||||
studio_id = table.Column<int>(type: "integer", nullable: true)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("pk_shows", x => x.id);
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "fk_shows_studios_studio_id",
|
|
||||||
column: x => x.studio_id,
|
|
||||||
principalTable: "studios",
|
|
||||||
principalColumn: "id",
|
|
||||||
onDelete: ReferentialAction.SetNull);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "studio_metadata_id",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
resource_id = table.Column<int>(type: "integer", nullable: false),
|
|
||||||
provider_id = table.Column<int>(type: "integer", nullable: false),
|
|
||||||
data_id = table.Column<string>(type: "text", nullable: true),
|
|
||||||
link = table.Column<string>(type: "text", nullable: true)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("pk_studio_metadata_id", x => new { x.resource_id, x.provider_id });
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "fk_studio_metadata_id_providers_provider_id",
|
|
||||||
column: x => x.provider_id,
|
|
||||||
principalTable: "providers",
|
|
||||||
principalColumn: "id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "fk_studio_metadata_id_studios_studio_id",
|
|
||||||
column: x => x.resource_id,
|
|
||||||
principalTable: "studios",
|
|
||||||
principalColumn: "id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "link_collection_show",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
collection_id = table.Column<int>(type: "integer", nullable: false),
|
|
||||||
show_id = table.Column<int>(type: "integer", nullable: false)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("pk_link_collection_show", x => new { x.collection_id, x.show_id });
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "fk_link_collection_show_collections_collection_id",
|
|
||||||
column: x => x.collection_id,
|
|
||||||
principalTable: "collections",
|
|
||||||
principalColumn: "id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "fk_link_collection_show_shows_show_id",
|
|
||||||
column: x => x.show_id,
|
|
||||||
principalTable: "shows",
|
|
||||||
principalColumn: "id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "link_library_show",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
library_id = table.Column<int>(type: "integer", nullable: false),
|
|
||||||
show_id = table.Column<int>(type: "integer", nullable: false)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("pk_link_library_show", x => new { x.library_id, x.show_id });
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "fk_link_library_show_libraries_library_id",
|
|
||||||
column: x => x.library_id,
|
|
||||||
principalTable: "libraries",
|
|
||||||
principalColumn: "id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "fk_link_library_show_shows_show_id",
|
|
||||||
column: x => x.show_id,
|
|
||||||
principalTable: "shows",
|
|
||||||
principalColumn: "id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "link_show_genre",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
genre_id = table.Column<int>(type: "integer", nullable: false),
|
|
||||||
show_id = table.Column<int>(type: "integer", nullable: false)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("pk_link_show_genre", x => new { x.genre_id, x.show_id });
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "fk_link_show_genre_genres_genre_id",
|
|
||||||
column: x => x.genre_id,
|
|
||||||
principalTable: "genres",
|
|
||||||
principalColumn: "id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "fk_link_show_genre_shows_show_id",
|
|
||||||
column: x => x.show_id,
|
|
||||||
principalTable: "shows",
|
|
||||||
principalColumn: "id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "link_user_show",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
users_id = table.Column<int>(type: "integer", nullable: false),
|
|
||||||
watched_id = table.Column<int>(type: "integer", nullable: false)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("pk_link_user_show", x => new { x.users_id, x.watched_id });
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "fk_link_user_show_shows_watched_id",
|
|
||||||
column: x => x.watched_id,
|
|
||||||
principalTable: "shows",
|
|
||||||
principalColumn: "id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "fk_link_user_show_users_users_id",
|
|
||||||
column: x => x.users_id,
|
|
||||||
principalTable: "users",
|
|
||||||
principalColumn: "id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "people_roles",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
id = table.Column<int>(type: "integer", nullable: false)
|
|
||||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
|
||||||
people_id = table.Column<int>(type: "integer", nullable: false),
|
|
||||||
show_id = table.Column<int>(type: "integer", nullable: false),
|
|
||||||
type = table.Column<string>(type: "text", nullable: true),
|
|
||||||
role = table.Column<string>(type: "text", nullable: true)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("pk_people_roles", x => x.id);
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "fk_people_roles_people_people_id",
|
|
||||||
column: x => x.people_id,
|
|
||||||
principalTable: "people",
|
|
||||||
principalColumn: "id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "fk_people_roles_shows_show_id",
|
|
||||||
column: x => x.show_id,
|
|
||||||
principalTable: "shows",
|
|
||||||
principalColumn: "id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "seasons",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
id = table.Column<int>(type: "integer", nullable: false)
|
|
||||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
|
||||||
slug = table.Column<string>(type: "text", nullable: true),
|
|
||||||
show_id = table.Column<int>(type: "integer", nullable: false),
|
|
||||||
season_number = table.Column<int>(type: "integer", nullable: false),
|
|
||||||
title = table.Column<string>(type: "text", nullable: true),
|
|
||||||
overview = table.Column<string>(type: "text", nullable: true),
|
|
||||||
start_date = table.Column<DateTime>(type: "timestamp without time zone", nullable: true),
|
|
||||||
end_date = table.Column<DateTime>(type: "timestamp without time zone", nullable: true),
|
|
||||||
images = table.Column<Dictionary<int, string>>(type: "jsonb", nullable: true)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("pk_seasons", x => x.id);
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "fk_seasons_shows_show_id",
|
|
||||||
column: x => x.show_id,
|
|
||||||
principalTable: "shows",
|
|
||||||
principalColumn: "id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "show_metadata_id",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
resource_id = table.Column<int>(type: "integer", nullable: false),
|
|
||||||
provider_id = table.Column<int>(type: "integer", nullable: false),
|
|
||||||
data_id = table.Column<string>(type: "text", nullable: true),
|
|
||||||
link = table.Column<string>(type: "text", nullable: true)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("pk_show_metadata_id", x => new { x.resource_id, x.provider_id });
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "fk_show_metadata_id_providers_provider_id",
|
|
||||||
column: x => x.provider_id,
|
|
||||||
principalTable: "providers",
|
|
||||||
principalColumn: "id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "fk_show_metadata_id_shows_show_id",
|
|
||||||
column: x => x.resource_id,
|
|
||||||
principalTable: "shows",
|
|
||||||
principalColumn: "id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "episodes",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
id = table.Column<int>(type: "integer", nullable: false)
|
|
||||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
|
||||||
slug = table.Column<string>(type: "text", nullable: true),
|
|
||||||
show_id = table.Column<int>(type: "integer", nullable: false),
|
|
||||||
season_id = table.Column<int>(type: "integer", nullable: true),
|
|
||||||
season_number = table.Column<int>(type: "integer", nullable: true),
|
|
||||||
episode_number = table.Column<int>(type: "integer", nullable: true),
|
|
||||||
absolute_number = table.Column<int>(type: "integer", nullable: true),
|
|
||||||
path = table.Column<string>(type: "text", nullable: true),
|
|
||||||
images = table.Column<Dictionary<int, string>>(type: "jsonb", nullable: true),
|
|
||||||
title = table.Column<string>(type: "text", nullable: true),
|
|
||||||
overview = table.Column<string>(type: "text", nullable: true),
|
|
||||||
release_date = table.Column<DateTime>(type: "timestamp without time zone", nullable: true)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("pk_episodes", x => x.id);
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "fk_episodes_seasons_season_id",
|
|
||||||
column: x => x.season_id,
|
|
||||||
principalTable: "seasons",
|
|
||||||
principalColumn: "id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "fk_episodes_shows_show_id",
|
|
||||||
column: x => x.show_id,
|
|
||||||
principalTable: "shows",
|
|
||||||
principalColumn: "id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "season_metadata_id",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
resource_id = table.Column<int>(type: "integer", nullable: false),
|
|
||||||
provider_id = table.Column<int>(type: "integer", nullable: false),
|
|
||||||
data_id = table.Column<string>(type: "text", nullable: true),
|
|
||||||
link = table.Column<string>(type: "text", nullable: true)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("pk_season_metadata_id", x => new { x.resource_id, x.provider_id });
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "fk_season_metadata_id_providers_provider_id",
|
|
||||||
column: x => x.provider_id,
|
|
||||||
principalTable: "providers",
|
|
||||||
principalColumn: "id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "fk_season_metadata_id_seasons_season_id",
|
|
||||||
column: x => x.resource_id,
|
|
||||||
principalTable: "seasons",
|
|
||||||
principalColumn: "id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "episode_metadata_id",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
resource_id = table.Column<int>(type: "integer", nullable: false),
|
|
||||||
provider_id = table.Column<int>(type: "integer", nullable: false),
|
|
||||||
data_id = table.Column<string>(type: "text", nullable: true),
|
|
||||||
link = table.Column<string>(type: "text", nullable: true)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("pk_episode_metadata_id", x => new { x.resource_id, x.provider_id });
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "fk_episode_metadata_id_episodes_episode_id",
|
|
||||||
column: x => x.resource_id,
|
|
||||||
principalTable: "episodes",
|
|
||||||
principalColumn: "id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "fk_episode_metadata_id_providers_provider_id",
|
|
||||||
column: x => x.provider_id,
|
|
||||||
principalTable: "providers",
|
|
||||||
principalColumn: "id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "tracks",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
id = table.Column<int>(type: "integer", nullable: false)
|
|
||||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
|
||||||
slug = table.Column<string>(type: "text", nullable: true),
|
|
||||||
title = table.Column<string>(type: "text", nullable: true),
|
|
||||||
language = table.Column<string>(type: "text", nullable: true),
|
|
||||||
codec = table.Column<string>(type: "text", nullable: true),
|
|
||||||
is_default = table.Column<bool>(type: "boolean", nullable: false),
|
|
||||||
is_forced = table.Column<bool>(type: "boolean", nullable: false),
|
|
||||||
is_external = table.Column<bool>(type: "boolean", nullable: false),
|
|
||||||
path = table.Column<string>(type: "text", nullable: true),
|
|
||||||
type = table.Column<object>(type: "stream_type", nullable: false),
|
|
||||||
episode_id = table.Column<int>(type: "integer", nullable: false),
|
|
||||||
track_index = table.Column<int>(type: "integer", nullable: false)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("pk_tracks", x => x.id);
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "fk_tracks_episodes_episode_id",
|
|
||||||
column: x => x.episode_id,
|
|
||||||
principalTable: "episodes",
|
|
||||||
principalColumn: "id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "watched_episodes",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
user_id = table.Column<int>(type: "integer", nullable: false),
|
|
||||||
episode_id = table.Column<int>(type: "integer", nullable: false),
|
|
||||||
watched_percentage = table.Column<int>(type: "integer", nullable: false)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("pk_watched_episodes", x => new { x.user_id, x.episode_id });
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "fk_watched_episodes_episodes_episode_id",
|
|
||||||
column: x => x.episode_id,
|
|
||||||
principalTable: "episodes",
|
|
||||||
principalColumn: "id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "fk_watched_episodes_users_user_id",
|
|
||||||
column: x => x.user_id,
|
|
||||||
principalTable: "users",
|
|
||||||
principalColumn: "id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "ix_collection_metadata_id_provider_id",
|
|
||||||
table: "collection_metadata_id",
|
|
||||||
column: "provider_id");
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "ix_collections_slug",
|
|
||||||
table: "collections",
|
|
||||||
column: "slug",
|
|
||||||
unique: true);
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "ix_episode_metadata_id_provider_id",
|
|
||||||
table: "episode_metadata_id",
|
|
||||||
column: "provider_id");
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "ix_episodes_season_id",
|
|
||||||
table: "episodes",
|
|
||||||
column: "season_id");
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "ix_episodes_show_id_season_number_episode_number_absolute_numb",
|
|
||||||
table: "episodes",
|
|
||||||
columns: new[] { "show_id", "season_number", "episode_number", "absolute_number" },
|
|
||||||
unique: true);
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "ix_episodes_slug",
|
|
||||||
table: "episodes",
|
|
||||||
column: "slug",
|
|
||||||
unique: true);
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "ix_genres_slug",
|
|
||||||
table: "genres",
|
|
||||||
column: "slug",
|
|
||||||
unique: true);
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "ix_libraries_slug",
|
|
||||||
table: "libraries",
|
|
||||||
column: "slug",
|
|
||||||
unique: true);
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "ix_link_collection_show_show_id",
|
|
||||||
table: "link_collection_show",
|
|
||||||
column: "show_id");
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "ix_link_library_collection_library_id",
|
|
||||||
table: "link_library_collection",
|
|
||||||
column: "library_id");
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "ix_link_library_provider_provider_id",
|
|
||||||
table: "link_library_provider",
|
|
||||||
column: "provider_id");
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "ix_link_library_show_show_id",
|
|
||||||
table: "link_library_show",
|
|
||||||
column: "show_id");
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "ix_link_show_genre_show_id",
|
|
||||||
table: "link_show_genre",
|
|
||||||
column: "show_id");
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "ix_link_user_show_watched_id",
|
|
||||||
table: "link_user_show",
|
|
||||||
column: "watched_id");
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "ix_people_slug",
|
|
||||||
table: "people",
|
|
||||||
column: "slug",
|
|
||||||
unique: true);
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "ix_people_metadata_id_provider_id",
|
|
||||||
table: "people_metadata_id",
|
|
||||||
column: "provider_id");
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "ix_people_roles_people_id",
|
|
||||||
table: "people_roles",
|
|
||||||
column: "people_id");
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "ix_people_roles_show_id",
|
|
||||||
table: "people_roles",
|
|
||||||
column: "show_id");
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "ix_providers_slug",
|
|
||||||
table: "providers",
|
|
||||||
column: "slug",
|
|
||||||
unique: true);
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "ix_season_metadata_id_provider_id",
|
|
||||||
table: "season_metadata_id",
|
|
||||||
column: "provider_id");
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "ix_seasons_show_id_season_number",
|
|
||||||
table: "seasons",
|
|
||||||
columns: new[] { "show_id", "season_number" },
|
|
||||||
unique: true);
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "ix_seasons_slug",
|
|
||||||
table: "seasons",
|
|
||||||
column: "slug",
|
|
||||||
unique: true);
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "ix_show_metadata_id_provider_id",
|
|
||||||
table: "show_metadata_id",
|
|
||||||
column: "provider_id");
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "ix_shows_slug",
|
|
||||||
table: "shows",
|
|
||||||
column: "slug",
|
|
||||||
unique: true);
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "ix_shows_studio_id",
|
|
||||||
table: "shows",
|
|
||||||
column: "studio_id");
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "ix_studio_metadata_id_provider_id",
|
|
||||||
table: "studio_metadata_id",
|
|
||||||
column: "provider_id");
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "ix_studios_slug",
|
|
||||||
table: "studios",
|
|
||||||
column: "slug",
|
|
||||||
unique: true);
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "ix_tracks_episode_id_type_language_track_index_is_forced",
|
|
||||||
table: "tracks",
|
|
||||||
columns: new[] { "episode_id", "type", "language", "track_index", "is_forced" },
|
|
||||||
unique: true);
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "ix_tracks_slug",
|
|
||||||
table: "tracks",
|
|
||||||
column: "slug",
|
|
||||||
unique: true);
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "ix_users_slug",
|
|
||||||
table: "users",
|
|
||||||
column: "slug",
|
|
||||||
unique: true);
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "ix_watched_episodes_episode_id",
|
|
||||||
table: "watched_episodes",
|
|
||||||
column: "episode_id");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
protected override void Down(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "collection_metadata_id");
|
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "episode_metadata_id");
|
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "link_collection_show");
|
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "link_library_collection");
|
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "link_library_provider");
|
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "link_library_show");
|
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "link_show_genre");
|
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "link_user_show");
|
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "people_metadata_id");
|
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "people_roles");
|
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "season_metadata_id");
|
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "show_metadata_id");
|
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "studio_metadata_id");
|
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "tracks");
|
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "watched_episodes");
|
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "collections");
|
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "libraries");
|
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "genres");
|
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "people");
|
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "providers");
|
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "episodes");
|
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "users");
|
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "seasons");
|
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "shows");
|
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "studios");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,192 +0,0 @@
|
|||||||
// 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 Microsoft.EntityFrameworkCore.Infrastructure;
|
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
|
|
||||||
namespace Kyoo.Postgresql.Migrations
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// A migration that adds postgres triggers to update slugs.
|
|
||||||
/// </summary>
|
|
||||||
[DbContext(typeof(PostgresContext))]
|
|
||||||
[Migration("20210801171641_Triggers")]
|
|
||||||
public partial class Triggers : Migration
|
|
||||||
{
|
|
||||||
/// <inheritdoc/>
|
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
// language=PostgreSQL
|
|
||||||
migrationBuilder.Sql(@"
|
|
||||||
CREATE FUNCTION season_slug_update()
|
|
||||||
RETURNS TRIGGER
|
|
||||||
LANGUAGE PLPGSQL
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
NEW.slug := CONCAT(
|
|
||||||
(SELECT slug FROM shows WHERE id = NEW.show_id),
|
|
||||||
'-s',
|
|
||||||
NEW.season_number
|
|
||||||
);
|
|
||||||
RETURN NEW;
|
|
||||||
END
|
|
||||||
$$;");
|
|
||||||
|
|
||||||
// language=PostgreSQL
|
|
||||||
migrationBuilder.Sql(@"
|
|
||||||
CREATE TRIGGER season_slug_trigger BEFORE INSERT OR UPDATE OF season_number, show_id ON seasons
|
|
||||||
FOR EACH ROW EXECUTE PROCEDURE season_slug_update();");
|
|
||||||
|
|
||||||
// language=PostgreSQL
|
|
||||||
migrationBuilder.Sql(@"
|
|
||||||
CREATE FUNCTION episode_slug_update()
|
|
||||||
RETURNS TRIGGER
|
|
||||||
LANGUAGE PLPGSQL
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
NEW.slug := CONCAT(
|
|
||||||
(SELECT slug FROM shows WHERE id = NEW.show_id),
|
|
||||||
CASE
|
|
||||||
WHEN NEW.season_number IS NULL AND NEW.episode_number IS NULL THEN NULL
|
|
||||||
WHEN NEW.season_number IS NULL THEN CONCAT('-', NEW.absolute_number)
|
|
||||||
ELSE CONCAT('-s', NEW.season_number, 'e', NEW.episode_number)
|
|
||||||
END
|
|
||||||
);
|
|
||||||
RETURN NEW;
|
|
||||||
END
|
|
||||||
$$;");
|
|
||||||
|
|
||||||
// language=PostgreSQL
|
|
||||||
migrationBuilder.Sql(@"
|
|
||||||
CREATE TRIGGER episode_slug_trigger
|
|
||||||
BEFORE INSERT OR UPDATE OF absolute_number, episode_number, season_number, show_id ON episodes
|
|
||||||
FOR EACH ROW EXECUTE PROCEDURE episode_slug_update();");
|
|
||||||
|
|
||||||
// language=PostgreSQL
|
|
||||||
migrationBuilder.Sql(@"
|
|
||||||
CREATE FUNCTION show_slug_update()
|
|
||||||
RETURNS TRIGGER
|
|
||||||
LANGUAGE PLPGSQL
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
UPDATE seasons SET slug = CONCAT(NEW.slug, '-s', season_number) WHERE show_id = NEW.id;
|
|
||||||
UPDATE episodes SET slug = CASE
|
|
||||||
WHEN season_number IS NULL AND episode_number IS NULL THEN NEW.slug
|
|
||||||
WHEN season_number IS NULL THEN CONCAT(NEW.slug, '-', absolute_number)
|
|
||||||
ELSE CONCAT(NEW.slug, '-s', season_number, 'e', episode_number)
|
|
||||||
END WHERE show_id = NEW.id;
|
|
||||||
RETURN NEW;
|
|
||||||
END
|
|
||||||
$$;");
|
|
||||||
// language=PostgreSQL
|
|
||||||
migrationBuilder.Sql(@"
|
|
||||||
CREATE TRIGGER show_slug_trigger AFTER UPDATE OF slug ON shows
|
|
||||||
FOR EACH ROW EXECUTE PROCEDURE show_slug_update();");
|
|
||||||
|
|
||||||
// language=PostgreSQL
|
|
||||||
migrationBuilder.Sql(@"
|
|
||||||
CREATE FUNCTION episode_update_tracks_slug()
|
|
||||||
RETURNS TRIGGER
|
|
||||||
LANGUAGE PLPGSQL
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
UPDATE tracks SET slug = CONCAT(
|
|
||||||
NEW.slug,
|
|
||||||
'.', language,
|
|
||||||
CASE (track_index)
|
|
||||||
WHEN 0 THEN ''
|
|
||||||
ELSE CONCAT('-', track_index)
|
|
||||||
END,
|
|
||||||
CASE (is_forced)
|
|
||||||
WHEN false THEN ''
|
|
||||||
ELSE '.forced'
|
|
||||||
END,
|
|
||||||
'.', type
|
|
||||||
) WHERE episode_id = NEW.id;
|
|
||||||
RETURN NEW;
|
|
||||||
END;
|
|
||||||
$$;");
|
|
||||||
// language=PostgreSQL
|
|
||||||
migrationBuilder.Sql(@"
|
|
||||||
CREATE TRIGGER episode_track_slug_trigger AFTER UPDATE OF slug ON episodes
|
|
||||||
FOR EACH ROW EXECUTE PROCEDURE episode_update_tracks_slug();");
|
|
||||||
|
|
||||||
// language=PostgreSQL
|
|
||||||
migrationBuilder.Sql(@"
|
|
||||||
CREATE FUNCTION track_slug_update()
|
|
||||||
RETURNS TRIGGER
|
|
||||||
LANGUAGE PLPGSQL
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
IF NEW.track_index = 0 THEN
|
|
||||||
NEW.track_index := (SELECT COUNT(*) FROM tracks
|
|
||||||
WHERE episode_id = NEW.episode_id AND type = NEW.type
|
|
||||||
AND language = NEW.language AND is_forced = NEW.is_forced);
|
|
||||||
END IF;
|
|
||||||
NEW.slug := CONCAT(
|
|
||||||
(SELECT slug FROM episodes WHERE id = NEW.episode_id),
|
|
||||||
'.', COALESCE(NEW.language, 'und'),
|
|
||||||
CASE (NEW.track_index)
|
|
||||||
WHEN 0 THEN ''
|
|
||||||
ELSE CONCAT('-', NEW.track_index)
|
|
||||||
END,
|
|
||||||
CASE (NEW.is_forced)
|
|
||||||
WHEN false THEN ''
|
|
||||||
ELSE '.forced'
|
|
||||||
END,
|
|
||||||
'.', NEW.type
|
|
||||||
);
|
|
||||||
RETURN NEW;
|
|
||||||
END
|
|
||||||
$$;");
|
|
||||||
// language=PostgreSQL
|
|
||||||
migrationBuilder.Sql(@"
|
|
||||||
CREATE TRIGGER track_slug_trigger
|
|
||||||
BEFORE INSERT OR UPDATE OF episode_id, is_forced, language, track_index, type ON tracks
|
|
||||||
FOR EACH ROW EXECUTE PROCEDURE track_slug_update();");
|
|
||||||
|
|
||||||
MigrationHelper.CreateLibraryItemsView(migrationBuilder);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
protected override void Down(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
// language=PostgreSQL
|
|
||||||
migrationBuilder.Sql("DROP TRIGGER show_slug_trigger ON shows;");
|
|
||||||
// language=PostgreSQL
|
|
||||||
migrationBuilder.Sql(@"DROP FUNCTION show_slug_update;");
|
|
||||||
// language=PostgreSQL
|
|
||||||
migrationBuilder.Sql(@"DROP TRIGGER season_slug_trigger ON seasons;");
|
|
||||||
// language=PostgreSQL
|
|
||||||
migrationBuilder.Sql(@"DROP FUNCTION season_slug_update;");
|
|
||||||
// language=PostgreSQL
|
|
||||||
migrationBuilder.Sql("DROP TRIGGER episode_slug_trigger ON episodes;");
|
|
||||||
// language=PostgreSQL
|
|
||||||
migrationBuilder.Sql(@"DROP FUNCTION episode_slug_update;");
|
|
||||||
// language=PostgreSQL
|
|
||||||
migrationBuilder.Sql("DROP TRIGGER track_slug_trigger ON tracks;");
|
|
||||||
// language=PostgreSQL
|
|
||||||
migrationBuilder.Sql(@"DROP FUNCTION track_slug_update;");
|
|
||||||
// language=PostgreSQL
|
|
||||||
migrationBuilder.Sql("DROP TRIGGER episode_track_slug_trigger ON episodes;");
|
|
||||||
// language=PostgreSQL
|
|
||||||
migrationBuilder.Sql(@"DROP FUNCTION episode_update_tracks_slug;");
|
|
||||||
MigrationHelper.DropLibraryItemsView(migrationBuilder);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,114 +0,0 @@
|
|||||||
// 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 Microsoft.EntityFrameworkCore.Infrastructure;
|
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
|
|
||||||
namespace Kyoo.Postgresql.Migrations
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Remove triggers
|
|
||||||
/// </summary>
|
|
||||||
[DbContext(typeof(PostgresContext))]
|
|
||||||
[Migration("20230724144449_RemoveTriggers")]
|
|
||||||
public partial class RemoveTriggers : Migration
|
|
||||||
{
|
|
||||||
/// <inheritdoc/>
|
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
// language=PostgreSQL
|
|
||||||
migrationBuilder.Sql("DROP TRIGGER show_slug_trigger ON shows;");
|
|
||||||
// language=PostgreSQL
|
|
||||||
migrationBuilder.Sql(@"DROP FUNCTION show_slug_update;");
|
|
||||||
// language=PostgreSQL
|
|
||||||
migrationBuilder.Sql(@"DROP TRIGGER season_slug_trigger ON seasons;");
|
|
||||||
// language=PostgreSQL
|
|
||||||
migrationBuilder.Sql(@"DROP FUNCTION season_slug_update;");
|
|
||||||
// language=PostgreSQL
|
|
||||||
migrationBuilder.Sql("DROP TRIGGER episode_slug_trigger ON episodes;");
|
|
||||||
// language=PostgreSQL
|
|
||||||
migrationBuilder.Sql(@"DROP FUNCTION episode_slug_update;");
|
|
||||||
// language=PostgreSQL
|
|
||||||
migrationBuilder.Sql("DROP TRIGGER track_slug_trigger ON tracks;");
|
|
||||||
// language=PostgreSQL
|
|
||||||
migrationBuilder.Sql(@"DROP FUNCTION track_slug_update;");
|
|
||||||
// language=PostgreSQL
|
|
||||||
migrationBuilder.Sql("DROP TRIGGER episode_track_slug_trigger ON episodes;");
|
|
||||||
// language=PostgreSQL
|
|
||||||
migrationBuilder.Sql(@"DROP FUNCTION episode_update_tracks_slug;");
|
|
||||||
|
|
||||||
migrationBuilder.AlterColumn<string>(
|
|
||||||
name: "slug",
|
|
||||||
table: "tracks",
|
|
||||||
type: "text",
|
|
||||||
nullable: false,
|
|
||||||
defaultValue: string.Empty,
|
|
||||||
oldClrType: typeof(string),
|
|
||||||
oldType: "text",
|
|
||||||
oldNullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AlterColumn<string>(
|
|
||||||
name: "slug",
|
|
||||||
table: "seasons",
|
|
||||||
type: "text",
|
|
||||||
nullable: false,
|
|
||||||
defaultValue: string.Empty,
|
|
||||||
oldClrType: typeof(string),
|
|
||||||
oldType: "text",
|
|
||||||
oldNullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AlterColumn<string>(
|
|
||||||
name: "slug",
|
|
||||||
table: "episodes",
|
|
||||||
type: "text",
|
|
||||||
nullable: false,
|
|
||||||
defaultValue: string.Empty,
|
|
||||||
oldClrType: typeof(string),
|
|
||||||
oldType: "text",
|
|
||||||
oldNullable: true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
protected override void Down(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.AlterColumn<string>(
|
|
||||||
name: "slug",
|
|
||||||
table: "tracks",
|
|
||||||
type: "text",
|
|
||||||
nullable: true,
|
|
||||||
oldClrType: typeof(string),
|
|
||||||
oldType: "text");
|
|
||||||
|
|
||||||
migrationBuilder.AlterColumn<string>(
|
|
||||||
name: "slug",
|
|
||||||
table: "seasons",
|
|
||||||
type: "text",
|
|
||||||
nullable: true,
|
|
||||||
oldClrType: typeof(string),
|
|
||||||
oldType: "text");
|
|
||||||
|
|
||||||
migrationBuilder.AlterColumn<string>(
|
|
||||||
name: "slug",
|
|
||||||
table: "episodes",
|
|
||||||
type: "text",
|
|
||||||
nullable: true,
|
|
||||||
oldClrType: typeof(string),
|
|
||||||
oldType: "text");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
@ -1,138 +0,0 @@
|
|||||||
// 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 Microsoft.EntityFrameworkCore.Infrastructure;
|
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace Kyoo.Postgresql.Migrations
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
[DbContext(typeof(PostgresContext))]
|
|
||||||
[Migration("20230726100747_Timestamp")]
|
|
||||||
public partial class Timestamp : Migration
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
MigrationHelper.DropLibraryItemsView(migrationBuilder);
|
|
||||||
|
|
||||||
migrationBuilder.AlterColumn<DateTime>(
|
|
||||||
name: "start_air",
|
|
||||||
table: "shows",
|
|
||||||
type: "timestamp with time zone",
|
|
||||||
nullable: true,
|
|
||||||
oldClrType: typeof(DateTime),
|
|
||||||
oldType: "timestamp without time zone",
|
|
||||||
oldNullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AlterColumn<DateTime>(
|
|
||||||
name: "end_air",
|
|
||||||
table: "shows",
|
|
||||||
type: "timestamp with time zone",
|
|
||||||
nullable: true,
|
|
||||||
oldClrType: typeof(DateTime),
|
|
||||||
oldType: "timestamp without time zone",
|
|
||||||
oldNullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AlterColumn<DateTime>(
|
|
||||||
name: "start_date",
|
|
||||||
table: "seasons",
|
|
||||||
type: "timestamp with time zone",
|
|
||||||
nullable: true,
|
|
||||||
oldClrType: typeof(DateTime),
|
|
||||||
oldType: "timestamp without time zone",
|
|
||||||
oldNullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AlterColumn<DateTime>(
|
|
||||||
name: "end_date",
|
|
||||||
table: "seasons",
|
|
||||||
type: "timestamp with time zone",
|
|
||||||
nullable: true,
|
|
||||||
oldClrType: typeof(DateTime),
|
|
||||||
oldType: "timestamp without time zone",
|
|
||||||
oldNullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AlterColumn<DateTime>(
|
|
||||||
name: "release_date",
|
|
||||||
table: "episodes",
|
|
||||||
type: "timestamp with time zone",
|
|
||||||
nullable: true,
|
|
||||||
oldClrType: typeof(DateTime),
|
|
||||||
oldType: "timestamp without time zone",
|
|
||||||
oldNullable: true);
|
|
||||||
|
|
||||||
MigrationHelper.CreateLibraryItemsView(migrationBuilder);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Down(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
MigrationHelper.DropLibraryItemsView(migrationBuilder);
|
|
||||||
|
|
||||||
migrationBuilder.AlterColumn<DateTime>(
|
|
||||||
name: "start_air",
|
|
||||||
table: "shows",
|
|
||||||
type: "timestamp without time zone",
|
|
||||||
nullable: true,
|
|
||||||
oldClrType: typeof(DateTime),
|
|
||||||
oldType: "timestamp with time zone",
|
|
||||||
oldNullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AlterColumn<DateTime>(
|
|
||||||
name: "end_air",
|
|
||||||
table: "shows",
|
|
||||||
type: "timestamp without time zone",
|
|
||||||
nullable: true,
|
|
||||||
oldClrType: typeof(DateTime),
|
|
||||||
oldType: "timestamp with time zone",
|
|
||||||
oldNullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AlterColumn<DateTime>(
|
|
||||||
name: "start_date",
|
|
||||||
table: "seasons",
|
|
||||||
type: "timestamp without time zone",
|
|
||||||
nullable: true,
|
|
||||||
oldClrType: typeof(DateTime),
|
|
||||||
oldType: "timestamp with time zone",
|
|
||||||
oldNullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AlterColumn<DateTime>(
|
|
||||||
name: "end_date",
|
|
||||||
table: "seasons",
|
|
||||||
type: "timestamp without time zone",
|
|
||||||
nullable: true,
|
|
||||||
oldClrType: typeof(DateTime),
|
|
||||||
oldType: "timestamp with time zone",
|
|
||||||
oldNullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AlterColumn<DateTime>(
|
|
||||||
name: "release_date",
|
|
||||||
table: "episodes",
|
|
||||||
type: "timestamp without time zone",
|
|
||||||
nullable: true,
|
|
||||||
oldClrType: typeof(DateTime),
|
|
||||||
oldType: "timestamp with time zone",
|
|
||||||
oldNullable: true);
|
|
||||||
|
|
||||||
MigrationHelper.CreateLibraryItemsView(migrationBuilder);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
@ -1,95 +0,0 @@
|
|||||||
// 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 Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace Kyoo.Postgresql.Migrations
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
public partial class RemoveTracks : Migration
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "tracks");
|
|
||||||
|
|
||||||
migrationBuilder.AlterDatabase()
|
|
||||||
.Annotation("Npgsql:Enum:item_type", "show,movie,collection")
|
|
||||||
.Annotation("Npgsql:Enum:status", "unknown,finished,airing,planned")
|
|
||||||
.OldAnnotation("Npgsql:Enum:item_type", "show,movie,collection")
|
|
||||||
.OldAnnotation("Npgsql:Enum:status", "unknown,finished,airing,planned")
|
|
||||||
.OldAnnotation("Npgsql:Enum:stream_type", "unknown,video,audio,subtitle");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Down(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.AlterDatabase()
|
|
||||||
.Annotation("Npgsql:Enum:item_type", "show,movie,collection")
|
|
||||||
.Annotation("Npgsql:Enum:status", "unknown,finished,airing,planned")
|
|
||||||
.Annotation("Npgsql:Enum:stream_type", "unknown,video,audio,subtitle")
|
|
||||||
.OldAnnotation("Npgsql:Enum:item_type", "show,movie,collection")
|
|
||||||
.OldAnnotation("Npgsql:Enum:status", "unknown,finished,airing,planned");
|
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "tracks",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
id = table.Column<int>(type: "integer", nullable: false)
|
|
||||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
|
||||||
episode_id = table.Column<int>(type: "integer", nullable: false),
|
|
||||||
codec = table.Column<string>(type: "text", nullable: true),
|
|
||||||
is_default = table.Column<bool>(type: "boolean", nullable: false),
|
|
||||||
is_external = table.Column<bool>(type: "boolean", nullable: false),
|
|
||||||
is_forced = table.Column<bool>(type: "boolean", nullable: false),
|
|
||||||
language = table.Column<string>(type: "text", nullable: true),
|
|
||||||
path = table.Column<string>(type: "text", nullable: true),
|
|
||||||
slug = table.Column<string>(type: "text", nullable: false),
|
|
||||||
title = table.Column<string>(type: "text", nullable: true),
|
|
||||||
track_index = table.Column<int>(type: "integer", nullable: false),
|
|
||||||
type = table.Column<string>(type: "stream_type", nullable: true)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("pk_tracks", x => x.id);
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "fk_tracks_episodes_episode_id",
|
|
||||||
column: x => x.episode_id,
|
|
||||||
principalTable: "episodes",
|
|
||||||
principalColumn: "id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "ix_tracks_episode_id_type_language_track_index_is_forced",
|
|
||||||
table: "tracks",
|
|
||||||
columns: new[] { "episode_id", "type", "language", "track_index", "is_forced" },
|
|
||||||
unique: true);
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "ix_tracks_slug",
|
|
||||||
table: "tracks",
|
|
||||||
column: "slug",
|
|
||||||
unique: true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,772 +0,0 @@
|
|||||||
// 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.Collections.Generic;
|
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace Kyoo.Postgresql.Migrations
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
public partial class AddBlurhash : Migration
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
MigrationHelper.DropLibraryItemsView(migrationBuilder);
|
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "collection_metadata_id");
|
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "episode_metadata_id");
|
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "link_library_provider");
|
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "people_metadata_id");
|
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "season_metadata_id");
|
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "show_metadata_id");
|
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "studio_metadata_id");
|
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "providers");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "images",
|
|
||||||
table: "users");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "images",
|
|
||||||
table: "shows");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "images",
|
|
||||||
table: "seasons");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "images",
|
|
||||||
table: "people");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "images",
|
|
||||||
table: "episodes");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "images",
|
|
||||||
table: "collections");
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "logo_blurhash",
|
|
||||||
table: "users",
|
|
||||||
type: "character varying(32)",
|
|
||||||
maxLength: 32,
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "logo_source",
|
|
||||||
table: "users",
|
|
||||||
type: "text",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "external_id",
|
|
||||||
table: "studios",
|
|
||||||
type: "json",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "external_id",
|
|
||||||
table: "shows",
|
|
||||||
type: "json",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "logo_blurhash",
|
|
||||||
table: "shows",
|
|
||||||
type: "character varying(32)",
|
|
||||||
maxLength: 32,
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "logo_source",
|
|
||||||
table: "shows",
|
|
||||||
type: "text",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "poster_blurhash",
|
|
||||||
table: "shows",
|
|
||||||
type: "character varying(32)",
|
|
||||||
maxLength: 32,
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "poster_source",
|
|
||||||
table: "shows",
|
|
||||||
type: "text",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "thumbnail_blurhash",
|
|
||||||
table: "shows",
|
|
||||||
type: "character varying(32)",
|
|
||||||
maxLength: 32,
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "thumbnail_source",
|
|
||||||
table: "shows",
|
|
||||||
type: "text",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "trailer",
|
|
||||||
table: "shows",
|
|
||||||
type: "text",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "external_id",
|
|
||||||
table: "seasons",
|
|
||||||
type: "json",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "logo_blurhash",
|
|
||||||
table: "seasons",
|
|
||||||
type: "character varying(32)",
|
|
||||||
maxLength: 32,
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "logo_source",
|
|
||||||
table: "seasons",
|
|
||||||
type: "text",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "poster_blurhash",
|
|
||||||
table: "seasons",
|
|
||||||
type: "character varying(32)",
|
|
||||||
maxLength: 32,
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "poster_source",
|
|
||||||
table: "seasons",
|
|
||||||
type: "text",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "thumbnail_blurhash",
|
|
||||||
table: "seasons",
|
|
||||||
type: "character varying(32)",
|
|
||||||
maxLength: 32,
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "thumbnail_source",
|
|
||||||
table: "seasons",
|
|
||||||
type: "text",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "external_id",
|
|
||||||
table: "people",
|
|
||||||
type: "json",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "logo_blurhash",
|
|
||||||
table: "people",
|
|
||||||
type: "character varying(32)",
|
|
||||||
maxLength: 32,
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "logo_source",
|
|
||||||
table: "people",
|
|
||||||
type: "text",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "poster_blurhash",
|
|
||||||
table: "people",
|
|
||||||
type: "character varying(32)",
|
|
||||||
maxLength: 32,
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "poster_source",
|
|
||||||
table: "people",
|
|
||||||
type: "text",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "thumbnail_blurhash",
|
|
||||||
table: "people",
|
|
||||||
type: "character varying(32)",
|
|
||||||
maxLength: 32,
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "thumbnail_source",
|
|
||||||
table: "people",
|
|
||||||
type: "text",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "external_id",
|
|
||||||
table: "episodes",
|
|
||||||
type: "json",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "logo_blurhash",
|
|
||||||
table: "episodes",
|
|
||||||
type: "character varying(32)",
|
|
||||||
maxLength: 32,
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "logo_source",
|
|
||||||
table: "episodes",
|
|
||||||
type: "text",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "poster_blurhash",
|
|
||||||
table: "episodes",
|
|
||||||
type: "character varying(32)",
|
|
||||||
maxLength: 32,
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "poster_source",
|
|
||||||
table: "episodes",
|
|
||||||
type: "text",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "thumbnail_blurhash",
|
|
||||||
table: "episodes",
|
|
||||||
type: "character varying(32)",
|
|
||||||
maxLength: 32,
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "thumbnail_source",
|
|
||||||
table: "episodes",
|
|
||||||
type: "text",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "external_id",
|
|
||||||
table: "collections",
|
|
||||||
type: "json",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "logo_blurhash",
|
|
||||||
table: "collections",
|
|
||||||
type: "character varying(32)",
|
|
||||||
maxLength: 32,
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "logo_source",
|
|
||||||
table: "collections",
|
|
||||||
type: "text",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "poster_blurhash",
|
|
||||||
table: "collections",
|
|
||||||
type: "character varying(32)",
|
|
||||||
maxLength: 32,
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "poster_source",
|
|
||||||
table: "collections",
|
|
||||||
type: "text",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "thumbnail_blurhash",
|
|
||||||
table: "collections",
|
|
||||||
type: "character varying(32)",
|
|
||||||
maxLength: 32,
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "thumbnail_source",
|
|
||||||
table: "collections",
|
|
||||||
type: "text",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
MigrationHelper.CreateLibraryItemsView(migrationBuilder);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Down(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
MigrationHelper.DropLibraryItemsView(migrationBuilder);
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "logo_blurhash",
|
|
||||||
table: "users");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "logo_source",
|
|
||||||
table: "users");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "external_id",
|
|
||||||
table: "studios");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "external_id",
|
|
||||||
table: "shows");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "logo_blurhash",
|
|
||||||
table: "shows");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "logo_source",
|
|
||||||
table: "shows");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "poster_blurhash",
|
|
||||||
table: "shows");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "poster_source",
|
|
||||||
table: "shows");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "thumbnail_blurhash",
|
|
||||||
table: "shows");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "thumbnail_source",
|
|
||||||
table: "shows");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "trailer",
|
|
||||||
table: "shows");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "external_id",
|
|
||||||
table: "seasons");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "logo_blurhash",
|
|
||||||
table: "seasons");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "logo_source",
|
|
||||||
table: "seasons");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "poster_blurhash",
|
|
||||||
table: "seasons");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "poster_source",
|
|
||||||
table: "seasons");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "thumbnail_blurhash",
|
|
||||||
table: "seasons");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "thumbnail_source",
|
|
||||||
table: "seasons");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "external_id",
|
|
||||||
table: "people");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "logo_blurhash",
|
|
||||||
table: "people");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "logo_source",
|
|
||||||
table: "people");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "poster_blurhash",
|
|
||||||
table: "people");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "poster_source",
|
|
||||||
table: "people");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "thumbnail_blurhash",
|
|
||||||
table: "people");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "thumbnail_source",
|
|
||||||
table: "people");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "external_id",
|
|
||||||
table: "episodes");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "logo_blurhash",
|
|
||||||
table: "episodes");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "logo_source",
|
|
||||||
table: "episodes");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "poster_blurhash",
|
|
||||||
table: "episodes");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "poster_source",
|
|
||||||
table: "episodes");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "thumbnail_blurhash",
|
|
||||||
table: "episodes");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "thumbnail_source",
|
|
||||||
table: "episodes");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "external_id",
|
|
||||||
table: "collections");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "logo_blurhash",
|
|
||||||
table: "collections");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "logo_source",
|
|
||||||
table: "collections");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "poster_blurhash",
|
|
||||||
table: "collections");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "poster_source",
|
|
||||||
table: "collections");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "thumbnail_blurhash",
|
|
||||||
table: "collections");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "thumbnail_source",
|
|
||||||
table: "collections");
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<Dictionary<int, string>>(
|
|
||||||
name: "images",
|
|
||||||
table: "users",
|
|
||||||
type: "jsonb",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<Dictionary<int, string>>(
|
|
||||||
name: "images",
|
|
||||||
table: "shows",
|
|
||||||
type: "jsonb",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<Dictionary<int, string>>(
|
|
||||||
name: "images",
|
|
||||||
table: "seasons",
|
|
||||||
type: "jsonb",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<Dictionary<int, string>>(
|
|
||||||
name: "images",
|
|
||||||
table: "people",
|
|
||||||
type: "jsonb",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<Dictionary<int, string>>(
|
|
||||||
name: "images",
|
|
||||||
table: "episodes",
|
|
||||||
type: "jsonb",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<Dictionary<int, string>>(
|
|
||||||
name: "images",
|
|
||||||
table: "collections",
|
|
||||||
type: "jsonb",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "providers",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
id = table.Column<int>(type: "integer", nullable: false)
|
|
||||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
|
||||||
images = table.Column<Dictionary<int, string>>(type: "jsonb", nullable: true),
|
|
||||||
name = table.Column<string>(type: "text", nullable: true),
|
|
||||||
slug = table.Column<string>(type: "text", nullable: false)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("pk_providers", x => x.id);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "collection_metadata_id",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
resource_id = table.Column<int>(type: "integer", nullable: false),
|
|
||||||
provider_id = table.Column<int>(type: "integer", nullable: false),
|
|
||||||
data_id = table.Column<string>(type: "text", nullable: true),
|
|
||||||
link = table.Column<string>(type: "text", nullable: true)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("pk_collection_metadata_id", x => new { x.resource_id, x.provider_id });
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "fk_collection_metadata_id_collections_collection_id",
|
|
||||||
column: x => x.resource_id,
|
|
||||||
principalTable: "collections",
|
|
||||||
principalColumn: "id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "fk_collection_metadata_id_providers_provider_id",
|
|
||||||
column: x => x.provider_id,
|
|
||||||
principalTable: "providers",
|
|
||||||
principalColumn: "id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "episode_metadata_id",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
resource_id = table.Column<int>(type: "integer", nullable: false),
|
|
||||||
provider_id = table.Column<int>(type: "integer", nullable: false),
|
|
||||||
data_id = table.Column<string>(type: "text", nullable: true),
|
|
||||||
link = table.Column<string>(type: "text", nullable: true)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("pk_episode_metadata_id", x => new { x.resource_id, x.provider_id });
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "fk_episode_metadata_id_episodes_episode_id",
|
|
||||||
column: x => x.resource_id,
|
|
||||||
principalTable: "episodes",
|
|
||||||
principalColumn: "id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "fk_episode_metadata_id_providers_provider_id",
|
|
||||||
column: x => x.provider_id,
|
|
||||||
principalTable: "providers",
|
|
||||||
principalColumn: "id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "link_library_provider",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
library_id = table.Column<int>(type: "integer", nullable: false),
|
|
||||||
provider_id = table.Column<int>(type: "integer", nullable: false)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("pk_link_library_provider", x => new { x.library_id, x.provider_id });
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "fk_link_library_provider_libraries_library_id",
|
|
||||||
column: x => x.library_id,
|
|
||||||
principalTable: "libraries",
|
|
||||||
principalColumn: "id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "fk_link_library_provider_providers_provider_id",
|
|
||||||
column: x => x.provider_id,
|
|
||||||
principalTable: "providers",
|
|
||||||
principalColumn: "id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "people_metadata_id",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
resource_id = table.Column<int>(type: "integer", nullable: false),
|
|
||||||
provider_id = table.Column<int>(type: "integer", nullable: false),
|
|
||||||
data_id = table.Column<string>(type: "text", nullable: true),
|
|
||||||
link = table.Column<string>(type: "text", nullable: true)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("pk_people_metadata_id", x => new { x.resource_id, x.provider_id });
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "fk_people_metadata_id_people_people_id",
|
|
||||||
column: x => x.resource_id,
|
|
||||||
principalTable: "people",
|
|
||||||
principalColumn: "id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "fk_people_metadata_id_providers_provider_id",
|
|
||||||
column: x => x.provider_id,
|
|
||||||
principalTable: "providers",
|
|
||||||
principalColumn: "id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "season_metadata_id",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
resource_id = table.Column<int>(type: "integer", nullable: false),
|
|
||||||
provider_id = table.Column<int>(type: "integer", nullable: false),
|
|
||||||
data_id = table.Column<string>(type: "text", nullable: true),
|
|
||||||
link = table.Column<string>(type: "text", nullable: true)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("pk_season_metadata_id", x => new { x.resource_id, x.provider_id });
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "fk_season_metadata_id_providers_provider_id",
|
|
||||||
column: x => x.provider_id,
|
|
||||||
principalTable: "providers",
|
|
||||||
principalColumn: "id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "fk_season_metadata_id_seasons_season_id",
|
|
||||||
column: x => x.resource_id,
|
|
||||||
principalTable: "seasons",
|
|
||||||
principalColumn: "id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "show_metadata_id",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
resource_id = table.Column<int>(type: "integer", nullable: false),
|
|
||||||
provider_id = table.Column<int>(type: "integer", nullable: false),
|
|
||||||
data_id = table.Column<string>(type: "text", nullable: true),
|
|
||||||
link = table.Column<string>(type: "text", nullable: true)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("pk_show_metadata_id", x => new { x.resource_id, x.provider_id });
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "fk_show_metadata_id_providers_provider_id",
|
|
||||||
column: x => x.provider_id,
|
|
||||||
principalTable: "providers",
|
|
||||||
principalColumn: "id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "fk_show_metadata_id_shows_show_id",
|
|
||||||
column: x => x.resource_id,
|
|
||||||
principalTable: "shows",
|
|
||||||
principalColumn: "id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "studio_metadata_id",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
resource_id = table.Column<int>(type: "integer", nullable: false),
|
|
||||||
provider_id = table.Column<int>(type: "integer", nullable: false),
|
|
||||||
data_id = table.Column<string>(type: "text", nullable: true),
|
|
||||||
link = table.Column<string>(type: "text", nullable: true)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("pk_studio_metadata_id", x => new { x.resource_id, x.provider_id });
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "fk_studio_metadata_id_providers_provider_id",
|
|
||||||
column: x => x.provider_id,
|
|
||||||
principalTable: "providers",
|
|
||||||
principalColumn: "id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "fk_studio_metadata_id_studios_studio_id",
|
|
||||||
column: x => x.resource_id,
|
|
||||||
principalTable: "studios",
|
|
||||||
principalColumn: "id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "ix_collection_metadata_id_provider_id",
|
|
||||||
table: "collection_metadata_id",
|
|
||||||
column: "provider_id");
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "ix_episode_metadata_id_provider_id",
|
|
||||||
table: "episode_metadata_id",
|
|
||||||
column: "provider_id");
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "ix_link_library_provider_provider_id",
|
|
||||||
table: "link_library_provider",
|
|
||||||
column: "provider_id");
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "ix_people_metadata_id_provider_id",
|
|
||||||
table: "people_metadata_id",
|
|
||||||
column: "provider_id");
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "ix_providers_slug",
|
|
||||||
table: "providers",
|
|
||||||
column: "slug",
|
|
||||||
unique: true);
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "ix_season_metadata_id_provider_id",
|
|
||||||
table: "season_metadata_id",
|
|
||||||
column: "provider_id");
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "ix_show_metadata_id_provider_id",
|
|
||||||
table: "show_metadata_id",
|
|
||||||
column: "provider_id");
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "ix_studio_metadata_id_provider_id",
|
|
||||||
table: "studio_metadata_id",
|
|
||||||
column: "provider_id");
|
|
||||||
|
|
||||||
MigrationHelper.CreateLibraryItemsView(migrationBuilder);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
528
back/src/Kyoo.Postgresql/Migrations/20230805051120_initial.cs
Normal file
528
back/src/Kyoo.Postgresql/Migrations/20230805051120_initial.cs
Normal file
@ -0,0 +1,528 @@
|
|||||||
|
using System;
|
||||||
|
using Kyoo.Abstractions.Models;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Kyoo.Postgresql.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class initial : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AlterDatabase()
|
||||||
|
.Annotation("Npgsql:Enum:genre", "action,adventure,animation,comedy,crime,documentary,drama,family,fantasy,history,horror,music,mystery,romance,science_fiction,thriller,war,western")
|
||||||
|
.Annotation("Npgsql:Enum:status", "unknown,finished,airing,planned");
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "collections",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
id = table.Column<int>(type: "integer", nullable: false)
|
||||||
|
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||||
|
slug = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: false),
|
||||||
|
name = table.Column<string>(type: "text", nullable: false),
|
||||||
|
poster_source = table.Column<string>(type: "text", nullable: true),
|
||||||
|
poster_blurhash = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: true),
|
||||||
|
thumbnail_source = table.Column<string>(type: "text", nullable: true),
|
||||||
|
thumbnail_blurhash = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: true),
|
||||||
|
logo_source = table.Column<string>(type: "text", nullable: true),
|
||||||
|
logo_blurhash = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: true),
|
||||||
|
overview = table.Column<string>(type: "text", nullable: true),
|
||||||
|
external_id = table.Column<string>(type: "json", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("pk_collections", x => x.id);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "people",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
id = table.Column<int>(type: "integer", nullable: false)
|
||||||
|
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||||
|
slug = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: false),
|
||||||
|
name = table.Column<string>(type: "text", nullable: false),
|
||||||
|
poster_source = table.Column<string>(type: "text", nullable: true),
|
||||||
|
poster_blurhash = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: true),
|
||||||
|
thumbnail_source = table.Column<string>(type: "text", nullable: true),
|
||||||
|
thumbnail_blurhash = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: true),
|
||||||
|
logo_source = table.Column<string>(type: "text", nullable: true),
|
||||||
|
logo_blurhash = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: true),
|
||||||
|
external_id = table.Column<string>(type: "json", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("pk_people", x => x.id);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "studios",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
id = table.Column<int>(type: "integer", nullable: false)
|
||||||
|
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||||
|
slug = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: false),
|
||||||
|
name = table.Column<string>(type: "text", nullable: false),
|
||||||
|
external_id = table.Column<string>(type: "json", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("pk_studios", x => x.id);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "users",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
id = table.Column<int>(type: "integer", nullable: false)
|
||||||
|
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||||
|
slug = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: false),
|
||||||
|
username = table.Column<string>(type: "text", nullable: false),
|
||||||
|
email = table.Column<string>(type: "text", nullable: false),
|
||||||
|
password = table.Column<string>(type: "text", nullable: false),
|
||||||
|
permissions = table.Column<string[]>(type: "text[]", nullable: false),
|
||||||
|
logo_source = table.Column<string>(type: "text", nullable: true),
|
||||||
|
logo_blurhash = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("pk_users", x => x.id);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "movies",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
id = table.Column<int>(type: "integer", nullable: false)
|
||||||
|
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||||
|
slug = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: false),
|
||||||
|
name = table.Column<string>(type: "text", nullable: false),
|
||||||
|
tagline = table.Column<string>(type: "text", nullable: true),
|
||||||
|
aliases = table.Column<string[]>(type: "text[]", nullable: false),
|
||||||
|
path = table.Column<string>(type: "text", nullable: false),
|
||||||
|
overview = table.Column<string>(type: "text", nullable: true),
|
||||||
|
tags = table.Column<string[]>(type: "text[]", nullable: false),
|
||||||
|
genres = table.Column<Genre[]>(type: "genre[]", nullable: false),
|
||||||
|
status = table.Column<Status>(type: "status", nullable: false),
|
||||||
|
air_date = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
|
||||||
|
poster_source = table.Column<string>(type: "text", nullable: true),
|
||||||
|
poster_blurhash = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: true),
|
||||||
|
thumbnail_source = table.Column<string>(type: "text", nullable: true),
|
||||||
|
thumbnail_blurhash = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: true),
|
||||||
|
logo_source = table.Column<string>(type: "text", nullable: true),
|
||||||
|
logo_blurhash = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: true),
|
||||||
|
trailer = table.Column<string>(type: "text", nullable: true),
|
||||||
|
external_id = table.Column<string>(type: "json", nullable: false),
|
||||||
|
studio_id = table.Column<int>(type: "integer", nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("pk_movies", x => x.id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "fk_movies_studios_studio_id",
|
||||||
|
column: x => x.studio_id,
|
||||||
|
principalTable: "studios",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.SetNull);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "shows",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
id = table.Column<int>(type: "integer", nullable: false)
|
||||||
|
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||||
|
slug = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: false),
|
||||||
|
name = table.Column<string>(type: "text", nullable: false),
|
||||||
|
tagline = table.Column<string>(type: "text", nullable: true),
|
||||||
|
aliases = table.Column<string[]>(type: "text[]", nullable: false),
|
||||||
|
overview = table.Column<string>(type: "text", nullable: true),
|
||||||
|
tags = table.Column<string[]>(type: "text[]", nullable: false),
|
||||||
|
genres = table.Column<Genre[]>(type: "genre[]", nullable: false),
|
||||||
|
status = table.Column<Status>(type: "status", nullable: false),
|
||||||
|
start_air = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
|
||||||
|
end_air = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
|
||||||
|
poster_source = table.Column<string>(type: "text", nullable: true),
|
||||||
|
poster_blurhash = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: true),
|
||||||
|
thumbnail_source = table.Column<string>(type: "text", nullable: true),
|
||||||
|
thumbnail_blurhash = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: true),
|
||||||
|
logo_source = table.Column<string>(type: "text", nullable: true),
|
||||||
|
logo_blurhash = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: true),
|
||||||
|
trailer = table.Column<string>(type: "text", nullable: true),
|
||||||
|
external_id = table.Column<string>(type: "json", nullable: false),
|
||||||
|
studio_id = table.Column<int>(type: "integer", nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("pk_shows", x => x.id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "fk_shows_studios_studio_id",
|
||||||
|
column: x => x.studio_id,
|
||||||
|
principalTable: "studios",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.SetNull);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "collection_movie",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
collections_id = table.Column<int>(type: "integer", nullable: false),
|
||||||
|
movies_id = table.Column<int>(type: "integer", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("pk_collection_movie", x => new { x.collections_id, x.movies_id });
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "fk_collection_movie_collections_collections_id",
|
||||||
|
column: x => x.collections_id,
|
||||||
|
principalTable: "collections",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "fk_collection_movie_movies_movies_id",
|
||||||
|
column: x => x.movies_id,
|
||||||
|
principalTable: "movies",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "link_collection_show",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
collection_id = table.Column<int>(type: "integer", nullable: false),
|
||||||
|
show_id = table.Column<int>(type: "integer", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("pk_link_collection_show", x => new { x.collection_id, x.show_id });
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "fk_link_collection_show_collections_collection_id",
|
||||||
|
column: x => x.collection_id,
|
||||||
|
principalTable: "collections",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "fk_link_collection_show_shows_show_id",
|
||||||
|
column: x => x.show_id,
|
||||||
|
principalTable: "shows",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "link_user_show",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
users_id = table.Column<int>(type: "integer", nullable: false),
|
||||||
|
watched_id = table.Column<int>(type: "integer", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("pk_link_user_show", x => new { x.users_id, x.watched_id });
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "fk_link_user_show_shows_watched_id",
|
||||||
|
column: x => x.watched_id,
|
||||||
|
principalTable: "shows",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "fk_link_user_show_users_users_id",
|
||||||
|
column: x => x.users_id,
|
||||||
|
principalTable: "users",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "people_roles",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
id = table.Column<int>(type: "integer", nullable: false)
|
||||||
|
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||||
|
people_id = table.Column<int>(type: "integer", nullable: false),
|
||||||
|
show_id = table.Column<int>(type: "integer", nullable: true),
|
||||||
|
movie_id = table.Column<int>(type: "integer", nullable: true),
|
||||||
|
type = table.Column<string>(type: "text", nullable: false),
|
||||||
|
role = table.Column<string>(type: "text", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("pk_people_roles", x => x.id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "fk_people_roles_movies_movie_id",
|
||||||
|
column: x => x.movie_id,
|
||||||
|
principalTable: "movies",
|
||||||
|
principalColumn: "id");
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "fk_people_roles_people_people_id",
|
||||||
|
column: x => x.people_id,
|
||||||
|
principalTable: "people",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "fk_people_roles_shows_show_id",
|
||||||
|
column: x => x.show_id,
|
||||||
|
principalTable: "shows",
|
||||||
|
principalColumn: "id");
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "seasons",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
id = table.Column<int>(type: "integer", nullable: false)
|
||||||
|
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||||
|
slug = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: false),
|
||||||
|
show_id = table.Column<int>(type: "integer", nullable: false),
|
||||||
|
season_number = table.Column<int>(type: "integer", nullable: false),
|
||||||
|
name = table.Column<string>(type: "text", nullable: true),
|
||||||
|
overview = table.Column<string>(type: "text", nullable: true),
|
||||||
|
start_date = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
|
||||||
|
end_date = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
|
||||||
|
poster_source = table.Column<string>(type: "text", nullable: true),
|
||||||
|
poster_blurhash = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: true),
|
||||||
|
thumbnail_source = table.Column<string>(type: "text", nullable: true),
|
||||||
|
thumbnail_blurhash = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: true),
|
||||||
|
logo_source = table.Column<string>(type: "text", nullable: true),
|
||||||
|
logo_blurhash = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: true),
|
||||||
|
external_id = table.Column<string>(type: "json", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("pk_seasons", x => x.id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "fk_seasons_shows_show_id",
|
||||||
|
column: x => x.show_id,
|
||||||
|
principalTable: "shows",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "episodes",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
id = table.Column<int>(type: "integer", nullable: false)
|
||||||
|
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||||
|
slug = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: false),
|
||||||
|
show_id = table.Column<int>(type: "integer", nullable: false),
|
||||||
|
season_id = table.Column<int>(type: "integer", nullable: true),
|
||||||
|
season_number = table.Column<int>(type: "integer", nullable: true),
|
||||||
|
episode_number = table.Column<int>(type: "integer", nullable: true),
|
||||||
|
absolute_number = table.Column<int>(type: "integer", nullable: true),
|
||||||
|
path = table.Column<string>(type: "text", nullable: false),
|
||||||
|
name = table.Column<string>(type: "text", nullable: true),
|
||||||
|
overview = table.Column<string>(type: "text", nullable: true),
|
||||||
|
release_date = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
|
||||||
|
poster_source = table.Column<string>(type: "text", nullable: true),
|
||||||
|
poster_blurhash = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: true),
|
||||||
|
thumbnail_source = table.Column<string>(type: "text", nullable: true),
|
||||||
|
thumbnail_blurhash = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: true),
|
||||||
|
logo_source = table.Column<string>(type: "text", nullable: true),
|
||||||
|
logo_blurhash = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: true),
|
||||||
|
external_id = table.Column<string>(type: "json", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("pk_episodes", x => x.id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "fk_episodes_seasons_season_id",
|
||||||
|
column: x => x.season_id,
|
||||||
|
principalTable: "seasons",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "fk_episodes_shows_show_id",
|
||||||
|
column: x => x.show_id,
|
||||||
|
principalTable: "shows",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "watched_episode",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
user_id = table.Column<int>(type: "integer", nullable: false),
|
||||||
|
episode_id = table.Column<int>(type: "integer", nullable: false),
|
||||||
|
watched_percentage = table.Column<int>(type: "integer", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("pk_watched_episode", x => new { x.user_id, x.episode_id });
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "fk_watched_episode_episodes_episode_id",
|
||||||
|
column: x => x.episode_id,
|
||||||
|
principalTable: "episodes",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "fk_watched_episode_users_user_id",
|
||||||
|
column: x => x.user_id,
|
||||||
|
principalTable: "users",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_collection_movie_movies_id",
|
||||||
|
table: "collection_movie",
|
||||||
|
column: "movies_id");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_collections_slug",
|
||||||
|
table: "collections",
|
||||||
|
column: "slug",
|
||||||
|
unique: true);
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_episodes_season_id",
|
||||||
|
table: "episodes",
|
||||||
|
column: "season_id");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_episodes_show_id_season_number_episode_number_absolute_numb",
|
||||||
|
table: "episodes",
|
||||||
|
columns: new[] { "show_id", "season_number", "episode_number", "absolute_number" },
|
||||||
|
unique: true);
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_episodes_slug",
|
||||||
|
table: "episodes",
|
||||||
|
column: "slug",
|
||||||
|
unique: true);
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_link_collection_show_show_id",
|
||||||
|
table: "link_collection_show",
|
||||||
|
column: "show_id");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_link_user_show_watched_id",
|
||||||
|
table: "link_user_show",
|
||||||
|
column: "watched_id");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_movies_slug",
|
||||||
|
table: "movies",
|
||||||
|
column: "slug",
|
||||||
|
unique: true);
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_movies_studio_id",
|
||||||
|
table: "movies",
|
||||||
|
column: "studio_id");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_people_slug",
|
||||||
|
table: "people",
|
||||||
|
column: "slug",
|
||||||
|
unique: true);
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_people_roles_movie_id",
|
||||||
|
table: "people_roles",
|
||||||
|
column: "movie_id");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_people_roles_people_id",
|
||||||
|
table: "people_roles",
|
||||||
|
column: "people_id");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_people_roles_show_id",
|
||||||
|
table: "people_roles",
|
||||||
|
column: "show_id");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_seasons_show_id_season_number",
|
||||||
|
table: "seasons",
|
||||||
|
columns: new[] { "show_id", "season_number" },
|
||||||
|
unique: true);
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_seasons_slug",
|
||||||
|
table: "seasons",
|
||||||
|
column: "slug",
|
||||||
|
unique: true);
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_shows_slug",
|
||||||
|
table: "shows",
|
||||||
|
column: "slug",
|
||||||
|
unique: true);
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_shows_studio_id",
|
||||||
|
table: "shows",
|
||||||
|
column: "studio_id");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_studios_slug",
|
||||||
|
table: "studios",
|
||||||
|
column: "slug",
|
||||||
|
unique: true);
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_users_slug",
|
||||||
|
table: "users",
|
||||||
|
column: "slug",
|
||||||
|
unique: true);
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_watched_episode_episode_id",
|
||||||
|
table: "watched_episode",
|
||||||
|
column: "episode_id");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "collection_movie");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "link_collection_show");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "link_user_show");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "people_roles");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "watched_episode");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "collections");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "movies");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "people");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "episodes");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "users");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "seasons");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "shows");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "studios");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,5 @@
|
|||||||
// <auto-generated />
|
// <auto-generated />
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using Kyoo.Abstractions.Models;
|
using Kyoo.Abstractions.Models;
|
||||||
using Kyoo.Postgresql;
|
using Kyoo.Postgresql;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
@ -22,10 +21,29 @@ namespace Kyoo.Postgresql.Migrations
|
|||||||
.HasAnnotation("ProductVersion", "7.0.9")
|
.HasAnnotation("ProductVersion", "7.0.9")
|
||||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||||
|
|
||||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "item_type", new[] { "show", "movie", "collection" });
|
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "genre", new[] { "action", "adventure", "animation", "comedy", "crime", "documentary", "drama", "family", "fantasy", "history", "horror", "music", "mystery", "romance", "science_fiction", "thriller", "war", "western" });
|
||||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "status", new[] { "unknown", "finished", "airing", "planned" });
|
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "status", new[] { "unknown", "finished", "airing", "planned" });
|
||||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||||
|
|
||||||
|
modelBuilder.Entity("CollectionMovie", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("CollectionsID")
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("collections_id");
|
||||||
|
|
||||||
|
b.Property<int>("MoviesID")
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("movies_id");
|
||||||
|
|
||||||
|
b.HasKey("CollectionsID", "MoviesID")
|
||||||
|
.HasName("pk_collection_movie");
|
||||||
|
|
||||||
|
b.HasIndex("MoviesID")
|
||||||
|
.HasDatabaseName("ix_collection_movie_movies_id");
|
||||||
|
|
||||||
|
b.ToTable("collection_movie", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Kyoo.Abstractions.Models.Collection", b =>
|
modelBuilder.Entity("Kyoo.Abstractions.Models.Collection", b =>
|
||||||
{
|
{
|
||||||
b.Property<int>("ID")
|
b.Property<int>("ID")
|
||||||
@ -35,11 +53,13 @@ namespace Kyoo.Postgresql.Migrations
|
|||||||
|
|
||||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("ID"));
|
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("ID"));
|
||||||
|
|
||||||
b.Property<string>("ExternalIDs")
|
b.Property<string>("ExternalId")
|
||||||
|
.IsRequired()
|
||||||
.HasColumnType("json")
|
.HasColumnType("json")
|
||||||
.HasColumnName("external_i_ds");
|
.HasColumnName("external_id");
|
||||||
|
|
||||||
b.Property<string>("Name")
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
.HasColumnType("text")
|
.HasColumnType("text")
|
||||||
.HasColumnName("name");
|
.HasColumnName("name");
|
||||||
|
|
||||||
@ -49,7 +69,8 @@ namespace Kyoo.Postgresql.Migrations
|
|||||||
|
|
||||||
b.Property<string>("Slug")
|
b.Property<string>("Slug")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasColumnType("text")
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("character varying(256)")
|
||||||
.HasColumnName("slug");
|
.HasColumnName("slug");
|
||||||
|
|
||||||
b.HasKey("ID")
|
b.HasKey("ID")
|
||||||
@ -79,15 +100,21 @@ namespace Kyoo.Postgresql.Migrations
|
|||||||
.HasColumnType("integer")
|
.HasColumnType("integer")
|
||||||
.HasColumnName("episode_number");
|
.HasColumnName("episode_number");
|
||||||
|
|
||||||
b.Property<string>("ExternalIDs")
|
b.Property<string>("ExternalId")
|
||||||
|
.IsRequired()
|
||||||
.HasColumnType("json")
|
.HasColumnType("json")
|
||||||
.HasColumnName("external_i_ds");
|
.HasColumnName("external_id");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("name");
|
||||||
|
|
||||||
b.Property<string>("Overview")
|
b.Property<string>("Overview")
|
||||||
.HasColumnType("text")
|
.HasColumnType("text")
|
||||||
.HasColumnName("overview");
|
.HasColumnName("overview");
|
||||||
|
|
||||||
b.Property<string>("Path")
|
b.Property<string>("Path")
|
||||||
|
.IsRequired()
|
||||||
.HasColumnType("text")
|
.HasColumnType("text")
|
||||||
.HasColumnName("path");
|
.HasColumnName("path");
|
||||||
|
|
||||||
@ -109,13 +136,10 @@ namespace Kyoo.Postgresql.Migrations
|
|||||||
|
|
||||||
b.Property<string>("Slug")
|
b.Property<string>("Slug")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasColumnType("text")
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("character varying(256)")
|
||||||
.HasColumnName("slug");
|
.HasColumnName("slug");
|
||||||
|
|
||||||
b.Property<string>("Title")
|
|
||||||
.HasColumnType("text")
|
|
||||||
.HasColumnName("title");
|
|
||||||
|
|
||||||
b.HasKey("ID")
|
b.HasKey("ID")
|
||||||
.HasName("pk_episodes");
|
.HasName("pk_episodes");
|
||||||
|
|
||||||
@ -133,7 +157,7 @@ namespace Kyoo.Postgresql.Migrations
|
|||||||
b.ToTable("episodes", (string)null);
|
b.ToTable("episodes", (string)null);
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Kyoo.Abstractions.Models.Genre", b =>
|
modelBuilder.Entity("Kyoo.Abstractions.Models.Movie", b =>
|
||||||
{
|
{
|
||||||
b.Property<int>("ID")
|
b.Property<int>("ID")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
@ -142,97 +166,77 @@ namespace Kyoo.Postgresql.Migrations
|
|||||||
|
|
||||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("ID"));
|
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("ID"));
|
||||||
|
|
||||||
b.Property<string>("Name")
|
b.Property<DateTime?>("AirDate")
|
||||||
.HasColumnType("text")
|
|
||||||
.HasColumnName("name");
|
|
||||||
|
|
||||||
b.Property<string>("Slug")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("text")
|
|
||||||
.HasColumnName("slug");
|
|
||||||
|
|
||||||
b.HasKey("ID")
|
|
||||||
.HasName("pk_genres");
|
|
||||||
|
|
||||||
b.HasIndex("Slug")
|
|
||||||
.IsUnique()
|
|
||||||
.HasDatabaseName("ix_genres_slug");
|
|
||||||
|
|
||||||
b.ToTable("genres", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Kyoo.Abstractions.Models.Library", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("ID")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("integer")
|
|
||||||
.HasColumnName("id");
|
|
||||||
|
|
||||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("ID"));
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.HasColumnType("text")
|
|
||||||
.HasColumnName("name");
|
|
||||||
|
|
||||||
b.Property<string[]>("Paths")
|
|
||||||
.HasColumnType("text[]")
|
|
||||||
.HasColumnName("paths");
|
|
||||||
|
|
||||||
b.Property<string>("Slug")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("text")
|
|
||||||
.HasColumnName("slug");
|
|
||||||
|
|
||||||
b.HasKey("ID")
|
|
||||||
.HasName("pk_libraries");
|
|
||||||
|
|
||||||
b.HasIndex("Slug")
|
|
||||||
.IsUnique()
|
|
||||||
.HasDatabaseName("ix_libraries_slug");
|
|
||||||
|
|
||||||
b.ToTable("libraries", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Kyoo.Abstractions.Models.LibraryItem", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("ID")
|
|
||||||
.HasColumnType("integer")
|
|
||||||
.HasColumnName("id");
|
|
||||||
|
|
||||||
b.Property<DateTime?>("EndAir")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
.HasColumnType("timestamp with time zone")
|
||||||
.HasColumnName("end_air");
|
.HasColumnName("air_date");
|
||||||
|
|
||||||
|
b.Property<string[]>("Aliases")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text[]")
|
||||||
|
.HasColumnName("aliases");
|
||||||
|
|
||||||
|
b.Property<string>("ExternalId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("json")
|
||||||
|
.HasColumnName("external_id");
|
||||||
|
|
||||||
|
b.Property<Genre[]>("Genres")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("genre[]")
|
||||||
|
.HasColumnName("genres");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("name");
|
||||||
|
|
||||||
b.Property<string>("Overview")
|
b.Property<string>("Overview")
|
||||||
.HasColumnType("text")
|
.HasColumnType("text")
|
||||||
.HasColumnName("overview");
|
.HasColumnName("overview");
|
||||||
|
|
||||||
b.Property<string>("Slug")
|
b.Property<string>("Path")
|
||||||
|
.IsRequired()
|
||||||
.HasColumnType("text")
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("path");
|
||||||
|
|
||||||
|
b.Property<string>("Slug")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("character varying(256)")
|
||||||
.HasColumnName("slug");
|
.HasColumnName("slug");
|
||||||
|
|
||||||
b.Property<DateTime?>("StartAir")
|
b.Property<Status>("Status")
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("start_air");
|
|
||||||
|
|
||||||
b.Property<Status?>("Status")
|
|
||||||
.HasColumnType("status")
|
.HasColumnType("status")
|
||||||
.HasColumnName("status");
|
.HasColumnName("status");
|
||||||
|
|
||||||
b.Property<string>("Title")
|
b.Property<int?>("StudioID")
|
||||||
.HasColumnType("text")
|
.HasColumnType("integer")
|
||||||
.HasColumnName("title");
|
.HasColumnName("studio_id");
|
||||||
|
|
||||||
b.Property<ItemType>("Type")
|
b.Property<string>("Tagline")
|
||||||
.HasColumnType("item_type")
|
.HasColumnType("text")
|
||||||
.HasColumnName("type");
|
.HasColumnName("tagline");
|
||||||
|
|
||||||
|
b.Property<string[]>("Tags")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text[]")
|
||||||
|
.HasColumnName("tags");
|
||||||
|
|
||||||
|
b.Property<string>("Trailer")
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("trailer");
|
||||||
|
|
||||||
b.HasKey("ID")
|
b.HasKey("ID")
|
||||||
.HasName("pk_library_items");
|
.HasName("pk_movies");
|
||||||
|
|
||||||
b.ToTable((string)null);
|
b.HasIndex("Slug")
|
||||||
|
.IsUnique()
|
||||||
|
.HasDatabaseName("ix_movies_slug");
|
||||||
|
|
||||||
b.ToView("library_items", (string)null);
|
b.HasIndex("StudioID")
|
||||||
|
.HasDatabaseName("ix_movies_studio_id");
|
||||||
|
|
||||||
|
b.ToTable("movies", (string)null);
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Kyoo.Abstractions.Models.People", b =>
|
modelBuilder.Entity("Kyoo.Abstractions.Models.People", b =>
|
||||||
@ -244,17 +248,20 @@ namespace Kyoo.Postgresql.Migrations
|
|||||||
|
|
||||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("ID"));
|
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("ID"));
|
||||||
|
|
||||||
b.Property<string>("ExternalIDs")
|
b.Property<string>("ExternalId")
|
||||||
|
.IsRequired()
|
||||||
.HasColumnType("json")
|
.HasColumnType("json")
|
||||||
.HasColumnName("external_i_ds");
|
.HasColumnName("external_id");
|
||||||
|
|
||||||
b.Property<string>("Name")
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
.HasColumnType("text")
|
.HasColumnType("text")
|
||||||
.HasColumnName("name");
|
.HasColumnName("name");
|
||||||
|
|
||||||
b.Property<string>("Slug")
|
b.Property<string>("Slug")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasColumnType("text")
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("character varying(256)")
|
||||||
.HasColumnName("slug");
|
.HasColumnName("slug");
|
||||||
|
|
||||||
b.HasKey("ID")
|
b.HasKey("ID")
|
||||||
@ -276,25 +283,34 @@ namespace Kyoo.Postgresql.Migrations
|
|||||||
|
|
||||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("ID"));
|
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("ID"));
|
||||||
|
|
||||||
|
b.Property<int?>("MovieID")
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("movie_id");
|
||||||
|
|
||||||
b.Property<int>("PeopleID")
|
b.Property<int>("PeopleID")
|
||||||
.HasColumnType("integer")
|
.HasColumnType("integer")
|
||||||
.HasColumnName("people_id");
|
.HasColumnName("people_id");
|
||||||
|
|
||||||
b.Property<string>("Role")
|
b.Property<string>("Role")
|
||||||
|
.IsRequired()
|
||||||
.HasColumnType("text")
|
.HasColumnType("text")
|
||||||
.HasColumnName("role");
|
.HasColumnName("role");
|
||||||
|
|
||||||
b.Property<int>("ShowID")
|
b.Property<int?>("ShowID")
|
||||||
.HasColumnType("integer")
|
.HasColumnType("integer")
|
||||||
.HasColumnName("show_id");
|
.HasColumnName("show_id");
|
||||||
|
|
||||||
b.Property<string>("Type")
|
b.Property<string>("Type")
|
||||||
|
.IsRequired()
|
||||||
.HasColumnType("text")
|
.HasColumnType("text")
|
||||||
.HasColumnName("type");
|
.HasColumnName("type");
|
||||||
|
|
||||||
b.HasKey("ID")
|
b.HasKey("ID")
|
||||||
.HasName("pk_people_roles");
|
.HasName("pk_people_roles");
|
||||||
|
|
||||||
|
b.HasIndex("MovieID")
|
||||||
|
.HasDatabaseName("ix_people_roles_movie_id");
|
||||||
|
|
||||||
b.HasIndex("PeopleID")
|
b.HasIndex("PeopleID")
|
||||||
.HasDatabaseName("ix_people_roles_people_id");
|
.HasDatabaseName("ix_people_roles_people_id");
|
||||||
|
|
||||||
@ -317,9 +333,14 @@ namespace Kyoo.Postgresql.Migrations
|
|||||||
.HasColumnType("timestamp with time zone")
|
.HasColumnType("timestamp with time zone")
|
||||||
.HasColumnName("end_date");
|
.HasColumnName("end_date");
|
||||||
|
|
||||||
b.Property<string>("ExternalIDs")
|
b.Property<string>("ExternalId")
|
||||||
|
.IsRequired()
|
||||||
.HasColumnType("json")
|
.HasColumnType("json")
|
||||||
.HasColumnName("external_i_ds");
|
.HasColumnName("external_id");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("name");
|
||||||
|
|
||||||
b.Property<string>("Overview")
|
b.Property<string>("Overview")
|
||||||
.HasColumnType("text")
|
.HasColumnType("text")
|
||||||
@ -335,17 +356,14 @@ namespace Kyoo.Postgresql.Migrations
|
|||||||
|
|
||||||
b.Property<string>("Slug")
|
b.Property<string>("Slug")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasColumnType("text")
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("character varying(256)")
|
||||||
.HasColumnName("slug");
|
.HasColumnName("slug");
|
||||||
|
|
||||||
b.Property<DateTime?>("StartDate")
|
b.Property<DateTime?>("StartDate")
|
||||||
.HasColumnType("timestamp with time zone")
|
.HasColumnType("timestamp with time zone")
|
||||||
.HasColumnName("start_date");
|
.HasColumnName("start_date");
|
||||||
|
|
||||||
b.Property<string>("Title")
|
|
||||||
.HasColumnType("text")
|
|
||||||
.HasColumnName("title");
|
|
||||||
|
|
||||||
b.HasKey("ID")
|
b.HasKey("ID")
|
||||||
.HasName("pk_seasons");
|
.HasName("pk_seasons");
|
||||||
|
|
||||||
@ -370,6 +388,7 @@ namespace Kyoo.Postgresql.Migrations
|
|||||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("ID"));
|
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("ID"));
|
||||||
|
|
||||||
b.Property<string[]>("Aliases")
|
b.Property<string[]>("Aliases")
|
||||||
|
.IsRequired()
|
||||||
.HasColumnType("text[]")
|
.HasColumnType("text[]")
|
||||||
.HasColumnName("aliases");
|
.HasColumnName("aliases");
|
||||||
|
|
||||||
@ -377,25 +396,29 @@ namespace Kyoo.Postgresql.Migrations
|
|||||||
.HasColumnType("timestamp with time zone")
|
.HasColumnType("timestamp with time zone")
|
||||||
.HasColumnName("end_air");
|
.HasColumnName("end_air");
|
||||||
|
|
||||||
b.Property<string>("ExternalIDs")
|
b.Property<string>("ExternalId")
|
||||||
|
.IsRequired()
|
||||||
.HasColumnType("json")
|
.HasColumnType("json")
|
||||||
.HasColumnName("external_i_ds");
|
.HasColumnName("external_id");
|
||||||
|
|
||||||
b.Property<bool>("IsMovie")
|
b.Property<Genre[]>("Genres")
|
||||||
.HasColumnType("boolean")
|
.IsRequired()
|
||||||
.HasColumnName("is_movie");
|
.HasColumnType("genre[]")
|
||||||
|
.HasColumnName("genres");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("name");
|
||||||
|
|
||||||
b.Property<string>("Overview")
|
b.Property<string>("Overview")
|
||||||
.HasColumnType("text")
|
.HasColumnType("text")
|
||||||
.HasColumnName("overview");
|
.HasColumnName("overview");
|
||||||
|
|
||||||
b.Property<string>("Path")
|
|
||||||
.HasColumnType("text")
|
|
||||||
.HasColumnName("path");
|
|
||||||
|
|
||||||
b.Property<string>("Slug")
|
b.Property<string>("Slug")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasColumnType("text")
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("character varying(256)")
|
||||||
.HasColumnName("slug");
|
.HasColumnName("slug");
|
||||||
|
|
||||||
b.Property<DateTime?>("StartAir")
|
b.Property<DateTime?>("StartAir")
|
||||||
@ -410,9 +433,14 @@ namespace Kyoo.Postgresql.Migrations
|
|||||||
.HasColumnType("integer")
|
.HasColumnType("integer")
|
||||||
.HasColumnName("studio_id");
|
.HasColumnName("studio_id");
|
||||||
|
|
||||||
b.Property<string>("Title")
|
b.Property<string>("Tagline")
|
||||||
.HasColumnType("text")
|
.HasColumnType("text")
|
||||||
.HasColumnName("title");
|
.HasColumnName("tagline");
|
||||||
|
|
||||||
|
b.Property<string[]>("Tags")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text[]")
|
||||||
|
.HasColumnName("tags");
|
||||||
|
|
||||||
b.Property<string>("Trailer")
|
b.Property<string>("Trailer")
|
||||||
.HasColumnType("text")
|
.HasColumnType("text")
|
||||||
@ -440,17 +468,20 @@ namespace Kyoo.Postgresql.Migrations
|
|||||||
|
|
||||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("ID"));
|
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("ID"));
|
||||||
|
|
||||||
b.Property<string>("ExternalIDs")
|
b.Property<string>("ExternalId")
|
||||||
|
.IsRequired()
|
||||||
.HasColumnType("json")
|
.HasColumnType("json")
|
||||||
.HasColumnName("external_i_ds");
|
.HasColumnName("external_id");
|
||||||
|
|
||||||
b.Property<string>("Name")
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
.HasColumnType("text")
|
.HasColumnType("text")
|
||||||
.HasColumnName("name");
|
.HasColumnName("name");
|
||||||
|
|
||||||
b.Property<string>("Slug")
|
b.Property<string>("Slug")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasColumnType("text")
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("character varying(256)")
|
||||||
.HasColumnName("slug");
|
.HasColumnName("slug");
|
||||||
|
|
||||||
b.HasKey("ID")
|
b.HasKey("ID")
|
||||||
@ -473,27 +504,28 @@ namespace Kyoo.Postgresql.Migrations
|
|||||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("ID"));
|
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("ID"));
|
||||||
|
|
||||||
b.Property<string>("Email")
|
b.Property<string>("Email")
|
||||||
|
.IsRequired()
|
||||||
.HasColumnType("text")
|
.HasColumnType("text")
|
||||||
.HasColumnName("email");
|
.HasColumnName("email");
|
||||||
|
|
||||||
b.Property<Dictionary<string, string>>("ExtraData")
|
|
||||||
.HasColumnType("jsonb")
|
|
||||||
.HasColumnName("extra_data");
|
|
||||||
|
|
||||||
b.Property<string>("Password")
|
b.Property<string>("Password")
|
||||||
|
.IsRequired()
|
||||||
.HasColumnType("text")
|
.HasColumnType("text")
|
||||||
.HasColumnName("password");
|
.HasColumnName("password");
|
||||||
|
|
||||||
b.Property<string[]>("Permissions")
|
b.Property<string[]>("Permissions")
|
||||||
|
.IsRequired()
|
||||||
.HasColumnType("text[]")
|
.HasColumnType("text[]")
|
||||||
.HasColumnName("permissions");
|
.HasColumnName("permissions");
|
||||||
|
|
||||||
b.Property<string>("Slug")
|
b.Property<string>("Slug")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasColumnType("text")
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("character varying(256)")
|
||||||
.HasColumnName("slug");
|
.HasColumnName("slug");
|
||||||
|
|
||||||
b.Property<string>("Username")
|
b.Property<string>("Username")
|
||||||
|
.IsRequired()
|
||||||
.HasColumnType("text")
|
.HasColumnType("text")
|
||||||
.HasColumnName("username");
|
.HasColumnName("username");
|
||||||
|
|
||||||
@ -522,12 +554,12 @@ namespace Kyoo.Postgresql.Migrations
|
|||||||
.HasColumnName("watched_percentage");
|
.HasColumnName("watched_percentage");
|
||||||
|
|
||||||
b.HasKey("UserID", "EpisodeID")
|
b.HasKey("UserID", "EpisodeID")
|
||||||
.HasName("pk_watched_episodes");
|
.HasName("pk_watched_episode");
|
||||||
|
|
||||||
b.HasIndex("EpisodeID")
|
b.HasIndex("EpisodeID")
|
||||||
.HasDatabaseName("ix_watched_episodes_episode_id");
|
.HasDatabaseName("ix_watched_episode_episode_id");
|
||||||
|
|
||||||
b.ToTable("watched_episodes", (string)null);
|
b.ToTable("watched_episode", (string)null);
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("ShowUser", b =>
|
modelBuilder.Entity("ShowUser", b =>
|
||||||
@ -568,61 +600,21 @@ namespace Kyoo.Postgresql.Migrations
|
|||||||
b.ToTable("link_collection_show", (string)null);
|
b.ToTable("link_collection_show", (string)null);
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("link_library_collection", b =>
|
modelBuilder.Entity("CollectionMovie", b =>
|
||||||
{
|
{
|
||||||
b.Property<int>("collection_id")
|
b.HasOne("Kyoo.Abstractions.Models.Collection", null)
|
||||||
.HasColumnType("integer")
|
.WithMany()
|
||||||
.HasColumnName("collection_id");
|
.HasForeignKey("CollectionsID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_collection_movie_collections_collections_id");
|
||||||
|
|
||||||
b.Property<int>("library_id")
|
b.HasOne("Kyoo.Abstractions.Models.Movie", null)
|
||||||
.HasColumnType("integer")
|
.WithMany()
|
||||||
.HasColumnName("library_id");
|
.HasForeignKey("MoviesID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
b.HasKey("collection_id", "library_id")
|
.IsRequired()
|
||||||
.HasName("pk_link_library_collection");
|
.HasConstraintName("fk_collection_movie_movies_movies_id");
|
||||||
|
|
||||||
b.HasIndex("library_id")
|
|
||||||
.HasDatabaseName("ix_link_library_collection_library_id");
|
|
||||||
|
|
||||||
b.ToTable("link_library_collection", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("link_library_show", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("library_id")
|
|
||||||
.HasColumnType("integer")
|
|
||||||
.HasColumnName("library_id");
|
|
||||||
|
|
||||||
b.Property<int>("show_id")
|
|
||||||
.HasColumnType("integer")
|
|
||||||
.HasColumnName("show_id");
|
|
||||||
|
|
||||||
b.HasKey("library_id", "show_id")
|
|
||||||
.HasName("pk_link_library_show");
|
|
||||||
|
|
||||||
b.HasIndex("show_id")
|
|
||||||
.HasDatabaseName("ix_link_library_show_show_id");
|
|
||||||
|
|
||||||
b.ToTable("link_library_show", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("link_show_genre", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("genre_id")
|
|
||||||
.HasColumnType("integer")
|
|
||||||
.HasColumnName("genre_id");
|
|
||||||
|
|
||||||
b.Property<int>("show_id")
|
|
||||||
.HasColumnType("integer")
|
|
||||||
.HasColumnName("show_id");
|
|
||||||
|
|
||||||
b.HasKey("genre_id", "show_id")
|
|
||||||
.HasName("pk_link_show_genre");
|
|
||||||
|
|
||||||
b.HasIndex("show_id")
|
|
||||||
.HasDatabaseName("ix_link_show_genre_show_id");
|
|
||||||
|
|
||||||
b.ToTable("link_show_genre", (string)null);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Kyoo.Abstractions.Models.Collection", b =>
|
modelBuilder.Entity("Kyoo.Abstractions.Models.Collection", b =>
|
||||||
@ -634,11 +626,13 @@ namespace Kyoo.Postgresql.Migrations
|
|||||||
.HasColumnName("id");
|
.HasColumnName("id");
|
||||||
|
|
||||||
b1.Property<string>("Blurhash")
|
b1.Property<string>("Blurhash")
|
||||||
|
.IsRequired()
|
||||||
.HasMaxLength(32)
|
.HasMaxLength(32)
|
||||||
.HasColumnType("character varying(32)")
|
.HasColumnType("character varying(32)")
|
||||||
.HasColumnName("logo_blurhash");
|
.HasColumnName("logo_blurhash");
|
||||||
|
|
||||||
b1.Property<string>("Source")
|
b1.Property<string>("Source")
|
||||||
|
.IsRequired()
|
||||||
.HasColumnType("text")
|
.HasColumnType("text")
|
||||||
.HasColumnName("logo_source");
|
.HasColumnName("logo_source");
|
||||||
|
|
||||||
@ -658,11 +652,13 @@ namespace Kyoo.Postgresql.Migrations
|
|||||||
.HasColumnName("id");
|
.HasColumnName("id");
|
||||||
|
|
||||||
b1.Property<string>("Blurhash")
|
b1.Property<string>("Blurhash")
|
||||||
|
.IsRequired()
|
||||||
.HasMaxLength(32)
|
.HasMaxLength(32)
|
||||||
.HasColumnType("character varying(32)")
|
.HasColumnType("character varying(32)")
|
||||||
.HasColumnName("poster_blurhash");
|
.HasColumnName("poster_blurhash");
|
||||||
|
|
||||||
b1.Property<string>("Source")
|
b1.Property<string>("Source")
|
||||||
|
.IsRequired()
|
||||||
.HasColumnType("text")
|
.HasColumnType("text")
|
||||||
.HasColumnName("poster_source");
|
.HasColumnName("poster_source");
|
||||||
|
|
||||||
@ -682,11 +678,13 @@ namespace Kyoo.Postgresql.Migrations
|
|||||||
.HasColumnName("id");
|
.HasColumnName("id");
|
||||||
|
|
||||||
b1.Property<string>("Blurhash")
|
b1.Property<string>("Blurhash")
|
||||||
|
.IsRequired()
|
||||||
.HasMaxLength(32)
|
.HasMaxLength(32)
|
||||||
.HasColumnType("character varying(32)")
|
.HasColumnType("character varying(32)")
|
||||||
.HasColumnName("thumbnail_blurhash");
|
.HasColumnName("thumbnail_blurhash");
|
||||||
|
|
||||||
b1.Property<string>("Source")
|
b1.Property<string>("Source")
|
||||||
|
.IsRequired()
|
||||||
.HasColumnType("text")
|
.HasColumnType("text")
|
||||||
.HasColumnName("thumbnail_source");
|
.HasColumnName("thumbnail_source");
|
||||||
|
|
||||||
@ -728,11 +726,13 @@ namespace Kyoo.Postgresql.Migrations
|
|||||||
.HasColumnName("id");
|
.HasColumnName("id");
|
||||||
|
|
||||||
b1.Property<string>("Blurhash")
|
b1.Property<string>("Blurhash")
|
||||||
|
.IsRequired()
|
||||||
.HasMaxLength(32)
|
.HasMaxLength(32)
|
||||||
.HasColumnType("character varying(32)")
|
.HasColumnType("character varying(32)")
|
||||||
.HasColumnName("logo_blurhash");
|
.HasColumnName("logo_blurhash");
|
||||||
|
|
||||||
b1.Property<string>("Source")
|
b1.Property<string>("Source")
|
||||||
|
.IsRequired()
|
||||||
.HasColumnType("text")
|
.HasColumnType("text")
|
||||||
.HasColumnName("logo_source");
|
.HasColumnName("logo_source");
|
||||||
|
|
||||||
@ -752,11 +752,13 @@ namespace Kyoo.Postgresql.Migrations
|
|||||||
.HasColumnName("id");
|
.HasColumnName("id");
|
||||||
|
|
||||||
b1.Property<string>("Blurhash")
|
b1.Property<string>("Blurhash")
|
||||||
|
.IsRequired()
|
||||||
.HasMaxLength(32)
|
.HasMaxLength(32)
|
||||||
.HasColumnType("character varying(32)")
|
.HasColumnType("character varying(32)")
|
||||||
.HasColumnName("poster_blurhash");
|
.HasColumnName("poster_blurhash");
|
||||||
|
|
||||||
b1.Property<string>("Source")
|
b1.Property<string>("Source")
|
||||||
|
.IsRequired()
|
||||||
.HasColumnType("text")
|
.HasColumnType("text")
|
||||||
.HasColumnName("poster_source");
|
.HasColumnName("poster_source");
|
||||||
|
|
||||||
@ -776,11 +778,13 @@ namespace Kyoo.Postgresql.Migrations
|
|||||||
.HasColumnName("id");
|
.HasColumnName("id");
|
||||||
|
|
||||||
b1.Property<string>("Blurhash")
|
b1.Property<string>("Blurhash")
|
||||||
|
.IsRequired()
|
||||||
.HasMaxLength(32)
|
.HasMaxLength(32)
|
||||||
.HasColumnType("character varying(32)")
|
.HasColumnType("character varying(32)")
|
||||||
.HasColumnName("thumbnail_blurhash");
|
.HasColumnName("thumbnail_blurhash");
|
||||||
|
|
||||||
b1.Property<string>("Source")
|
b1.Property<string>("Source")
|
||||||
|
.IsRequired()
|
||||||
.HasColumnType("text")
|
.HasColumnType("text")
|
||||||
.HasColumnName("thumbnail_source");
|
.HasColumnName("thumbnail_source");
|
||||||
|
|
||||||
@ -804,87 +808,98 @@ namespace Kyoo.Postgresql.Migrations
|
|||||||
b.Navigation("Thumbnail");
|
b.Navigation("Thumbnail");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Kyoo.Abstractions.Models.LibraryItem", b =>
|
modelBuilder.Entity("Kyoo.Abstractions.Models.Movie", b =>
|
||||||
{
|
{
|
||||||
|
b.HasOne("Kyoo.Abstractions.Models.Studio", "Studio")
|
||||||
|
.WithMany("Movies")
|
||||||
|
.HasForeignKey("StudioID")
|
||||||
|
.OnDelete(DeleteBehavior.SetNull)
|
||||||
|
.HasConstraintName("fk_movies_studios_studio_id");
|
||||||
|
|
||||||
b.OwnsOne("Kyoo.Abstractions.Models.Image", "Logo", b1 =>
|
b.OwnsOne("Kyoo.Abstractions.Models.Image", "Logo", b1 =>
|
||||||
{
|
{
|
||||||
b1.Property<int>("LibraryItemID")
|
b1.Property<int>("MovieID")
|
||||||
.HasColumnType("integer")
|
.HasColumnType("integer")
|
||||||
.HasColumnName("library_item_id");
|
.HasColumnName("id");
|
||||||
|
|
||||||
b1.Property<string>("Blurhash")
|
b1.Property<string>("Blurhash")
|
||||||
|
.IsRequired()
|
||||||
.HasMaxLength(32)
|
.HasMaxLength(32)
|
||||||
.HasColumnType("character varying(32)")
|
.HasColumnType("character varying(32)")
|
||||||
.HasColumnName("blurhash");
|
.HasColumnName("logo_blurhash");
|
||||||
|
|
||||||
b1.Property<string>("Source")
|
b1.Property<string>("Source")
|
||||||
|
.IsRequired()
|
||||||
.HasColumnType("text")
|
.HasColumnType("text")
|
||||||
.HasColumnName("source");
|
.HasColumnName("logo_source");
|
||||||
|
|
||||||
b1.HasKey("LibraryItemID");
|
b1.HasKey("MovieID");
|
||||||
|
|
||||||
b1.ToTable((string)null);
|
b1.ToTable("movies");
|
||||||
|
|
||||||
b1.ToView("library_items");
|
|
||||||
|
|
||||||
b1.WithOwner()
|
b1.WithOwner()
|
||||||
.HasForeignKey("LibraryItemID");
|
.HasForeignKey("MovieID")
|
||||||
|
.HasConstraintName("fk_movies_movies_id");
|
||||||
});
|
});
|
||||||
|
|
||||||
b.OwnsOne("Kyoo.Abstractions.Models.Image", "Poster", b1 =>
|
b.OwnsOne("Kyoo.Abstractions.Models.Image", "Poster", b1 =>
|
||||||
{
|
{
|
||||||
b1.Property<int>("LibraryItemID")
|
b1.Property<int>("MovieID")
|
||||||
.HasColumnType("integer")
|
.HasColumnType("integer")
|
||||||
.HasColumnName("library_item_id");
|
.HasColumnName("id");
|
||||||
|
|
||||||
b1.Property<string>("Blurhash")
|
b1.Property<string>("Blurhash")
|
||||||
|
.IsRequired()
|
||||||
.HasMaxLength(32)
|
.HasMaxLength(32)
|
||||||
.HasColumnType("character varying(32)")
|
.HasColumnType("character varying(32)")
|
||||||
.HasColumnName("blurhash");
|
.HasColumnName("poster_blurhash");
|
||||||
|
|
||||||
b1.Property<string>("Source")
|
b1.Property<string>("Source")
|
||||||
|
.IsRequired()
|
||||||
.HasColumnType("text")
|
.HasColumnType("text")
|
||||||
.HasColumnName("source");
|
.HasColumnName("poster_source");
|
||||||
|
|
||||||
b1.HasKey("LibraryItemID");
|
b1.HasKey("MovieID");
|
||||||
|
|
||||||
b1.ToTable((string)null);
|
b1.ToTable("movies");
|
||||||
|
|
||||||
b1.ToView("library_items");
|
|
||||||
|
|
||||||
b1.WithOwner()
|
b1.WithOwner()
|
||||||
.HasForeignKey("LibraryItemID");
|
.HasForeignKey("MovieID")
|
||||||
|
.HasConstraintName("fk_movies_movies_id");
|
||||||
});
|
});
|
||||||
|
|
||||||
b.OwnsOne("Kyoo.Abstractions.Models.Image", "Thumbnail", b1 =>
|
b.OwnsOne("Kyoo.Abstractions.Models.Image", "Thumbnail", b1 =>
|
||||||
{
|
{
|
||||||
b1.Property<int>("LibraryItemID")
|
b1.Property<int>("MovieID")
|
||||||
.HasColumnType("integer")
|
.HasColumnType("integer")
|
||||||
.HasColumnName("library_item_id");
|
.HasColumnName("id");
|
||||||
|
|
||||||
b1.Property<string>("Blurhash")
|
b1.Property<string>("Blurhash")
|
||||||
|
.IsRequired()
|
||||||
.HasMaxLength(32)
|
.HasMaxLength(32)
|
||||||
.HasColumnType("character varying(32)")
|
.HasColumnType("character varying(32)")
|
||||||
.HasColumnName("blurhash");
|
.HasColumnName("thumbnail_blurhash");
|
||||||
|
|
||||||
b1.Property<string>("Source")
|
b1.Property<string>("Source")
|
||||||
|
.IsRequired()
|
||||||
.HasColumnType("text")
|
.HasColumnType("text")
|
||||||
.HasColumnName("source");
|
.HasColumnName("thumbnail_source");
|
||||||
|
|
||||||
b1.HasKey("LibraryItemID");
|
b1.HasKey("MovieID");
|
||||||
|
|
||||||
b1.ToTable((string)null);
|
b1.ToTable("movies");
|
||||||
|
|
||||||
b1.ToView("library_items");
|
|
||||||
|
|
||||||
b1.WithOwner()
|
b1.WithOwner()
|
||||||
.HasForeignKey("LibraryItemID");
|
.HasForeignKey("MovieID")
|
||||||
|
.HasConstraintName("fk_movies_movies_id");
|
||||||
});
|
});
|
||||||
|
|
||||||
b.Navigation("Logo");
|
b.Navigation("Logo");
|
||||||
|
|
||||||
b.Navigation("Poster");
|
b.Navigation("Poster");
|
||||||
|
|
||||||
|
b.Navigation("Studio");
|
||||||
|
|
||||||
b.Navigation("Thumbnail");
|
b.Navigation("Thumbnail");
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -897,11 +912,13 @@ namespace Kyoo.Postgresql.Migrations
|
|||||||
.HasColumnName("id");
|
.HasColumnName("id");
|
||||||
|
|
||||||
b1.Property<string>("Blurhash")
|
b1.Property<string>("Blurhash")
|
||||||
|
.IsRequired()
|
||||||
.HasMaxLength(32)
|
.HasMaxLength(32)
|
||||||
.HasColumnType("character varying(32)")
|
.HasColumnType("character varying(32)")
|
||||||
.HasColumnName("logo_blurhash");
|
.HasColumnName("logo_blurhash");
|
||||||
|
|
||||||
b1.Property<string>("Source")
|
b1.Property<string>("Source")
|
||||||
|
.IsRequired()
|
||||||
.HasColumnType("text")
|
.HasColumnType("text")
|
||||||
.HasColumnName("logo_source");
|
.HasColumnName("logo_source");
|
||||||
|
|
||||||
@ -921,11 +938,13 @@ namespace Kyoo.Postgresql.Migrations
|
|||||||
.HasColumnName("id");
|
.HasColumnName("id");
|
||||||
|
|
||||||
b1.Property<string>("Blurhash")
|
b1.Property<string>("Blurhash")
|
||||||
|
.IsRequired()
|
||||||
.HasMaxLength(32)
|
.HasMaxLength(32)
|
||||||
.HasColumnType("character varying(32)")
|
.HasColumnType("character varying(32)")
|
||||||
.HasColumnName("poster_blurhash");
|
.HasColumnName("poster_blurhash");
|
||||||
|
|
||||||
b1.Property<string>("Source")
|
b1.Property<string>("Source")
|
||||||
|
.IsRequired()
|
||||||
.HasColumnType("text")
|
.HasColumnType("text")
|
||||||
.HasColumnName("poster_source");
|
.HasColumnName("poster_source");
|
||||||
|
|
||||||
@ -945,11 +964,13 @@ namespace Kyoo.Postgresql.Migrations
|
|||||||
.HasColumnName("id");
|
.HasColumnName("id");
|
||||||
|
|
||||||
b1.Property<string>("Blurhash")
|
b1.Property<string>("Blurhash")
|
||||||
|
.IsRequired()
|
||||||
.HasMaxLength(32)
|
.HasMaxLength(32)
|
||||||
.HasColumnType("character varying(32)")
|
.HasColumnType("character varying(32)")
|
||||||
.HasColumnName("thumbnail_blurhash");
|
.HasColumnName("thumbnail_blurhash");
|
||||||
|
|
||||||
b1.Property<string>("Source")
|
b1.Property<string>("Source")
|
||||||
|
.IsRequired()
|
||||||
.HasColumnType("text")
|
.HasColumnType("text")
|
||||||
.HasColumnName("thumbnail_source");
|
.HasColumnName("thumbnail_source");
|
||||||
|
|
||||||
@ -971,6 +992,11 @@ namespace Kyoo.Postgresql.Migrations
|
|||||||
|
|
||||||
modelBuilder.Entity("Kyoo.Abstractions.Models.PeopleRole", b =>
|
modelBuilder.Entity("Kyoo.Abstractions.Models.PeopleRole", b =>
|
||||||
{
|
{
|
||||||
|
b.HasOne("Kyoo.Abstractions.Models.Movie", "Movie")
|
||||||
|
.WithMany("People")
|
||||||
|
.HasForeignKey("MovieID")
|
||||||
|
.HasConstraintName("fk_people_roles_movies_movie_id");
|
||||||
|
|
||||||
b.HasOne("Kyoo.Abstractions.Models.People", "People")
|
b.HasOne("Kyoo.Abstractions.Models.People", "People")
|
||||||
.WithMany("Roles")
|
.WithMany("Roles")
|
||||||
.HasForeignKey("PeopleID")
|
.HasForeignKey("PeopleID")
|
||||||
@ -981,10 +1007,10 @@ namespace Kyoo.Postgresql.Migrations
|
|||||||
b.HasOne("Kyoo.Abstractions.Models.Show", "Show")
|
b.HasOne("Kyoo.Abstractions.Models.Show", "Show")
|
||||||
.WithMany("People")
|
.WithMany("People")
|
||||||
.HasForeignKey("ShowID")
|
.HasForeignKey("ShowID")
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired()
|
|
||||||
.HasConstraintName("fk_people_roles_shows_show_id");
|
.HasConstraintName("fk_people_roles_shows_show_id");
|
||||||
|
|
||||||
|
b.Navigation("Movie");
|
||||||
|
|
||||||
b.Navigation("People");
|
b.Navigation("People");
|
||||||
|
|
||||||
b.Navigation("Show");
|
b.Navigation("Show");
|
||||||
@ -1006,11 +1032,13 @@ namespace Kyoo.Postgresql.Migrations
|
|||||||
.HasColumnName("id");
|
.HasColumnName("id");
|
||||||
|
|
||||||
b1.Property<string>("Blurhash")
|
b1.Property<string>("Blurhash")
|
||||||
|
.IsRequired()
|
||||||
.HasMaxLength(32)
|
.HasMaxLength(32)
|
||||||
.HasColumnType("character varying(32)")
|
.HasColumnType("character varying(32)")
|
||||||
.HasColumnName("logo_blurhash");
|
.HasColumnName("logo_blurhash");
|
||||||
|
|
||||||
b1.Property<string>("Source")
|
b1.Property<string>("Source")
|
||||||
|
.IsRequired()
|
||||||
.HasColumnType("text")
|
.HasColumnType("text")
|
||||||
.HasColumnName("logo_source");
|
.HasColumnName("logo_source");
|
||||||
|
|
||||||
@ -1030,11 +1058,13 @@ namespace Kyoo.Postgresql.Migrations
|
|||||||
.HasColumnName("id");
|
.HasColumnName("id");
|
||||||
|
|
||||||
b1.Property<string>("Blurhash")
|
b1.Property<string>("Blurhash")
|
||||||
|
.IsRequired()
|
||||||
.HasMaxLength(32)
|
.HasMaxLength(32)
|
||||||
.HasColumnType("character varying(32)")
|
.HasColumnType("character varying(32)")
|
||||||
.HasColumnName("poster_blurhash");
|
.HasColumnName("poster_blurhash");
|
||||||
|
|
||||||
b1.Property<string>("Source")
|
b1.Property<string>("Source")
|
||||||
|
.IsRequired()
|
||||||
.HasColumnType("text")
|
.HasColumnType("text")
|
||||||
.HasColumnName("poster_source");
|
.HasColumnName("poster_source");
|
||||||
|
|
||||||
@ -1054,11 +1084,13 @@ namespace Kyoo.Postgresql.Migrations
|
|||||||
.HasColumnName("id");
|
.HasColumnName("id");
|
||||||
|
|
||||||
b1.Property<string>("Blurhash")
|
b1.Property<string>("Blurhash")
|
||||||
|
.IsRequired()
|
||||||
.HasMaxLength(32)
|
.HasMaxLength(32)
|
||||||
.HasColumnType("character varying(32)")
|
.HasColumnType("character varying(32)")
|
||||||
.HasColumnName("thumbnail_blurhash");
|
.HasColumnName("thumbnail_blurhash");
|
||||||
|
|
||||||
b1.Property<string>("Source")
|
b1.Property<string>("Source")
|
||||||
|
.IsRequired()
|
||||||
.HasColumnType("text")
|
.HasColumnType("text")
|
||||||
.HasColumnName("thumbnail_source");
|
.HasColumnName("thumbnail_source");
|
||||||
|
|
||||||
@ -1095,11 +1127,13 @@ namespace Kyoo.Postgresql.Migrations
|
|||||||
.HasColumnName("id");
|
.HasColumnName("id");
|
||||||
|
|
||||||
b1.Property<string>("Blurhash")
|
b1.Property<string>("Blurhash")
|
||||||
|
.IsRequired()
|
||||||
.HasMaxLength(32)
|
.HasMaxLength(32)
|
||||||
.HasColumnType("character varying(32)")
|
.HasColumnType("character varying(32)")
|
||||||
.HasColumnName("logo_blurhash");
|
.HasColumnName("logo_blurhash");
|
||||||
|
|
||||||
b1.Property<string>("Source")
|
b1.Property<string>("Source")
|
||||||
|
.IsRequired()
|
||||||
.HasColumnType("text")
|
.HasColumnType("text")
|
||||||
.HasColumnName("logo_source");
|
.HasColumnName("logo_source");
|
||||||
|
|
||||||
@ -1119,11 +1153,13 @@ namespace Kyoo.Postgresql.Migrations
|
|||||||
.HasColumnName("id");
|
.HasColumnName("id");
|
||||||
|
|
||||||
b1.Property<string>("Blurhash")
|
b1.Property<string>("Blurhash")
|
||||||
|
.IsRequired()
|
||||||
.HasMaxLength(32)
|
.HasMaxLength(32)
|
||||||
.HasColumnType("character varying(32)")
|
.HasColumnType("character varying(32)")
|
||||||
.HasColumnName("poster_blurhash");
|
.HasColumnName("poster_blurhash");
|
||||||
|
|
||||||
b1.Property<string>("Source")
|
b1.Property<string>("Source")
|
||||||
|
.IsRequired()
|
||||||
.HasColumnType("text")
|
.HasColumnType("text")
|
||||||
.HasColumnName("poster_source");
|
.HasColumnName("poster_source");
|
||||||
|
|
||||||
@ -1143,11 +1179,13 @@ namespace Kyoo.Postgresql.Migrations
|
|||||||
.HasColumnName("id");
|
.HasColumnName("id");
|
||||||
|
|
||||||
b1.Property<string>("Blurhash")
|
b1.Property<string>("Blurhash")
|
||||||
|
.IsRequired()
|
||||||
.HasMaxLength(32)
|
.HasMaxLength(32)
|
||||||
.HasColumnType("character varying(32)")
|
.HasColumnType("character varying(32)")
|
||||||
.HasColumnName("thumbnail_blurhash");
|
.HasColumnName("thumbnail_blurhash");
|
||||||
|
|
||||||
b1.Property<string>("Source")
|
b1.Property<string>("Source")
|
||||||
|
.IsRequired()
|
||||||
.HasColumnType("text")
|
.HasColumnType("text")
|
||||||
.HasColumnName("thumbnail_source");
|
.HasColumnName("thumbnail_source");
|
||||||
|
|
||||||
@ -1178,11 +1216,13 @@ namespace Kyoo.Postgresql.Migrations
|
|||||||
.HasColumnName("id");
|
.HasColumnName("id");
|
||||||
|
|
||||||
b1.Property<string>("Blurhash")
|
b1.Property<string>("Blurhash")
|
||||||
|
.IsRequired()
|
||||||
.HasMaxLength(32)
|
.HasMaxLength(32)
|
||||||
.HasColumnType("character varying(32)")
|
.HasColumnType("character varying(32)")
|
||||||
.HasColumnName("logo_blurhash");
|
.HasColumnName("logo_blurhash");
|
||||||
|
|
||||||
b1.Property<string>("Source")
|
b1.Property<string>("Source")
|
||||||
|
.IsRequired()
|
||||||
.HasColumnType("text")
|
.HasColumnType("text")
|
||||||
.HasColumnName("logo_source");
|
.HasColumnName("logo_source");
|
||||||
|
|
||||||
@ -1205,14 +1245,14 @@ namespace Kyoo.Postgresql.Migrations
|
|||||||
.HasForeignKey("EpisodeID")
|
.HasForeignKey("EpisodeID")
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasConstraintName("fk_watched_episodes_episodes_episode_id");
|
.HasConstraintName("fk_watched_episode_episodes_episode_id");
|
||||||
|
|
||||||
b.HasOne("Kyoo.Abstractions.Models.User", null)
|
b.HasOne("Kyoo.Abstractions.Models.User", null)
|
||||||
.WithMany("CurrentlyWatching")
|
.WithMany("CurrentlyWatching")
|
||||||
.HasForeignKey("UserID")
|
.HasForeignKey("UserID")
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasConstraintName("fk_watched_episodes_users_user_id");
|
.HasConstraintName("fk_watched_episode_users_user_id");
|
||||||
|
|
||||||
b.Navigation("Episode");
|
b.Navigation("Episode");
|
||||||
});
|
});
|
||||||
@ -1251,55 +1291,9 @@ namespace Kyoo.Postgresql.Migrations
|
|||||||
.HasConstraintName("fk_link_collection_show_shows_show_id");
|
.HasConstraintName("fk_link_collection_show_shows_show_id");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("link_library_collection", b =>
|
modelBuilder.Entity("Kyoo.Abstractions.Models.Movie", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("Kyoo.Abstractions.Models.Collection", null)
|
b.Navigation("People");
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("collection_id")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired()
|
|
||||||
.HasConstraintName("fk_link_library_collection_collections_collection_id");
|
|
||||||
|
|
||||||
b.HasOne("Kyoo.Abstractions.Models.Library", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("library_id")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired()
|
|
||||||
.HasConstraintName("fk_link_library_collection_libraries_library_id");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("link_library_show", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Kyoo.Abstractions.Models.Library", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("library_id")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired()
|
|
||||||
.HasConstraintName("fk_link_library_show_libraries_library_id");
|
|
||||||
|
|
||||||
b.HasOne("Kyoo.Abstractions.Models.Show", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("show_id")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired()
|
|
||||||
.HasConstraintName("fk_link_library_show_shows_show_id");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("link_show_genre", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Kyoo.Abstractions.Models.Genre", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("genre_id")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired()
|
|
||||||
.HasConstraintName("fk_link_show_genre_genres_genre_id");
|
|
||||||
|
|
||||||
b.HasOne("Kyoo.Abstractions.Models.Show", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("show_id")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired()
|
|
||||||
.HasConstraintName("fk_link_show_genre_shows_show_id");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Kyoo.Abstractions.Models.People", b =>
|
modelBuilder.Entity("Kyoo.Abstractions.Models.People", b =>
|
||||||
@ -1323,6 +1317,8 @@ namespace Kyoo.Postgresql.Migrations
|
|||||||
|
|
||||||
modelBuilder.Entity("Kyoo.Abstractions.Models.Studio", b =>
|
modelBuilder.Entity("Kyoo.Abstractions.Models.Studio", b =>
|
||||||
{
|
{
|
||||||
|
b.Navigation("Movies");
|
||||||
|
|
||||||
b.Navigation("Shows");
|
b.Navigation("Shows");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -43,12 +43,12 @@ namespace Kyoo.Postgresql
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly bool _skipConfigure;
|
private readonly bool _skipConfigure;
|
||||||
|
|
||||||
// TOOD: This needs ot be updated but ef-core still does not offer a way to use this.
|
// TODO: This needs ot be updated but ef-core still does not offer a way to use this.
|
||||||
[Obsolete]
|
[Obsolete]
|
||||||
static PostgresContext()
|
static PostgresContext()
|
||||||
{
|
{
|
||||||
NpgsqlConnection.GlobalTypeMapper.MapEnum<Status>();
|
NpgsqlConnection.GlobalTypeMapper.MapEnum<Status>();
|
||||||
NpgsqlConnection.GlobalTypeMapper.MapEnum<ItemType>();
|
NpgsqlConnection.GlobalTypeMapper.MapEnum<Genre>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -100,26 +100,11 @@ namespace Kyoo.Postgresql
|
|||||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||||
{
|
{
|
||||||
modelBuilder.HasPostgresEnum<Status>();
|
modelBuilder.HasPostgresEnum<Status>();
|
||||||
modelBuilder.HasPostgresEnum<ItemType>();
|
modelBuilder.HasPostgresEnum<Genre>();
|
||||||
|
|
||||||
modelBuilder.Entity<LibraryItem>()
|
|
||||||
.ToView("library_items")
|
|
||||||
.HasKey(x => x.ID);
|
|
||||||
|
|
||||||
modelBuilder.Entity<User>()
|
|
||||||
.Property(x => x.ExtraData)
|
|
||||||
.HasColumnType("jsonb");
|
|
||||||
|
|
||||||
base.OnModelCreating(modelBuilder);
|
base.OnModelCreating(modelBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override string MetadataName<T>()
|
|
||||||
{
|
|
||||||
SnakeCaseNameRewriter rewriter = new(CultureInfo.InvariantCulture);
|
|
||||||
return rewriter.RewriteName(typeof(T).Name + nameof(MetadataID));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override string LinkName<T, T2>()
|
protected override string LinkName<T, T2>()
|
||||||
{
|
{
|
||||||
|
@ -37,21 +37,17 @@ namespace Kyoo.Tests.Database
|
|||||||
{
|
{
|
||||||
Context = new PostgresTestContext(postgres, output);
|
Context = new PostgresTestContext(postgres, output);
|
||||||
|
|
||||||
LibraryRepository library = new(_NewContext());
|
|
||||||
CollectionRepository collection = new(_NewContext());
|
CollectionRepository collection = new(_NewContext());
|
||||||
GenreRepository genre = new(_NewContext());
|
|
||||||
StudioRepository studio = new(_NewContext());
|
StudioRepository studio = new(_NewContext());
|
||||||
PeopleRepository people = new(_NewContext(),
|
PeopleRepository people = new(_NewContext(),
|
||||||
new Lazy<IShowRepository>(() => LibraryManager.ShowRepository));
|
new Lazy<IShowRepository>(() => LibraryManager.ShowRepository));
|
||||||
ShowRepository show = new(_NewContext(), studio, people, genre);
|
ShowRepository show = new(_NewContext(), studio, people);
|
||||||
SeasonRepository season = new(_NewContext(), show);
|
SeasonRepository season = new(_NewContext(), show);
|
||||||
LibraryItemRepository libraryItem = new(_NewContext(),
|
LibraryItemRepository libraryItem = new(_NewContext());
|
||||||
new Lazy<ILibraryRepository>(() => LibraryManager.LibraryRepository));
|
|
||||||
EpisodeRepository episode = new(_NewContext(), show);
|
EpisodeRepository episode = new(_NewContext(), show);
|
||||||
UserRepository user = new(_NewContext());
|
UserRepository user = new(_NewContext());
|
||||||
|
|
||||||
LibraryManager = new LibraryManager(new IBaseRepository[] {
|
LibraryManager = new LibraryManager(new IBaseRepository[] {
|
||||||
library,
|
|
||||||
libraryItem,
|
libraryItem,
|
||||||
collection,
|
collection,
|
||||||
show,
|
show,
|
||||||
@ -59,7 +55,6 @@ namespace Kyoo.Tests.Database
|
|||||||
episode,
|
episode,
|
||||||
people,
|
people,
|
||||||
studio,
|
studio,
|
||||||
genre,
|
|
||||||
user
|
user
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -234,7 +234,7 @@ namespace Kyoo.Tests.Database
|
|||||||
public async Task EditTest()
|
public async Task EditTest()
|
||||||
{
|
{
|
||||||
Episode value = await _repository.Get(TestSample.Get<Episode>().Slug);
|
Episode value = await _repository.Get(TestSample.Get<Episode>().Slug);
|
||||||
value.Title = "New Title";
|
value.Name = "New Title";
|
||||||
value.Images = new Dictionary<int, string>
|
value.Images = new Dictionary<int, string>
|
||||||
{
|
{
|
||||||
[Images.Poster] = "new-poster"
|
[Images.Poster] = "new-poster"
|
||||||
@ -325,7 +325,7 @@ namespace Kyoo.Tests.Database
|
|||||||
{
|
{
|
||||||
Episode value = new()
|
Episode value = new()
|
||||||
{
|
{
|
||||||
Title = "This is a test super title",
|
Name = "This is a test super title",
|
||||||
ShowID = 1,
|
ShowID = 1,
|
||||||
AbsoluteNumber = 2
|
AbsoluteNumber = 2
|
||||||
};
|
};
|
||||||
|
@ -121,7 +121,7 @@ namespace Kyoo.Tests.Database
|
|||||||
public async Task EditTest()
|
public async Task EditTest()
|
||||||
{
|
{
|
||||||
Season value = await _repository.Get(TestSample.Get<Season>().Slug);
|
Season value = await _repository.Get(TestSample.Get<Season>().Slug);
|
||||||
value.Title = "New Title";
|
value.Name = "New Title";
|
||||||
value.Images = new Dictionary<int, string>
|
value.Images = new Dictionary<int, string>
|
||||||
{
|
{
|
||||||
[Images.Poster] = "new-poster"
|
[Images.Poster] = "new-poster"
|
||||||
@ -212,7 +212,7 @@ namespace Kyoo.Tests.Database
|
|||||||
{
|
{
|
||||||
Season value = new()
|
Season value = new()
|
||||||
{
|
{
|
||||||
Title = "This is a test super title",
|
Name = "This is a test super title",
|
||||||
ShowID = 1
|
ShowID = 1
|
||||||
};
|
};
|
||||||
await _repository.Create(value);
|
await _repository.Create(value);
|
||||||
|
@ -56,7 +56,7 @@ namespace Kyoo.Tests.Database
|
|||||||
{
|
{
|
||||||
Show value = await _repository.Get(TestSample.Get<Show>().Slug);
|
Show value = await _repository.Get(TestSample.Get<Show>().Slug);
|
||||||
value.Path = "/super";
|
value.Path = "/super";
|
||||||
value.Title = "New Title";
|
value.Name = "New Title";
|
||||||
Show edited = await _repository.Edit(value, false);
|
Show edited = await _repository.Edit(value, false);
|
||||||
KAssert.DeepEqual(value, edited);
|
KAssert.DeepEqual(value, edited);
|
||||||
|
|
||||||
@ -215,7 +215,7 @@ namespace Kyoo.Tests.Database
|
|||||||
{
|
{
|
||||||
ID = value.ID,
|
ID = value.ID,
|
||||||
Slug = "reset",
|
Slug = "reset",
|
||||||
Title = "Reset"
|
Name = "Reset"
|
||||||
};
|
};
|
||||||
|
|
||||||
Show edited = await _repository.Edit(newValue, true);
|
Show edited = await _repository.Edit(newValue, true);
|
||||||
@ -223,7 +223,7 @@ namespace Kyoo.Tests.Database
|
|||||||
Assert.Equal(value.ID, edited.ID);
|
Assert.Equal(value.ID, edited.ID);
|
||||||
Assert.Null(edited.Overview);
|
Assert.Null(edited.Overview);
|
||||||
Assert.Equal("reset", edited.Slug);
|
Assert.Equal("reset", edited.Slug);
|
||||||
Assert.Equal("Reset", edited.Title);
|
Assert.Equal("Reset", edited.Name);
|
||||||
Assert.Null(edited.Aliases);
|
Assert.Null(edited.Aliases);
|
||||||
Assert.Null(edited.ExternalId);
|
Assert.Null(edited.ExternalId);
|
||||||
Assert.Null(edited.People);
|
Assert.Null(edited.People);
|
||||||
@ -348,7 +348,7 @@ namespace Kyoo.Tests.Database
|
|||||||
Show value = new()
|
Show value = new()
|
||||||
{
|
{
|
||||||
Slug = "super-test",
|
Slug = "super-test",
|
||||||
Title = "This is a test title?"
|
Name = "This is a test title?"
|
||||||
};
|
};
|
||||||
await _repository.Create(value);
|
await _repository.Create(value);
|
||||||
ICollection<Show> ret = await _repository.Search(query);
|
ICollection<Show> ret = await _repository.Search(query);
|
||||||
|
@ -27,16 +27,6 @@ namespace Kyoo.Tests
|
|||||||
{
|
{
|
||||||
private static readonly Dictionary<Type, Func<object>> NewSamples = new()
|
private static readonly Dictionary<Type, Func<object>> NewSamples = new()
|
||||||
{
|
{
|
||||||
{
|
|
||||||
typeof(Library),
|
|
||||||
() => new Library
|
|
||||||
{
|
|
||||||
ID = 2,
|
|
||||||
Slug = "new-library",
|
|
||||||
Name = "New Library",
|
|
||||||
Paths = new[] { "/a/random/path" }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
typeof(Collection),
|
typeof(Collection),
|
||||||
() => new Collection
|
() => new Collection
|
||||||
@ -57,7 +47,7 @@ namespace Kyoo.Tests
|
|||||||
{
|
{
|
||||||
ID = 2,
|
ID = 2,
|
||||||
Slug = "new-show",
|
Slug = "new-show",
|
||||||
Title = "New Show",
|
Name = "New Show",
|
||||||
Overview = "overview",
|
Overview = "overview",
|
||||||
Status = Status.Planned,
|
Status = Status.Planned,
|
||||||
StartAir = new DateTime(2011, 1, 1).ToUniversalTime(),
|
StartAir = new DateTime(2011, 1, 1).ToUniversalTime(),
|
||||||
@ -79,7 +69,7 @@ namespace Kyoo.Tests
|
|||||||
ID = 2,
|
ID = 2,
|
||||||
ShowID = 1,
|
ShowID = 1,
|
||||||
ShowSlug = Get<Show>().Slug,
|
ShowSlug = Get<Show>().Slug,
|
||||||
Title = "New season",
|
Name = "New season",
|
||||||
Overview = "New overview",
|
Overview = "New overview",
|
||||||
EndDate = new DateTime(2000, 10, 10).ToUniversalTime(),
|
EndDate = new DateTime(2000, 10, 10).ToUniversalTime(),
|
||||||
SeasonNumber = 2,
|
SeasonNumber = 2,
|
||||||
@ -102,7 +92,7 @@ namespace Kyoo.Tests
|
|||||||
EpisodeNumber = 3,
|
EpisodeNumber = 3,
|
||||||
AbsoluteNumber = 4,
|
AbsoluteNumber = 4,
|
||||||
Path = "/episode-path",
|
Path = "/episode-path",
|
||||||
Title = "New Episode Title",
|
Name = "New Episode Title",
|
||||||
ReleaseDate = new DateTime(2000, 10, 10).ToUniversalTime(),
|
ReleaseDate = new DateTime(2000, 10, 10).ToUniversalTime(),
|
||||||
Overview = "new episode overview",
|
Overview = "new episode overview",
|
||||||
Images = new Dictionary<int, string>
|
Images = new Dictionary<int, string>
|
||||||
@ -172,7 +162,7 @@ namespace Kyoo.Tests
|
|||||||
{
|
{
|
||||||
ID = 1,
|
ID = 1,
|
||||||
Slug = "anohana",
|
Slug = "anohana",
|
||||||
Title = "Anohana: The Flower We Saw That Day",
|
Name = "Anohana: The Flower We Saw That Day",
|
||||||
Aliases = new[]
|
Aliases = new[]
|
||||||
{
|
{
|
||||||
"Ano Hi Mita Hana no Namae o Bokutachi wa Mada Shiranai.",
|
"Ano Hi Mita Hana no Namae o Bokutachi wa Mada Shiranai.",
|
||||||
@ -204,7 +194,7 @@ namespace Kyoo.Tests
|
|||||||
ShowSlug = "anohana",
|
ShowSlug = "anohana",
|
||||||
ShowID = 1,
|
ShowID = 1,
|
||||||
SeasonNumber = 1,
|
SeasonNumber = 1,
|
||||||
Title = "Season 1",
|
Name = "Season 1",
|
||||||
Overview = "The first season",
|
Overview = "The first season",
|
||||||
StartDate = new DateTime(2020, 06, 05).ToUniversalTime(),
|
StartDate = new DateTime(2020, 06, 05).ToUniversalTime(),
|
||||||
EndDate = new DateTime(2020, 07, 05).ToUniversalTime(),
|
EndDate = new DateTime(2020, 07, 05).ToUniversalTime(),
|
||||||
@ -234,7 +224,7 @@ namespace Kyoo.Tests
|
|||||||
[Images.Logo] = "Logo",
|
[Images.Logo] = "Logo",
|
||||||
[Images.Thumbnail] = "Thumbnail"
|
[Images.Thumbnail] = "Thumbnail"
|
||||||
},
|
},
|
||||||
Title = "Episode 1",
|
Name = "Episode 1",
|
||||||
Overview = "Summary of the first episode",
|
Overview = "Summary of the first episode",
|
||||||
ReleaseDate = new DateTime(2020, 06, 05).ToUniversalTime()
|
ReleaseDate = new DateTime(2020, 06, 05).ToUniversalTime()
|
||||||
}
|
}
|
||||||
@ -379,7 +369,7 @@ namespace Kyoo.Tests
|
|||||||
[Images.Logo] = "Logo",
|
[Images.Logo] = "Logo",
|
||||||
[Images.Thumbnail] = "Thumbnail"
|
[Images.Thumbnail] = "Thumbnail"
|
||||||
},
|
},
|
||||||
Title = "Episode 3",
|
Name = "Episode 3",
|
||||||
Overview = "Summary of the third absolute episode",
|
Overview = "Summary of the third absolute episode",
|
||||||
ReleaseDate = new DateTime(2020, 06, 05).ToUniversalTime()
|
ReleaseDate = new DateTime(2020, 06, 05).ToUniversalTime()
|
||||||
};
|
};
|
||||||
@ -399,7 +389,7 @@ namespace Kyoo.Tests
|
|||||||
[Images.Logo] = "Logo",
|
[Images.Logo] = "Logo",
|
||||||
[Images.Thumbnail] = "Thumbnail"
|
[Images.Thumbnail] = "Thumbnail"
|
||||||
},
|
},
|
||||||
Title = "John wick",
|
Name = "John wick",
|
||||||
Overview = "A movie episode test",
|
Overview = "A movie episode test",
|
||||||
ReleaseDate = new DateTime(1595, 05, 12).ToUniversalTime()
|
ReleaseDate = new DateTime(1595, 05, 12).ToUniversalTime()
|
||||||
};
|
};
|
||||||
|
@ -123,7 +123,7 @@ class TheMovieDatabase(Provider):
|
|||||||
ret = Movie(
|
ret = Movie(
|
||||||
original_language=movie["original_language"],
|
original_language=movie["original_language"],
|
||||||
aliases=[x["title"] for x in movie["alternative_titles"]["titles"]],
|
aliases=[x["title"] for x in movie["alternative_titles"]["titles"]],
|
||||||
release_date=datetime.strptime(movie["release_date"], "%Y-%m-%d").date()
|
air_date=datetime.strptime(movie["release_date"], "%Y-%m-%d").date()
|
||||||
if movie["release_date"]
|
if movie["release_date"]
|
||||||
else None,
|
else None,
|
||||||
status=MovieStatus.FINISHED
|
status=MovieStatus.FINISHED
|
||||||
@ -148,8 +148,8 @@ class TheMovieDatabase(Provider):
|
|||||||
)
|
)
|
||||||
translation = MovieTranslation(
|
translation = MovieTranslation(
|
||||||
name=movie["title"],
|
name=movie["title"],
|
||||||
tagline=movie["tagline"],
|
tagline=movie["tagline"] if movie["tagline"] else None,
|
||||||
keywords=list(map(lambda x: x["name"], movie["keywords"]["keywords"])),
|
tags=list(map(lambda x: x["name"], movie["keywords"]["keywords"])),
|
||||||
overview=movie["overview"],
|
overview=movie["overview"],
|
||||||
posters=self.get_image(movie["images"]["posters"]),
|
posters=self.get_image(movie["images"]["posters"]),
|
||||||
logos=self.get_image(movie["images"]["logos"]),
|
logos=self.get_image(movie["images"]["logos"]),
|
||||||
@ -224,8 +224,8 @@ class TheMovieDatabase(Provider):
|
|||||||
)
|
)
|
||||||
translation = ShowTranslation(
|
translation = ShowTranslation(
|
||||||
name=show["name"],
|
name=show["name"],
|
||||||
tagline=show["tagline"],
|
tagline=show["tagline"] if show["tagline"] else None,
|
||||||
keywords=list(map(lambda x: x["name"], show["keywords"]["results"])),
|
tags=list(map(lambda x: x["name"], show["keywords"]["results"])),
|
||||||
overview=show["overview"],
|
overview=show["overview"],
|
||||||
posters=self.get_image(show["images"]["posters"]),
|
posters=self.get_image(show["images"]["posters"]),
|
||||||
logos=self.get_image(show["images"]["logos"]),
|
logos=self.get_image(show["images"]["logos"]),
|
||||||
|
@ -40,9 +40,9 @@ class Episode:
|
|||||||
return {
|
return {
|
||||||
**asdict(self),
|
**asdict(self),
|
||||||
**asdict(self.translations[default_language]),
|
**asdict(self.translations[default_language]),
|
||||||
"title": self.translations[default_language].name,
|
# "poster": next(iter(self.translations[default_language].posters), None),
|
||||||
"images": {
|
# "thumbnail": next(iter(self.translations[default_language].thumbnails), None),
|
||||||
"1": self.thumbnail,
|
# "logo": next(iter(self.translations[default_language].logos), None),
|
||||||
},
|
"thumbnail": None,
|
||||||
"show": None,
|
"show": None,
|
||||||
}
|
}
|
||||||
|
@ -22,4 +22,4 @@ class Genre(str, Enum):
|
|||||||
WESTERN = "Western"
|
WESTERN = "Western"
|
||||||
|
|
||||||
def to_kyoo(self):
|
def to_kyoo(self):
|
||||||
return {"name": self.value}
|
return self.value
|
||||||
|
@ -20,7 +20,7 @@ class Status(str, Enum):
|
|||||||
class MovieTranslation:
|
class MovieTranslation:
|
||||||
name: str
|
name: str
|
||||||
tagline: Optional[str] = None
|
tagline: Optional[str] = None
|
||||||
keywords: list[str] = field(default_factory=list)
|
tags: list[str] = field(default_factory=list)
|
||||||
overview: Optional[str] = None
|
overview: Optional[str] = None
|
||||||
|
|
||||||
posters: list[str] = field(default_factory=list)
|
posters: list[str] = field(default_factory=list)
|
||||||
@ -33,7 +33,7 @@ class MovieTranslation:
|
|||||||
class Movie:
|
class Movie:
|
||||||
original_language: Optional[str] = None
|
original_language: Optional[str] = None
|
||||||
aliases: list[str] = field(default_factory=list)
|
aliases: list[str] = field(default_factory=list)
|
||||||
release_date: Optional[date | int] = None
|
air_date: Optional[date | int] = None
|
||||||
status: Status = Status.UNKNOWN
|
status: Status = Status.UNKNOWN
|
||||||
path: Optional[str] = None
|
path: Optional[str] = None
|
||||||
studios: list[Studio] = field(default_factory=list)
|
studios: list[Studio] = field(default_factory=list)
|
||||||
@ -50,18 +50,10 @@ class Movie:
|
|||||||
return {
|
return {
|
||||||
**asdict(self),
|
**asdict(self),
|
||||||
**asdict(self.translations[default_language]),
|
**asdict(self.translations[default_language]),
|
||||||
"images": {
|
# "poster": next(iter(self.translations[default_language].posters), None),
|
||||||
"0": next(iter(self.translations[default_language].posters), None),
|
# "thumbnail": next(iter(self.translations[default_language].thumbnails), None),
|
||||||
"1": next(iter(self.translations[default_language].thumbnails), None),
|
# "logo": next(iter(self.translations[default_language].logos), None),
|
||||||
"2": next(iter(self.translations[default_language].logos), None),
|
"trailer": next(iter(self.translations[default_language].trailers), None),
|
||||||
"3": next(iter(self.translations[default_language].trailers), None),
|
|
||||||
},
|
|
||||||
"studio": next((x.to_kyoo() for x in self.studios), None),
|
"studio": next((x.to_kyoo() for x in self.studios), None),
|
||||||
"release_date": None,
|
|
||||||
"startAir": format_date(self.release_date),
|
|
||||||
"title": self.translations[default_language].name,
|
|
||||||
"genres": [x.to_kyoo() for x in self.genres],
|
"genres": [x.to_kyoo() for x in self.genres],
|
||||||
"isMovie": True,
|
|
||||||
# TODO: The back has bad external id support, we disable it for now
|
|
||||||
"external_ids": None,
|
|
||||||
}
|
}
|
||||||
|
@ -30,11 +30,7 @@ class Season:
|
|||||||
return {
|
return {
|
||||||
**asdict(self),
|
**asdict(self),
|
||||||
**asdict(self.translations[default_language]),
|
**asdict(self.translations[default_language]),
|
||||||
"images": {
|
# "poster": next(iter(self.translations[default_language].posters), None),
|
||||||
"0": next(iter(self.translations[default_language].posters), None),
|
# "thumbnail": next(iter(self.translations[default_language].thumbnails), None),
|
||||||
"1": next(iter(self.translations[default_language].thumbnails), None),
|
# "logo": next(iter(self.translations[default_language].logos), None),
|
||||||
},
|
|
||||||
"title": self.translations[default_language].name,
|
|
||||||
# TODO: The back has bad external id support, we disable it for now
|
|
||||||
"external_ids": None,
|
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ class Status(str, Enum):
|
|||||||
class ShowTranslation:
|
class ShowTranslation:
|
||||||
name: str
|
name: str
|
||||||
tagline: Optional[str]
|
tagline: Optional[str]
|
||||||
keywords: list[str]
|
tags: list[str]
|
||||||
overview: Optional[str]
|
overview: Optional[str]
|
||||||
|
|
||||||
posters: list[str]
|
posters: list[str]
|
||||||
@ -52,16 +52,11 @@ class Show:
|
|||||||
return {
|
return {
|
||||||
**asdict(self),
|
**asdict(self),
|
||||||
**asdict(self.translations[default_language]),
|
**asdict(self.translations[default_language]),
|
||||||
"images": {
|
|
||||||
"0": next(iter(self.translations[default_language].posters), None),
|
|
||||||
"1": next(iter(self.translations[default_language].thumbnails), None),
|
|
||||||
"2": next(iter(self.translations[default_language].logos), None),
|
|
||||||
"3": next(iter(self.translations[default_language].trailers), None),
|
|
||||||
},
|
|
||||||
"studio": next((x.to_kyoo() for x in self.studios), None),
|
"studio": next((x.to_kyoo() for x in self.studios), None),
|
||||||
"title": self.translations[default_language].name,
|
|
||||||
"genres": [x.to_kyoo() for x in self.genres],
|
|
||||||
"seasons": None,
|
"seasons": None,
|
||||||
# TODO: The back has bad external id support, we disable it for now
|
# "poster": next(iter(self.translations[default_language].posters), None),
|
||||||
"external_ids": None,
|
# "thumbnail": next(iter(self.translations[default_language].thumbnails), None),
|
||||||
|
# "logo": next(iter(self.translations[default_language].logos), None),
|
||||||
|
"trailer": next(iter(self.translations[default_language].trailers), None),
|
||||||
|
"genres": [x.to_kyoo() for x in self.genres],
|
||||||
}
|
}
|
||||||
|
@ -12,9 +12,5 @@ class Studio:
|
|||||||
def to_kyoo(self):
|
def to_kyoo(self):
|
||||||
return {
|
return {
|
||||||
**asdict(self),
|
**asdict(self),
|
||||||
"images": {
|
# "logo": next(iter(self.logos), None),
|
||||||
"2": next(iter(self.logos), None),
|
|
||||||
},
|
|
||||||
# TODO: The back has bad external id support, we disable it for now
|
|
||||||
"external_ids": None,
|
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ class Scanner:
|
|||||||
await asyncio.gather(*map(self.identify, group))
|
await asyncio.gather(*map(self.identify, group))
|
||||||
|
|
||||||
async def get_registered_paths(self) -> List[str]:
|
async def get_registered_paths(self) -> List[str]:
|
||||||
# TODO: Once movies are separated from the api, a new endpoint should be created to check for paths.
|
paths = None
|
||||||
async with self._client.get(
|
async with self._client.get(
|
||||||
f"{self._url}/episodes",
|
f"{self._url}/episodes",
|
||||||
params={"limit": 0},
|
params={"limit": 0},
|
||||||
@ -56,7 +56,17 @@ class Scanner:
|
|||||||
) as r:
|
) as r:
|
||||||
r.raise_for_status()
|
r.raise_for_status()
|
||||||
ret = await r.json()
|
ret = await r.json()
|
||||||
return list(x["path"] for x in ret["items"])
|
paths = list(x["path"] for x in ret["items"])
|
||||||
|
|
||||||
|
async with self._client.get(
|
||||||
|
f"{self._url}/movies",
|
||||||
|
params={"limit": 0},
|
||||||
|
headers={"X-API-Key": self._api_key},
|
||||||
|
) as r:
|
||||||
|
r.raise_for_status()
|
||||||
|
ret = await r.json()
|
||||||
|
paths += list(x["path"] for x in ret["items"])
|
||||||
|
return paths;
|
||||||
|
|
||||||
@log_errors
|
@log_errors
|
||||||
async def identify(self, path: str):
|
async def identify(self, path: str):
|
||||||
@ -157,7 +167,13 @@ class Scanner:
|
|||||||
|
|
||||||
async def delete(self, path: str):
|
async def delete(self, path: str):
|
||||||
logging.info("Deleting %s", path)
|
logging.info("Deleting %s", path)
|
||||||
# TODO: Adapt this for movies as well when they are split
|
async with self._client.delete(
|
||||||
|
f"{self._url}/movies?path={path}", headers={"X-API-Key": self._api_key}
|
||||||
|
) as r:
|
||||||
|
if not r.ok:
|
||||||
|
logging.error(f"Request error: {await r.text()}")
|
||||||
|
r.raise_for_status()
|
||||||
|
|
||||||
async with self._client.delete(
|
async with self._client.delete(
|
||||||
f"{self._url}/episodes?path={path}", headers={"X-API-Key": self._api_key}
|
f"{self._url}/episodes?path={path}", headers={"X-API-Key": self._api_key}
|
||||||
) as r:
|
) as r:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user