diff --git a/ErsatzTV.Application/Images/Queries/GetImageContentsHandler.cs b/ErsatzTV.Application/Images/Queries/GetImageContentsHandler.cs index bcdcb389a..636ee0934 100644 --- a/ErsatzTV.Application/Images/Queries/GetImageContentsHandler.cs +++ b/ErsatzTV.Application/Images/Queries/GetImageContentsHandler.cs @@ -42,7 +42,7 @@ namespace ErsatzTV.Application.Images.Queries ArtworkKind.Poster => Path.Combine(FileSystemLayout.PosterCacheFolder, subfolder), ArtworkKind.Thumbnail => Path.Combine(FileSystemLayout.ThumbnailCacheFolder, subfolder), ArtworkKind.Logo => Path.Combine(FileSystemLayout.LogoCacheFolder, subfolder), - _ => FileSystemLayout.ImageCacheFolder + _ => FileSystemLayout.LegacyImageCacheFolder }; string fileName = Path.Combine(baseFolder, request.FileName); diff --git a/ErsatzTV.Core/FileSystemLayout.cs b/ErsatzTV.Core/FileSystemLayout.cs index fce0e1bae..f78453ecf 100644 --- a/ErsatzTV.Core/FileSystemLayout.cs +++ b/ErsatzTV.Core/FileSystemLayout.cs @@ -15,7 +15,7 @@ namespace ErsatzTV.Core public static readonly string LogDatabasePath = Path.Combine(AppDataFolder, "logs.sqlite3"); - public static readonly string ImageCacheFolder = Path.Combine(AppDataFolder, "cache", "images"); + public static readonly string LegacyImageCacheFolder = Path.Combine(AppDataFolder, "cache", "images"); public static readonly string PlexSecretsPath = Path.Combine(AppDataFolder, "plex-secrets.json"); diff --git a/ErsatzTV.Infrastructure/Images/ImageCache.cs b/ErsatzTV.Infrastructure/Images/ImageCache.cs index 6c658462d..1896c92e5 100644 --- a/ErsatzTV.Infrastructure/Images/ImageCache.cs +++ b/ErsatzTV.Infrastructure/Images/ImageCache.cs @@ -56,7 +56,7 @@ namespace ErsatzTV.Infrastructure.Images ArtworkKind.Poster => Path.Combine(FileSystemLayout.PosterCacheFolder, subfolder), ArtworkKind.Thumbnail => Path.Combine(FileSystemLayout.ThumbnailCacheFolder, subfolder), ArtworkKind.Logo => Path.Combine(FileSystemLayout.LogoCacheFolder, subfolder), - _ => FileSystemLayout.ImageCacheFolder + _ => FileSystemLayout.LegacyImageCacheFolder }; string target = Path.Combine(baseFolder, hex); @@ -85,7 +85,7 @@ namespace ErsatzTV.Infrastructure.Images ArtworkKind.Poster => Path.Combine(FileSystemLayout.PosterCacheFolder, subfolder), ArtworkKind.Thumbnail => Path.Combine(FileSystemLayout.ThumbnailCacheFolder, subfolder), ArtworkKind.Logo => Path.Combine(FileSystemLayout.LogoCacheFolder, subfolder), - _ => FileSystemLayout.ImageCacheFolder + _ => FileSystemLayout.LegacyImageCacheFolder }; string target = Path.Combine(baseFolder, hex); _localFileSystem.CopyFile(path, target); diff --git a/ErsatzTV/Extensions/HostExtensions.cs b/ErsatzTV/Extensions/HostExtensions.cs index 4c2522944..7571cea09 100644 --- a/ErsatzTV/Extensions/HostExtensions.cs +++ b/ErsatzTV/Extensions/HostExtensions.cs @@ -1,4 +1,8 @@ using System; +using System.IO; +using System.Linq; +using ErsatzTV.Core; +using ErsatzTV.Core.Domain; using ErsatzTV.Infrastructure.Data; using LanguageExt; using Microsoft.EntityFrameworkCore; @@ -17,12 +21,24 @@ namespace ErsatzTV.Extensions return host; } + public static IHost CleanCacheFolder(this IHost host) + { + Unit _ = use(() => host.Services.CreateScope(), CleanCache); + return host; + } + private static Unit Seed(IServiceScope scope) => Try(() => scope.ServiceProvider) .Bind(services => Try(GetDbContext(services))) .Bind(ctx => Try(Migrate(ctx))) .Bind(ctx => Try(InitializeDb(ctx))) - .IfFail(ex => LogException(ex, scope.ServiceProvider)); + .IfFail(ex => LogException(ex, "Error occured while seeding database", scope.ServiceProvider)); + + private static Unit CleanCache(IServiceScope scope) => + Try(() => scope.ServiceProvider) + .Bind(services => Try(GetDbContext(services))) + .Bind(ctx => Try(CleanCache(ctx, scope.ServiceProvider))) + .IfFail(ex => LogException(ex, "Error occured while cleaning cache", scope.ServiceProvider)); private static TvContext GetDbContext(IServiceProvider provider) => provider.GetRequiredService(); @@ -36,10 +52,40 @@ namespace ErsatzTV.Extensions private static Unit InitializeDb(TvContext context) => DbInitializer.Initialize(context); - private static Unit LogException(Exception ex, IServiceProvider provider) + private static Unit CleanCache(TvContext context, IServiceProvider provider) + { + if (Directory.Exists(FileSystemLayout.LegacyImageCacheFolder)) + { + ILogger logger = provider.GetRequiredService>(); + logger.LogInformation("Migrating channel logos from legacy image cache folder"); + + var logos = context.Channels + .SelectMany(c => c.Artwork) + .Where(a => a.ArtworkKind == ArtworkKind.Logo) + .Map(a => a.Path) + .ToList(); + + foreach (string logo in logos) + { + string legacyPath = Path.Combine(FileSystemLayout.LegacyImageCacheFolder, logo); + if (File.Exists(legacyPath)) + { + string subfolder = logo.Substring(0, 2); + string newPath = Path.Combine(FileSystemLayout.LogoCacheFolder, subfolder, logo); + File.Copy(legacyPath, newPath, true); + } + } + + logger.LogInformation("Deleting legacy image cache folder"); + Directory.Delete(FileSystemLayout.LegacyImageCacheFolder, true); + } + + return Unit.Default; + } + + private static Unit LogException(Exception ex, string message, IServiceProvider provider) { - provider.GetRequiredService>() - .LogError(ex, "Error occured while seeding database"); + provider.GetRequiredService>().LogError(ex, message); return unit; } } diff --git a/ErsatzTV/Program.cs b/ErsatzTV/Program.cs index b7c7d5fe8..4505b1a35 100644 --- a/ErsatzTV/Program.cs +++ b/ErsatzTV/Program.cs @@ -34,6 +34,7 @@ namespace ErsatzTV await CreateHostBuilder(args) .Build() .SeedDatabase() + .CleanCacheFolder() .RunAsync(); return 0; }