diff --git a/ErsatzTV.Application/Troubleshooting/Commands/ArchiveMediaSampleHandler.cs b/ErsatzTV.Application/Troubleshooting/Commands/ArchiveMediaSampleHandler.cs index 75fe7034a..3850aee40 100644 --- a/ErsatzTV.Application/Troubleshooting/Commands/ArchiveMediaSampleHandler.cs +++ b/ErsatzTV.Application/Troubleshooting/Commands/ArchiveMediaSampleHandler.cs @@ -26,6 +26,8 @@ public class ArchiveMediaSampleHandler( embyPathReplacementService, fileSystem), IRequestHandler> { + private readonly IFileSystem _fileSystem = fileSystem; + public async Task> Handle(ArchiveMediaSample request, CancellationToken cancellationToken) { await using TvContext dbContext = await dbContextFactory.CreateDbContextAsync(cancellationToken); @@ -57,9 +59,10 @@ public class ArchiveMediaSampleHandler( string mediaSample, CancellationToken cancellationToken) { + string tempFile = Path.GetTempFileName(); + try { - string tempFile = Path.GetTempFileName(); await using ZipArchive zipArchive = await ZipFile.OpenAsync( tempFile, ZipArchiveMode.Update, @@ -73,6 +76,7 @@ public class ArchiveMediaSampleHandler( catch (Exception ex) { logger.LogWarning(ex, "Failed to archive media sample for media item {MediaItemId}", request.MediaItemId); + _fileSystem.File.Delete(tempFile); } return Option.None; @@ -88,6 +92,14 @@ public class ArchiveMediaSampleHandler( try { string mediaItemPath = await GetMediaItemPath(dbContext, mediaItem, cancellationToken); + if (string.IsNullOrEmpty(mediaItemPath)) + { + logger.LogWarning( + "Media item {MediaItemId} does not exist on disk; cannot extract media sample.", + mediaItem.Id); + + return Option.None; + } string extension = Path.GetExtension(mediaItemPath); if (string.IsNullOrWhiteSpace(extension)) diff --git a/ErsatzTV.Application/Troubleshooting/Commands/TroubleshootingHandlerBase.cs b/ErsatzTV.Application/Troubleshooting/Commands/TroubleshootingHandlerBase.cs index e41317c26..e4d0e2c6c 100644 --- a/ErsatzTV.Application/Troubleshooting/Commands/TroubleshootingHandlerBase.cs +++ b/ErsatzTV.Application/Troubleshooting/Commands/TroubleshootingHandlerBase.cs @@ -76,6 +76,7 @@ public abstract class TroubleshootingHandlerBase( .Include(mi => (mi as RemoteStream).MediaVersions) .ThenInclude(mv => mv.Streams) .Include(mi => (mi as RemoteStream).RemoteStreamMetadata) + .AsSplitQuery() .SingleOrDefaultAsync(mi => mi.Id == mediaItemId, cancellationToken) .Map(Optional) .Map(o => o.ToValidation(new UnableToLocatePlayoutItem())); diff --git a/ErsatzTV/Controllers/Api/TroubleshootController.cs b/ErsatzTV/Controllers/Api/TroubleshootController.cs index 5ab03322a..8eabe6a0b 100644 --- a/ErsatzTV/Controllers/Api/TroubleshootController.cs +++ b/ErsatzTV/Controllers/Api/TroubleshootController.cs @@ -164,7 +164,13 @@ public class TroubleshootController( Option maybeArchivePath = await mediator.Send(new ArchiveTroubleshootingResults(), cancellationToken); foreach (string archivePath in maybeArchivePath) { - FileStream fs = System.IO.File.OpenRead(archivePath); + var fs = new FileStream( + archivePath, + FileMode.Open, + FileAccess.Read, + FileShare.Read, + 4096, + FileOptions.DeleteOnClose); return File( fs, "application/zip", @@ -181,7 +187,13 @@ public class TroubleshootController( Option maybeArchivePath = await mediator.Send(new ArchiveMediaSample(mediaItemId), cancellationToken); foreach (string archivePath in maybeArchivePath) { - FileStream fs = System.IO.File.OpenRead(archivePath); + var fs = new FileStream( + archivePath, + FileMode.Open, + FileAccess.Read, + FileShare.Read, + 4096, + FileOptions.DeleteOnClose); return File( fs, "application/zip",