using System.ServiceModel.Syndication; using System.Xml; using FinlyticCore.Dtos.News; namespace FinlyticNews.Adapters.Discovery; /// /// Discovery adapter targeting standard RSS/Atom syndication feeds. /// public class RssDiscoveryAdapter : ArticleDiscoveryAdapter { /// public override string Name => "rss"; /// public override List ExtractUrls(string content, string sourceUrl) { if (string.IsNullOrWhiteSpace(content)) return []; var articles = new List(); if (!Uri.TryCreate(sourceUrl, UriKind.Absolute, out var baseUri)) return articles; try { using var stringReader = new StringReader(content); using var xmlReader = XmlReader.Create(stringReader, new XmlReaderSettings { DtdProcessing = DtdProcessing.Ignore, IgnoreWhitespace = true }); var feed = SyndicationFeed.Load(xmlReader); var feedLanguage = feed?.Language; var feedTitle = feed?.Title?.Text; if (feed?.Items != null) { foreach (var item in feed.Items) { var link = item.Links.FirstOrDefault()?.Uri?.ToString() ?? item.Id; if (!string.IsNullOrWhiteSpace(link) && Uri.TryCreate(baseUri, link, out var absoluteUri)) { var title = item.Title?.Text?.Trim(); var summary = item.Summary?.Text?.Trim(); DateTime? pubDate = item.PublishDate != DateTimeOffset.MinValue ? item.PublishDate.UtcDateTime : (item.LastUpdatedTime != DateTimeOffset.MinValue ? item.LastUpdatedTime.UtcDateTime : null); articles.Add(new DiscoveredArticle( Url: absoluteUri.ToString(), Isins: null, Title: title, Summary: summary, PublishedAt: pubDate, Language: feedLanguage, SourceName: feedTitle )); } } } } catch { // Graceful handling fehlerhafter Feeds } return articles.GroupBy(u => u.Url, StringComparer.OrdinalIgnoreCase) .Select(g => g.First()) .ToList(); } }