From bbe73ee7da55ad932400888508f2c47978ac97c9 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Sat, 19 Mar 2022 12:57:00 -0700 Subject: [PATCH] Fixed: Automatic import of releases when file is not matched to series (cherry picked from commit e280897bc7f5c55d11714b0c25e7220477c18886) --- ...add_additional_info_to_pending_releases.cs | 14 ++++++++++ src/NzbDrone.Core/Datastore/TableMapping.cs | 1 + .../Download/CompletedDownloadService.cs | 10 +++++-- .../Download/Pending/PendingRelease.cs | 6 +++++ .../Download/Pending/PendingReleaseService.cs | 10 ++++--- src/NzbDrone.Core/History/EntityHistory.cs | 1 + .../History/EntityHistoryService.cs | 1 + .../Parser/Model/FindArtistResult.cs | 24 +++++++++++++++++ src/NzbDrone.Core/Parser/Model/RemoteAlbum.cs | 1 + src/NzbDrone.Core/Parser/ParsingService.cs | 27 ++++++++++++++++--- 10 files changed, 86 insertions(+), 9 deletions(-) create mode 100644 src/NzbDrone.Core/Datastore/Migration/067_add_additional_info_to_pending_releases.cs create mode 100644 src/NzbDrone.Core/Parser/Model/FindArtistResult.cs diff --git a/src/NzbDrone.Core/Datastore/Migration/067_add_additional_info_to_pending_releases.cs b/src/NzbDrone.Core/Datastore/Migration/067_add_additional_info_to_pending_releases.cs new file mode 100644 index 000000000..a9cd31c1e --- /dev/null +++ b/src/NzbDrone.Core/Datastore/Migration/067_add_additional_info_to_pending_releases.cs @@ -0,0 +1,14 @@ +using FluentMigrator; +using NzbDrone.Core.Datastore.Migration.Framework; + +namespace NzbDrone.Core.Datastore.Migration +{ + [Migration(067)] + public class add_additional_info_to_pending_releases : NzbDroneMigrationBase + { + protected override void MainDbUpgrade() + { + Alter.Table("PendingReleases").AddColumn("AdditionalInfo").AsString().Nullable(); + } + } +} diff --git a/src/NzbDrone.Core/Datastore/TableMapping.cs b/src/NzbDrone.Core/Datastore/TableMapping.cs index ca9052f58..8579ccdcc 100644 --- a/src/NzbDrone.Core/Datastore/TableMapping.cs +++ b/src/NzbDrone.Core/Datastore/TableMapping.cs @@ -229,6 +229,7 @@ namespace NzbDrone.Core.Datastore SqlMapper.AddTypeHandler(new EmbeddedDocumentConverter()); SqlMapper.AddTypeHandler(new EmbeddedDocumentConverter()); SqlMapper.AddTypeHandler(new EmbeddedDocumentConverter()); + SqlMapper.AddTypeHandler(new EmbeddedDocumentConverter()); SqlMapper.AddTypeHandler(new EmbeddedDocumentConverter>()); SqlMapper.AddTypeHandler(new OsPathConverter()); SqlMapper.RemoveTypeMap(typeof(Guid)); diff --git a/src/NzbDrone.Core/Download/CompletedDownloadService.cs b/src/NzbDrone.Core/Download/CompletedDownloadService.cs index 0f27bda99..283d861b4 100644 --- a/src/NzbDrone.Core/Download/CompletedDownloadService.cs +++ b/src/NzbDrone.Core/Download/CompletedDownloadService.cs @@ -14,6 +14,7 @@ using NzbDrone.Core.MediaFiles.TrackImport; using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Music; using NzbDrone.Core.Parser; +using NzbDrone.Core.Parser.Model; namespace NzbDrone.Core.Download { @@ -93,8 +94,13 @@ namespace NzbDrone.Core.Download if (artist == null) { - trackedDownload.Warn("Artist name mismatch, automatic import is not possible."); - return; + Enum.TryParse(historyItem.Data.GetValueOrDefault(EntityHistory.ARTIST_MATCH_TYPE, ArtistMatchType.Unknown.ToString()), out ArtistMatchType artistMatchType); + + if (artistMatchType == ArtistMatchType.Id) + { + trackedDownload.Warn("Found matching artist via grab history, but release was matched to artist by ID. Automatic import is not possible."); + return; + } } } diff --git a/src/NzbDrone.Core/Download/Pending/PendingRelease.cs b/src/NzbDrone.Core/Download/Pending/PendingRelease.cs index 15a7cfefc..89c5ce115 100644 --- a/src/NzbDrone.Core/Download/Pending/PendingRelease.cs +++ b/src/NzbDrone.Core/Download/Pending/PendingRelease.cs @@ -12,8 +12,14 @@ namespace NzbDrone.Core.Download.Pending public ParsedAlbumInfo ParsedAlbumInfo { get; set; } public ReleaseInfo Release { get; set; } public PendingReleaseReason Reason { get; set; } + public PendingReleaseAdditionalInfo AdditionalInfo { get; set; } // Not persisted public RemoteAlbum RemoteAlbum { get; set; } } + + public class PendingReleaseAdditionalInfo + { + public ArtistMatchType ArtistMatchType { get; set; } + } } diff --git a/src/NzbDrone.Core/Download/Pending/PendingReleaseService.cs b/src/NzbDrone.Core/Download/Pending/PendingReleaseService.cs index 5828664d0..512444175 100644 --- a/src/NzbDrone.Core/Download/Pending/PendingReleaseService.cs +++ b/src/NzbDrone.Core/Download/Pending/PendingReleaseService.cs @@ -300,8 +300,7 @@ namespace NzbDrone.Core.Download.Pending List albums; - RemoteAlbum knownRemoteAlbum; - if (knownRemoteAlbums != null && knownRemoteAlbums.TryGetValue(release.Release.Title, out knownRemoteAlbum)) + if (knownRemoteAlbums != null && knownRemoteAlbums.TryGetValue(release.Release.Title, out var knownRemoteAlbum)) { albums = knownRemoteAlbum.Albums; } @@ -313,6 +312,7 @@ namespace NzbDrone.Core.Download.Pending release.RemoteAlbum = new RemoteAlbum { Artist = artist, + ArtistMatchType = release.AdditionalInfo?.ArtistMatchType ?? ArtistMatchType.Unknown, Albums = albums, ParsedAlbumInfo = release.ParsedAlbumInfo, Release = release.Release @@ -336,7 +336,11 @@ namespace NzbDrone.Core.Download.Pending Release = decision.RemoteAlbum.Release, Title = decision.RemoteAlbum.Release.Title, Added = DateTime.UtcNow, - Reason = reason + Reason = reason, + AdditionalInfo = new PendingReleaseAdditionalInfo + { + ArtistMatchType = decision.RemoteAlbum.ArtistMatchType + } }); _eventAggregator.PublishEvent(new PendingReleasesUpdatedEvent()); diff --git a/src/NzbDrone.Core/History/EntityHistory.cs b/src/NzbDrone.Core/History/EntityHistory.cs index c9aada55e..dacdfb532 100644 --- a/src/NzbDrone.Core/History/EntityHistory.cs +++ b/src/NzbDrone.Core/History/EntityHistory.cs @@ -9,6 +9,7 @@ namespace NzbDrone.Core.History public class EntityHistory : ModelBase { public const string DOWNLOAD_CLIENT = "downloadClient"; + public const string ARTIST_MATCH_TYPE = "artistMatchType"; public EntityHistory() { diff --git a/src/NzbDrone.Core/History/EntityHistoryService.cs b/src/NzbDrone.Core/History/EntityHistoryService.cs index b1a028af4..0e3e40905 100644 --- a/src/NzbDrone.Core/History/EntityHistoryService.cs +++ b/src/NzbDrone.Core/History/EntityHistoryService.cs @@ -165,6 +165,7 @@ namespace NzbDrone.Core.History history.Data.Add("Protocol", ((int)message.Album.Release.DownloadProtocol).ToString()); history.Data.Add("DownloadForced", (!message.Album.DownloadAllowed).ToString()); history.Data.Add("CustomFormatScore", message.Album.CustomFormatScore.ToString()); + history.Data.Add("ArtistMatchType", message.Album.ArtistMatchType.ToString()); if (!message.Album.ParsedAlbumInfo.ReleaseHash.IsNullOrWhiteSpace()) { diff --git a/src/NzbDrone.Core/Parser/Model/FindArtistResult.cs b/src/NzbDrone.Core/Parser/Model/FindArtistResult.cs new file mode 100644 index 000000000..c12bf81f2 --- /dev/null +++ b/src/NzbDrone.Core/Parser/Model/FindArtistResult.cs @@ -0,0 +1,24 @@ +using NzbDrone.Core.Music; + +namespace NzbDrone.Core.Parser.Model +{ + public class FindArtistResult + { + public Artist Artist { get; set; } + public ArtistMatchType MatchType { get; set; } + + public FindArtistResult(Artist artist, ArtistMatchType matchType) + { + Artist = artist; + MatchType = matchType; + } + } + + public enum ArtistMatchType + { + Unknown = 0, + Title = 1, + Alias = 2, + Id = 3 + } +} diff --git a/src/NzbDrone.Core/Parser/Model/RemoteAlbum.cs b/src/NzbDrone.Core/Parser/Model/RemoteAlbum.cs index d05bf094b..36c1b328c 100644 --- a/src/NzbDrone.Core/Parser/Model/RemoteAlbum.cs +++ b/src/NzbDrone.Core/Parser/Model/RemoteAlbum.cs @@ -17,6 +17,7 @@ namespace NzbDrone.Core.Parser.Model public TorrentSeedConfiguration SeedConfiguration { get; set; } public List CustomFormats { get; set; } public int CustomFormatScore { get; set; } + public ArtistMatchType ArtistMatchType { get; set; } public RemoteAlbum() { diff --git a/src/NzbDrone.Core/Parser/ParsingService.cs b/src/NzbDrone.Core/Parser/ParsingService.cs index e95d2ef32..fab9fb3a4 100644 --- a/src/NzbDrone.Core/Parser/ParsingService.cs +++ b/src/NzbDrone.Core/Parser/ParsingService.cs @@ -103,7 +103,15 @@ namespace NzbDrone.Core.Parser ParsedAlbumInfo = parsedAlbumInfo, }; - var artist = GetArtist(parsedAlbumInfo, searchCriteria); + Artist artist = null; + + var artistMatch = FindArtist(parsedAlbumInfo, searchCriteria); + + if (artistMatch != null) + { + artist = artistMatch.Artist; + remoteAlbum.ArtistMatchType = artistMatch.MatchType; + } if (artist == null) { @@ -188,7 +196,7 @@ namespace NzbDrone.Core.Parser }; } - private Artist GetArtist(ParsedAlbumInfo parsedAlbumInfo, SearchCriteriaBase searchCriteria) + private FindArtistResult FindArtist(ParsedAlbumInfo parsedAlbumInfo, SearchCriteriaBase searchCriteria) { Artist artist = null; @@ -196,16 +204,27 @@ namespace NzbDrone.Core.Parser { if (searchCriteria.Artist.CleanName == parsedAlbumInfo.ArtistName.CleanArtistName()) { - return searchCriteria.Artist; + return new FindArtistResult(searchCriteria.Artist, ArtistMatchType.Title); } } + var matchType = ArtistMatchType.Unknown; artist = _artistService.FindByName(parsedAlbumInfo.ArtistName); + if (artist != null) + { + matchType = ArtistMatchType.Title; + } + if (artist == null) { _logger.Debug("Trying inexact artist match for {0}", parsedAlbumInfo.ArtistName); artist = _artistService.FindByNameInexact(parsedAlbumInfo.ArtistName); + + if (artist != null) + { + matchType = ArtistMatchType.Title; + } } if (artist == null) @@ -214,7 +233,7 @@ namespace NzbDrone.Core.Parser return null; } - return artist; + return new FindArtistResult(artist, matchType); } public Album GetLocalAlbum(string filename, Artist artist)