Reworking models.

This commit is contained in:
Max 2023-05-20 00:04:45 +02:00
parent 43cb208910
commit e4a0f4ce7d
14 changed files with 103 additions and 124 deletions

View File

@ -1,33 +0,0 @@
using System;
namespace SharpRss.Models
{
/// <summary>
/// To store and load data from file/database
/// </summary>
public class CategoryModel
{
public CategoryModel()
{
HexColor = $"#{_random.Next(0x1000000):X6}";
CategoryId = Guid.NewGuid().ToString();
}
private readonly Random _random = new Random();
public static CategoryModel Create(string categoryName, string hexColor, string id)
{
CategoryModel catModel = new CategoryModel()
{
Name = categoryName,
HexColor = hexColor,
CategoryId = id
};
return catModel;
}
public string Name { get; set; }
public string HexColor { get; set; }
public string PathIcon { get; set; }
public string CategoryId { get; private set; }
}
}

View File

@ -11,14 +11,13 @@ namespace SharpRss.Models
/// </summary>
public DateTime LastUpdated { get; set; }
/// <summary>
/// The feed in which the item is part.
/// The feed in which the item is part of.
/// </summary>
public string FeedId { get; set; }
/// <summary>
/// If the item is read.
/// </summary>
public string Read { get; set; }
public bool Read { get; set; }
public string Type { get; set; }
public string Title { get; set; }
public string Description { get; set; }

View File

@ -5,37 +5,14 @@ namespace SharpRss.Models
{
public class FeedModel
{
private FeedModel()
{
}
public FeedModel(string rssFeedUrl, CategoryModel? category = null)
{
if (category != null)
CategoryId = category.CategoryId;
FeedId = Guid.NewGuid().ToString();
FeedUrl = rssFeedUrl;
}
public string FeedId { get; private set; }
public string CategoryId { get; set; } = "";
public string FeedType { get; set; }
public string FeedId { get; set; }
public string CategoryId { 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 static FeedModel Create(string url, string feedId, string categoryId)
{
FeedModel feedModel = new FeedModel()
{
FeedUrl = url,
FeedId = feedId,
CategoryId = categoryId
};
return feedModel;
}
}
}

View File

@ -0,0 +1,22 @@
using System;
namespace SharpRss.Models
{
/// <summary>
/// To store and load data from file/database
/// </summary>
public class GroupModel
{
/*public GroupModel()
{
HexColor = $"#{_random.Next(0x1000000):X6}";
Id = Guid.NewGuid().ToString();
}
private readonly Random _random = new Random();*/
public string Name { get; set; }
public string HexColor { get; set; }
public string Icon { get; set; }
public string Id { get; private set; }
}
}

View File

@ -2,7 +2,6 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Dapper;
using Microsoft.Data.Sqlite;
@ -13,22 +12,30 @@ namespace SharpRss.Services
{
internal class DatabaseService : IDisposable
{
private string _connectionString => $"Data Source={Path.Combine(Environment.CurrentDirectory, "sharp_rss.db")};";
internal DatabaseService()
{
_sqlConn = new SqliteConnection(_connectionString);
InitializeDb();
}
private readonly SqliteConnection _sqlConn;
private readonly string _connectionString = $"Data Source={Path.Combine(Environment.CurrentDirectory, "sharp_rss.sqlite")};";
private readonly string _groupTable = "group_data";
private readonly string _feedTable = "feed_data";
private readonly string _feedItemTable = "feed_item_data";
public async Task<bool> AddCategoriesAsync(HashSet<CategoryModel> categories)
public async Task RemoveGroupFromFeedsAsync(string groupId)
{
await _sqlConn.QueryAsync("UPDATE feed_data SET group_id=NULL WHERE group_id=@GroupId", new { GroupId = groupId });
}
public async Task<bool> AddCategoriesAsync(HashSet<GroupModel> categories)
{
bool result = true;
_sqlConn.Open();
foreach (var categoryModel in categories)
{
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.PathIcon, categoryId = categoryModel.CategoryId });
new { catName = categoryModel.Name, hexColor = categoryModel.HexColor, pathIcon = categoryModel.Icon, categoryId = categoryModel.Id });
}
_sqlConn.Close();
return result;
@ -46,15 +53,18 @@ namespace SharpRss.Services
return result;
}
public async Task<HashSet<CategoryModel>> GetCategoriesAsync()
public async Task<HashSet<GroupModel>> GetCategoriesAsync()
{
HashSet<CategoryModel> categories = new HashSet<CategoryModel>();
HashSet<GroupModel> categories = new HashSet<GroupModel>();
_sqlConn.Open();
SqliteCommand cmd = _sqlConn.CreateCommand();
cmd.CommandText = "SELECT * FROM category_data";
await using SqliteDataReader reader = await cmd.ExecuteReaderAsync();
while (reader.Read())
categories.Add(CategoryModel.Create(reader["name"].ToString(), reader["hex_color"].ToString(), reader["category_id"].ToString()));
{
//categories.Add(GroupModel.Create(reader["name"].ToString(), reader["hex_color"].ToString(), reader["category_id"].ToString()));
}
_sqlConn.Close();
return categories;
}
@ -71,7 +81,9 @@ namespace SharpRss.Services
await using SqliteDataReader reader = await cmd.ExecuteReaderAsync();
while (reader.Read())
feeds.Add(FeedModel.Create(reader["url"].ToString(), reader["feed_id"].ToString(), reader["category_id"].ToString()));
{
//feeds.Add(FeedModel.Create(reader["url"].ToString(), reader["feed_id"].ToString(), reader["category_id"].ToString()));
}
_sqlConn.Close();
return feeds;
}
@ -81,14 +93,18 @@ namespace SharpRss.Services
Log.Verbose("Checking database...");
HashSet<string> failed = new HashSet<string>();
_sqlConn.Open();
// Check category_data table
var queryResponse = await _sqlConn.QueryAsync("CREATE TABLE IF NOT EXISTS category_data (name STRING NOT NULL, hex_color STRING NOT NULL, path_icon STRING, category_id STRING PRIMARY KEY, CONSTRAINT name UNIQUE (name))");
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))");
if (queryResponse.Any()) failed.Add("category_data");
// Check feed_data table
queryResponse = await _sqlConn.QueryAsync("CREATE TABLE IF NOT EXISTS feed_data (url STRING NOT NULL, feed_id STRING PRIMARY KEY, category_id STRING NOT NULL DEFAULT '', CONSTRAINT url, UNIQUE (url))");
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))");
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)");
if (queryResponse.Any()) failed.Add("feed_item_data");
_sqlConn.Close();
if (failed.Any())
{

View File

@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
@ -18,7 +19,7 @@ namespace SharpRss.Services
}
private readonly DatabaseService _dbService = new DatabaseService();
private async void SetupTestCategoriesAndFeedsAsync()
/*private async void SetupTestCategoriesAndFeedsAsync()
{
await _dbService.AddCategoriesAsync(new HashSet<CategoryModel>()
{
@ -34,56 +35,58 @@ namespace SharpRss.Services
new FeedModel("https://journals.plos.org/plosone/feed/atom"),
new FeedModel("https://itsfoss.com/feed")
});
}
}*/
public async Task<Feed> GetFeedAsync(string rssUrl)
{
return await FeedCache.GetFeed(rssUrl);
/*return await FeedCache.GetFeed(rssUrl);*/
return new Feed();
}
public async Task<HashSet<object>> GetAllUnsortedAsync()
{
HashSet<object> items = new HashSet<object>();
var categories = await _dbService.GetCategoriesAsync();
/*var categories = await _dbService.GetCategoriesAsync();
var feeds = await _dbService.GetFeedsAsync(string.Empty);
items.UnionWith(categories);
items.UnionWith(feeds);
items.UnionWith(feeds);*/
return items;
}
public async Task<HashSet<CategoryModel>> GetCategoriesAsync()
public async Task<HashSet<GroupModel>> GetCategoriesAsync()
{
var result = await _dbService.GetCategoriesAsync();
return result.OrderBy(x => x.Name).ToHashSet();
/*var result = await _dbService.GetCategoriesAsync();
return result.OrderBy(x => x.Name).ToHashSet();*/
return new HashSet<GroupModel>();
}
public async Task<HashSet<FeedModel>> GetFeedsAsync(CategoryModel? categoryModel = null)
public async Task<HashSet<FeedModel>> GetFeedsAsync(GroupModel? categoryModel = null)
{
HashSet<FeedModel> feeds;
if (categoryModel != null)
feeds = await _dbService.GetFeedsAsync(categoryModel.CategoryId);
HashSet<FeedModel> feeds = new HashSet<FeedModel>();
/*if (categoryModel != null)
feeds = await _dbService.GetFeedsAsync(categoryModel.Id);
else
feeds = await _dbService.GetFeedsAsync();
feeds = await _dbService.GetFeedsAsync();*/
return feeds;
}
public async void AddCategoryAsync(string name, string? icon, string hexColor)
{
CategoryModel categoryModel = new CategoryModel()
/*GroupModel groupModel = new GroupModel()
{
Name = name
};
if (icon != null)
categoryModel.PathIcon = icon;
groupModel.PathIcon = icon;
if (!hexColor.IsNullEmptyWhiteSpace())
categoryModel.HexColor = hexColor;
await _dbService.AddCategoriesAsync(new HashSet<CategoryModel>() { categoryModel });
groupModel.HexColor = hexColor;*/
//await _dbService.AddCategoriesAsync(new HashSet<GroupModel>() { groupModel });
}
public async void AddFeedAsync(string rssUrl, CategoryModel? category = null)
public async void AddFeedAsync(string rssUrl, GroupModel? category = null)
{
FeedModel feedModel = new FeedModel(rssUrl, category);
await _dbService.AddFeedsAsync(new HashSet<FeedModel>() { feedModel });
//FeedModel feedModel = new FeedModel(rssUrl, category);
//await _dbService.AddFeedsAsync(new HashSet<FeedModel>() { feedModel });
}
public void Dispose()

@ -1 +1 @@
Subproject commit af3abae0445b30c3ef58579a18e6e179eaea5986
Subproject commit b2a5173c7ffc21e83eb02c96b6e70434d7396d58

View File

@ -3,8 +3,10 @@ using System.IO;
using Serilog;
using Serilog.Formatting.Json;
using Serilog.Sinks.SystemConsole.Themes;
using SharpRss.Models;
using ToolQit;
using ToolQit.Containers;
using WebSharpRSS.Models;
namespace WebSharpRSS
{

View File

@ -1,19 +1,11 @@
using CodeHollow.FeedReader;
using SharpRss.Models;
using SharpRss.Models;
using ToolQit;
namespace WebSharpRSS.Models
{
public class FeedItemData
public class FeedItemData : FeedItemModel
{
public FeedItemData(FeedItem feedItem)
{
FeedItem = feedItem;
}
public FeedModel FeedModel { get; set; }
public FeedItem FeedItem { get; set; }
public string? Icon {get; set; }
public string? FaviconUrl { get; set; }
public string? CategoryColorHex { get; set; }
public bool Read { get; set; }
public static FeedItemData? FromModel(FeedItemModel model) => Utilities.ConvertFrom<FeedItemData, FeedItemModel>(model);
public string HexColor { get; set; }
}
}

View File

@ -12,7 +12,7 @@ namespace WebSharpRSS.Models
{
public class TreeItemData
{
public TreeItemData(CategoryModel catModel, RssService rssService)
public TreeItemData(GroupModel catModel, RssService rssService)
{
_service = rssService;
CategoryModel = catModel;
@ -28,7 +28,7 @@ namespace WebSharpRSS.Models
}
private readonly RssService _service;
public readonly CategoryModel? CategoryModel;
public readonly GroupModel? CategoryModel;
public readonly FeedModel? FeedModel;
private HashSet<FeedModel> _feedModels;
@ -69,16 +69,16 @@ namespace WebSharpRSS.Models
{
Title = CategoryModel.Name;
Icon = Icons.Material.Filled.Category;
_feedModels = await _service.GetFeedsAsync(CategoryModel);
/*_feedModels = await _service.GetFeedsAsync(CategoryModel);
if (_feedModels.Any())
Feeds = _feedModels.Select(x => new TreeItemData(x, _service)).OrderBy(x => x.Title).ToHashSet();
Feeds = _feedModels.Select(x => new TreeItemData(x, _service)).OrderBy(x => x.Title).ToHashSet();*/
}
if (FeedModel != null)
{
try
{
Feed = await _service.GetFeedAsync(FeedModel.FeedUrl);
//Feed = await _service.GetFeedAsync(FeedModel.FeedUrl);
}
catch (Exception e)
{

View File

@ -7,7 +7,7 @@
@inject FeedStateContainer _stateContainer;
<MudStack Spacing="2" Class="ml-2 mr-2">
@foreach (var feedItemData in _itemDatas)
@*@foreach (var feedItemData in _itemDatas)
{
<MudItem>
<MudCard>
@ -28,7 +28,7 @@
</MudCardContent>
</MudCard>
</MudItem>
}
}*@
</MudStack>
@code {
@ -42,11 +42,12 @@
UpdateFeeds();
InvokeAsync(StateHasChanged);
}
private HashSet<FeedItemData> _itemDatas = new HashSet<FeedItemData>();
private TreeItemData? _treeItemData;
//private HashSet<FeedItemData> _itemDatas = new HashSet<FeedItemData>();
//private TreeItemData? _treeItemData;
private void UpdateFeeds()
{
if (_stateContainer.TreeItem == null) return;
/*if (_stateContainer.TreeItem == null) return;
_treeItemData = _stateContainer.TreeItem;
if (_treeItemData.Feed != null)
{
@ -62,6 +63,6 @@
items.UnionWith(treeItem.Feed.Items.Select(x => new FeedItemData(x) { Icon = treeItem.Icon, FaviconUrl = treeItem.FaviconUrl, CategoryColorHex = _treeItemData.CategoryModel?.HexColor }));
_itemDatas = items.OrderBy(x => x.FeedItem.PublishingDate).Reverse().ToHashSet();
}
}
}*/
}
}

View File

@ -6,13 +6,12 @@
@using WebSharpRSS.Models;
@using ToolQit.Extensions;
@inject NavigationManager _navManager;
@inject FeedStateContainer _stateContainer;
@inject RssService _rssService
<MudStack Spacing="2">
<MudTreeView Items="_guideItems" @bind-SelectedValue="SelectedItem" Hover="true">
<ItemTemplate>
@*<ItemTemplate>
<MudTreeViewItem @bind-Expanded="@context.IsExpanded" Items="@context.Feeds" Value="@context" CanExpand="@context.HasChild" @onclick="ItemClicked">
<Content>
<div style="display: grid; grid-template-columns: 1fr auto; align-items: center; width: 100%">
@ -34,7 +33,7 @@
</div>
</Content>
</MudTreeViewItem>
</ItemTemplate>
</ItemTemplate>*@
</MudTreeView>
</MudStack>
@ -59,8 +58,8 @@
protected override async void OnInitialized()
{
Log.Verbose("Loading guide data...");
HashSet<object> items = await _rssService.GetAllUnsortedAsync();
_guideItems.UnionWith(items.Select(x => x is CategoryModel model ? new TreeItemData(model, _rssService) : x is FeedModel feedModel ? new TreeItemData(feedModel, _rssService) : throw new ArgumentException("Arg x is invalid!")));
/*HashSet<object> items = await _rssService.GetAllUnsortedAsync();
_guideItems.UnionWith(items.Select(x => x is CategoryModel model ? new TreeItemData(model, _rssService) : x is FeedModel feedModel ? new TreeItemData(feedModel, _rssService) : throw new ArgumentException("Arg x is invalid!")));*/
StateHasChanged();
Log.Verbose("Guide initialized!");

View File

@ -5,6 +5,7 @@
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<LangVersion>10</LangVersion>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>