mirror of
https://github.com/jellyfin/jellyfin.git
synced 2025-07-09 03:04:24 -04:00
Fix replacement logic
This commit is contained in:
parent
52cfd9f261
commit
37d7e8f5bf
@ -654,139 +654,123 @@ namespace MediaBrowser.Providers.Manager
|
|||||||
await RunCustomProvider(provider, item, logName, options, refreshResult, cancellationToken).ConfigureAwait(false);
|
await RunCustomProvider(provider, item, logName, options, refreshResult, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
var temp = new MetadataResult<TItemType>
|
if (!item.IsLocked)
|
||||||
{
|
{
|
||||||
Item = CreateNew()
|
var temp = new MetadataResult<TItemType>
|
||||||
};
|
|
||||||
temp.Item.Path = item.Path;
|
|
||||||
|
|
||||||
// If replacing all metadata, run internet providers first
|
|
||||||
if (options.ReplaceAllMetadata)
|
|
||||||
{
|
|
||||||
var remoteResult = await ExecuteRemoteProviders(temp, logName, true, id, providers.OfType<IRemoteMetadataProvider<TItemType, TIdType>>(), cancellationToken)
|
|
||||||
.ConfigureAwait(false);
|
|
||||||
|
|
||||||
refreshResult.UpdateType |= remoteResult.UpdateType;
|
|
||||||
refreshResult.ErrorMessage = remoteResult.ErrorMessage;
|
|
||||||
refreshResult.Failures += remoteResult.Failures;
|
|
||||||
}
|
|
||||||
|
|
||||||
var hasLocalMetadata = false;
|
|
||||||
var foundImageTypes = new List<ImageType>();
|
|
||||||
|
|
||||||
foreach (var provider in providers.OfType<ILocalMetadataProvider<TItemType>>())
|
|
||||||
{
|
|
||||||
var providerName = provider.GetType().Name;
|
|
||||||
Logger.LogDebug("Running {Provider} for {Item}", providerName, logName);
|
|
||||||
|
|
||||||
var itemInfo = new ItemInfo(item);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
var localItem = await provider.GetMetadata(itemInfo, options.DirectoryService, cancellationToken).ConfigureAwait(false);
|
Item = CreateNew()
|
||||||
|
};
|
||||||
|
temp.Item.Path = item.Path;
|
||||||
|
temp.Item.Id = item.Id;
|
||||||
|
|
||||||
if (localItem.HasMetadata)
|
var hasLocalBaseMetadataOrLocked = false;
|
||||||
|
var foundImageTypes = new List<ImageType>();
|
||||||
|
|
||||||
|
foreach (var provider in providers.OfType<ILocalMetadataProvider<TItemType>>())
|
||||||
|
{
|
||||||
|
var providerName = provider.GetType().Name;
|
||||||
|
Logger.LogDebug("Running {Provider} for {Item}", providerName, logName);
|
||||||
|
|
||||||
|
var itemInfo = new ItemInfo(item);
|
||||||
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
foreach (var remoteImage in localItem.RemoteImages)
|
var localItem = await provider.GetMetadata(itemInfo, options.DirectoryService, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
|
if (localItem.HasMetadata)
|
||||||
{
|
{
|
||||||
try
|
foreach (var remoteImage in localItem.RemoteImages)
|
||||||
{
|
{
|
||||||
if (item.ImageInfos.Any(x => x.Type == remoteImage.Type)
|
try
|
||||||
&& !options.IsReplacingImage(remoteImage.Type))
|
|
||||||
{
|
{
|
||||||
continue;
|
if (item.ImageInfos.Any(x => x.Type == remoteImage.Type)
|
||||||
|
&& !options.IsReplacingImage(remoteImage.Type))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
await ProviderManager.SaveImage(item, remoteImage.Url, remoteImage.Type, null, cancellationToken).ConfigureAwait(false);
|
||||||
|
refreshResult.UpdateType |= ItemUpdateType.ImageUpdate;
|
||||||
|
|
||||||
|
// remember imagetype that has just been downloaded
|
||||||
|
foundImageTypes.Add(remoteImage.Type);
|
||||||
|
}
|
||||||
|
catch (HttpRequestException ex)
|
||||||
|
{
|
||||||
|
Logger.LogError(ex, "Could not save {ImageType} image: {Url}", Enum.GetName(remoteImage.Type), remoteImage.Url);
|
||||||
}
|
}
|
||||||
|
|
||||||
await ProviderManager.SaveImage(item, remoteImage.Url, remoteImage.Type, null, cancellationToken).ConfigureAwait(false);
|
|
||||||
refreshResult.UpdateType |= ItemUpdateType.ImageUpdate;
|
|
||||||
|
|
||||||
// remember imagetype that has just been downloaded
|
|
||||||
foundImageTypes.Add(remoteImage.Type);
|
|
||||||
}
|
}
|
||||||
catch (HttpRequestException ex)
|
|
||||||
|
if (foundImageTypes.Count > 0)
|
||||||
{
|
{
|
||||||
Logger.LogError(ex, "Could not save {ImageType} image: {Url}", Enum.GetName(remoteImage.Type), remoteImage.Url);
|
imageService.UpdateReplaceImages(options, foundImageTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (imageService.MergeImages(item, localItem.Images, options))
|
||||||
|
{
|
||||||
|
refreshResult.UpdateType |= ItemUpdateType.ImageUpdate;
|
||||||
|
}
|
||||||
|
|
||||||
|
MergeData(localItem, temp, Array.Empty<MetadataField>(), false, true);
|
||||||
|
refreshResult.UpdateType |= ItemUpdateType.MetadataImport;
|
||||||
|
|
||||||
|
// Only one local provider allowed per item
|
||||||
|
if (item.IsLocked || localItem.Item.IsLocked || HasBaseMetadata(localItem.Item))
|
||||||
|
{
|
||||||
|
hasLocalBaseMetadataOrLocked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (foundImageTypes.Count > 0)
|
Logger.LogDebug("{Provider} returned no metadata for {Item}", providerName, logName);
|
||||||
{
|
|
||||||
imageService.UpdateReplaceImages(options, foundImageTypes);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (imageService.MergeImages(item, localItem.Images, options))
|
|
||||||
{
|
|
||||||
refreshResult.UpdateType |= ItemUpdateType.ImageUpdate;
|
|
||||||
}
|
|
||||||
|
|
||||||
MergeData(localItem, temp, Array.Empty<MetadataField>(), options.ReplaceAllMetadata, true);
|
|
||||||
refreshResult.UpdateType |= ItemUpdateType.MetadataImport;
|
|
||||||
|
|
||||||
// Only one local provider allowed per item
|
|
||||||
if (item.IsLocked || localItem.Item.IsLocked || IsFullLocalMetadata(localItem.Item))
|
|
||||||
{
|
|
||||||
hasLocalMetadata = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
catch (OperationCanceledException)
|
||||||
Logger.LogDebug("{Provider} returned no metadata for {Item}", providerName, logName);
|
|
||||||
}
|
|
||||||
catch (OperationCanceledException)
|
|
||||||
{
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Logger.LogError(ex, "Error in {Provider}", provider.Name);
|
|
||||||
|
|
||||||
// If a local provider fails, consider that a failure
|
|
||||||
refreshResult.ErrorMessage = ex.Message;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Local metadata is king - if any is found don't run remote providers
|
|
||||||
if (!options.ReplaceAllMetadata && (!hasLocalMetadata || options.MetadataRefreshMode == MetadataRefreshMode.FullRefresh || !item.StopRefreshIfLocalMetadataFound))
|
|
||||||
{
|
|
||||||
var remoteResult = await ExecuteRemoteProviders(temp, logName, false, id, providers.OfType<IRemoteMetadataProvider<TItemType, TIdType>>(), cancellationToken)
|
|
||||||
.ConfigureAwait(false);
|
|
||||||
|
|
||||||
refreshResult.UpdateType |= remoteResult.UpdateType;
|
|
||||||
refreshResult.ErrorMessage = remoteResult.ErrorMessage;
|
|
||||||
refreshResult.Failures += remoteResult.Failures;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (providers.Any(i => i is not ICustomMetadataProvider))
|
|
||||||
{
|
|
||||||
if (refreshResult.UpdateType > ItemUpdateType.None)
|
|
||||||
{
|
|
||||||
if (hasLocalMetadata)
|
|
||||||
{
|
{
|
||||||
MergeData(temp, metadata, item.LockedFields, true, true);
|
throw;
|
||||||
}
|
}
|
||||||
else
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
if (!options.RemoveOldMetadata)
|
Logger.LogError(ex, "Error in {Provider}", provider.Name);
|
||||||
{
|
|
||||||
MergeData(metadata, temp, Array.Empty<MetadataField>(), false, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Will always replace all metadata when Scan for new and updated files is used. Else, follow the options.
|
// If a local provider fails, consider that a failure
|
||||||
MergeData(temp, metadata, item.LockedFields, options.MetadataRefreshMode == MetadataRefreshMode.Default || options.ReplaceAllMetadata, false);
|
refreshResult.ErrorMessage = ex.Message;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var provider in customProviders.Where(i => i is not IPreRefreshProvider))
|
if (options.ReplaceAllMetadata || !(hasLocalBaseMetadataOrLocked && item.StopRefreshIfLocalMetadataFound) || options.MetadataRefreshMode == MetadataRefreshMode.FullRefresh)
|
||||||
{
|
{
|
||||||
await RunCustomProvider(provider, item, logName, options, refreshResult, cancellationToken).ConfigureAwait(false);
|
var remoteResult = await ExecuteRemoteProviders(temp, logName, false, id, providers.OfType<IRemoteMetadataProvider<TItemType, TIdType>>(), cancellationToken)
|
||||||
|
.ConfigureAwait(false);
|
||||||
|
|
||||||
|
refreshResult.UpdateType |= remoteResult.UpdateType;
|
||||||
|
refreshResult.ErrorMessage = remoteResult.ErrorMessage;
|
||||||
|
refreshResult.Failures += remoteResult.Failures;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (providers.Any(i => i is not ICustomMetadataProvider))
|
||||||
|
{
|
||||||
|
if (refreshResult.UpdateType > ItemUpdateType.None)
|
||||||
|
{
|
||||||
|
if (options.RemoveOldMetadata)
|
||||||
|
{
|
||||||
|
MergeData(metadata, temp, Array.Empty<MetadataField>(), true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
MergeData(temp, metadata, item.LockedFields, options.MetadataRefreshMode >= MetadataRefreshMode.Default || options.ReplaceAllMetadata, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var provider in customProviders.Where(i => i is not IPreRefreshProvider))
|
||||||
|
{
|
||||||
|
await RunCustomProvider(provider, item, logName, options, refreshResult, cancellationToken).ConfigureAwait(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return refreshResult;
|
return refreshResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual bool IsFullLocalMetadata(TItemType item)
|
protected virtual bool HasBaseMetadata(TItemType item)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(item.Name))
|
if (string.IsNullOrWhiteSpace(item.Name))
|
||||||
{
|
{
|
||||||
@ -948,11 +932,7 @@ namespace MediaBrowser.Providers.Manager
|
|||||||
|
|
||||||
if (replaceData || string.IsNullOrEmpty(target.OriginalTitle))
|
if (replaceData || string.IsNullOrEmpty(target.OriginalTitle))
|
||||||
{
|
{
|
||||||
// Safeguard against incoming data having an empty name
|
target.OriginalTitle = source.OriginalTitle;
|
||||||
if (!string.IsNullOrWhiteSpace(source.OriginalTitle))
|
|
||||||
{
|
|
||||||
target.OriginalTitle = source.OriginalTitle;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (replaceData || !target.CommunityRating.HasValue)
|
if (replaceData || !target.CommunityRating.HasValue)
|
||||||
@ -1015,7 +995,7 @@ namespace MediaBrowser.Providers.Manager
|
|||||||
{
|
{
|
||||||
targetResult.People = sourceResult.People;
|
targetResult.People = sourceResult.People;
|
||||||
}
|
}
|
||||||
else if (targetResult.People is not null && sourceResult.People is not null)
|
else if (sourceResult.People is not null && sourceResult.People.Count >= 0)
|
||||||
{
|
{
|
||||||
MergePeople(sourceResult.People, targetResult.People);
|
MergePeople(sourceResult.People, targetResult.People);
|
||||||
}
|
}
|
||||||
@ -1048,6 +1028,10 @@ namespace MediaBrowser.Providers.Manager
|
|||||||
{
|
{
|
||||||
target.Studios = source.Studios;
|
target.Studios = source.Studios;
|
||||||
}
|
}
|
||||||
|
else if (source.Studios.Length >= 0)
|
||||||
|
{
|
||||||
|
target.Studios = target.Studios.Concat(source.Studios).Distinct().ToArray();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!lockedFields.Contains(MetadataField.Tags))
|
if (!lockedFields.Contains(MetadataField.Tags))
|
||||||
@ -1056,6 +1040,10 @@ namespace MediaBrowser.Providers.Manager
|
|||||||
{
|
{
|
||||||
target.Tags = source.Tags;
|
target.Tags = source.Tags;
|
||||||
}
|
}
|
||||||
|
else if (source.Tags.Length >= 0)
|
||||||
|
{
|
||||||
|
target.Tags = target.Tags.Concat(source.Tags).Distinct().ToArray();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!lockedFields.Contains(MetadataField.ProductionLocations))
|
if (!lockedFields.Contains(MetadataField.ProductionLocations))
|
||||||
@ -1064,6 +1052,10 @@ namespace MediaBrowser.Providers.Manager
|
|||||||
{
|
{
|
||||||
target.ProductionLocations = source.ProductionLocations;
|
target.ProductionLocations = source.ProductionLocations;
|
||||||
}
|
}
|
||||||
|
else if (source.ProductionLocations.Length >= 0)
|
||||||
|
{
|
||||||
|
target.Tags = target.ProductionLocations.Concat(source.ProductionLocations).Distinct().ToArray();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var id in source.ProviderIds)
|
foreach (var id in source.ProviderIds)
|
||||||
@ -1081,17 +1073,28 @@ namespace MediaBrowser.Providers.Manager
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (replaceData || !target.CriticRating.HasValue)
|
||||||
|
{
|
||||||
|
target.CriticRating = source.CriticRating;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (replaceData || target.RemoteTrailers.Count == 0)
|
||||||
|
{
|
||||||
|
target.RemoteTrailers = source.RemoteTrailers;
|
||||||
|
}
|
||||||
|
else if (source.CriticRating.HasValue)
|
||||||
|
{
|
||||||
|
target.RemoteTrailers = target.RemoteTrailers.Concat(source.RemoteTrailers).Distinct().ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
MergeAlbumArtist(source, target, replaceData);
|
MergeAlbumArtist(source, target, replaceData);
|
||||||
MergeCriticRating(source, target, replaceData);
|
|
||||||
MergeTrailers(source, target, replaceData);
|
|
||||||
MergeVideoInfo(source, target, replaceData);
|
MergeVideoInfo(source, target, replaceData);
|
||||||
MergeDisplayOrder(source, target, replaceData);
|
MergeDisplayOrder(source, target, replaceData);
|
||||||
|
|
||||||
if (replaceData || string.IsNullOrEmpty(target.ForcedSortName))
|
if (replaceData || string.IsNullOrEmpty(target.ForcedSortName))
|
||||||
{
|
{
|
||||||
var forcedSortName = source.ForcedSortName;
|
var forcedSortName = source.ForcedSortName;
|
||||||
|
if (!string.IsNullOrEmpty(forcedSortName))
|
||||||
if (!string.IsNullOrWhiteSpace(forcedSortName))
|
|
||||||
{
|
{
|
||||||
target.ForcedSortName = forcedSortName;
|
target.ForcedSortName = forcedSortName;
|
||||||
}
|
}
|
||||||
@ -1099,22 +1102,49 @@ namespace MediaBrowser.Providers.Manager
|
|||||||
|
|
||||||
if (mergeMetadataSettings)
|
if (mergeMetadataSettings)
|
||||||
{
|
{
|
||||||
target.LockedFields = source.LockedFields;
|
if (replaceData || target.LockedFields.Length == 0)
|
||||||
target.IsLocked = source.IsLocked;
|
{
|
||||||
|
target.LockedFields = source.LockedFields;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
target.LockedFields = target.LockedFields.Concat(source.LockedFields).Distinct().ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (replaceData)
|
||||||
|
{
|
||||||
|
target.IsLocked = source.IsLocked;
|
||||||
|
}
|
||||||
|
|
||||||
// Grab the value if it's there, but if not then don't overwrite with the default
|
|
||||||
if (source.DateCreated != default)
|
if (source.DateCreated != default)
|
||||||
{
|
{
|
||||||
target.DateCreated = source.DateCreated;
|
target.DateCreated = source.DateCreated;
|
||||||
}
|
}
|
||||||
|
|
||||||
target.PreferredMetadataCountryCode = source.PreferredMetadataCountryCode;
|
if (replaceData)
|
||||||
target.PreferredMetadataLanguage = source.PreferredMetadataLanguage;
|
{
|
||||||
|
target.IsLocked = source.IsLocked;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (replaceData || string.IsNullOrEmpty(target.PreferredMetadataCountryCode))
|
||||||
|
{
|
||||||
|
target.PreferredMetadataCountryCode = source.PreferredMetadataCountryCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (replaceData || string.IsNullOrEmpty(target.PreferredMetadataLanguage))
|
||||||
|
{
|
||||||
|
target.PreferredMetadataLanguage = source.PreferredMetadataLanguage;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void MergePeople(List<PersonInfo> source, List<PersonInfo> target)
|
private static void MergePeople(List<PersonInfo> source, List<PersonInfo> target)
|
||||||
{
|
{
|
||||||
|
if (target is null)
|
||||||
|
{
|
||||||
|
target = new List<PersonInfo>();
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var person in target)
|
foreach (var person in target)
|
||||||
{
|
{
|
||||||
var normalizedName = person.Name.RemoveDiacritics();
|
var normalizedName = person.Name.RemoveDiacritics();
|
||||||
@ -1143,7 +1173,6 @@ namespace MediaBrowser.Providers.Manager
|
|||||||
if (replaceData || string.IsNullOrEmpty(targetHasDisplayOrder.DisplayOrder))
|
if (replaceData || string.IsNullOrEmpty(targetHasDisplayOrder.DisplayOrder))
|
||||||
{
|
{
|
||||||
var displayOrder = sourceHasDisplayOrder.DisplayOrder;
|
var displayOrder = sourceHasDisplayOrder.DisplayOrder;
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(displayOrder))
|
if (!string.IsNullOrWhiteSpace(displayOrder))
|
||||||
{
|
{
|
||||||
targetHasDisplayOrder.DisplayOrder = displayOrder;
|
targetHasDisplayOrder.DisplayOrder = displayOrder;
|
||||||
@ -1161,22 +1190,10 @@ namespace MediaBrowser.Providers.Manager
|
|||||||
{
|
{
|
||||||
targetHasAlbumArtist.AlbumArtists = sourceHasAlbumArtist.AlbumArtists;
|
targetHasAlbumArtist.AlbumArtists = sourceHasAlbumArtist.AlbumArtists;
|
||||||
}
|
}
|
||||||
}
|
else if (sourceHasAlbumArtist.AlbumArtists.Count >= 0)
|
||||||
}
|
{
|
||||||
|
targetHasAlbumArtist.AlbumArtists = targetHasAlbumArtist.AlbumArtists.Concat(sourceHasAlbumArtist.AlbumArtists).Distinct().ToArray();
|
||||||
private static void MergeCriticRating(BaseItem source, BaseItem target, bool replaceData)
|
}
|
||||||
{
|
|
||||||
if (replaceData || !target.CriticRating.HasValue)
|
|
||||||
{
|
|
||||||
target.CriticRating = source.CriticRating;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void MergeTrailers(BaseItem source, BaseItem target, bool replaceData)
|
|
||||||
{
|
|
||||||
if (replaceData || target.RemoteTrailers.Count == 0)
|
|
||||||
{
|
|
||||||
target.RemoteTrailers = source.RemoteTrailers;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1184,7 +1201,7 @@ namespace MediaBrowser.Providers.Manager
|
|||||||
{
|
{
|
||||||
if (source is Video sourceCast && target is Video targetCast)
|
if (source is Video sourceCast && target is Video targetCast)
|
||||||
{
|
{
|
||||||
if (replaceData || targetCast.Video3DFormat is null)
|
if (replaceData || !targetCast.Video3DFormat.HasValue)
|
||||||
{
|
{
|
||||||
targetCast.Video3DFormat = sourceCast.Video3DFormat;
|
targetCast.Video3DFormat = sourceCast.Video3DFormat;
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ namespace MediaBrowser.Providers.Movies
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override bool IsFullLocalMetadata(Movie item)
|
protected override bool HasBaseMetadata(Movie item)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(item.Overview))
|
if (string.IsNullOrWhiteSpace(item.Overview))
|
||||||
{
|
{
|
||||||
@ -36,7 +36,7 @@ namespace MediaBrowser.Providers.Movies
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return base.IsFullLocalMetadata(item);
|
return base.HasBaseMetadata(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
|
using System.Linq;
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
@ -24,7 +25,7 @@ namespace MediaBrowser.Providers.Movies
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override bool IsFullLocalMetadata(Trailer item)
|
protected override bool HasBaseMetadata(Trailer item)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(item.Overview))
|
if (string.IsNullOrWhiteSpace(item.Overview))
|
||||||
{
|
{
|
||||||
@ -36,7 +37,7 @@ namespace MediaBrowser.Providers.Movies
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return base.IsFullLocalMetadata(item);
|
return base.HasBaseMetadata(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@ -48,6 +49,10 @@ namespace MediaBrowser.Providers.Movies
|
|||||||
{
|
{
|
||||||
target.Item.TrailerTypes = source.Item.TrailerTypes;
|
target.Item.TrailerTypes = source.Item.TrailerTypes;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
target.Item.TrailerTypes = target.Item.TrailerTypes.Concat(source.Item.TrailerTypes).Distinct().ToArray();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -225,6 +225,10 @@ namespace MediaBrowser.Providers.Music
|
|||||||
{
|
{
|
||||||
targetItem.Artists = sourceItem.Artists;
|
targetItem.Artists = sourceItem.Artists;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
targetItem.Artists = targetItem.Artists.Concat(sourceItem.Artists).Distinct().ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
if (replaceData || string.IsNullOrEmpty(targetItem.GetProviderId(MetadataProvider.MusicBrainzAlbumArtist)))
|
if (replaceData || string.IsNullOrEmpty(targetItem.GetProviderId(MetadataProvider.MusicBrainzAlbumArtist)))
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
using MediaBrowser.Controller.Entities.Audio;
|
using MediaBrowser.Controller.Entities.Audio;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
@ -60,6 +61,10 @@ namespace MediaBrowser.Providers.Music
|
|||||||
{
|
{
|
||||||
targetItem.Artists = sourceItem.Artists;
|
targetItem.Artists = sourceItem.Artists;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
targetItem.Artists = targetItem.Artists.Concat(sourceItem.Artists).Distinct().ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
if (replaceData || string.IsNullOrEmpty(targetItem.Album))
|
if (replaceData || string.IsNullOrEmpty(targetItem.Album))
|
||||||
{
|
{
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
|
using System.Linq;
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
@ -45,6 +46,10 @@ namespace MediaBrowser.Providers.Music
|
|||||||
{
|
{
|
||||||
targetItem.Artists = sourceItem.Artists;
|
targetItem.Artists = sourceItem.Artists;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
targetItem.Artists = targetItem.Artists.Concat(sourceItem.Artists).Distinct().ToArray();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
@ -49,8 +50,24 @@ namespace MediaBrowser.Providers.Playlists
|
|||||||
if (mergeMetadataSettings)
|
if (mergeMetadataSettings)
|
||||||
{
|
{
|
||||||
targetItem.PlaylistMediaType = sourceItem.PlaylistMediaType;
|
targetItem.PlaylistMediaType = sourceItem.PlaylistMediaType;
|
||||||
targetItem.LinkedChildren = sourceItem.LinkedChildren;
|
|
||||||
targetItem.Shares = sourceItem.Shares;
|
if (replaceData || targetItem.LinkedChildren.Length == 0)
|
||||||
|
{
|
||||||
|
targetItem.LinkedChildren = sourceItem.LinkedChildren;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
targetItem.LinkedChildren = sourceItem.LinkedChildren.Concat(targetItem.LinkedChildren).Distinct().ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (replaceData || targetItem.Shares.Count == 0)
|
||||||
|
{
|
||||||
|
targetItem.Shares = sourceItem.Shares;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
targetItem.Shares = sourceItem.Shares.Concat(targetItem.Shares).DistinctBy(s => s.UserId).ToArray();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,7 @@ namespace MediaBrowser.Providers.TV
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override bool IsFullLocalMetadata(Series item)
|
protected override bool HasBaseMetadata(Series item)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(item.Overview))
|
if (string.IsNullOrWhiteSpace(item.Overview))
|
||||||
{
|
{
|
||||||
@ -78,7 +78,7 @@ namespace MediaBrowser.Providers.TV
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return base.IsFullLocalMetadata(item);
|
return base.HasBaseMetadata(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
@ -77,7 +77,7 @@ namespace Jellyfin.Providers.Tests.Manager
|
|||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData("Name", MetadataField.Name, false)]
|
[InlineData("Name", MetadataField.Name, false)]
|
||||||
[InlineData("OriginalTitle", null, false)]
|
[InlineData("OriginalTitle", null)]
|
||||||
[InlineData("OfficialRating", MetadataField.OfficialRating)]
|
[InlineData("OfficialRating", MetadataField.OfficialRating)]
|
||||||
[InlineData("CustomRating")]
|
[InlineData("CustomRating")]
|
||||||
[InlineData("Tagline")]
|
[InlineData("Tagline")]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user