using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using zero.Core.Database; using zero.Core.Entities; using zero.Core.Extensions; namespace zero.Web.ViewHelpers { public class ZeroMediaHelper : IZeroMediaHelper { IZeroStore Store; public IZeroMediaHelper Core { 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, bool global = false) { Store = store; if (!global) { Core = new ZeroMediaHelper(store, true); } } /// public async Task GetById(string id) { if (id.IsNullOrEmpty()) { return null; } if (!Cache.TryGetValue(id, out 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)) { 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 = await GetById(id); return media?.Source.TrimStart("url://"); } /// public async Task> GetUrls(string[] ids, bool isAbsolute = false) { Dictionary medias = await GetByIds(ids); return medias.ToDictionary(x => x.Key, x => x.Value?.Source.TrimStart("url://")); } } 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); } }