add static media creator

This commit is contained in:
2024-03-21 13:34:35 +01:00
parent ccd1db47cf
commit f56f9db161
5 changed files with 79 additions and 74 deletions
+1 -1
View File
@@ -45,7 +45,7 @@ public class ImageDimensionReader : IImageDimensionReader
MemoryCacheEntryOptions cacheEntryOptions = new();
cacheEntryOptions.AddExpirationToken(FileProvider.Watch(resolvedPath));
//cacheEntryOptions.SetSize(value.Length * sizeof(char));
cacheEntryOptions.SetSize(1);
Cache.Set(path, value, cacheEntryOptions);
return value;
+2 -2
View File
@@ -22,7 +22,7 @@ public class MediaCreator : IMediaCreator
/// <inheritdoc />
public async Task<Result<Media>> UploadFile(Stream fileStream, string filename, string folderId = null, CancellationToken cancellationToken = default)
public virtual async Task<Result<Media>> UploadFile(Stream fileStream, string filename, string folderId = null, CancellationToken cancellationToken = default)
{
string fileExtension = Path.GetExtension(filename);
string normalizedFilename = Safenames.File(filename);
@@ -92,7 +92,7 @@ public class MediaCreator : IMediaCreator
/// <inheritdoc />
protected virtual MediaMetadata GetImageMetadata(Image<Rgba32> image)
protected virtual MediaMetadata GetImageMetadata(IImageInfo image)
{
PngMetadata pngMetadata = image.Metadata.GetPngMetadata();
//WebpMetadata webpMetadata = image.Metadata.GetWebpMetadata();
-70
View File
@@ -1,70 +0,0 @@
namespace zero.Media;
/// <summary>
/// A cached media entity comes from the IMemoryCache
/// and is therefore reduced to only necessary properties
/// (Id, ParentId, Path, Metadata, AltText, Caption)
/// </summary>
public sealed class CachedMedia : Media
{
internal static CachedMedia Create(MediaCacheEntry entry)
{
return new()
{
Id = entry.Id,
ParentId = entry.ParentId,
Path = entry.Path,
AltText = entry.AltText,
Caption = entry.Caption,
Metadata = entry.Metadata
};
}
}
internal class MediaCacheEntry
{
/// <summary>
/// Id of the entity
/// </summary>
public string Id { get; set; }
/// <summary>
/// Id of the parent folder
/// </summary>
public string ParentId { get; set; }
/// <summary>
/// Path of the media item
/// </summary>
public string Path { get; set; }
/// <summary>
/// Alternative text which is used when the media can't be loaded
/// </summary>
public string AltText { get; set; }
/// <summary>
/// Additional caption text
/// </summary>
public string Caption { get; set; }
/// <summary>
/// Meta data for images/videos
/// </summary>
public MediaMetadata Metadata { get; set; }
internal static MediaCacheEntry Create(Media entry)
{
return new()
{
Id = entry.Id,
ParentId = entry.ParentId,
Path = entry.Path,
AltText = entry.AltText,
Caption = entry.Caption,
Metadata = entry.Metadata
};
}
}
+75
View File
@@ -0,0 +1,75 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.FileProviders;
using SixLabors.ImageSharp;
using System.IO;
namespace zero.Media;
public class StaticMediaCreator : MediaCreator, IStaticMediaCreator
{
protected IMemoryCache Cache { get; set; }
protected IFileProvider FileProvider { get; set; }
public StaticMediaCreator(IMediaFileSystem fileSystem, IZeroOptions options, IWebHostEnvironment hostingEnvironment, MediaMetadataCache cacheProvider) : base(fileSystem, options)
{
FileProvider = hostingEnvironment.WebRootFileProvider;
Cache = cacheProvider.Cache;
}
/// <inheritdoc />
public virtual async Task<Result<Media>> GetMedia(string path, CancellationToken cancellationToken = default)
{
if (Cache.TryGetValue(path, out Media media))
{
return Result<Media>.Success(media);
}
string filename = Path.GetFileName(path);
string fileExtension = Path.GetExtension(filename);
bool isImage = Options.AllowedImageFileExtensions.Contains(fileExtension, StringComparer.InvariantCultureIgnoreCase);
bool isDocument = !isImage && Options.AllowedOtherFileExtensions.Contains(fileExtension, StringComparer.InvariantCultureIgnoreCase);
if (!isImage && !isDocument)
{
return Result<Media>.Fail("This file type is not supported");
}
Media model = new();
model.Name = filename;
model.Path = path;
model.IsFolder = false;
// we need file metadata to get info about file size and the physical path for image modification
IFileMeta fileInfo = await FileSystem.GetFileInfo(model.Path, cancellationToken);
model.Size = fileInfo.Length;
if (isImage)
{
IImageInfo info = await Image.IdentifyAsync(fileInfo.AbsolutePath, cancellationToken);
model.Metadata = GetImageMetadata(info);
}
MemoryCacheEntryOptions cacheEntryOptions = new();
cacheEntryOptions.AddExpirationToken(FileProvider.Watch(fileInfo.AbsolutePath));
cacheEntryOptions.SetSize(1);
Cache.Set(path, model, cacheEntryOptions);
return Result<Media>.Success(model);
}
}
public interface IStaticMediaCreator
{
/// <summary>
/// Builds a media file from a path
/// </summary>
Task<Result<Media>> GetMedia(string path, CancellationToken cancellationToken = default);
}
+1 -1
View File
@@ -33,11 +33,11 @@ internal class ZeroMediaModule : ZeroModule
{
IOptions<MediaOptions> options = svc.GetRequiredService<IOptions<MediaOptions>>();
IWebHostEnvironment env = svc.GetRequiredService<IWebHostEnvironment>();
Console.WriteLine("media path: " + options.Value.FolderPath);
return new(Path.Combine(env.WebRootPath, options.Value.FolderPath), options.Value.PublicPathPrefix + options.Value.FolderPath.EnsureStartsWith('/'));
});
services.AddScoped<IMediaCreator, MediaCreator>();
services.AddScoped<IStaticMediaCreator, StaticMediaCreator>();
services.AddScoped<IMediaManagement, MediaManagement>();
services.AddScoped<IZeroMediaStoreDbProvider, EmptyZeroMediaStoreDbProvider>();
services.AddSingleton<IImageDimensionReader, ImageDimensionReader>();