diff --git a/back/Dockerfile.dev b/back/Dockerfile.dev index 778f9018..373dfa5b 100644 --- a/back/Dockerfile.dev +++ b/back/Dockerfile.dev @@ -20,7 +20,7 @@ COPY src/Kyoo.Swagger/Kyoo.Swagger.csproj src/Kyoo.Swagger/Kyoo.Swagger.csproj COPY tests/Kyoo.Tests/Kyoo.Tests.csproj tests/Kyoo.Tests/Kyoo.Tests.csproj RUN dotnet restore -COPY --from=transcoder /transcoder/libtranscoder.so /app +COPY --from=transcoder /transcoder/libtranscoder.so /app/out/bin/Kyoo.Host/Debug/net6.0/libtranscoder.so WORKDIR /kyoo EXPOSE 5000 diff --git a/back/src/Kyoo.Core/Controllers/ThumbnailsManager.cs b/back/src/Kyoo.Core/Controllers/ThumbnailsManager.cs index cdde9452..45cefc35 100644 --- a/back/src/Kyoo.Core/Controllers/ThumbnailsManager.cs +++ b/back/src/Kyoo.Core/Controllers/ThumbnailsManager.cs @@ -69,6 +69,7 @@ namespace Kyoo.Core.Controllers try { + _logger.LogInformation("Downloading image {What}", what); AsyncRef mime = new(); await using Stream reader = await _files.GetReader(url, mime); string extension = new FileExtensionContentTypeProvider() diff --git a/back/src/Kyoo.Core/Views/Helper/CrudApi.cs b/back/src/Kyoo.Core/Views/Helper/CrudApi.cs index dbb258b1..cb941c43 100644 --- a/back/src/Kyoo.Core/Views/Helper/CrudApi.cs +++ b/back/src/Kyoo.Core/Views/Helper/CrudApi.cs @@ -138,7 +138,7 @@ namespace Kyoo.Core.Api [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(RequestError))] [ProducesResponseType(StatusCodes.Status409Conflict, Type = typeof(ActionResult<>))] - public async Task> Create([FromBody] T resource) + public virtual async Task> Create([FromBody] T resource) { return await Repository.Create(resource); } diff --git a/back/src/Kyoo.Core/Views/Helper/CrudThumbsApi.cs b/back/src/Kyoo.Core/Views/Helper/CrudThumbsApi.cs index 89e2e8c0..8bff58e8 100644 --- a/back/src/Kyoo.Core/Views/Helper/CrudThumbsApi.cs +++ b/back/src/Kyoo.Core/Views/Helper/CrudThumbsApi.cs @@ -153,5 +153,14 @@ namespace Kyoo.Core.Api { return GetImage(identifier, Images.Thumbnail); } + + /// + public override async Task> Create([FromBody] T resource) + { + // TODO: Remove this method and use a websocket API to do that. + ActionResult ret = await base.Create(resource); + await _thumbs.DownloadImages(ret.Value); + return ret; + } } } diff --git a/back/src/Kyoo.Core/Views/Resources/EpisodeApi.cs b/back/src/Kyoo.Core/Views/Resources/EpisodeApi.cs index 21c5e952..188f3c81 100644 --- a/back/src/Kyoo.Core/Views/Resources/EpisodeApi.cs +++ b/back/src/Kyoo.Core/Views/Resources/EpisodeApi.cs @@ -24,6 +24,7 @@ using Kyoo.Abstractions.Models; using Kyoo.Abstractions.Models.Attributes; using Kyoo.Abstractions.Models.Permissions; using Kyoo.Abstractions.Models.Utils; +using Kyoo.Utils; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using static Kyoo.Abstractions.Models.Utils.Constants; @@ -76,6 +77,15 @@ namespace Kyoo.Core.Api _files = files; } + /// + public override async Task> Create([FromBody] Episode resource) + { + // TODO: Remove this method and use a websocket API to do that. + resource.Tracks = await _transcoder.ExtractInfos(resource, false); + ActionResult ret = await base.Create(resource); + return ret; + } + /// /// Get episode's show /// diff --git a/back/src/Kyoo.Core/Views/Resources/ShowApi.cs b/back/src/Kyoo.Core/Views/Resources/ShowApi.cs index 6db8323b..7fb6a843 100644 --- a/back/src/Kyoo.Core/Views/Resources/ShowApi.cs +++ b/back/src/Kyoo.Core/Views/Resources/ShowApi.cs @@ -48,6 +48,7 @@ namespace Kyoo.Core.Api /// The library manager used to modify or retrieve information in the data store. /// private readonly ILibraryManager _libraryManager; + private readonly ITranscoder _transcoder; /// /// Create a new . @@ -57,12 +58,34 @@ namespace Kyoo.Core.Api /// /// The file manager used to send images and fonts. /// The thumbnail manager used to retrieve images paths. + /// TODO: Remove this. public ShowApi(ILibraryManager libraryManager, IFileSystem files, - IThumbnailsManager thumbs) + IThumbnailsManager thumbs, + ITranscoder transcoder) : base(libraryManager.ShowRepository, files, thumbs) { _libraryManager = libraryManager; + _transcoder = transcoder; + } + + /// + public override async Task> Create([FromBody] Show resource) + { + ActionResult ret = await base.Create(resource); + if (ret.Value.IsMovie) + { + Episode episode = new() + { + Show = ret.Value, + Title = ret.Value.Title, + Path = ret.Value.Path + }; + + episode.Tracks = await _transcoder.ExtractInfos(episode, false); + await _libraryManager.Create(episode); + } + return ret; } /// diff --git a/back/src/Kyoo.Host/Application.cs b/back/src/Kyoo.Host/Application.cs index 284ee9ec..f266c579 100644 --- a/back/src/Kyoo.Host/Application.cs +++ b/back/src/Kyoo.Host/Application.cs @@ -24,7 +24,6 @@ using System.Threading.Tasks; using Autofac; using Autofac.Extensions.DependencyInjection; using Kyoo.Postgresql; -using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; @@ -176,6 +175,7 @@ namespace Kyoo.Host .MinimumLevel.Warning() .MinimumLevel.Override("Kyoo", LogEventLevel.Verbose) .MinimumLevel.Override("Microsoft.Hosting.Lifetime", LogEventLevel.Verbose) + .MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Fatal) .WriteTo.Console(new ExpressionTemplate(template, theme: TemplateTheme.Code)) .Enrich.WithThreadId() .Enrich.FromLogContext(); diff --git a/scanner/providers/implementations/themoviedatabase.py b/scanner/providers/implementations/themoviedatabase.py index 5e3dc426..b841a673 100644 --- a/scanner/providers/implementations/themoviedatabase.py +++ b/scanner/providers/implementations/themoviedatabase.py @@ -342,8 +342,8 @@ class TheMovieDatabase(Provider): release_date=datetime.strptime(episode["air_date"], "%Y-%m-%d").date() if episode["air_date"] else None, - thumbnail=f"https://image.tmdb.org/t/p/original{episode['poster_path']}" - if "poster_path" in episode + thumbnail=f"https://image.tmdb.org/t/p/original{episode['still_path']}" + if "still_path" in episode and episode["still_path"] is not None else None, external_ids={ self.name: MetadataID( diff --git a/scanner/providers/types/episode.py b/scanner/providers/types/episode.py index 238b814f..c9cc752c 100644 --- a/scanner/providers/types/episode.py +++ b/scanner/providers/types/episode.py @@ -41,6 +41,9 @@ class Episode: **asdict(self), **asdict(self.translations[default_language]), "title": self.translations[default_language].name, + "images": { + "1": self.thumbnail, + }, # TODO: The back has bad external id support, we disable it for now "external_ids": None, "show": None, diff --git a/scanner/providers/types/genre.py b/scanner/providers/types/genre.py index 22dedd6a..79c8c3ed 100644 --- a/scanner/providers/types/genre.py +++ b/scanner/providers/types/genre.py @@ -22,4 +22,4 @@ class Genre(str, Enum): WESTERN = "Western" def to_kyoo(self): - return {"name": f"{self}"} + return {"name": self.value} diff --git a/scanner/providers/types/movie.py b/scanner/providers/types/movie.py index f9349aa0..d0963153 100644 --- a/scanner/providers/types/movie.py +++ b/scanner/providers/types/movie.py @@ -50,12 +50,12 @@ class Movie: return { **asdict(self), **asdict(self.translations[default_language]), - "poster": next(iter(self.translations[default_language].posters), None), - "thumbnail": next( - iter(self.translations[default_language].thumbnails), None - ), - "logo": next(iter(self.translations[default_language].logos), None), - "trailer": next(iter(self.translations[default_language].trailers), None), + "images": { + "0": next(iter(self.translations[default_language].posters), None), + "1": next(iter(self.translations[default_language].thumbnails), None), + "2": next(iter(self.translations[default_language].logos), None), + "3": next(iter(self.translations[default_language].trailers), None), + }, "studio": next((x.to_kyoo() for x in self.studios), None), "release_date": None, "startAir": format_date(self.release_date), diff --git a/scanner/providers/types/season.py b/scanner/providers/types/season.py index c247b544..92e3dd7e 100644 --- a/scanner/providers/types/season.py +++ b/scanner/providers/types/season.py @@ -30,10 +30,10 @@ class Season: return { **asdict(self), **asdict(self.translations[default_language]), - "poster": next(iter(self.translations[default_language].posters), None), - "thumbnail": next( - iter(self.translations[default_language].thumbnails), None - ), + "images": { + "0": next(iter(self.translations[default_language].posters), None), + "1": next(iter(self.translations[default_language].thumbnails), None), + }, "title": self.translations[default_language].name, # TODO: The back has bad external id support, we disable it for now "external_ids": None, diff --git a/scanner/providers/types/show.py b/scanner/providers/types/show.py index 748abf33..cf3258b5 100644 --- a/scanner/providers/types/show.py +++ b/scanner/providers/types/show.py @@ -52,12 +52,12 @@ class Show: return { **asdict(self), **asdict(self.translations[default_language]), - "poster": next(iter(self.translations[default_language].posters), None), - "thumbnail": next( - iter(self.translations[default_language].thumbnails), None - ), - "logo": next(iter(self.translations[default_language].logos), None), - "trailer": next(iter(self.translations[default_language].trailers), None), + "images": { + "0": next(iter(self.translations[default_language].posters), None), + "1": next(iter(self.translations[default_language].thumbnails), None), + "2": next(iter(self.translations[default_language].logos), None), + "3": next(iter(self.translations[default_language].trailers), None), + }, "studio": next((x.to_kyoo() for x in self.studios), None), "title": self.translations[default_language].name, "genres": [x.to_kyoo() for x in self.genres], diff --git a/scanner/providers/types/studio.py b/scanner/providers/types/studio.py index 890efd5b..d952b63d 100644 --- a/scanner/providers/types/studio.py +++ b/scanner/providers/types/studio.py @@ -12,6 +12,9 @@ class Studio: def to_kyoo(self): return { **asdict(self), + "images": { + "2": next(iter(self.logos), None), + }, # TODO: The back has bad external id support, we disable it for now "external_ids": None, } diff --git a/scanner/scanner/utils.py b/scanner/scanner/utils.py index 2eda4ee2..a8c8f28e 100644 --- a/scanner/scanner/utils.py +++ b/scanner/scanner/utils.py @@ -38,7 +38,7 @@ def provider_cache(*args): if "event" in ic: await ic["event"].wait() - if not ic["ret"]: + if "ret" not in ic: raise ProviderError("Cache miss. Another error should exist") return ic["ret"] ic["event"] = asyncio.Event()