add static media creator
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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>();
|
||||
|
||||
Reference in New Issue
Block a user