mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-30 19:54:16 -04:00
Auto download missing images on startup
This commit is contained in:
parent
00cd94d624
commit
c4b42c9961
@ -22,7 +22,7 @@ FROM mcr.microsoft.com/dotnet/aspnet:8.0
|
|||||||
RUN apt-get update && apt-get install -y curl
|
RUN apt-get update && apt-get install -y curl
|
||||||
COPY --from=builder /app /app
|
COPY --from=builder /app /app
|
||||||
|
|
||||||
WORKDIR /kyoo
|
WORKDIR /app
|
||||||
EXPOSE 5000
|
EXPOSE 5000
|
||||||
# The back can take a long time to start if meilisearch is initializing
|
# 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
|
HEALTHCHECK --interval=5s --retries=15 CMD curl --fail http://localhost:5000/health || exit
|
||||||
|
@ -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
|
COPY src/Kyoo.Swagger/Kyoo.Swagger.csproj src/Kyoo.Swagger/Kyoo.Swagger.csproj
|
||||||
RUN dotnet restore
|
RUN dotnet restore
|
||||||
|
|
||||||
WORKDIR /kyoo
|
WORKDIR /app
|
||||||
EXPOSE 5000
|
EXPOSE 5000
|
||||||
ENV DOTNET_USE_POLLING_FILE_WATCHER 1
|
ENV DOTNET_USE_POLLING_FILE_WATCHER 1
|
||||||
# HEALTHCHECK --interval=5s CMD curl --fail http://localhost:5000/health || exit
|
# HEALTHCHECK --interval=5s CMD curl --fail http://localhost:5000/health || exit
|
||||||
|
@ -28,6 +28,8 @@ public interface IThumbnailsManager
|
|||||||
Task DownloadImages<T>(T item)
|
Task DownloadImages<T>(T item)
|
||||||
where T : IThumbnails;
|
where T : IThumbnails;
|
||||||
|
|
||||||
|
Task DownloadImage(Image? image, string what);
|
||||||
|
|
||||||
string GetImagePath(Guid imageId, ImageQuality quality);
|
string GetImagePath(Guid imageId, ImageQuality quality);
|
||||||
|
|
||||||
Task DeleteImages<T>(T item)
|
Task DeleteImages<T>(T item)
|
||||||
|
77
back/src/Kyoo.Core/Controllers/MiscRepository.cs
Normal file
77
back/src/Kyoo.Core/Controllers/MiscRepository.cs
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
@ -50,7 +50,7 @@ public class ThumbnailsManager(
|
|||||||
await reader.CopyToAsync(file);
|
await reader.CopyToAsync(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task _DownloadImage(Image? image, string what)
|
public async Task DownloadImage(Image? image, string what)
|
||||||
{
|
{
|
||||||
if (image == null)
|
if (image == null)
|
||||||
return;
|
return;
|
||||||
@ -108,9 +108,9 @@ public class ThumbnailsManager(
|
|||||||
{
|
{
|
||||||
string name = item is IResource res ? res.Slug : "???";
|
string name = item is IResource res ? res.Slug : "???";
|
||||||
|
|
||||||
await _DownloadImage(item.Poster, $"The poster of {name}");
|
await DownloadImage(item.Poster, $"The poster of {name}");
|
||||||
await _DownloadImage(item.Thumbnail, $"The thumbnail of {name}");
|
await DownloadImage(item.Thumbnail, $"The thumbnail of {name}");
|
||||||
await _DownloadImage(item.Logo, $"The logo of {name}");
|
await DownloadImage(item.Logo, $"The logo of {name}");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
@ -63,5 +63,6 @@ public static class CoreModule
|
|||||||
);
|
);
|
||||||
builder.Services.AddScoped<IIssueRepository, IssueRepository>();
|
builder.Services.AddScoped<IIssueRepository, IssueRepository>();
|
||||||
builder.Services.AddScoped<SqlVariableContext>();
|
builder.Services.AddScoped<SqlVariableContext>();
|
||||||
|
builder.Services.AddScoped<MiscRepository>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ using System.Text.Json;
|
|||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using AspNetCore.Proxy;
|
using AspNetCore.Proxy;
|
||||||
using Kyoo.Abstractions.Models.Utils;
|
using Kyoo.Abstractions.Models.Utils;
|
||||||
|
using Kyoo.Authentication;
|
||||||
using Kyoo.Core.Api;
|
using Kyoo.Core.Api;
|
||||||
using Kyoo.Core.Controllers;
|
using Kyoo.Core.Controllers;
|
||||||
using Kyoo.Utils;
|
using Kyoo.Utils;
|
||||||
@ -45,6 +46,8 @@ public static class ServiceExtensions
|
|||||||
options.ModelBinderProviders.Insert(0, new IncludeBinder.Provider());
|
options.ModelBinderProviders.Insert(0, new IncludeBinder.Provider());
|
||||||
options.ModelBinderProviders.Insert(0, new FilterBinder.Provider());
|
options.ModelBinderProviders.Insert(0, new FilterBinder.Provider());
|
||||||
})
|
})
|
||||||
|
.AddApplicationPart(typeof(CoreModule).Assembly)
|
||||||
|
.AddApplicationPart(typeof(AuthenticationModule).Assembly)
|
||||||
.AddJsonOptions(x =>
|
.AddJsonOptions(x =>
|
||||||
{
|
{
|
||||||
x.JsonSerializerOptions.TypeInfoResolver = new JsonKindResolver()
|
x.JsonSerializerOptions.TypeInfoResolver = new JsonKindResolver()
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using Kyoo.Authentication;
|
using Kyoo.Authentication;
|
||||||
using Kyoo.Core;
|
using Kyoo.Core;
|
||||||
|
using Kyoo.Core.Controllers;
|
||||||
using Kyoo.Core.Extensions;
|
using Kyoo.Core.Extensions;
|
||||||
using Kyoo.Meiliseach;
|
using Kyoo.Meiliseach;
|
||||||
using Kyoo.Postgresql;
|
using Kyoo.Postgresql;
|
||||||
@ -69,11 +70,6 @@ AppDomain.CurrentDomain.UnhandledException += (_, ex) =>
|
|||||||
Log.Fatal(ex.ExceptionObject as Exception, "Unhandled exception");
|
Log.Fatal(ex.ExceptionObject as Exception, "Unhandled exception");
|
||||||
builder.Host.UseSerilog();
|
builder.Host.UseSerilog();
|
||||||
|
|
||||||
builder
|
|
||||||
.Services.AddMvcCore()
|
|
||||||
.AddApplicationPart(typeof(CoreModule).Assembly)
|
|
||||||
.AddApplicationPart(typeof(AuthenticationModule).Assembly);
|
|
||||||
|
|
||||||
builder.Services.ConfigureMvc();
|
builder.Services.ConfigureMvc();
|
||||||
builder.Services.ConfigureOpenApi();
|
builder.Services.ConfigureOpenApi();
|
||||||
builder.ConfigureKyoo();
|
builder.ConfigureKyoo();
|
||||||
@ -99,6 +95,7 @@ app.Services.GetRequiredService<RabbitProducer>();
|
|||||||
await using (AsyncServiceScope scope = app.Services.CreateAsyncScope())
|
await using (AsyncServiceScope scope = app.Services.CreateAsyncScope())
|
||||||
{
|
{
|
||||||
await MeilisearchModule.Initialize(scope.ServiceProvider);
|
await MeilisearchModule.Initialize(scope.ServiceProvider);
|
||||||
|
await scope.ServiceProvider.GetRequiredService<MiscRepository>().DownloadMissingImages();
|
||||||
}
|
}
|
||||||
|
|
||||||
app.Run(Environment.GetEnvironmentVariable("KYOO_BIND_URL") ?? "http://*:5000");
|
app.Run(Environment.GetEnvironmentVariable("KYOO_BIND_URL") ?? "http://*:5000");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user