Exemple #1
0
        private static IDocument TreePlaceholderFactory(object[] path, MetadataItems items, IExecutionContext context)
        {
            FilePath indexPath = new FilePath(string.Join("/", path.Concat(new[] { "index.html" })));

            items.Add(Keys.RelativeFilePath, indexPath);
            items.Add(Keys.Title, Title.GetTitle(indexPath));
            return(context.GetDocument(context.GetContentStream("@Html.Partial(\"_ChildPages\")"), items));
        }
        /// <inheritdoc />
        protected override IEnumerable <IDocument> ExecuteContext(IExecutionContext context)
        {
            // Partition the pages and get a total before skip/take
            IDocument[][] pages =
                Partition(context.Inputs, _pageSize)
                .ToArray();

            // Skip/take the pages
            pages = pages
                    .Skip(_skipPages)
                    .Take(_takePages)
                    .ToArray();

            // Special case for no pages, create an empty one
            if (pages.Length == 0)
            {
                pages = new[] { Array.Empty <IDocument>() };
            }

            // Create the documents per page, setting previous and next values as we go
            Stack <(IDocument, LazyDocumentMetadataValue)> results = new Stack <(IDocument, LazyDocumentMetadataValue)>();

            for (int c = 0; c < pages.Length; c++)
            {
                MetadataItems items = new MetadataItems
                {
                    { Keys.Children, pages[c] },
                    { Keys.Index, c + 1 },
                    { Keys.TotalPages, pages.Length },
                    { Keys.TotalItems, context.Inputs.Length }
                };
                if (results.Count > 0)
                {
                    items.Add(Keys.Previous, new LazyDocumentMetadataValue(results.Peek().Item1));
                }
                LazyDocumentMetadataValue next = null;
                if (c < pages.Length - 1)
                {
                    next = new LazyDocumentMetadataValue();
                    items.Add(Keys.Next, next);
                }
                IDocument document = context.CreateDocument(
                    _source,
                    _source.IsNull ? _source : _source.GetRelativeInputPath(),
                    items);
                if (results.Count > 0)
                {
                    results.Peek().Item2.OriginalDocument = document;
                }
                results.Push((document, next));
            }

            return(results.Select(x => x.Item1).Reverse());
        }
Exemple #3
0
        private static void AddImage(MetadataItems metadata, IAsset?asset)
        {
            if (asset == null)
            {
                return;
            }

            var localPath = KontentAssetHelper.GetLocalFileName(asset.Url + "?w=800&h=800", "img");
            var download  = new KontentImageDownload(asset.Url, localPath);

            metadata.Add(FeedKeys.Image, localPath);
            metadata.Add("KONTENT-ASSET-DOWNLOADS", download); // TODO : an upcoming version of Kontent.Statiq will provide this key
        }
Exemple #4
0
            // We need to build the tree from the bottom up so that the children don't have to be lazy
            // This also sorts the children once they're created
            public void GenerateOutputDocuments(Tree tree, IExecutionContext context)
            {
                // Recursively build output documents for children
                foreach (TreeNode child in Children)
                {
                    child.GenerateOutputDocuments(tree, context);
                }

                // We're done if we've already created the output document
                if (OutputDocument != null)
                {
                    return;
                }

                // Sort the child documents since they're created now
                Children.Sort((x, y) => tree._sort(x.OutputDocument, y.OutputDocument));

                // Create this output document
                MetadataItems metadata = new MetadataItems();

                if (tree._childrenKey != null)
                {
                    metadata.Add(tree._childrenKey, new ReadOnlyCollection <IDocument>(Children.Select(x => x.OutputDocument).ToArray()));
                }
                if (tree._parentKey != null)
                {
                    metadata.Add(tree._parentKey, new CachedDelegateMetadataValue(_ => Parent?.OutputDocument));
                }
                if (tree._previousSiblingKey != null)
                {
                    metadata.Add(tree._previousSiblingKey, new CachedDelegateMetadataValue(_ => GetPreviousSibling()?.OutputDocument));
                }
                if (tree._nextSiblingKey != null)
                {
                    metadata.Add(tree._nextSiblingKey, new CachedDelegateMetadataValue(_ => GetNextSibling()?.OutputDocument));
                }
                if (tree._previousKey != null)
                {
                    metadata.Add(tree._previousKey, new CachedDelegateMetadataValue(_ => GetPrevious()?.OutputDocument));
                }
                if (tree._nextKey != null)
                {
                    metadata.Add(tree._nextKey, new CachedDelegateMetadataValue(_ => GetNext()?.OutputDocument));
                }
                if (tree._treePathKey != null)
                {
                    metadata.Add(tree._treePathKey, TreePath);
                }
                if (InputDocument == null)
                {
                    // There's no input document for this node so we need to make a placeholder
                    metadata.Add(Keys.TreePlaceholder, true);
                    OutputDocument = tree._placeholderFactory(TreePath, metadata, context) ?? context.GetDocument(metadata);
                }
                else
                {
                    OutputDocument = context.GetDocument(InputDocument, metadata);
                }
            }
Exemple #5
0
    public Api()
    {
        Dependencies.Add(nameof(Code));
        DependencyOf.Add(nameof(Content));

        ProcessModules = new ModuleList
        {
            new ConcatDocuments(nameof(Code)),
            new CacheDocuments(
                new AnalyzeCSharp()
                .WhereNamespaces(ns => ns.StartsWith("Spectre.Console") && !ns.Contains("Analyzer") &&
                                 !ns.Contains("Testing") && !ns.Contains("Examples"))
                .WherePublic(true)
                .WithCssClasses("code", "cs")
                .WithDestinationPrefix("api")
                .WithAssemblySymbols()
                .WithImplicitInheritDoc(false),
                new ExecuteConfig(Config.FromDocument((doc, ctx) =>
            {
                // Calculate a type name to link lookup for auto linking
                string name = null;

                var kind = doc.GetString(CodeAnalysisKeys.Kind);
                switch (kind)
                {
                case "NamedType":
                    name = doc.GetString(CodeAnalysisKeys.DisplayName);
                    break;

                case "Method":
                    var containingType = doc.GetDocument(CodeAnalysisKeys.ContainingType);
                    if (containingType != null)
                    {
                        name =
                            $"{containingType.GetString(CodeAnalysisKeys.DisplayName)}.{doc.GetString(CodeAnalysisKeys.DisplayName)}";
                    }
                    break;
                }

                if (name != null)
                {
                    var typeNameLinks = ctx.GetRequiredService <TypeNameLinks>();
                    typeNameLinks.Links.AddOrUpdate(WebUtility.HtmlEncode(name), ctx.GetLink(doc),
                                                    (_, _) => string.Empty);
                }

                // Add metadata
                var metadataItems = new MetadataItems
                {
                    { WebKeys.Xref, doc.GetString(CodeAnalysisKeys.CommentId) },
                    { WebKeys.Layout, "api/_layout.cshtml" },
                    { Constants.Hidden, true }
                };

                var contentProvider = doc.ContentProvider.CloneWithMediaType(MediaTypes.Html);
                metadataItems.Add(WebKeys.ContentType, ContentType.Content);
                return(doc.Clone(metadataItems, contentProvider));
            }))).WithoutSourceMapping()
        };
    }
Exemple #6
0
 internal void AddMetadataItem(MetadataItem item)
 {
     if (MetadataItems == null)
     {
         MetadataItems = new List <MetadataItem>();
     }
     MetadataItems.Add(item);
 }
Exemple #7
0
        private IDocument Write(IDocument input, IExecutionContext context, FilePath outputPath)
        {
            IFile output = context.FileSystem.GetOutputFile(outputPath);

            if (output != null)
            {
                using (Stream inputStream = input.GetStream())
                {
                    if (_ignoreEmptyContent && inputStream.Length == 0)
                    {
                        return(input);
                    }
                    if (!_onlyMetadata)
                    {
                        using (Stream outputStream = _append ? output.OpenAppend() : output.OpenWrite())
                        {
                            inputStream.CopyTo(outputStream);
                            if (!_append)
                            {
                                outputStream.SetLength(inputStream.Length);
                            }
                        }
                    }
                }
                Trace.Verbose($"{(_onlyMetadata ? "Set metadata for" : "Wrote")} file {output.Path.FullPath} from {input.SourceString()}");
                FilePath      relativePath             = context.FileSystem.GetOutputPath().GetRelativePath(output.Path) ?? output.Path.FileName;
                FilePath      fileNameWithoutExtension = output.Path.FileNameWithoutExtension;
                MetadataItems metadata = new MetadataItems
                {
                    { Keys.RelativeFilePath, relativePath },
                    { Keys.RelativeFilePathBase, fileNameWithoutExtension == null
                        ? null : relativePath.Directory.CombineFile(output.Path.FileNameWithoutExtension) },
                    { Keys.RelativeFileDir, relativePath.Directory }
                };
                if (_onlyMetadata)
                {
                    metadata.Add(Keys.WritePath, outputPath);
                }
                else
                {
                    metadata.AddRange(new MetadataItems
                    {
                        { Keys.DestinationFileBase, fileNameWithoutExtension },
                        { Keys.DestinationFileExt, output.Path.Extension },
                        { Keys.DestinationFileName, output.Path.FileName },
                        { Keys.DestinationFileDir, output.Path.Directory },
                        { Keys.DestinationFilePath, output.Path },
                        { Keys.DestinationFilePathBase, fileNameWithoutExtension == null
                            ? null : output.Path.Directory.CombineFile(output.Path.FileNameWithoutExtension) },
                    });
                }
                return(_onlyMetadata
                    ? context.GetDocument(input, metadata)
                    : context.GetDocument(input, output.OpenRead(), metadata));
            }
            return(input);
        }
Exemple #8
0
            // We need to build the tree from the bottom up so that the children don't have to be lazy
            // This also sorts the children once they're created
            public void GenerateOutputDocuments(CreateTree tree, IExecutionContext context)
            {
                // Recursively build output documents for children
                foreach (TreeNode child in Children)
                {
                    child.GenerateOutputDocuments(tree, context);
                }

                // We're done if we've already created the output document
                if (OutputDocument != null)
                {
                    return;
                }

                // Sort the child documents since they're created now
                Children.Sort((x, y) => tree._sort(x.OutputDocument, y.OutputDocument));

                // Create this output document
                MetadataItems metadata = new MetadataItems();

                if (tree._childrenKey != null)
                {
                    metadata.Add(tree._childrenKey, Children.Select(x => x.OutputDocument).ToImmutableArray());
                }
                if (tree._treePathKey != null)
                {
                    metadata.Add(tree._treePathKey, TreePath);
                }
                if (InputDocument == null)
                {
                    // There's no input document for this node so we need to make a placeholder
                    metadata.Add(Keys.TreePlaceholder, true);
                    OutputDocument = tree._placeholderFactory(TreePath, metadata, context) ?? context.CreateDocument(metadata);
                }
                else
                {
                    OutputDocument = InputDocument.Clone(metadata);
                }
            }
Exemple #9
0
        // Used for everything but namespace documents
        private IDocument AddDocument(ISymbol symbol, bool xmlDocumentation, MetadataItems items)
        {
            items.AddRange(new[]
            {
                new MetadataItem(CodeAnalysisKeys.Symbol, symbol)
            });

            // Add the containing assembly, but only if it's not the code analysis compilation
            if (symbol.ContainingAssembly?.Name != AnalyzeCSharp.CompilationAssemblyName && _assemblySymbols)
            {
                items.Add(new MetadataItem(CodeAnalysisKeys.ContainingAssembly, DocumentFor(symbol.ContainingAssembly)));
            }

            return(AddDocumentCommon(symbol, xmlDocumentation, items));
        }
        public override async Task <IEnumerable <IDocument> > ExecuteAsync(
            KeyValuePair <string, string>[] args,
            string content,
            IDocument document,
            IExecutionContext context)
        {
            IMetadataDictionary dictionary = args.ToDictionary(
                "Key",
                "ValueKey",
                "IndexKey");

            dictionary.RequireKeys("Key", "ValueKey");
            string valueKey = dictionary.GetString("ValueKey");

            if (string.IsNullOrEmpty(valueKey))
            {
                throw new ShortcodeArgumentException("Invalid ValueKey");
            }
            string indexKey = dictionary.GetString("IndexKey");

            IReadOnlyList <object> items = document.GetList <object>(dictionary.GetString("Key"));

            if (items != null)
            {
                List <IDocument> results = new List <IDocument>();
                int index = 0;
                foreach (object item in items)
                {
                    MetadataItems metadata = new MetadataItems()
                    {
                        { valueKey, item }
                    };
                    if (!string.IsNullOrEmpty(indexKey))
                    {
                        metadata.Add(indexKey, index);
                    }

                    results.Add(await document.CloneAsync(metadata, content));

                    index++;
                }

                return(results);
            }

            return(null);
        }
        public override IEnumerable <ShortcodeResult> Execute(
            KeyValuePair <string, string>[] args,
            string content,
            IDocument document,
            IExecutionContext context)
        {
            IMetadataDictionary dictionary = args.ToDictionary(Key, ValueKey, IndexKey);

            dictionary.RequireKeys(Key, ValueKey);
            string valueKey = dictionary.GetString(ValueKey);

            if (string.IsNullOrEmpty(valueKey))
            {
                throw new ShortcodeArgumentException(ValueKey);
            }
            string indexKey = dictionary.GetString(IndexKey);

            IReadOnlyList <object> items = document.GetList <object>(dictionary.GetString(Key));

            if (items != null)
            {
                List <ShortcodeResult> results = new List <ShortcodeResult>();
                int index = 0;
                foreach (object item in items)
                {
                    MetadataItems metadata = new MetadataItems()
                    {
                        { valueKey, item }
                    };
                    if (!string.IsNullOrEmpty(indexKey))
                    {
                        metadata.Add(indexKey, index);
                    }

                    results.Add(new ShortcodeResult(content, metadata));

                    index++;
                }

                return(results);
            }

            return(null);
        }
        public object GetMetadata(INancyModule module, RouteDescription routeDescription)
        {
            var type = GetModuleMetadataType(module);

            if (type == null)
            {
                return(null);
            }

            ModuleMetadata metadata;

            if (MetadataItems.TryGetValue(type, out metadata))
            {
                return(metadata[routeDescription.Method, routeDescription.Path]);
            }

            metadata = (ModuleMetadata)(_container.Resolve(type));
            MetadataItems.Add(type, metadata);

            return(metadata?[routeDescription.Method, routeDescription.Path]);
        }
Exemple #13
0
        protected override async Task <IEnumerable <Common.IDocument> > ExecuteInputAsync(Common.IDocument input, IExecutionContext context)
        {
            if (string.IsNullOrWhiteSpace(_metadataKey))
            {
                return(input.Yield());
            }

            // Parse the HTML content
            IHtmlDocument htmlDocument = await input.ParseHtmlAsync(context, HtmlParser);

            if (htmlDocument == null)
            {
                return(input.Yield());
            }

            // Evaluate the query and create the holding nodes
            Heading        previousHeading = null;
            List <Heading> headings        = htmlDocument
                                             .QuerySelectorAll(_query)
                                             .Select(x =>
            {
                previousHeading = new Heading
                {
                    Element  = x,
                    Previous = previousHeading,
                    Level    = int.Parse(x.NodeName.Substring(1))
                };
                return(previousHeading);
            })
                                             .ToList();

            // Build the tree from the bottom-up
            for (int level = _level; level >= 1; level--)
            {
                int currentLevel = level;
                foreach (Heading heading in headings.Where(x => x.Level == currentLevel))
                {
                    // Get the parent
                    Heading parent = null;
                    if (currentLevel > 1)
                    {
                        parent = heading.Previous;
                        while (parent != null && parent.Level >= currentLevel)
                        {
                            parent = parent.Previous;
                        }
                    }

                    // Create the document
                    MetadataItems metadata = new MetadataItems();
                    if (_levelKey != null)
                    {
                        metadata.Add(_levelKey, heading.Level);
                    }
                    if (_idKey != null && heading.Element.HasAttribute("id"))
                    {
                        metadata.Add(_idKey, heading.Element.GetAttribute("id"));
                    }
                    if (_headingKey != null)
                    {
                        metadata.Add(_headingKey, heading.Element.InnerHtml);
                    }
                    if (_childrenKey != null)
                    {
                        metadata.Add(_childrenKey, heading.Children.AsReadOnly());
                    }

                    using (Stream contentStream = await context.GetContentStreamAsync())
                    {
                        using (StreamWriter writer = contentStream.GetWriter())
                        {
                            heading.Element.ChildNodes.ToHtml(writer, ProcessingInstructionFormatter.Instance);
                            writer.Flush();
                            heading.Document = context.CreateDocument(metadata, context.GetContentProvider(contentStream, MediaTypes.Html));
                        }
                    }

                    // Add to parent
                    parent?.Children.Add(heading.Document);
                }
            }

            return(input
                   .Clone(new MetadataItems
            {
                {
                    _metadataKey,
                    _nesting
                            ? headings
                    .Where(x => x.Level == headings.Min(y => y.Level))
                    .Select(x => x.Document)
                    .ToArray()
                            : headings
                    .Select(x => x.Document)
                    .ToArray()
                }
            })
                   .Yield());
        }
        protected override async Task <IEnumerable <IDocument> > ExecuteInputAsync(IDocument input, IExecutionContext context)
        {
            IDocument output = input;

            // Extract the GitHub owner and name
            if (Uri.TryCreate(input.GetString("SourceCode"), UriKind.Absolute, out Uri sourceCode) &&
                sourceCode.Host.EndsWith("github.com", StringComparison.OrdinalIgnoreCase))
            {
                string owner = sourceCode.Segments[1].Trim('/');
                string name  = sourceCode.Segments[2].Trim('/');

                // Get issue data
                context.LogInformation($"Getting GitHub issue data for {owner}/{name}");
                IReadOnlyList <Issue> issues = await _gitHub.GetAsync(
                    x => x.Issue.GetAllForRepository(
                        owner,
                        name,
                        new RepositoryIssueRequest
                {
                    Filter = IssueFilter.All
                },
                        new ApiOptions
                {
                    PageSize = 100
                }),
                    context);

                issues = issues
                         .Where(x => x.PullRequest == null)
                         .ToList();

                // Get the metadata and document
                if (issues.Count > 0)
                {
                    Models.Issue[] issueData = issues
                                               .Select(x => new Models.Issue(x, OneDayAgo))
                                               .OrderByDescending(x => x.CreatedAt)
                                               .ToArray();
                    MetadataItems metadata = new MetadataItems
                    {
                        { "GitHubOwner", owner },
                        { "GitHubName", name },
                        { "Issues", issueData },
                        { "IssuesCount", issueData.Length },
                        { "RecentIssuesCount", issueData.Count(x => x.Recent) },
                        { "HelpWantedIssuesCount", issueData.Count(x => x.HelpWanted) }
                    };
                    if (!input.ContainsKey("Microsoft") && GitHubManager.MicrosoftOwners.Contains(owner, StringComparer.OrdinalIgnoreCase))
                    {
                        metadata.Add("Microsoft", true);
                    }
                    if (!input.ContainsKey("Foundation") && _foundation.IsInFoundation(owner, name))
                    {
                        metadata.Add("Foundation", true);
                    }

                    output = input.Clone(metadata);
                }
            }

            return(output.Yield());
        }
Exemple #15
0
        /// <inheritdoc />
        public IEnumerable <Common.Documents.IDocument> Execute(IReadOnlyList <Common.Documents.IDocument> inputs, IExecutionContext context)
        {
            if (string.IsNullOrWhiteSpace(_metadataKey))
            {
                return(inputs);
            }

            // Build the query
            StringBuilder query = new StringBuilder();

            for (int level = 1; level <= _level; level++)
            {
                if (level > 1)
                {
                    query.Append(",");
                }
                query.Append("h");
                query.Append(level);
            }

            // Process documents
            HtmlParser parser = new HtmlParser();

            return(inputs.AsParallel().Select(context, input =>
            {
                // Parse the HTML content
                IHtmlDocument htmlDocument = input.ParseHtml(parser);
                if (htmlDocument == null)
                {
                    return input;
                }

                // Evaluate the query and create the holding nodes
                Heading previousHeading = null;
                List <Heading> headings = htmlDocument
                                          .QuerySelectorAll(query.ToString())
                                          .Select(x =>
                {
                    previousHeading = new Heading
                    {
                        Element = x,
                        Previous = previousHeading,
                        Level = int.Parse(x.NodeName.Substring(1))
                    };
                    return previousHeading;
                })
                                          .ToList();

                // Build the tree from the bottom-up
                for (int level = _level; level >= 1; level--)
                {
                    int currentLevel = level;
                    foreach (Heading heading in headings.Where(x => x.Level == currentLevel))
                    {
                        // Get the parent
                        Heading parent = null;
                        if (currentLevel > 1)
                        {
                            parent = heading.Previous;
                            while (parent != null && parent.Level >= currentLevel)
                            {
                                parent = parent.Previous;
                            }
                        }

                        // Create the document
                        MetadataItems metadata = new MetadataItems();
                        if (_levelKey != null)
                        {
                            metadata.Add(_levelKey, heading.Level);
                        }
                        if (_idKey != null && heading.Element.HasAttribute("id"))
                        {
                            metadata.Add(_idKey, heading.Element.GetAttribute("id"));
                        }
                        if (_headingKey != null)
                        {
                            metadata.Add(_headingKey, heading.Element.InnerHtml);
                        }
                        if (_childrenKey != null)
                        {
                            metadata.Add(_childrenKey, heading.Children.AsReadOnly());
                        }
                        if (_parentKey != null)
                        {
                            metadata.Add(_parentKey, new CachedDelegateMetadataValue(_ => parent?.Document));
                        }
                        Stream contentStream = context.GetContentStream();
                        using (StreamWriter writer = contentStream.GetWriter())
                        {
                            heading.Element.ChildNodes.ToHtml(writer, HtmlMarkupFormatter.Instance);
                            writer.Flush();
                            heading.Document = context.GetDocument(contentStream, metadata);
                        }

                        // Add to parent
                        parent?.Children.Add(heading.Document);
                    }
                }

                return context.GetDocument(
                    input,
                    new MetadataItems
                {
                    {
                        _metadataKey,
                        _nesting
                                ? headings
                        .Where(x => x.Level == headings.Min(y => y.Level))
                        .Select(x => x.Document)
                        .ToArray()
                                : headings
                        .Select(x => x.Document)
                        .ToArray()
                    }
                });
            }));
        }
        protected override async Task <IEnumerable <IDocument> > ExecuteInputAsync(IDocument input, IExecutionContext context)
        {
            // Don't get data if we're just validating
            if (context.Settings.GetBool(SiteKeys.Validate))
            {
                return(null);
            }

            string feed = input.GetString(SiteKeys.Feed);

            if (!string.IsNullOrEmpty(feed))
            {
                try
                {
                    // Download the feed
                    context.LogInformation($"Getting feed for {feed}");
                    Uri    website                = null;
                    string title                  = null;
                    string author                 = null;
                    string description            = null;
                    string image                  = null;
                    List <ISyndicationItem> items = new List <ISyndicationItem>();
                    using (HttpClient httpClient = context.CreateHttpClient())
                    {
                        httpClient.DefaultRequestHeaders.Add("User-Agent", nameof(Statiq));

                        using (Stream stream = await httpClient.GetStreamAsync(feed))
                        {
                            using (StreamReader streamReader = new XmlStreamReader(stream))
                            {
                                using (XmlReader xmlReader = XmlReader.Create(streamReader, new XmlReaderSettings {
                                    Async = true, DtdProcessing = DtdProcessing.Ignore
                                }))
                                {
                                    xmlReader.MoveToContent();
                                    bool atom = xmlReader.Name == "feed";
                                    context.LogInformation($"Reading {feed} as " + (atom ? "Atom" : "RSS"));
                                    XmlFeedReader feedReader = atom
                                        ? (XmlFeedReader) new AtomFeedReader(xmlReader, new DiscoverAtomParser())
                                        : new RssFeedReader(xmlReader);
                                    while (await feedReader.Read())
                                    {
                                        try
                                        {
                                            switch (feedReader.ElementType)
                                            {
                                            case SyndicationElementType.Person:
                                                ISyndicationPerson person = await feedReader.ReadPerson();

                                                if (person.RelationshipType == "author")
                                                {
                                                    author = person.Name ?? person.Email;
                                                }
                                                break;

                                            case SyndicationElementType.Image:
                                                ISyndicationImage img = await feedReader.ReadImage();

                                                image = img.Url.ToString();
                                                break;

                                            case SyndicationElementType.Link:
                                                ISyndicationLink link = await feedReader.ReadLink();

                                                website = link.Uri;
                                                break;

                                            case SyndicationElementType.Item:
                                                ISyndicationItem item = await feedReader.ReadItem();

                                                items.Add(item);
                                                break;

                                            case SyndicationElementType.None:
                                                break;

                                            default:
                                                ISyndicationContent content = await feedReader.ReadContent();

                                                if (string.Equals(content.Name, "title", StringComparison.OrdinalIgnoreCase))
                                                {
                                                    title = content.Value;
                                                }
                                                else if (string.Equals(content.Name, "description", StringComparison.OrdinalIgnoreCase) ||
                                                         string.Equals(content.Name, "subtitle", StringComparison.OrdinalIgnoreCase))
                                                {
                                                    description = content.Value;
                                                }
                                                break;
                                            }
                                        }
                                        catch (Exception ex)
                                        {
                                            context.LogWarning($"Exception while processing {feedReader.ElementType} in {feed}: {ex.Message}");
                                        }
                                    }
                                }
                            }
                        }
                    }

                    // Get a new document with feed metadata
                    MetadataItems metadata = new MetadataItems();
                    if (items.Count > 0)
                    {
                        FeedItem[] feedItems = items
                                               .Select(x => new FeedItem(x, _recent, website, _truncateDescription, context))
                                               .OrderByDescending(x => x.Published)
                                               .Take(50) // Only take the 50 most recent items
                                               .ToArray();
                        metadata.Add(SiteKeys.FeedItems, feedItems);
                        metadata.Add(SiteKeys.LastPublished, feedItems.First().Published);
                        metadata.Add(SiteKeys.NewestFeedItem, feedItems[0]);
                    }
                    if (!input.ContainsKey(SiteKeys.Website) && website != null)
                    {
                        metadata.Add(SiteKeys.Website, website.ToString());
                    }
                    if (!input.ContainsKey(SiteKeys.Title))
                    {
                        if (!string.IsNullOrEmpty(title))
                        {
                            metadata.Add(SiteKeys.Title, title);
                        }
                        else
                        {
                            string generatedTitle = GenerateTitleFromFeedName(feed);
                            metadata.Add(SiteKeys.Title, generatedTitle);
                        }
                    }
                    if (!input.ContainsKey(SiteKeys.Author) && !string.IsNullOrEmpty(author))
                    {
                        metadata.Add(SiteKeys.Author, author);
                    }
                    if (!input.ContainsKey(SiteKeys.Description) && !string.IsNullOrEmpty(description))
                    {
                        metadata.Add(SiteKeys.Description, description);
                    }
                    if (!input.ContainsKey(SiteKeys.Image) && !string.IsNullOrEmpty(image))
                    {
                        metadata.Add(SiteKeys.Image, image);
                    }
                    return(input.Clone(metadata).Yield());
                }
                catch (Exception ex)
                {
                    context.LogWarning($"Error getting feed for {feed}: {ex.Message}");
                }
            }

            // Return null so this feed is not included
            return(null);
        }
Exemple #17
0
        protected override async Task <IEnumerable <IDocument> > ExecuteInputAsync(IDocument input, IExecutionContext context)
        {
            string feed = input.GetString("Feed");

            if (!string.IsNullOrEmpty(feed))
            {
                try
                {
                    // Download the feed
                    context.LogInformation($"Getting feed for {feed}");
                    Uri    website                = null;
                    string title                  = null;
                    string author                 = null;
                    string description            = null;
                    string image                  = null;
                    List <ISyndicationItem> items = new List <ISyndicationItem>();
                    using (HttpClient httpClient = context.CreateHttpClient())
                    {
                        httpClient.DefaultRequestHeaders.Add("User-Agent", "Wyam");

                        var response = await httpClient.GetAsync(feed);

                        if (response.StatusCode == HttpStatusCode.Redirect ||
                            response.StatusCode == HttpStatusCode.MovedPermanently)
                        {
                            context.LogWarning($"Attempting to follow redirect for {feed}");
                            feed     = response.Headers.Location.OriginalString;
                            response = await httpClient.GetAsync(feed);
                        }

                        if (response.IsSuccessStatusCode)
                        {
                            using (Stream stream = await response.Content.ReadAsStreamAsync())
                                using (StreamReader streamReader = new XmlStreamReader(stream))
                                    using (XmlReader xmlReader = XmlReader.Create(streamReader, new XmlReaderSettings {
                                        Async = true, DtdProcessing = DtdProcessing.Ignore
                                    }))
                                    {
                                        xmlReader.MoveToContent();
                                        bool atom = xmlReader.Name == "feed";
                                        context.LogInformation($"Reading {feed} as " + (atom ? "Atom" : "RSS"));
                                        XmlFeedReader feedReader = atom
                                    ? (XmlFeedReader) new AtomFeedReader(xmlReader, new FixedAtomParser())
                                    : new RssFeedReader(xmlReader);
                                        while (await feedReader.Read())
                                        {
                                            try
                                            {
                                                switch (feedReader.ElementType)
                                                {
                                                case SyndicationElementType.Person:
                                                    ISyndicationPerson person = await feedReader.ReadPerson();

                                                    if (person.RelationshipType == "author")
                                                    {
                                                        author = person.Name ?? person.Email;
                                                    }
                                                    break;

                                                case SyndicationElementType.Image:
                                                    ISyndicationImage img = await feedReader.ReadImage();

                                                    image = img.Url.ToString();
                                                    break;

                                                case SyndicationElementType.Link:
                                                    ISyndicationLink link = await feedReader.ReadLink();

                                                    website = link.Uri;
                                                    break;

                                                case SyndicationElementType.Item:
                                                    ISyndicationItem item = await feedReader.ReadItem();

                                                    items.Add(item);
                                                    break;

                                                case SyndicationElementType.None:
                                                    break;

                                                default:
                                                    ISyndicationContent content = await feedReader.ReadContent();

                                                    if (string.Equals(content.Name, "title", StringComparison.OrdinalIgnoreCase))
                                                    {
                                                        title = content.Value;
                                                    }
                                                    else if (string.Equals(content.Name, "description", StringComparison.OrdinalIgnoreCase) ||
                                                             string.Equals(content.Name, "subtitle", StringComparison.OrdinalIgnoreCase))
                                                    {
                                                        description = content.Value;
                                                    }
                                                    break;
                                                }
                                            }
                                            catch (Exception ex)
                                            {
                                                context.LogWarning($"Exception while processing {feedReader.ElementType} in {feed}: {ex.Message}");
                                            }
                                        }
                                    }
                        }

                        // Get a new document with feed metadata
                        MetadataItems metadata = new MetadataItems();
                        if (items.Count > 0)
                        {
                            BlogFeedItem[] feedItems = items
                                                       .Select(x => new BlogFeedItem(x, _recent, website))
                                                       .OrderByDescending(x => x.Published)
                                                       .Take(50) // Only take the 50 most recent items
                                                       .ToArray();
                            metadata.Add(SiteKeys.BlogFeedItems, feedItems);
                            return(input.Clone(metadata).Yield());
                        }
                    }
                }
                catch (Exception ex)
                {
                    context.LogWarning($"Error getting feed for {feed}: {ex.Message}");
                }
            }
            else
            {
                var speaker = input.GetString("Title");
                if (!string.IsNullOrWhiteSpace(speaker))
                {
                    context.LogWarning($"No RSS specified for {speaker}.");
                }
                else
                {
                    context.LogWarning($"No RSS specified for unknown speaker.");
                }
            }
            return(input.Yield());
        }
Exemple #18
0
 private IDocument Write(IDocument input, IExecutionContext context, FilePath outputPath)
 {
     IFile output = context.FileSystem.GetOutputFile(outputPath);
     if (output != null)
     {
         using (Stream inputStream = input.GetStream())
         {
             if (_ignoreEmptyContent && inputStream.Length == 0)
             {
                 return input;
             }
             if (!_onlyMetadata)
             {
                 using (Stream outputStream = _append ? output.OpenAppend() : output.OpenWrite())
                 {
                     inputStream.CopyTo(outputStream);
                 }
             }
         }
         Trace.Verbose($"{(_onlyMetadata ? "Set metadata for" : "Wrote")} file {output.Path.FullPath} from {input.SourceString()}");
         FilePath relativePath = context.FileSystem.GetOutputPath().GetRelativePath(output.Path) ?? output.Path.FileName;
         FilePath fileNameWithoutExtension = output.Path.FileNameWithoutExtension;
         MetadataItems metadata = new MetadataItems
         {
             { Keys.RelativeFilePath, relativePath },
             { Keys.RelativeFilePathBase, fileNameWithoutExtension == null
                 ? null : relativePath.Directory.CombineFile(output.Path.FileNameWithoutExtension) },
             { Keys.RelativeFileDir, relativePath.Directory }
         };
         if (_onlyMetadata)
         {
             metadata.Add(Keys.WritePath, outputPath);
         }
         else
         {
             metadata.AddRange(new MetadataItems
             {
                 { Keys.DestinationFileBase, fileNameWithoutExtension },
                 { Keys.DestinationFileExt, output.Path.Extension },
                 { Keys.DestinationFileName, output.Path.FileName },
                 { Keys.DestinationFileDir, output.Path.Directory },
                 { Keys.DestinationFilePath, output.Path },
                 { Keys.DestinationFilePathBase, fileNameWithoutExtension == null
                     ? null : output.Path.Directory.CombineFile(output.Path.FileNameWithoutExtension) },
             });
         }
         return _onlyMetadata
             ? context.GetDocument(input, metadata)
             : context.GetDocument(input, output.OpenRead(), metadata);
     }
     return input;
 }