diff --git a/back/Kyoo.ruleset b/back/Kyoo.ruleset
index 13d29e23..9a9c6d14 100644
--- a/back/Kyoo.ruleset
+++ b/back/Kyoo.ruleset
@@ -33,10 +33,11 @@
+
+
-
diff --git a/back/src/Directory.Build.props b/back/src/Directory.Build.props
index c0c382c2..90c33385 100644
--- a/back/src/Directory.Build.props
+++ b/back/src/Directory.Build.props
@@ -46,7 +46,7 @@
$(MSBuildThisFileDirectory)../Kyoo.ruleset
- 1591
+ 1591;1305;8618
diff --git a/back/src/Kyoo.Abstractions/Controllers/ILibraryManager.cs b/back/src/Kyoo.Abstractions/Controllers/ILibraryManager.cs
index 792e1978..fbe8d1ab 100644
--- a/back/src/Kyoo.Abstractions/Controllers/ILibraryManager.cs
+++ b/back/src/Kyoo.Abstractions/Controllers/ILibraryManager.cs
@@ -20,7 +20,6 @@ using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;
-using JetBrains.Annotations;
using Kyoo.Abstractions.Models;
using Kyoo.Abstractions.Models.Exceptions;
@@ -40,11 +39,6 @@ namespace Kyoo.Abstractions.Controllers
IRepository GetRepository()
where T : class, IResource;
- ///
- /// The repository that handle libraries.
- ///
- ILibraryRepository LibraryRepository { get; }
-
///
/// The repository that handle libraries items (a wrapper around shows and collections).
///
@@ -55,6 +49,11 @@ namespace Kyoo.Abstractions.Controllers
///
ICollectionRepository CollectionRepository { get; }
+ ///
+ /// The repository that handle shows.
+ ///
+ IMovieRepository MovieRepository { get; }
+
///
/// The repository that handle shows.
///
@@ -80,16 +79,6 @@ namespace Kyoo.Abstractions.Controllers
///
IStudioRepository StudioRepository { get; }
- ///
- /// The repository that handle genres.
- ///
- IGenreRepository GenreRepository { get; }
-
- ///
- /// The repository that handle providers.
- ///
- IProviderRepository ProviderRepository { get; }
-
///
/// The repository that handle users.
///
@@ -102,7 +91,6 @@ namespace Kyoo.Abstractions.Controllers
/// The type of the resource
/// If the item is not found
/// The resource found
- [ItemNotNull]
Task Get(int id)
where T : class, IResource;
@@ -113,7 +101,6 @@ namespace Kyoo.Abstractions.Controllers
/// The type of the resource
/// If the item is not found
/// The resource found
- [ItemNotNull]
Task Get(string slug)
where T : class, IResource;
@@ -124,7 +111,6 @@ namespace Kyoo.Abstractions.Controllers
/// The type of the resource
/// If the item is not found
/// The first resource found that match the where function
- [ItemNotNull]
Task Get(Expression> where)
where T : class, IResource;
@@ -135,7 +121,6 @@ namespace Kyoo.Abstractions.Controllers
/// The season's number
/// If the item is not found
/// The season found
- [ItemNotNull]
Task Get(int showID, int seasonNumber);
///
@@ -145,7 +130,6 @@ namespace Kyoo.Abstractions.Controllers
/// The season's number
/// If the item is not found
/// The season found
- [ItemNotNull]
Task Get(string showSlug, int seasonNumber);
///
@@ -156,7 +140,6 @@ namespace Kyoo.Abstractions.Controllers
/// The episode's number
/// If the item is not found
/// The episode found
- [ItemNotNull]
Task Get(int showID, int seasonNumber, int episodeNumber);
///
@@ -167,7 +150,6 @@ namespace Kyoo.Abstractions.Controllers
/// The episode's number
/// If the item is not found
/// The episode found
- [ItemNotNull]
Task Get(string showSlug, int seasonNumber, int episodeNumber);
///
@@ -176,8 +158,7 @@ namespace Kyoo.Abstractions.Controllers
/// The id of the resource
/// The type of the resource
/// The resource found
- [ItemCanBeNull]
- Task GetOrDefault(int id)
+ Task GetOrDefault(int id)
where T : class, IResource;
///
@@ -186,8 +167,7 @@ namespace Kyoo.Abstractions.Controllers
/// The slug of the resource
/// The type of the resource
/// The resource found
- [ItemCanBeNull]
- Task GetOrDefault(string slug)
+ Task GetOrDefault(string slug)
where T : class, IResource;
///
@@ -197,8 +177,7 @@ namespace Kyoo.Abstractions.Controllers
/// A custom sort method to handle cases where multiples items match the filters.
/// The type of the resource
/// The first resource found that match the where function
- [ItemCanBeNull]
- Task GetOrDefault(Expression> where, Sort sortBy = default)
+ Task GetOrDefault(Expression> where, Sort? sortBy = default)
where T : class, IResource;
///
@@ -207,8 +186,7 @@ namespace Kyoo.Abstractions.Controllers
/// The id of the show
/// The season's number
/// The season found
- [ItemCanBeNull]
- Task GetOrDefault(int showID, int seasonNumber);
+ Task GetOrDefault(int showID, int seasonNumber);
///
/// Get a season from it's show slug and it's seasonNumber or null if it is not found.
@@ -216,8 +194,7 @@ namespace Kyoo.Abstractions.Controllers
/// The slug of the show
/// The season's number
/// The season found
- [ItemCanBeNull]
- Task GetOrDefault(string showSlug, int seasonNumber);
+ Task GetOrDefault(string showSlug, int seasonNumber);
///
/// Get a episode from it's showID, it's seasonNumber and it's episode number or null if it is not found.
@@ -226,8 +203,7 @@ namespace Kyoo.Abstractions.Controllers
/// The season's number
/// The episode's number
/// The episode found
- [ItemCanBeNull]
- Task GetOrDefault(int showID, int seasonNumber, int episodeNumber);
+ Task GetOrDefault(int showID, int seasonNumber, int episodeNumber);
///
/// Get a episode from it's show slug, it's seasonNumber and it's episode number or null if it is not found.
@@ -236,8 +212,7 @@ namespace Kyoo.Abstractions.Controllers
/// The season's number
/// The episode's number
/// The episode found
- [ItemCanBeNull]
- Task GetOrDefault(string showSlug, int seasonNumber, int episodeNumber);
+ Task GetOrDefault(string showSlug, int seasonNumber, int episodeNumber);
///
/// Load a related resource
@@ -253,7 +228,7 @@ namespace Kyoo.Abstractions.Controllers
///
///
///
- Task Load([NotNull] T obj, Expression> member, bool force = false)
+ Task Load(T obj, Expression> member, bool force = false)
where T : class, IResource
where T2 : class, IResource;
@@ -271,7 +246,7 @@ namespace Kyoo.Abstractions.Controllers
///
///
///
- Task Load([NotNull] T obj, Expression>> member, bool force = false)
+ Task Load(T obj, Expression>> member, bool force = false)
where T : class, IResource
where T2 : class;
@@ -288,7 +263,7 @@ namespace Kyoo.Abstractions.Controllers
///
///
///
- Task Load([NotNull] T obj, string memberName, bool force = false)
+ Task Load(T obj, string memberName, bool force = false)
where T : class, IResource;
///
@@ -303,35 +278,7 @@ namespace Kyoo.Abstractions.Controllers
///
///
/// A representing the asynchronous operation.
- Task Load([NotNull] IResource obj, string memberName, bool force = false);
-
- ///
- /// Get items (A wrapper around shows or collections) from a library.
- ///
- /// The ID of the library
- /// A filter function
- /// Sort information (sort order and sort by)
- /// How many items to return and where to start
- /// No library exist with the given ID.
- /// A list of items that match every filters
- Task> GetItemsFromLibrary(int id,
- Expression> where = null,
- Sort sort = default,
- Pagination limit = default);
-
- ///
- /// Get items (A wrapper around shows or collections) from a library.
- ///
- /// The slug of the library
- /// A filter function
- /// Sort information (sort order and sort by)
- /// How many items to return and where to start
- /// No library exist with the given slug.
- /// A list of items that match every filters
- Task> GetItemsFromLibrary(string slug,
- Expression> where = null,
- Sort sort = default,
- Pagination limit = default);
+ Task Load(IResource obj, string memberName, bool force = false);
///
/// Get people's roles from a show.
@@ -343,9 +290,9 @@ namespace Kyoo.Abstractions.Controllers
/// No exist with the given ID.
/// A list of items that match every filters
Task> GetPeopleFromShow(int showID,
- Expression> where = null,
- Sort sort = default,
- Pagination limit = default);
+ Expression>? where = null,
+ Sort? sort = default,
+ Pagination? limit = default);
///
/// Get people's roles from a show.
@@ -357,9 +304,9 @@ namespace Kyoo.Abstractions.Controllers
/// No exist with the given slug.
/// A list of items that match every filters
Task> GetPeopleFromShow(string showSlug,
- Expression> where = null,
- Sort sort = default,
- Pagination limit = default);
+ Expression>? where = null,
+ Sort? sort = default,
+ Pagination? limit = default);
///
/// Get people's roles from a person.
@@ -371,9 +318,9 @@ namespace Kyoo.Abstractions.Controllers
/// No exist with the given ID.
/// A list of items that match every filters
Task> GetRolesFromPeople(int id,
- Expression> where = null,
- Sort sort = default,
- Pagination limit = default);
+ Expression>? where = null,
+ Sort? sort = default,
+ Pagination? limit = default);
///
/// Get people's roles from a person.
@@ -385,27 +332,9 @@ namespace Kyoo.Abstractions.Controllers
/// No exist with the given slug.
/// A list of items that match every filters
Task> GetRolesFromPeople(string slug,
- Expression> where = null,
- Sort sort = default,
- Pagination limit = default);
-
- ///
- /// Setup relations between a show, a library and a collection
- ///
- /// The show's ID to setup relations with
- /// The library's ID to setup relations with (optional)
- /// The collection's ID to setup relations with (optional)
- /// A representing the asynchronous operation.
- Task AddShowLink(int showID, int? libraryID, int? collectionID);
-
- ///
- /// Setup relations between a show, a library and a collection
- ///
- /// The show to setup relations with
- /// The library to setup relations with (optional)
- /// The collection to setup relations with (optional)
- /// A representing the asynchronous operation.
- Task AddShowLink([NotNull] Show show, Library library, Collection collection);
+ Expression>? where = null,
+ Sort? sort = default,
+ Pagination? limit = default);
///
/// Get all resources with filters
@@ -415,9 +344,9 @@ namespace Kyoo.Abstractions.Controllers
/// How many items to return and where to start
/// The type of resources to load
/// A list of resources that match every filters
- Task> GetAll(Expression> where = null,
- Sort sort = default,
- Pagination limit = default)
+ Task> GetAll(Expression>? where = null,
+ Sort? sort = default,
+ Pagination? limit = default)
where T : class, IResource;
///
@@ -426,7 +355,7 @@ namespace Kyoo.Abstractions.Controllers
/// A filter function
/// The type of resources to load
/// A list of resources that match every filters
- Task GetCount(Expression> where = null)
+ Task GetCount(Expression>? where = null)
where T : class, IResource;
///
@@ -444,7 +373,7 @@ namespace Kyoo.Abstractions.Controllers
/// The item to register
/// The type of resource
/// The resource registers and completed by database's information (related items and so on)
- Task Create([NotNull] T item)
+ Task Create(T item)
where T : class, IResource;
///
@@ -453,18 +382,31 @@ namespace Kyoo.Abstractions.Controllers
/// The item to register
/// The type of resource
/// The newly created item or the existing value if it existed.
- Task CreateIfNotExists([NotNull] T item)
+ Task CreateIfNotExists(T item)
where T : class, IResource;
///
/// Edit a resource
///
/// The resource to edit, it's ID can't change.
- /// Should old properties of the resource be discarded or should null values considered as not changed?
/// The type of resources
/// If the item is not found
/// The resource edited and completed by database's information (related items and so on)
- Task Edit(T item, bool resetOld)
+ Task Edit(T item)
+ where T : class, IResource;
+
+ ///
+ /// Edit only specific properties of a resource
+ ///
+ /// The id of the resource to edit
+ ///
+ /// A method that will be called when you need to update every properties that you want to
+ /// persist. It can return false to abort the process via an ArgumentException
+ ///
+ /// The type of resources
+ /// If the item is not found
+ /// The resource edited and completed by database's information (related items and so on)
+ Task Patch(int id, Func> patch)
where T : class, IResource;
///
diff --git a/back/src/Kyoo.Abstractions/Controllers/IRepository.cs b/back/src/Kyoo.Abstractions/Controllers/IRepository.cs
index a45827f0..fb00b768 100644
--- a/back/src/Kyoo.Abstractions/Controllers/IRepository.cs
+++ b/back/src/Kyoo.Abstractions/Controllers/IRepository.cs
@@ -20,7 +20,6 @@ using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;
-using JetBrains.Annotations;
using Kyoo.Abstractions.Models;
using Kyoo.Abstractions.Models.Exceptions;
@@ -45,7 +44,6 @@ namespace Kyoo.Abstractions.Controllers
/// The id of the resource
/// If the item could not be found.
/// The resource found
- [ItemNotNull]
Task Get(int id);
///
@@ -54,7 +52,6 @@ namespace Kyoo.Abstractions.Controllers
/// The slug of the resource
/// If the item could not be found.
/// The resource found
- [ItemNotNull]
Task Get(string slug);
///
@@ -63,7 +60,6 @@ namespace Kyoo.Abstractions.Controllers
/// A predicate to filter the resource.
/// If the item could not be found.
/// The resource found
- [ItemNotNull]
Task Get(Expression> where);
///
@@ -71,16 +67,14 @@ namespace Kyoo.Abstractions.Controllers
///
/// The id of the resource
/// The resource found
- [ItemCanBeNull]
- Task GetOrDefault(int id);
+ Task GetOrDefault(int id);
///
/// Get a resource from it's slug or null if it is not found.
///
/// The slug of the resource
/// The resource found
- [ItemCanBeNull]
- Task GetOrDefault(string slug);
+ Task GetOrDefault(string slug);
///
/// Get the first resource that match the predicate or null if it is not found.
@@ -88,15 +82,13 @@ namespace Kyoo.Abstractions.Controllers
/// A predicate to filter the resource.
/// A custom sort method to handle cases where multiples items match the filters.
/// The resource found
- [ItemCanBeNull]
- Task GetOrDefault(Expression> where, Sort sortBy = default);
+ Task GetOrDefault(Expression> where, Sort? sortBy = default);
///
/// Search for resources.
///
/// The query string.
/// A list of resources found
- [ItemNotNull]
Task> Search(string query);
///
@@ -106,33 +98,30 @@ namespace Kyoo.Abstractions.Controllers
/// Sort information about the query (sort by, sort order)
/// How pagination should be done (where to start and how many to return)
/// A list of resources that match every filters
- [ItemNotNull]
- Task> GetAll(Expression> where = null,
- Sort sort = default,
- Pagination limit = default);
+ Task> GetAll(Expression>? where = null,
+ Sort? sort = default,
+ Pagination? limit = default);
///
/// Get the number of resources that match the filter's predicate.
///
/// A filter predicate
/// How many resources matched that filter
- Task GetCount(Expression> where = null);
+ Task GetCount(Expression>? where = null);
///
/// Create a new resource.
///
/// The item to register
/// The resource registers and completed by database's information (related items and so on)
- [ItemNotNull]
- Task Create([NotNull] T obj);
+ Task Create(T obj);
///
/// Create a new resource if it does not exist already. If it does, the existing value is returned instead.
///
/// The object to create
/// The newly created item or the existing value if it existed.
- [ItemNotNull]
- Task CreateIfNotExists([NotNull] T obj);
+ Task CreateIfNotExists(T obj);
///
/// Called when a resource has been created.
@@ -140,14 +129,24 @@ namespace Kyoo.Abstractions.Controllers
event ResourceEventHandler OnCreated;
///
- /// Edit a resource
+ /// Edit a resource and replace every property
///
/// The resource to edit, it's ID can't change.
- /// Should old properties of the resource be discarded or should null values considered as not changed?
/// If the item is not found
/// The resource edited and completed by database's information (related items and so on)
- [ItemNotNull]
- Task Edit([NotNull] T edited, bool resetOld);
+ Task Edit(T edited);
+
+ ///
+ /// Edit only specific properties of a resource
+ ///
+ /// The id of the resource to edit
+ ///
+ /// A method that will be called when you need to update every properties that you want to
+ /// persist. It can return false to abort the process via an ArgumentException
+ ///
+ /// If the item is not found
+ /// The resource edited and completed by database's information (related items and so on)
+ Task Patch(int id, Func> patch);
///
/// Called when a resource has been edited.
@@ -176,14 +175,14 @@ namespace Kyoo.Abstractions.Controllers
/// The resource to delete
/// If the item is not found
/// A representing the asynchronous operation.
- Task Delete([NotNull] T obj);
+ Task Delete(T obj);
///
/// Delete all resources that match the predicate.
///
/// A predicate to filter resources to delete. Every resource that match this will be deleted.
/// A representing the asynchronous operation.
- Task DeleteAll([NotNull] Expression> where);
+ Task DeleteAll(Expression> where);
///
/// Called when a resource has been edited.
@@ -202,21 +201,16 @@ namespace Kyoo.Abstractions.Controllers
Type RepositoryType { get; }
}
+ ///
+ /// A repository to handle shows.
+ ///
+ public interface IMovieRepository : IRepository { }
+
///
/// A repository to handle shows.
///
public interface IShowRepository : IRepository
{
- ///
- /// 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.
- ///
- /// The ID of the show
- /// The ID of the library (optional)
- /// The ID of the collection (optional)
- /// A representing the asynchronous operation.
- Task AddShowLink(int showID, int? libraryID, int? collectionID);
-
///
/// Get a show's slug from it's ID.
///
@@ -330,55 +324,16 @@ namespace Kyoo.Abstractions.Controllers
Task GetAbsolute(string showSlug, int absoluteNumber);
}
- ///
- /// A repository to handle libraries.
- ///
- public interface ILibraryRepository : IRepository { }
-
///
/// A repository to handle library items (A wrapper around shows and collections).
///
- public interface ILibraryItemRepository : IRepository
- {
- ///
- /// Get items (A wrapper around shows or collections) from a library.
- ///
- /// The ID of the library
- /// A filter function
- /// Sort information (sort order and sort by)
- /// How many items to return and where to start
- /// No library exist with the given ID.
- /// A list of items that match every filters
- public Task> GetFromLibrary(int id,
- Expression> where = null,
- Sort sort = default,
- Pagination limit = default);
-
- ///
- /// Get items (A wrapper around shows or collections) from a library.
- ///
- /// The slug of the library
- /// A filter function
- /// Sort information (sort order and sort by)
- /// How many items to return and where to start
- /// No library exist with the given slug.
- /// A list of items that match every filters
- public Task> GetFromLibrary(string slug,
- Expression> where = null,
- Sort sort = default,
- Pagination limit = default);
- }
+ public interface ILibraryItemRepository : IRepository { }
///
/// A repository for collections
///
public interface ICollectionRepository : IRepository { }
- ///
- /// A repository for genres.
- ///
- public interface IGenreRepository : IRepository { }
-
///
/// A repository for studios.
///
@@ -399,9 +354,9 @@ namespace Kyoo.Abstractions.Controllers
/// No exist with the given ID.
/// A list of items that match every filters
Task> GetFromShow(int showID,
- Expression> where = null,
- Sort sort = default,
- Pagination limit = default);
+ Expression>? where = null,
+ Sort? sort = default,
+ Pagination? limit = default);
///
/// Get people's roles from a show.
@@ -413,9 +368,9 @@ namespace Kyoo.Abstractions.Controllers
/// No exist with the given slug.
/// A list of items that match every filters
Task> GetFromShow(string showSlug,
- Expression> where = null,
- Sort sort = default,
- Pagination limit = default);
+ Expression>? where = null,
+ Sort? sort = default,
+ Pagination? limit = default);
///
/// Get people's roles from a person.
@@ -427,9 +382,9 @@ namespace Kyoo.Abstractions.Controllers
/// No exist with the given ID.
/// A list of items that match every filters
Task> GetFromPeople(int id,
- Expression> where = null,
- Sort sort = default,
- Pagination limit = default);
+ Expression>? where = null,
+ Sort? sort = default,
+ Pagination? limit = default);
///
/// Get people's roles from a person.
@@ -441,28 +396,9 @@ namespace Kyoo.Abstractions.Controllers
/// No exist with the given slug.
/// A list of items that match every filters
Task> GetFromPeople(string slug,
- Expression> where = null,
- Sort sort = default,
- Pagination limit = default);
- }
-
- ///
- /// A repository to handle providers.
- ///
- public interface IProviderRepository : IRepository
- {
- ///
- /// Get a list of external ids that match all filters
- ///
- /// A predicate to add arbitrary filter
- /// Sort information (sort order and sort by)
- /// Pagination information (where to start and how many to get)
- /// The type of metadata to retrieve
- /// A filtered list of external ids.
- Task> GetMetadataID(Expression> where = null,
- Sort sort = default,
- Pagination limit = default)
- where T : class, IMetadata;
+ Expression>? where = null,
+ Sort? sort = default,
+ Pagination? limit = default);
}
///
diff --git a/back/src/Kyoo.Abstractions/Controllers/IThumbnailsManager.cs b/back/src/Kyoo.Abstractions/Controllers/IThumbnailsManager.cs
index 69ffe0bc..8ef426c5 100644
--- a/back/src/Kyoo.Abstractions/Controllers/IThumbnailsManager.cs
+++ b/back/src/Kyoo.Abstractions/Controllers/IThumbnailsManager.cs
@@ -35,22 +35,20 @@ namespace Kyoo.Abstractions.Controllers
///
/// The item to cache images.
///
- ///
- /// true if images should be downloaded even if they already exists locally, false otherwise.
- ///
/// The type of the item
/// true if an image has been downloaded, false otherwise.
- Task DownloadImages(T item, bool alwaysDownload = false)
+ Task DownloadImages(T item)
where T : IThumbnails;
///
/// Retrieve the local path of an image of the given item.
///
/// The item to retrieve the poster from.
- /// The ID of the image. See for values.
+ /// The ID of the image.
+ /// The quality of the image
/// The type of the item
/// The path of the image for the given resource or null if it does not exists.
- string? GetImagePath(T item, int imageId)
+ string GetImagePath(T item, string image, ImageQuality quality)
where T : IThumbnails;
}
}
diff --git a/back/src/Kyoo.Abstractions/Controllers/StartupAction.cs b/back/src/Kyoo.Abstractions/Controllers/StartupAction.cs
index 8e381387..279ec516 100644
--- a/back/src/Kyoo.Abstractions/Controllers/StartupAction.cs
+++ b/back/src/Kyoo.Abstractions/Controllers/StartupAction.cs
@@ -83,6 +83,7 @@ namespace Kyoo.Abstractions.Controllers
/// A dependency that this action will use.
/// A new
public static StartupAction New(Action action, int priority)
+ where T : notnull
=> new(action, priority);
///
@@ -94,6 +95,8 @@ namespace Kyoo.Abstractions.Controllers
/// A second dependency that this action will use.
/// A new
public static StartupAction New(Action action, int priority)
+ where T : notnull
+ where T2 : notnull
=> new(action, priority);
///
@@ -106,6 +109,9 @@ namespace Kyoo.Abstractions.Controllers
/// A third dependency that this action will use.
/// A new
public static StartupAction New(Action action, int priority)
+ where T : notnull
+ where T2 : notnull
+ where T3 : notnull
=> new(action, priority);
///
@@ -144,6 +150,7 @@ namespace Kyoo.Abstractions.Controllers
///
/// The dependency to use.
public class StartupAction : IStartupAction
+ where T : notnull
{
///
/// The action to execute at startup.
@@ -177,6 +184,8 @@ namespace Kyoo.Abstractions.Controllers
/// The dependency to use.
/// The second dependency to use.
public class StartupAction : IStartupAction
+ where T : notnull
+ where T2 : notnull
{
///
/// The action to execute at startup.
@@ -214,6 +223,9 @@ namespace Kyoo.Abstractions.Controllers
/// The second dependency to use.
/// The third dependency to use.
public class StartupAction : IStartupAction
+ where T : notnull
+ where T2 : notnull
+ where T3 : notnull
{
///
/// The action to execute at startup.
diff --git a/back/src/Kyoo.Abstractions/Kyoo.Abstractions.csproj b/back/src/Kyoo.Abstractions/Kyoo.Abstractions.csproj
index 9d8ddb0c..3433f9f1 100644
--- a/back/src/Kyoo.Abstractions/Kyoo.Abstractions.csproj
+++ b/back/src/Kyoo.Abstractions/Kyoo.Abstractions.csproj
@@ -3,6 +3,7 @@
Kyoo.Abstractions
Base package to create plugins for Kyoo.
Kyoo.Abstractions
+ enable
diff --git a/back/src/Kyoo.Abstractions/Models/Attributes/ApiDefinitionAttribute.cs b/back/src/Kyoo.Abstractions/Models/Attributes/ApiDefinitionAttribute.cs
index cd946714..785c8b55 100644
--- a/back/src/Kyoo.Abstractions/Models/Attributes/ApiDefinitionAttribute.cs
+++ b/back/src/Kyoo.Abstractions/Models/Attributes/ApiDefinitionAttribute.cs
@@ -17,7 +17,6 @@
// along with Kyoo. If not, see .
using System;
-using JetBrains.Annotations;
namespace Kyoo.Abstractions.Models.Attributes
{
@@ -32,23 +31,21 @@ namespace Kyoo.Abstractions.Models.Attributes
///
/// The public name of this api.
///
- [NotNull] public string Name { get; }
+ public string Name { get; }
///
/// The name of the group in witch this API is. You can also specify a custom sort order using the following
/// format: order:name
. Everything before the first : will be removed but kept for
/// th alphabetical ordering.
///
- public string Group { get; set; }
+ public string? Group { get; set; }
///
/// Create a new .
///
/// The name of the api that will be used on the documentation page.
- public ApiDefinitionAttribute([NotNull] string name)
+ public ApiDefinitionAttribute(string name)
{
- if (name == null)
- throw new ArgumentNullException(nameof(name));
Name = name;
}
}
diff --git a/back/src/Kyoo.Abstractions/Models/Attributes/LoadableRelationAttribute.cs b/back/src/Kyoo.Abstractions/Models/Attributes/LoadableRelationAttribute.cs
index 5bfb9e82..0a0a9672 100644
--- a/back/src/Kyoo.Abstractions/Models/Attributes/LoadableRelationAttribute.cs
+++ b/back/src/Kyoo.Abstractions/Models/Attributes/LoadableRelationAttribute.cs
@@ -30,7 +30,7 @@ namespace Kyoo.Abstractions.Models.Attributes
///
/// The name of the field containing the related resource's ID.
///
- public string RelationID { get; }
+ public string? RelationID { get; }
///
/// Create a new .
diff --git a/back/src/Kyoo.Abstractions/Models/Attributes/Permission/PartialPermissionAttribute.cs b/back/src/Kyoo.Abstractions/Models/Attributes/Permission/PartialPermissionAttribute.cs
index bac1edec..80bf585b 100644
--- a/back/src/Kyoo.Abstractions/Models/Attributes/Permission/PartialPermissionAttribute.cs
+++ b/back/src/Kyoo.Abstractions/Models/Attributes/Permission/PartialPermissionAttribute.cs
@@ -32,17 +32,17 @@ namespace Kyoo.Abstractions.Models.Permissions
///
/// The needed permission type.
///
- public string Type { get; }
+ public string? Type { get; }
///
/// The needed permission kind.
///
- public Kind Kind { get; }
+ public Kind? Kind { get; }
///
/// The group of this permission.
///
- public Group Group { get; set; }
+ public Group? Group { get; set; }
///
/// Ask a permission to run an action.
diff --git a/back/src/Kyoo.Abstractions/Models/ConfigurationReference.cs b/back/src/Kyoo.Abstractions/Models/ConfigurationReference.cs
deleted file mode 100644
index 635bbb97..00000000
--- a/back/src/Kyoo.Abstractions/Models/ConfigurationReference.cs
+++ /dev/null
@@ -1,121 +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 .
-
-using System;
-using System.Collections.Generic;
-using System.Reflection;
-using JetBrains.Annotations;
-using Kyoo.Utils;
-
-namespace Kyoo.Abstractions.Models
-{
- ///
- /// A class given information about a strongly typed configuration.
- ///
- public class ConfigurationReference
- {
- ///
- /// The path of the resource (separated by ':')
- ///
- public string Path { get; }
-
- ///
- /// The type of the resource.
- ///
- public Type Type { get; }
-
- ///
- /// Create a new using a given path and type.
- /// This method does not create sub configuration resources. Please see
- ///
- /// The path of the resource (separated by ':' or "__")
- /// The type of the resource
- ///
- public ConfigurationReference(string path, Type type)
- {
- Path = path;
- Type = type;
- }
-
- ///
- /// Return the list of configuration reference a type has.
- ///
- ///
- /// The base path of the type (separated by ':' or "__". If empty, it will start at root)
- ///
- /// The type of the object
- /// The list of configuration reference a type has.
- public static IEnumerable CreateReference(string path, [NotNull] Type type)
- {
- if (type == null)
- throw new ArgumentNullException(nameof(type));
-
- List ret = new()
- {
- new ConfigurationReference(path, type)
- };
-
- if (!type.IsClass || type.AssemblyQualifiedName?.StartsWith("System") == true)
- return ret;
-
- Type enumerable = Utility.GetGenericDefinition(type, typeof(IEnumerable<>));
- Type dictionary = Utility.GetGenericDefinition(type, typeof(IDictionary<,>));
- Type dictionaryKey = dictionary?.GetGenericArguments()[0];
-
- if (dictionary != null && dictionaryKey == typeof(string))
- ret.AddRange(CreateReference($"{path}:{type.Name}:*", dictionary.GetGenericArguments()[1]));
- else if (dictionary != null && dictionaryKey == typeof(int))
- ret.AddRange(CreateReference($"{path}:{type.Name}:", dictionary.GetGenericArguments()[1]));
- else if (enumerable != null)
- ret.AddRange(CreateReference($"{path}:{type.Name}:", enumerable.GetGenericArguments()[0]));
- else
- {
- foreach (PropertyInfo child in type.GetProperties())
- ret.AddRange(CreateReference($"{path}:{child.Name}", child.PropertyType));
- }
-
- return ret;
- }
-
- ///
- /// Return the list of configuration reference a type has.
- ///
- ///
- /// The base path of the type (separated by ':' or "__". If empty, it will start at root)
- ///
- /// The type of the object
- /// The list of configuration reference a type has.
- public static IEnumerable CreateReference(string path)
- {
- return CreateReference(path, typeof(T));
- }
-
- ///
- /// Return a meaning that the given path is of any type.
- /// It means that the type can't be edited.
- ///
- ///
- /// The path that will be untyped (separated by ':' or "__". If empty, it will start at root).
- ///
- /// A configuration reference representing a path of any type.
- public static ConfigurationReference CreateUntyped(string path)
- {
- return new ConfigurationReference(path, null);
- }
- }
-}
diff --git a/back/src/Kyoo.Abstractions/Models/Exceptions/DuplicatedItemException.cs b/back/src/Kyoo.Abstractions/Models/Exceptions/DuplicatedItemException.cs
index 0cd21975..f0aa4c1c 100644
--- a/back/src/Kyoo.Abstractions/Models/Exceptions/DuplicatedItemException.cs
+++ b/back/src/Kyoo.Abstractions/Models/Exceptions/DuplicatedItemException.cs
@@ -30,13 +30,13 @@ namespace Kyoo.Abstractions.Models.Exceptions
///
/// The existing object.
///
- public object Existing { get; }
+ public object? Existing { get; }
///
/// Create a new with the default message.
///
/// The existing object.
- public DuplicatedItemException(object existing = null)
+ public DuplicatedItemException(object? existing = null)
: base("Already exists in the database.")
{
Existing = existing;
diff --git a/back/src/Kyoo.Abstractions/Models/Resources/Interfaces/ILink.cs b/back/src/Kyoo.Abstractions/Models/Genre.cs
similarity index 75%
rename from back/src/Kyoo.Abstractions/Models/Resources/Interfaces/ILink.cs
rename to back/src/Kyoo.Abstractions/Models/Genre.cs
index 5c146786..2b7e16f0 100644
--- a/back/src/Kyoo.Abstractions/Models/Resources/Interfaces/ILink.cs
+++ b/back/src/Kyoo.Abstractions/Models/Genre.cs
@@ -19,13 +19,27 @@
namespace Kyoo.Abstractions.Models
{
///
- /// 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.
///
- public interface ILink
+ public enum Genre
{
- ///
- /// The link to return, in most cases this should be a string.
- ///
- public object Link { get; }
+ Action,
+ Adventure,
+ Animation,
+ Comedy,
+ Crime,
+ Documentary,
+ Drama,
+ Family,
+ Fantasy,
+ History,
+ Horror,
+ Music,
+ Mystery,
+ Romance,
+ ScienceFiction,
+ Thriller,
+ War,
+ Western,
}
}
diff --git a/back/src/Kyoo.Abstractions/Models/LibraryItem.cs b/back/src/Kyoo.Abstractions/Models/LibraryItem.cs
index fd9a5b85..6190bf6f 100644
--- a/back/src/Kyoo.Abstractions/Models/LibraryItem.cs
+++ b/back/src/Kyoo.Abstractions/Models/LibraryItem.cs
@@ -18,15 +18,16 @@
using System;
using System.Collections.Generic;
-using System.ComponentModel;
-using System.Linq.Expressions;
+using System.ComponentModel.DataAnnotations;
+using System.Text.Json.Serialization;
+using Kyoo.Utils;
namespace Kyoo.Abstractions.Models
{
///
/// The type of item, ether a show, a movie or a collection.
///
- public enum ItemType
+ public enum ItemKind
{
///
/// The is a .
@@ -34,8 +35,7 @@ namespace Kyoo.Abstractions.Models
Show,
///
- /// The is a Movie (a with
- /// equals to true).
+ /// The is a Movie.
///
Movie,
@@ -45,128 +45,135 @@ namespace Kyoo.Abstractions.Models
Collection
}
- ///
- /// A type union between and .
- /// This is used to list content put inside a library.
- ///
- public class LibraryItem : CustomTypeDescriptor, IResource, IThumbnails
+ public class LibraryItem : IResource, ILibraryItem, IThumbnails, IMetadata
{
///
- public int ID { get; set; }
+ public int Id { get; set; }
///
+ [MaxLength(256)]
public string Slug { get; set; }
///
- /// The title of the show or collection.
+ /// The title of this show.
///
- public string Title { get; set; }
+ public string Name { get; set; }
///
- /// The summary of the show or collection.
+ /// A catchphrase for this movie.
///
- public string Overview { get; set; }
+ public string? Tagline { get; set; }
///
- /// Is this show airing, not aired yet or finished? This is only applicable for shows.
+ /// The list of alternative titles of this show.
///
- public Status? Status { get; set; }
+ public string[] Aliases { get; set; } = Array.Empty();
///
- /// The date this show or collection started airing. It can be null if this is unknown.
+ /// The path of the movie video file.
+ ///
+ public string? Path { get; set; }
+
+ ///
+ /// The summary of this show.
+ ///
+ public string? Overview { get; set; }
+
+ ///
+ /// A list of tags that match this movie.
+ ///
+ public string[] Tags { get; set; } = Array.Empty();
+
+ ///
+ /// The list of genres (themes) this show has.
+ ///
+ public Genre[] Genres { get; set; } = Array.Empty();
+
+ ///
+ /// Is this show airing, not aired yet or finished?
+ ///
+ public Status Status { get; set; }
+
+ ///
+ /// The date this show started airing. It can be null if this is unknown.
///
public DateTime? StartAir { get; set; }
///
- /// The date this show or collection finished airing.
- /// It must be after the but can be the same (example: for movies).
+ /// The date this show finished airing.
/// It can also be null if this is unknown.
///
public DateTime? EndAir { get; set; }
+ ///
+ /// The date this movie aired.
+ ///
+ public DateTime? AirDate { get; set; }
+
///
- public Dictionary Images { get; set; }
+ public Image? Poster { get; set; }
+
+ ///
+ public Image? Thumbnail { get; set; }
+
+ ///
+ public Image? Logo { get; set; }
///
- /// The type of this item (ether a collection, a show or a movie).
+ /// A video of a few minutes that tease the content.
///
- public ItemType Type { get; set; }
+ public string? Trailer { get; set; }
+
+ ///
+ public ItemKind Kind { get; set; }
+
+ ///
+ public Dictionary ExternalId { get; set; } = new();
///
- /// Create a new, empty .
+ /// Links to watch this movie.
///
+ public VideoLinks? Links => Kind == ItemKind.Movie ? new()
+ {
+ Direct = $"/video/movie/{Slug}/direct",
+ Hls = $"/video/movie/{Slug}/master.m3u8",
+ }
+ : null;
+
public LibraryItem() { }
- ///
- /// Create a from a show.
- ///
- /// The show that this library item should represent.
- public LibraryItem(Show show)
+ [JsonConstructor]
+ public LibraryItem(string name)
{
- ID = show.ID;
- Slug = show.Slug;
- Title = show.Title;
- Overview = show.Overview;
- Status = show.Status;
- StartAir = show.StartAir;
- EndAir = show.EndAir;
- Images = show.Images;
- Type = show.IsMovie ? ItemType.Movie : ItemType.Show;
- }
-
- ///
- /// Create a from a collection
- ///
- /// The collection that this library item should represent.
- public LibraryItem(Collection collection)
- {
- ID = -collection.ID;
- Slug = collection.Slug;
- Title = collection.Name;
- Overview = collection.Overview;
- Status = Models.Status.Unknown;
- StartAir = null;
- EndAir = null;
- Images = collection.Images;
- Type = ItemType.Collection;
- }
-
- ///
- /// An expression to create a representing a show.
- ///
- public static Expression> 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,
- Images = x.Images,
- Type = x.IsMovie ? ItemType.Movie : ItemType.Show
- };
-
- ///
- /// An expression to create a representing a collection.
- ///
- public static Expression> FromCollection => x => new LibraryItem
- {
- ID = -x.ID,
- Slug = x.Slug,
- Title = x.Name,
- Overview = x.Overview,
- Status = Models.Status.Unknown,
- StartAir = null,
- EndAir = null,
- Images = x.Images,
- Type = ItemType.Collection
- };
-
- ///
- public override string GetClassName()
- {
- return Type.ToString();
+ Slug = Utility.ToSlug(name);
+ Name = name;
}
}
+
+ ///
+ /// A type union between and .
+ /// This is used to list content put inside a library.
+ ///
+ public interface ILibraryItem : IResource
+ {
+ ///
+ /// Is the item a collection, a movie or a show?
+ ///
+ public ItemKind Kind { get; }
+
+ ///
+ /// The title of this show.
+ ///
+ public string Name { get; }
+
+ ///
+ /// The summary of this show.
+ ///
+ public string? Overview { get; }
+
+ ///
+ /// The date this movie aired.
+ ///
+ public DateTime? AirDate { get; }
+ }
}
diff --git a/back/src/Kyoo.Abstractions/Models/MetadataID.cs b/back/src/Kyoo.Abstractions/Models/MetadataID.cs
index dbf00a3e..f16c59ae 100644
--- a/back/src/Kyoo.Abstractions/Models/MetadataID.cs
+++ b/back/src/Kyoo.Abstractions/Models/MetadataID.cs
@@ -16,48 +16,21 @@
// You should have received a copy of the GNU General Public License
// along with Kyoo. If not, see .
-using System;
-using System.Linq.Expressions;
-using Kyoo.Abstractions.Models.Attributes;
-
namespace Kyoo.Abstractions.Models
{
///
/// ID and link of an item on an external provider.
///
- public class MetadataID
+ public class MetadataId
{
- ///
- /// The expression to retrieve the unique ID of a MetadataID. This is an aggregate of the two resources IDs.
- ///
- public static Expression> PrimaryKey
- {
- get { return x => new { First = x.ResourceID, Second = x.ProviderID }; }
- }
-
- ///
- /// The ID of the resource which possess the metadata.
- ///
- [SerializeIgnore] public int ResourceID { get; set; }
-
- ///
- /// The ID of the provider.
- ///
- [SerializeIgnore] public int ProviderID { get; set; }
-
- ///
- /// The provider that can do something with this ID.
- ///
- public Provider Provider { get; set; }
-
///
/// The ID of the resource on the external provider.
///
- public string DataID { get; set; }
+ public string DataId { get; set; }
///
/// The URL of the resource on the external provider.
///
- public string Link { get; set; }
+ public string? Link { get; set; }
}
}
diff --git a/back/src/Kyoo.Abstractions/Models/Page.cs b/back/src/Kyoo.Abstractions/Models/Page.cs
index 6c09e54a..55fc9a5e 100644
--- a/back/src/Kyoo.Abstractions/Models/Page.cs
+++ b/back/src/Kyoo.Abstractions/Models/Page.cs
@@ -93,14 +93,14 @@ namespace Kyoo.Abstractions.Models
if (items.Count > 0 && query.ContainsKey("afterID"))
{
- query["afterID"] = items.First().ID.ToString();
+ query["afterID"] = items.First().Id.ToString();
query["reverse"] = "true";
Previous = url + query.ToQueryString();
}
query.Remove("reverse");
if (items.Count == limit && limit > 0)
{
- query["afterID"] = items.Last().ID.ToString();
+ query["afterID"] = items.Last().Id.ToString();
Next = url + query.ToQueryString();
}
diff --git a/back/tests/Kyoo.Tests/Database/SpecificTests/ProviderTests.cs b/back/src/Kyoo.Abstractions/Models/PartialResource.cs
similarity index 50%
rename from back/tests/Kyoo.Tests/Database/SpecificTests/ProviderTests.cs
rename to back/src/Kyoo.Abstractions/Models/PartialResource.cs
index 49340367..7e9b0089 100644
--- a/back/tests/Kyoo.Tests/Database/SpecificTests/ProviderTests.cs
+++ b/back/src/Kyoo.Abstractions/Models/PartialResource.cs
@@ -16,33 +16,11 @@
// You should have received a copy of the GNU General Public License
// along with Kyoo. If not, see .
-using System.Diagnostics.CodeAnalysis;
-using Kyoo.Abstractions.Controllers;
-using Kyoo.Abstractions.Models;
-using Xunit;
-using Xunit.Abstractions;
+namespace Kyoo.Models;
-namespace Kyoo.Tests.Database
+public class PartialResource
{
- namespace PostgreSQL
- {
- [Collection(nameof(Postgresql))]
- public class ProviderTests : AProviderTests
- {
- public ProviderTests(PostgresFixture postgres, ITestOutputHelper output)
- : base(new RepositoryActivator(output, postgres)) { }
- }
- }
+ public int? Id { get; set; }
- public abstract class AProviderTests : RepositoryTests
- {
- [SuppressMessage("ReSharper", "NotAccessedField.Local")]
- private readonly IProviderRepository _repository;
-
- protected AProviderTests(RepositoryActivator repositories)
- : base(repositories)
- {
- _repository = Repositories.LibraryManager.ProviderRepository;
- }
- }
+ public string? Slug { get; set; }
}
diff --git a/back/src/Kyoo.Abstractions/Models/PeopleRole.cs b/back/src/Kyoo.Abstractions/Models/PeopleRole.cs
index 3a416927..c6ac4bf0 100644
--- a/back/src/Kyoo.Abstractions/Models/PeopleRole.cs
+++ b/back/src/Kyoo.Abstractions/Models/PeopleRole.cs
@@ -29,10 +29,10 @@ namespace Kyoo.Abstractions.Models
public class PeopleRole : IResource
{
///
- public int ID { get; set; }
+ public int Id { get; set; }
///
- public string Slug => ForPeople ? Show.Slug : People.Slug;
+ public string Slug => ForPeople ? Show!.Slug : People.Slug;
///
/// Should this role be used as a Show substitute (the value is