Improved RSS feeds
This commit is contained in:
		
							parent
							
								
									b3867fdcae
								
							
						
					
					
						commit
						9f6f3cb142
					
				|  | @ -1,4 +1,5 @@ | ||||||
| using System.ServiceModel.Syndication; | using System.Net; | ||||||
|  | using System.ServiceModel.Syndication; | ||||||
| using Microsoft.AspNetCore.Mvc; | using Microsoft.AspNetCore.Mvc; | ||||||
| using Microsoft.EntityFrameworkCore; | using Microsoft.EntityFrameworkCore; | ||||||
| using Microsoft.Extensions.Options; | using Microsoft.Extensions.Options; | ||||||
|  | @ -58,18 +59,42 @@ public class RssController(IOptions<Customization> customizations, ApplicationDb | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private SyndicationFeed CreateFeedAsync(IEnumerable<Article> articles, DateTimeOffset date, string? routeName, string? category) { | 	private SyndicationFeed CreateFeedAsync(IEnumerable<Article> articles, DateTimeOffset date, string? routeName, string? category) { | ||||||
| 		string appName = Customizations.Value.AppName; | 		var customizations = Customizations.Value; | ||||||
| 		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 feed = new SyndicationFeed(appName, "Feed on " + appName, link, articles | 		string appName = customizations.AppName; | ||||||
| 			.Select(article => { | 		Uri host; | ||||||
|  | 		if (string.IsNullOrWhiteSpace(customizations.AppUrl)) { | ||||||
|  | 			host = new Uri(customizations.AppUrl); | ||||||
|  | 		} else { | ||||||
|  | 			host = new Uri($"https://{Request.Host}", UriKind.Absolute); | ||||||
|  | 		} | ||||||
|  | 		var feedLink = new Uri(Url.RouteUrl(routeName, null, "https", host.Host) ?? host.AbsoluteUri); | ||||||
|  | 		var htmlLink = host; | ||||||
|  | 		if (category is not null) { | ||||||
|  | 			feedLink = new Uri(feedLink.AbsoluteUri + "?category=" + WebUtility.HtmlEncode(category)); | ||||||
|  | 			htmlLink = new Uri(host, "/category/" + WebUtility.HtmlEncode(category)); | ||||||
|  | 		} | ||||||
|  | 		 | ||||||
|  | 		var feed = new SyndicationFeed(appName, "Feed on " + appName, htmlLink, host.AbsoluteUri, date) { | ||||||
|  | 			TimeToLive = TimeSpan.FromMinutes(15), | ||||||
|  | 			Generator = "Wave", | ||||||
|  | 			Links = { new SyndicationLink(feedLink) {RelationshipType = "self"} }, | ||||||
|  | 			Items = GetItems(articles, host) | ||||||
|  | 		}; | ||||||
|  | 		if (category != null) feed.Categories.Add(new SyndicationCategory(category)); | ||||||
|  | 
 | ||||||
|  | 		return feed; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	private static IEnumerable<SyndicationItem> GetItems(IEnumerable<Article> articles, Uri host) { | ||||||
|  | 		return articles.Select(article => { | ||||||
| 				var item = new SyndicationItem( | 				var item = new SyndicationItem( | ||||||
| 					article.Title, | 					article.Title, | ||||||
| 					new TextSyndicationContent(article.BodyHtml, TextSyndicationContentKind.Html), | 					new TextSyndicationContent(article.BodyHtml, TextSyndicationContentKind.Html), | ||||||
| 					new Uri(ArticleUtilities.GenerateArticleLink(article, host)), | 					new Uri(ArticleUtilities.GenerateArticleLink(article, host)), | ||||||
| 					new Uri(host, "article/" + article.Id).AbsoluteUri, | 					new Uri(host, "article/" + article.Id).AbsoluteUri, | ||||||
| 					article.PublishDate) { | 					article.LastPublicChange)  | ||||||
|  | 				{ | ||||||
| 					Authors = { | 					Authors = { | ||||||
| 						new SyndicationPerson {Name = article.Author.FullName} | 						new SyndicationPerson {Name = article.Author.FullName} | ||||||
| 					}, | 					}, | ||||||
|  | @ -80,18 +105,9 @@ public class RssController(IOptions<Customization> customizations, ApplicationDb | ||||||
| 				foreach (var category in article.Categories.OrderBy(c => c.Color)) { | 				foreach (var category in article.Categories.OrderBy(c => c.Color)) { | ||||||
| 					item.Categories.Add(new SyndicationCategory(category.Name)); | 					item.Categories.Add(new SyndicationCategory(category.Name)); | ||||||
| 				} | 				} | ||||||
|  | 
 | ||||||
| 				return item; | 				return item; | ||||||
| 			}) | 			}) | ||||||
| 			.ToList()) { | 			.ToList(); | ||||||
| 				TimeToLive = TimeSpan.FromMinutes(15), |  | ||||||
| 				LastUpdatedTime = date, |  | ||||||
| 				Generator = "Wave", |  | ||||||
| 				Links = { |  | ||||||
| 					new SyndicationLink(link) { RelationshipType = "self" } |  | ||||||
| 				} |  | ||||||
| 		}; |  | ||||||
| 		if (category != null) feed.Categories.Add(new SyndicationCategory(category)); |  | ||||||
| 
 |  | ||||||
| 		return feed; |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | @ -33,6 +33,11 @@ public class Article : ISoftDelete { | ||||||
|     public DateTimeOffset PublishDate { get; set; } = DateTimeOffset.MaxValue; |     public DateTimeOffset PublishDate { get; set; } = DateTimeOffset.MaxValue; | ||||||
|     public DateTimeOffset? LastModified { get; set; } |     public DateTimeOffset? LastModified { get; set; } | ||||||
| 
 | 
 | ||||||
|  |     /// <summary> | ||||||
|  |     /// Returns LastModified if it's after the articles PublishDate, otherwise gives you the PublishDate | ||||||
|  |     /// </summary> | ||||||
|  |     public DateTimeOffset LastPublicChange => LastModified > PublishDate ? LastModified.Value : PublishDate; | ||||||
|  | 
 | ||||||
|     public IList<Category> Categories { get; } = []; |     public IList<Category> Categories { get; } = []; | ||||||
|     public IList<ArticleImage> Images { get; } = []; |     public IList<ArticleImage> Images { get; } = []; | ||||||
| } | } | ||||||
		Loading…
	
		Reference in a new issue