diff --git a/backend/src/TeleWave.Api/Endpoints/ChannelEndpoints.cs b/backend/src/TeleWave.Api/Endpoints/ChannelEndpoints.cs index a38d96a..6a3376c 100644 --- a/backend/src/TeleWave.Api/Endpoints/ChannelEndpoints.cs +++ b/backend/src/TeleWave.Api/Endpoints/ChannelEndpoints.cs @@ -9,6 +9,8 @@ using TeleWave.Application.Broadcast.UpdateChannelSettings; using TeleWave.Application.Broadcast.UpdateChannelTime; using TeleWave.Domain.Broadcast; using TeleWave.Infrastructure.Identity; +using TeleWave.Application.Broadcast.UpdateViewerSettings; +using TeleWave.Application.Programming.Planning.Trace; namespace TeleWave.Api.Endpoints; @@ -92,10 +94,47 @@ public static partial class ChannelEndpoints admin .MapGet("/{id:guid}/schedule", GetSchedule) .Produces>(); + admin + .MapPut("/{id:guid}/viewer", UpdateViewerSettings) + .Produces(StatusCodes.Status204NoContent); + + // «Почему это здесь»: цепочка происхождения записи, записанная в момент генерации. + admin.MapGet("/entries/{entryId:guid}/trace", GetEntryTrace).Produces(); return app; } + private static async Task UpdateViewerSettings( + Guid id, + UpdateViewerSettingsBody body, + ISender sender, + CancellationToken cancellationToken + ) + { + var result = await sender.Send( + new UpdateViewerSettingsCommand( + id, + body.LogoImageId, + body.LogoCorner, + body.LogoOpacity, + body.ShowClock, + body.AnalogFilterStrength + ), + cancellationToken + ); + return result.ToHttpResult(); + } + + private static async Task GetEntryTrace( + Guid entryId, + ISender sender, + CancellationToken cancellationToken + ) + { + var result = await sender.Send(new GetEntryTraceQuery(entryId), cancellationToken); + return result.ToHttpResult(); + } + private static async Task CreateChannel( CreateChannelCommand command, ISender sender, @@ -203,3 +242,12 @@ public sealed record UpdateChannelSettingsBody( BumperSettingsInput Bumper, Guid? FillerAssetId ); + +/// Оверлеи и аналоговый фильтр — как канал выглядит у зрителя (см. 6.8). +public sealed record UpdateViewerSettingsBody( + Guid? LogoImageId, + LogoCorner LogoCorner, + double LogoOpacity, + bool ShowClock, + double AnalogFilterStrength +); diff --git a/backend/src/TeleWave.Api/Endpoints/SettingsEndpoints.cs b/backend/src/TeleWave.Api/Endpoints/SettingsEndpoints.cs index d52763f..d26bb62 100644 --- a/backend/src/TeleWave.Api/Endpoints/SettingsEndpoints.cs +++ b/backend/src/TeleWave.Api/Endpoints/SettingsEndpoints.cs @@ -1,53 +1,55 @@ -using LiteCqrs; -using TeleWave.Api.Common; -using TeleWave.Application.Settings; -using TeleWave.Application.Settings.GetSiteSettings; -using TeleWave.Application.Settings.UpdateSiteSettings; -using TeleWave.Infrastructure.Identity; - -namespace TeleWave.Api.Endpoints; - -public static class SettingsEndpoints -{ - public static IEndpointRouteBuilder MapSettingsEndpoints(this IEndpointRouteBuilder app) - { - var admin = app.MapGroup("/api/admin/settings") - .WithTags("Admin.Settings") - .RequireAuthorization(policy => policy.RequireRole(RoleNames.Admin)); - - admin.MapGet("", GetSettings).Produces(); - admin.MapPut("", UpdateSettings).Produces(StatusCodes.Status204NoContent); - - return app; - } - - private static async Task GetSettings( - ISender sender, - CancellationToken cancellationToken - ) - { - var settings = await sender.Send(new GetSiteSettingsQuery(), cancellationToken); - return Results.Ok(settings); - } - - private static async Task UpdateSettings( - UpdateSiteSettingsBody body, - ISender sender, - CancellationToken cancellationToken - ) - { - var result = await sender.Send( - new UpdateSiteSettingsCommand( - body.RegistrationEnabled, - body.PreferredAudioLanguages ?? "" - ), - cancellationToken - ); - return result.ToHttpResult(); - } -} - -public sealed record UpdateSiteSettingsBody( - bool RegistrationEnabled, - string? PreferredAudioLanguages -); +using LiteCqrs; +using TeleWave.Api.Common; +using TeleWave.Application.Settings; +using TeleWave.Application.Settings.GetSiteSettings; +using TeleWave.Application.Settings.UpdateSiteSettings; +using TeleWave.Infrastructure.Identity; + +namespace TeleWave.Api.Endpoints; + +public static class SettingsEndpoints +{ + public static IEndpointRouteBuilder MapSettingsEndpoints(this IEndpointRouteBuilder app) + { + var admin = app.MapGroup("/api/admin/settings") + .WithTags("Admin.Settings") + .RequireAuthorization(policy => policy.RequireRole(RoleNames.Admin)); + + admin.MapGet("", GetSettings).Produces(); + admin.MapPut("", UpdateSettings).Produces(StatusCodes.Status204NoContent); + + return app; + } + + private static async Task GetSettings( + ISender sender, + CancellationToken cancellationToken + ) + { + var settings = await sender.Send(new GetSiteSettingsQuery(), cancellationToken); + return Results.Ok(settings); + } + + private static async Task UpdateSettings( + UpdateSiteSettingsBody body, + ISender sender, + CancellationToken cancellationToken + ) + { + var result = await sender.Send( + new UpdateSiteSettingsCommand( + body.RegistrationEnabled, + body.PreferredAudioLanguages ?? "", + body.ChannelNumbersEnabled + ), + cancellationToken + ); + return result.ToHttpResult(); + } +} + +public sealed record UpdateSiteSettingsBody( + bool RegistrationEnabled, + string? PreferredAudioLanguages, + bool ChannelNumbersEnabled +); diff --git a/backend/src/TeleWave.Api/Endpoints/StreamingEndpoints.cs b/backend/src/TeleWave.Api/Endpoints/StreamingEndpoints.cs index aff5998..64759c3 100644 --- a/backend/src/TeleWave.Api/Endpoints/StreamingEndpoints.cs +++ b/backend/src/TeleWave.Api/Endpoints/StreamingEndpoints.cs @@ -1,184 +1,197 @@ -using System.Globalization; -using System.Text; -using System.Text.RegularExpressions; -using LiteCqrs; -using Microsoft.Extensions.Hosting; -using TeleWave.Api.Common; -using TeleWave.Application.Common.Interfaces; -using TeleWave.Application.Streaming; -using TeleWave.Application.Streaming.GetLivePlaylist; -using TeleWave.Application.Streaming.GetPublicEpg; -using TeleWave.Application.Streaming.ListPublicChannels; -using TeleWave.Infrastructure.Media; -using TeleWave.Infrastructure.Streaming; - -namespace TeleWave.Api.Endpoints; - -public static class StreamingEndpoints -{ - private const string StreamCookieName = "tw_stream"; - private static readonly Regex SegmentFileName = new(@"^seg\d{1,6}\.ts$", RegexOptions.Compiled); - - public static IEndpointRouteBuilder MapStreamingEndpoints(this IEndpointRouteBuilder app) - { - // Публичный API канала (Bearer): список, EPG, выдача stream-cookie. - var channels = app.MapGroup("/api/channels").WithTags("Channels").RequireAuthorization(); - channels.MapGet("", ListChannels).Produces>(); - channels.MapPost("/{slug}/watch", Watch).Produces(StatusCodes.Status204NoContent); - channels.MapGet("/{slug}/epg", Epg); - - // Раздача эфира (cookie tw_stream): плейлист и сегменты — их грузит