/// <summary> /// Enables processing of HTTP Web requests by a custom HttpHandler that implements /// the <see cref="T:System.Web.IHttpHandler"></see> interface. /// </summary> /// <param name="context">An <see cref="T:System.Web.HttpContext"></see> object that provides references /// to the intrinsic server objects (for example, Request, Response, Session, and Server) used to service HTTP requests. /// </param> public void ProcessRequest(HttpContext context) { string title = RetrieveTitle(context); SyndicationFormat format = RetrieveFormat(context); List<IPublishable> list = GenerateItemList(context); list = CleanList(list); if (string.IsNullOrEmpty(context.Request.QueryString["post"])) { // Shorten the list to the number of posts stated in the settings, except for the comment feed. int max = Math.Min(TrainSettings.Instance.PostsPerFeed, list.Count); list = list.FindAll(delegate(IPublishable item) { return item.IsVisible == true; }); list = list.GetRange(0, max); } SetHeaderInformation(context, list, format); if (TrainSettings.Instance.EnableHttpCompression) HttpModules.CompressionModule.CompressResponse(context); SyndicationGenerator generator = new SyndicationGenerator(TrainSettings.Instance, Category.Categories); generator.WriteFeed(format, context.Response.OutputStream, list, title); }
//============================================================ // PRIVATE ATOM METHODS //============================================================ #region WriteAtomContent(XmlWriter writer, List<IPublishable> publishables) /// <summary> /// Writes the Atom feed element information to the specified <see cref="XmlWriter"/> using the supplied collection. /// </summary> /// <param name="writer">The <see cref="XmlWriter"/> to write channel element information to.</param> /// <param name="publishables">The collection of <see cref="IPublishable"/> objects used to generate syndication content.</param> /// <param name="title">The title of the ATOM content.</param> private void WriteAtomContent(XmlWriter writer, List <IPublishable> publishables, string title) { //------------------------------------------------------------ // Write required feed elements //------------------------------------------------------------ writer.WriteElementString("id", Utils.AbsoluteWebRoot.ToString()); writer.WriteElementString("title", title); writer.WriteElementString("updated", (publishables.Count > 0) ? SyndicationGenerator.ToW3CDateTime(publishables[0].DateModified.ToUniversalTime()) : SyndicationGenerator.ToW3CDateTime(DateTime.UtcNow)); //------------------------------------------------------------ // Write recommended feed elements //------------------------------------------------------------ writer.WriteStartElement("link"); writer.WriteAttributeString("href", Utils.AbsoluteWebRoot.ToString()); writer.WriteEndElement(); writer.WriteStartElement("link"); writer.WriteAttributeString("rel", "self"); writer.WriteAttributeString("href", Utils.AbsoluteWebRoot + "syndication.axd?format=atom"); writer.WriteEndElement(); //writer.WriteStartElement("link"); //writer.WriteAttributeString("rel", "alternate"); //writer.WriteAttributeString("href", Utils.FeedUrl.ToString()); //writer.WriteEndElement(); //------------------------------------------------------------ // Write optional feed elements //------------------------------------------------------------ writer.WriteElementString("subtitle", this.Settings.Description); //------------------------------------------------------------ // Write common/shared feed elements //------------------------------------------------------------ this.WriteAtomContentCommonElements(writer); foreach (IPublishable publishable in publishables) { //------------------------------------------------------------ // Skip publishable content if it is not visible //------------------------------------------------------------ if (!publishable.IsVisible) { continue; } //------------------------------------------------------------ // Write <entry> element for publishable content //------------------------------------------------------------ WriteAtomEntry(writer, publishable); } }
/// <summary> /// Writes the Atom feed entry element information to the specified <see cref="XmlWriter"/> using the supplied <see cref="Page"/>. /// </summary> /// <param name="writer">The <see cref="XmlWriter"/> to write feed entry element information to.</param> /// <param name="publishable">The <see cref="IPublishable"/> used to generate feed entry content.</param> private static void WriteAtomEntry(XmlWriter writer, IPublishable publishable) { Training post = publishable as Training; Comment comment = publishable as Comment; //------------------------------------------------------------ // Raise serving event //------------------------------------------------------------ ServingEventArgs arg = new ServingEventArgs(publishable.Content, ServingLocation.Feed); publishable.OnServing(arg); if (arg.Cancel) { return; } //------------------------------------------------------------ // Modify publishable content to make references absolute //------------------------------------------------------------ string content = ConvertPathsToAbsolute(arg.Body); writer.WriteStartElement("entry"); //------------------------------------------------------------ // Write required entry elements //------------------------------------------------------------ writer.WriteElementString("id", Utils.ConvertToAbsolute(publishable.RelativeLink).ToString()); writer.WriteElementString("title", publishable.Title); writer.WriteElementString("updated", SyndicationGenerator.ToW3CDateTime(publishable.DateCreated.ToUniversalTime())); //------------------------------------------------------------ // Write recommended entry elements //------------------------------------------------------------ writer.WriteStartElement("link"); writer.WriteAttributeString("rel", "self"); writer.WriteAttributeString("href", SyndicationGenerator.GetPermaLink(publishable).ToString()); writer.WriteEndElement(); writer.WriteStartElement("link"); writer.WriteAttributeString("href", Utils.ConvertToAbsolute(publishable.RelativeLink).ToString()); writer.WriteEndElement(); writer.WriteStartElement("author"); writer.WriteElementString("name", publishable.Author); writer.WriteEndElement(); writer.WriteStartElement("summary"); writer.WriteAttributeString("type", "html"); writer.WriteString(content); writer.WriteEndElement(); //------------------------------------------------------------ // Write optional entry elements //------------------------------------------------------------ writer.WriteElementString("published", SyndicationGenerator.ToW3CDateTime(publishable.DateCreated.ToUniversalTime())); writer.WriteStartElement("link"); writer.WriteAttributeString("rel", "related"); writer.WriteAttributeString("href", String.Concat(Utils.ConvertToAbsolute(publishable.RelativeLink).ToString(), "#comment")); writer.WriteEndElement(); //------------------------------------------------------------ // Write enclosure tag for podcasting support //------------------------------------------------------------ if (TrainSettings.Instance.EnableEnclosures) { string encloser = GetEnclosure(content); if (!string.IsNullOrEmpty(encloser)) { writer.WriteRaw(encloser); } } //------------------------------------------------------------ // Write entry category elements //------------------------------------------------------------ if (publishable.Categories != null) { foreach (Category category in publishable.Categories) { writer.WriteStartElement("category"); writer.WriteAttributeString("term", category.Title); writer.WriteEndElement(); } } //------------------------------------------------------------ // Write Dublin Core syndication extension elements //------------------------------------------------------------ if (!String.IsNullOrEmpty(publishable.Author)) { writer.WriteElementString("dc", "publisher", "http://purl.org/dc/elements/1.1/", publishable.Author); } if (!String.IsNullOrEmpty(publishable.Description)) { writer.WriteElementString("dc", "description", "http://purl.org/dc/elements/1.1/", publishable.Description); } //------------------------------------------------------------ // Write pingback syndication extension elements //------------------------------------------------------------ Uri pingbackServer; if (Uri.TryCreate(String.Concat(Utils.AbsoluteWebRoot.ToString().TrimEnd('/'), "/pingback.axd"), UriKind.RelativeOrAbsolute, out pingbackServer)) { writer.WriteElementString("pingback", "server", "http://madskills.com/public/xml/rss/module/pingback/", pingbackServer.ToString()); writer.WriteElementString("pingback", "target", "http://madskills.com/public/xml/rss/module/pingback/", SyndicationGenerator.GetPermaLink(publishable).ToString()); } //------------------------------------------------------------ // Write slash syndication extension elements //------------------------------------------------------------ if (post != null && post.Comments != null) { writer.WriteElementString("slash", "comments", "http://purl.org/rss/1.0/modules/slash/", post.Comments.Count.ToString(CultureInfo.InvariantCulture)); } //------------------------------------------------------------ // Write trackback syndication extension elements //------------------------------------------------------------ if (post != null && post.TrackbackLink != null) { writer.WriteElementString("trackback", "ping", "http://madskills.com/public/xml/rss/module/trackback/", post.TrackbackLink.ToString()); } //------------------------------------------------------------ // Write well-formed web syndication extension elements //------------------------------------------------------------ writer.WriteElementString("wfw", "comment", "http://wellformedweb.org/CommentAPI/", String.Concat(Utils.ConvertToAbsolute(publishable.RelativeLink).ToString(), "#comment")); writer.WriteElementString("wfw", "commentRss", "http://wellformedweb.org/CommentAPI/", Utils.AbsoluteWebRoot.ToString().TrimEnd('/') + "/syndication.axd?post=" + publishable.Id.ToString()); //------------------------------------------------------------ // Write </entry> element //------------------------------------------------------------ writer.WriteEndElement(); }
/// <summary> /// Converts the supplied <see cref="DateTime"/> to its equivalent <a href="http://www.w3.org/TR/NOTE-datetime">W3C DateTime</a> string representation. /// </summary> /// <param name="utcDateTime">The Coordinated Universal Time (UTC) <see cref="DateTime"/> to convert.</param> /// <returns>The equivalent <a href="http://www.w3.org/TR/NOTE-datetime">W3C DateTime</a> string representation.</returns> private static string ToW3CDateTime(DateTime utcDateTime) { TimeSpan utcOffset = TimeSpan.Zero; return((utcDateTime + utcOffset).ToString("yyyy-MM-ddTHH:mm:ss", CultureInfo.InvariantCulture) + SyndicationGenerator.FormatW3cOffset(utcOffset, ":")); }