SharpRSS/SharpRss/Services/RssService.cs

183 lines
7.5 KiB
C#
Raw Normal View History

2023-05-20 00:04:45 +02:00
using System;
2023-05-18 01:27:11 +02:00
using System.Collections.Generic;
2023-06-02 10:56:30 +02:00
using System.ComponentModel.Design;
using System.Linq;
2023-05-18 01:27:11 +02:00
using System.Threading.Tasks;
2023-05-29 18:02:24 +02:00
using Argotic.Common;
using Argotic.Syndication;
using Microsoft.Data.Sqlite;
2023-05-22 15:55:21 +02:00
using Serilog;
2023-05-18 01:27:11 +02:00
using SharpRss.Models;
namespace SharpRss.Services
{
/// <summary>
2023-05-22 15:55:21 +02:00
/// Managing RSS feeds and groups.
2023-05-18 01:27:11 +02:00
/// </summary>
public class RssService : IDisposable
2023-05-18 01:27:11 +02:00
{
public RssService()
{
SetupTestGroupsAndFeedsAsync();
2023-05-18 01:27:11 +02:00
}
2023-05-23 15:04:02 +02:00
2023-05-24 19:27:22 +02:00
public async Task<HashSet<object>> GetGroupsFeedsAsync()
2023-05-23 15:04:02 +02:00
{
HashSet<object> items = new HashSet<object>();
items.UnionWith(await GetGroupsAsync());
items.UnionWith(await GetUngroupedFeedsAsync());
return items;
}
public async Task<bool> CreateGroupAsync(CategoryModel group) => await DbAccess.SetGroupAsync(group);
public async Task<HashSet<CategoryModel>> GetGroupsAsync() => await DbAccess.GetGroupsAsync();
2023-05-27 00:32:05 +02:00
//TODO: Rework this!
// Subscribe to a feed.
public async Task<bool> AddSubscriptionAsync(string url, CategoryModel? group = null)
2023-05-22 15:55:21 +02:00
{
// Check for valid feed url
bool validate = SyndicationDiscoveryUtility.UriExists(new Uri(url));
if (!validate) return false;
// Check if feed exists in db
2023-06-02 10:56:30 +02:00
FeedModel? fModel = await DbAccess.GetFeedAsync(url);
// If not exists fetch feed & add.
if (fModel == null)
{
2023-06-02 10:56:30 +02:00
GenericSyndicationFeed genFeed = GenericSyndicationFeed.Create(new Uri(url));
fModel = FromResource(genFeed.Resource);
fModel.GroupId = group?.Id;
// Add feed
FeedModel? dbFeed = await DbAccess.SetFeedAsync(fModel);
// Update/fetch items
2023-06-02 11:56:48 +02:00
//await DbAccess.FetchFeedItemsAsync(new string[] { fModel.Url });
}
2023-06-02 11:56:48 +02:00
return true;
2023-05-29 16:14:26 +02:00
}
private static FeedModel FromResource(ISyndicationResource resource)
{
2023-06-02 10:56:30 +02:00
FeedModel model = new FeedModel();
switch (resource.Format)
{
2023-06-02 10:56:30 +02:00
case SyndicationContentFormat.Rss:
RssFeed rssFeed = (RssFeed)resource;
2023-06-02 11:56:48 +02:00
model.FeedType = rssFeed.Format.ToString();
model.Title = rssFeed.Channel.Title;
model.Description = rssFeed.Channel.Description;
model.Copyright = rssFeed.Channel.Copyright;
model.Url = rssFeed.Channel.SelfLink.ToString();
model.ImageUrl = rssFeed.Channel.Image?.Url.ToString();
model.Language = rssFeed.Channel.Language?.ToString();
2023-06-02 10:56:30 +02:00
break;
case SyndicationContentFormat.Atom:
AtomFeed atomFeed = (AtomFeed)resource;
break;
default:
Log.Information("Feed implementation missing!");
break;
}
return model;
}
2023-05-29 18:02:24 +02:00
public async Task UpdateFeeds()
{
Log.Verbose("Fetching feeds...");
var feeds = await GetFeedsAsync();
}
2023-05-29 16:14:26 +02:00
public async Task<HashSet<FeedModel>> GetFeedsAsync(string? groupId = null) => await DbAccess.GetFeedsAsync(groupId);
public async Task<HashSet<FeedModel>> GetUngroupedFeedsAsync() => await DbAccess.GetFeedsAsync("");
2023-05-24 19:27:22 +02:00
2023-05-25 15:48:56 +02:00
public async Task<HashSet<FeedItemModel>> GetFeedItemsAsync(string feedId, string? groupId = null) => await GetFeedItemsFromFeedsAsync(new[] { feedId }, groupId);
public async Task<HashSet<FeedItemModel>> GetFeedItemsFromFeedsAsync(string[] feedIds, string? groupId = null)
2023-05-24 19:27:22 +02:00
{
2023-05-29 16:14:26 +02:00
var items = await DbAccess.GetFeedItemsAsync(feedIds);
2023-05-24 19:27:22 +02:00
return items;
}
2023-05-29 18:02:24 +02:00
/*private async Task<int> AddFeedItems(IList<FeedItem> items, FeedModel feedModel)
2023-05-22 15:55:21 +02:00
{
int result = 0;
if (!items.Any())
return result;
HashSet<FeedItemModel> itemModels = new HashSet<FeedItemModel>();
2023-05-29 16:14:26 +02:00
// TODO: implement!!!
result = await DbAccess.SetFeedItemsAsync(itemModels);
return result;
2023-05-29 18:02:24 +02:00
}*/
2023-05-29 16:14:26 +02:00
2023-05-29 18:02:24 +02:00
/*private IList<FeedItemModel> ConstructFeedItems(IList<FeedItem> items, FeedModel feed)
2023-05-29 16:14:26 +02:00
{
IList<FeedItemModel> itemModels = new List<FeedItemModel>();
if (!items.Any())
return itemModels;
2023-05-22 15:55:21 +02:00
foreach (FeedItem item in items)
{
itemModels.Add(new FeedItemModel()
{
Id = item.Id,
2023-05-29 16:14:26 +02:00
FeedId = feed.Id,
2023-05-22 15:55:21 +02:00
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
});
}
2023-05-29 16:14:26 +02:00
return itemModels;
2023-05-29 18:02:24 +02:00
}*/
2023-05-29 16:14:26 +02:00
2023-05-29 18:02:24 +02:00
private GenericSyndicationFeed? CreateFeed(string url)
2023-05-22 15:55:21 +02:00
{
2023-05-29 18:02:24 +02:00
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));
2023-05-22 15:55:21 +02:00
}
private async void SetupTestGroupsAndFeedsAsync()
2023-05-18 01:27:11 +02:00
{
//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" });*/
2023-05-27 00:32:05 +02:00
/*Log.Verbose("Fetching feeds...");
var groups = await GetGroupsAsync();
2023-05-22 15:55:21 +02:00
GroupModel testGroup = groups.Single(x => x.Name == "Test");
2023-05-27 00:32:05 +02:00
try
{
2023-05-27 00:32:05 +02:00
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;
}*/
2023-06-02 10:56:30 +02:00
/*var groups = await GetGroupsAsync();
2023-06-02 11:56:48 +02:00
CategoryModel testGroup = groups.Single(x => x.Name == "News");
await AddSubscriptionAsync("https://www.nu.nl/rss/Algemeen", testGroup);*/
/*await AddFeedsAsync(new[]
2023-05-29 18:02:24 +02:00
{
"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);*/
2023-05-18 01:27:11 +02:00
}
2023-05-29 16:14:26 +02:00
public void Dispose()
{
}
}
2023-05-18 01:27:11 +02:00
}