From ce066150cf40d8a8079495a734bd90f68af33af5 Mon Sep 17 00:00:00 2001 From: jackfiled Date: Thu, 25 Jan 2024 17:33:46 +0800 Subject: [PATCH] =?UTF-8?q?add:=20=E5=9B=BE=E7=89=87=E5=A4=84=E7=90=86?= =?UTF-8?q?=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BlogApplicationBuilderExtension.cs | 5 + .../Extensions/BlogApplicationExtension.cs | 2 +- .../Processors/ImagePostRenderProcessor.cs | 94 +++++++++++++++++++ YaeBlog.Core/YaeBlog.Core.csproj | 1 + 4 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 YaeBlog.Core/Processors/ImagePostRenderProcessor.cs diff --git a/YaeBlog.Core/Extensions/BlogApplicationBuilderExtension.cs b/YaeBlog.Core/Extensions/BlogApplicationBuilderExtension.cs index 0fd99e3..537ac38 100644 --- a/YaeBlog.Core/Extensions/BlogApplicationBuilderExtension.cs +++ b/YaeBlog.Core/Extensions/BlogApplicationBuilderExtension.cs @@ -4,6 +4,7 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using YaeBlog.Core.Builder; using YaeBlog.Core.Models; +using YaeBlog.Core.Processors; using YaeBlog.Core.Services; using YamlDotNet.Serialization; using YamlDotNet.Serialization.NamingConventions; @@ -35,6 +36,10 @@ public static class BlogApplicationBuilderExtension builder.Services.AddSingleton(); builder.Services.AddSingleton(); + // 设置图像处理器 + builder.Services.AddSingleton(); + ImagePostRenderProcessor.AddImageApiEndpoint(builder); + builder.Services.AddHostedService((provider) => new WebApplicationHostedService(builder.WebApplicationBuilderConfigurations, builder.WebApplicationConfigurations, provider)); diff --git a/YaeBlog.Core/Extensions/BlogApplicationExtension.cs b/YaeBlog.Core/Extensions/BlogApplicationExtension.cs index 31a0626..01d7d59 100644 --- a/YaeBlog.Core/Extensions/BlogApplicationExtension.cs +++ b/YaeBlog.Core/Extensions/BlogApplicationExtension.cs @@ -10,7 +10,7 @@ public static class BlogApplicationExtension { internal static void ConfigureDefaultBlogApplication(this BlogApplication application) { - //application.UsePostRenderProcessor(); + application.UsePostRenderProcessor(); } public static void UsePreRenderProcessor(this BlogApplication application) diff --git a/YaeBlog.Core/Processors/ImagePostRenderProcessor.cs b/YaeBlog.Core/Processors/ImagePostRenderProcessor.cs new file mode 100644 index 0000000..f1ea7ba --- /dev/null +++ b/YaeBlog.Core/Processors/ImagePostRenderProcessor.cs @@ -0,0 +1,94 @@ +using AngleSharp; +using AngleSharp.Dom; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.HttpResults; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using YaeBlog.Core.Abstractions; +using YaeBlog.Core.Builder; +using YaeBlog.Core.Extensions; +using YaeBlog.Core.Models; + +namespace YaeBlog.Core.Processors; + +public class ImagePostRenderProcessor(ILogger logger, + IOptions options) + : IPostRenderProcessor +{ + private static readonly IConfiguration s_configuration = Configuration.Default; + + private readonly BlogOptions _options = options.Value; + + public async Task ProcessAsync(BlogEssay essay) + { + BrowsingContext context = new(s_configuration); + IDocument html = await context.OpenAsync( + req => req.Content(essay.HtmlContent)); + + IEnumerable imageElements = from node in html.All + where node.LocalName == "img" + select node; + + foreach (IElement element in imageElements) + { + IAttr? attr = element.Attributes.GetNamedItem("src"); + if (attr is not null) + { + logger.LogDebug("Found image link: '{}'", attr.Value); + attr.Value = GenerateImageLink(attr.Value, essay.FileName); + } + element.ClassList.Add("essay-image"); + } + return essay.WithNewHtmlContent(html.DocumentElement.OuterHtml); + } + + public string Name => "ImagePostRenderProcessor"; + + public static void AddImageApiEndpoint(BlogApplicationBuilder builder) + { + builder.ConfigureWebApplication((application) => + { + application.MapGet("/api/files/{*filename}", ImageHandler); + }); + } + + private static Results ImageHandler(string filename) + { + string contentType = "image/png"; + if (filename.EndsWith("jpg") || filename.EndsWith("jpeg")) + { + contentType = "image/jpeg"; + } + + if (!Path.Exists(filename)) + { + return TypedResults.NotFound(); + } + + Stream imageStream = File.OpenRead(filename); + return TypedResults.Stream(imageStream, contentType); + } + + private string GenerateImageLink(string filename, string essayFilename) + { + if (!filename.Contains(essayFilename)) + { + filename = Path.Combine(essayFilename, filename); + } + + filename = Path.Combine(_options.Root, filename); + + if (!Path.Exists(filename)) + { + logger.LogWarning("Failed to found image: {}.", filename); + return _options.BannerImage; + } + + string imageLink = "api/files/" + filename; + logger.LogDebug("Generate image link '{}' for image file '{}'.", + imageLink, filename); + + return imageLink; + } +} diff --git a/YaeBlog.Core/YaeBlog.Core.csproj b/YaeBlog.Core/YaeBlog.Core.csproj index e6d8669..e861549 100644 --- a/YaeBlog.Core/YaeBlog.Core.csproj +++ b/YaeBlog.Core/YaeBlog.Core.csproj @@ -16,6 +16,7 @@ +