diff --git a/.editorconfig b/.editorconfig
index 418a3f49..ad56e82e 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -7,6 +7,7 @@ trim_trailing_whitespace = true
insert_final_newline = true
indent_style = tab
indent_size = tab
+smart_tab = true
[{*.yaml,*.yml}]
indent_style = space
diff --git a/Directory.Build.props b/Directory.Build.props
index 50209a07..5b03be84 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -6,12 +6,15 @@
-
+
+
+
-
+
$(MSBuildThisFileDirectory)Kyoo.ruleset
+
diff --git a/Kyoo.Abstractions/Controllers/ILibraryManager.cs b/Kyoo.Abstractions/Controllers/ILibraryManager.cs
index 856becb7..2257af97 100644
--- a/Kyoo.Abstractions/Controllers/ILibraryManager.cs
+++ b/Kyoo.Abstractions/Controllers/ILibraryManager.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Runtime.InteropServices;
@@ -26,62 +26,62 @@ namespace Kyoo.Abstractions.Controllers
/// The repository that handle libraries.
///
ILibraryRepository LibraryRepository { get; }
-
+
///
/// The repository that handle libraries's items (a wrapper arround shows & collections).
///
ILibraryItemRepository LibraryItemRepository { get; }
-
+
///
/// The repository that handle collections.
///
ICollectionRepository CollectionRepository { get; }
-
+
///
/// The repository that handle shows.
///
IShowRepository ShowRepository { get; }
-
+
///
/// The repository that handle seasons.
///
ISeasonRepository SeasonRepository { get; }
-
+
///
/// The repository that handle episodes.
///
IEpisodeRepository EpisodeRepository { get; }
-
+
///
/// The repository that handle tracks.
///
ITrackRepository TrackRepository { get; }
-
+
///
/// The repository that handle people.
///
IPeopleRepository PeopleRepository { get; }
-
+
///
/// The repository that handle studios.
///
IStudioRepository StudioRepository { get; }
-
+
///
/// The repository that handle genres.
///
IGenreRepository GenreRepository { get; }
-
+
///
/// The repository that handle providers.
///
IProviderRepository ProviderRepository { get; }
-
+
///
/// The repository that handle users.
///
IUserRepository UserRepository { get; }
-
+
///
/// Get the resource by it's ID
///
@@ -91,7 +91,7 @@ namespace Kyoo.Abstractions.Controllers
/// The resource found
[ItemNotNull]
Task Get(int id) where T : class, IResource;
-
+
///
/// Get the resource by it's slug
///
@@ -101,7 +101,7 @@ namespace Kyoo.Abstractions.Controllers
/// The resource found
[ItemNotNull]
Task Get(string slug) where T : class, IResource;
-
+
///
/// Get the resource by a filter function.
///
@@ -121,7 +121,7 @@ namespace Kyoo.Abstractions.Controllers
/// The season found
[ItemNotNull]
Task Get(int showID, int seasonNumber);
-
+
///
/// Get a season from it's show slug and it's seasonNumber
///
@@ -131,7 +131,7 @@ namespace Kyoo.Abstractions.Controllers
/// The season found
[ItemNotNull]
Task Get(string showSlug, int seasonNumber);
-
+
///
/// Get a episode from it's showID, it's seasonNumber and it's episode number.
///
@@ -142,7 +142,7 @@ namespace Kyoo.Abstractions.Controllers
/// The episode found
[ItemNotNull]
Task Get(int showID, int seasonNumber, int episodeNumber);
-
+
///
/// Get a episode from it's show slug, it's seasonNumber and it's episode number.
///
@@ -162,7 +162,7 @@ namespace Kyoo.Abstractions.Controllers
/// The resource found
[ItemCanBeNull]
Task GetOrDefault(int id) where T : class, IResource;
-
+
///
/// Get the resource by it's slug or null if it is not found.
///
@@ -171,7 +171,7 @@ namespace Kyoo.Abstractions.Controllers
/// The resource found
[ItemCanBeNull]
Task GetOrDefault(string slug) where T : class, IResource;
-
+
///
/// Get the resource by a filter function or null if it is not found.
///
@@ -189,7 +189,7 @@ namespace Kyoo.Abstractions.Controllers
/// The season found
[ItemCanBeNull]
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.
///
@@ -198,7 +198,7 @@ namespace Kyoo.Abstractions.Controllers
/// The season found
[ItemCanBeNull]
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.
///
@@ -208,7 +208,7 @@ namespace Kyoo.Abstractions.Controllers
/// The episode found
[ItemCanBeNull]
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.
///
@@ -284,7 +284,7 @@ namespace Kyoo.Abstractions.Controllers
///
///
Task Load([NotNull] IResource obj, string memberName, bool force = false);
-
+
///
/// Get items (A wrapper arround shows or collections) from a library.
///
@@ -297,7 +297,7 @@ namespace Kyoo.Abstractions.Controllers
Expression> where = null,
Sort sort = default,
Pagination limit = default);
-
+
///
/// Get items (A wrapper arround shows or collections) from a library.
///
@@ -311,7 +311,7 @@ namespace Kyoo.Abstractions.Controllers
Expression> sort,
Pagination limit = default
) => GetItemsFromLibrary(id, where, new Sort(sort), limit);
-
+
///
/// Get items (A wrapper arround shows or collections) from a library.
///
@@ -324,7 +324,7 @@ namespace Kyoo.Abstractions.Controllers
Expression> where = null,
Sort sort = default,
Pagination limit = default);
-
+
///
/// Get items (A wrapper arround shows or collections) from a library.
///
@@ -338,8 +338,8 @@ namespace Kyoo.Abstractions.Controllers
Expression> sort,
Pagination limit = default
) => GetItemsFromLibrary(slug, where, new Sort(sort), limit);
-
-
+
+
///
/// Get people's roles from a show.
///
@@ -349,10 +349,10 @@ namespace Kyoo.Abstractions.Controllers
/// How many items to return and where to start
/// A list of items that match every filters
Task> GetPeopleFromShow(int showID,
- Expression> where = null,
+ Expression> where = null,
Sort sort = default,
Pagination limit = default);
-
+
///
/// Get people's roles from a show.
///
@@ -366,7 +366,7 @@ namespace Kyoo.Abstractions.Controllers
Expression> sort,
Pagination limit = default
) => GetPeopleFromShow(showID, where, new Sort(sort), limit);
-
+
///
/// Get people's roles from a show.
///
@@ -376,10 +376,10 @@ namespace Kyoo.Abstractions.Controllers
/// How many items to return and where to start
/// A list of items that match every filters
Task> GetPeopleFromShow(string showSlug,
- Expression> where = null,
+ Expression> where = null,
Sort sort = default,
Pagination limit = default);
-
+
///
/// Get people's roles from a show.
///
@@ -393,8 +393,8 @@ namespace Kyoo.Abstractions.Controllers
Expression> sort,
Pagination limit = default
) => GetPeopleFromShow(showSlug, where, new Sort(sort), limit);
-
-
+
+
///
/// Get people's roles from a person.
///
@@ -404,10 +404,10 @@ namespace Kyoo.Abstractions.Controllers
/// How many items to return and where to start
/// A list of items that match every filters
Task> GetRolesFromPeople(int id,
- Expression> where = null,
+ Expression> where = null,
Sort sort = default,
Pagination limit = default);
-
+
///
/// Get people's roles from a person.
///
@@ -421,7 +421,7 @@ namespace Kyoo.Abstractions.Controllers
Expression> sort,
Pagination limit = default
) => GetRolesFromPeople(id, where, new Sort(sort), limit);
-
+
///
/// Get people's roles from a person.
///
@@ -431,10 +431,10 @@ namespace Kyoo.Abstractions.Controllers
/// How many items to return and where to start
/// A list of items that match every filters
Task> GetRolesFromPeople(string slug,
- Expression> where = null,
+ Expression> where = null,
Sort sort = default,
Pagination limit = default);
-
+
///
/// Get people's roles from a person.
///
@@ -449,7 +449,7 @@ namespace Kyoo.Abstractions.Controllers
Pagination limit = default
) => GetRolesFromPeople(slug, where, new Sort(sort), limit);
-
+
///
/// Setup relations between a show, a library and a collection
///
@@ -457,7 +457,7 @@ namespace Kyoo.Abstractions.Controllers
/// The library's ID to setup relations with (optional)
/// The collection's ID to setup relations with (optional)
Task AddShowLink(int showID, int? libraryID, int? collectionID);
-
+
///
/// Setup relations between a show, a library and a collection
///
@@ -477,7 +477,7 @@ namespace Kyoo.Abstractions.Controllers
Task> GetAll(Expression> where = null,
Sort sort = default,
Pagination limit = default) where T : class, IResource;
-
+
///
/// Get all resources with filters
///
@@ -516,7 +516,7 @@ namespace Kyoo.Abstractions.Controllers
/// The type of resource
/// The resource registers and completed by database's informations (related items & so on)
Task Create([NotNull] T item) where T : class, IResource;
-
+
///
/// Create a new resource if it does not exist already. If it does, the existing value is returned instead.
///
@@ -524,7 +524,7 @@ namespace Kyoo.Abstractions.Controllers
/// The type of resource
/// The newly created item or the existing value if it existed.
Task CreateIfNotExists([NotNull] T item) where T : class, IResource;
-
+
///
/// Edit a resource
///
@@ -542,7 +542,7 @@ namespace Kyoo.Abstractions.Controllers
/// The type of resource to delete
/// If the item is not found
Task Delete(T item) where T : class, IResource;
-
+
///
/// Delete a resource by it's ID.
///
@@ -550,7 +550,7 @@ namespace Kyoo.Abstractions.Controllers
/// The type of resource to delete
/// If the item is not found
Task Delete(int id) where T : class, IResource;
-
+
///
/// Delete a resource by it's slug.
///
diff --git a/Kyoo.Abstractions/Controllers/IPlugin.cs b/Kyoo.Abstractions/Controllers/IPlugin.cs
index 6fc2cc3c..507fbb39 100644
--- a/Kyoo.Abstractions/Controllers/IPlugin.cs
+++ b/Kyoo.Abstractions/Controllers/IPlugin.cs
@@ -20,17 +20,17 @@ namespace Kyoo.Abstractions.Controllers
/// A slug to identify this plugin in queries.
///
string Slug { get; }
-
+
///
/// The name of the plugin
///
string Name { get; }
-
+
///
/// The description of this plugin. This will be displayed on the "installed plugins" page.
///
string Description { get; }
-
+
///
/// true if the plugin should be enabled, false otherwise.
/// If a plugin is not enabled, no configure method will be called.
@@ -41,7 +41,7 @@ namespace Kyoo.Abstractions.Controllers
/// By default, a plugin is always enabled. This method can be overriden to change this behavior.
///
virtual bool Enabled => true;
-
+
///
/// A list of types that will be available via the IOptions interfaces and will be listed inside
/// an IConfiguration.
@@ -64,7 +64,7 @@ namespace Kyoo.Abstractions.Controllers
///
virtual IEnumerable ConfigureSteps => ArraySegment.Empty;
- ///
+ ///
/// A configure method that will be run on plugin's startup.
///
/// The autofac service container to register services.
@@ -72,7 +72,7 @@ namespace Kyoo.Abstractions.Controllers
{
// Skipped
}
-
+
///
/// A configure method that will be run on plugin's startup.
/// This is available for libraries that build upon a , for more precise
@@ -94,4 +94,4 @@ namespace Kyoo.Abstractions.Controllers
// Skipped
}
}
-}
\ No newline at end of file
+}
diff --git a/Kyoo.Abstractions/Controllers/IPluginManager.cs b/Kyoo.Abstractions/Controllers/IPluginManager.cs
index 795339a4..c9530e02 100644
--- a/Kyoo.Abstractions/Controllers/IPluginManager.cs
+++ b/Kyoo.Abstractions/Controllers/IPluginManager.cs
@@ -17,14 +17,14 @@ namespace Kyoo.Abstractions.Controllers
/// If no plugins match the query
/// A plugin that match the queries
public T GetPlugin(string name);
-
+
///
/// Get all plugins of the given type.
///
/// The type of plugins to get
/// A list of plugins matching the given type or an empty list of none match.
public ICollection GetPlugins();
-
+
///
/// Get all plugins currently running on Kyoo. This also includes deleted plugins if the app as not been restarted.
///
@@ -39,7 +39,7 @@ namespace Kyoo.Abstractions.Controllers
/// You should not try to put plugins from the plugins directory here as they will get automatically loaded.
///
public void LoadPlugins(ICollection plugins);
-
+
///
/// Load plugins and their dependencies from the plugin directory.
///
@@ -49,4 +49,4 @@ namespace Kyoo.Abstractions.Controllers
///
public void LoadPlugins(params Type[] plugins);
}
-}
\ No newline at end of file
+}
diff --git a/Kyoo.Abstractions/Controllers/IRepository.cs b/Kyoo.Abstractions/Controllers/IRepository.cs
index 45c866ba..5cc6c9a3 100644
--- a/Kyoo.Abstractions/Controllers/IRepository.cs
+++ b/Kyoo.Abstractions/Controllers/IRepository.cs
@@ -34,7 +34,7 @@ namespace Kyoo.Abstractions.Controllers
Count = count;
AfterID = afterID;
}
-
+
///
/// Implicitly create a new pagination from a limit number.
///
@@ -57,7 +57,7 @@ namespace Kyoo.Abstractions.Controllers
/// If this is set to true, items will be sorted in descend order else, they will be sorted in ascendant order.
///
public bool Descendant { get; }
-
+
///
/// Create a new instance.
///
@@ -68,7 +68,7 @@ namespace Kyoo.Abstractions.Controllers
{
Key = key;
Descendant = descendant;
-
+
if (!Utility.IsPropertyExpression(Key))
throw new ArgumentException("The given sort key is not valid.");
}
@@ -86,7 +86,7 @@ namespace Kyoo.Abstractions.Controllers
Descendant = false;
return;
}
-
+
string key = sortBy.Contains(':') ? sortBy[..sortBy.IndexOf(':')] : sortBy;
string order = sortBy.Contains(':') ? sortBy[(sortBy.IndexOf(':') + 1)..] : null;
@@ -116,7 +116,7 @@ namespace Kyoo.Abstractions.Controllers
///
Type RepositoryType { get; }
}
-
+
///
/// A common repository for every resources.
///
@@ -147,7 +147,7 @@ namespace Kyoo.Abstractions.Controllers
/// The resource found
[ItemNotNull]
Task Get(Expression> where);
-
+
///
/// Get a resource from it's ID or null if it is not found.
///
@@ -169,7 +169,7 @@ namespace Kyoo.Abstractions.Controllers
/// The resource found
[ItemCanBeNull]
Task GetOrDefault(Expression> where);
-
+
///
/// Search for resources.
///
@@ -177,7 +177,7 @@ namespace Kyoo.Abstractions.Controllers
/// A list of resources found
[ItemNotNull]
Task> Search(string query);
-
+
///
/// Get every resources that match all filters
///
@@ -186,7 +186,7 @@ namespace Kyoo.Abstractions.Controllers
/// 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,
+ Task> GetAll(Expression> where = null,
Sort sort = default,
Pagination limit = default);
///
@@ -208,8 +208,8 @@ namespace Kyoo.Abstractions.Controllers
/// A filter predicate
/// How many resources matched that filter
Task GetCount(Expression> where = null);
-
-
+
+
///
/// Create a new resource.
///
@@ -217,7 +217,7 @@ namespace Kyoo.Abstractions.Controllers
/// The resource registers and completed by database's information (related items & so on)
[ItemNotNull]
Task Create([NotNull] T obj);
-
+
///
/// Create a new resource if it does not exist already. If it does, the existing value is returned instead.
///
@@ -225,7 +225,7 @@ namespace Kyoo.Abstractions.Controllers
/// The newly created item or the existing value if it existed.
[ItemNotNull]
Task CreateIfNotExists([NotNull] T obj);
-
+
///
/// Edit a resource
///
@@ -235,7 +235,7 @@ namespace Kyoo.Abstractions.Controllers
/// The resource edited and completed by database's information (related items & so on)
[ItemNotNull]
Task Edit([NotNull] T edited, bool resetOld);
-
+
///
/// Delete a resource by it's ID
///
@@ -254,7 +254,7 @@ namespace Kyoo.Abstractions.Controllers
/// The resource to delete
/// If the item is not found
Task Delete([NotNull] T obj);
-
+
///
/// Delete all resources that match the predicate.
///
@@ -299,7 +299,7 @@ namespace Kyoo.Abstractions.Controllers
/// If the item is not found
/// The season found
Task Get(int showID, int seasonNumber);
-
+
///
/// Get a season from it's show slug and it's seasonNumber
///
@@ -308,7 +308,7 @@ namespace Kyoo.Abstractions.Controllers
/// If the item is not found
/// The season found
Task Get(string showSlug, int seasonNumber);
-
+
///
/// Get a season from it's showID and it's seasonNumber or null if it is not found.
///
@@ -316,7 +316,7 @@ namespace Kyoo.Abstractions.Controllers
/// The season's number
/// The season found
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.
///
@@ -325,7 +325,7 @@ namespace Kyoo.Abstractions.Controllers
/// The season found
Task GetOrDefault(string showSlug, int seasonNumber);
}
-
+
///
/// The repository to handle episodes
///
@@ -366,7 +366,7 @@ namespace Kyoo.Abstractions.Controllers
/// The episode's number
/// The episode found
Task GetOrDefault(string showSlug, int seasonNumber, int episodeNumber);
-
+
///
/// Get a episode from it's showID and it's absolute number.
///
@@ -389,7 +389,7 @@ namespace Kyoo.Abstractions.Controllers
/// A repository to handle tracks
///
public interface ITrackRepository : IRepository { }
-
+
///
/// A repository to handle libraries.
///
@@ -425,7 +425,7 @@ namespace Kyoo.Abstractions.Controllers
Expression> sort,
Pagination limit = default
) => GetFromLibrary(id, where, new Sort(sort), limit);
-
+
///
/// Get items (A wrapper around shows or collections) from a library.
///
@@ -451,18 +451,18 @@ namespace Kyoo.Abstractions.Controllers
Expression> sort,
Pagination limit = default
) => GetFromLibrary(slug, where, new Sort(sort), limit);
- }
-
+ }
+
///
/// A repository for collections
///
public interface ICollectionRepository : IRepository { }
-
+
///
/// A repository for genres.
///
public interface IGenreRepository : IRepository { }
-
+
///
/// A repository for studios.
///
@@ -482,7 +482,7 @@ namespace Kyoo.Abstractions.Controllers
/// How many items to return and where to start
/// A list of items that match every filters
Task> GetFromShow(int showID,
- Expression> where = null,
+ Expression> where = null,
Sort sort = default,
Pagination limit = default);
///
@@ -498,7 +498,7 @@ namespace Kyoo.Abstractions.Controllers
Expression> sort,
Pagination limit = default
) => GetFromShow(showID, where, new Sort(sort), limit);
-
+
///
/// Get people's roles from a show.
///
@@ -508,7 +508,7 @@ namespace Kyoo.Abstractions.Controllers
/// How many items to return and where to start
/// A list of items that match every filters
Task> GetFromShow(string showSlug,
- Expression> where = null,
+ Expression> where = null,
Sort sort = default,
Pagination limit = default);
///
@@ -524,7 +524,7 @@ namespace Kyoo.Abstractions.Controllers
Expression> sort,
Pagination limit = default
) => GetFromShow(showSlug, where, new Sort(sort), limit);
-
+
///
/// Get people's roles from a person.
///
@@ -534,7 +534,7 @@ namespace Kyoo.Abstractions.Controllers
/// How many items to return and where to start
/// A list of items that match every filters
Task> GetFromPeople(int id,
- Expression> where = null,
+ Expression> where = null,
Sort sort = default,
Pagination limit = default);
///
@@ -550,7 +550,7 @@ namespace Kyoo.Abstractions.Controllers
Expression> sort,
Pagination limit = default
) => GetFromPeople(id, where, new Sort(sort), limit);
-
+
///
/// Get people's roles from a person.
///
@@ -560,7 +560,7 @@ namespace Kyoo.Abstractions.Controllers
/// How many items to return and where to start
/// A list of items that match every filters
Task> GetFromPeople(string slug,
- Expression> where = null,
+ Expression> where = null,
Sort sort = default,
Pagination limit = default);
///
@@ -591,7 +591,7 @@ namespace Kyoo.Abstractions.Controllers
/// 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,
+ Task> GetMetadataID(Expression> where = null,
Sort sort = default,
Pagination limit = default)
where T : class, IMetadata;
@@ -609,9 +609,9 @@ namespace Kyoo.Abstractions.Controllers
) where T : class, IMetadata
=> GetMetadataID(where, new Sort(sort), limit);
}
-
+
///
/// A repository to handle users.
///
- public interface IUserRepository : IRepository {}
+ public interface IUserRepository : IRepository { }
}
diff --git a/Kyoo.Abstractions/Controllers/ITask.cs b/Kyoo.Abstractions/Controllers/ITask.cs
index 79c8c778..69856e21 100644
--- a/Kyoo.Abstractions/Controllers/ITask.cs
+++ b/Kyoo.Abstractions/Controllers/ITask.cs
@@ -19,22 +19,22 @@ namespace Kyoo.Abstractions.Controllers
/// The name of this parameter.
///
public string Name { get; init; }
-
+
///
/// The description of this parameter.
///
public string Description { get; init; }
-
+
///
/// The type of this parameter.
///
public Type Type { get; init; }
-
+
///
/// Is this parameter required or can it be ignored?
///
public bool IsRequired { get; init; }
-
+
///
/// The default value of this object.
///
@@ -44,7 +44,7 @@ namespace Kyoo.Abstractions.Controllers
/// The value of the parameter.
///
private object Value { get; init; }
-
+
///
/// Create a new task parameter.
///
@@ -61,7 +61,7 @@ namespace Kyoo.Abstractions.Controllers
Type = typeof(T)
};
}
-
+
///
/// Create a new required task parameter.
///
@@ -79,7 +79,7 @@ namespace Kyoo.Abstractions.Controllers
IsRequired = true
};
}
-
+
///
/// Create a parameter's value to give to a task.
///
@@ -104,9 +104,9 @@ namespace Kyoo.Abstractions.Controllers
/// A new parameter's value for this current parameter
public TaskParameter CreateValue(object value)
{
- return this with {Value = value};
+ return this with { Value = value };
}
-
+
///
/// Get the value of this parameter. If the value is of the wrong type, it will be converted.
///
@@ -140,12 +140,12 @@ namespace Kyoo.Abstractions.Controllers
/// The name of the task (case sensitive)
public TaskParameter this[string name] => this.FirstOrDefault(x => x.Name == name);
-
+
///
/// Create a new, empty,
///
- public TaskParameters() {}
-
+ public TaskParameters() { }
+
///
/// Create a with an initial parameters content
///
@@ -155,7 +155,7 @@ namespace Kyoo.Abstractions.Controllers
AddRange(parameters);
}
}
-
+
///
/// A common interface that tasks should implement.
///
@@ -168,7 +168,7 @@ namespace Kyoo.Abstractions.Controllers
/// All parameters that this task as. Every one of them will be given to the run function with a value.
///
public TaskParameters GetParameters();
-
+
///
/// Start this task.
///
@@ -191,4 +191,4 @@ namespace Kyoo.Abstractions.Controllers
[NotNull] IProgress progress,
CancellationToken cancellationToken);
}
-}
\ No newline at end of file
+}
diff --git a/Kyoo.Abstractions/Controllers/ITaskManager.cs b/Kyoo.Abstractions/Controllers/ITaskManager.cs
index 2a999aad..01eaeb19 100644
--- a/Kyoo.Abstractions/Controllers/ITaskManager.cs
+++ b/Kyoo.Abstractions/Controllers/ITaskManager.cs
@@ -35,7 +35,7 @@ namespace Kyoo.Abstractions.Controllers
///
/// The task could not be found.
///
- void StartTask(string taskSlug,
+ void StartTask(string taskSlug,
[NotNull] IProgress progress,
Dictionary arguments = null,
CancellationToken? cancellationToken = null);
@@ -66,13 +66,13 @@ namespace Kyoo.Abstractions.Controllers
Dictionary arguments = null,
CancellationToken? cancellationToken = null)
where T : ITask;
-
+
///
/// Get all currently running tasks
///
/// A list of currently running tasks.
ICollection<(TaskMetadataAttribute, ITask)> GetRunningTasks();
-
+
///
/// Get all available tasks
///
diff --git a/Kyoo.Abstractions/Controllers/IThumbnailsManager.cs b/Kyoo.Abstractions/Controllers/IThumbnailsManager.cs
index 54e5be0a..51fd8a85 100644
--- a/Kyoo.Abstractions/Controllers/IThumbnailsManager.cs
+++ b/Kyoo.Abstractions/Controllers/IThumbnailsManager.cs
@@ -1,6 +1,6 @@
-using Kyoo.Abstractions.Models;
using System.Threading.Tasks;
using JetBrains.Annotations;
+using Kyoo.Abstractions.Models;
namespace Kyoo.Abstractions.Controllers
{
diff --git a/Kyoo.Abstractions/Controllers/StartupAction.cs b/Kyoo.Abstractions/Controllers/StartupAction.cs
index fb2b29a5..b5b9274e 100644
--- a/Kyoo.Abstractions/Controllers/StartupAction.cs
+++ b/Kyoo.Abstractions/Controllers/StartupAction.cs
@@ -23,9 +23,9 @@ namespace Kyoo.Abstractions.Controllers
/// The action to run
/// The priority of the new action
/// A new
- public static StartupAction New(Action action, int priority)
+ public static StartupAction New(Action action, int priority)
=> new(action, priority);
-
+
///
/// Create a new .
///
@@ -33,9 +33,9 @@ namespace Kyoo.Abstractions.Controllers
/// The priority of the new action
/// A dependency that this action will use.
/// A new
- public static StartupAction New(Action action, int priority)
+ public static StartupAction New(Action action, int priority)
=> new(action, priority);
-
+
///
/// Create a new .
///
@@ -44,9 +44,9 @@ namespace Kyoo.Abstractions.Controllers
/// A dependency that this action will use.
/// A second dependency that this action will use.
/// A new
- public static StartupAction New(Action action, int priority)
+ public static StartupAction New(Action action, int priority)
=> new(action, priority);
-
+
///
/// Create a new .
///
@@ -56,11 +56,11 @@ namespace Kyoo.Abstractions.Controllers
/// A second dependency that this action will use.
/// A third dependency that this action will use.
/// A new
- public static StartupAction New(Action action, int priority)
+ public static StartupAction New(Action action, int priority)
=> new(action, priority);
}
-
-
+
+
///
/// An action executed on kyoo's startup to initialize the asp-net container.
///
@@ -81,7 +81,7 @@ namespace Kyoo.Abstractions.Controllers
/// The service provider containing all services can be used.
void Run(IServiceProvider provider);
}
-
+
///
/// A with no dependencies.
///
@@ -94,7 +94,7 @@ namespace Kyoo.Abstractions.Controllers
///
public int Priority { get; }
-
+
///
/// Create a new .
///
@@ -126,7 +126,7 @@ namespace Kyoo.Abstractions.Controllers
///
public int Priority { get; }
-
+
///
/// Create a new .
///
@@ -144,7 +144,7 @@ namespace Kyoo.Abstractions.Controllers
_action.Invoke(provider.GetRequiredService());
}
}
-
+
///
/// A with two dependencies.
///
@@ -180,7 +180,7 @@ namespace Kyoo.Abstractions.Controllers
);
}
}
-
+
///
/// A with three dependencies.
///
@@ -196,7 +196,7 @@ namespace Kyoo.Abstractions.Controllers
///
public int Priority { get; }
-
+
///
/// Create a new .
///
diff --git a/Kyoo.Abstractions/Models/Attributes/FileSystemMetadataAttribute.cs b/Kyoo.Abstractions/Models/Attributes/FileSystemMetadataAttribute.cs
index afab7bc1..574b98d6 100644
--- a/Kyoo.Abstractions/Models/Attributes/FileSystemMetadataAttribute.cs
+++ b/Kyoo.Abstractions/Models/Attributes/FileSystemMetadataAttribute.cs
@@ -20,13 +20,13 @@ namespace Kyoo.Abstractions.Models.Attributes
/// If multiples files with the same schemes exists, an exception will be thrown.
///
public string[] Scheme { get; }
-
+
///
/// true if the scheme should be removed from the path before calling
/// methods of this , false otherwise.
///
public bool StripScheme { get; set; }
-
+
///
/// Create a new using the specified schemes.
@@ -36,7 +36,7 @@ namespace Kyoo.Abstractions.Models.Attributes
{
Scheme = schemes;
}
-
+
///
/// Create a new using a dictionary of metadata.
///
diff --git a/Kyoo.Abstractions/Models/Attributes/PermissionAttribute.cs b/Kyoo.Abstractions/Models/Attributes/PermissionAttribute.cs
index b343547a..19bd1961 100644
--- a/Kyoo.Abstractions/Models/Attributes/PermissionAttribute.cs
+++ b/Kyoo.Abstractions/Models/Attributes/PermissionAttribute.cs
@@ -23,7 +23,7 @@ namespace Kyoo.Abstractions.Models.Permissions
Overall,
Admin
}
-
+
///
/// Specify permissions needed for the API.
///
@@ -63,7 +63,7 @@ namespace Kyoo.Abstractions.Models.Permissions
Kind = permission;
Group = group;
}
-
+
///
public IFilterMetadata CreateInstance(IServiceProvider serviceProvider)
{
@@ -97,7 +97,7 @@ namespace Kyoo.Abstractions.Models.Permissions
/// The needed permission kind.
///
public Kind Kind { get; }
-
+
///
/// Ask a permission to run an action.
///
@@ -118,7 +118,7 @@ namespace Kyoo.Abstractions.Models.Permissions
type = type[..^3];
Type = type.ToLower();
}
-
+
///
/// Ask a permission to run an action.
///
@@ -134,7 +134,7 @@ namespace Kyoo.Abstractions.Models.Permissions
{
Kind = permission;
}
-
+
///
public IFilterMetadata CreateInstance(IServiceProvider serviceProvider)
{
@@ -158,7 +158,7 @@ namespace Kyoo.Abstractions.Models.Permissions
/// The permission attribute to validate
/// An authorization filter used to validate the permission
IFilterMetadata Create(PermissionAttribute attribute);
-
+
///
/// Create an IAuthorizationFilter that will be used to validate permissions.
/// This can registered with any lifetime.
diff --git a/Kyoo.Abstractions/Models/Attributes/RelationAttributes.cs b/Kyoo.Abstractions/Models/Attributes/RelationAttributes.cs
index 943bd1fe..31b5fa87 100644
--- a/Kyoo.Abstractions/Models/Attributes/RelationAttributes.cs
+++ b/Kyoo.Abstractions/Models/Attributes/RelationAttributes.cs
@@ -19,11 +19,11 @@ namespace Kyoo.Abstractions.Models.Attributes
/// The name of the field containing the related resource's ID.
///
public string RelationID { get; }
-
+
///
/// Create a new .
///
- public LoadableRelationAttribute() {}
+ public LoadableRelationAttribute() { }
///
/// Create a new with a baking relationID field.
diff --git a/Kyoo.Abstractions/Models/Attributes/SerializeAttribute.cs b/Kyoo.Abstractions/Models/Attributes/SerializeAttribute.cs
index d2f2eb68..ae3f3f16 100644
--- a/Kyoo.Abstractions/Models/Attributes/SerializeAttribute.cs
+++ b/Kyoo.Abstractions/Models/Attributes/SerializeAttribute.cs
@@ -6,13 +6,13 @@ namespace Kyoo.Abstractions.Models.Attributes
/// Remove an property from the serialization pipeline. It will simply be skipped.
///
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
- public class SerializeIgnoreAttribute : Attribute {}
-
+ public class SerializeIgnoreAttribute : Attribute { }
+
///
/// Remove a property from the deserialization pipeline. The user can't input value for this property.
///
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
- public class DeserializeIgnoreAttribute : Attribute {}
+ public class DeserializeIgnoreAttribute : Attribute { }
///
/// Change the way the field is serialized. It allow one to use a string format like formatting instead of the default value.
@@ -25,7 +25,7 @@ namespace Kyoo.Abstractions.Models.Attributes
/// The format string to use.
///
public string Format { get; }
-
+
///
/// Create a new with the selected format.
///
diff --git a/Kyoo.Abstractions/Models/Attributes/TaskMetadataAttribute.cs b/Kyoo.Abstractions/Models/Attributes/TaskMetadataAttribute.cs
index 18cf7802..697303b7 100644
--- a/Kyoo.Abstractions/Models/Attributes/TaskMetadataAttribute.cs
+++ b/Kyoo.Abstractions/Models/Attributes/TaskMetadataAttribute.cs
@@ -16,12 +16,12 @@ namespace Kyoo.Abstractions.Models.Attributes
/// The slug of the task, used to start it.
///
public string Slug { get; }
-
+
///
/// The name of the task that will be displayed to the user.
///
public string Name { get; }
-
+
///
/// A quick description of what this task will do.
///
@@ -31,18 +31,18 @@ namespace Kyoo.Abstractions.Models.Attributes
/// Should this task be automatically run at app startup?
///
public bool RunOnStartup { get; set; }
-
+
///
/// The priority of this task. Only used if is true.
/// It allow one to specify witch task will be started first as tasked are run on a Priority's descending order.
///
public int Priority { get; set; }
-
+
///
/// true if this task should not be displayed to the user, false otherwise.
///
public bool IsHidden { get; set; }
-
+
///
/// Create a new with the given slug, name and description.
@@ -56,7 +56,7 @@ namespace Kyoo.Abstractions.Models.Attributes
Name = name;
Description = description;
}
-
+
///
/// Create a new using a dictionary of metadata.
///
diff --git a/Kyoo.Abstractions/Models/Chapter.cs b/Kyoo.Abstractions/Models/Chapter.cs
index 4605e7b4..35b75ec8 100644
--- a/Kyoo.Abstractions/Models/Chapter.cs
+++ b/Kyoo.Abstractions/Models/Chapter.cs
@@ -9,16 +9,16 @@ namespace Kyoo.Abstractions.Models
/// The start time of the chapter (in second from the start of the episode).
///
public float StartTime { get; set; }
-
+
///
- /// The end time of the chapter (in second from the start of the episode)&.
+ /// The end time of the chapter (in second from the start of the episode).
///
public float EndTime { get; set; }
-
+
///
/// The name of this chapter. This should be a human-readable name that could be presented to the user.
/// There should be well-known chapters name for commonly used chapters.
- /// For example, use "Opening" for the introduction-song and "Credits" for the end chapter with credits.
+ /// For example, use "Opening" for the introduction-song and "Credits" for the end chapter with credits.
///
public string Name { get; set; }
@@ -35,4 +35,4 @@ namespace Kyoo.Abstractions.Models
Name = name;
}
}
-}
\ No newline at end of file
+}
diff --git a/Kyoo.Abstractions/Models/ConfigurationReference.cs b/Kyoo.Abstractions/Models/ConfigurationReference.cs
index 676367e3..b0fde22c 100644
--- a/Kyoo.Abstractions/Models/ConfigurationReference.cs
+++ b/Kyoo.Abstractions/Models/ConfigurationReference.cs
@@ -21,7 +21,7 @@ namespace Kyoo.Abstractions.Models
///
public Type Type { get; }
-
+
///
/// Create a new using a given path and type.
/// This method does not create sub configuration resources. Please see
@@ -75,7 +75,7 @@ namespace Kyoo.Abstractions.Models
return ret;
}
-
+
///
/// Return the list of configuration reference a type has.
///
diff --git a/Kyoo.Abstractions/Models/Exceptions/DuplicatedItemException.cs b/Kyoo.Abstractions/Models/Exceptions/DuplicatedItemException.cs
index 248ea2ba..539fbe27 100644
--- a/Kyoo.Abstractions/Models/Exceptions/DuplicatedItemException.cs
+++ b/Kyoo.Abstractions/Models/Exceptions/DuplicatedItemException.cs
@@ -15,7 +15,7 @@ namespace Kyoo.Abstractions.Models.Exceptions
public DuplicatedItemException()
: base("Already exists in the database.")
{ }
-
+
///
/// Create a new with a custom message.
///
@@ -23,7 +23,7 @@ namespace Kyoo.Abstractions.Models.Exceptions
public DuplicatedItemException(string message)
: base(message)
{ }
-
+
///
/// The serialization constructor
///
diff --git a/Kyoo.Abstractions/Models/Exceptions/TaskFailedException.cs b/Kyoo.Abstractions/Models/Exceptions/TaskFailedException.cs
index eebc784e..7bac57e3 100644
--- a/Kyoo.Abstractions/Models/Exceptions/TaskFailedException.cs
+++ b/Kyoo.Abstractions/Models/Exceptions/TaskFailedException.cs
@@ -15,24 +15,24 @@ namespace Kyoo.Abstractions.Models.Exceptions
///
public TaskFailedException()
: base("A task failed.")
- {}
-
+ { }
+
///
/// Create a new with a custom message.
///
/// The message to use.
public TaskFailedException(string message)
: base(message)
- {}
-
+ { }
+
///
/// Create a new wrapping another exception.
///
/// The exception to wrap.
public TaskFailedException(Exception exception)
: base(exception)
- {}
-
+ { }
+
///
/// The serialization constructor
///
diff --git a/Kyoo.Abstractions/Models/LibraryItem.cs b/Kyoo.Abstractions/Models/LibraryItem.cs
index 802e98a3..d761bbf3 100644
--- a/Kyoo.Abstractions/Models/LibraryItem.cs
+++ b/Kyoo.Abstractions/Models/LibraryItem.cs
@@ -14,7 +14,7 @@ namespace Kyoo.Abstractions.Models
Movie,
Collection
}
-
+
///
/// A type union between and .
/// This is used to list content put inside a library.
@@ -23,30 +23,30 @@ namespace Kyoo.Abstractions.Models
{
///
public int ID { get; set; }
-
+
///
public string Slug { get; set; }
-
+
///
/// The title of the show or collection.
///
public string Title { get; set; }
-
+
///
/// The summary of the show or collection.
///
public string Overview { get; set; }
-
+
///
/// Is this show airing, not aired yet or finished? This is only applicable for shows.
///
public Status? Status { get; set; }
-
+
///
/// The date this show or collection 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).
@@ -64,17 +64,17 @@ namespace Kyoo.Abstractions.Models
///
[SerializeAs("{HOST}/api/{Type:l}/{Slug}/poster")]
public string Poster => Images?.GetValueOrDefault(Models.Images.Poster);
-
+
///
/// The type of this item (ether a collection, a show or a movie).
///
public ItemType Type { get; set; }
-
-
+
+
///
/// Create a new, empty .
///
- public LibraryItem() {}
+ public LibraryItem() { }
///
/// Create a from a show.
@@ -92,7 +92,7 @@ namespace Kyoo.Abstractions.Models
Images = show.Images;
Type = show.IsMovie ? ItemType.Movie : ItemType.Show;
}
-
+
///
/// Create a from a collection
///
@@ -125,7 +125,7 @@ namespace Kyoo.Abstractions.Models
Images = x.Images,
Type = x.IsMovie ? ItemType.Movie : ItemType.Show
};
-
+
///
/// An expression to create a representing a collection.
///
diff --git a/Kyoo.Abstractions/Models/Page.cs b/Kyoo.Abstractions/Models/Page.cs
index 5dc37abb..547e903f 100644
--- a/Kyoo.Abstractions/Models/Page.cs
+++ b/Kyoo.Abstractions/Models/Page.cs
@@ -15,12 +15,12 @@ namespace Kyoo.Abstractions.Models
/// The link of the current page.
///
public Uri This { get; }
-
+
///
/// The link of the first page.
///
public Uri First { get; }
-
+
///
/// The link of the next page.
///
@@ -30,13 +30,13 @@ namespace Kyoo.Abstractions.Models
/// The number of items in the current page.
///
public int Count => Items.Count;
-
+
///
/// The list of items in the page.
///
public ICollection Items { get; }
-
-
+
+
///
/// Create a new .
///
@@ -72,7 +72,7 @@ namespace Kyoo.Abstractions.Models
query["afterID"] = items.Last().ID.ToString();
Next = new Uri(url + query.ToQueryString());
}
-
+
query.Remove("afterID");
First = new Uri(url + query.ToQueryString());
}
diff --git a/Kyoo.Abstractions/Models/PeopleRole.cs b/Kyoo.Abstractions/Models/PeopleRole.cs
index 934daf7d..0baf681e 100644
--- a/Kyoo.Abstractions/Models/PeopleRole.cs
+++ b/Kyoo.Abstractions/Models/PeopleRole.cs
@@ -12,10 +12,10 @@ namespace Kyoo.Abstractions.Models
{
///
public int ID { get; set; }
-
+
///
public string Slug => ForPeople ? Show.Slug : People.Slug;
-
+
///
/// Should this role be used as a Show substitute (the value is true ) or
/// as a People substitute (the value is false ).
@@ -30,7 +30,7 @@ namespace Kyoo.Abstractions.Models
/// The people that played this role.
///
public People People { get; set; }
-
+
///
/// The ID of the Show where the People playing in.
///
@@ -39,13 +39,13 @@ namespace Kyoo.Abstractions.Models
/// The show where the People played in.
///
public Show Show { get; set; }
-
+
///
/// The type of work the person has done for the show.
/// That can be something like "Actor", "Writer", "Music", "Voice Actor"...
///
public string Type { get; set; }
-
+
///
/// The role the People played.
/// This is mostly used to inform witch character was played for actor and voice actors.
diff --git a/Kyoo.Abstractions/Models/Resources/Collection.cs b/Kyoo.Abstractions/Models/Resources/Collection.cs
index faa7ac9f..4472d57e 100644
--- a/Kyoo.Abstractions/Models/Resources/Collection.cs
+++ b/Kyoo.Abstractions/Models/Resources/Collection.cs
@@ -12,10 +12,10 @@ namespace Kyoo.Abstractions.Models
{
///
public int ID { get; set; }
-
+
///
public string Slug { get; set; }
-
+
///
/// The name of this collection.
///
@@ -23,7 +23,7 @@ namespace Kyoo.Abstractions.Models
///
public Dictionary Images { get; set; }
-
+
///
/// The path of this poster.
/// By default, the http path for this poster is returned from the public API.
@@ -37,17 +37,17 @@ namespace Kyoo.Abstractions.Models
/// The description of this collection.
///
public string Overview { get; set; }
-
+
///
/// The list of shows contained in this collection.
///
[LoadableRelation] public ICollection Shows { get; set; }
-
+
///
/// The list of libraries that contains this collection.
///
[LoadableRelation] public ICollection Libraries { get; set; }
-
+
///
[EditableRelation] [LoadableRelation] public ICollection ExternalIDs { get; set; }
}
diff --git a/Kyoo.Abstractions/Models/Resources/Episode.cs b/Kyoo.Abstractions/Models/Resources/Episode.cs
index 65e1bd29..b2d95a45 100644
--- a/Kyoo.Abstractions/Models/Resources/Episode.cs
+++ b/Kyoo.Abstractions/Models/Resources/Episode.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using JetBrains.Annotations;
@@ -22,15 +22,15 @@ namespace Kyoo.Abstractions.Models
{
if (ShowSlug != null || Show != null)
return GetSlug(ShowSlug ?? Show.Slug, SeasonNumber, EpisodeNumber, AbsoluteNumber);
- return ShowID != 0
- ? GetSlug(ShowID.ToString(), SeasonNumber, EpisodeNumber, AbsoluteNumber)
+ return ShowID != 0
+ ? GetSlug(ShowID.ToString(), SeasonNumber, EpisodeNumber, AbsoluteNumber)
: null;
}
[UsedImplicitly] [NotNull] private set
{
if (value == null)
throw new ArgumentNullException(nameof(value));
-
+
Match match = Regex.Match(value, @"(?.+)-s(?\d+)e(?\d+)");
if (match.Success)
@@ -59,7 +59,7 @@ namespace Kyoo.Abstractions.Models
/// The slug of the Show that contain this episode. If this is not set, this episode is ill-formed.
///
[SerializeIgnore] public string ShowSlug { private get; set; }
-
+
///
/// The ID of the Show containing this episode.
///
@@ -68,7 +68,7 @@ namespace Kyoo.Abstractions.Models
/// The show that contains this episode. This must be explicitly loaded via a call to .
///
[LoadableRelation(nameof(ShowID))] public Show Show { get; set; }
-
+
///
/// The ID of the Season containing this episode.
///
@@ -87,22 +87,22 @@ namespace Kyoo.Abstractions.Models
/// The season in witch this episode is in.
///
public int? SeasonNumber { get; set; }
-
+
///
/// The number of this episode in it's season.
///
public int? EpisodeNumber { get; set; }
-
+
///
/// The absolute number of this episode. It's an episode number that is not reset to 1 after a new season.
///
public int? AbsoluteNumber { get; set; }
-
+
///
/// The path of the video file for this episode. Any format supported by a is allowed.
///
[SerializeIgnore] public string Path { get; set; }
-
+
///
public Dictionary Images { get; set; }
@@ -114,17 +114,17 @@ namespace Kyoo.Abstractions.Models
[SerializeAs("{HOST}/api/episodes/{Slug}/thumbnail")]
[Obsolete("Use Images instead of this, this is only kept for the API response.")]
public string Thumb => Images?.GetValueOrDefault(Models.Images.Thumbnail);
-
+
///
/// The title of this episode.
///
public string Title { get; set; }
-
+
///
/// The overview of this episode.
///
public string Overview { get; set; }
-
+
///
/// The release date of this episode. It can be null if unknown.
///
@@ -137,7 +137,7 @@ namespace Kyoo.Abstractions.Models
/// The list of tracks this episode has. This lists video, audio and subtitles available.
///
[EditableRelation] [LoadableRelation] public ICollection Tracks { get; set; }
-
+
///
/// Get the slug of an episode.
@@ -157,8 +157,8 @@ namespace Kyoo.Abstractions.Models
///
/// The slug corresponding to the given arguments
/// The given show slug was null.
- public static string GetSlug([NotNull] string showSlug,
- int? seasonNumber,
+ public static string GetSlug([NotNull] string showSlug,
+ int? seasonNumber,
int? episodeNumber,
int? absoluteNumber = null)
{
diff --git a/Kyoo.Abstractions/Models/Resources/Genre.cs b/Kyoo.Abstractions/Models/Resources/Genre.cs
index 0cf2d9b3..62aeec6a 100644
--- a/Kyoo.Abstractions/Models/Resources/Genre.cs
+++ b/Kyoo.Abstractions/Models/Resources/Genre.cs
@@ -11,15 +11,15 @@ namespace Kyoo.Abstractions.Models
{
///
public int ID { get; set; }
-
+
///
public string Slug { get; set; }
-
+
///
/// The name of this genre.
///
public string Name { get; set; }
-
+
///
/// The list of shows that have this genre.
///
@@ -28,8 +28,8 @@ namespace Kyoo.Abstractions.Models
///
/// Create a new, empty .
///
- public Genre() {}
-
+ public Genre() { }
+
///
/// Create a new and specify it's .
/// The is automatically calculated from it's name.
diff --git a/Kyoo.Abstractions/Models/Resources/Interfaces/IMetadata.cs b/Kyoo.Abstractions/Models/Resources/Interfaces/IMetadata.cs
index b28d893a..6f8c9b46 100644
--- a/Kyoo.Abstractions/Models/Resources/Interfaces/IMetadata.cs
+++ b/Kyoo.Abstractions/Models/Resources/Interfaces/IMetadata.cs
@@ -14,7 +14,8 @@ namespace Kyoo.Abstractions.Models
///
/// The link to metadata providers that this show has. See for more information.
///
- [EditableRelation] [LoadableRelation]
+ [EditableRelation]
+ [LoadableRelation]
public ICollection ExternalIDs { get; set; }
}
diff --git a/Kyoo.Abstractions/Models/Resources/Interfaces/IResource.cs b/Kyoo.Abstractions/Models/Resources/Interfaces/IResource.cs
index bde5aef6..c7606d64 100644
--- a/Kyoo.Abstractions/Models/Resources/Interfaces/IResource.cs
+++ b/Kyoo.Abstractions/Models/Resources/Interfaces/IResource.cs
@@ -15,7 +15,7 @@ namespace Kyoo.Abstractions.Models
/// this field is automatically assigned by the .
///
public int ID { get; set; }
-
+
///
/// A human-readable identifier that can be used instead of an ID.
/// A slug must be unique for a type of resource but it can be changed.
@@ -24,6 +24,6 @@ namespace Kyoo.Abstractions.Models
/// There is no setter for a slug since it can be computed from other fields.
/// For example, a season slug is {ShowSlug}-s{SeasonNumber}.
///
- public string Slug { get; }
+ public string Slug { get; }
}
}
\ No newline at end of file
diff --git a/Kyoo.Abstractions/Models/Resources/Interfaces/IThumbnails.cs b/Kyoo.Abstractions/Models/Resources/Interfaces/IThumbnails.cs
index 670dbb51..b693dea9 100644
--- a/Kyoo.Abstractions/Models/Resources/Interfaces/IThumbnails.cs
+++ b/Kyoo.Abstractions/Models/Resources/Interfaces/IThumbnails.cs
@@ -16,7 +16,7 @@ namespace Kyoo.Abstractions.Models
/// An arbitrary index should not be used, instead use indexes from
///
public Dictionary Images { get; set; }
-
+
// TODO remove Posters properties add them via the json serializer for every IThumbnails
}
diff --git a/Kyoo.Abstractions/Models/Resources/Library.cs b/Kyoo.Abstractions/Models/Resources/Library.cs
index fad1156e..b3b7037c 100644
--- a/Kyoo.Abstractions/Models/Resources/Library.cs
+++ b/Kyoo.Abstractions/Models/Resources/Library.cs
@@ -10,15 +10,15 @@ namespace Kyoo.Abstractions.Models
{
///
public int ID { get; set; }
-
+
///
public string Slug { get; set; }
-
+
///
/// The name of this library.
///
public string Name { get; set; }
-
+
///
/// The list of paths that this library is responsible for. This is mainly used by the Scan task.
///
@@ -33,7 +33,7 @@ namespace Kyoo.Abstractions.Models
/// The list of shows in this library.
///
[LoadableRelation] public ICollection Shows { get; set; }
-
+
///
/// The list of collections in this library.
///
diff --git a/Kyoo.Abstractions/Models/Resources/People.cs b/Kyoo.Abstractions/Models/Resources/People.cs
index ce46c6a7..85ced0c6 100644
--- a/Kyoo.Abstractions/Models/Resources/People.cs
+++ b/Kyoo.Abstractions/Models/Resources/People.cs
@@ -11,15 +11,15 @@ namespace Kyoo.Abstractions.Models
{
///
public int ID { get; set; }
-
+
///
public string Slug { get; set; }
-
+
///
/// The name of this person.
///
public string Name { get; set; }
-
+
///
public Dictionary Images { get; set; }
@@ -31,10 +31,10 @@ namespace Kyoo.Abstractions.Models
[SerializeAs("{HOST}/api/people/{Slug}/poster")]
[Obsolete("Use Images instead of this, this is only kept for the API response.")]
public string Poster => Images?.GetValueOrDefault(Models.Images.Poster);
-
+
///
[EditableRelation] [LoadableRelation] public ICollection ExternalIDs { get; set; }
-
+
///
/// The list of roles this person has played in. See for more information.
///
diff --git a/Kyoo.Abstractions/Models/Resources/Provider.cs b/Kyoo.Abstractions/Models/Resources/Provider.cs
index d1a34223..f32fbad0 100644
--- a/Kyoo.Abstractions/Models/Resources/Provider.cs
+++ b/Kyoo.Abstractions/Models/Resources/Provider.cs
@@ -14,15 +14,15 @@ namespace Kyoo.Abstractions.Models
{
///
public int ID { get; set; }
-
+
///
public string Slug { get; set; }
-
+
///
/// The name of this provider.
///
public string Name { get; set; }
-
+
///
public Dictionary Images { get; set; }
diff --git a/Kyoo.Abstractions/Models/Resources/Season.cs b/Kyoo.Abstractions/Models/Resources/Season.cs
index d60da6d8..ed9f415c 100644
--- a/Kyoo.Abstractions/Models/Resources/Season.cs
+++ b/Kyoo.Abstractions/Models/Resources/Season.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using JetBrains.Annotations;
@@ -13,7 +13,7 @@ namespace Kyoo.Abstractions.Models
public class Season : IResource, IMetadata, IThumbnails
{
///
- public int ID { get; set; }
+ public int ID { get; set; }
///
[Computed] public string Slug
@@ -27,7 +27,7 @@ namespace Kyoo.Abstractions.Models
[UsedImplicitly] [NotNull] private set
{
Match match = Regex.Match(value ?? "", @"(?.+)-s(?\d+)");
-
+
if (!match.Success)
throw new ArgumentException("Invalid season slug. Format: {showSlug}-s{seasonNumber}");
ShowSlug = match.Groups["show"].Value;
@@ -39,7 +39,7 @@ namespace Kyoo.Abstractions.Models
/// The slug of the Show that contain this episode. If this is not set, this season is ill-formed.
///
[SerializeIgnore] public string ShowSlug { private get; set; }
-
+
///
/// The ID of the Show containing this season.
///
@@ -59,17 +59,17 @@ namespace Kyoo.Abstractions.Models
/// The title of this season.
///
public string Title { get; set; }
-
+
///
/// A quick overview of this season.
///
public string Overview { get; set; }
-
+
///
/// The starting air date of this season.
///
public DateTime? StartDate { get; set; }
-
+
///
/// The ending date of this season.
///
@@ -86,7 +86,7 @@ namespace Kyoo.Abstractions.Models
[SerializeAs("{HOST}/api/seasons/{Slug}/thumb")]
[Obsolete("Use Images instead of this, this is only kept for the API response.")]
public string Poster => Images?.GetValueOrDefault(Models.Images.Poster);
-
+
///
[EditableRelation] [LoadableRelation] public ICollection ExternalIDs { get; set; }
diff --git a/Kyoo.Abstractions/Models/Resources/Show.cs b/Kyoo.Abstractions/Models/Resources/Show.cs
index 77f18d99..1a4b87c9 100644
--- a/Kyoo.Abstractions/Models/Resources/Show.cs
+++ b/Kyoo.Abstractions/Models/Resources/Show.cs
@@ -12,31 +12,31 @@ namespace Kyoo.Abstractions.Models
{
///
public int ID { get; set; }
-
+
///
public string Slug { get; set; }
-
+
///
/// The title of this show.
///
public string Title { get; set; }
-
+
///
/// The list of alternative titles of this show.
///
[EditableRelation] public string[] Aliases { get; set; }
-
+
///
/// The path of the root directory of this show.
/// This can be any kind of path supported by
///
[SerializeIgnore] public string Path { get; set; }
-
+
///
/// The summary of this show.
///
public string Overview { get; set; }
-
+
///
/// Is this show airing, not aired yet or finished?
///
@@ -48,12 +48,12 @@ namespace Kyoo.Abstractions.Models
/// TODO for now, this is set to a youtube url. It should be cached and converted to a local file.
[Obsolete("Use Images instead of this, this is only kept for the API response.")]
public string TrailerUrl => Images?.GetValueOrDefault(Models.Images.Trailer);
-
+
///
/// The date this show started airing. It can be null if this is unknown.
///
public DateTime? StartAir { get; set; }
-
+
///
/// The date this show finished airing.
/// It must be after the but can be the same (example: for movies).
@@ -108,39 +108,39 @@ namespace Kyoo.Abstractions.Models
/// This must be explicitly loaded via a call to .
///
[LoadableRelation(nameof(StudioID))] [EditableRelation] public Studio Studio { get; set; }
-
+
///
/// The list of genres (themes) this show has.
///
[LoadableRelation] [EditableRelation] public ICollection Genres { get; set; }
-
+
///
/// The list of people that made this show.
///
[LoadableRelation] [EditableRelation] public ICollection People { get; set; }
-
+
///
/// The different seasons in this show. If this is a movie, this list is always null or empty.
///
[LoadableRelation] public ICollection Seasons { get; set; }
-
+
///
/// 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).
/// Having an episode is necessary to store metadata and tracks.
///
[LoadableRelation] public ICollection Episodes { get; set; }
-
+
///
/// The list of libraries that contains this show.
///
[LoadableRelation] public ICollection Libraries { get; set; }
-
+
///
/// The list of collections that contains this show.
///
[LoadableRelation] public ICollection Collections { get; set; }
-
+
///
public void OnMerge(object merged)
{
diff --git a/Kyoo.Abstractions/Models/Resources/Studio.cs b/Kyoo.Abstractions/Models/Resources/Studio.cs
index fbc4934b..6edb8a28 100644
--- a/Kyoo.Abstractions/Models/Resources/Studio.cs
+++ b/Kyoo.Abstractions/Models/Resources/Studio.cs
@@ -11,15 +11,15 @@ namespace Kyoo.Abstractions.Models
{
///
public int ID { get; set; }
-
+
///
public string Slug { get; set; }
-
+
///
/// The name of this studio.
///
public string Name { get; set; }
-
+
///
/// The list of shows that are made by this studio.
///
@@ -27,7 +27,7 @@ namespace Kyoo.Abstractions.Models
///
[EditableRelation] [LoadableRelation] public ICollection ExternalIDs { get; set; }
-
+
///
/// Create a new, empty, .
///
diff --git a/Kyoo.Abstractions/Models/Resources/Track.cs b/Kyoo.Abstractions/Models/Resources/Track.cs
index 4f94b7f3..1e5da085 100644
--- a/Kyoo.Abstractions/Models/Resources/Track.cs
+++ b/Kyoo.Abstractions/Models/Resources/Track.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Globalization;
using System.Linq;
using System.Text.RegularExpressions;
@@ -27,7 +27,7 @@ namespace Kyoo.Abstractions.Models
{
///
public int ID { get; set; }
-
+
///
[Computed] public string Slug
{
@@ -42,12 +42,14 @@ namespace Kyoo.Abstractions.Models
{
if (value == null)
throw new ArgumentNullException(nameof(value));
- Match match = Regex.Match(value,
+ Match match = Regex.Match(value,
@"(?[^\.]+)\.(?\w{0,3})(-(?\d+))?(\.(?forced))?\.(?\w+)(\.\w*)?");
if (!match.Success)
+ {
throw new ArgumentException("Invalid track slug. " +
"Format: {episodeSlug}.{language}[-{index}][.forced].{type}[.{extension}]");
+ }
EpisodeSlug = match.Groups["ep"].Value;
Language = match.Groups["lang"].Value;
@@ -58,53 +60,53 @@ namespace Kyoo.Abstractions.Models
Type = Enum.Parse(match.Groups["type"].Value, true);
}
}
-
+
///
/// The slug of the episode that contain this track. If this is not set, this track is ill-formed.
///
[SerializeIgnore] public string EpisodeSlug { private get; set; }
-
+
///
/// The title of the stream.
///
public string Title { get; set; }
-
+
///
/// The language of this stream (as a ISO-639-2 language code)
///
public string Language { get; set; }
-
+
///
/// The codec of this stream.
///
public string Codec { get; set; }
-
-
+
+
///
/// Is this stream the default one of it's type?
///
public bool IsDefault { get; set; }
-
+
///
/// Is this stream tagged as forced?
///
public bool IsForced { get; set; }
-
+
///
/// Is this track extern to the episode's file?
///
public bool IsExternal { get; set; }
-
+
///
/// The path of this track.
///
[SerializeIgnore] public string Path { get; set; }
-
+
///
/// The type of this stream.
///
[SerializeIgnore] public StreamType Type { get; set; }
-
+
///
/// The ID of the episode that uses this track.
///
@@ -137,7 +139,7 @@ namespace Kyoo.Abstractions.Models
name += " Forced";
if (IsExternal)
name += " (External)";
- if (Title is {Length: > 1})
+ if (Title is { Length: > 1 })
name += " - " + Title;
return name;
}
@@ -164,8 +166,8 @@ namespace Kyoo.Abstractions.Models
public static string BuildSlug(string baseSlug,
StreamType type)
{
- return baseSlug.EndsWith($".{type}", StringComparison.InvariantCultureIgnoreCase)
- ? baseSlug
+ return baseSlug.EndsWith($".{type}", StringComparison.InvariantCultureIgnoreCase)
+ ? baseSlug
: $"{baseSlug}.{type.ToString().ToLowerInvariant()}";
}
}
diff --git a/Kyoo.Abstractions/Models/Resources/User.cs b/Kyoo.Abstractions/Models/Resources/User.cs
index 8e61cb64..cad4fd73 100644
--- a/Kyoo.Abstractions/Models/Resources/User.cs
+++ b/Kyoo.Abstractions/Models/Resources/User.cs
@@ -9,30 +9,30 @@ namespace Kyoo.Abstractions.Models
{
///
public int ID { get; set; }
-
+
///
public string Slug { get; set; }
-
+
///
/// A username displayed to the user.
///
public string Username { get; set; }
-
+
///
/// The user email address.
///
public string Email { get; set; }
-
+
///
/// The user password (hashed, it can't be read like that). The hashing format is implementation defined.
///
public string Password { get; set; }
-
+
///
/// The list of permissions of the user. The format of this is implementation dependent.
///
public string[] Permissions { get; set; }
-
+
///
/// Arbitrary extra data that can be used by specific authentication implementations.
///
@@ -45,13 +45,13 @@ namespace Kyoo.Abstractions.Models
/// The list of shows the user has finished.
///
public ICollection Watched { get; set; }
-
+
///
/// The list of episodes the user is watching (stopped in progress or the next episode of the show)
///
public ICollection CurrentlyWatching { get; set; }
}
-
+
///
/// Metadata of episode currently watching by an user
///
@@ -61,17 +61,17 @@ namespace Kyoo.Abstractions.Models
/// The ID of the user that started watching this episode.
///
public int UserID { get; set; }
-
+
///
/// The ID of the episode started.
///
public int EpisodeID { get; set; }
-
+
///
/// The started.
///
public Episode Episode { get; set; }
-
+
///
/// Where the player has stopped watching the episode (between 0 and 100).
///
diff --git a/Kyoo.Abstractions/Models/SearchResult.cs b/Kyoo.Abstractions/Models/SearchResult.cs
index 9b1b5006..b9b62040 100644
--- a/Kyoo.Abstractions/Models/SearchResult.cs
+++ b/Kyoo.Abstractions/Models/SearchResult.cs
@@ -11,32 +11,32 @@ namespace Kyoo.Abstractions.Models
/// The query of the search request.
///
public string Query { get; init; }
-
+
///
/// The collections that matched the search.
///
public ICollection Collections { get; init; }
-
+
///
/// The shows that matched the search.
///
public ICollection Shows { get; init; }
-
+
///
/// The episodes that matched the search.
///
public ICollection Episodes { get; init; }
-
+
///
/// The people that matched the search.
///
public ICollection People { get; init; }
-
+
///
/// The genres that matched the search.
///
public ICollection Genres { get; init; }
-
+
///
/// The studios that matched the search.
///
diff --git a/Kyoo.Abstractions/Models/WatchItem.cs b/Kyoo.Abstractions/Models/WatchItem.cs
index 3f48a636..570ba17b 100644
--- a/Kyoo.Abstractions/Models/WatchItem.cs
+++ b/Kyoo.Abstractions/Models/WatchItem.cs
@@ -20,7 +20,7 @@ namespace Kyoo.Abstractions.Models
/// The ID of the episode associated with this item.
///
public int EpisodeID { get; set; }
-
+
///
/// The slug of this episode.
///
@@ -30,54 +30,54 @@ namespace Kyoo.Abstractions.Models
/// The title of the show containing this episode.
///
public string ShowTitle { get; set; }
-
+
///
/// The slug of the show containing this episode
///
public string ShowSlug { get; set; }
-
+
///
/// The season in witch this episode is in.
///
public int? SeasonNumber { get; set; }
-
+
///
/// The number of this episode is it's season.
///
public int? EpisodeNumber { get; set; }
-
+
///
/// The absolute number of this episode. It's an episode number that is not reset to 1 after a new season.
///
public int? AbsoluteNumber { get; set; }
-
+
///
/// The title of this episode.
///
public string Title { get; set; }
-
+
///
/// The release date of this episode. It can be null if unknown.
///
public DateTime? ReleaseDate { get; set; }
-
+
///
/// The path of the video file for this episode. Any format supported by a is allowed.
///
[SerializeIgnore] public string Path { get; set; }
-
+
///
/// 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.
///
public Episode PreviousEpisode { get; set; }
-
+
///
/// 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.
///
public Episode NextEpisode { get; set; }
-
+
///
/// true if this is a movie, false otherwise.
///
@@ -89,14 +89,14 @@ namespace Kyoo.Abstractions.Models
/// This can be disabled using the internal query flag.
///
[SerializeAs("{HOST}/api/show/{ShowSlug}/poster")] public string Poster { get; set; }
-
+
///
/// The path of this item's logo.
/// By default, the http path for the logo is returned from the public API.
/// This can be disabled using the internal query flag.
///
[SerializeAs("{HOST}/api/show/{ShowSlug}/logo")] public string Logo { get; set; }
-
+
///
/// The path of this item's backdrop.
/// By default, the http path for the backdrop is returned from the public API.
@@ -109,27 +109,27 @@ namespace Kyoo.Abstractions.Models
/// Common containers are mp4, mkv, avi and so on.
///
public string Container { get; set; }
-
+
///
/// The video track. See for more information.
///
public Track Video { get; set; }
-
+
///
/// The list of audio tracks. See for more information.
///
public ICollection Audios { get; set; }
-
+
///
/// The list of subtitles tracks. See for more information.
///
public ICollection Subtitles { get; set; }
-
+
///
/// The list of chapters. See for more information.
///
public ICollection Chapters { get; set; }
-
+
///
/// Create a from an .
@@ -146,15 +146,15 @@ namespace Kyoo.Abstractions.Models
await library.Load(ep, x => x.Show);
await library.Load(ep, x => x.Tracks);
-
+
if (!ep.Show.IsMovie && ep.SeasonNumber != null && ep.EpisodeNumber != null)
{
if (ep.EpisodeNumber > 1)
previous = await library.GetOrDefault(ep.ShowID, ep.SeasonNumber.Value, ep.EpisodeNumber.Value - 1);
else if (ep.SeasonNumber > 1)
{
- previous = (await library.GetAll(x => x.ShowID == ep.ShowID
- && x.SeasonNumber == ep.SeasonNumber.Value - 1,
+ previous = (await library.GetAll(x => x.ShowID == ep.ShowID
+ && x.SeasonNumber == ep.SeasonNumber.Value - 1,
limit: 1,
sort: new Sort(x => x.EpisodeNumber, true))
).FirstOrDefault();
@@ -167,12 +167,12 @@ namespace Kyoo.Abstractions.Models
}
else if (!ep.Show.IsMovie && ep.AbsoluteNumber != null)
{
- previous = await library.GetOrDefault(x => x.ShowID == ep.ShowID
+ previous = await library.GetOrDefault(x => x.ShowID == ep.ShowID
&& x.AbsoluteNumber == ep.EpisodeNumber + 1);
- next = await library.GetOrDefault(x => x.ShowID == ep.ShowID
+ next = await library.GetOrDefault(x => x.ShowID == ep.ShowID
&& x.AbsoluteNumber == ep.AbsoluteNumber + 1);
}
-
+
return new WatchItem
{
EpisodeID = ep.ID,
@@ -188,7 +188,7 @@ namespace Kyoo.Abstractions.Models
Container = PathIO.GetExtension(ep.Path)![1..],
Video = ep.Tracks.FirstOrDefault(x => x.Type == StreamType.Video),
Audios = ep.Tracks.Where(x => x.Type == StreamType.Audio).ToArray(),
- Subtitles = ep.Tracks.Where(x => x.Type == StreamType.Subtitle).ToArray(),
+ Subtitles = ep.Tracks.Where(x => x.Type == StreamType.Subtitle).ToArray(),
PreviousEpisode = previous,
NextEpisode = next,
Chapters = await GetChapters(ep.Path)
@@ -200,7 +200,7 @@ namespace Kyoo.Abstractions.Models
private static async Task> GetChapters(string episodePath)
{
string path = PathIO.Combine(
- PathIO.GetDirectoryName(episodePath)!,
+ PathIO.GetDirectoryName(episodePath)!,
"Chapters",
PathIO.GetFileNameWithoutExtension(episodePath) + ".txt"
);
diff --git a/Kyoo.Abstractions/Module.cs b/Kyoo.Abstractions/Module.cs
index dcc5bc18..442a1070 100644
--- a/Kyoo.Abstractions/Module.cs
+++ b/Kyoo.Abstractions/Module.cs
@@ -30,7 +30,7 @@ namespace Kyoo.Abstractions
/// The container
/// The type of the task
/// The registration builder of this new provider. That can be used to edit the registration.
- public static IRegistrationBuilder
+ public static IRegistrationBuilder
RegisterProvider(this ContainerBuilder builder)
where T : class, IMetadataProvider
{
@@ -46,7 +46,7 @@ namespace Kyoo.Abstractions
/// If your repository implements a special interface, please use
///
/// The initial container.
- public static IRegistrationBuilder
+ public static IRegistrationBuilder
RegisterRepository(this ContainerBuilder builder)
where T : IBaseRepository
{
diff --git a/Kyoo.Abstractions/Utility/EnumerableExtensions.cs b/Kyoo.Abstractions/Utility/EnumerableExtensions.cs
index 9bd81157..7b13bc11 100644
--- a/Kyoo.Abstractions/Utility/EnumerableExtensions.cs
+++ b/Kyoo.Abstractions/Utility/EnumerableExtensions.cs
@@ -42,7 +42,7 @@ namespace Kyoo.Utils
}
return Generator(self, mapper);
}
-
+
///
/// A map where the mapping function is asynchronous.
/// Note: might interest you.
@@ -54,7 +54,7 @@ namespace Kyoo.Utils
/// The list mapped as an AsyncEnumerable
/// The list or the mapper can't be null
[LinqTunnel]
- public static IAsyncEnumerable MapAsync([NotNull] this IEnumerable self,
+ public static IAsyncEnumerable MapAsync([NotNull] this IEnumerable self,
[NotNull] Func> mapper)
{
if (self == null)
@@ -76,7 +76,7 @@ namespace Kyoo.Utils
return Generator(self, mapper);
}
-
+
///
/// An asynchronous version of Select.
///
@@ -87,7 +87,7 @@ namespace Kyoo.Utils
/// The list mapped as an AsyncEnumerable
/// The list or the mapper can't be null
[LinqTunnel]
- public static IAsyncEnumerable SelectAsync([NotNull] this IEnumerable self,
+ public static IAsyncEnumerable SelectAsync([NotNull] this IEnumerable self,
[NotNull] Func> mapper)
{
if (self == null)
@@ -159,7 +159,7 @@ namespace Kyoo.Utils
do
{
yield return enumerator.Current;
- }
+ }
while (enumerator.MoveNext());
}
@@ -179,7 +179,7 @@ namespace Kyoo.Utils
foreach (T i in self)
action(i);
}
-
+
///
/// A foreach used as a function with a little specificity: the list can be null.
///
@@ -192,7 +192,7 @@ namespace Kyoo.Utils
foreach (object i in self)
action(i);
}
-
+
///
/// A foreach used as a function with a little specificity: the list can be null.
///
@@ -205,7 +205,7 @@ namespace Kyoo.Utils
foreach (object i in self)
await action(i);
}
-
+
///
/// A foreach used as a function with a little specificity: the list can be null.
///
@@ -219,7 +219,7 @@ namespace Kyoo.Utils
foreach (T i in self)
await action(i);
}
-
+
///
/// A foreach used as a function with a little specificity: the list can be null.
///
@@ -233,7 +233,7 @@ namespace Kyoo.Utils
await foreach (T i in self)
action(i);
}
-
+
///
/// Split a list in a small chunk of data.
///
@@ -247,7 +247,7 @@ namespace Kyoo.Utils
for (int i = 0; i < list.Count; i += countPerList)
yield return list.GetRange(i, Math.Min(list.Count - i, countPerList));
}
-
+
///
/// Split a list in a small chunk of data.
///
@@ -260,7 +260,7 @@ namespace Kyoo.Utils
{
T[] ret = new T[countPerList];
int i = 0;
-
+
using IEnumerator enumerator = list.GetEnumerator();
while (enumerator.MoveNext())
{
diff --git a/Kyoo.Abstractions/Utility/Merger.cs b/Kyoo.Abstractions/Utility/Merger.cs
index fe00a924..17b21bd5 100644
--- a/Kyoo.Abstractions/Utility/Merger.cs
+++ b/Kyoo.Abstractions/Utility/Merger.cs
@@ -24,7 +24,7 @@ namespace Kyoo.Utils
/// The two list merged as an array
[ContractAnnotation("first:notnull => notnull; second:notnull => notnull", true)]
public static T[] MergeLists([CanBeNull] IEnumerable first,
- [CanBeNull] IEnumerable second,
+ [CanBeNull] IEnumerable second,
[CanBeNull] Func isEqual = null)
{
if (first == null)
@@ -82,7 +82,7 @@ namespace Kyoo.Utils
{
bool success = first.TryAdd(key, value);
hasChanged |= success;
-
+
if (success || first[key]?.Equals(default) == false || value?.Equals(default) != false)
continue;
first[key] = value;
@@ -150,9 +150,9 @@ namespace Kyoo.Utils
{
Type type = typeof(T);
IEnumerable properties = type.GetProperties()
- .Where(x => x.CanRead && x.CanWrite
+ .Where(x => x.CanRead && x.CanWrite
&& Attribute.GetCustomAttribute(x, typeof(NotMergeableAttribute)) == null);
-
+
foreach (PropertyInfo property in properties)
{
object value = property.GetValue(second);
@@ -163,7 +163,7 @@ namespace Kyoo.Utils
merge.OnMerge(second);
return first;
}
-
+
///
/// 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
@@ -190,15 +190,15 @@ namespace Kyoo.Utils
/// Fields of T will be completed
///
/// If first is null
- public static T Complete([NotNull] T first,
- [CanBeNull] T second,
+ public static T Complete([NotNull] T first,
+ [CanBeNull] T second,
[InstantHandle] Func where = null)
{
if (first == null)
throw new ArgumentNullException(nameof(first));
if (second == null)
return first;
-
+
Type type = typeof(T);
IEnumerable properties = type.GetProperties()
.Where(x => x.CanRead && x.CanWrite
@@ -206,7 +206,7 @@ namespace Kyoo.Utils
if (where != null)
properties = properties.Where(where);
-
+
foreach (PropertyInfo property in properties)
{
object value = property.GetValue(second);
@@ -261,7 +261,7 @@ namespace Kyoo.Utils
/// Fields of T will be merged
///
[ContractAnnotation("first:notnull => notnull; second:notnull => notnull", true)]
- public static T Merge([CanBeNull] T first,
+ public static T Merge([CanBeNull] T first,
[CanBeNull] T second,
[InstantHandle] Func where = null)
{
@@ -269,21 +269,21 @@ namespace Kyoo.Utils
return second;
if (second == null)
return first;
-
+
Type type = typeof(T);
IEnumerable properties = type.GetProperties()
- .Where(x => x.CanRead && x.CanWrite
+ .Where(x => x.CanRead && x.CanWrite
&& Attribute.GetCustomAttribute(x, typeof(NotMergeableAttribute)) == null);
-
+
if (where != null)
properties = properties.Where(where);
-
+
foreach (PropertyInfo property in properties)
{
object oldValue = property.GetValue(first);
object newValue = property.GetValue(second);
object defaultValue = property.PropertyType.GetClrDefault();
-
+
if (oldValue?.Equals(defaultValue) != false)
property.SetValue(first, newValue);
else if (Utility.IsOfGenericType(property.PropertyType, typeof(IDictionary<,>)))
@@ -310,7 +310,7 @@ namespace Kyoo.Utils
.GenericTypeArguments
.First();
Func equalityComparer = enumerableType.IsAssignableTo(typeof(IResource))
- ? (x, y) => x.Slug == y.Slug
+ ? (x, y) => x.Slug == y.Slug
: null;
property.SetValue(first, Utility.RunGenericMethod(
typeof(Merger),
@@ -344,4 +344,4 @@ namespace Kyoo.Utils
return obj;
}
}
-}
\ No newline at end of file
+}
diff --git a/Kyoo.Abstractions/Utility/MethodOfUtils.cs b/Kyoo.Abstractions/Utility/MethodOfUtils.cs
index 30a1ce4c..21e65919 100644
--- a/Kyoo.Abstractions/Utility/MethodOfUtils.cs
+++ b/Kyoo.Abstractions/Utility/MethodOfUtils.cs
@@ -17,7 +17,7 @@ namespace Kyoo.Utils
{
return action.Method;
}
-
+
///
/// Get a MethodInfo from a direct method.
///
@@ -27,7 +27,7 @@ namespace Kyoo.Utils
{
return action.Method;
}
-
+
///
/// Get a MethodInfo from a direct method.
///
@@ -37,7 +37,7 @@ namespace Kyoo.Utils
{
return action.Method;
}
-
+
///
/// Get a MethodInfo from a direct method.
///
@@ -47,7 +47,7 @@ namespace Kyoo.Utils
{
return action.Method;
}
-
+
///
/// Get a MethodInfo from a direct method.
///
@@ -57,7 +57,7 @@ namespace Kyoo.Utils
{
return action.Method;
}
-
+
///
/// Get a MethodInfo from a direct method.
///
@@ -67,7 +67,7 @@ namespace Kyoo.Utils
{
return action.Method;
}
-
+
///
/// Get a MethodInfo from a direct method.
///
@@ -77,7 +77,7 @@ namespace Kyoo.Utils
{
return action.Method;
}
-
+
///
/// Get a MethodInfo from a direct method.
///
diff --git a/Kyoo.Abstractions/Utility/Utility.cs b/Kyoo.Abstractions/Utility/Utility.cs
index d1bb91b1..7b9d1950 100644
--- a/Kyoo.Abstractions/Utility/Utility.cs
+++ b/Kyoo.Abstractions/Utility/Utility.cs
@@ -28,7 +28,7 @@ namespace Kyoo.Utils
return ex.Body is MemberExpression ||
ex.Body.NodeType == ExpressionType.Convert && ((UnaryExpression)ex.Body).Operand is MemberExpression;
}
-
+
///
/// Get the name of a property. Useful for selectors as members ex: Load(x => x.Shows)
///
@@ -66,7 +66,7 @@ namespace Kyoo.Utils
_ => throw new ArgumentException($"Can't get value of a non property/field (member: {member}).")
};
}
-
+
///
/// Slugify a string (Replace spaces by -, Uniformize accents é -> e)
///
@@ -78,7 +78,7 @@ namespace Kyoo.Utils
return null;
str = str.ToLowerInvariant();
-
+
string normalizedString = str.Normalize(NormalizationForm.FormD);
StringBuilder stringBuilder = new();
foreach (char c in normalizedString)
@@ -104,7 +104,7 @@ namespace Kyoo.Utils
public static object GetClrDefault(this Type type)
{
return type.IsValueType
- ? Activator.CreateInstance(type)
+ ? Activator.CreateInstance(type)
: null;
}
@@ -135,7 +135,7 @@ namespace Kyoo.Utils
throw new ArgumentNullException(nameof(obj));
return IsOfGenericType(obj.GetType(), genericType);
}
-
+
///
/// Check if inherit from a generic type .
///
@@ -201,15 +201,15 @@ namespace Kyoo.Utils
/// The list of generic parameters.
///
///
- /// The list of parameters.
+ /// The list of parameters.
///
/// No method match the given constraints.
/// The method handle of the matching method.
[PublicAPI]
[NotNull]
- public static MethodInfo GetMethod([NotNull] Type type,
+ public static MethodInfo GetMethod([NotNull] Type type,
BindingFlags flag,
- string name,
+ string name,
[NotNull] Type[] generics,
[NotNull] object[] args)
{
@@ -219,7 +219,7 @@ namespace Kyoo.Utils
throw new ArgumentNullException(nameof(generics));
if (args == null)
throw new ArgumentNullException(nameof(args));
-
+
MethodInfo[] methods = type.GetMethods(flag | BindingFlags.Public)
.Where(x => x.Name == name)
.Where(x => x.GetGenericArguments().Length == generics.Length)
@@ -234,7 +234,7 @@ namespace Kyoo.Utils
// return x.GetGenericArguments().All(y => y.IsAssignableFrom(generics[i++]));
// })
// .IfEmpty(() => throw new NullReferenceException($"No method {name} match the generics specified."))
-
+
// TODO this won't work for Type because T is specified in arguments but not in the parameters type.
// .Where(x =>
// {
@@ -249,7 +249,7 @@ namespace Kyoo.Utils
return methods[0];
throw new ArgumentException($"Multiple methods named {name} match the generics and parameters constraints.");
}
-
+
///
/// Run a generic static method for a runtime .
///
@@ -276,14 +276,14 @@ namespace Kyoo.Utils
///
///
public static T RunGenericMethod(
- [NotNull] Type owner,
+ [NotNull] Type owner,
[NotNull] string methodName,
[NotNull] Type type,
params object[] args)
{
- return RunGenericMethod(owner, methodName, new[] {type}, args);
+ return RunGenericMethod(owner, methodName, new[] { type }, args);
}
-
+
///
/// Run a generic static method for a multiple runtime .
/// If your generic method only needs one type, see
@@ -313,7 +313,7 @@ namespace Kyoo.Utils
///
[PublicAPI]
public static T RunGenericMethod(
- [NotNull] Type owner,
+ [NotNull] Type owner,
[NotNull] string methodName,
[NotNull] Type[] types,
params object[] args)
@@ -361,7 +361,7 @@ namespace Kyoo.Utils
[NotNull] Type type,
params object[] args)
{
- return RunGenericMethod(instance, methodName, new[] {type}, args);
+ return RunGenericMethod(instance, methodName, new[] { type }, args);
}
///
@@ -392,7 +392,7 @@ namespace Kyoo.Utils
///
///
public static T RunGenericMethod(
- [NotNull] object instance,
+ [NotNull] object instance,
[NotNull] string methodName,
[NotNull] Type[] types,
params object[] args)
@@ -436,4 +436,4 @@ namespace Kyoo.Utils
return $"{type.Name[..type.Name.IndexOf('`')]}<{generics}>";
}
}
-}
\ No newline at end of file
+}
diff --git a/Kyoo.Authentication/AuthenticationModule.cs b/Kyoo.Authentication/AuthenticationModule.cs
index 805b01cd..054b0268 100644
--- a/Kyoo.Authentication/AuthenticationModule.cs
+++ b/Kyoo.Authentication/AuthenticationModule.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Reflection;
@@ -32,10 +33,10 @@ namespace Kyoo.Authentication
{
///
public string Slug => "auth";
-
+
///
public string Name => "Authentication";
-
+
///
public string Description => "Enable OpenID authentication for Kyoo.";
@@ -70,8 +71,10 @@ namespace Kyoo.Authentication
/// The configuration to use
/// The logger used to allow IdentityServer to log things
/// The environment information to check if the app runs in debug mode
+ [SuppressMessage("ReSharper", "ContextualLoggerProblem",
+ Justification = "The logger is used for a dependency that is not created via the container.")]
public AuthenticationModule(IConfiguration configuration,
- ILogger logger,
+ ILogger logger,
IWebHostEnvironment environment)
{
_configuration = configuration;
@@ -100,16 +103,16 @@ namespace Kyoo.Authentication
IdentityModelEventSource.ShowPII = true;
services.AddControllers();
-
+
// TODO handle direct-videos with bearers (probably add a cookie and a app.Use to translate that for videos)
-
+
// TODO Check if tokens should be stored.
List clients = new();
_configuration.GetSection("authentication:clients").Bind(clients);
CertificateOption certificateOptions = new();
_configuration.GetSection(CertificateOption.Path).Bind(certificateOptions);
-
+
clients.AddRange(IdentityContext.GetClients());
foreach (Client client in clients)
{
@@ -131,7 +134,7 @@ namespace Kyoo.Authentication
.AddInMemoryClients(clients)
.AddProfileService()
.AddSigninKeys(certificateOptions);
-
+
services.AddAuthentication()
.AddJwtBearer(options =>
{
@@ -181,4 +184,4 @@ namespace Kyoo.Authentication
SA.New(app => app.UseAuthorization(), SA.Authorization)
};
}
-}
\ No newline at end of file
+}
diff --git a/Kyoo.Authentication/Controllers/Certificates.cs b/Kyoo.Authentication/Controllers/Certificates.cs
index 906890c4..26edbaf1 100644
--- a/Kyoo.Authentication/Controllers/Certificates.cs
+++ b/Kyoo.Authentication/Controllers/Certificates.cs
@@ -28,12 +28,12 @@ namespace Kyoo.Authentication
/// The identity server that will be modified.
/// The certificate options
///
- public static IIdentityServerBuilder AddSigninKeys(this IIdentityServerBuilder builder,
+ public static IIdentityServerBuilder AddSigninKeys(this IIdentityServerBuilder builder,
CertificateOption options)
{
X509Certificate2 certificate = GetCertificate(options);
builder.AddSigningCredential(certificate);
-
+
if (certificate.NotAfter.AddDays(-7) <= DateTime.UtcNow)
{
Console.WriteLine("Signin certificate will expire soon, renewing it.");
@@ -54,8 +54,8 @@ namespace Kyoo.Authentication
/// A valid certificate
private static X509Certificate2 GetCertificate(CertificateOption options)
{
- return File.Exists(options.File)
- ? GetExistingCredential(options.File, options.Password)
+ return File.Exists(options.File)
+ ? GetExistingCredential(options.File, options.Password)
: GenerateCertificate(options.File, options.Password);
}
@@ -83,19 +83,19 @@ namespace Kyoo.Authentication
private static X509Certificate2 GenerateCertificate(string file, string password)
{
SecureRandom random = new();
-
+
X509V3CertificateGenerator certificateGenerator = new();
- certificateGenerator.SetSerialNumber(BigIntegers.CreateRandomInRange(BigInteger.One,
+ certificateGenerator.SetSerialNumber(BigIntegers.CreateRandomInRange(BigInteger.One,
BigInteger.ValueOf(long.MaxValue), random));
certificateGenerator.SetIssuerDN(new X509Name($"C=NL, O=SDG, CN=Kyoo"));
certificateGenerator.SetSubjectDN(new X509Name($"C=NL, O=SDG, CN=Kyoo"));
certificateGenerator.SetNotBefore(DateTime.UtcNow.Date);
certificateGenerator.SetNotAfter(DateTime.UtcNow.Date.AddMonths(3));
-
+
KeyGenerationParameters keyGenerationParameters = new(random, 2048);
RsaKeyPairGenerator keyPairGenerator = new();
keyPairGenerator.Init(keyGenerationParameters);
-
+
AsymmetricCipherKeyPair subjectKeyPair = keyPairGenerator.GenerateKeyPair();
certificateGenerator.SetPublicKey(subjectKeyPair.Public);
@@ -104,7 +104,7 @@ namespace Kyoo.Authentication
X509Certificate bouncyCert = certificateGenerator.Generate(signatureFactory);
Pkcs12Store store = new Pkcs12StoreBuilder().Build();
- store.SetKeyEntry("Kyoo_key", new AsymmetricKeyEntry(subjectKeyPair.Private), new []
+ store.SetKeyEntry("Kyoo_key", new AsymmetricKeyEntry(subjectKeyPair.Private), new[]
{
new X509CertificateEntry(bouncyCert)
});
diff --git a/Kyoo.Authentication/Controllers/PremissionValidator.cs b/Kyoo.Authentication/Controllers/PremissionValidator.cs
index d34f5e57..05ef1a16 100644
--- a/Kyoo.Authentication/Controllers/PremissionValidator.cs
+++ b/Kyoo.Authentication/Controllers/PremissionValidator.cs
@@ -15,7 +15,7 @@ namespace Kyoo.Authentication
{
///
/// A permission validator to validate permission with user Permission array
- /// or the default array from the configurations if the user is not logged.
+ /// or the default array from the configurations if the user is not logged.
///
public class PermissionValidatorFactory : IPermissionValidator
{
@@ -38,7 +38,7 @@ namespace Kyoo.Authentication
{
return new PermissionValidator(attribute.Type, attribute.Kind, attribute.Group, _options);
}
-
+
///
public IFilterMetadata Create(PartialPermissionAttribute attribute)
{
@@ -149,4 +149,4 @@ namespace Kyoo.Authentication
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Kyoo.Authentication/Extensions.cs b/Kyoo.Authentication/Extensions.cs
index ca37cd09..2a6b734b 100644
--- a/Kyoo.Authentication/Extensions.cs
+++ b/Kyoo.Authentication/Extensions.cs
@@ -37,7 +37,7 @@ namespace Kyoo.Authentication
return new(user.ID.ToString())
{
DisplayName = user.Username,
- AdditionalClaims = new[] {new Claim("permissions", string.Join(',', user.Permissions))}
+ AdditionalClaims = new[] { new Claim("permissions", string.Join(',', user.Permissions)) }
};
}
diff --git a/Kyoo.Authentication/Models/DTO/AccountUpdateRequest.cs b/Kyoo.Authentication/Models/DTO/AccountUpdateRequest.cs
index ac135799..0ad32d47 100644
--- a/Kyoo.Authentication/Models/DTO/AccountUpdateRequest.cs
+++ b/Kyoo.Authentication/Models/DTO/AccountUpdateRequest.cs
@@ -13,13 +13,13 @@ namespace Kyoo.Authentication.Models.DTO
///
[EmailAddress(ErrorMessage = "The email is invalid.")]
public string Email { get; set; }
-
+
///
/// The new username of the user.
///
[MinLength(4, ErrorMessage = "The username must have at least 4 characters")]
public string Username { get; set; }
-
+
///
/// The picture icon.
///
diff --git a/Kyoo.Authentication/Models/DTO/LoginRequest.cs b/Kyoo.Authentication/Models/DTO/LoginRequest.cs
index 9bee4e04..14f1badf 100644
--- a/Kyoo.Authentication/Models/DTO/LoginRequest.cs
+++ b/Kyoo.Authentication/Models/DTO/LoginRequest.cs
@@ -9,17 +9,17 @@ namespace Kyoo.Authentication.Models.DTO
/// The user's username.
///
public string Username { get; set; }
-
+
///
/// The user's password.
///
public string Password { get; set; }
-
+
///
/// Should the user stay logged in? If true a cookie will be put.
///
public bool StayLoggedIn { get; set; }
-
+
///
/// The return url of the login flow.
///
diff --git a/Kyoo.Authentication/Models/DTO/OtacRequest.cs b/Kyoo.Authentication/Models/DTO/OtacRequest.cs
index 0c007f78..36eb4e56 100644
--- a/Kyoo.Authentication/Models/DTO/OtacRequest.cs
+++ b/Kyoo.Authentication/Models/DTO/OtacRequest.cs
@@ -9,7 +9,7 @@ namespace Kyoo.Authentication.Models.DTO
/// The One Time Access Code
///
public string Otac { get; set; }
-
+
///
/// Should the user stay logged
///
diff --git a/Kyoo.Authentication/Models/DTO/RegisterRequest.cs b/Kyoo.Authentication/Models/DTO/RegisterRequest.cs
index 1e505bb7..5ba89f3b 100644
--- a/Kyoo.Authentication/Models/DTO/RegisterRequest.cs
+++ b/Kyoo.Authentication/Models/DTO/RegisterRequest.cs
@@ -15,13 +15,13 @@ namespace Kyoo.Authentication.Models.DTO
///
[EmailAddress(ErrorMessage = "The email must be a valid email address")]
public string Email { get; set; }
-
+
///
/// The user's username.
///
[MinLength(4, ErrorMessage = "The username must have at least {1} characters")]
public string Username { get; set; }
-
+
///
/// The user's password.
///
@@ -44,5 +44,5 @@ namespace Kyoo.Authentication.Models.DTO
ExtraData = new Dictionary()
};
}
- }
+ }
}
\ No newline at end of file
diff --git a/Kyoo.Authentication/Models/IdentityContext.cs b/Kyoo.Authentication/Models/IdentityContext.cs
index e6ca3353..013fa6e5 100644
--- a/Kyoo.Authentication/Models/IdentityContext.cs
+++ b/Kyoo.Authentication/Models/IdentityContext.cs
@@ -42,11 +42,11 @@ namespace Kyoo.Authentication
AllowedGrantTypes = GrantTypes.Code,
RequirePkce = true,
RequireClientSecret = false,
-
+
AllowAccessTokensViaBrowser = true,
AllowOfflineAccess = true,
RequireConsent = false,
-
+
AllowedScopes = { "openid", "profile", "kyoo.read", "kyoo.write", "kyoo.play", "kyoo.admin" },
RedirectUris = { "/", "/silent.html" },
PostLogoutRedirectUris = { "/logout" }
@@ -84,7 +84,7 @@ namespace Kyoo.Authentication
}
};
}
-
+
///
/// The list of APIs (this is used to create Audiences)
///
diff --git a/Kyoo.Authentication/Models/Options/AuthenticationOption.cs b/Kyoo.Authentication/Models/Options/AuthenticationOption.cs
index 23e917aa..df22a323 100644
--- a/Kyoo.Authentication/Models/Options/AuthenticationOption.cs
+++ b/Kyoo.Authentication/Models/Options/AuthenticationOption.cs
@@ -14,12 +14,12 @@ namespace Kyoo.Authentication.Models
/// The options for certificates
///
public CertificateOption Certificate { get; set; }
-
+
///
/// Options for permissions
///
public PermissionOption Permissions { get; set; }
-
+
///
/// Root path of user's profile pictures.
///
diff --git a/Kyoo.Authentication/Models/Options/CertificateOption.cs b/Kyoo.Authentication/Models/Options/CertificateOption.cs
index 93d2a878..41eba09a 100644
--- a/Kyoo.Authentication/Models/Options/CertificateOption.cs
+++ b/Kyoo.Authentication/Models/Options/CertificateOption.cs
@@ -9,7 +9,7 @@ namespace Kyoo.Authentication.Models
/// The path to get this option from the root configuration.
///
public const string Path = "authentication:certificate";
-
+
///
/// The path of the certificate file.
///
diff --git a/Kyoo.Authentication/Models/Options/PermissionOption.cs b/Kyoo.Authentication/Models/Options/PermissionOption.cs
index 8d6c698d..f6098110 100644
--- a/Kyoo.Authentication/Models/Options/PermissionOption.cs
+++ b/Kyoo.Authentication/Models/Options/PermissionOption.cs
@@ -14,7 +14,7 @@ namespace Kyoo.Authentication.Models
/// The default permissions that will be given to a non-connected user.
///
public string[] Default { get; set; }
-
+
///
/// Permissions applied to a new user.
///
diff --git a/Kyoo.Authentication/Views/AccountApi.cs b/Kyoo.Authentication/Views/AccountApi.cs
index 1e369e31..4c496632 100644
--- a/Kyoo.Authentication/Views/AccountApi.cs
+++ b/Kyoo.Authentication/Views/AccountApi.cs
@@ -57,8 +57,8 @@ namespace Kyoo.Authentication.Views
_files = files;
_options = options;
}
-
-
+
+
///
/// Register a new user and return a OTAC to connect to it.
///
@@ -78,10 +78,10 @@ namespace Kyoo.Authentication.Views
}
catch (DuplicatedItemException)
{
- return Conflict(new {Errors = new {Duplicate = new[] {"A user with this name already exists"}}});
+ return Conflict(new { Errors = new { Duplicate = new[] { "A user with this name already exists" } } });
}
- return Ok(new {Otac = user.ExtraData["otac"]});
+ return Ok(new { Otac = user.ExtraData["otac"] });
}
///
@@ -99,7 +99,7 @@ namespace Kyoo.Authentication.Views
ExpiresUtc = DateTimeOffset.UtcNow.AddMonths(1)
};
}
-
+
///
/// Login the user.
///
@@ -117,7 +117,7 @@ namespace Kyoo.Authentication.Views
await HttpContext.SignInAsync(user.ToIdentityUser(), StayLogged(login.StayLoggedIn));
return Ok(new { RedirectUrl = login.ReturnURL, IsOk = true });
}
-
+
///
/// Use a OTAC to login a user.
///
@@ -127,22 +127,23 @@ namespace Kyoo.Authentication.Views
{
// TODO once hstore (Dictionary accessor) are supported, use them.
// We retrieve all users, this is inefficient.
- User user = (await _users.GetAll()).FirstOrDefault(x => x.ExtraData.GetValueOrDefault("otac") == otac.Otac);
+ User user = (await _users.GetAll()).FirstOrDefault(x => x.ExtraData.GetValueOrDefault("otac") == otac.Otac);
if (user == null)
return Unauthorized();
if (DateTime.ParseExact(user.ExtraData["otac-expire"], "s", CultureInfo.InvariantCulture) <=
- DateTime.UtcNow)
+ DateTime.UtcNow)
{
return BadRequest(new
{
- code = "ExpiredOTAC", description = "The OTAC has expired. Try to login with your password."
+ code = "ExpiredOTAC",
+ description = "The OTAC has expired. Try to login with your password."
});
}
-
+
await HttpContext.SignInAsync(user.ToIdentityUser(), StayLogged(otac.StayLoggedIn));
return Ok();
}
-
+
///
/// Sign out an user
///
@@ -170,7 +171,7 @@ namespace Kyoo.Authentication.Views
User user = await _users.GetOrDefault(int.Parse(context.Subject.GetSubjectId()));
context.IsActive = user != null;
}
-
+
///
/// Get the user's profile picture.
///
@@ -185,7 +186,7 @@ namespace Kyoo.Authentication.Views
string path = Path.Combine(_options.Value.ProfilePicturePath, user.ID.ToString());
return _files.FileResult(path);
}
-
+
///
/// Update profile information (email, username, profile picture...)
///
diff --git a/Kyoo.Core/Application.cs b/Kyoo.Core/Application.cs
index d3a2553f..643aa89c 100644
--- a/Kyoo.Core/Application.cs
+++ b/Kyoo.Core/Application.cs
@@ -32,7 +32,7 @@ namespace Kyoo.Core
/// Should the application restart after a shutdown?
///
private bool _shouldRestart;
-
+
///
/// The cancellation token source used to allow the app to be shutdown or restarted.
///
@@ -48,7 +48,7 @@ namespace Kyoo.Core
///
private ILogger _logger;
-
+
///
/// Create a new that will use the specified environment.
///
@@ -80,28 +80,28 @@ namespace Kyoo.Core
public async Task Start(string[] args, Action configure)
{
_dataDir = _SetupDataDir(args);
-
+
LoggerConfiguration config = new();
_ConfigureLogging(config, null, null);
Log.Logger = config.CreateBootstrapLogger();
_logger = Log.Logger.ForContext();
AppDomain.CurrentDomain.ProcessExit += (_, _) => Log.CloseAndFlush();
- AppDomain.CurrentDomain.UnhandledException += (_, ex)
+ AppDomain.CurrentDomain.UnhandledException += (_, ex)
=> Log.Fatal(ex.ExceptionObject as Exception, "Unhandled exception");
-
+
do
{
IHost host = _CreateWebHostBuilder(args)
.ConfigureContainer(configure)
.Build();
-
+
_tokenSource = new CancellationTokenSource();
await _StartWithHost(host, _tokenSource.Token);
- }
+ }
while (_shouldRestart);
}
-
+
///
public void Shutdown()
{
@@ -155,7 +155,7 @@ namespace Kyoo.Core
.AddCommandLine(args)
.Build();
- string path = parsed.GetValue("datadir")
+ string path = parsed.GetValue("datadir")
?? Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Kyoo");
if (!Directory.Exists(path))
@@ -165,7 +165,7 @@ namespace Kyoo.Core
if (!File.Exists(GetConfigFile()))
File.Copy(Path.Join(AppDomain.CurrentDomain.BaseDirectory, GetConfigFile()),
GetConfigFile());
-
+
return path;
}
@@ -217,7 +217,7 @@ namespace Kyoo.Core
.UseStartup(host => PluginsStartup.FromWebHost(host, new LoggerFactory().AddSerilog()))
);
}
-
+
///
/// Register settings.json, environment variables and command lines arguments as configuration.
///
diff --git a/Kyoo.Core/Controllers/ConfigurationManager.cs b/Kyoo.Core/Controllers/ConfigurationManager.cs
index 7f5432f1..88927d76 100644
--- a/Kyoo.Core/Controllers/ConfigurationManager.cs
+++ b/Kyoo.Core/Controllers/ConfigurationManager.cs
@@ -17,7 +17,7 @@ namespace Kyoo.Core.Controllers
public class ConfigurationManager : IConfigurationManager
{
///
- /// The configuration to retrieve and edit.
+ /// The configuration to retrieve and edit.
///
private readonly IConfiguration _configuration;
@@ -58,7 +58,7 @@ namespace Kyoo.Core.Controllers
ConfigurationReference config = ConfigurationReference.CreateUntyped(path);
_references.Add(config.Path, config.Type);
}
-
+
///
public void Register(string path, Type type)
{
@@ -98,7 +98,7 @@ namespace Kyoo.Core.Controllers
throw new ArgumentException($"The configuration at {path} is not editable or readable.");
throw new ItemNotFoundException($"No configuration exists for the name: {path}");
}
-
+
///
public object GetValue(string path)
{
@@ -124,7 +124,7 @@ namespace Kyoo.Core.Controllers
$"a resource of type {type.Name}.");
return (T)GetValue(path);
}
-
+
///
public async Task EditValue(string path, object value)
{
@@ -133,7 +133,7 @@ namespace Kyoo.Core.Controllers
value = JObject.FromObject(value).ToObject(type);
if (value == null)
throw new ArgumentException("Invalid value format.");
-
+
ExpandoObject config = _ToObject(_configuration);
IDictionary configDic = config;
configDic[path] = value;
@@ -141,7 +141,7 @@ namespace Kyoo.Core.Controllers
await using StreamWriter writer = new(_application.GetConfigFile());
await writer.WriteAsync(obj.ToString());
}
-
+
///
/// Transform a configuration to a strongly typed object (the root configuration is an
/// but child elements are using strong types.
@@ -169,7 +169,7 @@ namespace Kyoo.Core.Controllers
continue;
}
}
-
+
return obj;
}
@@ -192,4 +192,4 @@ namespace Kyoo.Core.Controllers
return obj;
}
}
-}
\ No newline at end of file
+}
diff --git a/Kyoo.Core/Controllers/FileSystems/FileSystemComposite.cs b/Kyoo.Core/Controllers/FileSystems/FileSystemComposite.cs
index 4a715602..2b637051 100644
--- a/Kyoo.Core/Controllers/FileSystems/FileSystemComposite.cs
+++ b/Kyoo.Core/Controllers/FileSystems/FileSystemComposite.cs
@@ -31,12 +31,12 @@ namespace Kyoo.Core.Controllers
/// (only if the option is set to metadata in show)
///
private readonly ILibraryManager _libraryManager;
-
+
///
/// Options to check if the metadata should be kept in the show directory or in a kyoo's directory.
///
private readonly IOptionsMonitor _options;
-
+
///
/// Create a new from a list of mapped to their
/// metadata.
@@ -45,7 +45,7 @@ namespace Kyoo.Core.Controllers
/// The library manager used to load shows to retrieve their path.
/// The options to use.
public FileSystemComposite(ICollection , FileSystemMetadataAttribute>> fileSystems,
- ILibraryManager libraryManager,
+ ILibraryManager libraryManager,
IOptionsMonitor options)
{
_fileSystems = fileSystems;
@@ -53,7 +53,7 @@ namespace Kyoo.Core.Controllers
_options = options;
}
-
+
///
/// Retrieve the file system that should be used for a given path.
///
@@ -159,7 +159,7 @@ namespace Kyoo.Core.Controllers
return _GetFileSystemForPath(path, out string relativePath)
.Exists(relativePath);
}
-
+
///
public async Task GetExtraDirectory(T resource)
{
@@ -191,7 +191,7 @@ namespace Kyoo.Core.Controllers
Season season => await GetExtraDirectory(season.Show),
Episode episode => await GetExtraDirectory(episode.Show),
Track track => await GetExtraDirectory(track.Episode),
- IResource res => Combine(_options.CurrentValue.MetadataPath,
+ IResource res => Combine(_options.CurrentValue.MetadataPath,
typeof(T).Name.ToLowerInvariant(), res.Slug),
_ => Combine(_options.CurrentValue.MetadataPath, typeof(T).Name.ToLowerInvariant())
};
diff --git a/Kyoo.Core/Controllers/FileSystems/HttpFileSystem.cs b/Kyoo.Core/Controllers/FileSystems/HttpFileSystem.cs
index 0b5618fa..fb09db8e 100644
--- a/Kyoo.Core/Controllers/FileSystems/HttpFileSystem.cs
+++ b/Kyoo.Core/Controllers/FileSystems/HttpFileSystem.cs
@@ -14,7 +14,7 @@ namespace Kyoo.Core.Controllers
///
/// A for http/https links.
///
- [FileSystemMetadata(new [] {"http", "https"})]
+ [FileSystemMetadata(new[] { "http", "https" })]
public class HttpFileSystem : IFileSystem
{
///
@@ -30,8 +30,8 @@ namespace Kyoo.Core.Controllers
{
_clientFactory = factory;
}
-
-
+
+
///
public IActionResult FileResult(string path, bool rangeSupport = false, string type = null)
{
@@ -46,7 +46,7 @@ namespace Kyoo.Core.Controllers
HttpClient client = _clientFactory.CreateClient();
return client.GetStreamAsync(path);
}
-
+
///
public async Task GetReader(string path, AsyncRef mime)
{
diff --git a/Kyoo.Core/Controllers/FileSystems/LocalFileSystem.cs b/Kyoo.Core/Controllers/FileSystems/LocalFileSystem.cs
index 3c75717f..d70a1f0c 100644
--- a/Kyoo.Core/Controllers/FileSystems/LocalFileSystem.cs
+++ b/Kyoo.Core/Controllers/FileSystems/LocalFileSystem.cs
@@ -15,7 +15,7 @@ namespace Kyoo.Core.Controllers
///
/// A for the local filesystem (using System.IO).
///
- [FileSystemMetadata(new [] {"", "file"}, StripScheme = true)]
+ [FileSystemMetadata(new[] { "", "file" }, StripScheme = true)]
public class LocalFileSystem : IFileSystem
{
///
@@ -51,7 +51,7 @@ namespace Kyoo.Core.Controllers
return contentType;
throw new NotImplementedException($"Can't get the content type of the file at: {path}");
}
-
+
///
public IActionResult FileResult(string path, bool rangeSupport = false, string type = null)
{
@@ -72,7 +72,7 @@ namespace Kyoo.Core.Controllers
throw new ArgumentNullException(nameof(path));
return Task.FromResult(File.OpenRead(path));
}
-
+
///
public Task GetReader(string path, AsyncRef mime)
{
@@ -99,19 +99,19 @@ namespace Kyoo.Core.Controllers
Directory.CreateDirectory(path);
return Task.FromResult(path);
}
-
+
///
public string Combine(params string[] paths)
{
return Path.Combine(paths);
}
-
+
///
public Task> ListFiles(string path, SearchOption options = SearchOption.TopDirectoryOnly)
{
if (path == null)
throw new ArgumentNullException(nameof(path));
- string[] ret = Directory.Exists(path)
+ string[] ret = Directory.Exists(path)
? Directory.GetFiles(path, "*", options)
: Array.Empty();
return Task.FromResult>(ret);
@@ -122,7 +122,7 @@ namespace Kyoo.Core.Controllers
{
return Task.FromResult(File.Exists(path) || Directory.Exists(path));
}
-
+
///
public Task GetExtraDirectory(T resource)
{
diff --git a/Kyoo.Core/Controllers/LibraryManager.cs b/Kyoo.Core/Controllers/LibraryManager.cs
index e7759f0a..374dac89 100644
--- a/Kyoo.Core/Controllers/LibraryManager.cs
+++ b/Kyoo.Core/Controllers/LibraryManager.cs
@@ -16,7 +16,7 @@ namespace Kyoo.Core.Controllers
/// The list of repositories
///
private readonly IBaseRepository[] _repositories;
-
+
///
public ILibraryRepository LibraryRepository { get; }
///
@@ -41,8 +41,8 @@ namespace Kyoo.Core.Controllers
public IProviderRepository ProviderRepository { get; }
///
public IUserRepository UserRepository { get; }
-
-
+
+
///
/// Create a new instance with every repository available.
///
@@ -82,7 +82,7 @@ namespace Kyoo.Core.Controllers
}
///
- public Task Get(string slug)
+ public Task Get(string slug)
where T : class, IResource
{
return GetRepository().Get(slug);
@@ -120,19 +120,19 @@ namespace Kyoo.Core.Controllers
}
///
- public async Task GetOrDefault(int id)
+ public async Task GetOrDefault(int id)
where T : class, IResource
{
return await GetRepository().GetOrDefault(id);
}
-
+
///
- public async Task GetOrDefault(string slug)
+ public async Task GetOrDefault(string slug)
where T : class, IResource
{
return await GetRepository().GetOrDefault(slug);
}
-
+
///
public async Task GetOrDefault(Expression> where)
where T : class, IResource
@@ -145,19 +145,19 @@ namespace Kyoo.Core.Controllers
{
return await SeasonRepository.GetOrDefault(showID, seasonNumber);
}
-
+
///
public async Task GetOrDefault(string showSlug, int seasonNumber)
{
return await SeasonRepository.GetOrDefault(showSlug, seasonNumber);
}
-
+
///
public async Task GetOrDefault(int showID, int seasonNumber, int episodeNumber)
{
return await EpisodeRepository.GetOrDefault(showID, seasonNumber, episodeNumber);
}
-
+
///
public async Task GetOrDefault(string showSlug, int seasonNumber, int episodeNumber)
{
@@ -173,9 +173,9 @@ namespace Kyoo.Core.Controllers
/// A setter function to store the owner of a releated object loaded
/// The type of the owner object
/// The type of the related object
- private static async Task SetRelation(T1 obj,
- Task> loader,
- Action> setter,
+ private static async Task SetRelation(T1 obj,
+ Task> loader,
+ Action> setter,
Action inverse)
{
ICollection loaded = await loader;
@@ -230,61 +230,61 @@ namespace Kyoo.Core.Controllers
(Library l, nameof(Library.Providers)) => ProviderRepository
.GetAll(x => x.Libraries.Any(y => y.ID == obj.ID))
.Then(x => l.Providers = x),
-
+
(Library l, nameof(Library.Shows)) => ShowRepository
.GetAll(x => x.Libraries.Any(y => y.ID == obj.ID))
- .Then(x => l.Shows = x),
-
+ .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.ExternalIDs)) => SetRelation(c,
+ .Then(x => l.Collections = x),
+
+
+ (Collection c, nameof(Collection.ExternalIDs)) => SetRelation(c,
ProviderRepository.GetMetadataID(x => x.ResourceID == obj.ID),
(x, y) => x.ExternalIDs = y,
(x, y) => { x.ResourceID = y.ID; }),
-
+
(Collection c, nameof(Collection.Shows)) => ShowRepository
.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.ExternalIDs)) => SetRelation(s,
+ .Then(x => c.Libraries = x),
+
+
+ (Show s, nameof(Show.ExternalIDs)) => SetRelation(s,
ProviderRepository.GetMetadataID(x => x.ResourceID == obj.ID),
(x, y) => x.ExternalIDs = y,
(x, y) => { x.ResourceID = y.ID; }),
-
+
(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
.GetFromShow(obj.ID)
.Then(x => s.People = x),
-
- (Show s, nameof(Show.Seasons)) => SetRelation(s,
+
+ (Show s, nameof(Show.Seasons)) => SetRelation(s,
SeasonRepository.GetAll(x => x.Show.ID == obj.ID),
(x, y) => x.Seasons = y,
(x, y) => { x.Show = y; x.ShowID = y.ID; }),
-
- (Show s, nameof(Show.Episodes)) => SetRelation(s,
+
+ (Show s, nameof(Show.Episodes)) => SetRelation(s,
EpisodeRepository.GetAll(x => x.Show.ID == obj.ID),
(x, y) => x.Episodes = y,
(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
.GetAll(x => x.Shows.Any(y => y.ID == obj.ID))
.Then(x => s.Collections = x),
-
+
(Show s, nameof(Show.Studio)) => StudioRepository
.GetOrDefault(x => x.Shows.Any(y => y.ID == obj.ID))
.Then(x =>
@@ -292,18 +292,18 @@ namespace Kyoo.Core.Controllers
s.Studio = x;
s.StudioID = x?.ID ?? 0;
}),
-
-
- (Season s, nameof(Season.ExternalIDs)) => SetRelation(s,
+
+
+ (Season s, nameof(Season.ExternalIDs)) => SetRelation(s,
ProviderRepository.GetMetadataID(x => x.ResourceID == obj.ID),
(x, y) => x.ExternalIDs = y,
(x, y) => { x.ResourceID = y.ID; }),
-
- (Season s, nameof(Season.Episodes)) => SetRelation(s,
+
+ (Season s, nameof(Season.Episodes)) => SetRelation(s,
EpisodeRepository.GetAll(x => x.Season.ID == obj.ID),
(x, y) => x.Episodes = y,
(x, y) => { x.Season = y; x.SeasonID = y.ID; }),
-
+
(Season s, nameof(Season.Show)) => ShowRepository
.GetOrDefault(x => x.Seasons.Any(y => y.ID == obj.ID))
.Then(x =>
@@ -311,18 +311,18 @@ namespace Kyoo.Core.Controllers
s.Show = x;
s.ShowID = x?.ID ?? 0;
}),
-
-
- (Episode e, nameof(Episode.ExternalIDs)) => SetRelation(e,
- ProviderRepository.GetMetadataID(x => x.ResourceID == obj.ID),
+
+
+ (Episode e, nameof(Episode.ExternalIDs)) => SetRelation(e,
+ ProviderRepository.GetMetadataID(x => x.ResourceID == obj.ID),
(x, y) => x.ExternalIDs = y,
(x, y) => { x.ResourceID = y.ID; }),
-
- (Episode e, nameof(Episode.Tracks)) => SetRelation(e,
+
+ (Episode e, nameof(Episode.Tracks)) => SetRelation(e,
TrackRepository.GetAll(x => x.Episode.ID == obj.ID),
(x, y) => x.Tracks = y,
(x, y) => { x.Episode = y; x.EpisodeID = y.ID; }),
-
+
(Episode e, nameof(Episode.Show)) => ShowRepository
.GetOrDefault(x => x.Episodes.Any(y => y.ID == obj.ID))
.Then(x =>
@@ -330,7 +330,7 @@ namespace Kyoo.Core.Controllers
e.Show = x;
e.ShowID = x?.ID ?? 0;
}),
-
+
(Episode e, nameof(Episode.Season)) => SeasonRepository
.GetOrDefault(x => x.Episodes.Any(y => y.ID == e.ID))
.Then(x =>
@@ -338,8 +338,8 @@ namespace Kyoo.Core.Controllers
e.Season = x;
e.SeasonID = x?.ID ?? 0;
}),
-
-
+
+
(Track t, nameof(Track.Episode)) => EpisodeRepository
.GetOrDefault(x => x.Tracks.Any(y => y.ID == obj.ID))
.Then(x =>
@@ -347,62 +347,62 @@ namespace Kyoo.Core.Controllers
t.Episode = x;
t.EpisodeID = x?.ID ?? 0;
}),
-
-
+
+
(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
.GetAll(x => x.Studio.ID == obj.ID)
.Then(x => s.Shows = x),
-
- (Studio s, nameof(Studio.ExternalIDs)) => SetRelation(s,
+
+ (Studio s, nameof(Studio.ExternalIDs)) => SetRelation(s,
ProviderRepository.GetMetadataID(x => x.ResourceID == obj.ID),
(x, y) => x.ExternalIDs = y,
(x, y) => { x.ResourceID = y.ID; }),
-
-
- (People p, nameof(People.ExternalIDs)) => SetRelation(p,
+
+
+ (People p, nameof(People.ExternalIDs)) => SetRelation(p,
ProviderRepository.GetMetadataID(x => x.ResourceID == obj.ID),
(x, y) => x.ExternalIDs = y,
(x, y) => { x.ResourceID = y.ID; }),
-
+
(People p, nameof(People.Roles)) => PeopleRepository
.GetFromPeople(obj.ID)
.Then(x => p.Roles = x),
-
-
+
+
(Provider p, nameof(Provider.Libraries)) => LibraryRepository
.GetAll(x => x.Providers.Any(y => y.ID == obj.ID))
.Then(x => p.Libraries = x),
-
+
_ => throw new ArgumentException($"Couldn't find a way to load {memberName} of {obj.Slug}.")
};
}
///
- public Task> GetItemsFromLibrary(int id,
- Expression> where = null,
- Sort sort = default,
+ public Task> GetItemsFromLibrary(int id,
+ Expression> where = null,
+ Sort sort = default,
Pagination limit = default)
{
return LibraryItemRepository.GetFromLibrary(id, where, sort, limit);
}
///
- public Task> GetItemsFromLibrary(string slug,
- Expression> where = null,
- Sort sort = default,
+ public Task> GetItemsFromLibrary(string slug,
+ Expression> where = null,
+ Sort sort = default,
Pagination limit = default)
{
return LibraryItemRepository.GetFromLibrary(slug, where, sort, limit);
}
///
- public Task> GetPeopleFromShow(int showID,
+ public Task> GetPeopleFromShow(int showID,
Expression> where = null,
Sort sort = default,
Pagination limit = default)
@@ -411,16 +411,16 @@ namespace Kyoo.Core.Controllers
}
///
- public Task> GetPeopleFromShow(string showSlug,
+ public Task> GetPeopleFromShow(string showSlug,
Expression> where = null,
- Sort sort = default,
+ Sort sort = default,
Pagination limit = default)
{
return PeopleRepository.GetFromShow(showSlug, where, sort, limit);
}
///
- public Task> GetRolesFromPeople(int id,
+ public Task> GetRolesFromPeople(int id,
Expression> where = null,
Sort sort = default,
Pagination limit = default)
@@ -454,7 +454,7 @@ namespace Kyoo.Core.Controllers
///
public Task> GetAll(Expression> where = null,
Sort sort = default,
- Pagination limit = default)
+ Pagination limit = default)
where T : class, IResource
{
return GetRepository().GetAll(where, sort, limit);
@@ -468,19 +468,19 @@ namespace Kyoo.Core.Controllers
}
///
- public Task> Search(string query)
+ public Task> Search(string query)
where T : class, IResource
{
return GetRepository().Search(query);
}
///
- public Task Create(T item)
+ public Task Create(T item)
where T : class, IResource
{
return GetRepository().Create(item);
}
-
+
///
public Task CreateIfNotExists(T item)
where T : class, IResource
@@ -496,21 +496,21 @@ namespace Kyoo.Core.Controllers
}
///
- public Task Delete(T item)
+ public Task Delete(T item)
where T : class, IResource
{
return GetRepository().Delete(item);
}
///
- public Task Delete(int id)
+ public Task Delete(int id)
where T : class, IResource
{
return GetRepository().Delete(id);
}
///
- public Task Delete(string slug)
+ public Task Delete(string slug)
where T : class, IResource
{
return GetRepository().Delete(slug);
diff --git a/Kyoo.Core/Controllers/PassthroughPermissionValidator.cs b/Kyoo.Core/Controllers/PassthroughPermissionValidator.cs
index 914835bf..ff9b07aa 100644
--- a/Kyoo.Core/Controllers/PassthroughPermissionValidator.cs
+++ b/Kyoo.Core/Controllers/PassthroughPermissionValidator.cs
@@ -14,7 +14,7 @@ namespace Kyoo.Core.Controllers
{
logger.LogWarning("No permission validator has been enabled, all users will have all permissions");
}
-
+
///
public IFilterMetadata Create(PermissionAttribute attribute)
{
diff --git a/Kyoo.Core/Controllers/PluginManager.cs b/Kyoo.Core/Controllers/PluginManager.cs
index 7fc2c6cf..77c00924 100644
--- a/Kyoo.Core/Controllers/PluginManager.cs
+++ b/Kyoo.Core/Controllers/PluginManager.cs
@@ -30,7 +30,7 @@ namespace Kyoo.Core.Controllers
/// The logger used by this class.
///
private readonly ILogger _logger;
-
+
///
/// The list of plugins that are currently loaded.
///
@@ -93,7 +93,7 @@ namespace Kyoo.Core.Controllers
return Array.Empty();
}
}
-
+
///
public void LoadPlugins(ICollection plugins)
{
diff --git a/Kyoo.Core/Controllers/ProviderComposite.cs b/Kyoo.Core/Controllers/ProviderComposite.cs
index 1032b022..d804860f 100644
--- a/Kyoo.Core/Controllers/ProviderComposite.cs
+++ b/Kyoo.Core/Controllers/ProviderComposite.cs
@@ -40,7 +40,7 @@ namespace Kyoo.Core.Controllers
_providers = providers.ToArray();
_logger = logger;
}
-
+
///
public override void UseProviders(IEnumerable providers)
@@ -71,9 +71,9 @@ namespace Kyoo.Core.Controllers
{
ret = Merger.Merge(ret, await provider.Get(ret));
}
- catch (Exception ex)
+ catch (Exception ex)
{
- _logger.LogError(ex, "The provider {Provider} could not get a {Type}",
+ _logger.LogError(ex, "The provider {Provider} could not get a {Type}",
provider.Provider.Name, typeof(T).Name);
}
}
@@ -85,16 +85,16 @@ namespace Kyoo.Core.Controllers
public override async Task> Search(string query)
{
List ret = new();
-
+
foreach (IMetadataProvider provider in _GetProviders())
{
try
{
ret.AddRange(await provider.Search(query));
}
- catch (Exception ex)
+ catch (Exception ex)
{
- _logger.LogError(ex, "The provider {Provider} could not search for {Type}",
+ _logger.LogError(ex, "The provider {Provider} could not search for {Type}",
provider.Provider.Name, typeof(T).Name);
}
}
diff --git a/Kyoo.Core/Controllers/RegexIdentifier.cs b/Kyoo.Core/Controllers/RegexIdentifier.cs
index 1032d4bb..c3da511a 100644
--- a/Kyoo.Core/Controllers/RegexIdentifier.cs
+++ b/Kyoo.Core/Controllers/RegexIdentifier.cs
@@ -53,7 +53,7 @@ namespace Kyoo.Core.Controllers
.FirstOrDefault();
return path[(libraryPath?.Length ?? 0)..];
}
-
+
///
public async Task<(Collection, Show, Season, Episode)> Identify(string path)
{
@@ -77,21 +77,21 @@ namespace Kyoo.Core.Controllers
Slug = Utility.ToSlug(match.Groups["Show"].Value),
Title = match.Groups["Show"].Value,
Path = Path.GetDirectoryName(path),
- StartAir = match.Groups["StartYear"].Success
- ? new DateTime(int.Parse(match.Groups["StartYear"].Value), 1, 1)
+ StartAir = match.Groups["StartYear"].Success
+ ? new DateTime(int.Parse(match.Groups["StartYear"].Value), 1, 1)
: null
},
season: null,
episode: new Episode
{
- SeasonNumber = match.Groups["Season"].Success
- ? int.Parse(match.Groups["Season"].Value)
+ SeasonNumber = match.Groups["Season"].Success
+ ? int.Parse(match.Groups["Season"].Value)
: null,
- EpisodeNumber = match.Groups["Episode"].Success
- ? int.Parse(match.Groups["Episode"].Value)
+ EpisodeNumber = match.Groups["Episode"].Success
+ ? int.Parse(match.Groups["Episode"].Value)
: null,
- AbsoluteNumber = match.Groups["Absolute"].Success
- ? int.Parse(match.Groups["Absolute"].Value)
+ AbsoluteNumber = match.Groups["Absolute"].Success
+ ? int.Parse(match.Groups["Absolute"].Value)
: null,
Path = path
}
diff --git a/Kyoo.Core/Controllers/Repositories/CollectionRepository.cs b/Kyoo.Core/Controllers/Repositories/CollectionRepository.cs
index f6d1e220..d10b862c 100644
--- a/Kyoo.Core/Controllers/Repositories/CollectionRepository.cs
+++ b/Kyoo.Core/Controllers/Repositories/CollectionRepository.cs
@@ -19,12 +19,12 @@ namespace Kyoo.Core.Controllers
/// The database handle
///
private readonly DatabaseContext _database;
-
+
///
/// A provider repository to handle externalID creation and deletion
///
private readonly IProviderRepository _providers;
-
+
///
protected override Expression> DefaultSort => x => x.Name;
@@ -58,12 +58,12 @@ namespace Kyoo.Core.Controllers
await _database.SaveChangesAsync($"Trying to insert a duplicated collection (slug {obj.Slug} already exists).");
return obj;
}
-
+
///
protected override async Task Validate(Collection resource)
{
await base.Validate(resource);
-
+
if (string.IsNullOrEmpty(resource.Slug))
throw new ArgumentException("The collection's slug must be set and not empty");
if (string.IsNullOrEmpty(resource.Name))
@@ -72,7 +72,7 @@ namespace Kyoo.Core.Controllers
if (resource.ExternalIDs != null)
{
foreach (MetadataID id in resource.ExternalIDs)
- {
+ {
id.Provider = _database.LocalEntity(id.Provider.Slug)
?? await _providers.CreateIfNotExists(id.Provider);
id.ProviderID = id.Provider.ID;
@@ -80,12 +80,12 @@ namespace Kyoo.Core.Controllers
_database.MetadataIds().AttachRange(resource.ExternalIDs);
}
}
-
+
///
protected override async Task EditRelations(Collection resource, Collection changed, bool resetOld)
{
await Validate(changed);
-
+
if (changed.ExternalIDs != null || resetOld)
{
await Database.Entry(resource).Collection(x => x.ExternalIDs).LoadAsync();
diff --git a/Kyoo.Core/Controllers/Repositories/EpisodeRepository.cs b/Kyoo.Core/Controllers/Repositories/EpisodeRepository.cs
index f19acdb2..05f6b86d 100644
--- a/Kyoo.Core/Controllers/Repositories/EpisodeRepository.cs
+++ b/Kyoo.Core/Controllers/Repositories/EpisodeRepository.cs
@@ -29,7 +29,7 @@ namespace Kyoo.Core.Controllers
/// A track repository to handle creation and deletion of tracks related to the current episode.
///
private readonly ITrackRepository _tracks;
-
+
///
protected override Expression> DefaultSort => x => x.EpisodeNumber;
@@ -42,27 +42,27 @@ namespace Kyoo.Core.Controllers
/// A track repository
public EpisodeRepository(DatabaseContext database,
IProviderRepository providers,
- ITrackRepository tracks)
+ ITrackRepository tracks)
: base(database)
{
_database = database;
_providers = providers;
_tracks = tracks;
}
-
+
///
public Task GetOrDefault(int showID, int seasonNumber, int episodeNumber)
{
- return _database.Episodes.FirstOrDefaultAsync(x => x.ShowID == showID
- && x.SeasonNumber == seasonNumber
+ return _database.Episodes.FirstOrDefaultAsync(x => x.ShowID == showID
+ && x.SeasonNumber == seasonNumber
&& x.EpisodeNumber == episodeNumber);
}
///
public Task GetOrDefault(string showSlug, int seasonNumber, int episodeNumber)
{
- return _database.Episodes.FirstOrDefaultAsync(x => x.Show.Slug == showSlug
- && x.SeasonNumber == seasonNumber
+ return _database.Episodes.FirstOrDefaultAsync(x => x.Show.Slug == showSlug
+ && x.SeasonNumber == seasonNumber
&& x.EpisodeNumber == episodeNumber);
}
@@ -87,14 +87,14 @@ namespace Kyoo.Core.Controllers
///
public Task GetAbsolute(int showID, int absoluteNumber)
{
- return _database.Episodes.FirstOrDefaultAsync(x => x.ShowID == showID
+ return _database.Episodes.FirstOrDefaultAsync(x => x.ShowID == showID
&& x.AbsoluteNumber == absoluteNumber);
}
///
public Task GetAbsolute(string showSlug, int absoluteNumber)
{
- return _database.Episodes.FirstOrDefaultAsync(x => x.Show.Slug == showSlug
+ return _database.Episodes.FirstOrDefaultAsync(x => x.Show.Slug == showSlug
&& x.AbsoluteNumber == absoluteNumber);
}
@@ -108,7 +108,7 @@ namespace Kyoo.Core.Controllers
.Take(20)
.ToListAsync();
}
-
+
///
public override async Task Create(Episode obj)
{
@@ -146,7 +146,7 @@ namespace Kyoo.Core.Controllers
{
if (resource.Tracks == null)
return resource;
-
+
resource.Tracks = await resource.Tracks.SelectAsync(x =>
{
x.Episode = resource;
@@ -156,7 +156,7 @@ namespace Kyoo.Core.Controllers
_database.Tracks.AttachRange(resource.Tracks);
return resource;
}
-
+
///
protected override async Task Validate(Episode resource)
{
@@ -180,17 +180,17 @@ namespace Kyoo.Core.Controllers
_database.MetadataIds().AttachRange(resource.ExternalIDs);
}
}
-
+
///
public override async Task Delete(Episode obj)
{
if (obj == null)
throw new ArgumentNullException(nameof(obj));
-
+
_database.Entry(obj).State = EntityState.Deleted;
await obj.Tracks.ForEachAsync(x => _tracks.Delete(x));
obj.ExternalIDs.ForEach(x => _database.Entry(x).State = EntityState.Deleted);
await _database.SaveChangesAsync();
}
}
-}
\ No newline at end of file
+}
diff --git a/Kyoo.Core/Controllers/Repositories/GenreRepository.cs b/Kyoo.Core/Controllers/Repositories/GenreRepository.cs
index f72b13e7..cb58406f 100644
--- a/Kyoo.Core/Controllers/Repositories/GenreRepository.cs
+++ b/Kyoo.Core/Controllers/Repositories/GenreRepository.cs
@@ -19,11 +19,11 @@ namespace Kyoo.Core.Controllers
/// The database handle
///
private readonly DatabaseContext _database;
-
+
///
protected override Expression> DefaultSort => x => x.Slug;
-
-
+
+
///
/// Create a new .
///
diff --git a/Kyoo.Core/Controllers/Repositories/LibraryItemRepository.cs b/Kyoo.Core/Controllers/Repositories/LibraryItemRepository.cs
index ba075c09..ad6d3958 100644
--- a/Kyoo.Core/Controllers/Repositories/LibraryItemRepository.cs
+++ b/Kyoo.Core/Controllers/Repositories/LibraryItemRepository.cs
@@ -34,7 +34,7 @@ namespace Kyoo.Core.Controllers
///
/// The database instance
/// A lazy loaded library repository
- public LibraryItemRepository(DatabaseContext database,
+ public LibraryItemRepository(DatabaseContext database,
Lazy libraries)
: base(database)
{
@@ -42,13 +42,13 @@ namespace Kyoo.Core.Controllers
_libraries = libraries;
}
-
+
///
public override Task GetOrDefault(int id)
{
return _database.LibraryItems.FirstOrDefaultAsync(x => x.ID == id);
}
-
+
///
public override Task GetOrDefault(string slug)
{
@@ -83,27 +83,27 @@ namespace Kyoo.Core.Controllers
}
///
- public override Task Create(LibraryItem obj)
+ public override Task Create(LibraryItem obj)
=> throw new InvalidOperationException();
-
+
///
- public override Task CreateIfNotExists(LibraryItem obj)
+ public override Task CreateIfNotExists(LibraryItem obj)
=> throw new InvalidOperationException();
-
+
///
- public override Task Edit(LibraryItem obj, bool resetOld)
+ public override Task Edit(LibraryItem obj, bool resetOld)
=> throw new InvalidOperationException();
-
+
///
- public override Task Delete(int id)
+ public override Task Delete(int id)
=> throw new InvalidOperationException();
-
+
///
- public override Task Delete(string slug)
+ public override Task Delete(string slug)
=> throw new InvalidOperationException();
-
+
///
- public override Task Delete(LibraryItem obj)
+ public override Task Delete(LibraryItem obj)
=> throw new InvalidOperationException();
///
@@ -125,8 +125,8 @@ namespace Kyoo.Core.Controllers
///
public async Task> GetFromLibrary(int id,
- Expression> where = null,
- Sort sort = default,
+ Expression> where = null,
+ Sort sort = default,
Pagination limit = default)
{
ICollection items = await ApplyFilters(LibraryRelatedQuery(x => x.ID == id),
@@ -137,11 +137,11 @@ namespace Kyoo.Core.Controllers
throw new ItemNotFoundException();
return items;
}
-
+
///
public async Task> GetFromLibrary(string slug,
- Expression> where = null,
- Sort sort = default,
+ Expression> where = null,
+ Sort sort = default,
Pagination limit = default)
{
ICollection items = await ApplyFilters(LibraryRelatedQuery(x => x.Slug == slug),
diff --git a/Kyoo.Core/Controllers/Repositories/LibraryRepository.cs b/Kyoo.Core/Controllers/Repositories/LibraryRepository.cs
index 1e835114..933a2c07 100644
--- a/Kyoo.Core/Controllers/Repositories/LibraryRepository.cs
+++ b/Kyoo.Core/Controllers/Repositories/LibraryRepository.cs
@@ -24,7 +24,7 @@ namespace Kyoo.Core.Controllers
/// A provider repository to handle externalID creation and deletion
///
private readonly IProviderRepository _providers;
-
+
///
protected override Expression> DefaultSort => x => x.ID;
@@ -41,7 +41,7 @@ namespace Kyoo.Core.Controllers
_providers = providers;
}
-
+
///
public override async Task> Search(string query)
{
@@ -65,14 +65,14 @@ namespace Kyoo.Core.Controllers
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.");
-
+
if (resource.Providers != null)
{
resource.Providers = await resource.Providers
@@ -99,7 +99,7 @@ namespace Kyoo.Core.Controllers
{
if (obj == null)
throw new ArgumentNullException(nameof(obj));
-
+
_database.Entry(obj).State = EntityState.Deleted;
await _database.SaveChangesAsync();
}
diff --git a/Kyoo.Core/Controllers/Repositories/LocalRepository.cs b/Kyoo.Core/Controllers/Repositories/LocalRepository.cs
index 55c6e259..0a729adb 100644
--- a/Kyoo.Core/Controllers/Repositories/LocalRepository.cs
+++ b/Kyoo.Core/Controllers/Repositories/LocalRepository.cs
@@ -30,8 +30,8 @@ namespace Kyoo.Core.Controllers
/// The default sort order that will be used for this resource's type.
///
protected abstract Expression> DefaultSort { get; }
-
-
+
+
///
/// Create a new base with the given database handle.
///
@@ -57,7 +57,7 @@ namespace Kyoo.Core.Controllers
throw new ItemNotFoundException($"No {typeof(T).Name} found with the id {id}");
return ret;
}
-
+
///
public virtual async Task Get(int id)
{
@@ -84,19 +84,19 @@ namespace Kyoo.Core.Controllers
throw new ItemNotFoundException($"No {typeof(T).Name} found with the given predicate.");
return ret;
}
-
+
///
public virtual Task GetOrDefault(int id)
{
return Database.Set().FirstOrDefaultAsync(x => x.ID == id);
}
-
+
///
public virtual Task GetOrDefault(string slug)
{
return Database.Set().FirstOrDefaultAsync(x => x.Slug == slug);
}
-
+
///
public virtual Task GetOrDefault(Expression> where)
{
@@ -105,7 +105,7 @@ namespace Kyoo.Core.Controllers
///
public abstract Task> Search(string query);
-
+
///
public virtual Task> GetAll(Expression> where = null,
Sort sort = default,
@@ -113,7 +113,7 @@ namespace Kyoo.Core.Controllers
{
return ApplyFilters(Database.Set(), where, sort, limit);
}
-
+
///
/// Apply filters to a query to ease sort, pagination & where queries for resources of this repository
///
@@ -124,12 +124,12 @@ namespace Kyoo.Core.Controllers
/// The filtered query
protected Task> ApplyFilters(IQueryable query,
Expression> where = null,
- Sort sort = default,
+ Sort sort = default,
Pagination limit = default)
{
return ApplyFilters(query, GetOrDefault, DefaultSort, where, sort, limit);
}
-
+
///
/// Apply filters to a query to ease sort, pagination & where queries for any resources types.
/// For resources of type , see
@@ -145,17 +145,17 @@ namespace Kyoo.Core.Controllers
Func> get,
Expression> defaultSort,
Expression> where = null,
- Sort sort = default,
+ Sort sort = default,
Pagination limit = default)
{
if (where != null)
query = query.Where(where);
-
+
Expression> sortKey = sort.Key ?? defaultSort;
Expression sortExpression = sortKey.Body.NodeType == ExpressionType.Convert
? ((UnaryExpression)sortKey.Body).Operand
: sortKey.Body;
-
+
if (typeof(Enum).IsAssignableFrom(sortExpression.Type))
throw new ArgumentException("Invalid sort key.");
@@ -205,7 +205,7 @@ namespace Kyoo.Core.Controllers
T old = await GetOrDefault(obj.Slug);
if (old != null)
return old;
-
+
return await Create(obj);
}
catch (DuplicatedItemException)
@@ -225,7 +225,7 @@ namespace Kyoo.Core.Controllers
try
{
T old = await GetWithTracking(edited.ID);
-
+
if (resetOld)
old = Merger.Nullify(old);
Merger.Complete(old, edited, x => x.GetCustomAttribute() == null);
@@ -239,7 +239,7 @@ namespace Kyoo.Core.Controllers
Database.ChangeTracker.Clear();
}
}
-
+
///
/// An overridable method to edit relation of a resource.
///
@@ -257,7 +257,7 @@ namespace Kyoo.Core.Controllers
{
return Validate(resource);
}
-
+
///
/// A method called just before saving a new resource to the database.
/// It is also called on the default implementation of
@@ -278,7 +278,7 @@ namespace Kyoo.Core.Controllers
{
MethodInfo setter = typeof(T).GetProperty(nameof(resource.Slug))!.GetSetMethod();
if (setter != null)
- setter.Invoke(resource, new object[] {resource.Slug + '!'});
+ setter.Invoke(resource, new object[] { resource.Slug + '!' });
else
throw new ArgumentException("Resources slug can't be number only.");
}
@@ -306,7 +306,7 @@ namespace Kyoo.Core.Controllers
///
public abstract Task Delete(T obj);
-
+
///
public async Task DeleteAll(Expression> where)
{
diff --git a/Kyoo.Core/Controllers/Repositories/PeopleRepository.cs b/Kyoo.Core/Controllers/Repositories/PeopleRepository.cs
index 9b8eb38f..ca615782 100644
--- a/Kyoo.Core/Controllers/Repositories/PeopleRepository.cs
+++ b/Kyoo.Core/Controllers/Repositories/PeopleRepository.cs
@@ -29,7 +29,7 @@ namespace Kyoo.Core.Controllers
/// A lazy loaded show repository to validate requests from shows.
///
private readonly Lazy _shows;
-
+
///
protected override Expression> DefaultSort => x => x.Name;
@@ -41,14 +41,14 @@ namespace Kyoo.Core.Controllers
/// A lazy loaded show repository
public PeopleRepository(DatabaseContext database,
IProviderRepository providers,
- Lazy shows)
+ Lazy shows)
: base(database)
{
_database = database;
_providers = providers;
_shows = shows;
}
-
+
///
public override async Task> Search(string query)
@@ -89,7 +89,7 @@ namespace Kyoo.Core.Controllers
{
foreach (PeopleRole role in resource.Roles)
{
- role.Show = _database.LocalEntity(role.Show.Slug)
+ role.Show = _database.LocalEntity(role.Show.Slug)
?? await _shows.Value.CreateIfNotExists(role.Show);
role.ShowID = role.Show.ID;
_database.Entry(role).State = EntityState.Added;
@@ -101,7 +101,7 @@ namespace Kyoo.Core.Controllers
protected override async Task EditRelations(People resource, People changed, bool resetOld)
{
await Validate(changed);
-
+
if (changed.Roles != null || resetOld)
{
await Database.Entry(resource).Collection(x => x.Roles).LoadAsync();
@@ -120,7 +120,7 @@ namespace Kyoo.Core.Controllers
{
if (obj == null)
throw new ArgumentNullException(nameof(obj));
-
+
_database.Entry(obj).State = EntityState.Deleted;
obj.ExternalIDs.ForEach(x => _database.Entry(x).State = EntityState.Deleted);
obj.Roles.ForEach(x => _database.Entry(x).State = EntityState.Deleted);
@@ -128,9 +128,9 @@ namespace Kyoo.Core.Controllers
}
///
- public async Task> GetFromShow(int showID,
- Expression> where = null,
- Sort sort = default,
+ public async Task> GetFromShow(int showID,
+ Expression> where = null,
+ Sort sort = default,
Pagination limit = default)
{
ICollection people = await ApplyFilters(_database.PeopleRoles
@@ -151,7 +151,7 @@ namespace Kyoo.Core.Controllers
///
public async Task> GetFromShow(string showSlug,
Expression> where = null,
- Sort sort = default,
+ Sort sort = default,
Pagination limit = default)
{
ICollection people = await ApplyFilters(_database.PeopleRoles
@@ -169,11 +169,11 @@ namespace Kyoo.Core.Controllers
role.ForPeople = true;
return people;
}
-
+
///
public async Task> GetFromPeople(int id,
Expression> where = null,
- Sort sort = default,
+ Sort sort = default,
Pagination limit = default)
{
ICollection roles = await ApplyFilters(_database.PeopleRoles
@@ -188,11 +188,11 @@ namespace Kyoo.Core.Controllers
throw new ItemNotFoundException();
return roles;
}
-
+
///
public async Task> GetFromPeople(string slug,
Expression> where = null,
- Sort sort = default,
+ Sort sort = default,
Pagination limit = default)
{
ICollection roles = await ApplyFilters(_database.PeopleRoles
diff --git a/Kyoo.Core/Controllers/Repositories/SeasonRepository.cs b/Kyoo.Core/Controllers/Repositories/SeasonRepository.cs
index 1a22fe15..7075e1ad 100644
--- a/Kyoo.Core/Controllers/Repositories/SeasonRepository.cs
+++ b/Kyoo.Core/Controllers/Repositories/SeasonRepository.cs
@@ -50,7 +50,7 @@ namespace Kyoo.Core.Controllers
throw new ItemNotFoundException($"No season {seasonNumber} found for the show {showID}");
return ret;
}
-
+
///
public async Task Get(string showSlug, int seasonNumber)
{
@@ -63,14 +63,14 @@ namespace Kyoo.Core.Controllers
///
public Task GetOrDefault(int showID, int seasonNumber)
{
- return _database.Seasons.FirstOrDefaultAsync(x => x.ShowID == showID
+ return _database.Seasons.FirstOrDefaultAsync(x => x.ShowID == showID
&& x.SeasonNumber == seasonNumber);
}
///
public Task GetOrDefault(string showSlug, int seasonNumber)
{
- return _database.Seasons.FirstOrDefaultAsync(x => x.Show.Slug == showSlug
+ return _database.Seasons.FirstOrDefaultAsync(x => x.Show.Slug == showSlug
&& x.SeasonNumber == seasonNumber);
}
@@ -121,14 +121,14 @@ namespace Kyoo.Core.Controllers
protected override async Task EditRelations(Season resource, Season changed, bool resetOld)
{
await Validate(changed);
-
+
if (changed.ExternalIDs != null || resetOld)
{
await Database.Entry(resource).Collection(x => x.ExternalIDs).LoadAsync();
resource.ExternalIDs = changed.ExternalIDs;
}
}
-
+
///
public override async Task Delete(Season obj)
{
@@ -139,4 +139,4 @@ namespace Kyoo.Core.Controllers
await _database.SaveChangesAsync();
}
}
-}
\ No newline at end of file
+}
diff --git a/Kyoo.Core/Controllers/Repositories/ShowRepository.cs b/Kyoo.Core/Controllers/Repositories/ShowRepository.cs
index dca498c7..740ea06f 100644
--- a/Kyoo.Core/Controllers/Repositories/ShowRepository.cs
+++ b/Kyoo.Core/Controllers/Repositories/ShowRepository.cs
@@ -50,8 +50,8 @@ namespace Kyoo.Core.Controllers
/// A provider repository
public ShowRepository(DatabaseContext database,
IStudioRepository studios,
- IPeopleRepository people,
- IGenreRepository genres,
+ IPeopleRepository people,
+ IGenreRepository genres,
IProviderRepository providers)
: base(database)
{
@@ -61,7 +61,7 @@ namespace Kyoo.Core.Controllers
_genres = genres;
_providers = providers;
}
-
+
///
public override async Task> Search(string query)
@@ -82,7 +82,7 @@ namespace Kyoo.Core.Controllers
await _database.SaveChangesAsync($"Trying to insert a duplicated show (slug {obj.Slug} already exists).");
return obj;
}
-
+
///
protected override async Task Validate(Show resource)
{
@@ -128,7 +128,7 @@ namespace Kyoo.Core.Controllers
protected override async Task EditRelations(Show resource, Show changed, bool resetOld)
{
await Validate(changed);
-
+
if (changed.Aliases != null || resetOld)
resource.Aliases = changed.Aliases;
@@ -137,7 +137,7 @@ namespace Kyoo.Core.Controllers
await Database.Entry(resource).Reference(x => x.Studio).LoadAsync();
resource.Studio = changed.Studio;
}
-
+
if (changed.Genres != null || resetOld)
{
await Database.Entry(resource).Collection(x => x.Genres).LoadAsync();
@@ -177,7 +177,7 @@ namespace Kyoo.Core.Controllers
await _database.SaveIfNoDuplicates();
}
}
-
+
///
public Task GetSlug(int showID)
{
@@ -185,7 +185,7 @@ namespace Kyoo.Core.Controllers
.Select(x => x.Slug)
.FirstOrDefaultAsync();
}
-
+
///
public override async Task Delete(Show obj)
{
diff --git a/Kyoo.Core/Controllers/Repositories/StudioRepository.cs b/Kyoo.Core/Controllers/Repositories/StudioRepository.cs
index 185e4420..24bf8122 100644
--- a/Kyoo.Core/Controllers/Repositories/StudioRepository.cs
+++ b/Kyoo.Core/Controllers/Repositories/StudioRepository.cs
@@ -19,12 +19,12 @@ namespace Kyoo.Core.Controllers
/// The database handle
///
private readonly DatabaseContext _database;
-
+
///
/// A provider repository to handle externalID creation and deletion
///
private readonly IProviderRepository _providers;
-
+
///
protected override Expression> DefaultSort => x => x.Name;
@@ -40,7 +40,7 @@ namespace Kyoo.Core.Controllers
_database = database;
_providers = providers;
}
-
+
///
public override async Task> Search(string query)
{
@@ -59,7 +59,7 @@ namespace Kyoo.Core.Controllers
await _database.SaveChangesAsync($"Trying to insert a duplicated studio (slug {obj.Slug} already exists).");
return obj;
}
-
+
///
protected override async Task Validate(Studio resource)
{
@@ -75,7 +75,7 @@ namespace Kyoo.Core.Controllers
_database.MetadataIds().AttachRange(resource.ExternalIDs);
}
}
-
+
///
protected override async Task EditRelations(Studio resource, Studio changed, bool resetOld)
{
@@ -93,7 +93,7 @@ namespace Kyoo.Core.Controllers
{
if (obj == null)
throw new ArgumentNullException(nameof(obj));
-
+
_database.Entry(obj).State = EntityState.Deleted;
await _database.SaveChangesAsync();
}
diff --git a/Kyoo.Core/Controllers/Repositories/TrackRepository.cs b/Kyoo.Core/Controllers/Repositories/TrackRepository.cs
index c6b7889c..ce582bb8 100644
--- a/Kyoo.Core/Controllers/Repositories/TrackRepository.cs
+++ b/Kyoo.Core/Controllers/Repositories/TrackRepository.cs
@@ -18,7 +18,7 @@ namespace Kyoo.Core.Controllers
/// The database handle
///
private readonly DatabaseContext _database;
-
+
///
protected override Expression> DefaultSort => x => x.TrackIndex;
@@ -27,7 +27,7 @@ namespace Kyoo.Core.Controllers
/// Create a new .
///
/// The database handle
- public TrackRepository(DatabaseContext database)
+ public TrackRepository(DatabaseContext database)
: base(database)
{
_database = database;
@@ -69,7 +69,7 @@ namespace Kyoo.Core.Controllers
{
if (obj == null)
throw new ArgumentNullException(nameof(obj));
-
+
_database.Entry(obj).State = EntityState.Deleted;
await _database.SaveChangesAsync();
}
diff --git a/Kyoo.Core/Controllers/Repositories/UserRepository.cs b/Kyoo.Core/Controllers/Repositories/UserRepository.cs
index 1b267ab6..d632a473 100644
--- a/Kyoo.Core/Controllers/Repositories/UserRepository.cs
+++ b/Kyoo.Core/Controllers/Repositories/UserRepository.cs
@@ -19,11 +19,11 @@ namespace Kyoo.Core.Controllers
/// The database handle
///
private readonly DatabaseContext _database;
-
+
///
protected override Expression> DefaultSort => x => x.Username;
-
-
+
+
///
/// Create a new
///
@@ -33,7 +33,7 @@ namespace Kyoo.Core.Controllers
{
_database = database;
}
-
+
///
public override async Task> Search(string query)
{
@@ -43,7 +43,7 @@ namespace Kyoo.Core.Controllers
.Take(20)
.ToListAsync();
}
-
+
///
public override async Task Create(User obj)
{
@@ -58,7 +58,7 @@ namespace Kyoo.Core.Controllers
{
if (obj == null)
throw new ArgumentNullException(nameof(obj));
-
+
_database.Entry(obj).State = EntityState.Deleted;
await _database.SaveChangesAsync();
}
diff --git a/Kyoo.Core/Controllers/TaskManager.cs b/Kyoo.Core/Controllers/TaskManager.cs
index af1d24e6..ba713e81 100644
--- a/Kyoo.Core/Controllers/TaskManager.cs
+++ b/Kyoo.Core/Controllers/TaskManager.cs
@@ -32,7 +32,7 @@ namespace Kyoo.Core.Controllers
/// The metadata for this task (the slug, and other useful information).
///
public TaskMetadataAttribute Metadata { get; set; }
-
+
///
/// The function used to create the task object.
///
@@ -53,23 +53,23 @@ namespace Kyoo.Core.Controllers
/// The task currently queued.
///
public ManagedTask Task { get; init; }
-
+
///
/// The progress reporter that this task should use.
///
public IProgress ProgressReporter { get; init; }
-
+
///
/// The arguments to give to run the task with.
///
public Dictionary Arguments { get; init; }
-
+
///
/// A token informing the task that it should be cancelled or not.
///
public CancellationToken? CancellationToken { get; init; }
}
-
+
///
/// The configuration instance used to get schedule information
///
@@ -115,14 +115,14 @@ namespace Kyoo.Core.Controllers
Metadata = x.Metadata,
ScheduledDate = GetNextTaskDate(x.Metadata.Slug)
}).ToList();
-
+
if (_tasks.Any())
_logger.LogTrace("Task manager initiated with: {Tasks}", _tasks.Select(x => x.Metadata.Name));
else
_logger.LogInformation("Task manager initiated without any tasks");
}
-
-
+
+
///
/// Triggered when the application host is ready to start the service.
///
@@ -133,7 +133,7 @@ namespace Kyoo.Core.Controllers
Task.Run(() => base.StartAsync(cancellationToken), CancellationToken.None);
return Task.CompletedTask;
}
-
+
///
public override Task StopAsync(CancellationToken cancellationToken)
{
@@ -148,7 +148,7 @@ namespace Kyoo.Core.Controllers
protected override async Task ExecuteAsync(CancellationToken cancellationToken)
{
_EnqueueStartupTasks();
-
+
while (!cancellationToken.IsCancellationRequested)
{
if (_queuedTasks.Any())
@@ -160,12 +160,12 @@ namespace Kyoo.Core.Controllers
}
catch (TaskFailedException ex)
{
- _logger.LogWarning("The task \"{Task}\" failed: {Message}",
+ _logger.LogWarning("The task \"{Task}\" failed: {Message}",
task.Task.Metadata.Name, ex.Message);
}
catch (Exception e)
{
- _logger.LogError(e, "An unhandled exception occured while running the task {Task}",
+ _logger.LogError(e, "An unhandled exception occured while running the task {Task}",
task.Task.Metadata.Name);
}
}
@@ -188,7 +188,7 @@ namespace Kyoo.Core.Controllers
/// If the number of arguments is invalid, if an argument can't be converted or if the task finds the argument
/// invalid.
///
- private async Task _RunTask(ManagedTask task,
+ private async Task _RunTask(ManagedTask task,
[NotNull] IProgress progress,
Dictionary arguments,
CancellationToken? cancellationToken = null)
@@ -220,14 +220,14 @@ namespace Kyoo.Core.Controllers
return x.CreateValue(value ?? x.DefaultValue);
}));
- _logger.LogInformation("Task starting: {Task} ({Parameters})",
+ _logger.LogInformation("Task starting: {Task} ({Parameters})",
task.Metadata.Name, args.ToDictionary(x => x.Name, x => x.As()));
-
+
CancellationToken token = cancellationToken != null
? CancellationTokenSource.CreateLinkedTokenSource(_taskToken.Token, cancellationToken.Value).Token
: _taskToken.Token;
await taskObj.Value.Run(args, progress, token);
-
+
_logger.LogInformation("Task finished: {Task}", task.Metadata.Name);
_runningTask = null;
}
@@ -261,13 +261,13 @@ namespace Kyoo.Core.Controllers
}
///
- public void StartTask(string taskSlug,
+ public void StartTask(string taskSlug,
IProgress progress,
Dictionary arguments = null,
CancellationToken? cancellationToken = null)
{
arguments ??= new Dictionary();
-
+
int index = _tasks.FindIndex(x => x.Metadata.Slug == taskSlug);
if (index == -1)
throw new ItemNotFoundException($"No task found with the slug {taskSlug}");
@@ -276,13 +276,13 @@ namespace Kyoo.Core.Controllers
Task = _tasks[index],
ProgressReporter = progress,
Arguments = arguments,
- CancellationToken = cancellationToken
+ CancellationToken = cancellationToken
});
_tasks[index].ScheduledDate = GetNextTaskDate(taskSlug);
}
///
- public void StartTask(IProgress progress,
+ public void StartTask(IProgress progress,
Dictionary arguments = null,
CancellationToken? cancellationToken = null)
where T : ITask
@@ -304,12 +304,12 @@ namespace Kyoo.Core.Controllers
return DateTime.Now + delay;
return DateTime.MaxValue;
}
-
+
///
public ICollection<(TaskMetadataAttribute, ITask)> GetRunningTasks()
{
- return _runningTask == null
- ? ArraySegment<(TaskMetadataAttribute, ITask)>.Empty
+ return _runningTask == null
+ ? ArraySegment<(TaskMetadataAttribute, ITask)>.Empty
: new[] { _runningTask.Value };
}
diff --git a/Kyoo.Core/Controllers/ThumbnailsManager.cs b/Kyoo.Core/Controllers/ThumbnailsManager.cs
index d82db69f..0f414d62 100644
--- a/Kyoo.Core/Controllers/ThumbnailsManager.cs
+++ b/Kyoo.Core/Controllers/ThumbnailsManager.cs
@@ -28,7 +28,7 @@ namespace Kyoo.Core.Controllers
///
/// The file manager to use.
/// A logger to report errors
- public ThumbnailsManager(IFileSystem files,
+ public ThumbnailsManager(IFileSystem files,
ILogger logger)
{
_files = files;
@@ -66,7 +66,7 @@ namespace Kyoo.Core.Controllers
}
///
- public async Task DownloadImages(T item, bool alwaysDownload = false)
+ public async Task DownloadImages(T item, bool alwaysDownload = false)
where T : IThumbnails
{
if (item == null)
@@ -84,7 +84,7 @@ namespace Kyoo.Core.Controllers
if (alwaysDownload || !await _files.Exists(localPath))
ret |= await _DownloadImage(image, localPath, $"The image n°{id} of {name}");
}
-
+
return ret;
}
@@ -99,7 +99,7 @@ namespace Kyoo.Core.Controllers
{
if (item == null)
throw new ArgumentNullException(nameof(item));
-
+
string directory = await _files.GetExtraDirectory(item);
string imageName = imageID switch
{
@@ -109,7 +109,7 @@ namespace Kyoo.Core.Controllers
Images.Trailer => "trailer",
_ => $"{imageID}"
};
-
+
switch (item)
{
case Season season:
@@ -123,7 +123,7 @@ namespace Kyoo.Core.Controllers
return _files.Combine(directory, imageName);
}
-
+
///
public async Task GetImagePath(T item, int imageID)
where T : IThumbnails
diff --git a/Kyoo.Core/Controllers/Transcoder.cs b/Kyoo.Core/Controllers/Transcoder.cs
index 1f2f8d08..fdbd28e1 100644
--- a/Kyoo.Core/Controllers/Transcoder.cs
+++ b/Kyoo.Core/Controllers/Transcoder.cs
@@ -13,8 +13,8 @@ using Stream = Kyoo.Core.Models.Watch.Stream;
namespace Kyoo.Core.Controllers
{
- public class BadTranscoderException : Exception {}
-
+ public class BadTranscoderException : Exception { }
+
public class Transcoder : ITranscoder
{
private static class TranscoderAPI
@@ -26,7 +26,7 @@ namespace Kyoo.Core.Controllers
public static int Init() => init();
- [DllImport(TranscoderPath, CallingConvention = CallingConvention.Cdecl,
+ [DllImport(TranscoderPath, CallingConvention = CallingConvention.Cdecl,
CharSet = CharSet.Ansi, BestFitMapping = false, ThrowOnUnmappableChar = true)]
private static extern int transmux(string path, string outpath, out float playableDuration);
@@ -37,9 +37,9 @@ namespace Kyoo.Core.Controllers
return transmux(path, outPath, out playableDuration);
}
- [DllImport(TranscoderPath, CallingConvention = CallingConvention.Cdecl,
+ [DllImport(TranscoderPath, CallingConvention = CallingConvention.Cdecl,
CharSet = CharSet.Ansi, BestFitMapping = false, ThrowOnUnmappableChar = true)]
- private static extern IntPtr extract_infos(string path,
+ private static extern IntPtr extract_infos(string path,
string outpath,
out uint length,
out uint trackCount,
@@ -53,12 +53,12 @@ namespace Kyoo.Core.Controllers
{
path = path.Replace('\\', '/');
outPath = outPath.Replace('\\', '/');
-
+
int size = Marshal.SizeOf();
IntPtr ptr = extract_infos(path, outPath, out uint arrayLength, out uint trackCount, reextract);
IntPtr streamsPtr = ptr;
Track[] tracks;
-
+
if (trackCount > 0 && ptr != IntPtr.Zero)
{
tracks = new Track[trackCount];
@@ -113,7 +113,7 @@ namespace Kyoo.Core.Controllers
{
if (!File.Exists(episode.Path))
throw new ArgumentException("Path does not exists. Can't transcode.");
-
+
string folder = Path.Combine(_options.Value.TransmuxPath, episode.Slug);
string manifest = Path.Combine(folder, episode.Slug + ".m3u8");
float playableDuration = 0;
@@ -130,7 +130,7 @@ namespace Kyoo.Core.Controllers
await Console.Error.WriteLineAsync($"Access to the path {manifest} is denied. Please change your transmux path in the config.");
return null;
}
-
+
Task.Factory.StartNew(() =>
{
transmuxFailed = TranscoderAPI.Transmux(episode.Path, manifest, out playableDuration) != 0;
diff --git a/Kyoo.Core/CoreModule.cs b/Kyoo.Core/CoreModule.cs
index ef0961cc..0b04223f 100644
--- a/Kyoo.Core/CoreModule.cs
+++ b/Kyoo.Core/CoreModule.cs
@@ -29,10 +29,10 @@ namespace Kyoo.Core
{
///
public string Slug => "core";
-
+
///
public string Name => "Core";
-
+
///
public string Description => "The core module containing default implementations.";
@@ -66,11 +66,11 @@ namespace Kyoo.Core
public void Configure(ContainerBuilder builder)
{
builder.RegisterModule();
-
+
builder.RegisterComposite().InstancePerLifetimeScope();
builder.RegisterType().As().SingleInstance();
builder.RegisterType().As().SingleInstance();
-
+
builder.RegisterType().As().As().SingleInstance();
builder.RegisterType().As().SingleInstance();
@@ -78,7 +78,7 @@ namespace Kyoo.Core
builder.RegisterType().As().InstancePerLifetimeScope();
builder.RegisterType().As().InstancePerLifetimeScope();
builder.RegisterType().As().SingleInstance();
-
+
builder.RegisterComposite();
builder.Register(x => (AProviderComposite)x.Resolve());
@@ -106,7 +106,7 @@ namespace Kyoo.Core
builder.RegisterType().As()
.IfNotRegistered(typeof(IPermissionValidator));
-
+
builder.RegisterType().As().SingleInstance()
.OnActivating(x =>
{
@@ -117,7 +117,7 @@ namespace Kyoo.Core
x.Instance.Mappings[".m3u8"] = "application/x-mpegurl";
});
}
-
+
///
public void Configure(IServiceCollection services)
{
@@ -130,12 +130,12 @@ namespace Kyoo.Core
x.SerializerSettings.ContractResolver = new JsonPropertyIgnorer(publicUrl);
x.SerializerSettings.Converters.Add(new PeopleRoleConverter());
});
-
+
services.AddResponseCompression(x =>
{
x.EnableForHttps = true;
});
-
+
services.AddHttpClient();
}
diff --git a/Kyoo.Core/Models/FileExtensions.cs b/Kyoo.Core/Models/FileExtensions.cs
index 26e520d1..b8d9f0ee 100644
--- a/Kyoo.Core/Models/FileExtensions.cs
+++ b/Kyoo.Core/Models/FileExtensions.cs
@@ -17,7 +17,7 @@ namespace Kyoo.Core.Models.Watch
".mkv",
".flv",
".vob",
- ".ogg",
+ ".ogg",
".ogv",
".avi",
".mts",
@@ -25,7 +25,7 @@ namespace Kyoo.Core.Models.Watch
".ts",
".mov",
".qt",
- ".asf",
+ ".asf",
".mp4",
".m4p",
".m4v",
@@ -48,11 +48,11 @@ namespace Kyoo.Core.Models.Watch
{
return VideoExtensions.Contains(Path.GetExtension(filePath));
}
-
+
///
/// The dictionary of known subtitles extensions and the name of the subtitle codec.
///
- public static readonly ImmutableDictionary SubtitleExtensions = new Dictionary
+ public static readonly ImmutableDictionary SubtitleExtensions = new Dictionary
{
{".ass", "ass"},
{".str", "subrip"}
diff --git a/Kyoo.Core/Models/Options/BasicOptions.cs b/Kyoo.Core/Models/Options/BasicOptions.cs
index 5bb108f8..81dd50df 100644
--- a/Kyoo.Core/Models/Options/BasicOptions.cs
+++ b/Kyoo.Core/Models/Options/BasicOptions.cs
@@ -32,7 +32,7 @@ namespace Kyoo.Core.Models.Options
/// The temporary folder to cache transmuxed file.
///
public string TransmuxPath { get; set; } = "cached/transmux";
-
+
///
/// The temporary folder to cache transcoded file.
///
diff --git a/Kyoo.Core/Models/Options/MediaOptions.cs b/Kyoo.Core/Models/Options/MediaOptions.cs
index 3133e8d2..9f2aba26 100644
--- a/Kyoo.Core/Models/Options/MediaOptions.cs
+++ b/Kyoo.Core/Models/Options/MediaOptions.cs
@@ -9,12 +9,12 @@ namespace Kyoo.Core.Models.Options
/// The path of this options
///
public const string Path = "Media";
-
+
///
/// A regex for episodes
///
public string[] Regex { get; set; }
-
+
///
/// A regex for subtitles
///
diff --git a/Kyoo.Core/Models/Options/TaskOptions.cs b/Kyoo.Core/Models/Options/TaskOptions.cs
index 89b77687..abd49a1a 100644
--- a/Kyoo.Core/Models/Options/TaskOptions.cs
+++ b/Kyoo.Core/Models/Options/TaskOptions.cs
@@ -13,7 +13,7 @@ namespace Kyoo.Core.Models.Options
/// The path of this options
///
public const string Path = "Tasks";
-
+
///
/// The number of tasks that can be run concurrently.
///
diff --git a/Kyoo.Core/Models/Stream.cs b/Kyoo.Core/Models/Stream.cs
index 2980adae..0161b16b 100644
--- a/Kyoo.Core/Models/Stream.cs
+++ b/Kyoo.Core/Models/Stream.cs
@@ -14,17 +14,17 @@ namespace Kyoo.Core.Models.Watch
/// The title of the stream.
///
public string Title { get; set; }
-
+
///
/// The language of this stream (as a ISO-639-2 language code)
///
public string Language { get; set; }
-
+
///
/// The codec of this stream.
///
public string Codec { get; set; }
-
+
///
/// Is this stream the default one of it's type?
///
@@ -34,12 +34,12 @@ namespace Kyoo.Core.Models.Watch
/// Is this stream tagged as forced?
///
[MarshalAs(UnmanagedType.I1)] public bool IsForced;
-
+
///
/// The path of this track.
///
[SerializeIgnore] public string Path { get; set; }
-
+
///
/// The type of this stream.
///
diff --git a/Kyoo.Core/PluginsStartup.cs b/Kyoo.Core/PluginsStartup.cs
index 470c9a4f..74c800f9 100644
--- a/Kyoo.Core/PluginsStartup.cs
+++ b/Kyoo.Core/PluginsStartup.cs
@@ -69,7 +69,7 @@ namespace Kyoo.Core
{
foreach (IPlugin plugin in _plugins.GetAllPlugins())
plugin.Configure(services);
-
+
IEnumerable> configTypes = _plugins.GetAllPlugins()
.SelectMany(x => x.Configuration)
.Where(x => x.Value != null);
@@ -92,7 +92,7 @@ namespace Kyoo.Core
{
builder.RegisterInstance(_plugins).As().ExternallyOwned();
builder.RegisterTask();
-
+
foreach (IPlugin plugin in _plugins.GetAllPlugins())
plugin.Configure(builder);
}
@@ -125,8 +125,8 @@ namespace Kyoo.Core
foreach ((string path, Type type) in pluginConfig)
config.Register(path, type);
}
-
-
+
+
///
/// Create a new from a webhost.
/// This is meant to be used from .
@@ -136,7 +136,7 @@ namespace Kyoo.Core
/// The logger factory used to log while the application is setting itself up.
///
/// A new .
- public static PluginsStartup FromWebHost(WebHostBuilderContext host,
+ public static PluginsStartup FromWebHost(WebHostBuilderContext host,
ILoggerFactory logger)
{
HostServiceProvider hostProvider = new(host.HostingEnvironment, host.Configuration, logger);
@@ -147,7 +147,7 @@ namespace Kyoo.Core
);
return new PluginsStartup(plugins, host.Configuration);
}
-
+
///
/// A simple host service provider used to activate plugins instance.
/// The same services as a generic host are available and an has been added.
@@ -158,18 +158,18 @@ namespace Kyoo.Core
/// The host environment that could be used by plugins to configure themself.
///
private readonly IWebHostEnvironment _hostEnvironment;
-
+
///
/// The configuration context.
///
private readonly IConfiguration _configuration;
-
+
///
/// A logger factory used to create a logger for the plugin manager.
///
private readonly ILoggerFactory _loggerFactory;
-
+
///
/// Create a new that will return given services when asked.
///
diff --git a/Kyoo.Core/Tasks/Crawler.cs b/Kyoo.Core/Tasks/Crawler.cs
index 3633fbb3..186f2c7e 100644
--- a/Kyoo.Core/Tasks/Crawler.cs
+++ b/Kyoo.Core/Tasks/Crawler.cs
@@ -52,8 +52,8 @@ namespace Kyoo.Core.Tasks
_taskManager = taskManager;
_logger = logger;
}
-
-
+
+
///
public TaskParameters GetParameters()
{
@@ -67,9 +67,9 @@ namespace Kyoo.Core.Tasks
public async Task Run(TaskParameters arguments, IProgress progress, CancellationToken cancellationToken)
{
string argument = arguments["slug"].As();
- ICollection libraries = argument == null
+ ICollection libraries = argument == null
? await _libraryManager.GetAll()
- : new [] { await _libraryManager.GetOrDefault(argument)};
+ : new[] { await _libraryManager.GetOrDefault(argument) };
if (argument != null && libraries.First() == null)
throw new ArgumentException($"No library found with the name {argument}");
@@ -79,7 +79,7 @@ namespace Kyoo.Core.Tasks
progress.Report(0);
float percent = 0;
-
+
ICollection episodes = await _libraryManager.GetAll();
ICollection tracks = await _libraryManager.GetAll();
foreach (Library library in libraries)
@@ -91,15 +91,15 @@ namespace Kyoo.Core.Tasks
});
await Scan(library, episodes, tracks, reporter, cancellationToken);
percent += 100f / libraries.Count;
-
+
if (cancellationToken.IsCancellationRequested)
return;
}
-
+
progress.Report(100);
}
- private async Task Scan(Library library,
+ private async Task Scan(Library library,
IEnumerable episodes,
IEnumerable tracks,
IProgress progress,
@@ -109,7 +109,7 @@ namespace Kyoo.Core.Tasks
foreach (string path in library.Paths)
{
ICollection files = await _fileSystem.ListFiles(path, SearchOption.AllDirectories);
-
+
if (cancellationToken.IsCancellationRequested)
return;
@@ -121,8 +121,8 @@ namespace Kyoo.Core.Tasks
.Where(x => episodes.All(y => y.Path != x))
.GroupBy(Path.GetDirectoryName)
.ToList();
-
-
+
+
string[] paths = shows.Select(x => x.First())
.Concat(shows.SelectMany(x => x.Skip(1)))
.ToArray();
@@ -132,7 +132,7 @@ namespace Kyoo.Core.Tasks
// ReSharper disable once AccessToModifiedClosure
progress.Report((percent + x / paths.Length - 10) / library.Paths.Length);
});
-
+
foreach (string episodePath in paths)
{
_taskManager.StartTask(reporter, new Dictionary
@@ -143,7 +143,7 @@ namespace Kyoo.Core.Tasks
percent += 100f / paths.Length;
}
-
+
string[] subtitles = files
.Where(FileExtensions.IsSubtitle)
.Where(x => !x.Contains("Extra"))
@@ -155,7 +155,7 @@ namespace Kyoo.Core.Tasks
// ReSharper disable once AccessToModifiedClosure
progress.Report((90 + (percent + x / subtitles.Length)) / library.Paths.Length);
});
-
+
foreach (string trackPath in subtitles)
{
_taskManager.StartTask(reporter, new Dictionary
diff --git a/Kyoo.Core/Tasks/Housekeeping.cs b/Kyoo.Core/Tasks/Housekeeping.cs
index 38d1c9f4..f27a05c4 100644
--- a/Kyoo.Core/Tasks/Housekeeping.cs
+++ b/Kyoo.Core/Tasks/Housekeeping.cs
@@ -57,10 +57,10 @@ namespace Kyoo.Core.Tasks
{
progress.Report(count / delCount * 100);
count++;
-
+
if (await _fileSystem.Exists(show.Path))
continue;
- _logger.LogWarning("Show {Name}'s folder has been deleted (was {Path}), removing it from kyoo",
+ _logger.LogWarning("Show {Name}'s folder has been deleted (was {Path}), removing it from kyoo",
show.Title, show.Path);
await _libraryManager.Delete(show);
}
@@ -69,14 +69,14 @@ namespace Kyoo.Core.Tasks
{
progress.Report(count / delCount * 100);
count++;
-
+
if (await _fileSystem.Exists(episode.Path))
continue;
- _logger.LogWarning("Episode {Slug}'s file has been deleted (was {Path}), removing it from kyoo",
+ _logger.LogWarning("Episode {Slug}'s file has been deleted (was {Path}), removing it from kyoo",
episode.Slug, episode.Path);
await _libraryManager.Delete(episode);
}
-
+
progress.Report(100);
}
}
diff --git a/Kyoo.Core/Tasks/MetadataProviderLoader.cs b/Kyoo.Core/Tasks/MetadataProviderLoader.cs
index cfe398ae..6a3270f3 100644
--- a/Kyoo.Core/Tasks/MetadataProviderLoader.cs
+++ b/Kyoo.Core/Tasks/MetadataProviderLoader.cs
@@ -40,7 +40,7 @@ namespace Kyoo.Core.Tasks
///
/// The list of metadata providers to register.
///
- public MetadataProviderLoader(IProviderRepository providers,
+ public MetadataProviderLoader(IProviderRepository providers,
IThumbnailsManager thumbnails,
ICollection metadataProviders)
{
@@ -61,7 +61,7 @@ namespace Kyoo.Core.Tasks
{
float percent = 0;
progress.Report(0);
-
+
foreach (IMetadataProvider provider in _metadataProviders)
{
if (string.IsNullOrEmpty(provider.Provider.Slug))
diff --git a/Kyoo.Core/Tasks/PluginInitializer.cs b/Kyoo.Core/Tasks/PluginInitializer.cs
index a5b36b6d..ece55603 100644
--- a/Kyoo.Core/Tasks/PluginInitializer.cs
+++ b/Kyoo.Core/Tasks/PluginInitializer.cs
@@ -10,7 +10,7 @@ namespace Kyoo.Core.Tasks
///
/// A task run on Kyoo's startup to initialize plugins
///
- [TaskMetadata("plugin-init", "Plugin Initializer", "A task to initialize plugins.",
+ [TaskMetadata("plugin-init", "Plugin Initializer", "A task to initialize plugins.",
RunOnStartup = true, Priority = int.MaxValue, IsHidden = true)]
public class PluginInitializer : ITask
{
@@ -33,14 +33,14 @@ namespace Kyoo.Core.Tasks
_pluginManager = pluginManager;
_provider = provider;
}
-
+
///
public TaskParameters GetParameters()
{
return new();
}
-
+
///
public Task Run(TaskParameters arguments, IProgress progress, CancellationToken cancellationToken)
{
@@ -51,11 +51,11 @@ namespace Kyoo.Core.Tasks
foreach (IPlugin plugin in plugins)
{
plugin.Initialize(_provider);
-
+
progress.Report(count / plugins.Count * 100);
count++;
}
-
+
progress.Report(100);
return Task.CompletedTask;
}
diff --git a/Kyoo.Core/Tasks/RegisterEpisode.cs b/Kyoo.Core/Tasks/RegisterEpisode.cs
index d713a9d1..88913b3d 100644
--- a/Kyoo.Core/Tasks/RegisterEpisode.cs
+++ b/Kyoo.Core/Tasks/RegisterEpisode.cs
@@ -76,7 +76,7 @@ namespace Kyoo.Core.Tasks
TaskParameter.CreateRequired("library", "The library in witch the episode is")
};
}
-
+
///
public async Task Run(TaskParameters arguments, IProgress progress, CancellationToken cancellationToken)
{
@@ -148,7 +148,7 @@ namespace Kyoo.Core.Tasks
throw new TaskFailedException(ex);
}
}
-
+
///
/// Retrieve the equivalent item if it already exists in the database,
/// if it does not, fill metadata using the metadata provider, download images and register the item to the
@@ -172,7 +172,7 @@ namespace Kyoo.Core.Tasks
item = await _metadataProvider.Get(item);
await _thumbnailsManager.DownloadImages(item);
-
+
switch (item)
{
case Show show when show.People != null:
diff --git a/Kyoo.Core/Tasks/RegisterSubtitle.cs b/Kyoo.Core/Tasks/RegisterSubtitle.cs
index 3b931ab7..dffd5cdc 100644
--- a/Kyoo.Core/Tasks/RegisterSubtitle.cs
+++ b/Kyoo.Core/Tasks/RegisterSubtitle.cs
@@ -42,7 +42,7 @@ namespace Kyoo.Core.Tasks
TaskParameter.CreateRequired("path", "The path of the subtitle file")
};
}
-
+
///
public async Task Run(TaskParameters arguments, IProgress progress, CancellationToken cancellationToken)
{
diff --git a/Kyoo.Core/Views/CollectionApi.cs b/Kyoo.Core/Views/CollectionApi.cs
index 56af8b0a..3ad2ab08 100644
--- a/Kyoo.Core/Views/CollectionApi.cs
+++ b/Kyoo.Core/Views/CollectionApi.cs
@@ -22,17 +22,17 @@ namespace Kyoo.Core.Api
private readonly IFileSystem _files;
private readonly IThumbnailsManager _thumbs;
- public CollectionApi(ILibraryManager libraryManager,
- IFileSystem files,
+ public CollectionApi(ILibraryManager libraryManager,
+ IFileSystem files,
IThumbnailsManager thumbs,
- IOptions options)
+ IOptions options)
: base(libraryManager.CollectionRepository, options.Value.PublicUrl)
{
_libraryManager = libraryManager;
_files = files;
_thumbs = thumbs;
}
-
+
[HttpGet("{id:int}/show")]
[HttpGet("{id:int}/shows")]
[PartialPermission(Kind.Read)]
@@ -55,10 +55,10 @@ namespace Kyoo.Core.Api
}
catch (ArgumentException ex)
{
- return BadRequest(new {Error = ex.Message});
+ return BadRequest(new { Error = ex.Message });
}
}
-
+
[HttpGet("{slug}/show")]
[HttpGet("{slug}/shows")]
[PartialPermission(Kind.Read)]
@@ -81,10 +81,10 @@ namespace Kyoo.Core.Api
}
catch (ArgumentException ex)
{
- return BadRequest(new {Error = ex.Message});
+ return BadRequest(new { Error = ex.Message });
}
}
-
+
[HttpGet("{id:int}/library")]
[HttpGet("{id:int}/libraries")]
[PartialPermission(Kind.Read)]
@@ -107,10 +107,10 @@ namespace Kyoo.Core.Api
}
catch (ArgumentException ex)
{
- return BadRequest(new {Error = ex.Message});
+ return BadRequest(new { Error = ex.Message });
}
}
-
+
[HttpGet("{slug}/library")]
[HttpGet("{slug}/libraries")]
[PartialPermission(Kind.Read)]
@@ -133,10 +133,10 @@ namespace Kyoo.Core.Api
}
catch (ArgumentException ex)
{
- return BadRequest(new {Error = ex.Message});
+ return BadRequest(new { Error = ex.Message });
}
}
-
+
[HttpGet("{slug}/poster")]
public async Task GetPoster(string slug)
{
@@ -150,7 +150,7 @@ namespace Kyoo.Core.Api
return NotFound();
}
}
-
+
[HttpGet("{slug}/logo")]
public async Task GetLogo(string slug)
{
@@ -164,7 +164,7 @@ namespace Kyoo.Core.Api
return NotFound();
}
}
-
+
[HttpGet("{slug}/backdrop")]
[HttpGet("{slug}/thumbnail")]
public async Task GetBackdrop(string slug)
diff --git a/Kyoo.Core/Views/EpisodeApi.cs b/Kyoo.Core/Views/EpisodeApi.cs
index c4fdf566..086e21e4 100644
--- a/Kyoo.Core/Views/EpisodeApi.cs
+++ b/Kyoo.Core/Views/EpisodeApi.cs
@@ -25,7 +25,7 @@ namespace Kyoo.Core.Api
public EpisodeApi(ILibraryManager libraryManager,
IOptions options,
IFileSystem files,
- IThumbnailsManager thumbnails)
+ IThumbnailsManager thumbnails)
: base(libraryManager.EpisodeRepository, options.Value.PublicUrl)
{
_libraryManager = libraryManager;
@@ -37,12 +37,12 @@ namespace Kyoo.Core.Api
[PartialPermission(Kind.Read)]
public async Task> GetShow(int episodeID)
{
- Show ret = await _libraryManager.GetOrDefault(x => x.Episodes.Any(y => y.ID == episodeID));
+ Show ret = await _libraryManager.GetOrDefault(x => x.Episodes.Any(y => y.ID == episodeID));
if (ret == null)
return NotFound();
return ret;
}
-
+
[HttpGet("{showSlug}-s{seasonNumber:int}e{episodeNumber:int}/show")]
[PartialPermission(Kind.Read)]
public async Task> GetShow(string showSlug, int seasonNumber, int episodeNumber)
@@ -52,7 +52,7 @@ namespace Kyoo.Core.Api
return NotFound();
return ret;
}
-
+
[HttpGet("{showID:int}-{seasonNumber:int}e{episodeNumber:int}/show")]
[PartialPermission(Kind.Read)]
public async Task> GetShow(int showID, int seasonNumber, int episodeNumber)
@@ -62,7 +62,7 @@ namespace Kyoo.Core.Api
return NotFound();
return ret;
}
-
+
[HttpGet("{episodeID:int}/season")]
[PartialPermission(Kind.Read)]
public async Task> GetSeason(int episodeID)
@@ -72,7 +72,7 @@ namespace Kyoo.Core.Api
return NotFound();
return ret;
}
-
+
[HttpGet("{showSlug}-s{seasonNumber:int}e{episodeNumber:int}/season")]
[PartialPermission(Kind.Read)]
public async Task> GetSeason(string showSlug, int seasonNumber, int episodeNumber)
@@ -86,7 +86,7 @@ namespace Kyoo.Core.Api
return NotFound();
}
}
-
+
[HttpGet("{showID:int}-{seasonNumber:int}e{episodeNumber:int}/season")]
[PartialPermission(Kind.Read)]
public async Task> GetSeason(int showID, int seasonNumber, int episodeNumber)
@@ -100,7 +100,7 @@ namespace Kyoo.Core.Api
return NotFound();
}
}
-
+
[HttpGet("{episodeID:int}/track")]
[HttpGet("{episodeID:int}/tracks")]
[PartialPermission(Kind.Read)]
@@ -123,10 +123,10 @@ namespace Kyoo.Core.Api
}
catch (ArgumentException ex)
{
- return BadRequest(new {Error = ex.Message});
+ return BadRequest(new { Error = ex.Message });
}
}
-
+
[HttpGet("{showID:int}-s{seasonNumber:int}e{episodeNumber:int}/track")]
[HttpGet("{showID:int}-s{seasonNumber:int}e{episodeNumber:int}/tracks")]
[PartialPermission(Kind.Read)]
@@ -141,7 +141,7 @@ namespace Kyoo.Core.Api
try
{
ICollection resources = await _libraryManager.GetAll(
- ApiHelper.ParseWhere(where, x => x.Episode.ShowID == showID
+ ApiHelper.ParseWhere(where, x => x.Episode.ShowID == showID
&& x.Episode.SeasonNumber == seasonNumber
&& x.Episode.EpisodeNumber == episodeNumber),
new Sort(sortBy),
@@ -153,10 +153,10 @@ namespace Kyoo.Core.Api
}
catch (ArgumentException ex)
{
- return BadRequest(new {Error = ex.Message});
+ return BadRequest(new { Error = ex.Message });
}
}
-
+
[HttpGet("{slug}-s{seasonNumber:int}e{episodeNumber:int}/track")]
[HttpGet("{slug}-s{seasonNumber:int}e{episodeNumber:int}/tracks")]
[PartialPermission(Kind.Read)]
@@ -171,7 +171,7 @@ namespace Kyoo.Core.Api
try
{
ICollection resources = await _libraryManager.GetAll(
- ApiHelper.ParseWhere(where, x => x.Episode.Show.Slug == slug
+ ApiHelper.ParseWhere(where, x => x.Episode.Show.Slug == slug
&& x.Episode.SeasonNumber == seasonNumber
&& x.Episode.EpisodeNumber == episodeNumber),
new Sort(sortBy),
@@ -183,10 +183,10 @@ namespace Kyoo.Core.Api
}
catch (ArgumentException ex)
{
- return BadRequest(new {Error = ex.Message});
+ return BadRequest(new { Error = ex.Message });
}
}
-
+
[HttpGet("{id:int}/thumbnail")]
[HttpGet("{id:int}/backdrop")]
public async Task GetThumb(int id)
@@ -201,7 +201,7 @@ namespace Kyoo.Core.Api
return NotFound();
}
}
-
+
[HttpGet("{slug}/thumbnail")]
[HttpGet("{slug}/backdrop")]
public async Task GetThumb(string slug)
@@ -217,4 +217,4 @@ namespace Kyoo.Core.Api
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Kyoo.Core/Views/GenreApi.cs b/Kyoo.Core/Views/GenreApi.cs
index d6e6a678..aa74aded 100644
--- a/Kyoo.Core/Views/GenreApi.cs
+++ b/Kyoo.Core/Views/GenreApi.cs
@@ -24,7 +24,7 @@ namespace Kyoo.Core.Api
{
_libraryManager = libraryManager;
}
-
+
[HttpGet("{id:int}/show")]
[HttpGet("{id:int}/shows")]
[PartialPermission(Kind.Read)]
@@ -47,10 +47,10 @@ namespace Kyoo.Core.Api
}
catch (ArgumentException ex)
{
- return BadRequest(new {Error = ex.Message});
+ return BadRequest(new { Error = ex.Message });
}
}
-
+
[HttpGet("{slug}/show")]
[HttpGet("{slug}/shows")]
[PartialPermission(Kind.Read)]
@@ -73,7 +73,7 @@ namespace Kyoo.Core.Api
}
catch (ArgumentException ex)
{
- return BadRequest(new {Error = ex.Message});
+ return BadRequest(new { Error = ex.Message });
}
}
}
diff --git a/Kyoo.Core/Views/Helper/ApiHelper.cs b/Kyoo.Core/Views/Helper/ApiHelper.cs
index 31e545c6..35d9cd88 100644
--- a/Kyoo.Core/Views/Helper/ApiHelper.cs
+++ b/Kyoo.Core/Views/Helper/ApiHelper.cs
@@ -21,8 +21,8 @@ namespace Kyoo.Core.Api
}
return operand(left, right);
}
-
- public static Expression> ParseWhere(Dictionary where,
+
+ public static Expression> ParseWhere(Dictionary where,
Expression> defaultWhere = null)
{
if (where == null || where.Count == 0)
@@ -35,7 +35,7 @@ namespace Kyoo.Core.Api
{
if (key == null || desired == null)
throw new ArgumentException("Invalid key/value pair. Can't be null.");
-
+
string value = desired;
string operand = "eq";
if (desired.Contains(':'))
@@ -68,15 +68,15 @@ namespace Kyoo.Core.Api
valueExpr = Expression.Constant(val, property.PropertyType);
}
-
+
Expression condition = operand switch
{
"eq" when isList => ContainsResourceExpression(propertyExpr, value),
"ctn" => ContainsResourceExpression(propertyExpr, value),
-
+
"eq" when valueExpr == null => ResourceEqual(propertyExpr, value),
"not" when valueExpr == null => ResourceEqual(propertyExpr, value, true),
-
+
"eq" => Expression.Equal(propertyExpr, valueExpr),
"not" => Expression.NotEqual(propertyExpr, valueExpr!),
"lt" => StringCompatibleExpression(Expression.LessThan, propertyExpr, valueExpr),
@@ -110,11 +110,11 @@ namespace Kyoo.Core.Api
valueConst = Expression.Constant(value);
}
- return notEqual
- ? Expression.NotEqual(field, valueConst)
+ return notEqual
+ ? Expression.NotEqual(field, valueConst)
: Expression.Equal(field, valueConst);
}
-
+
private static Expression ContainsResourceExpression(MemberExpression xProperty, string value)
{
// x => x.PROPERTY.Any(y => y.Slug == value)
diff --git a/Kyoo.Core/Views/Helper/CrudApi.cs b/Kyoo.Core/Views/Helper/CrudApi.cs
index ab1eef72..e8010d58 100644
--- a/Kyoo.Core/Views/Helper/CrudApi.cs
+++ b/Kyoo.Core/Views/Helper/CrudApi.cs
@@ -54,10 +54,10 @@ namespace Kyoo.Core.Api
}
catch (ArgumentException ex)
{
- return BadRequest(new {Error = ex.Message});
+ return BadRequest(new { Error = ex.Message });
}
}
-
+
[HttpGet]
[PartialPermission(Kind.Read)]
public virtual async Task>> GetAll([FromQuery] string sortBy,
@@ -75,7 +75,7 @@ namespace Kyoo.Core.Api
}
catch (ArgumentException ex)
{
- return BadRequest(new {Error = ex.Message});
+ return BadRequest(new { Error = ex.Message });
}
}
@@ -98,7 +98,7 @@ namespace Kyoo.Core.Api
}
catch (ArgumentException ex)
{
- return BadRequest(new {Error = ex.Message});
+ return BadRequest(new { Error = ex.Message });
}
catch (DuplicatedItemException)
{
@@ -106,7 +106,7 @@ namespace Kyoo.Core.Api
return Conflict(existing);
}
}
-
+
[HttpPut]
[PartialPermission(Kind.Write)]
public virtual async Task> Edit([FromQuery] bool resetOld, [FromBody] T resource)
@@ -140,7 +140,7 @@ namespace Kyoo.Core.Api
return NotFound();
}
}
-
+
[HttpPut("{slug}")]
[PartialPermission(Kind.Write)]
public virtual async Task> Edit(string slug, [FromQuery] bool resetOld, [FromBody] T resource)
@@ -172,7 +172,7 @@ namespace Kyoo.Core.Api
return Ok();
}
-
+
[HttpDelete("{slug}")]
[PartialPermission(Kind.Delete)]
public virtual async Task Delete(string slug)
@@ -188,7 +188,7 @@ namespace Kyoo.Core.Api
return Ok();
}
-
+
[PartialPermission(Kind.Delete)]
public virtual async Task Delete(Dictionary where)
{
diff --git a/Kyoo.Core/Views/Helper/JsonSerializer.cs b/Kyoo.Core/Views/Helper/JsonSerializer.cs
index 96d6d6ea..1cd78e05 100644
--- a/Kyoo.Core/Views/Helper/JsonSerializer.cs
+++ b/Kyoo.Core/Views/Helper/JsonSerializer.cs
@@ -81,7 +81,7 @@ namespace Kyoo.Core.Api
value.Show.People = null;
if (value.People != null)
value.People.Roles = null;
-
+
JObject obj = JObject.FromObject((value.ForPeople ? value.People : value.Show)!, serializer);
obj.Add("role", value.Role);
obj.Add("type", value.Type);
@@ -93,7 +93,7 @@ namespace Kyoo.Core.Api
value.People.Roles = oldRoles;
}
- public override PeopleRole ReadJson(JsonReader reader,
+ public override PeopleRole ReadJson(JsonReader reader,
Type objectType,
PeopleRole existingValue,
bool hasExistingValue,
@@ -113,7 +113,7 @@ namespace Kyoo.Core.Api
_format = format;
_host = host.TrimEnd('/');
}
-
+
public object GetValue(object target)
{
return Regex.Replace(_format, @"(?
@@ -123,7 +123,7 @@ namespace Kyoo.Core.Api
if (value == "HOST")
return _host;
-
+
PropertyInfo properties = target.GetType()
.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
.FirstOrDefault(y => y.Name == value);
@@ -147,7 +147,7 @@ namespace Kyoo.Core.Api
return ret;
});
}
-
+
public void SetValue(object target, object value)
{
// Values are ignored and should not be editable, except if the internal value is set.
diff --git a/Kyoo.Core/Views/Helper/ResourceViewAttribute.cs b/Kyoo.Core/Views/Helper/ResourceViewAttribute.cs
index ad4d9055..b3d3a2a8 100644
--- a/Kyoo.Core/Views/Helper/ResourceViewAttribute.cs
+++ b/Kyoo.Core/Views/Helper/ResourceViewAttribute.cs
@@ -40,7 +40,7 @@ namespace Kyoo.Core.Api
type = Utility.GetGenericDefinition(type, typeof(Task<>))?.GetGenericArguments()[0] ?? type;
type = Utility.GetGenericDefinition(type, typeof(ActionResult<>))?.GetGenericArguments()[0] ?? type;
type = Utility.GetGenericDefinition(type, typeof(Page<>))?.GetGenericArguments()[0] ?? type;
-
+
PropertyInfo[] properties = type.GetProperties()
.Where(x => x.GetCustomAttribute() != null)
.ToArray();
@@ -90,7 +90,7 @@ namespace Kyoo.Core.Api
ICollection fields = (ICollection)context.HttpContext.Items["fields"];
Type pageType = Utility.GetGenericDefinition(result.DeclaredType, typeof(Page<>));
-
+
if (pageType != null)
{
foreach (IResource resource in ((dynamic)result.Value).Items)
diff --git a/Kyoo.Core/Views/LibraryApi.cs b/Kyoo.Core/Views/LibraryApi.cs
index 6dd4faba..454b8836 100644
--- a/Kyoo.Core/Views/LibraryApi.cs
+++ b/Kyoo.Core/Views/LibraryApi.cs
@@ -34,7 +34,7 @@ namespace Kyoo.Core.Api
if (result.Value != null)
_taskManager.StartTask("scan",
new Progress(),
- new Dictionary {{"slug", result.Value.Slug}});
+ new Dictionary