private static string MakeLinksAbsolute(HtmlParser parser, HtmlMarkupFormatter formatter, IExecutionContext context, string value) { if (!string.IsNullOrEmpty(value)) { IHtmlDocument dom = parser.Parse(string.Empty); INodeList nodes = parser.ParseFragment(value, dom.Body); IEnumerable <IElement> elements = nodes.SelectMany(x => x.Descendents <IElement>().Where(y => y.HasAttribute("href") || y.HasAttribute("src"))); bool replaced = false; foreach (IElement element in elements) { replaced = MakeLinkAbsolute(element, "href", context) || replaced; replaced = MakeLinkAbsolute(element, "src", context) || replaced; } if (replaced) { using (StringWriter writer = new StringWriter()) { nodes.ToHtml(writer, formatter); return(writer.ToString()); } } } return(null); }
/// <inheritdoc /> protected override async Task <IEnumerable <IDocument> > ExecuteContextAsync(IExecutionContext context) { // Get the feed Feed feed = new Feed { Id = _feedId ?? context.GetLink(), Title = _feedTitle ?? context.Settings.GetString(FeedKeys.Title), Description = _feedDescription ?? context.Settings.GetString(FeedKeys.Description), Author = _feedAuthor ?? context.Settings.GetString(FeedKeys.Author), Published = _feedPublished ?? DateTime.UtcNow, Updated = _feedUpdated ?? DateTime.UtcNow, Link = _feedLink ?? TypeHelper.Convert <Uri>(context.GetLink()), ImageLink = _feedImageLink ?? TypeHelper.Convert <Uri>(context.GetLink(context.Settings, FeedKeys.Image, true)), Copyright = _feedCopyright ?? context.Settings.GetString(FeedKeys.Copyright) ?? DateTime.UtcNow.Year.ToString() }; // Sort the items and take the maximum items List <(IDocument, DateTime?)> items = new List <(IDocument, DateTime?)>(); if (_preserveOrdering) { // Preserve the input order, take first so we don't calculate unnecessary published dates foreach (IDocument input in _maximumItems <= 0 ? context.Inputs : context.Inputs.Take(_maximumItems)) { items.Add((input, await _itemPublished.GetValueAsync(input, context))); } } else { // Order by published date then take the maximum items foreach (IDocument input in context.Inputs) { items.Add((input, await _itemPublished.GetValueAsync(input, context))); } IEnumerable <(IDocument, DateTime?)> orderedItems = items.OrderByDescending(x => x.Item2); items = _maximumItems <= 0 ? orderedItems.ToList() : orderedItems.Take(_maximumItems).ToList(); } // Add items foreach ((IDocument, DateTime?)item in items) { feed.Items.Add(new FeedItem { Id = await _itemId.GetValueAsync(item.Item1, context), Title = await _itemTitle.GetValueAsync(item.Item1, context), Description = await _itemDescription.GetValueAsync(item.Item1, context), Author = await _itemAuthor.GetValueAsync(item.Item1, context), Published = item.Item2, Updated = await _itemUpdated.GetValueAsync(item.Item1, context), Link = await _itemLink.GetValueAsync(item.Item1, context), ImageLink = await _itemImageLink.GetValueAsync(item.Item1, context), Content = await _itemContent.GetValueAsync(item.Item1, context), ThreadLink = await _itemThreadLink.GetValueAsync(item.Item1, context), ThreadCount = await _itemThreadCount.GetValueAsync(item.Item1, context), ThreadUpdated = await _itemThreadUpdated.GetValueAsync(item.Item1, context) }); } // Make description and content links absolute if (_absolutizeLinks) { HtmlParser parser = new HtmlParser(); HtmlMarkupFormatter formatter = new HtmlMarkupFormatter(); foreach (FeedItem feedItem in feed.Items) { string description = MakeLinksAbsolute(parser, formatter, context, feedItem.Description); if (description != null) { feedItem.Description = description; } string content = MakeLinksAbsolute(parser, formatter, context, feedItem.Content); if (content != null) { feedItem.Content = content; } } } // Generate the feeds return(new[] { await GenerateFeedAsync(FeedType.Rss, feed, _rssPath, context), await GenerateFeedAsync(FeedType.Atom, feed, _atomPath, context), await GenerateFeedAsync(FeedType.Rdf, feed, _rdfPath, context) }.Where(x => x != null)); }