From 134af1ba833e298898d06e686587980eec680afd Mon Sep 17 00:00:00 2001 From: PaulaBean Date: Thu, 16 Oct 2014 14:14:44 -0400 Subject: [PATCH] Add RSS feed handling --- TheDailyWtf/App_Start/RouteConfig.cs | 6 ++ .../Common/ActionResults/RssArticlesResult.cs | 65 +++++++++++++++++++ TheDailyWtf/Controllers/HomeController.cs | 9 +++ TheDailyWtf/Models/ArticleModel.cs | 22 ++++++- TheDailyWtf/TheDailyWtf.csproj | 4 +- TheDailyWtf/robots.txt | 6 ++ 6 files changed, 108 insertions(+), 4 deletions(-) create mode 100644 TheDailyWtf/Common/ActionResults/RssArticlesResult.cs create mode 100644 TheDailyWtf/robots.txt diff --git a/TheDailyWtf/App_Start/RouteConfig.cs b/TheDailyWtf/App_Start/RouteConfig.cs index 154d098..638abed 100644 --- a/TheDailyWtf/App_Start/RouteConfig.cs +++ b/TheDailyWtf/App_Start/RouteConfig.cs @@ -27,6 +27,12 @@ public static void RegisterRoutes(RouteCollection routes) defaults: new { controller = "Admin", action = "EditSeries", slug = UrlParameter.Optional } ); + routes.MapRoute( + name: "Rss", + url: "rss", + defaults: new { controller = "Home", action = "Rss" } + ); + routes.MapRoute( name: "Contact", url: "contact", diff --git a/TheDailyWtf/Common/ActionResults/RssArticlesResult.cs b/TheDailyWtf/Common/ActionResults/RssArticlesResult.cs new file mode 100644 index 0000000..9df9ff9 --- /dev/null +++ b/TheDailyWtf/Common/ActionResults/RssArticlesResult.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Web.Mvc; +using System.Xml; +using System.Xml.Linq; +using TheDailyWtf.Models; + +namespace TheDailyWtf +{ + public sealed class RssArticlesResult : ActionResult + { + private readonly IEnumerable articles; + + public RssArticlesResult(IEnumerable articles) + { + if (articles == null) + throw new ArgumentNullException("articles"); + + this.articles = articles; + } + + public override void ExecuteResult(ControllerContext context) + { + var response = context.HttpContext.Response; + response.ContentEncoding = Encoding.UTF8; + response.ContentType = "application/rss+xml"; + + var dc = XNamespace.Get("http://purl.org/dc/elements/1.1/"); + var slash = XNamespace.Get("http://purl.org/rss/1.0/modules/slash/"); + var wfw = XNamespace.Get("http://wellformedweb.org/CommentAPI/"); + + var xdoc = new XDocument( + new XElement("rss", + new XAttribute("version", "2.0"), + new XAttribute(XNamespace.Xmlns + "dc", dc), + new XAttribute(XNamespace.Xmlns + "slash", slash), + new XAttribute(XNamespace.Xmlns + "wfw", wfw), + new XElement("channel", + new XElement("title", "The Daily WTF"), + new XElement("link", "http://thedailywtf.com/"), + new XElement("description", "Curious Perversions in Information Technology"), + this.articles.Select(a => new XElement("item", + new XElement("author", a.Author.Name), + new XElement("title", a.RssTitle), + new XElement("link", a.Url), + new XElement("category", a.Series.Title), + new XElement("pubDate", a.PublishedDate.Value.ToUniversalTime().ToString("r")), + new XElement("guid", a.Id), + new XElement("description", ""), + new XElement(slash + "comments", a.CoalescedCommentCount), + new XElement("comments", a.CommentsUrl) + )) + ) + ) + ); + + using (var writer = XmlWriter.Create(response.OutputStream, new XmlWriterSettings { Encoding = Encoding.UTF8, Indent = false, NewLineChars = "" })) + { + xdoc.WriteTo(writer); + } + } + } +} \ No newline at end of file diff --git a/TheDailyWtf/Controllers/HomeController.cs b/TheDailyWtf/Controllers/HomeController.cs index 30d9862..724e7c3 100644 --- a/TheDailyWtf/Controllers/HomeController.cs +++ b/TheDailyWtf/Controllers/HomeController.cs @@ -36,6 +36,15 @@ public ActionResult Sponsors() return View(new HomeIndexViewModel()); } + [OutputCache(CacheProfile = CacheProfile.Timed5Minutes, VaryByParam = "*")] + public ActionResult Rss() + { + if (Request.QueryString["fbsrc"] != "Y" && Request.QueryString["sneak"] != "Y") + return new RedirectResult("http://syndication.thedailywtf.com/TheDailyWtf", false); + + return new RssArticlesResult(ArticleModel.GetRecentArticles(15)); + } + [HttpPost] [ValidateAntiForgeryToken] public ActionResult Contact(ContactFormViewModel model) diff --git a/TheDailyWtf/Models/ArticleModel.cs b/TheDailyWtf/Models/ArticleModel.cs index 9083489..ad56c5a 100644 --- a/TheDailyWtf/Models/ArticleModel.cs +++ b/TheDailyWtf/Models/ArticleModel.cs @@ -24,8 +24,19 @@ public ArticleModel() [AllowHtml] public string BodyHtml { get; set; } public string Title { get; set; } + public string RssTitle + { + get + { + if (this.Series.Title.Equals("Feature Articles", StringComparison.OrdinalIgnoreCase)) + return HttpUtility.HtmlEncode(this.Title); + else + return HttpUtility.HtmlEncode(string.Format("{0}: {1}", this.Series.Title, this.Title)); + } + } public int DiscourseCommentCount { get; set; } public int CachedCommentCount { get; set; } + public int CoalescedCommentCount { get { return Math.Max(this.DiscourseCommentCount, this.CachedCommentCount); } } public DateTime? LastCommentDate { get; set; } public string LastCommentDateDescription { @@ -43,8 +54,8 @@ public string LastCommentDateDescription public string DiscourseThreadUrl { get { return string.Format("http://what.thedailywtf.com/t/{0}/{1}", this.DiscourseTopicSlug, this.DiscourseTopicId); } } public DateTime? PublishedDate { get; set; } public SeriesModel Series { get; set; } - public string Url { get { return string.Format("//{0}/articles/{1}", Config.Wtf.Host, this.Slug); } } - public string CommentsUrl { get { return string.Format("//{0}/articles/comments/{1}", Config.Wtf.Host, this.Slug); } } + public string Url { get { return string.Format("http://{0}/articles/{1}", Config.Wtf.Host, this.Slug); } } + public string CommentsUrl { get { return string.Format("http://{0}/articles/comments/{1}", Config.Wtf.Host, this.Slug); } } public string Slug { get; set; } public string TwitterUrl { get { return string.Format("//www.twitter.com/home?status=http:{0}+-+{1}+-+The+Daily+WTF", HttpUtility.UrlEncode(this.Url), HttpUtility.UrlEncode(this.Title)); } } public string FacebookUrl { get { return string.Format("//www.facebook.com/sharer.php?u=http:{0}&t={1}+-+The+Daily+WTF", HttpUtility.UrlEncode(this.Url), HttpUtility.UrlEncode(this.Title)); } } @@ -97,7 +108,12 @@ public static IEnumerable GetSeriesArticlesByMonth(string series, public static IEnumerable GetRecentArticles() { - var articles = StoredProcs.Articles_GetRecentArticles(Domains.PublishedStatus.Published, Article_Count: 8).Execute(); + return GetRecentArticles(8); + } + + public static IEnumerable GetRecentArticles(int count) + { + var articles = StoredProcs.Articles_GetRecentArticles(Domains.PublishedStatus.Published, Article_Count: count).Execute(); return articles.Select(a => ArticleModel.FromTable(a)); } diff --git a/TheDailyWtf/TheDailyWtf.csproj b/TheDailyWtf/TheDailyWtf.csproj index e54a3f4..ba15ce7 100644 --- a/TheDailyWtf/TheDailyWtf.csproj +++ b/TheDailyWtf/TheDailyWtf.csproj @@ -1,5 +1,5 @@  - + Debug @@ -106,6 +106,7 @@ + @@ -213,6 +214,7 @@ + diff --git a/TheDailyWtf/robots.txt b/TheDailyWtf/robots.txt new file mode 100644 index 0000000..0bf49af --- /dev/null +++ b/TheDailyWtf/robots.txt @@ -0,0 +1,6 @@ +User-agent: * +Disallow: /Resources/ +Disallow: /Admin/ +Disallow: /Comments/AddComment.aspx +Disallow: /Comments/EditComment.aspx +Disallow: /Comments/DeleteComment.aspx \ No newline at end of file