Files
mixtape/zero/Media/StaticMediaCreator.cs
T

81 lines
2.5 KiB
C#

using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.FileProviders;
using SixLabors.ImageSharp;
using System.IO;
using Microsoft.Extensions.Logging;
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, ILogger<IMediaCreator> logger) : base(fileSystem, options, logger)
{
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);
}
if (!await FileSystem.Exists(path, cancellationToken))
{
return Result<Media>.Fail("File not found");
}
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)
{
ImageInfo info = await Image.IdentifyAsync(fileInfo.AbsolutePath, cancellationToken);
model.Metadata = GetImageMetadata(info.Metadata, info.Size);
}
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);
}