// AtomEntry conversion private FeedEntry CreateFeedEntry(IAtomEntry entry, Feed feed) { var link = GetLinkFromFeedEntry(entry.Links); var feedEntry = new FeedEntry() { FeedTitle = feed.Name, Id = entry.Id, Title = entry.Title, Summary = entry.Summary, Description = entry.Description, LastUpdated = entry.LastUpdated, Published = entry.Published, Link = link }; if (feedEntry.Id == null) { feedEntry.Id = CreateIdFromFeedEntry(feedEntry); } //TODO: This could be better if (entry.Categories != null) { foreach (var category in entry.Categories) { feedEntry.Tags.Add(category.Name); } } return(feedEntry); }
public AtomEntry(IAtomEntry item) : base(item) { ContentType = item.ContentType; Summary = item.Summary; Rights = item.Rights; }
public virtual async Task <IAtomEntry> ReadEntry() { IAtomEntry item = await base.ReadItem() as IAtomEntry; if (item == null) { throw new FormatException("Invalid Atom entry"); } return(item); }
public async Task ReadItem() { using (XmlReader xmlReader = XmlReader.Create(@"..\..\..\TestFeeds\simpleAtomFeed.xml", new XmlReaderSettings { Async = true })) { var reader = new AtomFeedReader(xmlReader); while (await reader.Read()) { if (reader.ElementType == SyndicationElementType.Item) { IAtomEntry item = await reader.ReadEntry(); //Assert content of item Assert.True(item.Title == "Atom draft-07 snapshot"); Assert.True(item.Links.Count() == 3); Assert.True(item.Contributors.Count() == 3); Assert.True(item.Rights == "All rights Reserved. Contoso."); Assert.True(item.Id == "tag:example.org,2003:3.2397"); } } } }
public AtomEntry(IAtomEntry entry, object content) { FeedEntry = entry ?? throw new ArgumentNullException(nameof(entry)); Content = content ?? throw new ArgumentNullException(nameof(content)); }
private async Task <List <BlogPost> > GetFeed() { var xmlReader = XmlReader.Create(_settings.Value.FeedUrl); var reader = new AtomFeedReader(xmlReader); var posts = new List <BlogPost>(); // // Read the feed while (await reader.Read()) { // // Check the type of the current element. switch (reader.ElementType) { // // Read category case SyndicationElementType.Category: ISyndicationCategory category = await reader.ReadCategory(); break; // // Read image case SyndicationElementType.Image: ISyndicationImage image = await reader.ReadImage(); break; // // Read entry case SyndicationElementType.Item: IAtomEntry entry = await reader.ReadEntry(); // these are the only ones we need for now posts.Add(new BlogPost { Title = entry.Title, PublishedDate = entry.Published.DateTime, Categories = entry.Categories?.Select(c => c.Name)?.ToList() }); break; // // Read link case SyndicationElementType.Link: ISyndicationLink link = await reader.ReadLink(); break; // // Read person case SyndicationElementType.Person: ISyndicationPerson person = await reader.ReadPerson(); break; // // Read content default: ISyndicationContent content = await reader.ReadContent(); break; } } return(posts); }
public string Format(IAtomEntry entry) { return(Format(CreateContent(entry))); }
public virtual ISyndicationContent CreateContent(ISyndicationItem item) { if (item == null) { throw new ArgumentNullException(nameof(item)); } if (string.IsNullOrEmpty(item.Id)) { throw new ArgumentNullException("Id"); } if (string.IsNullOrEmpty(item.Title)) { throw new ArgumentNullException("Title"); } if (item.LastUpdated == default(DateTimeOffset)) { throw new ArgumentException("LastUpdated"); } var result = new SyndicationContent(AtomElementNames.Entry); // // id result.AddField(new SyndicationContent(AtomElementNames.Id, item.Id)); // // title result.AddField(new SyndicationContent(AtomElementNames.Title, item.Title)); // // updated result.AddField(new SyndicationContent(AtomElementNames.Updated, FormatValue(item.LastUpdated))); // // published if (item.Published != default(DateTimeOffset)) { result.AddField(new SyndicationContent(AtomElementNames.Published, FormatValue(item.Published))); } // // link bool hasContentLink = false; bool hasAlternateLink = false; if (item.Links != null) { foreach (var link in item.Links) { if (link.RelationshipType == AtomLinkTypes.Content) { if (hasContentLink) { throw new ArgumentNullException("Multiple content links are not allowed"); } hasContentLink = true; } else if (link.RelationshipType == null || link.RelationshipType == AtomLinkTypes.Alternate) { hasAlternateLink = true; } result.AddField(CreateContent(link)); } } // // author/contributor bool hasAuthor = false; if (item.Contributors != null) { foreach (var c in item.Contributors) { if (c.RelationshipType == null || c.RelationshipType == AtomContributorTypes.Author) { hasAuthor = true; } result.AddField(CreateContent(c)); } } if (!hasAuthor) { throw new ArgumentException("Author is required"); } // // category if (item.Categories != null) { foreach (var category in item.Categories) { result.AddField(CreateContent(category)); } } IAtomEntry entry = item as IAtomEntry; // // content if (!string.IsNullOrEmpty(item.Description)) { if (hasContentLink) { throw new ArgumentException("Description and content link are not allowed simultaneously"); } var content = new SyndicationContent(AtomElementNames.Content, item.Description); // // type if (entry != null && !(string.IsNullOrEmpty(entry.ContentType) || entry.ContentType.Equals(AtomConstants.PlainTextContentType, StringComparison.OrdinalIgnoreCase))) { content.AddAttribute(new SyndicationAttribute(AtomConstants.Type, entry.ContentType)); } result.AddField(content); } else { if (!(hasContentLink || hasAlternateLink)) { throw new ArgumentException("Description or alternate link is required"); } } if (entry != null) { // // summary if (!string.IsNullOrEmpty(entry.Summary)) { result.AddField(new SyndicationContent(AtomElementNames.Summary, entry.Summary)); } // // rights if (!string.IsNullOrEmpty(entry.Rights)) { result.AddField(new SyndicationContent(AtomElementNames.Rights, entry.Rights)); } } return(result); }
public static async Task ReadAtomFeed(string filePath) { // // Create an XmlReader from file // Example: ..\tests\TestFeeds\simpleAtomFeed.xml using (XmlReader xmlReader = XmlReader.Create(filePath, new XmlReaderSettings() { Async = true })) { // // Create an AtomFeedReader var reader = new AtomFeedReader(xmlReader); // // Read the feed while (await reader.Read()) { // // Check the type of the current element. switch (reader.ElementType) { // // Read category case SyndicationElementType.Category: ISyndicationCategory category = await reader.ReadCategory(); break; // // Read image case SyndicationElementType.Image: ISyndicationImage image = await reader.ReadImage(); break; // // Read entry case SyndicationElementType.Item: IAtomEntry entry = await reader.ReadEntry(); break; // // Read link case SyndicationElementType.Link: ISyndicationLink link = await reader.ReadLink(); break; // // Read person case SyndicationElementType.Person: ISyndicationPerson person = await reader.ReadPerson(); break; // // Read content default: ISyndicationContent content = await reader.ReadContent(); break; } } } }
// Handles RSS2.0 and Atom feeds private async Task <bool> HandleXmlFeed(Feed feed, bool populateCacheOnly = false) { using (log.BeginScope($"{ nameof(FeedService) }->{ nameof(HandleXmlFeed) } with feed: {feed}")) { try { // Create async reader using (XmlReader xmlReader = XmlReader.Create(feed.ConnectionString, new XmlReaderSettings() { Async = true })) { ISyndicationFeedReader reader = null; // Special reader for every type switch (feed.Type) { case FeedType.RSS: log.LogDebug("Creating RssFeedReader"); reader = new RssFeedReader(xmlReader); break; case FeedType.Atom: log.LogDebug("Creating AtomFeedReader"); reader = new AtomFeedReader(xmlReader); break; default: log.LogError("Invalid FeedType found."); return(false); } log.LogDebug("Starting feed reading"); // Read the entries async while (await reader.Read()) { log.LogDebug("Found elementType '{ElementType}'", reader.ElementType); // We only need the entrytypes (yet) if (reader.ElementType == SyndicationElementType.Item) { FeedEntry feedEntry = null; // Create my feedEntry switch (feed.Type) { case FeedType.RSS: ISyndicationItem rssEntry = await(reader as RssFeedReader).ReadItem(); log.LogDebug("ISyndicationItem: {Item}", rssEntry); feedEntry = CreateFeedEntry(rssEntry, feed); break; case FeedType.Atom: IAtomEntry atomEntry = await(reader as AtomFeedReader).ReadEntry(); log.LogDebug("IAtomEntry: {Entry}", atomEntry); feedEntry = CreateFeedEntry(atomEntry, feed); break; default: continue; } // Check if we already had this one if (await cache.IsCached(feedEntry.Id)) { log.LogDebug("ID '{Id}' is in cache", feedEntry.Id); } // Check if the entry is older then MaxAge to prevent double posting else if (feedEntry?.Published <= (DateTime.Now - cfg.Application.Cache.MaxAge)) { log.LogInformation("Entry '{Id}' is too old.", feedEntry.Id); } else { // Hand over to instance service log.LogDebug("Tooting id '{Id}' ", feedEntry.Id); await TootTheFeedEntry(feedEntry, populateCacheOnly, feed); } } } return(true); } } catch (Exception ex) { log.LogError(ex, "HandleXmlFeed Exception - {feed}", feed); return(false); } } }