refactor(blog): use api controller for /blog/feed endpoint

This commit is contained in:
Oliver Booth 2023-08-13 18:02:58 +01:00
parent 369436ccce
commit bbc76bc305
Signed by: oliverbooth
GPG Key ID: B89D139977693FED
4 changed files with 32 additions and 31 deletions

View File

@ -1,32 +1,39 @@
using System.Diagnostics.CodeAnalysis;
using System.Xml.Serialization;
using System.Xml.Serialization;
using Microsoft.AspNetCore.Mvc;
using OliverBooth.Data.Blog;
using OliverBooth.Data.Blog.Rss;
using OliverBooth.Services;
namespace OliverBooth.Middleware;
namespace OliverBooth.Controllers.Blog;
internal sealed class RssMiddleware
[ApiController]
[Route("blog/feed")]
public class RssController : Controller
{
private readonly IBlogPostService _blogPostService;
public RssMiddleware(RequestDelegate _, IBlogPostService blogPostService)
/// <summary>
/// Initializes a new instance of the <see cref="RssController" /> class.
/// </summary>
/// <param name="blogPostService">The <see cref="IBlogPostService" />.</param>
public RssController(IBlogPostService blogPostService)
{
_blogPostService = blogPostService;
}
[SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "Middleware")]
public async Task Invoke(HttpContext context)
[HttpGet]
[Produces("application/rss+xml")]
public IActionResult OnGet()
{
context.Response.ContentType = "application/rss+xml";
Response.ContentType = "application/rss+xml";
var baseUrl = $"https://{context.Request.Host}/blog";
var baseUrl = $"https://{Request.Host}/blog";
var blogItems = new List<BlogItem>();
foreach (IBlogPost post in _blogPostService.GetAllBlogPosts())
{
var url = $"{baseUrl}/{post.Published:yyyy/MM/dd}/{post.Slug}";
string excerpt = _blogPostService.RenderExcerpt(post, out _);
string excerpt = _blogPostService.RenderPost(post);
var description = $"{excerpt}<p><a href=\"{url}\">Read more...</a></p>";
var item = new BlogItem
@ -36,7 +43,7 @@ internal sealed class RssMiddleware
Comments = $"{url}#disqus_thread",
Creator = post.Author.DisplayName,
PubDate = post.Published.ToString("R"),
Guid = $"{baseUrl}?pid={post.Id}",
Guid = post.WordPressId.HasValue ? $"{baseUrl}?p={post.WordPressId.Value}" : $"{baseUrl}?pid={post.Id}",
Description = description
};
blogItems.Add(item);
@ -68,7 +75,9 @@ internal sealed class RssMiddleware
xmlNamespaces.Add("sy", "http://purl.org/rss/1.0/modules/syndication/");
xmlNamespaces.Add("slash", "http://purl.org/rss/1.0/modules/slash/");
await using var writer = new StreamWriter(context.Response.BodyWriter.AsStream());
using var writer = new StreamWriter(Response.BodyWriter.AsStream());
serializer.Serialize(writer, rss, xmlNamespaces);
return Ok();
}
}

View File

@ -37,6 +37,9 @@ internal sealed class BlogPost : IBlogPost
/// <inheritdoc />
public DateTimeOffset? Updated { get; internal set; }
/// <inheritdoc />
public int? WordPressId { get; set; }
/// <summary>
/// Gets or sets the ID of the author of this blog post.
/// </summary>
@ -61,12 +64,6 @@ internal sealed class BlogPost : IBlogPost
/// <value>The Disqus URL path.</value>
internal string? DisqusPath { get; set; }
/// <summary>
/// Gets or sets the WordPress ID of this blog post.
/// </summary>
/// <value>The WordPress ID of this blog post.</value>
internal int? WordPressId { get; set; }
/// <summary>
/// Gets the Disqus domain for the blog post.
/// </summary>

View File

@ -69,6 +69,14 @@ public interface IBlogPost
/// <value>The update date and time, or <see langword="null" /> if the post has not been updated.</value>
DateTimeOffset? Updated { get; }
/// <summary>
/// Gets the WordPress ID of the post.
/// </summary>
/// <value>
/// The WordPress ID of the post, or <see langword="null" /> if the post was not imported from WordPress.
/// </value>
int? WordPressId { get; }
/// <summary>
/// Gets the Disqus identifier for the post.
/// </summary>

View File

@ -1,13 +0,0 @@
namespace OliverBooth.Middleware;
internal static class RssEndpointExtensions
{
public static IEndpointConventionBuilder MapRssFeed(this IEndpointRouteBuilder endpoints, string pattern)
{
RequestDelegate pipeline = endpoints.CreateApplicationBuilder()
.UseMiddleware<RssMiddleware>()
.Build();
return endpoints.Map(pattern, pipeline).WithDisplayName("RSS Feed");
}
}