diff --git a/CHANGELOG.md b/CHANGELOG.md index e8725d350..16ed4c581 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - This fixes potential UI hangs and database concurrency bugs - Maintain watermark alpha channel (built-in transparency) using QSV acceleration - Properly extract and burn in embedded text subtitles using Jellyfin, Emby and Plex libraries +- Fix bug where deleting a channel would not remove its data from XMLTV ### Changed - Remove duplicate items from smart collections before scheduling diff --git a/ErsatzTV.Application/Channels/Commands/DeleteChannelHandler.cs b/ErsatzTV.Application/Channels/Commands/DeleteChannelHandler.cs index fbb13998f..7df959878 100644 --- a/ErsatzTV.Application/Channels/Commands/DeleteChannelHandler.cs +++ b/ErsatzTV.Application/Channels/Commands/DeleteChannelHandler.cs @@ -1,5 +1,8 @@ -using ErsatzTV.Core; +using System.Threading; +using System.Threading.Channels; +using ErsatzTV.Core; using ErsatzTV.Core.Domain; +using ErsatzTV.Core.Interfaces.Metadata; using ErsatzTV.Infrastructure.Data; using ErsatzTV.Infrastructure.Extensions; using Microsoft.EntityFrameworkCore; @@ -8,31 +11,49 @@ namespace ErsatzTV.Application.Channels; public class DeleteChannelHandler : IRequestHandler> { + private readonly ChannelWriter _workerChannel; private readonly IDbContextFactory _dbContextFactory; + private readonly ILocalFileSystem _localFileSystem; - public DeleteChannelHandler(IDbContextFactory dbContextFactory) + public DeleteChannelHandler( + ChannelWriter workerChannel, + IDbContextFactory dbContextFactory, + ILocalFileSystem localFileSystem) { + _workerChannel = workerChannel; _dbContextFactory = dbContextFactory; + _localFileSystem = localFileSystem; } public async Task> Handle(DeleteChannel request, CancellationToken cancellationToken) { await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken); - Validation validation = await ChannelMustExist(dbContext, request); - return await validation.Apply(c => DoDeletion(dbContext, c)); + Validation validation = await ChannelMustExist(dbContext, request); + + return await validation.Apply(c => DoDeletion(dbContext, c, cancellationToken)); } - private static async Task DoDeletion(TvContext dbContext, Channel channel) + private async Task DoDeletion(TvContext dbContext, Core.Domain.Channel channel, CancellationToken cancellationToken) { dbContext.Channels.Remove(channel); await dbContext.SaveChangesAsync(); - + + // delete channel data from channel guide cache + string cacheFile = Path.Combine(FileSystemLayout.ChannelGuideCacheFolder, $"{channel.Number}.xml"); + if (_localFileSystem.FileExists(cacheFile)) + { + File.Delete(cacheFile); + } + + // refresh channel list to remove channel that has no playout + await _workerChannel.WriteAsync(new RefreshChannelList(), cancellationToken); + return Unit.Default; } - private static async Task> ChannelMustExist(TvContext dbContext, DeleteChannel deleteChannel) + private static async Task> ChannelMustExist(TvContext dbContext, DeleteChannel deleteChannel) { - Option maybeChannel = await dbContext.Channels + Option maybeChannel = await dbContext.Channels .SelectOneAsync(c => c.Id, c => c.Id == deleteChannel.ChannelId); return maybeChannel.ToValidation($"Channel {deleteChannel.ChannelId} does not exist."); }