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();
}
}