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()); }
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 }
// 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); } }
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() }; }
internal void AddMetadataItem(MetadataItem item) { if (MetadataItems == null) { MetadataItems = new List <MetadataItem>(); } MetadataItems.Add(item); }
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); }
// 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); } }
// 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]); }
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()); }
/// <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); }
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()); }
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; }