diff --git a/Kyoo.Common/Controllers/IThumbnailsManager.cs b/Kyoo.Common/Controllers/IThumbnailsManager.cs index 0e966b12..32666e84 100644 --- a/Kyoo.Common/Controllers/IThumbnailsManager.cs +++ b/Kyoo.Common/Controllers/IThumbnailsManager.cs @@ -9,6 +9,7 @@ namespace Kyoo.Controllers Task Validate(Show show, bool alwaysDownload = false); Task Validate(Season season, bool alwaysDownload = false); Task Validate(Episode episode, bool alwaysDownload = false); - Task> Validate(IEnumerable actors, bool alwaysDownload = false); + Task Validate(People actors, bool alwaysDownload = false); + Task Validate(ProviderID actors, bool alwaysDownload = false); } } diff --git a/Kyoo.Common/Models/Resources/Collection.cs b/Kyoo.Common/Models/Resources/Collection.cs index b1274278..3c7bed25 100644 --- a/Kyoo.Common/Models/Resources/Collection.cs +++ b/Kyoo.Common/Models/Resources/Collection.cs @@ -8,7 +8,7 @@ namespace Kyoo.Models public int ID { get; set; } public string Slug { get; set; } public string Name { get; set; } - [SerializeAs("{HOST}/api/library/{Slug}/poster")] public string Poster { get; set; } + [SerializeAs("{HOST}/api/collection/{Slug}/poster")] public string Poster { get; set; } public string Overview { get; set; } [LoadableRelation] public virtual ICollection Shows { get; set; } [LoadableRelation] public virtual ICollection Libraries { get; set; } diff --git a/Kyoo.Common/Models/Resources/ProviderID.cs b/Kyoo.Common/Models/Resources/ProviderID.cs index a874d09e..85374979 100644 --- a/Kyoo.Common/Models/Resources/ProviderID.cs +++ b/Kyoo.Common/Models/Resources/ProviderID.cs @@ -8,7 +8,7 @@ namespace Kyoo.Models public int ID { get; set; } public string Slug { get; set; } public string Name { get; set; } - public string Logo { get; set; } + [SerializeAs("{HOST}/api/providers/{Slug}/logo")] public string Logo { get; set; } [LoadableRelation] public virtual ICollection Libraries { get; set; } diff --git a/Kyoo/Controllers/TaskManager.cs b/Kyoo/Controllers/TaskManager.cs index 9a791fdc..519fb43f 100644 --- a/Kyoo/Controllers/TaskManager.cs +++ b/Kyoo/Controllers/TaskManager.cs @@ -110,7 +110,7 @@ namespace Kyoo.Controllers _tasks.AddRange(CoreTaskHolder.Tasks.Select(x => (x, DateTime.Now + GetTaskDelay(x.Slug)))); IEnumerable prerunTasks = _tasks.Select(x => x.task) - .Where(x => x.RunOnStartup && x.Priority == Int32.MaxValue); + .Where(x => x.RunOnStartup && x.Priority == int.MaxValue); foreach (ITask task in prerunTasks) task.Run(_serviceProvider, _taskToken.Token); diff --git a/Kyoo/Controllers/ThumbnailsManager.cs b/Kyoo/Controllers/ThumbnailsManager.cs index ac4aeeec..783e7a0a 100644 --- a/Kyoo/Controllers/ThumbnailsManager.cs +++ b/Kyoo/Controllers/ThumbnailsManager.cs @@ -1,10 +1,10 @@ using Kyoo.Models; using Microsoft.Extensions.Configuration; using System; -using System.Collections.Generic; using System.IO; using System.Net; using System.Threading.Tasks; +using JetBrains.Annotations; namespace Kyoo.Controllers { @@ -26,7 +26,7 @@ namespace Kyoo.Controllers } catch (WebException exception) { - await Console.Error.WriteLineAsync($"{what} could not be downloaded.\n\tError: {exception.Message}."); + await Console.Error.WriteLineAsync($"{what} could not be downloaded. Error: {exception.Message}."); } } @@ -53,26 +53,23 @@ namespace Kyoo.Controllers if (alwaysDownload || !File.Exists(backdropPath)) await DownloadImage(show.Backdrop, backdropPath, $"The backdrop of {show.Title}"); } + + foreach (PeopleRole role in show.People) + await Validate(role.People, alwaysDownload); return show; } - public async Task> Validate(IEnumerable people, bool alwaysDownload) + public async Task Validate([NotNull] People people, bool alwaysDownload) { if (people == null) - return null; - + throw new ArgumentNullException(nameof(people)); string root = _config.GetValue("peoplePath"); - Directory.CreateDirectory(root); + string localPath = Path.Combine(root, people.Slug + ".jpg"); - foreach (PeopleRole peop in people) - { - string localPath = Path.Combine(root, peop.People.Slug + ".jpg"); - if (peop.People.Poster == null) - continue; - if (alwaysDownload || !File.Exists(localPath)) - await DownloadImage(peop.People.Poster, localPath, $"The profile picture of {peop.People.Name}"); - } + Directory.CreateDirectory(root); + if (alwaysDownload || !File.Exists(localPath)) + await DownloadImage(people.Poster, localPath, $"The profile picture of {people.Name}"); return people; } @@ -100,9 +97,25 @@ namespace Kyoo.Controllers { string localPath = Path.ChangeExtension(episode.Path, "jpg"); if (alwaysDownload || !File.Exists(localPath)) - await DownloadImage(episode.Thumb, localPath, $"The thumbnail of {episode.Show.Title}"); + await DownloadImage(episode.Thumb, localPath, $"The thumbnail of {episode.Slug}"); } return episode; } + + public async Task Validate(ProviderID provider, bool alwaysDownload) + { + if (provider.Logo == null) + return provider; + + string root = _config.GetValue("peoplePath"); + string localPath = Path.Combine(root, provider.Slug + ".jpg"); + + Directory.CreateDirectory(root); + if (alwaysDownload || !File.Exists(localPath)) + await DownloadImage(provider.Logo, localPath, $"The thumbnail of {provider.Slug}"); + return provider; + } + + //TODO add get thumbs here } } diff --git a/Kyoo/Startup.cs b/Kyoo/Startup.cs index 72666c57..7cede9d7 100644 --- a/Kyoo/Startup.cs +++ b/Kyoo/Startup.cs @@ -43,6 +43,10 @@ namespace Kyoo { configuration.RootPath = Path.Join(AppDomain.CurrentDomain.BaseDirectory, "wwwroot"); }); + services.AddResponseCompression(x => + { + x.EnableForHttps = true; + }); services.AddControllers() .AddNewtonsoftJson(x => @@ -187,7 +191,20 @@ namespace Kyoo app.UseRouting(); - app.UseCookiePolicy(new CookiePolicyOptions + // app.Use((ctx, next) => + // { + // ctx.Response.Headers.Remove("X-Powered-By"); + // ctx.Response.Headers.Remove("Server"); + // ctx.Response.Headers.Add("Feature-Policy", "autoplay 'self'; fullscreen"); + // ctx.Response.Headers.Add("Content-Security-Policy", "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'"); + // ctx.Response.Headers.Add("X-Frame-Options", "SAMEORIGIN"); + // ctx.Response.Headers.Add("Referrer-Policy", "no-referrer"); + // ctx.Response.Headers.Add("Access-Control-Allow-Origin", "null"); + // ctx.Response.Headers.Add("X-Content-Type-Options", "nosniff"); + // return next(); + // }); + app.UseResponseCompression(); + app.UseCookiePolicy(new CookiePolicyOptions { MinimumSameSitePolicy = SameSiteMode.Strict }); diff --git a/Kyoo/Tasks/Crawler.cs b/Kyoo/Tasks/Crawler.cs index 0cbf431a..0c0db5c4 100644 --- a/Kyoo/Tasks/Crawler.cs +++ b/Kyoo/Tasks/Crawler.cs @@ -291,7 +291,6 @@ namespace Kyoo.Controllers show.Slug += $"-{show.StartYear}"; await libraryManager.RegisterShow(show); } - await _thumbnailsManager.Validate(show.People); await _thumbnailsManager.Validate(show); return show; } diff --git a/Kyoo/Tasks/ExtractMetadata.cs b/Kyoo/Tasks/ExtractMetadata.cs index 85c81612..f78caddf 100644 --- a/Kyoo/Tasks/ExtractMetadata.cs +++ b/Kyoo/Tasks/ExtractMetadata.cs @@ -72,6 +72,7 @@ namespace Kyoo.Tasks { if (thumbs) await _thumbnails!.Validate(show, true); + await _library.Load(show, x => x.Seasons); foreach (Season season in show.Seasons) { if (token.IsCancellationRequested) @@ -84,6 +85,7 @@ namespace Kyoo.Tasks { if (thumbs) await _thumbnails!.Validate(season, true); + await _library.Load(season, x => x.Episodes); foreach (Episode episode in season.Episodes) { if (token.IsCancellationRequested) diff --git a/Kyoo/Tasks/MetadataProviderLoader.cs b/Kyoo/Tasks/MetadataProviderLoader.cs index 95539677..5811775e 100644 --- a/Kyoo/Tasks/MetadataProviderLoader.cs +++ b/Kyoo/Tasks/MetadataProviderLoader.cs @@ -21,13 +21,15 @@ namespace Kyoo.Tasks { using IServiceScope serviceScope = serviceProvider.CreateScope(); IProviderRepository providers = serviceScope.ServiceProvider.GetService(); + IThumbnailsManager thumbnails = serviceScope.ServiceProvider.GetService(); IPluginManager pluginManager = serviceScope.ServiceProvider.GetService(); - foreach (IMetadataProvider provider in pluginManager.GetPlugins()) + foreach (IMetadataProvider provider in pluginManager!.GetPlugins()) { if (string.IsNullOrEmpty(provider.Provider.Slug)) throw new ArgumentException($"Empty provider slug (name: {provider.Provider.Name})."); - await providers.CreateIfNotExists(provider.Provider); + await providers!.CreateIfNotExists(provider.Provider); + await thumbnails!.Validate(provider.Provider); } } diff --git a/Kyoo/Views/API/ProviderApi.cs b/Kyoo/Views/API/ProviderApi.cs index c2798434..6d1cbb86 100644 --- a/Kyoo/Views/API/ProviderApi.cs +++ b/Kyoo/Views/API/ProviderApi.cs @@ -1,4 +1,6 @@ using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; using Kyoo.CommonApi; using Kyoo.Controllers; using Kyoo.Models; @@ -14,11 +16,32 @@ namespace Kyoo.Api public class ProviderAPI : CrudApi { private readonly ILibraryManager _libraryManager; + private readonly string _providerPath; public ProviderAPI(ILibraryManager libraryManager, IConfiguration config) : base(libraryManager.ProviderRepository, config) { _libraryManager = libraryManager; + _providerPath = Path.GetFullPath(config.GetValue("providerPath")); + } + + [HttpGet("{id:int}/logo")] + [Authorize(Policy="Read")] + public async Task GetLogo(int id) + { + string slug = (await _libraryManager.GetPeople(id)).Slug; + return GetLogo(slug); + } + + [HttpGet("{slug}/logo")] + [Authorize(Policy="Read")] + public IActionResult GetLogo(string slug) + { + string thumbPath = Path.GetFullPath(Path.Combine(_providerPath, slug + ".jpg")); + if (!thumbPath.StartsWith(_providerPath) || !System.IO.File.Exists(thumbPath)) + return NotFound(); + + return new PhysicalFileResult(Path.GetFullPath(thumbPath), "image/jpg"); } } } \ No newline at end of file diff --git a/Kyoo/appsettings.json b/Kyoo/appsettings.json index 19f3d82f..3cc8f735 100644 --- a/Kyoo/appsettings.json +++ b/Kyoo/appsettings.json @@ -29,6 +29,7 @@ "transmuxTempPath": "cached/kyoo/transmux", "transcodeTempPath": "cached/kyoo/transcode", "peoplePath": "people", + "providerPath": "providers", "profilePicturePath": "users/", "plugins": "plugins/", "defaultPermissions": "read,play,write,admin",