From 9375f31bd33f1174f70af84c5c110da17bc3ade0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 15 Jun 2026 16:28:58 +0000 Subject: [PATCH 1/3] Update dependency SharpCompress to 0.49.1 --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 6d2845d1e7..7ab5b5d53a 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -67,7 +67,7 @@ - + From f6bb086415988b144c4e944dae3292f9f0862d6b Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Mon, 15 Jun 2026 18:52:20 +0200 Subject: [PATCH 2/3] fix build errors --- .../ComicBookInfo/ComicBookInfoProvider.cs | 28 ++++++++------- .../Books/ComicImageProvider.cs | 34 +++++++++++++------ 2 files changed, 38 insertions(+), 24 deletions(-) diff --git a/MediaBrowser.Providers/Books/ComicBookInfo/ComicBookInfoProvider.cs b/MediaBrowser.Providers/Books/ComicBookInfo/ComicBookInfoProvider.cs index 4fcbb3ce40..787d2ad878 100644 --- a/MediaBrowser.Providers/Books/ComicBookInfo/ComicBookInfoProvider.cs +++ b/MediaBrowser.Providers/Books/ComicBookInfo/ComicBookInfoProvider.cs @@ -49,24 +49,26 @@ public class ComicBookInfoProvider : IComicProvider try { Stream stream = AsyncFile.OpenRead(path); - await using (stream.ConfigureAwait(false)) - await using (var archive = await ZipArchive.CreateAsync(stream, ZipArchiveMode.Read, false, null, cancellationToken).ConfigureAwait(false)) { - if (archive.Comment is null) + var archive = await ZipArchive.CreateAsync(stream, ZipArchiveMode.Read, false, null, cancellationToken).ConfigureAwait(false); + await using (archive.ConfigureAwait(false)) { - _logger.LogInformation("missing ComicBookInfo in archive comment: {Path}", info.Path); - return new MetadataResult { HasMetadata = false }; - } + if (archive.Comment is null) + { + _logger.LogInformation("missing ComicBookInfo in archive comment: {Path}", info.Path); + return new MetadataResult { HasMetadata = false }; + } - var comicBookMetadata = JsonSerializer.Deserialize(archive.Comment, JsonDefaults.Options); - if (comicBookMetadata is null) - { - _logger.LogError("ComicBookInfo deserialization failure: {Path}", info.Path); - return new MetadataResult { HasMetadata = false }; - } + var comicBookMetadata = JsonSerializer.Deserialize(archive.Comment, JsonDefaults.Options); + if (comicBookMetadata is null) + { + _logger.LogError("ComicBookInfo deserialization failure: {Path}", info.Path); + return new MetadataResult { HasMetadata = false }; + } - return SaveMetadata(comicBookMetadata); + return SaveMetadata(comicBookMetadata); + } } } catch (Exception ex) diff --git a/MediaBrowser.Providers/Books/ComicImageProvider.cs b/MediaBrowser.Providers/Books/ComicImageProvider.cs index 01ab22a520..2716d45637 100644 --- a/MediaBrowser.Providers/Books/ComicImageProvider.cs +++ b/MediaBrowser.Providers/Books/ComicImageProvider.cs @@ -9,6 +9,7 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Drawing; using MediaBrowser.Model.Entities; +using MediaBrowser.Model.IO; using Microsoft.Extensions.Logging; using SharpCompress.Archives; @@ -44,7 +45,7 @@ public class ComicImageProvider : IDynamicImageProvider if (_comicBookExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase)) { - return LoadCover(item); + return LoadCoverAsync(item, cancellationToken); } return Task.FromResult(new DynamicImageResponse { HasImage = false }); @@ -67,7 +68,8 @@ public class ComicImageProvider : IDynamicImageProvider /// with no image if nothing is found. /// /// Item to check for covers. - private async Task LoadCover(BaseItem item) + /// The cancellation token. + private async Task LoadCoverAsync(BaseItem item, CancellationToken cancellationToken) { var memoryStream = new MemoryStream(); @@ -75,14 +77,22 @@ public class ComicImageProvider : IDynamicImageProvider { ImageFormat imageFormat; - using (Stream stream = File.OpenRead(item.Path)) - using (var archive = ArchiveFactory.Open(stream)) + using (Stream stream = AsyncFile.OpenRead(item.Path)) { - // throw exception to log results if no cover is found - (var cover, imageFormat) = FindCoverEntryInArchive(archive) ?? throw new InvalidOperationException("no supported cover found"); + var archive = await ArchiveFactory.OpenAsyncArchive(stream, cancellationToken: cancellationToken).ConfigureAwait(false); + await using (archive.ConfigureAwait(false)) + { + // throw exception to log results if no cover is found + (var cover, imageFormat) = await FindCoverEntryInArchiveAsync(archive).ConfigureAwait(false) + ?? throw new InvalidOperationException("no supported cover found"); - // copy the cover to memory stream - await cover.OpenEntryStream().CopyToAsync(memoryStream).ConfigureAwait(false); + // copy the cover to memory stream + var coverStream = await cover.OpenEntryStreamAsync(cancellationToken).ConfigureAwait(false); + await using (coverStream.ConfigureAwait(false)) + { + await coverStream.CopyToAsync(memoryStream, cancellationToken).ConfigureAwait(false); + } + } } // reset stream position after copying @@ -102,7 +112,7 @@ public class ComicImageProvider : IDynamicImageProvider /// /// The archive to search. /// The search result. - private (IArchiveEntry CoverEntry, ImageFormat ImageFormat)? FindCoverEntryInArchive(IArchive archive) + private async ValueTask<(IArchiveEntry CoverEntry, ImageFormat ImageFormat)?> FindCoverEntryInArchiveAsync(IAsyncArchive archive) { IArchiveEntry? cover; @@ -110,7 +120,7 @@ public class ComicImageProvider : IDynamicImageProvider // in many cases the cover will simply be the first image in the archive foreach (var extension in _coverExtensions) { - cover = archive.Entries.FirstOrDefault(e => e.Key == "cover" + extension); + cover = await archive.EntriesAsync.FirstOrDefaultAsync(e => e.Key == "cover" + extension).ConfigureAwait(false); if (cover is not null) { @@ -120,7 +130,9 @@ public class ComicImageProvider : IDynamicImageProvider } } - cover = archive.Entries.OrderBy(x => x.Key).FirstOrDefault(x => _coverExtensions.Contains(Path.GetExtension(x.Key), StringComparison.OrdinalIgnoreCase)); + cover = await archive.EntriesAsync.OrderBy(x => x.Key) + .FirstOrDefaultAsync(x => _coverExtensions.Contains(Path.GetExtension(x.Key), StringComparison.OrdinalIgnoreCase)) + .ConfigureAwait(false); if (cover is not null) { From ac92da233b0896ba33ad0da8b2761236a4ce7465 Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Mon, 15 Jun 2026 20:41:30 +0200 Subject: [PATCH 3/3] await instead of returning Task --- MediaBrowser.Providers/Books/ComicImageProvider.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MediaBrowser.Providers/Books/ComicImageProvider.cs b/MediaBrowser.Providers/Books/ComicImageProvider.cs index 2716d45637..34936cff13 100644 --- a/MediaBrowser.Providers/Books/ComicImageProvider.cs +++ b/MediaBrowser.Providers/Books/ComicImageProvider.cs @@ -39,16 +39,16 @@ public class ComicImageProvider : IDynamicImageProvider public string Name => "Comic Book Archive Cover Extractor"; /// - public Task GetImage(BaseItem item, ImageType type, CancellationToken cancellationToken) + public async Task GetImage(BaseItem item, ImageType type, CancellationToken cancellationToken) { var extension = Path.GetExtension(item.Path); if (_comicBookExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase)) { - return LoadCoverAsync(item, cancellationToken); + return await LoadCoverAsync(item, cancellationToken).ConfigureAwait(false); } - return Task.FromResult(new DynamicImageResponse { HasImage = false }); + return new DynamicImageResponse { HasImage = false }; } ///