diff --git a/SharpRSS.sln b/SharpRSS.sln index 7d57dc9..f26a4d9 100644 --- a/SharpRSS.sln +++ b/SharpRSS.sln @@ -9,6 +9,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SharpRss", "SharpRss\SharpR EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ToolQit", "ToolQit\ToolQit\ToolQit.csproj", "{BD905344-9DBF-4986-B853-E70B22848876}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpSyndicationApi", "SharpSyndicationApi\SharpSyndicationApi.csproj", "{349033BA-F5C3-4CDB-AFEA-9E85711FFBD5}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -27,6 +29,10 @@ Global {BD905344-9DBF-4986-B853-E70B22848876}.Debug|Any CPU.Build.0 = Debug|Any CPU {BD905344-9DBF-4986-B853-E70B22848876}.Release|Any CPU.ActiveCfg = Release|Any CPU {BD905344-9DBF-4986-B853-E70B22848876}.Release|Any CPU.Build.0 = Release|Any CPU + {349033BA-F5C3-4CDB-AFEA-9E85711FFBD5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {349033BA-F5C3-4CDB-AFEA-9E85711FFBD5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {349033BA-F5C3-4CDB-AFEA-9E85711FFBD5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {349033BA-F5C3-4CDB-AFEA-9E85711FFBD5}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/SharpRss/Core/IDbAccess.cs b/SharpRss/Core/IDbAccess.cs index cb49276..4ec7849 100644 --- a/SharpRss/Core/IDbAccess.cs +++ b/SharpRss/Core/IDbAccess.cs @@ -1,6 +1,11 @@ namespace SharpRss.Core { + public struct DbState + { + + } + // Interface for implementing the database endpoints. public interface IDbAccess { diff --git a/SharpRss/DbAccess.cs b/SharpRss/DbAccess.cs index c2dec7d..d5b9b82 100644 --- a/SharpRss/DbAccess.cs +++ b/SharpRss/DbAccess.cs @@ -12,6 +12,13 @@ using SharpRss.Models; namespace SharpRss { + public class ItemFetchState + { + public string[]? SyndicationUrls { get; internal set; } + public int TakeAmount { get; internal set; } = 20; + public int TakenCount { get; internal set; } + public HashSet Items { get; internal set; } = new HashSet(); + } internal static class DbAccess { private static readonly string ConnectionString = $"Data Source={Path.Combine(Environment.CurrentDirectory, "sharp_rss.sqlite")};"; @@ -198,14 +205,16 @@ namespace SharpRss } dbTransaction.Commit(); } + - public static async Task> GetSyndicationItemsAsync(string[]? encodedSyndicationUrls) + + public static async Task GetSyndicationItemsAsync(ItemFetchState state) { await using SqliteConnection dbc = new SqliteConnection(ConnectionString); dbc.Open(); HashSet items = new HashSet(); await TempCache.UpdateCache(CacheFetch.Syndication); - await using DbDataReader reader = await dbc.ExecuteReaderAsync(encodedSyndicationUrls == null ? "SELECT * FROM syndication_item" : $"SELECT * FROM syndication_item WHERE encoded_syndication_url IN({FormatParametersFromArray(encodedSyndicationUrls)})"); + await using DbDataReader reader = await dbc.ExecuteReaderAsync(state.SyndicationUrls == null ? "SELECT * FROM syndication_item" : $"SELECT * FROM syndication_item WHERE encoded_syndication_url IN({FormatParametersFromArray(state.SyndicationUrls)})"); //NOTE(dbg): While debugging this part of the function the code below (Reader.ReadAsync) will return 0, because the debugger already reads the items from the reader. while (await reader.ReadAsync()) { @@ -229,7 +238,8 @@ namespace SharpRss items.Add(syndicationItemModel); } Log.Information("Fetching feed items resulted: {ItemCount} item(s)", items.Count); - return items; + state.Items = items; + return true; } public static async void Initialize() { diff --git a/SharpRss/FetchState.cs b/SharpRss/FetchState.cs deleted file mode 100644 index 2fe408c..0000000 --- a/SharpRss/FetchState.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; - -namespace SharpRss -{ - // To keep a state at fetching item from the database. - public class FetchState - { - public int TakeAmount { get; set; } = 20; - public int TotalFetched { get; internal set; } - public string DbTableName { get; internal set; } = string.Empty; - public DateTime LastFetchTime { get; internal set; } - } -} \ No newline at end of file diff --git a/SharpRss/Services/SyndicationService.cs b/SharpRss/Services/SyndicationService.cs index 1d663a9..421c751 100644 --- a/SharpRss/Services/SyndicationService.cs +++ b/SharpRss/Services/SyndicationService.cs @@ -72,8 +72,9 @@ namespace SharpRss.Services public async Task> GetSyndicationItemsAsync(string feedId, string? groupId = null) => await GetSyndicationItemsFromSyndicationsAsync(new[] { feedId }, groupId); public async Task> GetSyndicationItemsFromSyndicationsAsync(string[] feedIds, string? categoryId = null) { - var items = await DbAccess.GetSyndicationItemsAsync(feedIds); - return items; + /*var items = await DbAccess.GetSyndicationItemsAsync(feedIds); + return items;*/ + return new HashSet(); } diff --git a/SharpSyndicationApi/Controllers/CategoryController.cs b/SharpSyndicationApi/Controllers/CategoryController.cs new file mode 100644 index 0000000..cfd10c0 --- /dev/null +++ b/SharpSyndicationApi/Controllers/CategoryController.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using SharpSyndicationApi.Models; + +namespace SharpSyndicationApi.Controllers +{ + [Route("api/[controller]")] + [ApiController] + public class CategoryController : ControllerBase + { + private readonly DataContext _context; + + public CategoryController(DataContext context) + { + _context = context; + } + + [HttpPost] + public async Task PostCategory(Category category) + { + _context.Categories.Add(category); + await _context.SaveChangesAsync(); + } + + [HttpGet] + [ProducesResponseType(200, Type = typeof(IEnumerable))] + public ActionResult> GetCategories() + { + IEnumerable categories = _context.Categories.ToList(); + if (categories == null || !categories.Any()) + return NotFound(); + return Ok(categories); + } + } +} diff --git a/SharpSyndicationApi/DataContext.cs b/SharpSyndicationApi/DataContext.cs new file mode 100644 index 0000000..06b1b03 --- /dev/null +++ b/SharpSyndicationApi/DataContext.cs @@ -0,0 +1,14 @@ +using Microsoft.EntityFrameworkCore; +using SharpSyndicationApi.Models; + +namespace SharpSyndicationApi +{ + public class DataContext : DbContext + { + public DataContext(DbContextOptions options) : base(options) + { + + } + public DbSet Categories { get; set; } + } +} \ No newline at end of file diff --git a/SharpSyndicationApi/Models/Category.cs b/SharpSyndicationApi/Models/Category.cs new file mode 100644 index 0000000..b608460 --- /dev/null +++ b/SharpSyndicationApi/Models/Category.cs @@ -0,0 +1,13 @@ +using System; + +namespace SharpSyndicationApi.Models +{ + public class Category + { + public string Name { get; set; } + public string Id { get; set; } + public string Icon { get; set; } + public string HexColor { get; set; } + public DateTime CreationDate { get; set; } + } +} \ No newline at end of file diff --git a/SharpSyndicationApi/Models/ContinuationToken.cs b/SharpSyndicationApi/Models/ContinuationToken.cs new file mode 100644 index 0000000..eb47417 --- /dev/null +++ b/SharpSyndicationApi/Models/ContinuationToken.cs @@ -0,0 +1,16 @@ +namespace SharpSyndicationApi.Models +{ + public class ContinuationToken + { + public int TakeAmount { get; set; } = 30; + public int TotalTaken { get; set; } + public ApiCallType ApiCall { get; set; } + } + + public enum ApiCallType + { + Category, + Syndication, + SyndicationItem + } +} \ No newline at end of file diff --git a/SharpSyndicationApi/Program.cs b/SharpSyndicationApi/Program.cs new file mode 100644 index 0000000..f46afe9 --- /dev/null +++ b/SharpSyndicationApi/Program.cs @@ -0,0 +1,32 @@ +using Microsoft.AspNetCore.Builder; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using SharpSyndicationApi; + +var builder = WebApplication.CreateBuilder(args); + +// Add services to the container. + +builder.Services.AddControllers(); +builder.Services.AddDbContext(opt => opt.UseInMemoryDatabase("sharprss")); +// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle +builder.Services.AddEndpointsApiExplorer(); +builder.Services.AddSwaggerGen(); + +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (app.Environment.IsDevelopment()) +{ + app.UseSwagger(); + app.UseSwaggerUI(); +} + +app.UseHttpsRedirection(); + +app.UseAuthorization(); + +app.MapControllers(); + +app.Run(); \ No newline at end of file diff --git a/SharpSyndicationApi/Properties/launchSettings.json b/SharpSyndicationApi/Properties/launchSettings.json new file mode 100644 index 0000000..d6ef3fc --- /dev/null +++ b/SharpSyndicationApi/Properties/launchSettings.json @@ -0,0 +1,41 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:42659", + "sslPort": 44369 + } + }, + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "http://localhost:5277", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "https://localhost:7119;http://localhost:5277", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/SharpSyndicationApi/SharpSyndicationApi.csproj b/SharpSyndicationApi/SharpSyndicationApi.csproj new file mode 100644 index 0000000..de639d3 --- /dev/null +++ b/SharpSyndicationApi/SharpSyndicationApi.csproj @@ -0,0 +1,28 @@ + + + + net7.0 + enable + enable + 10 + + + + + + + + + + + + + + + + + + + + + diff --git a/SharpSyndicationApi/appsettings.Development.json b/SharpSyndicationApi/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/SharpSyndicationApi/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/SharpSyndicationApi/appsettings.json b/SharpSyndicationApi/appsettings.json new file mode 100644 index 0000000..10f68b8 --- /dev/null +++ b/SharpSyndicationApi/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +}