diff --git a/zero/Media/ImageDimensionReader.cs b/zero/Media/ImageDimensionReader.cs
index 263bd813..06ddf966 100644
--- a/zero/Media/ImageDimensionReader.cs
+++ b/zero/Media/ImageDimensionReader.cs
@@ -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;
diff --git a/zero/Media/MediaCreator.cs b/zero/Media/MediaCreator.cs
index 3a187e97..f8195c9b 100644
--- a/zero/Media/MediaCreator.cs
+++ b/zero/Media/MediaCreator.cs
@@ -22,7 +22,7 @@ public class MediaCreator : IMediaCreator
///
- public async Task> UploadFile(Stream fileStream, string filename, string folderId = null, CancellationToken cancellationToken = default)
+ public virtual async Task> 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
///
- protected virtual MediaMetadata GetImageMetadata(Image image)
+ protected virtual MediaMetadata GetImageMetadata(IImageInfo image)
{
PngMetadata pngMetadata = image.Metadata.GetPngMetadata();
//WebpMetadata webpMetadata = image.Metadata.GetWebpMetadata();
diff --git a/zero/Media/Models/CachedMedia.cs b/zero/Media/Models/CachedMedia.cs
deleted file mode 100644
index 413d7173..00000000
--- a/zero/Media/Models/CachedMedia.cs
+++ /dev/null
@@ -1,70 +0,0 @@
-namespace zero.Media;
-
-///
-/// A cached media entity comes from the IMemoryCache
-/// and is therefore reduced to only necessary properties
-/// (Id, ParentId, Path, Metadata, AltText, Caption)
-///
-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
-{
- ///
- /// Id of the entity
- ///
- public string Id { get; set; }
-
- ///
- /// Id of the parent folder
- ///
- public string ParentId { get; set; }
-
- ///
- /// Path of the media item
- ///
- public string Path { get; set; }
-
- ///
- /// Alternative text which is used when the media can't be loaded
- ///
- public string AltText { get; set; }
-
- ///
- /// Additional caption text
- ///
- public string Caption { get; set; }
-
- ///
- /// Meta data for images/videos
- ///
- 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
- };
- }
-}
\ No newline at end of file
diff --git a/zero/Media/StaticMediaCreator.cs b/zero/Media/StaticMediaCreator.cs
new file mode 100644
index 00000000..347627a2
--- /dev/null
+++ b/zero/Media/StaticMediaCreator.cs
@@ -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;
+ }
+
+
+
+ ///
+ public virtual async Task> GetMedia(string path, CancellationToken cancellationToken = default)
+ {
+ if (Cache.TryGetValue(path, out Media media))
+ {
+ return Result.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.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.Success(model);
+ }
+}
+
+
+
+public interface IStaticMediaCreator
+{
+ ///
+ /// Builds a media file from a path
+ ///
+ Task> GetMedia(string path, CancellationToken cancellationToken = default);
+}
\ No newline at end of file
diff --git a/zero/Media/ZeroMediaModule.cs b/zero/Media/ZeroMediaModule.cs
index 48869e7a..fdb9571e 100644
--- a/zero/Media/ZeroMediaModule.cs
+++ b/zero/Media/ZeroMediaModule.cs
@@ -33,11 +33,11 @@ internal class ZeroMediaModule : ZeroModule
{
IOptions options = svc.GetRequiredService>();
IWebHostEnvironment env = svc.GetRequiredService();
- 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();
+ services.AddScoped();
services.AddScoped();
services.AddScoped();
services.AddSingleton();