dev: 渲染服务和文件内容服务
This commit is contained in:
24
YaeBlog.Core/Services/BlogHostedService.cs
Normal file
24
YaeBlog.Core/Services/BlogHostedService.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace YaeBlog.Core.Services;
|
||||
|
||||
public class BlogHostedService(
|
||||
ILogger<BlogHostedService> logger,
|
||||
RendererService rendererService) : IHostedService
|
||||
{
|
||||
public async Task StartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
logger.LogInformation("Welcome to YaeBlog!");
|
||||
|
||||
await rendererService.RenderAsync();
|
||||
}
|
||||
|
||||
public Task StopAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
logger.LogInformation("YaeBlog stopped!\nHave a nice day!");
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
|
||||
}
|
18
YaeBlog.Core/Services/EssayContentService.cs
Normal file
18
YaeBlog.Core/Services/EssayContentService.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using System.Collections.Concurrent;
|
||||
using YaeBlog.Core.Models;
|
||||
|
||||
namespace YaeBlog.Core.Services;
|
||||
|
||||
public class EssayContentService
|
||||
{
|
||||
private readonly ConcurrentDictionary<string, BlogEssay> _essays = new();
|
||||
|
||||
public bool TryGet(string key, out BlogEssay? essay)
|
||||
=> _essays.TryGetValue(key, out essay);
|
||||
|
||||
public bool TryAdd(string key, BlogEssay essay) => _essays.TryAdd(key, essay);
|
||||
|
||||
public IEnumerable<KeyValuePair<string, BlogEssay>> Essays => _essays;
|
||||
|
||||
public int Count => _essays.Count;
|
||||
}
|
57
YaeBlog.Core/Services/EssayScanService.cs
Normal file
57
YaeBlog.Core/Services/EssayScanService.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using System.Collections.Concurrent;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using YaeBlog.Core.Exceptions;
|
||||
using YaeBlog.Core.Models;
|
||||
|
||||
namespace YaeBlog.Core.Services;
|
||||
|
||||
public class EssayScanService(
|
||||
IOptions<BlogOptions> blogOptions,
|
||||
ILogger<EssayContentService> logger)
|
||||
{
|
||||
private readonly BlogOptions _blogOptions = blogOptions.Value;
|
||||
|
||||
public async Task<List<BlogContent>> ScanAsync()
|
||||
{
|
||||
string root = Path.Combine(Environment.CurrentDirectory, _blogOptions.Root);
|
||||
DirectoryInfo rootDirectory = new(root);
|
||||
|
||||
if (!rootDirectory.Exists)
|
||||
{
|
||||
throw new BlogFileException($"'{root}' is not a directory.");
|
||||
}
|
||||
|
||||
List<FileInfo> markdownFiles = [];
|
||||
|
||||
await Task.Run(() =>
|
||||
{
|
||||
foreach (FileInfo fileInfo in rootDirectory.EnumerateFiles())
|
||||
{
|
||||
if (fileInfo.Extension != ".md")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
logger.LogDebug("Scan markdown file: {}.", fileInfo.Name);
|
||||
markdownFiles.Add(fileInfo);
|
||||
}
|
||||
});
|
||||
|
||||
ConcurrentBag<BlogContent> contents = [];
|
||||
|
||||
await Parallel.ForEachAsync(markdownFiles, async (info, token) =>
|
||||
{
|
||||
StreamReader reader = new(info.OpenRead());
|
||||
|
||||
BlogContent content = new()
|
||||
{
|
||||
FileName = info.Name, FileContent = await reader.ReadToEndAsync(token)
|
||||
};
|
||||
|
||||
contents.Add(content);
|
||||
});
|
||||
|
||||
return contents.ToList();
|
||||
}
|
||||
}
|
35
YaeBlog.Core/Services/RendererService.cs
Normal file
35
YaeBlog.Core/Services/RendererService.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
using System.Collections.Concurrent;
|
||||
using Markdig;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using YaeBlog.Core.Exceptions;
|
||||
using YaeBlog.Core.Models;
|
||||
|
||||
namespace YaeBlog.Core.Services;
|
||||
|
||||
public class RendererService(ILogger<RendererService> logger,
|
||||
EssayScanService essayScanService,
|
||||
MarkdownPipeline markdownPipeline,
|
||||
EssayContentService essayContentService)
|
||||
{
|
||||
public async Task RenderAsync()
|
||||
{
|
||||
List<BlogContent> contents = await essayScanService.ScanAsync();
|
||||
|
||||
Parallel.ForEach(contents, content =>
|
||||
{
|
||||
logger.LogDebug("Render markdown file {}.", content.FileName);
|
||||
BlogEssay essay = new()
|
||||
{
|
||||
Title = content.FileName,
|
||||
PublishTime = DateTime.Now,
|
||||
HtmlContent = Markdown.ToHtml(content.FileContent, markdownPipeline)
|
||||
};
|
||||
|
||||
if (!essayContentService.TryAdd(essay.Title, essay))
|
||||
{
|
||||
throw new BlogFileException(
|
||||
$"There are two essays with the same name: '{content.FileName}'.");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user