Auto download missing images on startup

This commit is contained in:
Zoe Roux 2024-04-21 19:41:36 +02:00
parent 00cd94d624
commit c4b42c9961
No known key found for this signature in database
8 changed files with 91 additions and 11 deletions

View File

@ -22,7 +22,7 @@ FROM mcr.microsoft.com/dotnet/aspnet:8.0
RUN apt-get update && apt-get install -y curl
COPY --from=builder /app /app
WORKDIR /kyoo
WORKDIR /app
EXPOSE 5000
# The back can take a long time to start if meilisearch is initializing
HEALTHCHECK --interval=5s --retries=15 CMD curl --fail http://localhost:5000/health || exit

View File

@ -14,7 +14,7 @@ COPY src/Kyoo.RabbitMq/Kyoo.RabbitMq.csproj src/Kyoo.RabbitMq/Kyoo.RabbitMq.cspr
COPY src/Kyoo.Swagger/Kyoo.Swagger.csproj src/Kyoo.Swagger/Kyoo.Swagger.csproj
RUN dotnet restore
WORKDIR /kyoo
WORKDIR /app
EXPOSE 5000
ENV DOTNET_USE_POLLING_FILE_WATCHER 1
# HEALTHCHECK --interval=5s CMD curl --fail http://localhost:5000/health || exit

View File

@ -28,6 +28,8 @@ public interface IThumbnailsManager
Task DownloadImages<T>(T item)
where T : IThumbnails;
Task DownloadImage(Image? image, string what);
string GetImagePath(Guid imageId, ImageQuality quality);
Task DeleteImages<T>(T item)

View File

@ -0,0 +1,77 @@
// Kyoo - A portable and vast media library solution.
// Copyright (c) Kyoo.
//
// See AUTHORS.md and LICENSE file in the project root for full license information.
//
// Kyoo is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// Kyoo is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Dapper;
using Kyoo.Abstractions.Controllers;
using Kyoo.Abstractions.Models;
using Kyoo.Postgresql;
using Microsoft.EntityFrameworkCore;
namespace Kyoo.Core.Controllers;
public class MiscRepository(
DatabaseContext context,
DbConnection database,
IThumbnailsManager thumbnails
)
{
private async Task<ICollection<Image>> _GetAllImages()
{
string GetSql(string type) =>
$"""
select poster from {type}
union all select thumbnail from {type}
union all select logo from {type}
""";
var queries = new string[]
{
"movies",
"collections",
"shows",
"seasons",
"episodes"
}.Select(x => GetSql(x));
string sql = string.Join(" union all ", queries);
IEnumerable<Image?> ret = await database.QueryAsync<Image?>(sql);
return ret.Where(x => x != null).ToArray() as Image[];
}
public async Task DownloadMissingImages()
{
ICollection<Image> images = await _GetAllImages();
await Task.WhenAll(
images
.Where(x => !File.Exists(thumbnails.GetImagePath(x.Id, ImageQuality.Low)))
.Select(x => thumbnails.DownloadImage(x, x.Id.ToString()))
);
}
public async Task<ICollection<string>> GetRegisteredPaths()
{
return await context
.Episodes.Select(x => x.Path)
.Concat(context.Movies.Select(x => x.Path))
.ToListAsync();
}
}

View File

@ -50,7 +50,7 @@ public class ThumbnailsManager(
await reader.CopyToAsync(file);
}
private async Task _DownloadImage(Image? image, string what)
public async Task DownloadImage(Image? image, string what)
{
if (image == null)
return;
@ -108,9 +108,9 @@ public class ThumbnailsManager(
{
string name = item is IResource res ? res.Slug : "???";
await _DownloadImage(item.Poster, $"The poster of {name}");
await _DownloadImage(item.Thumbnail, $"The thumbnail of {name}");
await _DownloadImage(item.Logo, $"The logo of {name}");
await DownloadImage(item.Poster, $"The poster of {name}");
await DownloadImage(item.Thumbnail, $"The thumbnail of {name}");
await DownloadImage(item.Logo, $"The logo of {name}");
}
/// <inheritdoc />

View File

@ -63,5 +63,6 @@ public static class CoreModule
);
builder.Services.AddScoped<IIssueRepository, IssueRepository>();
builder.Services.AddScoped<SqlVariableContext>();
builder.Services.AddScoped<MiscRepository>();
}
}

View File

@ -21,6 +21,7 @@ using System.Text.Json;
using System.Text.Json.Serialization;
using AspNetCore.Proxy;
using Kyoo.Abstractions.Models.Utils;
using Kyoo.Authentication;
using Kyoo.Core.Api;
using Kyoo.Core.Controllers;
using Kyoo.Utils;
@ -45,6 +46,8 @@ public static class ServiceExtensions
options.ModelBinderProviders.Insert(0, new IncludeBinder.Provider());
options.ModelBinderProviders.Insert(0, new FilterBinder.Provider());
})
.AddApplicationPart(typeof(CoreModule).Assembly)
.AddApplicationPart(typeof(AuthenticationModule).Assembly)
.AddJsonOptions(x =>
{
x.JsonSerializerOptions.TypeInfoResolver = new JsonKindResolver()

View File

@ -19,6 +19,7 @@
using System;
using Kyoo.Authentication;
using Kyoo.Core;
using Kyoo.Core.Controllers;
using Kyoo.Core.Extensions;
using Kyoo.Meiliseach;
using Kyoo.Postgresql;
@ -69,11 +70,6 @@ AppDomain.CurrentDomain.UnhandledException += (_, ex) =>
Log.Fatal(ex.ExceptionObject as Exception, "Unhandled exception");
builder.Host.UseSerilog();
builder
.Services.AddMvcCore()
.AddApplicationPart(typeof(CoreModule).Assembly)
.AddApplicationPart(typeof(AuthenticationModule).Assembly);
builder.Services.ConfigureMvc();
builder.Services.ConfigureOpenApi();
builder.ConfigureKyoo();
@ -99,6 +95,7 @@ app.Services.GetRequiredService<RabbitProducer>();
await using (AsyncServiceScope scope = app.Services.CreateAsyncScope())
{
await MeilisearchModule.Initialize(scope.ServiceProvider);
await scope.ServiceProvider.GetRequiredService<MiscRepository>().DownloadMissingImages();
}
app.Run(Environment.GetEnvironmentVariable("KYOO_BIND_URL") ?? "http://*:5000");