diff --git a/SharpRss/Models/FeedItemModel.cs b/SharpRss/Models/FeedItemModel.cs
index 5a812fc..b153340 100644
--- a/SharpRss/Models/FeedItemModel.cs
+++ b/SharpRss/Models/FeedItemModel.cs
@@ -1,30 +1,19 @@
using System;
-using System.Collections.Generic;
-using System.Text;
namespace SharpRss.Models
{
public class FeedItemModel
{
- ///
- /// Last time the item is fetched.
- ///
- public DateTime LastUpdated { get; set; }
- ///
- /// The feed in which the item is part of.
- ///
+ public string Id { get; set; }
public string FeedId { get; set; }
- ///
- /// If the item is read.
- ///
public bool Read { get; set; }
public string Type { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string Link { get; set; }
- public DateTime? PublishingDate { get; set; }
+ public DateTimeOffset LastUpdated { get; set; }
+ public DateTimeOffset? PublishingDate { get; set; }
public string Author { get; set; }
- public string Id { get; set; }
public string[] Categories { get; set; }
public string Content { get; set; }
}
diff --git a/SharpRss/Models/FeedModel.cs b/SharpRss/Models/FeedModel.cs
index 6ebbf1c..a2e1a59 100644
--- a/SharpRss/Models/FeedModel.cs
+++ b/SharpRss/Models/FeedModel.cs
@@ -4,16 +4,20 @@ namespace SharpRss.Models
{
public class FeedModel
{
- public string FeedId { get; set; }
- public string GroupId { get; set; }
- public string FeedType { get; set; }
- public string FeedUrl { get; set; }
- public string Description { get; set; }
- public string Language { get; set; }
- public string Copyright { get; set; }
- public DateTime LastUpdated { get; set; }
- public string ImageUrl { get; set; }
- public int TotalItems { get; set; }
- public int TotalRead { get; set; }
+ public FeedModel(string rssUrl)
+ {
+ Id = Guid.NewGuid().ToString();
+ Url = rssUrl;
+ }
+ public string Id { get; set; }
+ public string Url { get; set; }
+ public string? GroupId { get; set; }
+ public string FeedType { get; set; } = string.Empty;
+ public string Description { get; set; } = string.Empty;
+ public string Language { get; set; } = string.Empty;
+ public string Copyright { get; set; } = string.Empty;
+ public DateTimeOffset DateAdded { get; set; }
+ public DateTimeOffset LastUpdated { get; set; }
+ public string ImageUrl { get; set; } = string.Empty;
}
}
diff --git a/SharpRss/Models/GroupModel.cs b/SharpRss/Models/GroupModel.cs
index 9a5b17f..3af821b 100644
--- a/SharpRss/Models/GroupModel.cs
+++ b/SharpRss/Models/GroupModel.cs
@@ -5,15 +5,15 @@ namespace SharpRss.Models
{
public class GroupModel
{
- public GroupModel(string name)
+ public GroupModel()
{
- Name = name;
HexColor = Utilities.GenerateRandomHexColor();
Id = Guid.NewGuid().ToString();
}
- public string Name { get; set; }
+
+ public string Name { get; set; } = string.Empty;
public string HexColor { get; set; }
- public string Icon { get; set; }
- public string Id { get; private set; }
+ public string Icon { get; set; } = string.Empty;
+ public string Id { get; set; }
}
}
diff --git a/SharpRss/Services/DatabaseService.cs b/SharpRss/Services/DatabaseService.cs
index c910a97..3e76aa7 100644
--- a/SharpRss/Services/DatabaseService.cs
+++ b/SharpRss/Services/DatabaseService.cs
@@ -23,86 +23,139 @@ namespace SharpRss.Services
private readonly string _feedTable = "feed_data";
private readonly string _feedItemTable = "feed_item_data";
- public async Task RemoveGroupFromFeedsAsync(string groupId)
+ // Group
+ public async Task> GetGroupsAsync(string? groupName = null)
{
- await _sqlConn.QueryAsync("UPDATE feed_data SET group_id=NULL WHERE group_id=@GroupId", new { GroupId = groupId });
- }
-
- public async Task AddCategoriesAsync(HashSet categories)
- {
- bool result = true;
_sqlConn.Open();
- foreach (var categoryModel in categories)
+ SqliteCommand cmd = new SqliteCommand(groupName != null ? $"SELECT * FROM {_groupTable} WHERE name=@name;" : $"SELECT * FROM {_groupTable}", _sqlConn)
{
- await _sqlConn.QueryAsync("INSERT INTO category_data (name, hex_color, path_icon, category_id) VALUES(@catName, @hexColor, @pathIcon, @categoryId) ON CONFLICT(name) DO UPDATE SET hex_color=@hexColor, path_icon=@pathIcon",
- new { catName = categoryModel.Name, hexColor = categoryModel.HexColor, pathIcon = categoryModel.Icon, categoryId = categoryModel.Id });
- }
- _sqlConn.Close();
- return result;
- }
-
- public async Task AddFeedsAsync(HashSet feeds)
- {
- bool result = true;
- _sqlConn.Open();
- foreach (var feedModel in feeds)
- {
- await _sqlConn.QueryAsync("INSERT OR REPLACE INTO feed_data(url, feed_id, category_id) VALUES(@url, @feedId, @categoryId) ON CONFLICT(url) DO UPDATE SET category_id=@categoryId", new { url = feedModel.FeedUrl, feedId = feedModel.FeedId, categoryId = feedModel.GroupId });
- }
- _sqlConn.Close();
- return result;
- }
-
- public async Task> GetCategoriesAsync()
- {
- HashSet categories = new HashSet();
- _sqlConn.Open();
- SqliteCommand cmd = _sqlConn.CreateCommand();
- cmd.CommandText = "SELECT * FROM category_data";
+ Parameters =
+ {
+ new SqliteParameter("name", groupName)
+ }
+ };
await using SqliteDataReader reader = await cmd.ExecuteReaderAsync();
+ HashSet groups = new HashSet();
while (reader.Read())
{
- //categories.Add(GroupModel.Create(reader["name"].ToString(), reader["hex_color"].ToString(), reader["category_id"].ToString()));
+ groups.Add(new GroupModel()
+ {
+ Name = reader["name"].ToString(),
+ HexColor = reader["hex_color"].ToString(),
+ Icon = reader["icon"].ToString(),
+ Id = reader["id"].ToString()
+ });
}
-
_sqlConn.Close();
- return categories;
+ return groups;
}
- public async Task> GetFeedsAsync(string? categoryId = null)
+ ///
+ /// Creates a group if not exists else will update the group.
+ ///
+ ///
+ ///
+ public async Task SetGroupAsync(GroupModel groupModel)
+ {
+ bool result = false;
+ _sqlConn.Open();
+ SqliteCommand cmd = new SqliteCommand($"INSERT OR REPLACE INTO {_groupTable} (id, hex_color, icon, name) VALUES (IFNULL((SELECT id FROM {_groupTable} WHERE name=@name), @id), @hexColor, @icon, @name)", _sqlConn)
+ {
+ Parameters =
+ {
+ new SqliteParameter("id", groupModel.Id),
+ new SqliteParameter("hexColor", groupModel.HexColor),
+ new SqliteParameter("icon", groupModel.Icon),
+ new SqliteParameter("name", groupModel.Name)
+ }
+ };
+ int affected = await cmd.ExecuteNonQueryAsync();
+ if (affected != 0)
+ result = true;
+ _sqlConn.Close();
+ return result;
+ }
+
+ public async Task RemoveGroupAsync(GroupModel groupModel)
+ {
+ bool result = false;
+ _sqlConn.Open();
+ // Remove the group and remove the feeds that were part of the group.
+ SqliteCommand cmd = new SqliteCommand($"DELETE FROM {_groupTable} WHERE id=@id; UPDATE {_feedTable} SET group_id=NULL WHERE group_id=@id", _sqlConn)
+ {
+ Parameters =
+ {
+ new SqliteParameter("id", groupModel.Id)
+ }
+ };
+ int affected = await cmd.ExecuteNonQueryAsync();
+ if (affected != 0)
+ result = true;
+ _sqlConn.Close();
+ return result;
+ }
+ // Feed
+ public async Task> GetFeedsAsync(string? feedName = null)
{
HashSet feeds = new HashSet();
_sqlConn.Open();
-
- SqliteCommand cmd = _sqlConn.CreateCommand();
- cmd.CommandText = categoryId == null ? "SELECT * FROM feed_data" : "SELECT * FROM feed_data WHERE category_id=@categoryId";
- if (categoryId != null)
- cmd.Parameters.Add(new SqliteParameter("categoryId", categoryId));
-
- await using SqliteDataReader reader = await cmd.ExecuteReaderAsync();
- while (reader.Read())
+ SqliteCommand cmd = new SqliteCommand(feedName != null ? $"SELECT * FROM {_feedTable} WHERE name=@name" : $"SELECT * FROM {_feedTable}", _sqlConn)
{
- //feeds.Add(FeedModel.Create(reader["url"].ToString(), reader["feed_id"].ToString(), reader["category_id"].ToString()));
- }
+ Parameters =
+ {
+ new SqliteParameter("name", feedName)
+ }
+ };
+ int affected = await cmd.ExecuteNonQueryAsync();
+ Log.Verbose("{FeedAmount} feeds found!", affected);
_sqlConn.Close();
return feeds;
}
+ public async Task AddFeedAsync(FeedModel feedModel)
+ {
+ bool result = false;
+ _sqlConn.Open();
+ SqliteCommand cmd = new SqliteCommand($"INSERT OR REPLACE INTO {_feedTable} (id, url, group_id, feed_type, description, language, copyright, date_added, last_updated, image_url)" +
+ $"VALUES (IFNULL((SELECT id FROM {_feedTable} WHERE url=@url), @id), @url, @groupId, @feedType, @description, @language, @copyright, @dateAdded, @lastUpdated, @imageUrl)", _sqlConn)
+ {
+ Parameters =
+ {
+ new SqliteParameter("id", feedModel.Id),
+ new SqliteParameter("url", feedModel.Url),
+ new SqliteParameter("groupId", feedModel.GroupId),
+ new SqliteParameter("feedType", feedModel.FeedType),
+ new SqliteParameter("description", feedModel.Description),
+ new SqliteParameter("language", feedModel.Language),
+ new SqliteParameter("copyright", feedModel.Copyright),
+ new SqliteParameter("dateAdded", feedModel.DateAdded.ToUnixTimeMilliseconds()),
+ new SqliteParameter("lastUpdated", feedModel.LastUpdated.ToUnixTimeMilliseconds()),
+ new SqliteParameter("imageUrl", feedModel.ImageUrl)
+ }
+ };
+ int affected = await cmd.ExecuteNonQueryAsync();
+ if (affected != 0)
+ result = true;
+ _sqlConn.Close();
+ return result;
+ }
+ // Feed item
+
private async void InitializeDb()
{
Log.Verbose("Checking database...");
HashSet failed = new HashSet();
_sqlConn.Open();
Log.Verbose("Checking table: {Table}", _groupTable);
- var queryResponse = await _sqlConn.QueryAsync($"CREATE TABLE IF NOT EXISTS {_groupTable} (name STRING NOT NULL, hex_color STRING NOT NULL, icon STRING, id STRING PRIMARY KEY, CONSTRAINT name UNIQUE (name))");
+ var queryResponse = await _sqlConn.QueryAsync($"CREATE TABLE IF NOT EXISTS {_groupTable} (name STRING NOT NULL, hex_color STRING NOT NULL, icon STRING, id STRING PRIMARY KEY)");
if (queryResponse.Any()) failed.Add("category_data");
Log.Verbose("Checking table: {Table}", _feedTable);
- queryResponse = await _sqlConn.QueryAsync($"CREATE TABLE IF NOT EXISTS {_feedTable} (url STRING NOT NULL, id STRING PRIMARY KEY, group_id STRING DEFAULT NULL, CONSTRAINT url, UNIQUE (url))");
+ queryResponse = await _sqlConn.QueryAsync($"CREATE TABLE IF NOT EXISTS {_feedTable} (id STRING PRIMARY KEY, url STRING NOT NULL, group_id STRING DEFAULT NULL, feed_type STRING, description STRING, language STRING, copyright STRING, date_added INT, last_updated INT, image_url STRING)");
if (queryResponse.Any()) failed.Add("feed_data");
Log.Verbose("Checking table: {Table}", _feedItemTable);
- queryResponse = await _sqlConn.QueryAsync($"CREATE TABLE IF NOT EXISTS {_feedItemTable} (id STRING PRIMARY KEY, feed_id STRING NOT NULL)");
+ queryResponse = await _sqlConn.QueryAsync($"CREATE TABLE IF NOT EXISTS {_feedItemTable} (id STRING PRIMARY KEY, feed_id STRING DEFAULT NULL, read INT, type STRING, title STRING, description STRING, link STRING, last_updated INT, publishing_date INT, author STRING, categories STRING, content STRING)");
if (queryResponse.Any()) failed.Add("feed_item_data");
_sqlConn.Close();
diff --git a/SharpRss/Services/RssService.cs b/SharpRss/Services/RssService.cs
index 5c06879..639e3e3 100644
--- a/SharpRss/Services/RssService.cs
+++ b/SharpRss/Services/RssService.cs
@@ -15,13 +15,23 @@ namespace SharpRss.Services
{
public RssService()
{
- //SetupTestCategoriesAndFeedsAsync();
+ SetupTestCategoriesAndFeedsAsync();
}
private readonly DatabaseService _dbService = new DatabaseService();
- /*private async void SetupTestCategoriesAndFeedsAsync()
+ private async void SetupTestCategoriesAndFeedsAsync()
{
- await _dbService.AddCategoriesAsync(new HashSet()
+ /*bool result = await _dbService.SetGroupAsync(new GroupModel() { Name = "News" });
+ result = await _dbService.SetGroupAsync(new GroupModel() { Name = "Tech" });
+ result = await _dbService.SetGroupAsync(new GroupModel() { Name = "Science" });
+ result = await _dbService.SetGroupAsync(new GroupModel() { Name = "Test" });*/
+
+ /*GroupModel? editGroup = await _dbService.GetGroupsAsync("Test");
+ if (editGroup != null)
+ {
+ bool result2 = await _dbService.RemoveGroupAsync(editGroup);
+ }*/
+ /*await _dbService.AddCategoriesAsync(new HashSet()
{
new CategoryModel() { Name = "All" },
new CategoryModel() { Name = "RSS" },
@@ -34,59 +44,7 @@ namespace SharpRss.Services
new FeedModel("https://www.nasa.gov/rss/dyn/breaking_news.rss"),
new FeedModel("https://journals.plos.org/plosone/feed/atom"),
new FeedModel("https://itsfoss.com/feed")
- });
- }*/
-
- public async Task GetFeedAsync(string rssUrl)
- {
- /*return await FeedCache.GetFeed(rssUrl);*/
- return new Feed();
- }
-
- public async Task> GetAllUnsortedAsync()
- {
- HashSet