Adding handling of provider's logo locally

This commit is contained in:
Zoe Roux 2021-03-15 21:06:11 +01:00
parent 42ff22ad13
commit fdf2f37ceb
11 changed files with 81 additions and 23 deletions

View File

@ -9,6 +9,7 @@ namespace Kyoo.Controllers
Task<Show> Validate(Show show, bool alwaysDownload = false); Task<Show> Validate(Show show, bool alwaysDownload = false);
Task<Season> Validate(Season season, bool alwaysDownload = false); Task<Season> Validate(Season season, bool alwaysDownload = false);
Task<Episode> Validate(Episode episode, bool alwaysDownload = false); Task<Episode> Validate(Episode episode, bool alwaysDownload = false);
Task<IEnumerable<PeopleRole>> Validate(IEnumerable<PeopleRole> actors, bool alwaysDownload = false); Task<People> Validate(People actors, bool alwaysDownload = false);
Task<ProviderID> Validate(ProviderID actors, bool alwaysDownload = false);
} }
} }

View File

@ -8,7 +8,7 @@ namespace Kyoo.Models
public int ID { get; set; } public int ID { get; set; }
public string Slug { get; set; } public string Slug { get; set; }
public string Name { 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; } public string Overview { get; set; }
[LoadableRelation] public virtual ICollection<Show> Shows { get; set; } [LoadableRelation] public virtual ICollection<Show> Shows { get; set; }
[LoadableRelation] public virtual ICollection<Library> Libraries { get; set; } [LoadableRelation] public virtual ICollection<Library> Libraries { get; set; }

View File

@ -8,7 +8,7 @@ namespace Kyoo.Models
public int ID { get; set; } public int ID { get; set; }
public string Slug { get; set; } public string Slug { get; set; }
public string Name { 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<Library> Libraries { get; set; } [LoadableRelation] public virtual ICollection<Library> Libraries { get; set; }

View File

@ -110,7 +110,7 @@ namespace Kyoo.Controllers
_tasks.AddRange(CoreTaskHolder.Tasks.Select(x => (x, DateTime.Now + GetTaskDelay(x.Slug)))); _tasks.AddRange(CoreTaskHolder.Tasks.Select(x => (x, DateTime.Now + GetTaskDelay(x.Slug))));
IEnumerable<ITask> prerunTasks = _tasks.Select(x => x.task) IEnumerable<ITask> 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) foreach (ITask task in prerunTasks)
task.Run(_serviceProvider, _taskToken.Token); task.Run(_serviceProvider, _taskToken.Token);

View File

@ -1,10 +1,10 @@
using Kyoo.Models; using Kyoo.Models;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Net; using System.Net;
using System.Threading.Tasks; using System.Threading.Tasks;
using JetBrains.Annotations;
namespace Kyoo.Controllers namespace Kyoo.Controllers
{ {
@ -26,7 +26,7 @@ namespace Kyoo.Controllers
} }
catch (WebException exception) 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}.");
} }
} }
@ -54,25 +54,22 @@ namespace Kyoo.Controllers
await DownloadImage(show.Backdrop, backdropPath, $"The backdrop of {show.Title}"); await DownloadImage(show.Backdrop, backdropPath, $"The backdrop of {show.Title}");
} }
foreach (PeopleRole role in show.People)
await Validate(role.People, alwaysDownload);
return show; return show;
} }
public async Task<IEnumerable<PeopleRole>> Validate(IEnumerable<PeopleRole> people, bool alwaysDownload) public async Task<People> Validate([NotNull] People people, bool alwaysDownload)
{ {
if (people == null) if (people == null)
return null; throw new ArgumentNullException(nameof(people));
string root = _config.GetValue<string>("peoplePath"); string root = _config.GetValue<string>("peoplePath");
Directory.CreateDirectory(root); string localPath = Path.Combine(root, people.Slug + ".jpg");
foreach (PeopleRole peop in people) Directory.CreateDirectory(root);
{
string localPath = Path.Combine(root, peop.People.Slug + ".jpg");
if (peop.People.Poster == null)
continue;
if (alwaysDownload || !File.Exists(localPath)) if (alwaysDownload || !File.Exists(localPath))
await DownloadImage(peop.People.Poster, localPath, $"The profile picture of {peop.People.Name}"); await DownloadImage(people.Poster, localPath, $"The profile picture of {people.Name}");
}
return people; return people;
} }
@ -100,9 +97,25 @@ namespace Kyoo.Controllers
{ {
string localPath = Path.ChangeExtension(episode.Path, "jpg"); string localPath = Path.ChangeExtension(episode.Path, "jpg");
if (alwaysDownload || !File.Exists(localPath)) 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; return episode;
} }
public async Task<ProviderID> Validate(ProviderID provider, bool alwaysDownload)
{
if (provider.Logo == null)
return provider;
string root = _config.GetValue<string>("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
} }
} }

View File

@ -43,6 +43,10 @@ namespace Kyoo
{ {
configuration.RootPath = Path.Join(AppDomain.CurrentDomain.BaseDirectory, "wwwroot"); configuration.RootPath = Path.Join(AppDomain.CurrentDomain.BaseDirectory, "wwwroot");
}); });
services.AddResponseCompression(x =>
{
x.EnableForHttps = true;
});
services.AddControllers() services.AddControllers()
.AddNewtonsoftJson(x => .AddNewtonsoftJson(x =>
@ -187,6 +191,19 @@ namespace Kyoo
app.UseRouting(); app.UseRouting();
// 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 app.UseCookiePolicy(new CookiePolicyOptions
{ {
MinimumSameSitePolicy = SameSiteMode.Strict MinimumSameSitePolicy = SameSiteMode.Strict

View File

@ -291,7 +291,6 @@ namespace Kyoo.Controllers
show.Slug += $"-{show.StartYear}"; show.Slug += $"-{show.StartYear}";
await libraryManager.RegisterShow(show); await libraryManager.RegisterShow(show);
} }
await _thumbnailsManager.Validate(show.People);
await _thumbnailsManager.Validate(show); await _thumbnailsManager.Validate(show);
return show; return show;
} }

View File

@ -72,6 +72,7 @@ namespace Kyoo.Tasks
{ {
if (thumbs) if (thumbs)
await _thumbnails!.Validate(show, true); await _thumbnails!.Validate(show, true);
await _library.Load(show, x => x.Seasons);
foreach (Season season in show.Seasons) foreach (Season season in show.Seasons)
{ {
if (token.IsCancellationRequested) if (token.IsCancellationRequested)
@ -84,6 +85,7 @@ namespace Kyoo.Tasks
{ {
if (thumbs) if (thumbs)
await _thumbnails!.Validate(season, true); await _thumbnails!.Validate(season, true);
await _library.Load(season, x => x.Episodes);
foreach (Episode episode in season.Episodes) foreach (Episode episode in season.Episodes)
{ {
if (token.IsCancellationRequested) if (token.IsCancellationRequested)

View File

@ -21,13 +21,15 @@ namespace Kyoo.Tasks
{ {
using IServiceScope serviceScope = serviceProvider.CreateScope(); using IServiceScope serviceScope = serviceProvider.CreateScope();
IProviderRepository providers = serviceScope.ServiceProvider.GetService<IProviderRepository>(); IProviderRepository providers = serviceScope.ServiceProvider.GetService<IProviderRepository>();
IThumbnailsManager thumbnails = serviceScope.ServiceProvider.GetService<IThumbnailsManager>();
IPluginManager pluginManager = serviceScope.ServiceProvider.GetService<IPluginManager>(); IPluginManager pluginManager = serviceScope.ServiceProvider.GetService<IPluginManager>();
foreach (IMetadataProvider provider in pluginManager.GetPlugins<IMetadataProvider>()) foreach (IMetadataProvider provider in pluginManager!.GetPlugins<IMetadataProvider>())
{ {
if (string.IsNullOrEmpty(provider.Provider.Slug)) if (string.IsNullOrEmpty(provider.Provider.Slug))
throw new ArgumentException($"Empty provider slug (name: {provider.Provider.Name})."); 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);
} }
} }

View File

@ -1,4 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using Kyoo.CommonApi; using Kyoo.CommonApi;
using Kyoo.Controllers; using Kyoo.Controllers;
using Kyoo.Models; using Kyoo.Models;
@ -14,11 +16,32 @@ namespace Kyoo.Api
public class ProviderAPI : CrudApi<ProviderID> public class ProviderAPI : CrudApi<ProviderID>
{ {
private readonly ILibraryManager _libraryManager; private readonly ILibraryManager _libraryManager;
private readonly string _providerPath;
public ProviderAPI(ILibraryManager libraryManager, IConfiguration config) public ProviderAPI(ILibraryManager libraryManager, IConfiguration config)
: base(libraryManager.ProviderRepository, config) : base(libraryManager.ProviderRepository, config)
{ {
_libraryManager = libraryManager; _libraryManager = libraryManager;
_providerPath = Path.GetFullPath(config.GetValue<string>("providerPath"));
}
[HttpGet("{id:int}/logo")]
[Authorize(Policy="Read")]
public async Task<IActionResult> 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");
} }
} }
} }

View File

@ -29,6 +29,7 @@
"transmuxTempPath": "cached/kyoo/transmux", "transmuxTempPath": "cached/kyoo/transmux",
"transcodeTempPath": "cached/kyoo/transcode", "transcodeTempPath": "cached/kyoo/transcode",
"peoplePath": "people", "peoplePath": "people",
"providerPath": "providers",
"profilePicturePath": "users/", "profilePicturePath": "users/",
"plugins": "plugins/", "plugins": "plugins/",
"defaultPermissions": "read,play,write,admin", "defaultPermissions": "read,play,write,admin",