feat(web): add local portfolio cover storage
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.StaticFiles;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.FileProviders;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
|
||||
namespace GmRelay.Web.Services.Portfolio.Covers;
|
||||
|
||||
public static class PortfolioCoverStorageExtensions
|
||||
{
|
||||
public static IServiceCollection AddPortfolioCoverStorage(
|
||||
this IServiceCollection services,
|
||||
IConfiguration configuration)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(services);
|
||||
ArgumentNullException.ThrowIfNull(configuration);
|
||||
|
||||
services
|
||||
.AddOptions<PortfolioCoverStorageOptions>()
|
||||
.Bind(configuration.GetSection(PortfolioCoverStorageOptions.SectionName))
|
||||
.Validate(
|
||||
o => !string.IsNullOrWhiteSpace(o.StoragePath),
|
||||
"PortfolioCovers:StoragePath must be configured.")
|
||||
.ValidateOnStart();
|
||||
|
||||
services.AddSingleton<IPortfolioCoverStorage>(sp =>
|
||||
{
|
||||
var options = sp.GetRequiredService<
|
||||
Microsoft.Extensions.Options.IOptions<PortfolioCoverStorageOptions>>().Value;
|
||||
var logger = sp.GetService<ILoggerFactory>()?.CreateLogger<LocalPortfolioCoverStorage>()
|
||||
?? NullLogger<LocalPortfolioCoverStorage>.Instance;
|
||||
return new LocalPortfolioCoverStorage(options, logger);
|
||||
});
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
public static WebApplication UsePortfolioCoverFiles(this WebApplication app)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(app);
|
||||
|
||||
var options = app.Services.GetRequiredService<
|
||||
Microsoft.Extensions.Options.IOptions<PortfolioCoverStorageOptions>>().Value;
|
||||
|
||||
var storagePath = Path.IsPathRooted(options.StoragePath)
|
||||
? options.StoragePath
|
||||
: Path.Combine(app.Environment.ContentRootPath, options.StoragePath);
|
||||
|
||||
Directory.CreateDirectory(storagePath);
|
||||
|
||||
var contentTypeProvider = new FileExtensionContentTypeProvider();
|
||||
if (!contentTypeProvider.Mappings.ContainsKey(".jpg"))
|
||||
{
|
||||
contentTypeProvider.Mappings[".jpg"] = "image/jpeg";
|
||||
}
|
||||
|
||||
if (!contentTypeProvider.Mappings.ContainsKey(".png"))
|
||||
{
|
||||
contentTypeProvider.Mappings[".png"] = "image/png";
|
||||
}
|
||||
|
||||
if (!contentTypeProvider.Mappings.ContainsKey(".webp"))
|
||||
{
|
||||
contentTypeProvider.Mappings[".webp"] = "image/webp";
|
||||
}
|
||||
|
||||
app.UseStaticFiles(new StaticFileOptions
|
||||
{
|
||||
FileProvider = new PhysicalFileProvider(storagePath),
|
||||
RequestPath = "/portfolio-covers",
|
||||
ContentTypeProvider = contentTypeProvider,
|
||||
OnPrepareResponse = ctx =>
|
||||
{
|
||||
ctx.Context.Response.Headers["Cache-Control"] = "public, max-age=31536000, immutable";
|
||||
}
|
||||
});
|
||||
|
||||
return app;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user