diff --git a/Kyoo.Authentication/AuthenticationModule.cs b/Kyoo.Authentication/AuthenticationModule.cs
index 9c7c3687..8e2c78c4 100644
--- a/Kyoo.Authentication/AuthenticationModule.cs
+++ b/Kyoo.Authentication/AuthenticationModule.cs
@@ -84,7 +84,7 @@ namespace Kyoo.Authentication
///
public void Configure(IServiceCollection services, ICollection availableTypes)
{
- string publicUrl = _configuration.GetValue("publicUrl").TrimEnd('/');
+ string publicUrl = _configuration.GetPublicUrl();
if (_environment.IsDevelopment())
IdentityModelEventSource.ShowPII = true;
@@ -98,6 +98,7 @@ namespace Kyoo.Authentication
services.Configure(_configuration.GetSection(PermissionOption.Path));
services.Configure(_configuration.GetSection(CertificateOption.Path));
services.Configure(_configuration.GetSection(AuthenticationOption.Path));
+ services.AddConfiguration(AuthenticationOption.Path);
List clients = new();
@@ -145,7 +146,7 @@ namespace Kyoo.Authentication
app.UseAuthentication();
app.Use((ctx, next) =>
{
- ctx.SetIdentityServerOrigin(_configuration.GetValue("publicUrl").TrimEnd('/'));
+ ctx.SetIdentityServerOrigin(_configuration.GetPublicUrl());
return next();
});
app.UseIdentityServer();
diff --git a/Kyoo.Authentication/Controllers/PremissionValidator.cs b/Kyoo.Authentication/Controllers/PremissionValidator.cs
index dc60faa7..ca3102ed 100644
--- a/Kyoo.Authentication/Controllers/PremissionValidator.cs
+++ b/Kyoo.Authentication/Controllers/PremissionValidator.cs
@@ -36,7 +36,7 @@ namespace Kyoo.Authentication
///
public IFilterMetadata Create(PermissionAttribute attribute)
{
- return new PermissionValidator(attribute.Type, attribute.Kind, _options);
+ return new PermissionValidator(attribute.Type, attribute.Kind, attribute.Group, _options);
}
///
@@ -58,6 +58,11 @@ namespace Kyoo.Authentication
/// The kind of permission needed
///
private readonly Kind? _kind;
+
+ ///
+ /// The group of he permission
+ ///
+ private readonly Group _group = Group.Overall;
///
/// The permissions options to retrieve default permissions.
///
@@ -68,11 +73,13 @@ namespace Kyoo.Authentication
///
/// The permission to validate
/// The kind of permission needed
+ /// The group of the permission
/// The option containing default values.
- public PermissionValidator(string permission, Kind kind, IOptionsMonitor options)
+ public PermissionValidator(string permission, Kind kind, Group group, IOptionsMonitor options)
{
_permission = permission;
_kind = kind;
+ _group = group;
_options = options;
}
@@ -125,7 +132,7 @@ namespace Kyoo.Authentication
}
string permStr = $"{permission.ToLower()}.{kind.ToString()!.ToLower()}";
- string overallStr = $"overall.{kind.ToString()!.ToLower()}";
+ string overallStr = $"{_group.ToString().ToLower()}.{kind.ToString()!.ToLower()}";
AuthenticateResult res = await context.HttpContext.AuthenticateAsync(JwtBearerDefaults.AuthenticationScheme);
if (res.Succeeded)
{
diff --git a/Kyoo.Common/Controllers/IConfigurationManager.cs b/Kyoo.Common/Controllers/IConfigurationManager.cs
new file mode 100644
index 00000000..9159d92c
--- /dev/null
+++ b/Kyoo.Common/Controllers/IConfigurationManager.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Threading.Tasks;
+using Kyoo.Models;
+using Kyoo.Models.Exceptions;
+
+namespace Kyoo.Controllers
+{
+ ///
+ /// A class to ease configuration management. This work WITH Microsoft's package, you can still use IOptions patterns
+ /// to access your options, this manager ease dynamic work and editing.
+ /// It works with .
+ ///
+ public interface IConfigurationManager
+ {
+ ///
+ /// Get the value of a setting using it's path.
+ ///
+ /// The path of the resource (can be separated by ':' or '__')
+ /// No setting found at the given path.
+ /// The value of the settings (if it's a strongly typed one, the given type is instantiated
+ object GetValue(string path);
+
+ ///
+ /// Get the value of a setting using it's path.
+ /// If your don't need a strongly typed value, see .
+ ///
+ /// The path of the resource (can be separated by ':' or '__')
+ /// A type to strongly type your option.
+ /// If your type is not the same as the registered type
+ /// No setting found at the given path.
+ /// The value of the settings (if it's a strongly typed one, the given type is instantiated
+ T GetValue(string path);
+
+ ///
+ /// Edit the value of a setting using it's path. Save it to the json file.
+ ///
+ /// The path of the resource (can be separated by ':' or '__')
+ /// The new value of the resource
+ /// No setting found at the given path.
+ Task EditValue(string path, object value);
+ }
+}
\ No newline at end of file
diff --git a/Kyoo.Common/Models/Account.cs b/Kyoo.Common/Models/Account.cs
deleted file mode 100644
index a3f51c61..00000000
--- a/Kyoo.Common/Models/Account.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace Kyoo.Models
-{
- public class Account
- {
- public string Username { get; set; }
- public string Email { get; set; }
- public string Picture { get; set; }
- }
-}
\ No newline at end of file
diff --git a/Kyoo.Common/Models/Attributes/PermissionAttribute.cs b/Kyoo.Common/Models/Attributes/PermissionAttribute.cs
index b34fb48b..24de7950 100644
--- a/Kyoo.Common/Models/Attributes/PermissionAttribute.cs
+++ b/Kyoo.Common/Models/Attributes/PermissionAttribute.cs
@@ -14,6 +14,15 @@ namespace Kyoo.Models.Permissions
Create,
Delete
}
+
+ ///
+ /// The group of the permission.
+ ///
+ public enum Group
+ {
+ Overall,
+ Admin
+ }
///
/// Specify permissions needed for the API.
@@ -29,6 +38,10 @@ namespace Kyoo.Models.Permissions
/// The needed permission kind.
///
public Kind Kind { get; }
+ ///
+ /// The group of this permission
+ ///
+ public Group Group { get; }
///
/// Ask a permission to run an action.
@@ -38,12 +51,17 @@ namespace Kyoo.Models.Permissions
/// (if the type ends with api, it will be removed. This allow you to use nameof(YourApi)).
///
/// The kind of permission needed
- public PermissionAttribute(string type, Kind permission)
+ ///
+ /// The group of this permission (allow grouped permission like overall.read
+ /// for all read permissions of this group)
+ ///
+ public PermissionAttribute(string type, Kind permission, Group group = Group.Overall)
{
if (type.EndsWith("API", StringComparison.OrdinalIgnoreCase))
type = type[..^3];
Type = type.ToLower();
Kind = permission;
+ Group = group;
}
///
diff --git a/Kyoo.Common/Models/ConfigurationReference.cs b/Kyoo.Common/Models/ConfigurationReference.cs
new file mode 100644
index 00000000..00d20b4c
--- /dev/null
+++ b/Kyoo.Common/Models/ConfigurationReference.cs
@@ -0,0 +1,97 @@
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using JetBrains.Annotations;
+
+namespace Kyoo.Models
+{
+ ///
+ /// A class given information about a strongly typed configuration.
+ ///
+ public class ConfigurationReference
+ {
+ ///
+ /// The path of the resource (separated by ':')
+ ///
+ public string Path { get; }
+
+ ///
+ /// The type of the resource.
+ ///
+ public Type Type { get; }
+
+
+ ///
+ /// Create a new using a given path and type.
+ /// This method does not create sub configuration resources. Please see
+ ///
+ /// The path of the resource (separated by ':' or "__")
+ /// The type of the resource
+ ///
+ public ConfigurationReference(string path, Type type)
+ {
+ Path = path;
+ Type = type;
+ }
+
+ ///
+ /// Return the list of configuration reference a type has.
+ ///
+ ///
+ /// The base path of the type (separated by ':' or "__". If empty, it will start at root)
+ ///
+ /// The type of the object
+ /// The list of configuration reference a type has.
+ public static IEnumerable CreateReference(string path, [NotNull] Type type)
+ {
+ if (type == null)
+ throw new ArgumentNullException(nameof(type));
+
+ List ret = new()
+ {
+ new ConfigurationReference(path, type)
+ };
+
+
+ if (!type.IsClass || type.AssemblyQualifiedName?.StartsWith("System") == true)
+ return ret;
+
+ Type enumerable = Utility.GetGenericDefinition(type, typeof(IEnumerable<>));
+ Type dictionary = Utility.GetGenericDefinition(type, typeof(IDictionary<,>));
+ Type dictionaryKey = dictionary?.GetGenericArguments()[0];
+
+ if (dictionary != null && dictionaryKey == typeof(string))
+ ret.AddRange(CreateReference($"{path}:{type.Name}:*", dictionary.GetGenericArguments()[1]));
+ else if (dictionary != null && dictionaryKey == typeof(int))
+ ret.AddRange(CreateReference($"{path}:{type.Name}:", dictionary.GetGenericArguments()[1]));
+ else if (enumerable != null)
+ ret.AddRange(CreateReference($"{path}:{type.Name}:", enumerable.GetGenericArguments()[0]));
+ else
+ {
+ foreach (PropertyInfo child in type.GetProperties())
+ ret.AddRange(CreateReference($"{path}:{child.Name}", child.PropertyType));
+ }
+
+ return ret;
+ }
+
+ ///
+ /// Return the list of configuration reference a type has.
+ ///
+ ///
+ /// The base path of the type (separated by ':' or "__". If empty, it will start at root)
+ ///
+ /// The type of the object
+ /// The list of configuration reference a type has.
+ public static IEnumerable CreateReference(string path)
+ {
+ return CreateReference(path, typeof(T));
+ }
+
+
+ public static ConfigurationReference CreateUntyped(string path)
+ {
+ return new(path, null);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Kyoo.Common/Models/ImageTypes.cs b/Kyoo.Common/Models/ImageTypes.cs
deleted file mode 100644
index 6dea10d4..00000000
--- a/Kyoo.Common/Models/ImageTypes.cs
+++ /dev/null
@@ -1,4 +0,0 @@
-namespace Kyoo.Models
-{
- public enum ImageType { Poster, Background, Logo }
-}
\ No newline at end of file
diff --git a/Kyoo.Common/Module.cs b/Kyoo.Common/Module.cs
index c1c09165..a8a81b88 100644
--- a/Kyoo.Common/Module.cs
+++ b/Kyoo.Common/Module.cs
@@ -1,5 +1,8 @@
using System;
+using System.Linq;
using Kyoo.Controllers;
+using Kyoo.Models;
+using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace Kyoo
@@ -62,5 +65,46 @@ namespace Kyoo
services.Add(ServiceDescriptor.Describe(typeof(T), typeof(T2), lifetime));
return services.AddRepository(lifetime);
}
+
+ ///
+ /// Add an editable configuration to the editable configuration list
+ ///
+ /// The service collection to edit
+ /// The root path of the editable configuration. It should not be a nested type.
+ /// The type of the configuration
+ /// The given service collection is returned.
+ public static IServiceCollection AddConfiguration(this IServiceCollection services, string path)
+ where T : class
+ {
+ if (services.Any(x => x.ServiceType == typeof(T)))
+ return services;
+ foreach (ConfigurationReference confRef in ConfigurationReference.CreateReference(path))
+ services.AddSingleton(confRef);
+ return services;
+ }
+
+ ///
+ /// Add an editable configuration to the editable configuration list.
+ /// WARNING: this method allow you to add an unmanaged type. This type won't be editable. This can be used
+ /// for external libraries or variable arguments.
+ ///
+ /// The service collection to edit
+ /// The root path of the editable configuration. It should not be a nested type.
+ /// The given service collection is returned.
+ public static IServiceCollection AddUntypedConfiguration(this IServiceCollection services, string path)
+ {
+ services.AddSingleton(ConfigurationReference.CreateUntyped(path));
+ return services;
+ }
+
+ ///
+ /// Get the public URL of kyoo using the given configuration instance.
+ ///
+ /// The configuration instance
+ /// The public URl of kyoo (without a slash at the end)
+ public static string GetPublicUrl(this IConfiguration configuration)
+ {
+ return configuration["basics:publicUrl"]?.TrimEnd('/') ?? "http://localhost:5000";
+ }
}
}
\ No newline at end of file
diff --git a/Kyoo.Common/Utility.cs b/Kyoo.Common/Utility.cs
index 6583f704..743cf545 100644
--- a/Kyoo.Common/Utility.cs
+++ b/Kyoo.Common/Utility.cs
@@ -10,7 +10,6 @@ using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using JetBrains.Annotations;
-using Kyoo.Models;
using Kyoo.Models.Attributes;
namespace Kyoo
@@ -33,7 +32,7 @@ namespace Kyoo
}
///
- /// Get the name of a property. Usfull for selectors as members ex: Load(x => x.Shows)
+ /// Get the name of a property. Useful for selectors as members ex: Load(x => x.Shows)
///
/// The expression
/// The name of the expression
@@ -71,10 +70,10 @@ namespace Kyoo
}
///
- /// Slugify a string (Replace spaces by -, Uniformise accents é -> e)
+ /// Slugify a string (Replace spaces by -, Uniformize accents é -> e)
///
/// The string to slugify
- /// The slugified string
+ /// The slug version of the given string
public static string ToSlug(string str)
{
if (str == null)
@@ -98,37 +97,12 @@ namespace Kyoo
str = Regex.Replace(str, @"([-_]){2,}", "$1", RegexOptions.Compiled);
return str;
}
-
-
- ///
- /// Set the image of a show using the type.
- ///
- /// The owner of the image
- /// The url of the image
- /// The type of the image
- public static void SetImage(Show show, string imgUrl, ImageType type)
- {
- switch(type)
- {
- case ImageType.Poster:
- show.Poster = imgUrl;
- break;
- case ImageType.Logo:
- show.Logo = imgUrl;
- break;
- case ImageType.Background:
- show.Backdrop = imgUrl;
- break;
- default:
- throw new ArgumentOutOfRangeException(nameof(type), type, null);
- }
- }
///
/// Merge two lists, can keep duplicates or remove them.
///
- /// The first enumarble to merge
- /// The second enumerable to merge, if items from this list are equals to one from the first, they are not keeped
+ /// The first enumerable to merge
+ /// The second enumerable to merge, if items from this list are equals to one from the first, they are not kept
/// Equality function to compare items. If this is null, duplicated elements are kept
/// The two list merged as an array
public static T[] MergeLists(IEnumerable first,
@@ -150,7 +124,7 @@ namespace Kyoo
/// At the end, the OnMerge method of first will be called if first is a
///
/// The object to assign
- /// The object containg new values
+ /// The object containing new values
/// Fields of T will be used
///
public static T Assign(T first, T second)
@@ -339,7 +313,7 @@ namespace Kyoo
///
/// The type to check
/// The generic type to check against (Only generic types are supported like typeof(IEnumerable<>).
- /// The generic definition of genericType that type inherit or null if type does not implement the genric type.
+ /// The generic definition of genericType that type inherit or null if type does not implement the generic type.
/// and can't be null
/// must be a generic type
public static Type GetGenericDefinition([NotNull] Type type, [NotNull] Type genericType)
diff --git a/Kyoo.CommonAPI/CrudApi.cs b/Kyoo.CommonAPI/CrudApi.cs
index 75a2758c..b6d03580 100644
--- a/Kyoo.CommonAPI/CrudApi.cs
+++ b/Kyoo.CommonAPI/CrudApi.cs
@@ -7,7 +7,6 @@ using Kyoo.Models;
using Kyoo.Models.Exceptions;
using Kyoo.Models.Permissions;
using Microsoft.AspNetCore.Mvc;
-using Microsoft.Extensions.Configuration;
namespace Kyoo.CommonApi
{
@@ -18,10 +17,10 @@ namespace Kyoo.CommonApi
private readonly IRepository _repository;
protected readonly string BaseURL;
- public CrudApi(IRepository repository, IConfiguration configuration)
+ public CrudApi(IRepository repository, string baseURL)
{
_repository = repository;
- BaseURL = configuration.GetValue("publicUrl").TrimEnd('/');
+ BaseURL = baseURL;
}
diff --git a/Kyoo.Postgresql/PostgresModule.cs b/Kyoo.Postgresql/PostgresModule.cs
index 7a818296..f0c8f23c 100644
--- a/Kyoo.Postgresql/PostgresModule.cs
+++ b/Kyoo.Postgresql/PostgresModule.cs
@@ -66,10 +66,6 @@ namespace Kyoo.Postgresql
if (_environment.IsDevelopment())
x.EnableDetailedErrors().EnableSensitiveDataLogging();
});
- // services.AddScoped(_ => new PostgresContext(
- // _configuration.GetDatabaseConnection("postgres"),
- // _environment.IsDevelopment()));
- // services.AddScoped(x => x.GetRequiredService());
}
///
diff --git a/Kyoo/Controllers/ConfigurationManager.cs b/Kyoo/Controllers/ConfigurationManager.cs
new file mode 100644
index 00000000..c0a63895
--- /dev/null
+++ b/Kyoo/Controllers/ConfigurationManager.cs
@@ -0,0 +1,150 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+using System.Dynamic;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+using Kyoo.Api;
+using Kyoo.Models;
+using Kyoo.Models.Exceptions;
+using Microsoft.Extensions.Configuration;
+using Newtonsoft.Json.Linq;
+
+namespace Kyoo.Controllers
+{
+ public class ConfigurationManager : IConfigurationManager
+ {
+ ///
+ /// The configuration to retrieve and edit.
+ ///
+ private readonly IConfiguration _configuration;
+
+ ///
+ /// The strongly typed list of options
+ ///
+ private readonly Dictionary _references;
+
+ ///
+ /// Create a new using the given configuration.
+ ///
+ /// The configuration to use.
+ /// The strongly typed option list.
+ public ConfigurationManager(IConfiguration configuration, IEnumerable references)
+ {
+ _configuration = configuration;
+ _references = references.ToDictionary(x => x.Path, x => x.Type, StringComparer.OrdinalIgnoreCase);
+ }
+
+ private Type GetType(string path)
+ {
+ path = path.Replace("__", ":");
+
+ // TODO handle lists and dictionaries.
+ if (_references.TryGetValue(path, out Type type))
+ {
+ if (type != null)
+ return type;
+ throw new ArgumentException($"The configuration at {path} is not editable or readable.");
+ }
+
+ string parent = path.Contains(':') ? path[..path.IndexOf(':')] : null;
+ if (parent != null && _references.TryGetValue(parent, out type) && type == null)
+ 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)
+ {
+ path = path.Replace("__", ":");
+ // TODO handle lists and dictionaries.
+ Type type = GetType(path);
+ object ret = _configuration.GetValue(type, path);
+ if (ret != null)
+ return ret;
+ object option = Activator.CreateInstance(type);
+ _configuration.Bind(path, option);
+ return option;
+ }
+
+ ///
+ public T GetValue(string path)
+ {
+ path = path.Replace("__", ":");
+ // TODO handle lists and dictionaries.
+ Type type = GetType(path);
+ if (typeof(T).IsAssignableFrom(type))
+ throw new InvalidCastException($"The type {typeof(T).Name} is not valid for " +
+ $"a resource of type {type.Name}.");
+ return (T)GetValue(path);
+ }
+
+ ///
+ public async Task EditValue(string path, object value)
+ {
+ path = path.Replace("__", ":");
+ Type type = GetType(path);
+ 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;
+ JObject obj = JObject.FromObject(config);
+ await using StreamWriter writer = new(Program.JsonConfigPath);
+ 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.
+ ///
+ /// The configuration to transform
+ /// A strongly typed representation of the configuration.
+ [SuppressMessage("ReSharper", "RedundantJumpStatement")]
+ private ExpandoObject ToObject(IConfiguration config)
+ {
+ ExpandoObject obj = new();
+
+ foreach (IConfigurationSection section in config.GetChildren())
+ {
+ try
+ {
+ Type type = GetType(section.Path);
+ obj.TryAdd(section.Key, section.Get(type));
+ }
+ catch (ArgumentException)
+ {
+ obj.TryAdd(section.Key, ToUntyped(section));
+ }
+ catch
+ {
+ continue;
+ }
+ }
+
+ return obj;
+ }
+
+ ///
+ /// Transform the configuration section in nested expando objects.
+ ///
+ /// The section to convert
+ /// The converted section
+ private static object ToUntyped(IConfigurationSection config)
+ {
+ ExpandoObject obj = new();
+
+ foreach (IConfigurationSection section in config.GetChildren())
+ {
+ obj.TryAdd(section.Key, ToUntyped(section));
+ }
+
+ if (!obj.Any())
+ return config.Value;
+ return obj;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Kyoo/Controllers/PluginManager.cs b/Kyoo/Controllers/PluginManager.cs
index 321d2f57..7d0c399b 100644
--- a/Kyoo/Controllers/PluginManager.cs
+++ b/Kyoo/Controllers/PluginManager.cs
@@ -4,10 +4,11 @@ using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Loader;
+using Kyoo.Models.Options;
using Microsoft.AspNetCore.Builder;
-using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
namespace Kyoo.Controllers
{
@@ -24,7 +25,7 @@ namespace Kyoo.Controllers
///
/// The configuration to get the plugin's directory.
///
- private readonly IConfiguration _config;
+ private readonly IOptionsMonitor _options;
///
/// The logger used by this class.
///
@@ -39,14 +40,14 @@ namespace Kyoo.Controllers
/// Create a new instance.
///
/// A service container to allow initialization of plugins
- /// The configuration instance, to get the plugin's directory path.
+ /// The configuration instance, to get the plugin's directory path.
/// The logger used by this class.
public PluginManager(IServiceProvider provider,
- IConfiguration config,
+ IOptionsMonitor options,
ILogger logger)
{
_provider = provider;
- _config = config;
+ _options = options;
_logger = logger;
}
@@ -97,7 +98,7 @@ namespace Kyoo.Controllers
///
public void LoadPlugins(ICollection plugins)
{
- string pluginFolder = _config.GetValue("plugins");
+ string pluginFolder = _options.CurrentValue.PluginPath;
if (!Directory.Exists(pluginFolder))
Directory.CreateDirectory(pluginFolder);
diff --git a/Kyoo/Controllers/TaskManager.cs b/Kyoo/Controllers/TaskManager.cs
index 5f281ba3..caa7a01d 100644
--- a/Kyoo/Controllers/TaskManager.cs
+++ b/Kyoo/Controllers/TaskManager.cs
@@ -7,10 +7,11 @@ using System.Threading.Tasks;
using JetBrains.Annotations;
using Kyoo.Models.Attributes;
using Kyoo.Models.Exceptions;
-using Microsoft.Extensions.Configuration;
+using Kyoo.Models.Options;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
namespace Kyoo.Controllers
{
@@ -27,7 +28,7 @@ namespace Kyoo.Controllers
///
/// The configuration instance used to get schedule information
///
- private readonly IConfiguration _configuration;
+ private readonly IOptionsMonitor _options;
///
/// The logger instance.
///
@@ -56,15 +57,15 @@ namespace Kyoo.Controllers
///
/// The list of tasks to manage
/// The service provider to request services for tasks
- /// The configuration to load schedule information.
+ /// The configuration to load schedule information.
/// The logger.
public TaskManager(IEnumerable tasks,
IServiceProvider provider,
- IConfiguration configuration,
+ IOptionsMonitor options,
ILogger logger)
{
_provider = provider;
- _configuration = configuration.GetSection("scheduledTasks");
+ _options = options;
_logger = logger;
_tasks = tasks.Select(x => (x, GetNextTaskDate(x.Slug))).ToList();
@@ -224,10 +225,9 @@ namespace Kyoo.Controllers
/// The next date.
private DateTime GetNextTaskDate(string taskSlug)
{
- TimeSpan delay = _configuration.GetValue(taskSlug);
- if (delay == default)
- return DateTime.MaxValue;
- return DateTime.Now + delay;
+ if (_options.CurrentValue.Scheduled.TryGetValue(taskSlug, out TimeSpan delay))
+ return DateTime.Now + delay;
+ return DateTime.MaxValue;
}
///
diff --git a/Kyoo/Controllers/ThumbnailsManager.cs b/Kyoo/Controllers/ThumbnailsManager.cs
index b75e3231..1e84cef6 100644
--- a/Kyoo/Controllers/ThumbnailsManager.cs
+++ b/Kyoo/Controllers/ThumbnailsManager.cs
@@ -1,26 +1,25 @@
using Kyoo.Models;
-using Microsoft.Extensions.Configuration;
using System;
using System.IO;
using System.Net;
using System.Threading.Tasks;
using JetBrains.Annotations;
+using Kyoo.Models.Options;
+using Microsoft.Extensions.Options;
namespace Kyoo.Controllers
{
public class ThumbnailsManager : IThumbnailsManager
{
private readonly IFileManager _files;
- private readonly string _peoplePath;
- private readonly string _providerPath;
+ private readonly IOptionsMonitor _options;
- public ThumbnailsManager(IConfiguration configuration, IFileManager files)
+ public ThumbnailsManager(IFileManager files, IOptionsMonitor options)
{
_files = files;
- _peoplePath = Path.GetFullPath(configuration.GetValue("peoplePath"));
- _providerPath = Path.GetFullPath(configuration.GetValue("providerPath"));
- Directory.CreateDirectory(_peoplePath);
- Directory.CreateDirectory(_providerPath);
+ _options = options;
+ Directory.CreateDirectory(_options.CurrentValue.PeoplePath);
+ Directory.CreateDirectory(_options.CurrentValue.ProviderPath);
}
private static async Task DownloadImage(string url, string localPath, string what)
@@ -141,16 +140,18 @@ namespace Kyoo.Controllers
{
if (people == null)
throw new ArgumentNullException(nameof(people));
- string thumbPath = Path.GetFullPath(Path.Combine(_peoplePath, $"{people.Slug}.jpg"));
- return Task.FromResult(thumbPath.StartsWith(_peoplePath) ? thumbPath : null);
+ string peoplePath = _options.CurrentValue.PeoplePath;
+ string thumbPath = Path.GetFullPath(Path.Combine(peoplePath, $"{people.Slug}.jpg"));
+ return Task.FromResult(thumbPath.StartsWith(peoplePath) ? thumbPath : null);
}
public Task GetProviderLogo(Provider provider)
{
if (provider == null)
throw new ArgumentNullException(nameof(provider));
- string thumbPath = Path.GetFullPath(Path.Combine(_providerPath, $"{provider.Slug}.{provider.LogoExtension}"));
- return Task.FromResult(thumbPath.StartsWith(_providerPath) ? thumbPath : null);
+ string providerPath = _options.CurrentValue.ProviderPath;
+ string thumbPath = Path.GetFullPath(Path.Combine(providerPath, $"{provider.Slug}.{provider.LogoExtension}"));
+ return Task.FromResult(thumbPath.StartsWith(providerPath) ? thumbPath : null);
}
}
}
diff --git a/Kyoo/Controllers/Transcoder.cs b/Kyoo/Controllers/Transcoder.cs
index 54cb5bfc..823aa9d2 100644
--- a/Kyoo/Controllers/Transcoder.cs
+++ b/Kyoo/Controllers/Transcoder.cs
@@ -3,7 +3,8 @@ using System.IO;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Kyoo.Models;
-using Microsoft.Extensions.Configuration;
+using Kyoo.Models.Options;
+using Microsoft.Extensions.Options;
using Stream = Kyoo.Models.Watch.Stream;
// We use threads so tasks are not always awaited.
@@ -66,20 +67,18 @@ namespace Kyoo.Controllers
tracks = Array.Empty