using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using CodeHollow.FeedReader; using Serilog; using SharpRss.Models; namespace SharpRss.Services { /// /// Managing RSS feeds and groups. /// public class RssService : IDisposable { public RssService() { SetupTestGroupsAndFeedsAsync(); } private readonly DatabaseService _dbService = new DatabaseService(); public async Task> GetGroupsFeedsAsync() { HashSet items = new HashSet(); items.UnionWith(await GetGroupsAsync()); items.UnionWith(await GetUngroupedFeedsAsync()); return items; } public async Task CreateGroupAsync(GroupModel group) => await _dbService.SetGroupAsync(group); public async Task> GetGroupsAsync() => await _dbService.GetGroupsAsync(); //TODO: Need to rework this implementation!!! /*public async Task FetchFeeds(string[]? rssUrls, GroupModel? group = null) { bool result = false; if (rssUrls == null) return result; HashSet fetchedFeeds = new HashSet(); foreach (var rssUrl in rssUrls) { fetchedFeeds.Add(await FetchFeed(rssUrl)); } Feed fetched = await FetchFeed(rssUrl); if (fetched == null) return result; FeedModel feedModel = new FeedModel(rssUrl) { Title = fetched.Title, GroupId = group?.Id ?? string.Empty, FeedType = fetched.Type.ToString(), Description = fetched.Description, Language = fetched.Language, Copyright = fetched.Copyright, DateAdded = DateTimeOffset.Now, LastUpdated = DateTimeOffset.Now, ImageUrl = fetched.ImageUrl, OriginalDocument = fetched.OriginalDocument }; FeedModel? dbFeed = await _dbService.SetFeedAsync(feedModel); result = dbFeed != null; if (dbFeed == null) return result; if (await AddFeedItems(fetched.Items, dbFeed) == 0) Log.Warning("No feed items added to feed: {FeedUrl}", dbFeed.Url); return result; }*/ public async Task> GetFeedsAsync(string? groupId = null) => await _dbService.GetFeedsAsync(groupId); public async Task> GetUngroupedFeedsAsync() => await _dbService.GetFeedsAsync(""); public async Task> GetFeedItemsAsync(string feedId, string? groupId = null) => await GetFeedItemsFromFeedsAsync(new[] { feedId }, groupId); public async Task> GetFeedItemsFromFeedsAsync(string[] feedIds, string? groupId = null) { var items = await _dbService.GetFeedItemsAsync(feedIds); return items; } private async Task AddFeedItems(IList items, FeedModel feedModel) { int result = 0; if (!items.Any()) return result; HashSet itemModels = new HashSet(); foreach (FeedItem item in items) { itemModels.Add(new FeedItemModel() { Id = item.Id, FeedId = feedModel.Id, Title = item.Title, Description = item.Description, Link = item.Link, LastUpdated = DateTimeOffset.Now, PublishingDate = item.PublishingDate != null ? new DateTimeOffset((DateTime)item.PublishingDate) : null, Author = item.Author, Categories = item.Categories.ToArray(), Content = item.Content }); } result = await _dbService.SetFeedItemsAsync(itemModels); return result; } private async Task FetchFeed(string url) { Log.Verbose("Fetching feed: {FeedUrl}", url); var urls = await FeedReader.ParseFeedUrlsAsStringAsync(url); string feedUrl = url; if (urls.Any()) feedUrl = urls.First(); return await FeedReader.ReadAsync(feedUrl); } private async void SetupTestGroupsAndFeedsAsync() { //TODO: Make multiple adding of feed to a transaction, now throws an exception. /*var groupRes = await CreateGroupAsync(new GroupModel() { Name = "Test" }); groupRes = await CreateGroupAsync(new GroupModel() { Name = "News" }); groupRes = await CreateGroupAsync(new GroupModel() { Name = "Tech" }); groupRes = await CreateGroupAsync(new GroupModel() { Name = "Science" });*/ /*Log.Verbose("Fetching feeds..."); var groups = await GetGroupsAsync(); GroupModel testGroup = groups.Single(x => x.Name == "Test"); try { var res = await AddFeed("http://fedoramagazine.org/feed/", testGroup); res = await AddFeed("https://www.nasa.gov/rss/dyn/breaking_news.rss", testGroup); res = await AddFeed("https://journals.plos.org/plosone/feed/atom", testGroup); res = await AddFeed("https://itsfoss.com/feed", testGroup); res = await AddFeed("https://advisories.ncsc.nl/rss/advisories", testGroup); } catch (Exception e) { Log.Error(e, "Error fetching feeds!"); throw; }*/ } public void Dispose() { _dbService.Dispose(); } } }