using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using zero.Extensions; using zero.Media; using zero.Persistence; namespace zero.Web.ViewHelpers; public class ZeroMediaHelper : IZeroMediaHelper { IZeroStore Store; public IZeroMediaHelper Core { get; private set; } protected IMediaManagement MediaManagement { get; private set; } protected bool Global { get; set; } /// /// Media cache for repetitive queries within an HTTP request /// ConcurrentDictionary Cache { get; set; } = new(); public ZeroMediaHelper(IZeroStore store, IMediaManagement mediaManagement, bool global = false) { Store = store; MediaManagement = mediaManagement; if (!global) { Core = new ZeroMediaHelper(store, MediaManagement, true); } } /// public async Task GetById(string id) { if (id.IsNullOrEmpty()) { return null; } if (!Cache.TryGetValue(id, out Media.Media media)) { media = await Store.Session(Global).LoadAsync(id); Cache.TryAdd(id, media); } return media; } /// public async Task> GetByIds(string[] ids) { HashSet remoteIds = new HashSet(); Dictionary items = new Dictionary(); foreach (string id in ids) { if (Cache.TryGetValue(id, out Media.Media media)) { items.TryAdd(id, media); } else { remoteIds.Add(id); } } if (remoteIds.Count > 0) { Dictionary remoteItems = await Store.Session(Global).LoadAsync(remoteIds); foreach (var item in remoteItems) { items.TryAdd(item.Key, item.Value); Cache.TryAdd(item.Key, item.Value); } } return items; } /// public async Task GetUrl(string id, bool isAbsolute = false) { Media.Media media = await GetById(id); if (media == null) { return null; } if (media.Path.StartsWith("url://")) { return media.Path.TrimStart("url://"); } return MediaManagement.GetPublicFilePath(media); } /// public async Task> GetUrls(string[] ids, bool isAbsolute = false) { Dictionary result = new(); Dictionary medias = await GetByIds(ids); foreach ((string id, Media.Media media) in medias) { if (media == null) { result.Add(id, null); } else if (media.Path.StartsWith("url://")) { result.Add(id, media.Path.TrimStart("url://")); } else { result.Add(id, MediaManagement.GetPublicFilePath(media)); } } return result; } } public interface IZeroMediaHelper { IZeroMediaHelper Core { get; } /// /// Get media by Id /// Task GetById(string id); /// /// Get media items by Ids /// Task> GetByIds(string[] ids); /// /// Get source for a media item /// Task GetUrl(string id, bool isAbsolute = false); /// /// Get source for media items /// Task> GetUrls(string[] ids, bool isAbsolute = false); }