Adding an identify for shows

This commit is contained in:
Zoe Roux 2020-05-04 03:26:49 +02:00
parent b7618c9c54
commit 562c39b970
4 changed files with 103 additions and 92 deletions

View File

@ -6,8 +6,8 @@ namespace Kyoo.Controllers
{ {
public interface IThumbnailsManager public interface IThumbnailsManager
{ {
Task<Show> Validate(Show show); Task<Show> Validate(Show show, bool alwaysDownload = false);
Task<IEnumerable<PeopleLink>> Validate(IEnumerable<PeopleLink> actors); Task<IEnumerable<PeopleLink>> Validate(IEnumerable<PeopleLink> actors, bool alwaysDownload = false);
Task<Episode> Validate(Episode episode); Task<Episode> Validate(Episode episode, bool alwaysDownload = false);
} }
} }

View File

@ -5,6 +5,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using Kyoo.Models.Exceptions; using Kyoo.Models.Exceptions;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Query;
namespace Kyoo.Controllers namespace Kyoo.Controllers
{ {
@ -385,9 +386,12 @@ namespace Kyoo.Controllers
try try
{ {
var query = _database.Shows.Include(x => x.GenreLinks)
.Include(x => x.People)
.Include(x => x.ExternalIDs);
Show show = _database.Entry(edited).IsKeySet Show show = _database.Entry(edited).IsKeySet
? _database.Shows.Include(x => x.GenreLinks).FirstOrDefault(x => x.ID == edited.ID) ? query.FirstOrDefault(x => x.ID == edited.ID)
: _database.Shows.Include(x => x.GenreLinks).FirstOrDefault(x => x.Slug == edited.Slug); : query.FirstOrDefault(x => x.Slug == edited.Slug);
if (show == null) if (show == null)
throw new ItemNotFound($"No show could be found with the id {edited.ID} or the slug {edited.Slug}"); throw new ItemNotFound($"No show could be found with the id {edited.ID} or the slug {edited.Slug}");
@ -413,7 +417,11 @@ namespace Kyoo.Controllers
}).ToList(); }).ToList();
show.People = edited.People?.Select(x => show.People = edited.People?.Select(x =>
{ {
x.People = _database.Peoples.FirstOrDefault(y => y.Slug == x.People.Slug) ?? x.People; People people = _database.Peoples.FirstOrDefault(y => y.Slug == x.People.Slug);
if (people != null)
x.People = people;
else
x.People.ExternalIDs = ValidateExternalIDs(x.People.ExternalIDs);
return x; return x;
}).ToList(); }).ToList();
show.Seasons = edited.Seasons?.Select(x => show.Seasons = edited.Seasons?.Select(x =>
@ -427,6 +435,7 @@ namespace Kyoo.Controllers
&& y.SeasonNumber == x.SeasonNumber && y.SeasonNumber == x.SeasonNumber
&& y.EpisodeNumber == x.EpisodeNumber) ?? x; && y.EpisodeNumber == x.EpisodeNumber) ?? x;
}).ToList(); }).ToList();
show.ExternalIDs = ValidateExternalIDs(show.ExternalIDs);
_database.ChangeTracker.DetectChanges(); _database.ChangeTracker.DetectChanges();
_database.SaveChanges(); _database.SaveChanges();

View File

@ -17,100 +17,77 @@ namespace Kyoo.Controllers
_config = configuration; _config = configuration;
} }
public async Task<Show> Validate(Show show) private static async Task DownloadImage(string url, string localPath, string what)
{
try
{
using WebClient client = new WebClient();
await client.DownloadFileTaskAsync(new Uri(url), localPath);
}
catch (WebException exception)
{
await Console.Error.WriteLineAsync($"\t{what} could not be downloaded.\n\tError: {exception.Message}.");
}
}
public async Task<Show> Validate(Show show, bool alwaysDownload)
{ {
if (show?.Path == null) if (show?.Path == null)
return null; return default;
string localThumb = Path.Combine(show.Path, "poster.jpg");
string localLogo = Path.Combine(show.Path, "logo.png");
string localBackdrop = Path.Combine(show.Path, "backdrop.jpg");
if (show.Poster != null)
if (show.Poster != null && !File.Exists(localThumb))
{ {
try string posterPath = Path.Combine(show.Path, "poster.jpg");
{ if (alwaysDownload || !File.Exists(posterPath))
using WebClient client = new WebClient(); await DownloadImage(show.Poster, posterPath, $"The poster of {show.Title}");
await client.DownloadFileTaskAsync(new Uri(show.Poster), localThumb);
}
catch (WebException exception)
{
Console.Error.WriteLine($"\tThe poster of {show.Title} could not be downloaded.\n\tError: {exception.Message}. ");
}
} }
if (show.Logo != null)
if (show.Logo != null && !File.Exists(localLogo))
{ {
try string logoPath = Path.Combine(show.Path, "logo.png");
{ if (alwaysDownload || !File.Exists(logoPath))
using WebClient client = new WebClient(); await DownloadImage(show.Logo, logoPath, $"The logo of {show.Title}");
await client.DownloadFileTaskAsync(new Uri(show.Logo), localLogo);
}
catch (WebException exception)
{
Console.Error.WriteLine($"\tThe logo of {show.Title} could not be downloaded.\n\tError: {exception.Message}. ");
}
} }
if (show.Backdrop != null)
if (show.Backdrop != null && !File.Exists(localBackdrop))
{ {
try string backdropPath = Path.Combine(show.Path, "backdrop.jpg");
{ if (alwaysDownload || !File.Exists(backdropPath))
using WebClient client = new WebClient(); await DownloadImage(show.Backdrop, backdropPath, $"The backdrop of {show.Title}");
await client.DownloadFileTaskAsync(new Uri(show.Backdrop), localBackdrop);
}
catch (WebException exception)
{
Console.Error.WriteLine($"\tThe backdrop of {show.Title} could not be downloaded.\n\tError: {exception.Message}. ");
}
} }
return show; return show;
} }
public async Task<IEnumerable<PeopleLink>> Validate(IEnumerable<PeopleLink> people) public async Task<IEnumerable<PeopleLink>> Validate(IEnumerable<PeopleLink> people, bool alwaysDownload)
{ {
if (people == null) if (people == null)
return null; return null;
string root = _config.GetValue<string>("peoplePath");
Directory.CreateDirectory(root);
foreach (PeopleLink peop in people) foreach (PeopleLink peop in people)
{ {
string root = _config.GetValue<string>("peoplePath"); string localPath = Path.Combine(root, peop.People.Slug + ".jpg");
Directory.CreateDirectory(root); if (peop.People.ImgPrimary == null)
string localThumb = root + "/" + peop.People.Slug + ".jpg";
if (peop.People.ImgPrimary == null || File.Exists(localThumb))
continue; continue;
try if (alwaysDownload || !File.Exists(localPath))
{ await DownloadImage(peop.People.ImgPrimary, localPath, $"The profile picture of {peop.People.Name}");
using WebClient client = new WebClient();
await client.DownloadFileTaskAsync(new Uri(peop.People.ImgPrimary), localThumb);
}
catch (WebException exception)
{
Console.Error.WriteLine($"\tThe profile picture of {peop.People.Name} could not be downloaded.\n\tError: {exception.Message}. ");
}
} }
return people; return people;
} }
public async Task<Episode> Validate(Episode episode) public async Task<Episode> Validate(Episode episode, bool alwaysDownload)
{ {
if (episode == null || episode.Path == null) if (episode?.Path == null)
return null; return default;
string localThumb = Path.ChangeExtension(episode.Path, "jpg");
if (episode.ImgPrimary == null || File.Exists(localThumb))
return episode;
try
{
using WebClient client = new WebClient();
await client.DownloadFileTaskAsync(new Uri(episode.ImgPrimary), localThumb);
}
catch (WebException exception)
{
Console.Error.WriteLine($"\tThe thumbnail of {episode.Show.Title} s{episode.SeasonNumber}e{episode.EpisodeNumber} could not be downloaded.\n\tError: {exception.Message}. ");
}
if (episode.ImgPrimary == null)
{
string localPath = Path.ChangeExtension(episode.Path, "jpg");
if (alwaysDownload || !File.Exists(localPath))
await DownloadImage(episode.ImgPrimary, localPath, $"The thumbnail of {episode.Show.Title}");
}
return episode; return episode;
} }
} }

View File

@ -1,10 +1,12 @@
using Kyoo.Models; using Kyoo.Models;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Kyoo.Controllers; using Kyoo.Controllers;
using Kyoo.Models.Exceptions; using Kyoo.Models.Exceptions;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.EntityFrameworkCore;
namespace Kyoo.Api namespace Kyoo.Api
{ {
@ -15,11 +17,15 @@ namespace Kyoo.Api
{ {
private readonly ILibraryManager _libraryManager; private readonly ILibraryManager _libraryManager;
private readonly IProviderManager _providerManager; private readonly IProviderManager _providerManager;
private readonly DatabaseContext _database;
private readonly IThumbnailsManager _thumbnailsManager;
public ShowsAPI(ILibraryManager libraryManager, IProviderManager providerManager) public ShowsAPI(ILibraryManager libraryManager, IProviderManager providerManager, DatabaseContext database, IThumbnailsManager thumbnailsManager)
{ {
_libraryManager = libraryManager; _libraryManager = libraryManager;
_providerManager = providerManager; _providerManager = providerManager;
_database = database;
_thumbnailsManager = thumbnailsManager;
} }
[HttpGet] [HttpGet]
@ -47,17 +53,33 @@ namespace Kyoo.Api
public IActionResult EditShow(string slug, [FromBody] Show show) public IActionResult EditShow(string slug, [FromBody] Show show)
{ {
if (!ModelState.IsValid) if (!ModelState.IsValid)
return BadRequest(show); return BadRequest(show);
show.ID = 0;
show.Slug = slug; Show old = _database.Shows.AsNoTracking().FirstOrDefault(x => x.Slug == slug);
try if (old == null)
{
_libraryManager.EditShow(show);
}
catch (ItemNotFound)
{
return NotFound(); return NotFound();
} show.ID = old.ID;
show.Slug = slug;
show.Path = old.Path;
_libraryManager.EditShow(show);
return Ok();
}
[HttpPost("re-identify/{slug}")]
[Authorize(Policy = "Write")]
public async Task<IActionResult> ReIdentityShow(string slug, [FromBody] Show show)
{
if (!ModelState.IsValid)
return BadRequest(show);
Show old = _database.Shows.FirstOrDefault(x => x.Slug == slug);
if (old == null)
return NotFound();
Show edited = await _providerManager.CompleteShow(show, _libraryManager.GetLibraryForShow(slug));
edited.ID = old.ID;
edited.Slug = old.Slug;
edited.Path = old.Path;
_libraryManager.EditShow(edited);
await _thumbnailsManager.Validate(edited, true);
return Ok(); return Ok();
} }
@ -67,13 +89,16 @@ namespace Kyoo.Api
{ {
return await _providerManager.SearchShows(name, isMovie, null); return await _providerManager.SearchShows(name, isMovie, null);
} }
[HttpGet("details")] [HttpPost("download-images/{slug}")]
[Authorize(Policy = "Read")] [Authorize(Policy = "Write")]
public async Task<Show> IdentityShow([FromBody] Show show) public async Task<IActionResult> DownloadImages(string slug)
{ {
Library library = _libraryManager.GetLibraryForShow(show.Slug); Show show = _libraryManager.GetShowBySlug(slug);
return await _providerManager.CompleteShow(show, library); if (show == null)
return NotFound();
await _thumbnailsManager.Validate(show, true);
return Ok();
} }
} }
} }