137 lines
5.3 KiB
C#
137 lines
5.3 KiB
C#
using CarneiroTech.Models;
|
|
using Microsoft.Extensions.Caching.Memory;
|
|
using System.Globalization;
|
|
|
|
namespace CarneiroTech.Services;
|
|
|
|
public class CaseService : ICaseService
|
|
{
|
|
private readonly IMarkdownService _markdownService;
|
|
private readonly IMemoryCache _cache;
|
|
private readonly IWebHostEnvironment _environment;
|
|
private readonly string _casesPath;
|
|
private const string CACHE_KEY = "cases_retail";
|
|
private const int CACHE_MINUTES = 60;
|
|
|
|
public CaseService(IMarkdownService markdownService, IMemoryCache cache, IWebHostEnvironment environment)
|
|
{
|
|
_markdownService = markdownService;
|
|
_cache = cache;
|
|
_environment = environment;
|
|
_casesPath = Path.Combine(_environment.ContentRootPath, "Content", "Cases", "Retail");
|
|
}
|
|
|
|
public async Task<List<CaseModel>> GetAllCasesAsync()
|
|
{
|
|
if (_cache.TryGetValue(CACHE_KEY, out List<CaseModel>? cachedCases) && cachedCases != null)
|
|
{
|
|
return cachedCases;
|
|
}
|
|
|
|
var cases = new List<CaseModel>();
|
|
|
|
if (!Directory.Exists(_casesPath))
|
|
{
|
|
return cases;
|
|
}
|
|
|
|
var markdownFiles = Directory.GetFiles(_casesPath, "*.md");
|
|
|
|
foreach (var file in markdownFiles)
|
|
{
|
|
var caseModel = await ParseCaseFileAsync(file);
|
|
if (caseModel != null)
|
|
{
|
|
cases.Add(caseModel);
|
|
}
|
|
}
|
|
|
|
cases = cases.OrderBy(c => c.Metadata.Order)
|
|
.ThenByDescending(c => c.Metadata.Date)
|
|
.ToList();
|
|
|
|
_cache.Set(CACHE_KEY, cases, TimeSpan.FromMinutes(CACHE_MINUTES));
|
|
|
|
return cases;
|
|
}
|
|
|
|
public async Task<List<CaseModel>> GetFeaturedCasesAsync()
|
|
{
|
|
var allCases = await GetAllCasesAsync();
|
|
return allCases.Where(c => c.Metadata.Featured).ToList();
|
|
}
|
|
|
|
public async Task<CaseModel?> GetCaseBySlugAsync(string slug)
|
|
{
|
|
var allCases = await GetAllCasesAsync();
|
|
return allCases.FirstOrDefault(c => c.Metadata.Slug.Equals(slug, StringComparison.OrdinalIgnoreCase));
|
|
}
|
|
|
|
public async Task<List<string>> GetAllTagsAsync()
|
|
{
|
|
var allCases = await GetAllCasesAsync();
|
|
return allCases.SelectMany(c => c.Metadata.Tags).Distinct().OrderBy(t => t).ToList();
|
|
}
|
|
|
|
public async Task<List<CaseModel>> GetCasesByTagAsync(string tag)
|
|
{
|
|
var allCases = await GetAllCasesAsync();
|
|
return allCases.Where(c => c.Metadata.Tags.Contains(tag, StringComparer.OrdinalIgnoreCase)).ToList();
|
|
}
|
|
|
|
private async Task<CaseModel?> ParseCaseFileAsync(string filePath)
|
|
{
|
|
try
|
|
{
|
|
var content = await File.ReadAllTextAsync(filePath);
|
|
var frontMatter = _markdownService.ParseFrontMatter(content, out string bodyContent);
|
|
|
|
var metadata = new CaseMetadata
|
|
{
|
|
Title = GetStringValue(frontMatter, "title"),
|
|
Slug = GetStringValue(frontMatter, "slug"),
|
|
Summary = GetStringValue(frontMatter, "summary"),
|
|
Client = GetStringValue(frontMatter, "client"),
|
|
DeviceModel = GetStringValue(frontMatter, "device_model"),
|
|
EstimatedSavings = GetDecimalValue(frontMatter, "estimated_savings"),
|
|
Category = GetStringValue(frontMatter, "category"),
|
|
Thumbnail = GetStringValue(frontMatter, "thumbnail"),
|
|
Image = GetStringValue(frontMatter, "image"),
|
|
Tags = GetListValue(frontMatter, "tags"),
|
|
Featured = GetBoolValue(frontMatter, "featured"),
|
|
Order = GetIntValue(frontMatter, "order"),
|
|
Date = GetDateValue(frontMatter, "date"),
|
|
SeoTitle = GetStringValue(frontMatter, "seo_title"),
|
|
SeoDescription = GetStringValue(frontMatter, "seo_description"),
|
|
SeoKeywords = GetStringValue(frontMatter, "seo_keywords")
|
|
};
|
|
|
|
return new CaseModel
|
|
{
|
|
Metadata = metadata,
|
|
ContentHtml = _markdownService.ConvertToHtml(bodyContent),
|
|
ContentMarkdown = bodyContent
|
|
};
|
|
}
|
|
catch { return null; }
|
|
}
|
|
|
|
private string GetStringValue(Dictionary<string, object> dict, string key) =>
|
|
dict.ContainsKey(key) ? dict[key]?.ToString() ?? string.Empty : string.Empty;
|
|
|
|
private decimal GetDecimalValue(Dictionary<string, object> dict, string key) =>
|
|
dict.ContainsKey(key) && decimal.TryParse(dict[key]?.ToString(), NumberStyles.Any, CultureInfo.InvariantCulture, out decimal res) ? res : 0;
|
|
|
|
private List<string> GetListValue(Dictionary<string, object> dict, string key) =>
|
|
dict.ContainsKey(key) && dict[key] is List<object> list ? list.Select(i => i?.ToString() ?? "").ToList() : new();
|
|
|
|
private bool GetBoolValue(Dictionary<string, object> dict, string key) =>
|
|
dict.ContainsKey(key) && (dict[key]?.ToString()?.ToLower() == "true" || dict[key]?.ToString() == "1");
|
|
|
|
private int GetIntValue(Dictionary<string, object> dict, string key) =>
|
|
dict.ContainsKey(key) && int.TryParse(dict[key]?.ToString(), out int res) ? res : 0;
|
|
|
|
private DateTime GetDateValue(Dictionary<string, object> dict, string key) =>
|
|
dict.ContainsKey(key) && DateTime.TryParse(dict[key]?.ToString(), CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime res) ? res : DateTime.MinValue;
|
|
}
|