public async Task MakesLinksAbsoluteInDescription()
            {
                // Given
                TestExecutionContext context = new TestExecutionContext();

                context.Settings[Keys.Host] = "statiq.dev";
                TestDocument document = new TestDocument(new NormalizedPath("a.txt"))
                {
                    { FeedKeys.Title, "A" },
                    { FeedKeys.Description, "<p>Foo <a href=\"/fizz/buzz\">Fizzbuzz</a> bar <img src=\"/abc/def.png\"> baz</p>" }
                };
                GenerateFeeds module = new GenerateFeeds();

                // When
                IReadOnlyList <TestDocument> results = await ExecuteAsync(document, context, module);

                // Then
                TestDocument result = results.Single(x => x.Destination.FullPath == "feed.rss");

                result.Content.ShouldContain(@"<description>&lt;p&gt;Foo &lt;a href=""http://statiq.dev/fizz/buzz""&gt;Fizzbuzz&lt;/a&gt; bar &lt;img src=""http://statiq.dev/abc/def.png""&gt; baz&lt;/p&gt;</description>");
            }
예제 #2
0
            public async Task DoesNotChangeImageDomain()
            {
                // Given
                TestExecutionContext context = new TestExecutionContext();

                context.Settings[Keys.Host] = "buzz.com";
                TestDocument document = new TestDocument(
                    new FilePath("/input/fizz/buzz"),
                    new FilePath("fizz/buzz"),
                    new Dictionary <string, object>
                {
                    { FeedKeys.Image, new Uri("http://foo.com/bar/baz.png") }
                });
                GenerateFeeds module = new GenerateFeeds();

                // When
                IReadOnlyList <TestDocument> results = await ExecuteAsync(document, context, module);

                // Then
                results.Select(x => x.Destination.FullPath).ShouldBe(new[] { "feed.rss", "feed.atom" }, true);
                results[0].Content.ShouldContain("http://foo.com/bar/baz.png");
            }
            public async Task PreservesInputOrder()
            {
                // Given
                TestDocument a = new TestDocument(new NormalizedPath("a.txt"))
                {
                    { FeedKeys.Title, "A" },
                    { FeedKeys.Published, new DateTime(2010, 1, 1) }
                };
                TestDocument b = new TestDocument(new NormalizedPath("b.txt"))
                {
                    { FeedKeys.Title, "B" },
                    { FeedKeys.Published, new DateTime(2010, 2, 1) }
                };
                GenerateFeeds module = new GenerateFeeds().PreserveOrdering();

                // When
                IReadOnlyList <TestDocument> results = await ExecuteAsync(new[] { a, b }, module);

                // Then
                TestDocument result = results.Single(x => x.Destination.FullPath == "feed.rss");

                result.Content.IndexOf("<title>A</title>").ShouldBeLessThan(result.Content.IndexOf("<title>B</title>"));
            }
            public void DoesNotChangeImageDomain()
            {
                // Given
                TestExecutionContext context = new TestExecutionContext();

                context.AddTypeConversion <string, Uri>(x => new Uri(x));
                context.Settings[Keys.Host] = "buzz.com";
                TestDocument document = new TestDocument(new Dictionary <string, object>
                {
                    { Keys.RelativeFilePath, new FilePath("fizz/buzz") },
                    { FeedKeys.Image, new Uri("http://foo.com/bar/baz.png") }
                });

                document.AddTypeConversion <Uri, string>(x => x.ToString());
                document.AddTypeConversion <FilePath, string>(x => x.FullPath);
                GenerateFeeds module = new GenerateFeeds();

                // When
                IList <IDocument> results = module.Execute(new[] { document }, context).ToList();  // Make sure to materialize the result list

                // Then
                results.Select(x => x.FilePath(Keys.WritePath).FullPath).ShouldBe(new[] { "feed.rss", "feed.atom" }, true);
                results[0].Content.ShouldContain("http://foo.com/bar/baz.png");
            }
예제 #5
0
        public Feeds()
        {
            Dependencies.AddRange(nameof(Content), nameof(Archives), nameof(Data));

            InputModules = new ModuleList
            {
                new ReadFiles("**/{!_,}*.{json,yaml,yml}")
            };

            ProcessModules = new ModuleList
            {
                new ExecuteSwitch(Config.FromDocument(doc => doc.ContentProvider.MediaType))
                .Case(MediaTypes.Json, new ParseJson())
                .Case(MediaTypes.Yaml, new ParseYaml()),
                new FilterDocuments(Config.FromDocument(IsFeed)),
                new ForEachDocument
                {
                    new ExecuteConfig(Config.FromDocument(feedDoc =>
                    {
                        ModuleList modules = new ModuleList();

                        // Get outputs from the pipeline(s)
                        modules.Add(
                            new ReplaceDocuments(feedDoc.GetList(WebKeys.FeedPipelines, new[] { nameof(Content) }).ToArray()),
                            new MergeMetadata(Config.FromValue(feedDoc.Yield())).KeepExisting());

                        // Filter by document source
                        if (feedDoc.ContainsKey(WebKeys.FeedSources))
                        {
                            modules.Add(new FilterSources(feedDoc.GetList <string>(WebKeys.FeedSources)));
                        }

                        // Filter by metadata
                        if (feedDoc.ContainsKey(WebKeys.FeedFilter))
                        {
                            modules.Add(new FilterDocuments(Config.FromDocument(doc => doc.GetBool(WebKeys.FeedFilter))));
                        }

                        // Order the documents
                        if (feedDoc.ContainsKey(WebKeys.FeedOrderKey))
                        {
                            modules.Add(
                                new OrderDocuments(feedDoc.GetString(WebKeys.FeedOrderKey))
                                .Descending(feedDoc.GetBool(WebKeys.FeedOrderDescending)));
                        }

                        // Limit the count
                        if (feedDoc.ContainsKey(WebKeys.FeedSize))
                        {
                            modules.Add(new TakeDocuments(feedDoc.GetInt(WebKeys.FeedSize)));
                        }

                        // Generate the feed(s)
                        GenerateFeeds generateFeeds = new GenerateFeeds()
                                                      .MaximumItems(feedDoc.GetInt(WebKeys.FeedSize))
                                                      .WithRssPath(feedDoc.GetBool(WebKeys.FeedRss, false) ? feedDoc.Destination.ChangeExtension("rss") : null)
                                                      .WithAtomPath(feedDoc.GetBool(WebKeys.FeedAtom, false) ? feedDoc.Destination.ChangeExtension("atom") : null)
                                                      .WithRdfPath(feedDoc.GetBool(WebKeys.FeedRdf, false) ? feedDoc.Destination.ChangeExtension("rdf") : null)
                                                      .WithFeedId(feedDoc.Get <Uri>(WebKeys.FeedId))
                                                      .WithFeedTitle(feedDoc.GetString(WebKeys.FeedTitle))
                                                      .WithFeedDescription(feedDoc.GetString(WebKeys.FeedDescription))
                                                      .WithFeedAuthor(feedDoc.GetString(WebKeys.FeedAuthor))
                                                      .WithFeedPublished(feedDoc.ContainsKey(WebKeys.FeedPublished) ? feedDoc.GetDateTime(WebKeys.FeedPublished) : (DateTime?)null)
                                                      .WithFeedUpdated(feedDoc.ContainsKey(WebKeys.FeedUpdated) ? feedDoc.GetDateTime(WebKeys.FeedUpdated) : (DateTime?)null)
                                                      .WithFeedLink(feedDoc.Get <Uri>(WebKeys.FeedLink))
                                                      .WithFeedImageLink(feedDoc.Get <Uri>(WebKeys.FeedImageLink))
                                                      .WithFeedCopyright(feedDoc.GetString(WebKeys.Copyright));

                        // Set the per-item delegates (these would have been copied down to each document from the feed document in the MergeMetadata up above)
                        if (feedDoc.ContainsKey(WebKeys.FeedItemId))
                        {
                            generateFeeds = generateFeeds.WithItemId(Config.FromDocument(doc => doc.Get <Uri>(WebKeys.FeedItemId)));
                        }
                        if (feedDoc.ContainsKey(WebKeys.FeedItemTitle))
                        {
                            generateFeeds = generateFeeds.WithItemTitle(Config.FromDocument(doc => doc.GetString(WebKeys.FeedItemTitle)));
                        }
                        if (feedDoc.ContainsKey(WebKeys.FeedItemDescription))
                        {
                            generateFeeds = generateFeeds.WithItemDescription(Config.FromDocument(doc => doc.GetString(WebKeys.FeedItemDescription)));
                        }
                        if (feedDoc.ContainsKey(WebKeys.FeedItemAuthor))
                        {
                            generateFeeds = generateFeeds.WithItemAuthor(Config.FromDocument(doc => doc.GetString(WebKeys.FeedItemAuthor)));
                        }
                        if (feedDoc.ContainsKey(WebKeys.FeedItemPublished))
                        {
                            generateFeeds = generateFeeds.WithItemPublished(Config.FromDocument(doc => doc.Get <DateTime?>(WebKeys.FeedItemPublished)));
                        }
                        if (feedDoc.ContainsKey(WebKeys.FeedItemUpdated))
                        {
                            generateFeeds = generateFeeds.WithItemUpdated(Config.FromDocument(doc => doc.Get <DateTime?>(WebKeys.FeedItemUpdated)));
                        }
                        if (feedDoc.ContainsKey(WebKeys.FeedItemLink))
                        {
                            generateFeeds = generateFeeds.WithItemLink(Config.FromDocument(doc => doc.Get <Uri>(WebKeys.FeedItemLink)));
                        }
                        if (feedDoc.ContainsKey(WebKeys.FeedItemImageLink))
                        {
                            generateFeeds = generateFeeds.WithItemImageLink(Config.FromDocument(doc => doc.Get <Uri>(WebKeys.FeedItemImageLink)));
                        }
                        if (feedDoc.ContainsKey(WebKeys.FeedItemContent))
                        {
                            generateFeeds = generateFeeds.WithItemContent(Config.FromDocument(doc => doc.GetString(WebKeys.FeedItemContent)));
                        }
                        if (feedDoc.ContainsKey(WebKeys.FeedItemThreadLink))
                        {
                            generateFeeds = generateFeeds.WithItemThreadLink(Config.FromDocument(doc => doc.Get <Uri>(WebKeys.FeedItemThreadLink)));
                        }
                        if (feedDoc.ContainsKey(WebKeys.FeedItemThreadCount))
                        {
                            generateFeeds = generateFeeds.WithItemThreadCount(Config.FromDocument(doc => doc.GetInt(WebKeys.FeedItemThreadCount)));
                        }
                        if (feedDoc.ContainsKey(WebKeys.FeedItemThreadUpdated))
                        {
                            generateFeeds = generateFeeds.WithItemThreadUpdated(Config.FromDocument(doc => doc.Get <DateTime?>(WebKeys.FeedItemThreadUpdated)));
                        }

                        modules.Add(generateFeeds);
                        return(modules);
                    }))
                }
            };

            OutputModules = new ModuleList
            {
                new WriteFiles()
            };
        }
        public EmailFeedPipeline()
        {
            Dependencies.AddRange(nameof(Inputs), nameof(Content), nameof(Archives), nameof(Data));

            ProcessModules = new ModuleList
            {
                new GetPipelineDocuments(ContentType.Data),

                // Filter to feeds
                new FilterDocuments(Config.FromDocument(IsFeed)),

                // Generate the feeds
                new ForEachDocument
                {
                    new ExecuteConfig(Config.FromDocument(feedDoc =>
                    {
                        ModuleList modules = new ModuleList();

                        // Get outputs from the pipeline(s)
                        modules.Add(
                            new ReplaceDocuments(feedDoc.GetList(WebKeys.FeedPipelines, new[] { nameof(Content) }).ToArray()),
                            new MergeMetadata(Config.FromValue(feedDoc.Yield())).KeepExisting());

                        // Filter by document source
                        if (feedDoc.ContainsKey(WebKeys.FeedSources))
                        {
                            modules.Add(new FilterSources(feedDoc.GetList <string>(WebKeys.FeedSources)));
                        }

                        // Filter by metadata
                        if (feedDoc.ContainsKey(WebKeys.FeedFilter))
                        {
                            modules.Add(new FilterDocuments(Config.FromDocument(doc => doc.GetBool(WebKeys.FeedFilter))));
                        }

                        // Order the documents
                        if (feedDoc.ContainsKey(WebKeys.FeedOrderKey))
                        {
                            modules.Add(
                                new OrderDocuments(feedDoc.GetString(WebKeys.FeedOrderKey))
                                .Descending(feedDoc.GetBool(WebKeys.FeedOrderDescending)));
                        }

                        // Generate the feed(s)
                        GenerateFeeds generateFeeds = new GenerateFeeds()
                                                      .WithRssPath("feed/index.xml")
                                                      .WithFeedId(feedDoc.GetString(WebKeys.FeedId))
                                                      .WithFeedTitle(feedDoc.GetString(WebKeys.FeedTitle))
                                                      .WithFeedDescription(feedDoc.GetString(WebKeys.FeedDescription))
                                                      .WithFeedAuthor(feedDoc.GetString(WebKeys.FeedAuthor))
                                                      .WithFeedPublished(feedDoc.ContainsKey(WebKeys.FeedPublished) ? feedDoc.GetDateTime(WebKeys.FeedPublished) : (DateTime?)null)
                                                      .WithFeedUpdated(feedDoc.ContainsKey(WebKeys.FeedUpdated) ? feedDoc.GetDateTime(WebKeys.FeedUpdated) : (DateTime?)null)
                                                      .WithFeedLink(feedDoc.Get <Uri>(WebKeys.FeedLink))
                                                      .WithFeedImageLink(feedDoc.Get <Uri>(WebKeys.FeedImageLink))
                                                      .WithFeedCopyright(feedDoc.GetString(WebKeys.Copyright));


                        // Set the per-item delegates (these would have been copied down to each document from the feed document in the MergeMetadata up above)
                        if (feedDoc.ContainsKey(WebKeys.FeedItemId))
                        {
                            generateFeeds = generateFeeds.WithItemId(Config.FromDocument(doc => doc.GetString(WebKeys.FeedItemId)));
                        }
                        if (feedDoc.ContainsKey(WebKeys.FeedItemTitle))
                        {
                            generateFeeds = generateFeeds.WithItemTitle(Config.FromDocument(doc => doc.GetString(WebKeys.FeedItemTitle)));
                        }

                        generateFeeds = generateFeeds.WithItemDescription(Config.FromDocument(doc => doc.GetString("Excerpt", WebKeys.FeedItemDescription)));


                        if (feedDoc.ContainsKey(WebKeys.FeedItemAuthor))
                        {
                            generateFeeds = generateFeeds.WithItemAuthor(Config.FromDocument(doc => doc.GetString(WebKeys.FeedItemAuthor)));
                        }
                        if (feedDoc.ContainsKey(WebKeys.FeedItemPublished))
                        {
                            generateFeeds = generateFeeds.WithItemPublished(Config.FromDocument(doc => doc.Get <DateTime?>(WebKeys.FeedItemPublished)));
                        }
                        if (feedDoc.ContainsKey(WebKeys.FeedItemUpdated))
                        {
                            generateFeeds = generateFeeds.WithItemUpdated(Config.FromDocument(doc => doc.Get <DateTime?>(WebKeys.FeedItemUpdated)));
                        }
                        if (feedDoc.ContainsKey(WebKeys.FeedItemLink))
                        {
                            //generateFeeds = generateFeeds.WithItemLink(Config.FromDocument(doc => doc.Get<Uri>(WebKeys.FeedItemLink)));
                        }

                        generateFeeds = generateFeeds.WithItemImageLink(Config.FromDocument((doc, ctx) => {
                            return(TypeHelper.Convert <Uri>(ctx.GetLink(doc, "Card", true)) ?? TypeHelper.Convert <Uri>(ctx.GetLink("/images/ogcard.jpeg", true)));
                        }
                                                                                            ));

                        if (feedDoc.ContainsKey(WebKeys.FeedItemContent))
                        {
                            generateFeeds = generateFeeds.WithItemContent(Config.FromDocument(doc => doc.GetString(WebKeys.FeedItemContent)));
                        }
                        if (feedDoc.ContainsKey(WebKeys.FeedItemThreadLink))
                        {
                            generateFeeds = generateFeeds.WithItemThreadLink(Config.FromDocument(doc => doc.Get <Uri>(WebKeys.FeedItemThreadLink)));
                        }
                        if (feedDoc.ContainsKey(WebKeys.FeedItemThreadCount))
                        {
                            generateFeeds = generateFeeds.WithItemThreadCount(Config.FromDocument(doc => doc.GetInt(WebKeys.FeedItemThreadCount)));
                        }
                        if (feedDoc.ContainsKey(WebKeys.FeedItemThreadUpdated))
                        {
                            generateFeeds = generateFeeds.WithItemThreadUpdated(Config.FromDocument(doc => doc.Get <DateTime?>(WebKeys.FeedItemThreadUpdated)));
                        }

                        modules.Add(generateFeeds);
                        return(modules);
                    }))
                }
            };

            OutputModules = new ModuleList
            {
                new FilterDocuments(Config.FromDocument(WebKeys.ShouldOutput, true)),
                new WriteFiles()
            };
        }