From 7b779a79b27c9e53ea4909a4c67bf993de198de7 Mon Sep 17 00:00:00 2001 From: cxfksword <718792+cxfksword@users.noreply.github.com> Date: Sat, 18 Mar 2023 10:51:43 +0800 Subject: [PATCH] Fix search tmdb identity. close #21 --- .../DoubanApiTest.cs | 1 - .../MovieImageProviderTest.cs | 26 ++++++++ .../ParseNameTest.cs | 1 + Jellyfin.Plugin.MetaShark.Test/TmdbApiTest.cs | 34 +++++++---- Jellyfin.Plugin.MetaShark/Api/OmdbApi.cs | 6 ++ Jellyfin.Plugin.MetaShark/Core/NameParser.cs | 23 +++++--- .../Providers/BaseProvider.cs | 59 +------------------ .../Providers/MovieImageProvider.cs | 3 +- .../Providers/MovieProvider.cs | 13 +++- .../Providers/SeriesImageProvider.cs | 3 +- .../Providers/SeriesProvider.cs | 4 +- 11 files changed, 88 insertions(+), 85 deletions(-) diff --git a/Jellyfin.Plugin.MetaShark.Test/DoubanApiTest.cs b/Jellyfin.Plugin.MetaShark.Test/DoubanApiTest.cs index fdba052..f9afa2c 100644 --- a/Jellyfin.Plugin.MetaShark.Test/DoubanApiTest.cs +++ b/Jellyfin.Plugin.MetaShark.Test/DoubanApiTest.cs @@ -48,7 +48,6 @@ namespace Jellyfin.Plugin.MetaShark.Test try { var result = await api.SearchAsync(keyword, CancellationToken.None); - var str = result.ToJson(); TestContext.WriteLine(result.ToJson()); } catch (Exception ex) diff --git a/Jellyfin.Plugin.MetaShark.Test/MovieImageProviderTest.cs b/Jellyfin.Plugin.MetaShark.Test/MovieImageProviderTest.cs index 8e0297a..b4d09f0 100644 --- a/Jellyfin.Plugin.MetaShark.Test/MovieImageProviderTest.cs +++ b/Jellyfin.Plugin.MetaShark.Test/MovieImageProviderTest.cs @@ -1,5 +1,6 @@ using Jellyfin.Plugin.MetaShark.Api; using Jellyfin.Plugin.MetaShark.Core; +using Jellyfin.Plugin.MetaShark.Model; using Jellyfin.Plugin.MetaShark.Providers; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; @@ -56,5 +57,30 @@ namespace Jellyfin.Plugin.MetaShark.Test }).GetAwaiter().GetResult(); } + [TestMethod] + public void TestGetMovieImageFromTMDB() + { + var info = new MediaBrowser.Controller.Entities.Movies.Movie() + { + PreferredMetadataLanguage = "zh", + ProviderIds = new Dictionary { { MetadataProvider.Tmdb.ToString(), "752" }, { Plugin.ProviderId, MetaSource.Tmdb } } + }; + var doubanApi = new DoubanApi(loggerFactory); + var tmdbApi = new TmdbApi(loggerFactory); + var omdbApi = new OmdbApi(loggerFactory); + var httpClientFactory = new DefaultHttpClientFactory(); + var libraryManagerStub = new Mock(); + var httpContextAccessorStub = new Mock(); + + Task.Run(async () => + { + var provider = new MovieImageProvider(httpClientFactory, loggerFactory, libraryManagerStub.Object, httpContextAccessorStub.Object, doubanApi, tmdbApi, omdbApi); + var result = await provider.GetImages(info, CancellationToken.None); + Assert.IsNotNull(result); + + var str = result.ToJson(); + Console.WriteLine(result.ToJson()); + }).GetAwaiter().GetResult(); + } } } diff --git a/Jellyfin.Plugin.MetaShark.Test/ParseNameTest.cs b/Jellyfin.Plugin.MetaShark.Test/ParseNameTest.cs index 2ab023b..edc2104 100644 --- a/Jellyfin.Plugin.MetaShark.Test/ParseNameTest.cs +++ b/Jellyfin.Plugin.MetaShark.Test/ParseNameTest.cs @@ -233,6 +233,7 @@ namespace Jellyfin.Plugin.MetaShark.Test // anime特典 fileName = "[KissSub][Steins;Gate][SP][GB_BIG5_JP][BDrip][1080P][HEVC] 边界曲面的缺失之环"; parseResult = NameParser.Parse(fileName); + Assert.IsTrue(parseResult.IsSpecial); Assert.AreEqual(parseResult.Name, "边界曲面的缺失之环"); Assert.AreEqual(parseResult.ParentIndexNumber, null); Assert.AreEqual(parseResult.IndexNumber, null); diff --git a/Jellyfin.Plugin.MetaShark.Test/TmdbApiTest.cs b/Jellyfin.Plugin.MetaShark.Test/TmdbApiTest.cs index cab5b0d..1e0563d 100644 --- a/Jellyfin.Plugin.MetaShark.Test/TmdbApiTest.cs +++ b/Jellyfin.Plugin.MetaShark.Test/TmdbApiTest.cs @@ -36,6 +36,26 @@ namespace Jellyfin.Plugin.MetaShark.Test })); + [TestMethod] + public void TestGetMovie() + { + var api = new TmdbApi(loggerFactory); + + Task.Run(async () => + { + try + { + var result = await api.GetMovieAsync(752, "zh", "zh", CancellationToken.None) + .ConfigureAwait(false); + Assert.IsNotNull(result); + TestContext.WriteLine(result.Images.ToJson()); + } + catch (Exception ex) + { + TestContext.WriteLine(ex.Message); + } + }).GetAwaiter().GetResult(); + } [TestMethod] @@ -47,12 +67,7 @@ namespace Jellyfin.Plugin.MetaShark.Test { try { - var result = await api.GetSeriesAsync(13372, "zh", BaseProvider.GetImageLanguagesParam("zh"), CancellationToken.None) - .ConfigureAwait(false); - Assert.IsNotNull(result); - TestContext.WriteLine(result.Images.ToJson()); - - result = await api.GetSeriesAsync(13372, "zh", null, CancellationToken.None) + var result = await api.GetSeriesAsync(13372, "zh", "zh", CancellationToken.None) .ConfigureAwait(false); Assert.IsNotNull(result); TestContext.WriteLine(result.Images.ToJson()); @@ -74,15 +89,10 @@ namespace Jellyfin.Plugin.MetaShark.Test { try { - var result = await api.GetEpisodeAsync(13372, 1, 1, "zh", BaseProvider.GetImageLanguagesParam("zh"), CancellationToken.None) + var result = await api.GetEpisodeAsync(13372, 1, 1, "zh", "zh", CancellationToken.None) .ConfigureAwait(false); Assert.IsNotNull(result); TestContext.WriteLine(result.Images.Stills.ToJson()); - - result = await api.GetEpisodeAsync(13372, 1, 1, null, null, CancellationToken.None) - .ConfigureAwait(false); - Assert.IsNotNull(result); - TestContext.WriteLine(result.ToJson()); } catch (Exception ex) { diff --git a/Jellyfin.Plugin.MetaShark/Api/OmdbApi.cs b/Jellyfin.Plugin.MetaShark/Api/OmdbApi.cs index f309b0a..436c376 100644 --- a/Jellyfin.Plugin.MetaShark/Api/OmdbApi.cs +++ b/Jellyfin.Plugin.MetaShark/Api/OmdbApi.cs @@ -30,6 +30,12 @@ namespace Jellyfin.Plugin.MetaShark.Api httpClient.Timeout = TimeSpan.FromSeconds(5); } + /// + /// 通过imdb获取信息(会返回最新的imdb id) + /// + /// imdb id + /// + /// public async Task GetByImdbID(string id, CancellationToken cancellationToken) { if (!this.IsEnable()) diff --git a/Jellyfin.Plugin.MetaShark/Core/NameParser.cs b/Jellyfin.Plugin.MetaShark/Core/NameParser.cs index f43b5c7..c7690c1 100644 --- a/Jellyfin.Plugin.MetaShark/Core/NameParser.cs +++ b/Jellyfin.Plugin.MetaShark/Core/NameParser.cs @@ -219,14 +219,23 @@ namespace Jellyfin.Plugin.MetaShark.Core public static bool IsSpecialDirectory(string path) { - var fileName = Path.GetFileNameWithoutExtension(path) ?? string.Empty; - if (IsAnime(fileName) && fileName.Contains("[SP]")) - { - return true; - } + var folder = Path.GetFileName(Path.GetDirectoryName(path))?.ToUpper() ?? string.Empty; + return folder == "SPS" || folder == "SPECIALS" || folder.Contains("特典"); + } - var folder = Path.GetFileName(Path.GetDirectoryName(path)) ?? string.Empty; - return folder == "SPs" || folder == "Specials" || folder.Contains("特典"); + public static bool IsExtraDirectory(string path) + { + var folder = Path.GetFileName(Path.GetDirectoryName(path))?.ToUpper() ?? string.Empty; + return folder == "EXTRA" + || folder == "MENU" + || folder == "MENUS" + || folder == "PV" + || folder == "PV&CM" + || folder == "CM" + || folder == "BONUS" + || folder.Contains("OPED") + || folder.Contains("NCED") + || folder.Contains("花絮"); } diff --git a/Jellyfin.Plugin.MetaShark/Providers/BaseProvider.cs b/Jellyfin.Plugin.MetaShark/Providers/BaseProvider.cs index 28f924e..1d03054 100644 --- a/Jellyfin.Plugin.MetaShark/Providers/BaseProvider.cs +++ b/Jellyfin.Plugin.MetaShark/Providers/BaseProvider.cs @@ -492,67 +492,10 @@ namespace Jellyfin.Plugin.MetaShark.Providers } - /// - /// Normalizes a language string for use with TMDb's include image language parameter. - /// - /// The preferred language as either a 2 letter code with or without country code. - /// The comma separated language string. - public static string GetImageLanguagesParam(string preferredLanguage) - { - var languages = new List(); - - if (!string.IsNullOrEmpty(preferredLanguage)) - { - preferredLanguage = NormalizeLanguage(preferredLanguage); - - languages.Add(preferredLanguage); - - if (preferredLanguage.Length == 5) // like en-US - { - // Currently, TMDB supports 2-letter language codes only - // They are planning to change this in the future, thus we're - // supplying both codes if we're having a 5-letter code. - languages.Add(preferredLanguage.Substring(0, 2)); - } - } - - languages.Add("null"); - - if (!string.Equals(preferredLanguage, "en", StringComparison.OrdinalIgnoreCase)) - { - languages.Add("en"); - } - - return string.Join(',', languages); - } - - /// - /// Normalizes a language string for use with TMDb's language parameter. - /// - /// The language code. - /// The normalized language code. - public static string NormalizeLanguage(string language) - { - if (string.IsNullOrEmpty(language)) - { - return language; - } - - // They require this to be uppercase - // Everything after the hyphen must be written in uppercase due to a way TMDB wrote their api. - // See here: https://www.themoviedb.org/talk/5119221d760ee36c642af4ad?page=3#56e372a0c3a3685a9e0019ab - var parts = language.Split('-'); - - if (parts.Length == 2) - { - language = parts[0] + "-" + parts[1].ToUpperInvariant(); - } - - return language; - } protected string GetOriginalFileName(ItemLookupInfo info) { + // movie放在文件夹中时,应该使用文件夹名 switch (info) { case SeriesInfo: diff --git a/Jellyfin.Plugin.MetaShark/Providers/MovieImageProvider.cs b/Jellyfin.Plugin.MetaShark/Providers/MovieImageProvider.cs index eac72c7..4ef5c9d 100644 --- a/Jellyfin.Plugin.MetaShark/Providers/MovieImageProvider.cs +++ b/Jellyfin.Plugin.MetaShark/Providers/MovieImageProvider.cs @@ -77,7 +77,7 @@ namespace Jellyfin.Plugin.MetaShark.Providers } var tmdbId = item.GetProviderId(MetadataProvider.Tmdb); - if (!string.IsNullOrEmpty(tmdbId)) + if (metaSource == MetaSource.Tmdb && !string.IsNullOrEmpty(tmdbId)) { var language = item.GetPreferredMetadataLanguage(); var movie = await _tmdbApi @@ -101,6 +101,7 @@ namespace Jellyfin.Plugin.MetaShark.Providers VoteCount = poster.VoteCount, Width = poster.Width, Height = poster.Height, + Language = AdjustImageLanguage(poster.Iso_639_1, language), ProviderName = Name, Type = ImageType.Primary, }); diff --git a/Jellyfin.Plugin.MetaShark/Providers/MovieProvider.cs b/Jellyfin.Plugin.MetaShark/Providers/MovieProvider.cs index 5fd166e..559b81b 100644 --- a/Jellyfin.Plugin.MetaShark/Providers/MovieProvider.cs +++ b/Jellyfin.Plugin.MetaShark/Providers/MovieProvider.cs @@ -58,7 +58,7 @@ namespace Jellyfin.Plugin.MetaShark.Providers return new RemoteSearchResult { SearchProviderName = DoubanProviderName, - ProviderIds = new Dictionary { { DoubanProviderId, x.Sid } }, + ProviderIds = new Dictionary { { DoubanProviderId, x.Sid }, { Plugin.ProviderId, MetaSource.Douban } }, ImageUrl = this.GetProxyImageUrl(x.Img), ProductionYear = x.Year, Name = x.Name, @@ -75,7 +75,7 @@ namespace Jellyfin.Plugin.MetaShark.Providers return new RemoteSearchResult { SearchProviderName = TmdbProviderName, - ProviderIds = new Dictionary { { MetadataProvider.Tmdb.ToString(), x.Id.ToString(CultureInfo.InvariantCulture) } }, + ProviderIds = new Dictionary { { MetadataProvider.Tmdb.ToString(), x.Id.ToString(CultureInfo.InvariantCulture) }, { Plugin.ProviderId, MetaSource.Tmdb } }, Name = string.Format("[TMDB]{0}", x.Title ?? x.OriginalTitle), ImageUrl = this._tmdbApi.GetPosterUrl(x.PosterPath), Overview = x.Overview, @@ -188,7 +188,7 @@ namespace Jellyfin.Plugin.MetaShark.Providers } - if (!string.IsNullOrEmpty(tmdbId)) + if (metaSource == MetaSource.Tmdb && !string.IsNullOrEmpty(tmdbId)) { this.Log($"GetMovieMetadata of tmdb [id]: \"{tmdbId}\""); var movieResult = await _tmdbApi @@ -265,6 +265,13 @@ namespace Jellyfin.Plugin.MetaShark.Providers return new MetadataResult(); } + // 动画常用特典文件夹 + if (NameParser.IsSpecialDirectory(info.Path) || NameParser.IsExtraDirectory(info.Path)) + { + this.Log($"Found extra of [name]: {fileName}"); + return new MetadataResult(); + } + return null; } diff --git a/Jellyfin.Plugin.MetaShark/Providers/SeriesImageProvider.cs b/Jellyfin.Plugin.MetaShark/Providers/SeriesImageProvider.cs index b359bc5..77a78e9 100644 --- a/Jellyfin.Plugin.MetaShark/Providers/SeriesImageProvider.cs +++ b/Jellyfin.Plugin.MetaShark/Providers/SeriesImageProvider.cs @@ -77,7 +77,7 @@ namespace Jellyfin.Plugin.MetaShark.Providers } var tmdbId = item.GetProviderId(MetadataProvider.Tmdb); - if (!string.IsNullOrEmpty(tmdbId)) + if (metaSource == MetaSource.Tmdb && !string.IsNullOrEmpty(tmdbId)) { var language = item.GetPreferredMetadataLanguage(); var movie = await _tmdbApi @@ -101,6 +101,7 @@ namespace Jellyfin.Plugin.MetaShark.Providers VoteCount = poster.VoteCount, Width = poster.Width, Height = poster.Height, + Language = AdjustImageLanguage(poster.Iso_639_1, language), ProviderName = Name, Type = ImageType.Primary, }); diff --git a/Jellyfin.Plugin.MetaShark/Providers/SeriesProvider.cs b/Jellyfin.Plugin.MetaShark/Providers/SeriesProvider.cs index 1ea23e0..6fcabb4 100644 --- a/Jellyfin.Plugin.MetaShark/Providers/SeriesProvider.cs +++ b/Jellyfin.Plugin.MetaShark/Providers/SeriesProvider.cs @@ -50,7 +50,7 @@ namespace Jellyfin.Plugin.MetaShark.Providers return new RemoteSearchResult { SearchProviderName = DoubanProviderName, - ProviderIds = new Dictionary { { DoubanProviderId, x.Sid } }, + ProviderIds = new Dictionary { { DoubanProviderId, x.Sid }, { Plugin.ProviderId, MetaSource.Douban } }, ImageUrl = this.GetProxyImageUrl(x.Img), ProductionYear = x.Year, Name = x.Name, @@ -66,7 +66,7 @@ namespace Jellyfin.Plugin.MetaShark.Providers return new RemoteSearchResult { SearchProviderName = TmdbProviderName, - ProviderIds = new Dictionary { { MetadataProvider.Tmdb.ToString(), x.Id.ToString(CultureInfo.InvariantCulture) } }, + ProviderIds = new Dictionary { { MetadataProvider.Tmdb.ToString(), x.Id.ToString(CultureInfo.InvariantCulture) }, { Plugin.ProviderId, MetaSource.Tmdb } }, Name = string.Format("[TMDB]{0}", x.Name ?? x.OriginalName), ImageUrl = this._tmdbApi.GetPosterUrl(x.PosterPath), Overview = x.Overview,