Example #1
0
        public IEnumerable <IDocument> Execute(IReadOnlyList <IDocument> inputs, IExecutionContext context)
        {
            XDocument rss     = new XDocument(new XDeclaration("1.0", "UTF-8", null));
            FilePath  rssPath = new DirectoryPath(_siteUri.ToString()).CombineFile(_rssPath);

            XElement rssRoot = new XElement("rss",
                                            new XAttribute("version", "2.0"),
                                            new XAttribute(XNamespace.Xmlns + "atom", AtomNamespace)
                                            );

            XElement channel = new XElement("channel",
                                            new XElement("title", _feedTitle),
                                            new XElement("description", _feedDescription),
                                            new XElement("link", _siteUri.ToString()),
                                            new XElement(AtomNamespace + "link",
                                                         new XAttribute("href", rssPath.FullPath),
                                                         new XAttribute("rel", "self")
                                                         ),
                                            new XElement("lastBuildDate", DateTimeHelper.ToRssDate(DateTime.Now))
                                            );

            if (_language != null)
            {
                channel.Add(new XElement("language", _language));
            }

            foreach (IDocument input in inputs)
            {
                XElement item = new XElement("item");

                object title;
                bool   hasTitle = input.TryGetValue(_titleMetaKey, out title);
                item.Add(new XElement("title", hasTitle ? title : "Untitled"));

                // Get the item link
                FilePath link = input.FilePath(Keys.RssItemUrl)
                                ?? input.FilePath(Keys.RelativeFilePath);
                if (link != null)
                {
                    if (link.IsAbsolute)
                    {
                        link = new DirectoryPath("/").GetRelativePath(link);
                    }
                    if (_linkCustomizerDelegate != null)
                    {
                        link = _linkCustomizerDelegate(link);

                        // Check for absolute one more time in case the customizer returned an absolute path
                        if (link.IsAbsolute)
                        {
                            link = new DirectoryPath("/").GetRelativePath(link);
                        }
                    }
                }
                if (link == null)
                {
                    throw new Exception($"Required metadata keys {Keys.RssItemUrl} or {Keys.RelativeFilePath} were not found in the document {input.SourceString()}");
                }

                FilePath itemLink = new DirectoryPath(_siteUri.ToString()).CombineFile(link);
                item.Add(new XElement("link", itemLink.FullPath));

                object description    = null;
                bool   hasDescription = input.TryGetValue(_descriptionMetaKey, out description);
                item.Add(new XElement("description", hasDescription ? description : "No description"));

                object pubDate = null;
                if (input.TryGetValue(_pubDateMetaKey, out pubDate))
                {
                    item.Add(new XElement("pubDate", DateTimeHelper.ToRssDate(DateTime.Parse((string)pubDate))));
                }

                if (_appendGuid)
                {
                    object guid;
                    bool   hasGuid = input.TryGetValue(_guidMetaKey, out guid);

                    if (hasGuid)
                    {
                        item.Add(new XElement("guid", guid, new XAttribute("isPermaLink", false)));
                    }
                    else
                    {
                        if (_assumePermalinks)
                        {
                            item.Add(new XElement("guid", link));
                        }
                        else if (input.Source == null)
                        {
                            Trace.Warning($"Cannot generate RSS item guid for document {input.SourceString()} because document source is not valid");
                        }
                        else
                        {
                            item.Add(new XElement("guid", GuidHelper.ToGuid(input.Source.FullPath).ToString(), new XAttribute("isPermaLink", false)));
                        }
                    }
                }

                channel.Add(item);
            }

            rss.Add(rssRoot);
            rssRoot.Add(channel);

            // rss.ToString() doesn't return XML declaration
            StringBuilder outText = new StringBuilder();

            using (UTF8StringWriter stream = new UTF8StringWriter(outText))
            {
                rss.Save(stream);
            }

            return(new IDocument[] { context.GetDocument(outText.ToString(), new KeyValuePair <string, object>[] {
                    new KeyValuePair <string, object>(Keys.IsRssFeed, true),
                    new KeyValuePair <string, object>(Keys.RelativeFilePath, _rssPath),
                    new KeyValuePair <string, object>(Keys.WritePath, _rssPath)
                }) });
        }