mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-24 02:02:36 -04:00
Automatically download/extract info on API creation (dirtyfix) (#161
* Download thumbnails automatically * Automatically extract tracks
This commit is contained in:
parent
d0db4815f1
commit
592c92785f
@ -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
|
||||
|
@ -69,6 +69,7 @@ namespace Kyoo.Core.Controllers
|
||||
|
||||
try
|
||||
{
|
||||
_logger.LogInformation("Downloading image {What}", what);
|
||||
AsyncRef<string> mime = new();
|
||||
await using Stream reader = await _files.GetReader(url, mime);
|
||||
string extension = new FileExtensionContentTypeProvider()
|
||||
|
@ -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<ActionResult<T>> Create([FromBody] T resource)
|
||||
public virtual async Task<ActionResult<T>> Create([FromBody] T resource)
|
||||
{
|
||||
return await Repository.Create(resource);
|
||||
}
|
||||
|
@ -153,5 +153,14 @@ namespace Kyoo.Core.Api
|
||||
{
|
||||
return GetImage(identifier, Images.Thumbnail);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override async Task<ActionResult<T>> Create([FromBody] T resource)
|
||||
{
|
||||
// TODO: Remove this method and use a websocket API to do that.
|
||||
ActionResult<T> ret = await base.Create(resource);
|
||||
await _thumbs.DownloadImages(ret.Value);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override async Task<ActionResult<Episode>> Create([FromBody] Episode resource)
|
||||
{
|
||||
// TODO: Remove this method and use a websocket API to do that.
|
||||
resource.Tracks = await _transcoder.ExtractInfos(resource, false);
|
||||
ActionResult<Episode> ret = await base.Create(resource);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get episode's show
|
||||
/// </summary>
|
||||
|
@ -48,6 +48,7 @@ namespace Kyoo.Core.Api
|
||||
/// The library manager used to modify or retrieve information in the data store.
|
||||
/// </summary>
|
||||
private readonly ILibraryManager _libraryManager;
|
||||
private readonly ITranscoder _transcoder;
|
||||
|
||||
/// <summary>
|
||||
/// Create a new <see cref="ShowApi"/>.
|
||||
@ -57,12 +58,34 @@ namespace Kyoo.Core.Api
|
||||
/// </param>
|
||||
/// <param name="files">The file manager used to send images and fonts.</param>
|
||||
/// <param name="thumbs">The thumbnail manager used to retrieve images paths.</param>
|
||||
/// <param name="transcoder">TODO: Remove this.</param>
|
||||
public ShowApi(ILibraryManager libraryManager,
|
||||
IFileSystem files,
|
||||
IThumbnailsManager thumbs)
|
||||
IThumbnailsManager thumbs,
|
||||
ITranscoder transcoder)
|
||||
: base(libraryManager.ShowRepository, files, thumbs)
|
||||
{
|
||||
_libraryManager = libraryManager;
|
||||
_transcoder = transcoder;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override async Task<ActionResult<Show>> Create([FromBody] Show resource)
|
||||
{
|
||||
ActionResult<Show> 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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -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();
|
||||
|
@ -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(
|
||||
|
@ -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,
|
||||
|
@ -22,4 +22,4 @@ class Genre(str, Enum):
|
||||
WESTERN = "Western"
|
||||
|
||||
def to_kyoo(self):
|
||||
return {"name": f"{self}"}
|
||||
return {"name": self.value}
|
||||
|
@ -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),
|
||||
|
@ -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,
|
||||
|
@ -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],
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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()
|
||||
|
Loading…
x
Reference in New Issue
Block a user