New: Use TmdbId from parsing for mapping

This commit is contained in:
Qstick 2023-04-23 00:10:58 -05:00
parent a03323703a
commit 9bef430635
8 changed files with 91 additions and 103 deletions

View File

@ -19,7 +19,6 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
{
private List<ReleaseInfo> _reports;
private RemoteMovie _remoteEpisode;
private FindMovieResult _mappingResult;
private Mock<IDecisionEngineSpecification> _pass1;
private Mock<IDecisionEngineSpecification> _pass2;
@ -55,10 +54,8 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
ParsedMovieInfo = new ParsedMovieInfo()
};
_mappingResult = new FindMovieResult(new Movie(), MovieMatchType.Title);
Mocker.GetMock<IParsingService>()
.Setup(c => c.Map(It.IsAny<ParsedMovieInfo>(), It.IsAny<string>(), It.IsAny<SearchCriteriaBase>())).Returns(_remoteEpisode);
.Setup(c => c.Map(It.IsAny<ParsedMovieInfo>(), It.IsAny<string>(), It.IsAny<int>(), It.IsAny<SearchCriteriaBase>())).Returns(_remoteEpisode);
}
private void GivenSpecifications(params Mock<IDecisionEngineSpecification>[] mocks)
@ -128,30 +125,13 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
Subject.GetRssDecision(_reports).ToList();
Mocker.GetMock<IParsingService>().Verify(c => c.Map(It.IsAny<ParsedMovieInfo>(), It.IsAny<string>(), It.IsAny<SearchCriteriaBase>()), Times.Never());
Mocker.GetMock<IParsingService>().Verify(c => c.Map(It.IsAny<ParsedMovieInfo>(), It.IsAny<string>(), It.IsAny<int>(), It.IsAny<SearchCriteriaBase>()), Times.Never());
_pass1.Verify(c => c.IsSatisfiedBy(It.IsAny<RemoteMovie>(), null), Times.Never());
_pass2.Verify(c => c.IsSatisfiedBy(It.IsAny<RemoteMovie>(), null), Times.Never());
_pass3.Verify(c => c.IsSatisfiedBy(It.IsAny<RemoteMovie>(), null), Times.Never());
}
[Test]
public void should_not_attempt_to_map_episode_if_series_title_is_blank()
{
GivenSpecifications(_pass1, _pass2, _pass3);
_reports[0].Title = "1937 - Snow White and the Seven Dwarves";
var results = Subject.GetRssDecision(_reports).ToList();
Mocker.GetMock<IParsingService>().Verify(c => c.Map(It.IsAny<ParsedMovieInfo>(), It.IsAny<string>(), It.IsAny<SearchCriteriaBase>()), Times.Never());
_pass1.Verify(c => c.IsSatisfiedBy(It.IsAny<RemoteMovie>(), null), Times.Never());
_pass2.Verify(c => c.IsSatisfiedBy(It.IsAny<RemoteMovie>(), null), Times.Never());
_pass3.Verify(c => c.IsSatisfiedBy(It.IsAny<RemoteMovie>(), null), Times.Never());
results.Should().NotBeEmpty();
}
[Test]
public void should_return_rejected_result_for_unparsable_search()
{
@ -160,7 +140,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
Subject.GetSearchDecision(_reports, new MovieSearchCriteria()).ToList();
Mocker.GetMock<IParsingService>().Verify(c => c.Map(It.IsAny<ParsedMovieInfo>(), It.IsAny<string>(), It.IsAny<SearchCriteriaBase>()), Times.Never());
Mocker.GetMock<IParsingService>().Verify(c => c.Map(It.IsAny<ParsedMovieInfo>(), It.IsAny<string>(), It.IsAny<int>(), It.IsAny<SearchCriteriaBase>()), Times.Never());
_pass1.Verify(c => c.IsSatisfiedBy(It.IsAny<RemoteMovie>(), null), Times.Never());
_pass2.Verify(c => c.IsSatisfiedBy(It.IsAny<RemoteMovie>(), null), Times.Never());
@ -186,7 +166,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
{
GivenSpecifications(_pass1);
Mocker.GetMock<IParsingService>().Setup(c => c.Map(It.IsAny<ParsedMovieInfo>(), It.IsAny<string>(), It.IsAny<SearchCriteriaBase>()))
Mocker.GetMock<IParsingService>().Setup(c => c.Map(It.IsAny<ParsedMovieInfo>(), It.IsAny<string>(), It.IsAny<int>(), It.IsAny<SearchCriteriaBase>()))
.Throws<TestException>();
_reports = new List<ReleaseInfo>
@ -198,7 +178,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
Subject.GetRssDecision(_reports);
Mocker.GetMock<IParsingService>().Verify(c => c.Map(It.IsAny<ParsedMovieInfo>(), It.IsAny<string>(), It.IsAny<SearchCriteriaBase>()), Times.Exactly(_reports.Count));
Mocker.GetMock<IParsingService>().Verify(c => c.Map(It.IsAny<ParsedMovieInfo>(), It.IsAny<string>(), It.IsAny<int>(), It.IsAny<SearchCriteriaBase>()), Times.Exactly(_reports.Count));
ExceptionVerification.ExpectedErrors(3);
}
@ -249,7 +229,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
{
GivenSpecifications(_pass1);
Mocker.GetMock<IParsingService>().Setup(c => c.Map(It.IsAny<ParsedMovieInfo>(), It.IsAny<string>(), It.IsAny<SearchCriteriaBase>()))
Mocker.GetMock<IParsingService>().Setup(c => c.Map(It.IsAny<ParsedMovieInfo>(), It.IsAny<string>(), It.IsAny<int>(), It.IsAny<SearchCriteriaBase>()))
.Throws<TestException>();
_reports = new List<ReleaseInfo>

View File

@ -32,7 +32,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests
.Returns(30);
Mocker.GetMock<IParsingService>()
.Setup(s => s.Map(It.IsAny<ParsedMovieInfo>(), It.IsAny<string>(), (SearchCriteriaBase)null))
.Setup(s => s.Map(It.IsAny<ParsedMovieInfo>(), It.IsAny<string>(), It.IsAny<int>(), (SearchCriteriaBase)null))
.Returns(() => CreateRemoteMovie());
Mocker.GetMock<IHttpClient>()

View File

@ -55,7 +55,7 @@ namespace NzbDrone.Core.Test.Download.TrackedDownloads
};
Mocker.GetMock<IParsingService>()
.Setup(s => s.Map(It.Is<ParsedMovieInfo>(i => i.PrimaryMovieTitle == "A Movie"), It.IsAny<string>(), null))
.Setup(s => s.Map(It.Is<ParsedMovieInfo>(i => i.PrimaryMovieTitle == "A Movie"), It.IsAny<string>(), It.IsAny<int>(), null))
.Returns(remoteMovie);
var client = new DownloadClientDefinition()
@ -101,7 +101,7 @@ namespace NzbDrone.Core.Test.Download.TrackedDownloads
};
Mocker.GetMock<IParsingService>()
.Setup(s => s.Map(It.IsAny<ParsedMovieInfo>(), It.IsAny<string>(), null))
.Setup(s => s.Map(It.IsAny<ParsedMovieInfo>(), It.IsAny<string>(), It.IsAny<int>(), null))
.Returns(remoteMovie);
Mocker.GetMock<IHistoryService>()
@ -131,7 +131,7 @@ namespace NzbDrone.Core.Test.Download.TrackedDownloads
Subject.GetTrackedDownloads().Should().HaveCount(1);
Mocker.GetMock<IParsingService>()
.Setup(s => s.Map(It.IsAny<ParsedMovieInfo>(), It.IsAny<string>(), null))
.Setup(s => s.Map(It.IsAny<ParsedMovieInfo>(), It.IsAny<string>(), It.IsAny<int>(), null))
.Returns(default(RemoteMovie));
Subject.Handle(new MoviesDeletedEvent(new List<Movie> { remoteMovie.Movie }, false, false));
@ -158,7 +158,7 @@ namespace NzbDrone.Core.Test.Download.TrackedDownloads
};
Mocker.GetMock<IParsingService>()
.Setup(s => s.Map(It.IsAny<ParsedMovieInfo>(), It.IsAny<string>(), null))
.Setup(s => s.Map(It.IsAny<ParsedMovieInfo>(), It.IsAny<string>(), It.IsAny<int>(), null))
.Returns(default(RemoteMovie));
Mocker.GetMock<IHistoryService>()
@ -188,7 +188,7 @@ namespace NzbDrone.Core.Test.Download.TrackedDownloads
Subject.GetTrackedDownloads().Should().HaveCount(1);
Mocker.GetMock<IParsingService>()
.Setup(s => s.Map(It.IsAny<ParsedMovieInfo>(), It.IsAny<string>(), null))
.Setup(s => s.Map(It.IsAny<ParsedMovieInfo>(), It.IsAny<string>(), It.IsAny<int>(), null))
.Returns(default(RemoteMovie));
Subject.Handle(new MoviesDeletedEvent(new List<Movie> { remoteMovie.Movie }, false, false));

View File

@ -129,7 +129,7 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
{
GivenMatchByMovieTitle();
Subject.Map(_parsedMovieInfo, "", null);
Subject.Map(_parsedMovieInfo, "", 0, null);
Mocker.GetMock<IMovieService>()
.Verify(v => v.FindByTitle(It.IsAny<List<string>>(), It.IsAny<int>(), It.IsAny<List<string>>(), null), Times.Once());
@ -140,7 +140,7 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
{
GivenMatchByMovieTitle();
Subject.Map(_parsedMovieInfo, "", _movieSearchCriteria);
Subject.Map(_parsedMovieInfo, "", 0, _movieSearchCriteria);
Mocker.GetMock<IMovieService>()
.Verify(v => v.FindByTitle(It.IsAny<string>()), Times.Never());
@ -149,26 +149,26 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
[Test]
public void should_match_alternative_title()
{
Subject.Map(_alternativeTitleInfo, "", _movieSearchCriteria).Movie.Should().Be(_movieSearchCriteria.Movie);
Subject.Map(_alternativeTitleInfo, "", 0, _movieSearchCriteria).Movie.Should().Be(_movieSearchCriteria.Movie);
}
[Test]
public void should_match_translation_title()
{
Subject.Map(_translationTitleInfo, "", _movieSearchCriteria).Movie.Should().Be(_movieSearchCriteria.Movie);
Subject.Map(_translationTitleInfo, "", 0, _movieSearchCriteria).Movie.Should().Be(_movieSearchCriteria.Movie);
}
[Test]
public void should_match_roman_title()
{
Subject.Map(_romanTitleInfo, "", _movieSearchCriteria).Movie.Should().Be(_movieSearchCriteria.Movie);
Subject.Map(_romanTitleInfo, "", 0, _movieSearchCriteria).Movie.Should().Be(_movieSearchCriteria.Movie);
}
[Test]
public void should_match_umlauts()
{
Subject.Map(_umlautInfo, "", _movieSearchCriteria).Movie.Should().Be(_movieSearchCriteria.Movie);
Subject.Map(_umlautAltInfo, "", _movieSearchCriteria).Movie.Should().Be(_movieSearchCriteria.Movie);
Subject.Map(_umlautInfo, "", 0, _movieSearchCriteria).Movie.Should().Be(_movieSearchCriteria.Movie);
Subject.Map(_umlautAltInfo, "", 0, _movieSearchCriteria).Movie.Should().Be(_movieSearchCriteria.Movie);
}
}
}

View File

@ -80,7 +80,7 @@ namespace NzbDrone.Core.DecisionEngine
if (parsedMovieInfo != null && !parsedMovieInfo.PrimaryMovieTitle.IsNullOrWhiteSpace())
{
var remoteMovie = _parsingService.Map(parsedMovieInfo, report.ImdbId.ToString(), searchCriteria);
var remoteMovie = _parsingService.Map(parsedMovieInfo, report.ImdbId.ToString(), report.TmdbId, searchCriteria);
remoteMovie.Release = report;
if (remoteMovie.Movie == null)

View File

@ -122,7 +122,7 @@ namespace NzbDrone.Core.Download.TrackedDownloads
if (parsedMovieInfo != null)
{
trackedDownload.RemoteMovie = _parsingService.Map(parsedMovieInfo, "", null);
trackedDownload.RemoteMovie = _parsingService.Map(parsedMovieInfo, "", 0, null);
_aggregationService.Augment(trackedDownload.RemoteMovie);
}
@ -205,7 +205,7 @@ namespace NzbDrone.Core.Download.TrackedDownloads
{
var parsedMovieInfo = Parser.Parser.ParseMovieTitle(trackedDownload.DownloadItem.Title);
trackedDownload.RemoteMovie = parsedMovieInfo == null ? null : _parsingService.Map(parsedMovieInfo, "", null);
trackedDownload.RemoteMovie = parsedMovieInfo == null ? null : _parsingService.Map(parsedMovieInfo, "", 0, null);
_aggregationService.Augment(trackedDownload.RemoteMovie);
}

View File

@ -2,7 +2,7 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using NLog;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.IndexerSearch.Definitions;
using NzbDrone.Core.Movies;
using NzbDrone.Core.Parser.Model;
@ -13,7 +13,7 @@ namespace NzbDrone.Core.Parser
public interface IParsingService
{
Movie GetMovie(string title);
RemoteMovie Map(ParsedMovieInfo parsedMovieInfo, string imdbId, SearchCriteriaBase searchCriteria = null);
RemoteMovie Map(ParsedMovieInfo parsedMovieInfo, string imdbId, int tmdbId, SearchCriteriaBase searchCriteria = null);
RemoteMovie Map(ParsedMovieInfo parsedMovieInfo, int movieId);
ParsedMovieInfo ParseMinimalPathMovieInfo(string path);
}
@ -67,7 +67,9 @@ namespace NzbDrone.Core.Parser
return _movieService.FindByTitle(title);
}
if (TryGetMovieByTitleAndOrYear(parsedMovieInfo, out var result))
var result = TryGetMovieByTitleAndOrYear(parsedMovieInfo);
if (result != null)
{
return result.Movie;
}
@ -75,9 +77,9 @@ namespace NzbDrone.Core.Parser
return null;
}
public RemoteMovie Map(ParsedMovieInfo parsedMovieInfo, string imdbId, SearchCriteriaBase searchCriteria = null)
public RemoteMovie Map(ParsedMovieInfo parsedMovieInfo, string imdbId, int tmdbId, SearchCriteriaBase searchCriteria = null)
{
return Map(parsedMovieInfo, imdbId, null, searchCriteria);
return Map(parsedMovieInfo, imdbId, tmdbId, null, searchCriteria);
}
public RemoteMovie Map(ParsedMovieInfo parsedMovieInfo, int movieId)
@ -89,7 +91,7 @@ namespace NzbDrone.Core.Parser
};
}
public RemoteMovie Map(ParsedMovieInfo parsedMovieInfo, string imdbId, Movie movie, SearchCriteriaBase searchCriteria)
public RemoteMovie Map(ParsedMovieInfo parsedMovieInfo, string imdbId, int tmdbId, Movie movie, SearchCriteriaBase searchCriteria)
{
var remoteMovie = new RemoteMovie
{
@ -98,7 +100,7 @@ namespace NzbDrone.Core.Parser
if (movie == null)
{
var movieMatch = FindMovie(parsedMovieInfo, imdbId, searchCriteria);
var movieMatch = FindMovie(parsedMovieInfo, imdbId, tmdbId, searchCriteria);
if (movieMatch != null)
{
@ -117,62 +119,67 @@ namespace NzbDrone.Core.Parser
return remoteMovie;
}
private FindMovieResult FindMovie(ParsedMovieInfo parsedMovieInfo, string imdbId, SearchCriteriaBase searchCriteria)
private FindMovieResult FindMovie(ParsedMovieInfo parsedMovieInfo, string imdbId, int tmdbId, SearchCriteriaBase searchCriteria)
{
FindMovieResult result = null;
if (!string.IsNullOrWhiteSpace(imdbId) && imdbId != "0")
{
if (TryGetMovieByImDbId(parsedMovieInfo, imdbId, out result))
result = TryGetMovieByImDbId(parsedMovieInfo, imdbId);
}
if (result == null && tmdbId > 0)
{
result = TryGetMovieByTmdbId(parsedMovieInfo, tmdbId);
}
if (result == null)
{
if (searchCriteria != null)
{
return result;
result = TryGetMovieBySearchCriteria(parsedMovieInfo, imdbId, tmdbId, searchCriteria);
}
else
{
result = TryGetMovieByTitleAndOrYear(parsedMovieInfo);
}
}
if (searchCriteria != null)
if (result == null)
{
if (TryGetMovieBySearchCriteria(parsedMovieInfo, searchCriteria, out result))
{
return result;
}
}
else
{
if (TryGetMovieByTitleAndOrYear(parsedMovieInfo, out result))
{
return result;
}
_logger.Debug($"No matching movie for titles {string.Join(", ", parsedMovieInfo.MovieTitles)} ({parsedMovieInfo.Year})");
}
// nothing found up to here => logging that and returning null
_logger.Debug($"No matching movie for titles {string.Join(", ", parsedMovieInfo.MovieTitles)} ({parsedMovieInfo.Year})");
return result;
}
private bool TryGetMovieByImDbId(ParsedMovieInfo parsedMovieInfo, string imdbId, out FindMovieResult result)
private FindMovieResult TryGetMovieByImDbId(ParsedMovieInfo parsedMovieInfo, string imdbId)
{
var movie = _movieService.FindByImdbId(imdbId);
// Should fix practically all problems, where indexer is shite at adding correct imdbids to movies.
if (movie != null && parsedMovieInfo.Year > 1800 && (parsedMovieInfo.Year != movie.MovieMetadata.Value.Year && movie.MovieMetadata.Value.SecondaryYear != parsedMovieInfo.Year))
if (movie != null && (parsedMovieInfo.Year < 1800 || movie.MovieMetadata.Value.Year == parsedMovieInfo.Year || movie.MovieMetadata.Value.SecondaryYear == parsedMovieInfo.Year))
{
result = new FindMovieResult(movie, MovieMatchType.Id);
return false;
return new FindMovieResult(movie, MovieMatchType.Id);
}
if (movie != null)
{
result = new FindMovieResult(movie, MovieMatchType.Id);
}
else
{
result = new FindMovieResult(movie, MovieMatchType.Unknown);
}
return movie != null;
return null;
}
private bool TryGetMovieByTitleAndOrYear(ParsedMovieInfo parsedMovieInfo, out FindMovieResult result)
private FindMovieResult TryGetMovieByTmdbId(ParsedMovieInfo parsedMovieInfo, int tmdbId)
{
var movie = _movieService.FindByTmdbId(tmdbId);
// Should fix practically all problems, where indexer is shite at adding correct imdbids to movies.
if (movie != null && (parsedMovieInfo.Year < 1800 || movie.MovieMetadata.Value.Year == parsedMovieInfo.Year || movie.MovieMetadata.Value.SecondaryYear == parsedMovieInfo.Year))
{
return new FindMovieResult(movie, MovieMatchType.Id);
}
return null;
}
private FindMovieResult TryGetMovieByTitleAndOrYear(ParsedMovieInfo parsedMovieInfo)
{
var candidates = _movieService.FindByTitleCandidates(parsedMovieInfo.MovieTitles, out var otherTitles);
@ -182,8 +189,7 @@ namespace NzbDrone.Core.Parser
movieByTitleAndOrYear = _movieService.FindByTitle(parsedMovieInfo.MovieTitles, parsedMovieInfo.Year, otherTitles, candidates);
if (movieByTitleAndOrYear != null)
{
result = new FindMovieResult(movieByTitleAndOrYear, MovieMatchType.Title);
return true;
return new FindMovieResult(movieByTitleAndOrYear, MovieMatchType.Title);
}
// Only default to not using year when one is parsed if only one movie candidate exists
@ -192,33 +198,31 @@ namespace NzbDrone.Core.Parser
movieByTitleAndOrYear = _movieService.FindByTitle(parsedMovieInfo.MovieTitles, null, otherTitles, candidates);
if (movieByTitleAndOrYear != null)
{
result = new FindMovieResult(movieByTitleAndOrYear, MovieMatchType.Title);
return false;
return new FindMovieResult(movieByTitleAndOrYear, MovieMatchType.Title);
}
}
result = new FindMovieResult(movieByTitleAndOrYear, MovieMatchType.Unknown);
return false;
return null;
}
movieByTitleAndOrYear = _movieService.FindByTitle(parsedMovieInfo.MovieTitles, null, otherTitles, candidates);
if (movieByTitleAndOrYear != null)
{
result = new FindMovieResult(movieByTitleAndOrYear, MovieMatchType.Title);
return true;
return new FindMovieResult(movieByTitleAndOrYear, MovieMatchType.Title);
}
result = new FindMovieResult(movieByTitleAndOrYear, MovieMatchType.Unknown);
return false;
return null;
}
private bool TryGetMovieBySearchCriteria(ParsedMovieInfo parsedMovieInfo, SearchCriteriaBase searchCriteria, out FindMovieResult result)
private FindMovieResult TryGetMovieBySearchCriteria(ParsedMovieInfo parsedMovieInfo, string imdbId, int tmdbId, SearchCriteriaBase searchCriteria)
{
Movie possibleMovie = null;
var possibleTitles = new List<string>();
possibleTitles.Add(searchCriteria.Movie.MovieMetadata.Value.CleanTitle);
var possibleTitles = new List<string>
{
searchCriteria.Movie.MovieMetadata.Value.CleanTitle
};
possibleTitles.AddIfNotNull(searchCriteria.Movie.MovieMetadata.Value.CleanOriginalTitle);
possibleTitles.AddRange(searchCriteria.Movie.MovieMetadata.Value.AlternativeTitles.Select(t => t.CleanTitle));
possibleTitles.AddRange(searchCriteria.Movie.MovieMetadata.Value.Translations.Select(t => t.CleanTitle));
@ -237,17 +241,21 @@ namespace NzbDrone.Core.Parser
{
if (parsedMovieInfo.Year < 1800 || possibleMovie.MovieMetadata.Value.Year == parsedMovieInfo.Year || possibleMovie.MovieMetadata.Value.SecondaryYear == parsedMovieInfo.Year)
{
result = new FindMovieResult(possibleMovie, MovieMatchType.Title);
return true;
return new FindMovieResult(possibleMovie, MovieMatchType.Title);
}
result = new FindMovieResult(possibleMovie, MovieMatchType.Title);
return false;
}
result = new FindMovieResult(searchCriteria.Movie, MovieMatchType.Unknown);
if (tmdbId > 0 && tmdbId == searchCriteria.Movie.TmdbId)
{
return new FindMovieResult(searchCriteria.Movie, MovieMatchType.Id);
}
return false;
if (imdbId.IsNotNullOrWhiteSpace() && imdbId == searchCriteria.Movie.ImdbId)
{
return new FindMovieResult(searchCriteria.Movie, MovieMatchType.Id);
}
return null;
}
}
}

View File

@ -43,7 +43,7 @@ namespace Radarr.Api.V3.Parse
};
}
var remoteMovie = _parsingService.Map(parsedMovieInfo, "");
var remoteMovie = _parsingService.Map(parsedMovieInfo, "", 0);
_aggregationService.Augment(remoteMovie);