From dda8040d5c33f9b2e4a50c92233e39bef527175b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20W=C3=BCller?= Date: Mon, 13 May 2024 20:30:48 +0200 Subject: [PATCH] Adapt to breaking changes made by Jellyfin 10.9.x --- Directory.Build.props | 2 +- .../ArcIdentifierTests.cs | 24 ++++++++++++++--- .../EpisodeIdentifierTests.cs | 24 ++++++++++++++--- .../JWueller.Jellyfin.OnePace.Tests.csproj | 2 +- .../SeriesIdentifierTests.cs | 6 ++--- .../WebRepositoryTests.cs | 26 +++++++++---------- JWueller.Jellyfin.OnePace/ArcIdentifier.cs | 2 +- .../EpisodeIdentifier.cs | 2 +- .../JWueller.Jellyfin.OnePace.csproj | 2 +- .../ServiceRegistrator.cs | 5 ++-- changelogs/1.5.0.0.md | 1 + meta.template.yaml | 4 +-- 12 files changed, 67 insertions(+), 33 deletions(-) create mode 100644 changelogs/1.5.0.0.md diff --git a/Directory.Build.props b/Directory.Build.props index ea713c4..9fa3725 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,6 +1,6 @@ - 1.4.0.0 + 1.5.1.0 $(ProjectVersion) $(ProjectVersion) $(ProjectVersion) diff --git a/JWueller.Jellyfin.OnePace.Tests/ArcIdentifierTests.cs b/JWueller.Jellyfin.OnePace.Tests/ArcIdentifierTests.cs index ac0c806..cff63e1 100644 --- a/JWueller.Jellyfin.OnePace.Tests/ArcIdentifierTests.cs +++ b/JWueller.Jellyfin.OnePace.Tests/ArcIdentifierTests.cs @@ -100,7 +100,7 @@ public ArcIdentifierTests() [InlineData("clkso3n3l000008l751pk86u4", "Romance Dawn")] [InlineData("clkso3uwi000108l724rj9vc0", "Orange Town")] [InlineData("clkso3zi6000208l7bhq7dtn6", "Syrup Village")] - public async void ShouldIdentifyArcByProviderId(string id, string expectedInvariantTitle) + public async Task ShouldIdentifyArcByProviderId(string id, string expectedInvariantTitle) { var itemLookupInfo = new ItemLookupInfo(); itemLookupInfo.SetOnePaceId(id); @@ -119,7 +119,7 @@ public async void ShouldIdentifyArcByProviderId(string id, string expectedInvari [InlineData("/path/to/One Pace/001", "Romance Dawn")] // rank (padded) [InlineData("/path/to/One Pace/[One Pace][8-21] Orange Town [1080p]", "Orange Town")] // release name [InlineData("/path/to/One Pace/[One Pace][23-41] Syrup Village [480p]", "Syrup Village")] // release name - public async void ShouldIdentifyArcByPath(string path, string expectedInvariantTitle) + public async Task ShouldIdentifyArcByPath(string path, string expectedInvariantTitle) { var itemLookupInfo = new ItemLookupInfo { @@ -139,7 +139,7 @@ public async void ShouldIdentifyArcByPath(string path, string expectedInvariantT [Theory] [InlineData("/path/to/One Pace/Enies Lobby", "Enies Lobby")] [InlineData("/path/to/One Pace/Post-Enies Lobby", "Post-Enies Lobby")] - public async void ShouldPreferLongerTitles(string path, string expectedInvariantTitle) + public async Task ShouldPreferLongerTitles(string path, string expectedInvariantTitle) { var itemLookupInfo = new ItemLookupInfo { @@ -156,7 +156,7 @@ public async void ShouldPreferLongerTitles(string path, string expectedInvariant /// It's 'Whisky Peak', not 'Whiskey Peak', but its such a common typo that we need to handle it. /// [Fact] - public async void ShouldIdentifyWhiskyPeakDespiteTypo() + public async Task ShouldIdentifyWhiskyPeakDespiteTypo() { var itemLookupInfo = new ItemLookupInfo { @@ -168,4 +168,20 @@ public async void ShouldIdentifyWhiskyPeakDespiteTypo() Assert.NotNull(arc); Assert.Equal("Whisky Peak", arc.InvariantTitle); } + + /// + /// Jellyfin 10.9.x apparently decided to not have paths for all media anymore. + /// + [Fact] + public async Task ShouldNotCrashWithMissingPath() + { + var itemLookupInfo = new ItemLookupInfo + { + Path = null + }; + + var arc = await ArcIdentifier.IdentifyAsync(_repository, itemLookupInfo, CancellationToken.None); + + Assert.Null(arc); + } } diff --git a/JWueller.Jellyfin.OnePace.Tests/EpisodeIdentifierTests.cs b/JWueller.Jellyfin.OnePace.Tests/EpisodeIdentifierTests.cs index c6956c3..3c0c49f 100644 --- a/JWueller.Jellyfin.OnePace.Tests/EpisodeIdentifierTests.cs +++ b/JWueller.Jellyfin.OnePace.Tests/EpisodeIdentifierTests.cs @@ -128,7 +128,7 @@ public EpisodeIdentifierTests() [InlineData("clkso9t8u000108jk5lbu2409", "Romance Dawn 02")] [InlineData("clkso9z6n000208jk069u63ih", "Orange Town 01")] [InlineData("clksoa57k000308jkb3cu73n8", "Orange Town 02")] - public async void ShouldIdentifyEpisodeByProviderId(string episodeId, string expectedInvariantTitle) + public async Task ShouldIdentifyEpisodeByProviderId(string episodeId, string expectedInvariantTitle) { var itemLookupInfo = new ItemLookupInfo(); itemLookupInfo.SetOnePaceId(episodeId); @@ -152,7 +152,7 @@ public async void ShouldIdentifyEpisodeByProviderId(string episodeId, string exp [InlineData("/path/to/One Pace/Orange Town 01.mkv", "Orange Town 01")] // invariant title only [InlineData("/path/to/One Pace/D767799C.mkv", "Romance Dawn 01")] // uppercase CRC-32 only [InlineData("/path/to/One Pace/c7ca5080.mkv", "Orange Town 01")] // lowercase CRC-32 only - public async void ShouldIdentifyEpisodeByPath(string path, string expectedInvariantTitle) + public async Task ShouldIdentifyEpisodeByPath(string path, string expectedInvariantTitle) { var itemLookupInfo = new ItemLookupInfo { @@ -172,7 +172,7 @@ public async void ShouldIdentifyEpisodeByPath(string path, string expectedInvari [Theory] [InlineData("/path/to/One Pace/Enies Lobby 01.mkv", "Enies Lobby 01")] [InlineData("/path/to/One Pace/Post-Enies Lobby 01.mkv", "Post-Enies Lobby 01")] - public async void ShouldPreferLongerTitles(string path, string expectedInvariantTitle) + public async Task ShouldPreferLongerTitles(string path, string expectedInvariantTitle) { var itemLookupInfo = new ItemLookupInfo { @@ -189,7 +189,7 @@ public async void ShouldPreferLongerTitles(string path, string expectedInvariant /// It's 'Whisky Peak', not 'Whiskey Peak', but its such a common typo that we need to handle it. /// [Fact] - public async void ShouldIdentifyWhiskyPeakDespiteTypo() + public async Task ShouldIdentifyWhiskyPeakDespiteTypo() { var itemLookupInfo = new ItemLookupInfo { @@ -201,4 +201,20 @@ public async void ShouldIdentifyWhiskyPeakDespiteTypo() Assert.NotNull(episode); Assert.Equal("Whisky Peak 01", episode.InvariantTitle); } + + /// + /// Jellyfin 10.9.x apparently decided to not have paths for all media anymore. + /// + [Fact] + public async Task ShouldNotCrashWithMissingPath() + { + var itemLookupInfo = new ItemLookupInfo + { + Path = null + }; + + var episode = await EpisodeIdentifier.IdentifyAsync(_repository, itemLookupInfo, CancellationToken.None); + + Assert.Null(episode); + } } diff --git a/JWueller.Jellyfin.OnePace.Tests/JWueller.Jellyfin.OnePace.Tests.csproj b/JWueller.Jellyfin.OnePace.Tests/JWueller.Jellyfin.OnePace.Tests.csproj index c7de827..14c5f90 100644 --- a/JWueller.Jellyfin.OnePace.Tests/JWueller.Jellyfin.OnePace.Tests.csproj +++ b/JWueller.Jellyfin.OnePace.Tests/JWueller.Jellyfin.OnePace.Tests.csproj @@ -1,6 +1,6 @@ - net6.0 + net8.0 enable enable false diff --git a/JWueller.Jellyfin.OnePace.Tests/SeriesIdentifierTests.cs b/JWueller.Jellyfin.OnePace.Tests/SeriesIdentifierTests.cs index 964d9b3..24a555f 100644 --- a/JWueller.Jellyfin.OnePace.Tests/SeriesIdentifierTests.cs +++ b/JWueller.Jellyfin.OnePace.Tests/SeriesIdentifierTests.cs @@ -33,7 +33,7 @@ public SeriesIdentifierTests() } [Fact] - public async void ShouldIdentifySeriesByProviderId() + public async Task ShouldIdentifySeriesByProviderId() { var itemLookupInfo = new ItemLookupInfo(); itemLookupInfo.SetOnePaceId(Plugin.DummySeriesId); @@ -47,7 +47,7 @@ public async void ShouldIdentifySeriesByProviderId() [Theory] [InlineData("/path/to/One Pace")] [InlineData("/path/to/One Piece [One Pace]")] - public async void ShouldIdentifySeriesByPath(string path) + public async Task ShouldIdentifySeriesByPath(string path) { var itemLookupInfo = new ItemLookupInfo { @@ -63,7 +63,7 @@ public async void ShouldIdentifySeriesByPath(string path) [Theory] [InlineData("One Pace")] [InlineData("One Piece [One Pace]")] - public async void ShouldIdentifySeriesByName(string name) + public async Task ShouldIdentifySeriesByName(string name) { var itemLookupInfo = new ItemLookupInfo { diff --git a/JWueller.Jellyfin.OnePace.Tests/WebRepositoryTests.cs b/JWueller.Jellyfin.OnePace.Tests/WebRepositoryTests.cs index 647cfe0..75c14e1 100644 --- a/JWueller.Jellyfin.OnePace.Tests/WebRepositoryTests.cs +++ b/JWueller.Jellyfin.OnePace.Tests/WebRepositoryTests.cs @@ -238,7 +238,7 @@ public WebRepositoryTests() } [Fact] - public async void ShouldFindSeries() + public async Task ShouldFindSeries() { var result = await _webRepository.FindSeriesAsync(CancellationToken.None); @@ -247,7 +247,7 @@ public async void ShouldFindSeries() } [Fact] - public async void ShouldFindAllArcs() + public async Task ShouldFindAllArcs() { var result = await _webRepository.FindAllArcsAsync(CancellationToken.None); @@ -258,7 +258,7 @@ public async void ShouldFindAllArcs() } [Fact] - public async void ShouldFindAllEpisodes() + public async Task ShouldFindAllEpisodes() { var result = await _webRepository.FindAllEpisodesAsync(CancellationToken.None); @@ -273,7 +273,7 @@ public async void ShouldFindAllEpisodes() [Theory] [InlineData("clksypeix000008jw066ye7lo", "Romance Dawn")] [InlineData("clksyq4q5000108jwgihd6jud", "Orange Town")] - public async void ShouldFindArcById(string arcId, string expectedInvariantTitle) + public async Task ShouldFindArcById(string arcId, string expectedInvariantTitle) { var result = await _webRepository.FindArcByIdAsync(arcId, CancellationToken.None); @@ -286,7 +286,7 @@ public async void ShouldFindArcById(string arcId, string expectedInvariantTitle) [InlineData("clksys3c2000308jwa08325o7", "Romance Dawn 02")] [InlineData("clksysvim000408jw6anzden8", "Romance Dawn 03")] [InlineData("clksytlbt000508jw6r9x1jb1", "Orange Town 01")] - public async void ShouldFindEpisodeById(string episodeId, string expectedInvariantTitle) + public async Task ShouldFindEpisodeById(string episodeId, string expectedInvariantTitle) { var result = await _webRepository.FindEpisodeByIdAsync(episodeId, CancellationToken.None); @@ -300,7 +300,7 @@ public async void ShouldFindEpisodeById(string episodeId, string expectedInvaria /// /// [Fact] - public async void ShouldFindEpisodeWithMatchingArcById() + public async Task ShouldFindEpisodeWithMatchingArcById() { var result = await _webRepository.FindEpisodeByIdAsync("clksyqwxl000208jw82wh3y0g", CancellationToken.None); @@ -313,7 +313,7 @@ public async void ShouldFindEpisodeWithMatchingArcById() [InlineData("en", "One Pace en", "English description")] [InlineData("de", "One Pace de", "Deutsche Beschreibung")] [InlineData("invalid", "One Pace en", "English description")] // fallback - public async void ShouldFindBestSeriesLocalization(string languageCode, string expectedTitle, + public async Task ShouldFindBestSeriesLocalization(string languageCode, string expectedTitle, string expectedDescription) { var result = await _webRepository.FindBestLocalizationBySeriesAsync(languageCode, CancellationToken.None); @@ -328,7 +328,7 @@ public async void ShouldFindBestSeriesLocalization(string languageCode, string e [InlineData("clksyq4q5000108jwgihd6jud", "en", "Orange Town en", "English description for Orange Town")] [InlineData("clksyq4q5000108jwgihd6jud", "de", "Orange Town de", "Deutsche Beschreibung für Orange Town")] [InlineData("clksyq4q5000108jwgihd6jud", "invalid", "Orange Town en", "English description for Orange Town")] // fallback - public async void ShouldFindBestArcLocalization( + public async Task ShouldFindBestArcLocalization( string arcId, string languageCode, string expectedTitle, @@ -345,7 +345,7 @@ public async void ShouldFindBestArcLocalization( [InlineData("clksyqwxl000208jw82wh3y0g", "de", "Romance Dawn 01 de", "Deutsche Beschreibung für Romance Dawn 01")] [InlineData("clksyqwxl000208jw82wh3y0g", "en", "Romance Dawn 01 en", "English description for Romance Dawn 01")] [InlineData("clksyqwxl000208jw82wh3y0g", "invalid", "Romance Dawn 01 en", "English description for Romance Dawn 01")] // fallback - public async void ShouldFindBestEpisodeLocalization( + public async Task ShouldFindBestEpisodeLocalization( string episodeId, string languageCode, string expectedTitle, @@ -360,7 +360,7 @@ public async void ShouldFindBestEpisodeLocalization( } [Fact] - public async void ShouldFindSeriesLogoArt() + public async Task ShouldFindSeriesLogoArt() { var result = await _webRepository.FindAllLogoArtBySeriesAsync(CancellationToken.None); @@ -369,7 +369,7 @@ public async void ShouldFindSeriesLogoArt() } [Fact] - public async void ShouldFindSeriesCoverArt() + public async Task ShouldFindSeriesCoverArt() { var result = await _webRepository.FindAllCoverArtBySeriesAsync(CancellationToken.None); @@ -379,7 +379,7 @@ public async void ShouldFindSeriesCoverArt() [Theory] [InlineData("clksypeix000008jw066ye7lo", 4)] [InlineData("clksyq4q5000108jwgihd6jud", 1)] - public async void ShouldFindAllArcCoverArt(string arcId, int expectedCoverArtCount) + public async Task ShouldFindAllArcCoverArt(string arcId, int expectedCoverArtCount) { var result = await _webRepository.FindAllCoverArtByArcIdAsync(arcId, CancellationToken.None); @@ -391,7 +391,7 @@ public async void ShouldFindAllArcCoverArt(string arcId, int expectedCoverArtCou [InlineData("clksyqwxl000208jw82wh3y0g", 3)] [InlineData("clksys3c2000308jwa08325o7", 1)] [InlineData("clksytlbt000508jw6r9x1jb1", 2)] - public async void ShouldFindAllEpisodeCoverArt(string episodeId, int expectedCoverArtCount) + public async Task ShouldFindAllEpisodeCoverArt(string episodeId, int expectedCoverArtCount) { var result = await _webRepository.FindAllCoverArtByEpisodeIdAsync(episodeId, CancellationToken.None); diff --git a/JWueller.Jellyfin.OnePace/ArcIdentifier.cs b/JWueller.Jellyfin.OnePace/ArcIdentifier.cs index aad6c88..655fe32 100644 --- a/JWueller.Jellyfin.OnePace/ArcIdentifier.cs +++ b/JWueller.Jellyfin.OnePace/ArcIdentifier.cs @@ -26,7 +26,7 @@ internal static class ArcIdentifier } } - if (IdentifierUtil.OnePaceInvariantTitleRegex.IsMatch(itemLookupInfo.Path)) + if (itemLookupInfo.Path != null && IdentifierUtil.OnePaceInvariantTitleRegex.IsMatch(itemLookupInfo.Path)) { var arcs = await repository.FindAllArcsAsync(cancellationToken).ConfigureAwait(false); diff --git a/JWueller.Jellyfin.OnePace/EpisodeIdentifier.cs b/JWueller.Jellyfin.OnePace/EpisodeIdentifier.cs index 4c45359..e215804 100644 --- a/JWueller.Jellyfin.OnePace/EpisodeIdentifier.cs +++ b/JWueller.Jellyfin.OnePace/EpisodeIdentifier.cs @@ -27,7 +27,7 @@ internal static class EpisodeIdentifier } } - if (IdentifierUtil.OnePaceInvariantTitleRegex.IsMatch(itemLookupInfo.Path)) + if (itemLookupInfo.Path != null && IdentifierUtil.OnePaceInvariantTitleRegex.IsMatch(itemLookupInfo.Path)) { var episodes = await repository.FindAllEpisodesAsync(cancellationToken).ConfigureAwait(false); diff --git a/JWueller.Jellyfin.OnePace/JWueller.Jellyfin.OnePace.csproj b/JWueller.Jellyfin.OnePace/JWueller.Jellyfin.OnePace.csproj index b1d2b0f..7633525 100644 --- a/JWueller.Jellyfin.OnePace/JWueller.Jellyfin.OnePace.csproj +++ b/JWueller.Jellyfin.OnePace/JWueller.Jellyfin.OnePace.csproj @@ -1,6 +1,6 @@ - net6.0 + net8.0 JWueller.Jellyfin.OnePace true true diff --git a/JWueller.Jellyfin.OnePace/ServiceRegistrator.cs b/JWueller.Jellyfin.OnePace/ServiceRegistrator.cs index 2af91c1..d151ce9 100644 --- a/JWueller.Jellyfin.OnePace/ServiceRegistrator.cs +++ b/JWueller.Jellyfin.OnePace/ServiceRegistrator.cs @@ -1,5 +1,6 @@ using System.Diagnostics.CodeAnalysis; -using MediaBrowser.Common.Plugins; +using MediaBrowser.Controller; +using MediaBrowser.Controller.Plugins; using Microsoft.Extensions.DependencyInjection; namespace JWueller.Jellyfin.OnePace; @@ -9,7 +10,7 @@ namespace JWueller.Jellyfin.OnePace; public class ServiceRegistrator : IPluginServiceRegistrator { /// - public void RegisterServices(IServiceCollection serviceCollection) + public void RegisterServices(IServiceCollection serviceCollection, IServerApplicationHost applicationHost) { serviceCollection.AddSingleton(); } diff --git a/changelogs/1.5.0.0.md b/changelogs/1.5.0.0.md new file mode 100644 index 0000000..e7e4c0f --- /dev/null +++ b/changelogs/1.5.0.0.md @@ -0,0 +1 @@ +Adapt to breaking changes by Jellyfin 10.9.x diff --git a/meta.template.yaml b/meta.template.yaml index d2a3cf9..4623ca0 100644 --- a/meta.template.yaml +++ b/meta.template.yaml @@ -1,8 +1,8 @@ --- name: "One Pace" guid: "1c0bf35e-3df4-47cc-8a4e-e3865de60d2f" -targetAbi: "10.8.0.0" -framework: "net6.0" +targetAbi: "10.9.1.0" +framework: "net8.0" overview: "Metadata and cover art integration for the One Pace project" description: >- Please report bugs at https://github.com/jwueller/jellyfin-plugin-onepace