Addead Features configuration for RSS and Email Subscriptions
This commit is contained in:
parent
ef3c71e2ab
commit
5c78e5a391
|
@ -1,35 +1,34 @@
|
||||||
using System.Collections.ObjectModel;
|
using System.ServiceModel.Syndication;
|
||||||
using System.Linq;
|
|
||||||
using System.ServiceModel.Syndication;
|
|
||||||
using System.Xml;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.Mvc.Routing;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Microsoft.Net.Http.Headers;
|
|
||||||
using Wave.Data;
|
using Wave.Data;
|
||||||
using Wave.Data.Migrations.postgres;
|
|
||||||
|
|
||||||
namespace Wave.Controllers;
|
namespace Wave.Controllers;
|
||||||
|
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[Route("/[controller]")]
|
[Route("/[controller]")]
|
||||||
public class RssController(IOptions<Customization> customizations, ApplicationDbContext context) : ControllerBase {
|
public class RssController(IOptions<Customization> customizations, ApplicationDbContext context, IOptions<Features> features) : ControllerBase {
|
||||||
private ApplicationDbContext Context { get; } = context;
|
private ApplicationDbContext Context { get; } = context;
|
||||||
private IOptions<Customization> Customizations { get; } = customizations;
|
private IOptions<Customization> Customizations { get; } = customizations;
|
||||||
|
private IOptions<Features> Features { get; } = features;
|
||||||
|
|
||||||
[HttpGet("rss.xml", Name = "RssFeed")]
|
[HttpGet("rss.xml", Name = "RssFeed")]
|
||||||
[Produces("application/rss+xml")]
|
[Produces("application/rss+xml", "application/json")]
|
||||||
[ResponseCache(Duration = 60*15, Location = ResponseCacheLocation.Any)]
|
[ResponseCache(Duration = 60*15, Location = ResponseCacheLocation.Any)]
|
||||||
public async Task<IActionResult> GetRssFeedAsync(string? category = null) {
|
public async Task<IActionResult> GetRssFeedAsync(string? category = null) {
|
||||||
|
if (!Features.Value.Rss) return Unauthorized("RSS is disabled");
|
||||||
|
|
||||||
var feed = await CreateFeedAll("RssFeed", category);
|
var feed = await CreateFeedAll("RssFeed", category);
|
||||||
if (feed is null) return NotFound();
|
if (feed is null) return NotFound();
|
||||||
return Ok(feed);
|
return Ok(feed);
|
||||||
}
|
}
|
||||||
[HttpGet("atom.xml", Name = "AtomFeed")]
|
[HttpGet("atom.xml", Name = "AtomFeed")]
|
||||||
[Produces("application/atom+xml")]
|
[Produces("application/atom+xml", "application/json")]
|
||||||
[ResponseCache(Duration = 60*15, Location = ResponseCacheLocation.Any)]
|
[ResponseCache(Duration = 60*15, Location = ResponseCacheLocation.Any)]
|
||||||
public async Task<IActionResult> GetAtomFeedAsync(string? category = null) {
|
public async Task<IActionResult> GetAtomFeedAsync(string? category = null) {
|
||||||
|
if (!Features.Value.Rss) return Unauthorized("RSS is disabled");
|
||||||
|
|
||||||
var feed = await CreateFeedAll("AtomFeed", category);
|
var feed = await CreateFeedAll("AtomFeed", category);
|
||||||
if (feed is null) return NotFound();
|
if (feed is null) return NotFound();
|
||||||
return Ok(feed);
|
return Ok(feed);
|
||||||
|
|
6
Wave/Data/Features.cs
Normal file
6
Wave/Data/Features.cs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
namespace Wave.Data;
|
||||||
|
|
||||||
|
public class Features {
|
||||||
|
public bool Rss { get; set; } = true;
|
||||||
|
public bool EmailSubscriptions { get; set; } = false;
|
||||||
|
}
|
|
@ -112,6 +112,7 @@
|
||||||
builder.Services.AddScoped<ImageService>();
|
builder.Services.AddScoped<ImageService>();
|
||||||
builder.Services.AddHttpClient();
|
builder.Services.AddHttpClient();
|
||||||
|
|
||||||
|
builder.Services.Configure<Features>(builder.Configuration.GetSection(nameof(Features)));
|
||||||
builder.Services.Configure<Customization>(builder.Configuration.GetSection(nameof(Customization)));
|
builder.Services.Configure<Customization>(builder.Configuration.GetSection(nameof(Customization)));
|
||||||
builder.Services.AddCascadingValue("TitlePrefix",
|
builder.Services.AddCascadingValue("TitlePrefix",
|
||||||
sf => (sf.GetService<IOptions<Customization>>()?.Value.AppName ?? "Wave") + " - ");
|
sf => (sf.GetService<IOptions<Customization>>()?.Value.AppName ?? "Wave") + " - ");
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
using MailKit.Net.Smtp;
|
using MailKit.Net.Smtp;
|
||||||
using MailKit.Security;
|
using MailKit.Security;
|
||||||
using Microsoft.AspNetCore.Hosting.Server;
|
|
||||||
using Microsoft.AspNetCore.Hosting.Server.Features;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using MimeKit;
|
using MimeKit;
|
||||||
|
@ -11,15 +9,18 @@
|
||||||
|
|
||||||
namespace Wave.Services;
|
namespace Wave.Services;
|
||||||
|
|
||||||
public class EmailBackgroundWorker(ILogger<EmailBackgroundWorker> logger, IDbContextFactory<ApplicationDbContext> contextFactory, IOptions<SmtpConfiguration> config, IOptions<Customization> customizations) : IHostedService, IDisposable {
|
public class EmailBackgroundWorker(ILogger<EmailBackgroundWorker> logger, IDbContextFactory<ApplicationDbContext> contextFactory, IOptions<SmtpConfiguration> config, IOptions<Customization> customizations, IOptions<Features> features) : IHostedService, IDisposable {
|
||||||
private ILogger<EmailBackgroundWorker> Logger { get; } = logger;
|
private ILogger<EmailBackgroundWorker> Logger { get; } = logger;
|
||||||
private IDbContextFactory<ApplicationDbContext> ContextFactory { get; } = contextFactory;
|
private IDbContextFactory<ApplicationDbContext> ContextFactory { get; } = contextFactory;
|
||||||
private SmtpConfiguration Configuration { get; } = config.Value;
|
private SmtpConfiguration Configuration { get; } = config.Value;
|
||||||
private Customization Customizations { get; } = customizations.Value;
|
private Customization Customizations { get; } = customizations.Value;
|
||||||
|
private Features Features { get; } = features.Value;
|
||||||
|
|
||||||
private Timer? Timer { get; set; }
|
private Timer? Timer { get; set; }
|
||||||
|
|
||||||
public Task StartAsync(CancellationToken cancellationToken) {
|
public Task StartAsync(CancellationToken cancellationToken) {
|
||||||
|
if (!Features.EmailSubscriptions) return Task.CompletedTask;
|
||||||
|
|
||||||
Logger.LogInformation("Background email worker starting.");
|
Logger.LogInformation("Background email worker starting.");
|
||||||
|
|
||||||
// we want this timer to execute every 15 minutes, at fixed times (:00, :15, :30, :45)
|
// we want this timer to execute every 15 minutes, at fixed times (:00, :15, :30, :45)
|
||||||
|
@ -34,6 +35,8 @@ public class EmailBackgroundWorker(ILogger<EmailBackgroundWorker> logger, IDbCon
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task StopAsync(CancellationToken cancellationToken) {
|
public Task StopAsync(CancellationToken cancellationToken) {
|
||||||
|
if (!Features.EmailSubscriptions) return Task.CompletedTask;
|
||||||
|
|
||||||
Logger.LogInformation("Background email worker stopping.");
|
Logger.LogInformation("Background email worker stopping.");
|
||||||
Timer?.Change(Timeout.Infinite, 0);
|
Timer?.Change(Timeout.Infinite, 0);
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
|
@ -47,7 +50,6 @@ public class EmailBackgroundWorker(ILogger<EmailBackgroundWorker> logger, IDbCon
|
||||||
private void DoWork(object? _) {
|
private void DoWork(object? _) {
|
||||||
try {
|
try {
|
||||||
Logger.LogInformation("Checking Articles...");
|
Logger.LogInformation("Checking Articles...");
|
||||||
if (string.IsNullOrWhiteSpace(Configuration.SenderName)) return;
|
|
||||||
|
|
||||||
using var context = ContextFactory.CreateDbContext();
|
using var context = ContextFactory.CreateDbContext();
|
||||||
var now = DateTimeOffset.UtcNow;
|
var now = DateTimeOffset.UtcNow;
|
||||||
|
|
Loading…
Reference in a new issue