Implemented category filter on RSS

This commit is contained in:
Mia Rose Winter 2024-02-04 14:46:18 +01:00
parent 894a653cdd
commit 2d4e7c9b9d
Signed by: miawinter
GPG key ID: 4B6F6A83178F595E

View file

@ -12,7 +12,6 @@
namespace Wave.Controllers; namespace Wave.Controllers;
[ApiController] [ApiController]
[Route("/[controller]")] [Route("/[controller]")]
public class RssController(IOptions<Customization> customizations, ApplicationDbContext context) : ControllerBase { public class RssController(IOptions<Customization> customizations, ApplicationDbContext context) : ControllerBase {
@ -22,37 +21,46 @@ public class RssController(IOptions<Customization> customizations, ApplicationDb
[HttpGet("rss.xml", Name = "RssFeed")] [HttpGet("rss.xml", Name = "RssFeed")]
[Produces("application/rss+xml")] [Produces("application/rss+xml")]
[ResponseCache(Duration = 60*15, Location = ResponseCacheLocation.Any)] [ResponseCache(Duration = 60*15, Location = ResponseCacheLocation.Any)]
public async Task<IActionResult> GetRssFeedAsync() { public async Task<IActionResult> GetRssFeedAsync(string? category = null) {
return Ok(await CreateFeedAll("RssFeed")); var feed = await CreateFeedAll("RssFeed", category);
if (feed is null) return NotFound();
return Ok(feed);
} }
[HttpGet("atom.xml", Name = "AtomFeed")] [HttpGet("atom.xml", Name = "AtomFeed")]
[Produces("application/atom+xml")] [Produces("application/atom+xml")]
[ResponseCache(Duration = 60*15, Location = ResponseCacheLocation.Any)] [ResponseCache(Duration = 60*15, Location = ResponseCacheLocation.Any)]
public async Task<IActionResult> GetAtomFeedAsync() { public async Task<IActionResult> GetAtomFeedAsync(string? category = null) {
return Ok(await CreateFeedAll("AtomFeed")); var feed = await CreateFeedAll("AtomFeed", category);
if (feed is null) return NotFound();
return Ok(feed);
} }
private async Task<SyndicationFeed> CreateFeedAll(string? routeName) { private async Task<SyndicationFeed?> CreateFeedAll(string? routeName, string? category) {
var now = DateTimeOffset.UtcNow; var now = DateTimeOffset.UtcNow;
var query = Context.Set<Article>() IQueryable<Article> query = Context.Set<Article>()
.Include(a => a.Author) .Include(a => a.Author)
.Include(a => a.Categories) .Include(a => a.Categories)
.Where(a => a.Status >= ArticleStatus.Published && a.PublishDate <= now) .Where(a => a.Status >= ArticleStatus.Published && a.PublishDate <= now)
.OrderByDescending(a => a.PublishDate) .OrderByDescending(a => a.PublishDate);
.Take(15);
var articles = await query.ToListAsync(); if (!string.IsNullOrWhiteSpace(category)) {
var date = query.Max(a => a.PublishDate); query = query.Where(a => a.Categories.Any(c => c.Name == category));
return CreateFeedAsync(articles, date, routeName);
} }
private SyndicationFeed CreateFeedAsync(IEnumerable<Article> articles, DateTimeOffset date, string? routeName) { query = query.Take(15);
var articles = await query.ToListAsync();
if (articles.Count < 1) return null;
var date = query.Max(a => a.PublishDate);
return CreateFeedAsync(articles, date, routeName, category);
}
private SyndicationFeed CreateFeedAsync(IEnumerable<Article> articles, DateTimeOffset date, string? routeName, string? category) {
string appName = Customizations.Value.AppName; string appName = Customizations.Value.AppName;
var host = new Uri($"https://{Request.Host}{Request.PathBase}", UriKind.Absolute); var host = new Uri($"https://{Request.Host}{Request.PathBase}", UriKind.Absolute);
var link = new Uri(Url.RouteUrl(routeName, null, "https", host.Host) ?? host.AbsoluteUri); var link = new Uri(Url.RouteUrl(routeName, null, "https", host.Host) ?? host.AbsoluteUri);
return new SyndicationFeed(appName, "Feed on " + appName, link, articles var feed = new SyndicationFeed(appName, "Feed on " + appName, link, articles
.Select(article => { .Select(article => {
var item = new SyndicationItem( var item = new SyndicationItem(
article.Title, article.Title,
@ -81,5 +89,8 @@ public class RssController(IOptions<Customization> customizations, ApplicationDb
new SyndicationLink(link) { RelationshipType = "self" } new SyndicationLink(link) { RelationshipType = "self" }
} }
}; };
if (category != null) feed.Categories.Add(new SyndicationCategory(category));
return feed;
} }
} }