using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Argotic.Common; using Argotic.Syndication; using Microsoft.Data.Sqlite; using Serilog; using SharpRss.Models; namespace SharpRss.Services { /// /// Managing RSS feeds and groups. /// public class RssService : IDisposable { public RssService() { SetupTestGroupsAndFeedsAsync(); } public async Task> GetGroupsFeedsAsync() { HashSet items = new HashSet(); items.UnionWith(await GetGroupsAsync()); items.UnionWith(await GetUngroupedFeedsAsync()); return items; } public async Task CreateGroupAsync(CategoryModel group) => await DbAccess.SetGroupAsync(group); public async Task> GetGroupsAsync() => await DbAccess.GetGroupsAsync(); //TODO: Rework this! // Subscribe to a feed. public async Task AddSubscriptionAsync(string url, CategoryModel? group = null) { // Check for valid feed url bool validate = SyndicationDiscoveryUtility.UriExists(new Uri(url)); if (!validate) return false; // Check if feed exists in db FeedModel? dbFeed = await DbAccess.GetFeedAsync(url); if (dbFeed == null) { GenericSyndicationFeed genFeed = new GenericSyndicationFeed(); switch (genFeed.Format) { case SyndicationContentFormat.Rss: RssFeed rssFeed = (RssFeed)genFeed.Resource; break; case SyndicationContentFormat.Atom: AtomFeed atomFeed = (AtomFeed)genFeed.Resource; break; default: Log.Information("Feed implementation missing!"); break; } } // Update feed if newer // Update/fetch items return false; } private static FeedModel FromResource(ISyndicationResource resource) { FeedModel model = new FeedModel(""); switch (resource) { case RssFeed rssFeed: //TODO: From feed to model break; } return model; } public async Task UpdateFeeds() { Log.Verbose("Fetching feeds..."); var feeds = await GetFeedsAsync(); } public async Task> GetFeedsAsync(string? groupId = null) => await DbAccess.GetFeedsAsync(groupId); public async Task> GetUngroupedFeedsAsync() => await DbAccess.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 DbAccess.GetFeedItemsAsync(feedIds); return items; } /*private async Task AddFeedItems(IList items, FeedModel feedModel) { int result = 0; if (!items.Any()) return result; HashSet itemModels = new HashSet(); // TODO: implement!!! result = await DbAccess.SetFeedItemsAsync(itemModels); return result; }*/ /*private IList ConstructFeedItems(IList items, FeedModel feed) { IList itemModels = new List(); if (!items.Any()) return itemModels; foreach (FeedItem item in items) { itemModels.Add(new FeedItemModel() { Id = item.Id, FeedId = feed.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 }); } return itemModels; }*/ private GenericSyndicationFeed? CreateFeed(string url) { Uri feedUri = new Uri(url); Log.Verbose("Checking feed: {FeedUrl}", feedUri.ToString()); if (!SyndicationDiscoveryUtility.UriExists(feedUri)) { Log.Warning("Feed: {FeedUri} does not exists!", feedUri.ToString()); return null; } Log.Verbose("Fetching feed: {FeedUrl}", feedUri.ToString()); return GenericSyndicationFeed.Create(new Uri(url)); } 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; }*/ var groups = await GetGroupsAsync(); CategoryModel testGroup = groups.Single(x => x.Name == "News"); /*await AddFeedsAsync(new[] { "https://www.nu.nl/rss/Algemeen", "https://www.nu.nl/rss/Economie", "https://www.nu.nl/rss/Sport", "http://news.google.com/?output=atom" }, testGroup);*/ } public void Dispose() { } } }