diff --git a/CHANGELOG.md b/CHANGELOG.md index 14db28f2e..21303fe37 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,13 +6,26 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [Unreleased] ### Added - Attempt to release memory periodically -- Add SSO support via OIDC +- Add OpenID Connect (OIDC) support (e.g. Keycloak, Authelia, Auth0) - This only protects the management UI; all streaming endpoints will continue to allow anonymous access - This can be configured with the following env vars (note the double underscore separator `__`) - `OIDC__AUTHORITY` - `OIDC__CLIENTID` - `OIDC__CLIENTSECRET` - - `OIDC__LOGOUTURI` (optional, needed for Auth0) + - `OIDC__LOGOUTURI` (optional, needed for Auth0, use `https://{auth0-domain}/v2/logout?client_id={auth0-client-id}` with proper values for domain and client-id) +- Add *experimental* alternate schedule system + - This allows a single playout to dynamically select a schedule based on date criteria, for example: + - Weekday vs weekend schedules + - Summer vs fall schedules + - Shark week schedules + - Alternate schedules can be managed by clicking the calendar icon in the playout list + - Playouts contain a prioritized (top to bottom) list of alternate schedules + - Whenever a playout is built for a given day, ErsatzTV will check for a matching schedule from top to bottom + - A given day must match all alternate schedule parameters; wildcards (`*any*`) will always match + - Day of week + - Day of month + - Month + - The lowest priority (bottom) item will always match all parameters, and can be considered a "default" or "fallback" schedule ### Fixed - Fix schedule editor crashing due to bad music video artist data diff --git a/ErsatzTV/Controllers/Api/ChannelController.cs b/ErsatzTV/Controllers/Api/ChannelController.cs index f60f1f9c2..33e66c006 100644 --- a/ErsatzTV/Controllers/Api/ChannelController.cs +++ b/ErsatzTV/Controllers/Api/ChannelController.cs @@ -1,11 +1,13 @@ using ErsatzTV.Application.Channels; using ErsatzTV.Core.Api.Channels; +using ErsatzTV.Filters; using MediatR; using Microsoft.AspNetCore.Mvc; namespace ErsatzTV.Controllers.Api; [ApiController] +[V2ApiActionFilter] public class ChannelController { private readonly IMediator _mediator; diff --git a/ErsatzTV/Controllers/Api/FFmpegProfileController.cs b/ErsatzTV/Controllers/Api/FFmpegProfileController.cs index 21f14a521..f7742ee18 100644 --- a/ErsatzTV/Controllers/Api/FFmpegProfileController.cs +++ b/ErsatzTV/Controllers/Api/FFmpegProfileController.cs @@ -2,12 +2,14 @@ using ErsatzTV.Application.FFmpegProfiles; using ErsatzTV.Core; using ErsatzTV.Core.Api.FFmpegProfiles; +using ErsatzTV.Filters; using MediatR; using Microsoft.AspNetCore.Mvc; namespace ErsatzTV.Controllers.Api; [ApiController] +[V2ApiActionFilter] public class FFmpegProfileController { private readonly IMediator _mediator; @@ -28,10 +30,10 @@ public class FFmpegProfileController [Required] [FromBody] UpdateFFmpegProfile request) => await _mediator.Send(request); - [HttpGet("/api/ffmpeg/profiles/{id}")] + [HttpGet("/api/ffmpeg/profiles/{id:int}")] public async Task> GetOne(int id) => await _mediator.Send(new GetFFmpegFullProfileByIdForApi(id)); - [HttpDelete("/api/ffmpeg/delete/{id}")] + [HttpDelete("/api/ffmpeg/delete/{id:int}")] public async Task DeleteProfileAsync(int id) => await _mediator.Send(new DeleteFFmpegProfile(id)); } diff --git a/ErsatzTV/Filters/V2ApiActionFilter.cs b/ErsatzTV/Filters/V2ApiActionFilter.cs new file mode 100644 index 000000000..cf035b4ea --- /dev/null +++ b/ErsatzTV/Filters/V2ApiActionFilter.cs @@ -0,0 +1,18 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Filters; + +namespace ErsatzTV.Filters; + +public class V2ApiActionFilter : ActionFilterAttribute +{ + private static readonly Lazy UseV2Ui = + new(() => !string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("ETV_V2_UI"))); + + public override void OnActionExecuting(ActionExecutingContext context) + { + if (!UseV2Ui.Value) + { + context.Result = new NotFoundResult(); + } + } +} diff --git a/ErsatzTV/Services/SchedulerService.cs b/ErsatzTV/Services/SchedulerService.cs index 5d5c5bf07..70876d992 100644 --- a/ErsatzTV/Services/SchedulerService.cs +++ b/ErsatzTV/Services/SchedulerService.cs @@ -83,6 +83,11 @@ public class SchedulerService : BackgroundService // do other work every hour (on the hour) await DoWork(cancellationToken); } + else if (roundedMinute % 30 == 0) + { + // release memory every 30 minutes no matter what + await ReleaseMemory(cancellationToken); + } } } }