diff --git a/.github/workflows/openapi.yml b/.github/workflows/openapi.yml index c4300b39ab0..295b655330b 100644 --- a/.github/workflows/openapi.yml +++ b/.github/workflows/openapi.yml @@ -23,7 +23,7 @@ jobs: - name: Generate openapi.json run: dotnet test tests/Jellyfin.Server.Integration.Tests/Jellyfin.Server.Integration.Tests.csproj -c Release --filter "Jellyfin.Server.Integration.Tests.OpenApiSpecTests" - name: Upload openapi.json - uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 # tag=v3 + uses: actions/upload-artifact@83fd05a356d7e2593de66fc9913b3002723633cb # tag=v3 with: name: openapi-head retention-days: 14 @@ -47,7 +47,7 @@ jobs: - name: Generate openapi.json run: dotnet test tests/Jellyfin.Server.Integration.Tests/Jellyfin.Server.Integration.Tests.csproj -c Release --filter "Jellyfin.Server.Integration.Tests.OpenApiSpecTests" - name: Upload openapi.json - uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 # tag=v3 + uses: actions/upload-artifact@83fd05a356d7e2593de66fc9913b3002723633cb # tag=v3 with: name: openapi-base retention-days: 14 diff --git a/MediaBrowser.Providers/Books/AudioBookMetadataService.cs b/MediaBrowser.Providers/Books/AudioBookMetadataService.cs index 96e1165b692..8695ed6994f 100644 --- a/MediaBrowser.Providers/Books/AudioBookMetadataService.cs +++ b/MediaBrowser.Providers/Books/AudioBookMetadataService.cs @@ -29,9 +29,10 @@ protected override void MergeData( MetadataResult target, MetadataField[] lockedFields, bool replaceData, - bool mergeMetadataSettings) + bool mergeMetadataSettings, + string? requestedLanguage) { - base.MergeData(source, target, lockedFields, replaceData, mergeMetadataSettings); + base.MergeData(source, target, lockedFields, replaceData, mergeMetadataSettings, requestedLanguage); var sourceItem = source.Item; var targetItem = target.Item; diff --git a/MediaBrowser.Providers/Books/BookMetadataService.cs b/MediaBrowser.Providers/Books/BookMetadataService.cs index 50b9922c692..a42bac32ea2 100644 --- a/MediaBrowser.Providers/Books/BookMetadataService.cs +++ b/MediaBrowser.Providers/Books/BookMetadataService.cs @@ -24,9 +24,15 @@ public BookMetadataService( } /// - protected override void MergeData(MetadataResult source, MetadataResult target, MetadataField[] lockedFields, bool replaceData, bool mergeMetadataSettings) + protected override void MergeData( + MetadataResult source, + MetadataResult target, + MetadataField[] lockedFields, + bool replaceData, + bool mergeMetadataSettings, + string? requestedLanguage) { - base.MergeData(source, target, lockedFields, replaceData, mergeMetadataSettings); + base.MergeData(source, target, lockedFields, replaceData, mergeMetadataSettings, requestedLanguage); if (replaceData || string.IsNullOrEmpty(target.Item.SeriesName)) { diff --git a/MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs b/MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs index cbbb343e5ed..f1acb9c7d45 100644 --- a/MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs +++ b/MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs @@ -45,9 +45,15 @@ protected override IList GetChildrenForMetadataUpdates(BoxSet item) } /// - protected override void MergeData(MetadataResult source, MetadataResult target, MetadataField[] lockedFields, bool replaceData, bool mergeMetadataSettings) + protected override void MergeData( + MetadataResult source, + MetadataResult target, + MetadataField[] lockedFields, + bool replaceData, + bool mergeMetadataSettings, + string? requestedLanguage) { - base.MergeData(source, target, lockedFields, replaceData, mergeMetadataSettings); + base.MergeData(source, target, lockedFields, replaceData, mergeMetadataSettings, requestedLanguage); var sourceItem = source.Item; var targetItem = target.Item; diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs index 5a2936bd8b8..8ea2ef58bb2 100644 --- a/MediaBrowser.Providers/Manager/MetadataService.cs +++ b/MediaBrowser.Providers/Manager/MetadataService.cs @@ -704,7 +704,7 @@ protected virtual async Task RefreshWithProviders( refreshResult.UpdateType |= ItemUpdateType.ImageUpdate; } - MergeData(localItem, temp, Array.Empty(), !options.ReplaceAllMetadata, true); + MergeData(localItem, temp, Array.Empty(), !options.ReplaceAllMetadata, true, id.MetadataLanguage); refreshResult.UpdateType |= ItemUpdateType.MetadataImport; // Only one local provider allowed per item @@ -748,16 +748,16 @@ protected virtual async Task RefreshWithProviders( { if (hasLocalMetadata) { - MergeData(temp, metadata, item.LockedFields, true, true); + MergeData(temp, metadata, item.LockedFields, true, true, id.MetadataLanguage); } else { if (!options.RemoveOldMetadata) { - MergeData(metadata, temp, Array.Empty(), false, false); + MergeData(metadata, temp, Array.Empty(), false, false, id.MetadataLanguage); } - MergeData(temp, metadata, item.LockedFields, true, false); + MergeData(temp, metadata, item.LockedFields, true, false, id.MetadataLanguage); } } } @@ -829,7 +829,7 @@ private async Task ExecuteRemoteProviders(MetadataResult(), false, false); + MergeData(result, temp, Array.Empty(), false, false, id.MetadataLanguage); MergeNewData(temp.Item, id); refreshResult.UpdateType |= ItemUpdateType.MetadataDownload; @@ -897,15 +897,17 @@ private bool HasChanged(BaseItem item, IHasItemChangeMonitor changeMonitor, IDir /// The fields that are locked and should not be updated. /// true if existing data should be replaced. /// true if the metadata settings in target should be updated to match source. + /// ?????. /// Thrown if source or target are null. protected virtual void MergeData( MetadataResult source, MetadataResult target, MetadataField[] lockedFields, bool replaceData, - bool mergeMetadataSettings) + bool mergeMetadataSettings, + string requestedLanguage) { - MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings); + MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings, requestedLanguage); } internal static void MergeBaseItemData( @@ -913,10 +915,12 @@ internal static void MergeBaseItemData( MetadataResult targetResult, MetadataField[] lockedFields, bool replaceData, - bool mergeMetadataSettings) + bool mergeMetadataSettings, + string requestedLanguage) { var source = sourceResult.Item; var target = targetResult.Item; + var changeLanguage = false; if (source == null) { @@ -930,13 +934,22 @@ internal static void MergeBaseItemData( if (!lockedFields.Contains(MetadataField.Name)) { - if (replaceData || string.IsNullOrEmpty(target.Name)) + if (targetResult.ResultLanguage != requestedLanguage + && targetResult.ResultLanguage != "en" + && sourceResult.ResultLanguage != requestedLanguage + && sourceResult.ResultLanguage != "en") { - // Safeguard against incoming data having an empty name - if (!string.IsNullOrWhiteSpace(source.Name)) - { - target.Name = source.Name; - } + target.Name = ""; + } + else if (replaceData || ReplaceLanguageCheck( + target.Name, + source.Name, + targetResult.ResultLanguage, + sourceResult.ResultLanguage, + requestedLanguage)) + { + target.Name = source.Name; + changeLanguage = true; } } @@ -985,16 +998,42 @@ internal static void MergeBaseItemData( target.CustomRating = source.CustomRating; } - if (replaceData || string.IsNullOrEmpty(target.Tagline)) + if (targetResult.ResultLanguage != requestedLanguage + && targetResult.ResultLanguage != "en" + && sourceResult.ResultLanguage != requestedLanguage + && sourceResult.ResultLanguage != "en") + { + target.Tagline = ""; + } + else if (replaceData || ReplaceLanguageCheck( + target.Tagline, + source.Tagline, + targetResult.ResultLanguage, + sourceResult.ResultLanguage, + requestedLanguage)) { target.Tagline = source.Tagline; + changeLanguage = true; } if (!lockedFields.Contains(MetadataField.Overview)) { - if (replaceData || string.IsNullOrEmpty(target.Overview)) + if (targetResult.ResultLanguage != requestedLanguage + && targetResult.ResultLanguage != "en" + && sourceResult.ResultLanguage != requestedLanguage + && sourceResult.ResultLanguage != "en") + { + target.Overview = ""; + } + else if (replaceData || ReplaceLanguageCheck( + target.Overview, + source.Overview, + targetResult.ResultLanguage, + sourceResult.ResultLanguage, + requestedLanguage)) { target.Overview = source.Overview; + changeLanguage = true; } } @@ -1105,6 +1144,11 @@ internal static void MergeBaseItemData( target.PreferredMetadataCountryCode = source.PreferredMetadataCountryCode; target.PreferredMetadataLanguage = source.PreferredMetadataLanguage; } + + if (changeLanguage) + { + targetResult.ResultLanguage = sourceResult.ResultLanguage; + } } private static void MergePeople(List source, List target) @@ -1184,5 +1228,15 @@ private static void MergeVideoInfo(BaseItem source, BaseItem target, bool replac } } } + + private static bool ReplaceLanguageCheck(string targetString, string sourceString, string targetLanguage, string sourceLanguage, string requestedLanguage) + { + var sourceEnglish = sourceLanguage == "en"; + var targetHasContent = !string.IsNullOrEmpty(targetString); + var sourceHasContent = !string.IsNullOrEmpty(sourceString); + var targetIsRequeted = targetLanguage == requestedLanguage; + var sourceIsRequested = requestedLanguage is null || sourceLanguage == requestedLanguage; + return ((!targetHasContent && sourceIsRequested) || (sourceHasContent && !targetIsRequeted && sourceIsRequested) || (sourceEnglish && !targetHasContent) || (!sourceEnglish && !targetIsRequeted && sourceIsRequested)) && !(targetHasContent && !sourceHasContent && targetLanguage == "en"); + } } } diff --git a/MediaBrowser.Providers/Movies/MovieMetadataService.cs b/MediaBrowser.Providers/Movies/MovieMetadataService.cs index 984a3c122a8..521782b0a21 100644 --- a/MediaBrowser.Providers/Movies/MovieMetadataService.cs +++ b/MediaBrowser.Providers/Movies/MovieMetadataService.cs @@ -40,9 +40,15 @@ protected override bool IsFullLocalMetadata(Movie item) } /// - protected override void MergeData(MetadataResult source, MetadataResult target, MetadataField[] lockedFields, bool replaceData, bool mergeMetadataSettings) + protected override void MergeData( + MetadataResult source, + MetadataResult target, + MetadataField[] lockedFields, + bool replaceData, + bool mergeMetadataSettings, + string? requestedLanguage) { - base.MergeData(source, target, lockedFields, replaceData, mergeMetadataSettings); + base.MergeData(source, target, lockedFields, replaceData, mergeMetadataSettings, requestedLanguage); var sourceItem = source.Item; var targetItem = target.Item; diff --git a/MediaBrowser.Providers/Movies/TrailerMetadataService.cs b/MediaBrowser.Providers/Movies/TrailerMetadataService.cs index ad0c5aaa7be..70dbacd6ac5 100644 --- a/MediaBrowser.Providers/Movies/TrailerMetadataService.cs +++ b/MediaBrowser.Providers/Movies/TrailerMetadataService.cs @@ -40,9 +40,15 @@ protected override bool IsFullLocalMetadata(Trailer item) } /// - protected override void MergeData(MetadataResult source, MetadataResult target, MetadataField[] lockedFields, bool replaceData, bool mergeMetadataSettings) + protected override void MergeData( + MetadataResult source, + MetadataResult target, + MetadataField[] lockedFields, + bool replaceData, + bool mergeMetadataSettings, + string? requestedLanguage) { - base.MergeData(source, target, lockedFields, replaceData, mergeMetadataSettings); + base.MergeData(source, target, lockedFields, replaceData, mergeMetadataSettings, requestedLanguage); if (replaceData || target.Item.TrailerTypes.Length == 0) { diff --git a/MediaBrowser.Providers/Music/AlbumMetadataService.cs b/MediaBrowser.Providers/Music/AlbumMetadataService.cs index ac40f0b3a48..5438c238fad 100644 --- a/MediaBrowser.Providers/Music/AlbumMetadataService.cs +++ b/MediaBrowser.Providers/Music/AlbumMetadataService.cs @@ -206,9 +206,10 @@ protected override void MergeData( MetadataResult target, MetadataField[] lockedFields, bool replaceData, - bool mergeMetadataSettings) + bool mergeMetadataSettings, + string? requestedLanguage) { - base.MergeData(source, target, lockedFields, replaceData, mergeMetadataSettings); + base.MergeData(source, target, lockedFields, replaceData, mergeMetadataSettings, requestedLanguage); var sourceItem = source.Item; var targetItem = target.Item; diff --git a/MediaBrowser.Providers/Music/AudioMetadataService.cs b/MediaBrowser.Providers/Music/AudioMetadataService.cs index a5b7cb89594..af73afae381 100644 --- a/MediaBrowser.Providers/Music/AudioMetadataService.cs +++ b/MediaBrowser.Providers/Music/AudioMetadataService.cs @@ -49,9 +49,15 @@ private void SetProviderId(Audio sourceItem, Audio targetItem, bool replaceData, } /// - protected override void MergeData(MetadataResult