1
0
mirror of https://github.com/Radarr/Radarr.git synced 2024-10-27 06:02:33 +01:00

Fixed: Automatic import of releases when file is not matched to movie

This commit is contained in:
Qstick 2023-04-22 23:03:53 -05:00
parent 7527eff268
commit 875bf0c59e
18 changed files with 164 additions and 203 deletions

View File

@ -19,7 +19,7 @@ public class DownloadDecisionMakerFixture : CoreTest<DownloadDecisionMaker>
{
private List<ReleaseInfo> _reports;
private RemoteMovie _remoteEpisode;
private MappingResult _mappingResult;
private FindMovieResult _mappingResult;
private Mock<IDecisionEngineSpecification> _pass1;
private Mock<IDecisionEngineSpecification> _pass2;
@ -57,11 +57,10 @@ public void Setup()
ParsedMovieInfo = new ParsedMovieInfo()
};
_mappingResult = new MappingResult { Movie = new Movie(), MappingResultType = MappingResultType.Success };
_mappingResult.RemoteMovie = _remoteEpisode;
_mappingResult = new FindMovieResult(new Movie(), MovieMatchType.Title);
Mocker.GetMock<IParsingService>()
.Setup(c => c.Map(It.IsAny<ParsedMovieInfo>(), It.IsAny<string>(), It.IsAny<SearchCriteriaBase>())).Returns(_mappingResult);
.Setup(c => c.Map(It.IsAny<ParsedMovieInfo>(), It.IsAny<string>(), It.IsAny<SearchCriteriaBase>())).Returns(_remoteEpisode);
}
private void GivenSpecifications(params Mock<IDecisionEngineSpecification>[] mocks)
@ -128,7 +127,6 @@ public void should_not_attempt_to_map_episode_if_not_parsable()
{
GivenSpecifications(_pass1, _pass2, _pass3);
_reports[0].Title = "Not parsable";
_mappingResult.MappingResultType = MappingResultType.NotParsable;
Subject.GetRssDecision(_reports).ToList();
@ -144,7 +142,6 @@ 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";
_mappingResult.MappingResultType = MappingResultType.NotParsable;
var results = Subject.GetRssDecision(_reports).ToList();
@ -162,7 +159,6 @@ public void should_return_rejected_result_for_unparsable_search()
{
GivenSpecifications(_pass1, _pass2, _pass3);
_reports[0].Title = "1937 - Snow White and the Seven Dwarves";
_mappingResult.MappingResultType = MappingResultType.NotParsable;
Subject.GetSearchDecision(_reports, new MovieSearchCriteria()).ToList();
@ -179,7 +175,6 @@ public void should_not_attempt_to_make_decision_if_series_is_unknown()
GivenSpecifications(_pass1, _pass2, _pass3);
_remoteEpisode.Movie = null;
_mappingResult.MappingResultType = MappingResultType.TitleNotFound;
Subject.GetRssDecision(_reports);
@ -228,7 +223,6 @@ public void should_not_allow_download_if_series_is_unknown()
GivenSpecifications(_pass1, _pass2, _pass3);
_remoteEpisode.Movie = null;
_mappingResult.MappingResultType = MappingResultType.TitleNotFound;
var result = Subject.GetRssDecision(_reports);

View File

@ -33,7 +33,7 @@ public void SetupBase()
Mocker.GetMock<IParsingService>()
.Setup(s => s.Map(It.IsAny<ParsedMovieInfo>(), It.IsAny<string>(), (SearchCriteriaBase)null))
.Returns(() => new MappingResult { RemoteMovie = CreateRemoteMovie(), MappingResultType = MappingResultType.Success });
.Returns(() => CreateRemoteMovie());
Mocker.GetMock<IHttpClient>()
.Setup(s => s.Get(It.IsAny<HttpRequest>()))

View File

@ -43,7 +43,7 @@ public void should_track_downloads_using_the_source_title_if_it_cannot_be_found_
{
GivenDownloadHistory();
var remoteEpisode = new RemoteMovie
var remoteMovie = new RemoteMovie
{
Movie = new Movie() { Id = 3 },
@ -56,7 +56,7 @@ public void should_track_downloads_using_the_source_title_if_it_cannot_be_found_
Mocker.GetMock<IParsingService>()
.Setup(s => s.Map(It.Is<ParsedMovieInfo>(i => i.PrimaryMovieTitle == "A Movie"), It.IsAny<string>(), null))
.Returns(new MappingResult { RemoteMovie = remoteEpisode });
.Returns(remoteMovie);
ParseMovieTitle();
@ -104,7 +104,7 @@ public void should_unmap_tracked_download_if_movie_deleted()
Mocker.GetMock<IParsingService>()
.Setup(s => s.Map(It.IsAny<ParsedMovieInfo>(), It.IsAny<string>(), null))
.Returns(new MappingResult { RemoteMovie = remoteMovie });
.Returns(remoteMovie);
Mocker.GetMock<IHistoryService>()
.Setup(s => s.FindByDownloadId(It.IsAny<string>()))
@ -136,7 +136,7 @@ public void should_unmap_tracked_download_if_movie_deleted()
Mocker.GetMock<IParsingService>()
.Setup(s => s.Map(It.IsAny<ParsedMovieInfo>(), It.IsAny<string>(), null))
.Returns(new MappingResult { MappingResultType = MappingResultType.Unknown });
.Returns(default(RemoteMovie));
Subject.Handle(new MoviesDeletedEvent(new List<Movie> { remoteMovie.Movie }, false, false));
@ -163,7 +163,7 @@ public void should_not_throw_when_processing_deleted_movie()
Mocker.GetMock<IParsingService>()
.Setup(s => s.Map(It.IsAny<ParsedMovieInfo>(), It.IsAny<string>(), null))
.Returns(new MappingResult { MappingResultType = MappingResultType.Unknown });
.Returns(default(RemoteMovie));
Mocker.GetMock<IHistoryService>()
.Setup(s => s.FindByDownloadId(It.IsAny<string>()))
@ -195,7 +195,7 @@ public void should_not_throw_when_processing_deleted_movie()
Mocker.GetMock<IParsingService>()
.Setup(s => s.Map(It.IsAny<ParsedMovieInfo>(), It.IsAny<string>(), null))
.Returns(new MappingResult { MappingResultType = MappingResultType.Unknown });
.Returns(default(RemoteMovie));
Subject.Handle(new MoviesDeletedEvent(new List<Movie> { remoteMovie.Movie }, false, false));

View File

@ -146,30 +146,6 @@ public void should_use_search_criteria_movie_title()
.Verify(v => v.FindByTitle(It.IsAny<string>()), Times.Never());
}
[Test]
public void should_not_match_with_wrong_year()
{
GivenMatchByMovieTitle();
Subject.Map(_wrongYearInfo, "", _movieSearchCriteria).MappingResultType.Should().Be(MappingResultType.WrongYear);
}
[Test]
public void should_not_match_wrong_title()
{
GivenMatchByMovieTitle();
Subject.Map(_wrongTitleInfo, "", _movieSearchCriteria).MappingResultType.Should().Be(MappingResultType.WrongTitle);
}
[Test]
public void should_return_title_not_found_when_all_is_null()
{
Mocker.GetMock<IMovieService>()
.Setup(s => s.FindByTitle(It.IsAny<string>()))
.Returns((Movie)null);
Subject.Map(_parsedMovieInfo, "", null).MappingResultType.Should()
.Be(MappingResultType.TitleNotFound);
}
[Test]
public void should_match_alternative_title()
{

View File

@ -0,0 +1,14 @@
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
{
[Migration(218)]
public class add_additional_info_to_pending_releases : NzbDroneMigrationBase
{
protected override void MainDbUpgrade()
{
Alter.Table("PendingReleases").AddColumn("AdditionalInfo").AsString().Nullable();
}
}
}

View File

@ -197,6 +197,7 @@ private static void RegisterMappers()
SqlMapper.AddTypeHandler(new EmbeddedDocumentConverter<List<string>>());
SqlMapper.AddTypeHandler(new EmbeddedDocumentConverter<ParsedMovieInfo>(new QualityIntConverter(), new LanguageIntConverter()));
SqlMapper.AddTypeHandler(new EmbeddedDocumentConverter<ReleaseInfo>());
SqlMapper.AddTypeHandler(new EmbeddedDocumentConverter<PendingReleaseAdditionalInfo>());
SqlMapper.AddTypeHandler(new EmbeddedDocumentConverter<Ratings>());
SqlMapper.AddTypeHandler(new EmbeddedDocumentConverter<List<MovieTranslation>>());
SqlMapper.AddTypeHandler(new EmbeddedDocumentConverter<HashSet<int>>());

View File

@ -10,10 +10,8 @@
using NzbDrone.Core.DecisionEngine.Specifications;
using NzbDrone.Core.Download.Aggregation;
using NzbDrone.Core.IndexerSearch.Definitions;
using NzbDrone.Core.Languages;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Qualities;
namespace NzbDrone.Core.DecisionEngine
{
@ -80,51 +78,50 @@ private IEnumerable<DownloadDecision> GetDecisions(List<ReleaseInfo> reports, Se
{
var parsedMovieInfo = _parsingService.ParseMovieInfo(report.Title, new List<object> { report });
MappingResult result = null;
if (parsedMovieInfo == null || parsedMovieInfo.PrimaryMovieTitle.IsNullOrWhiteSpace())
if (parsedMovieInfo != null && !parsedMovieInfo.PrimaryMovieTitle.IsNullOrWhiteSpace())
{
_logger.Debug("{0} could not be parsed :(.", report.Title);
parsedMovieInfo = new ParsedMovieInfo
{
MovieTitles = new List<string>() { report.Title },
SimpleReleaseTitle = report.Title.SimplifyReleaseTitle(),
Year = 1290,
Languages = new List<Language> { Language.Unknown },
Quality = new QualityModel(),
};
var remoteMovie = _parsingService.Map(parsedMovieInfo, report.ImdbId.ToString(), searchCriteria);
remoteMovie.Release = report;
if (result == null)
if (remoteMovie.Movie == null)
{
result = new MappingResult { MappingResultType = MappingResultType.NotParsable };
result.Movie = null; // To ensure we have a remote movie, else null exception on next line!
result.RemoteMovie.ParsedMovieInfo = parsedMovieInfo;
var reason = "Unknown Movie";
decision = new DownloadDecision(remoteMovie, new Rejection(reason));
}
else
{
_aggregationService.Augment(remoteMovie);
remoteMovie.CustomFormats = _formatCalculator.ParseCustomFormat(remoteMovie, remoteMovie.Release.Size);
remoteMovie.CustomFormatScore = remoteMovie?.Movie?.Profile?.CalculateCustomFormatScore(remoteMovie.CustomFormats) ?? 0;
remoteMovie.DownloadAllowed = remoteMovie.Movie != null;
decision = GetDecisionForReport(remoteMovie, searchCriteria);
}
}
else
if (searchCriteria != null)
{
result = _parsingService.Map(parsedMovieInfo, report.ImdbId.ToString(), searchCriteria);
}
if (parsedMovieInfo == null)
{
parsedMovieInfo = new ParsedMovieInfo
{
Languages = LanguageParser.ParseLanguages(report.Title),
Quality = QualityParser.ParseQuality(report.Title)
};
}
result.ReleaseName = report.Title;
var remoteMovie = result.RemoteMovie;
remoteMovie.Release = report;
remoteMovie.MappingResult = result.MappingResultType;
if (parsedMovieInfo.PrimaryMovieTitle.IsNullOrWhiteSpace())
{
var remoteMovie = new RemoteMovie
{
Release = report,
ParsedMovieInfo = parsedMovieInfo,
};
_aggregationService.Augment(remoteMovie);
if (result.MappingResultType != MappingResultType.Success)
{
var rejection = result.ToRejection();
decision = new DownloadDecision(remoteMovie, rejection);
}
else
{
remoteMovie.CustomFormats = _formatCalculator.ParseCustomFormat(remoteMovie, remoteMovie.Release.Size);
remoteMovie.CustomFormatScore = remoteMovie?.Movie?.Profile?.CalculateCustomFormatScore(remoteMovie.CustomFormats) ?? 0;
remoteMovie.DownloadAllowed = remoteMovie.Movie != null;
decision = GetDecisionForReport(remoteMovie, searchCriteria);
decision = new DownloadDecision(remoteMovie, new Rejection("Unable to parse release"));
}
}
}
catch (Exception e)

View File

@ -1,7 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Profiles.Delay;
using NzbDrone.Core.Qualities;
@ -27,13 +26,13 @@ public DownloadDecisionPriorizationService(IConfigService configService, IDelayP
public List<DownloadDecision> PrioritizeDecisionsForMovies(List<DownloadDecision> decisions)
{
return decisions.Where(c => c.RemoteMovie.MappingResult == MappingResultType.Success)
return decisions.Where(c => c.RemoteMovie.Movie != null)
.GroupBy(c => c.RemoteMovie.Movie.Id, (movieId, downloadDecisions) =>
{
return downloadDecisions.OrderByDescending(decision => decision, new DownloadDecisionComparer(_configService, _delayProfileService, _qualityDefinitionService));
})
.SelectMany(c => c)
.Union(decisions.Where(c => c.RemoteMovie.MappingResult != MappingResultType.Success))
.Union(decisions.Where(c => c.RemoteMovie.Movie == null))
.ToList();
}
}

View File

@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@ -13,6 +14,7 @@
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.Movies;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.Download
{
@ -92,13 +94,17 @@ public void Check(TrackedDownload trackedDownload)
if (movie == null)
{
trackedDownload.Warn("Movie title mismatch, automatic import is not possible.");
trackedDownload.Warn("Movie title mismatch, Manual Import required.");
return;
}
trackedDownload.Warn("Found matching movie via grab history, but release title doesn't match movie title. Automatic import is not possible.");
Enum.TryParse(historyItem.Data.GetValueOrDefault(MovieHistory.MOVIE_MATCH_TYPE, MovieMatchType.Unknown.ToString()), out MovieMatchType movieMatchType);
return;
if (movieMatchType == MovieMatchType.Id)
{
trackedDownload.Warn("Found matching movie via grab history, but release was matched to movie by ID. Manual Import required.");
return;
}
}
trackedDownload.State = TrackedDownloadState.ImportPending;

View File

@ -12,8 +12,14 @@ public class PendingRelease : ModelBase
public ParsedMovieInfo ParsedMovieInfo { get; set; }
public ReleaseInfo Release { get; set; }
public PendingReleaseReason Reason { get; set; }
public PendingReleaseAdditionalInfo AdditionalInfo { get; set; }
// Not persisted
public RemoteMovie RemoteMovie { get; set; }
}
public class PendingReleaseAdditionalInfo
{
public MovieMatchType MovieMatchType { get; set; }
}
}

View File

@ -293,6 +293,7 @@ private List<PendingRelease> IncludeRemoteMovies(List<PendingRelease> releases,
release.RemoteMovie = new RemoteMovie
{
Movie = movie,
MovieMatchType = release.AdditionalInfo?.MovieMatchType ?? MovieMatchType.Unknown,
ParsedMovieInfo = release.ParsedMovieInfo,
Release = release.Release
};
@ -315,7 +316,11 @@ private void Insert(DownloadDecision decision, PendingReleaseReason reason)
Release = decision.RemoteMovie.Release,
Title = decision.RemoteMovie.Release.Title,
Added = DateTime.UtcNow,
Reason = reason
Reason = reason,
AdditionalInfo = new PendingReleaseAdditionalInfo
{
MovieMatchType = decision.RemoteMovie.MovieMatchType
}
};
if (release.ParsedMovieInfo == null)

View File

@ -121,7 +121,7 @@ public TrackedDownload TrackDownload(DownloadClientDefinition downloadClient, Do
if (parsedMovieInfo != null)
{
trackedDownload.RemoteMovie = _parsingService.Map(parsedMovieInfo, "", null).RemoteMovie;
trackedDownload.RemoteMovie = _parsingService.Map(parsedMovieInfo, "", null);
_aggregationService.Augment(trackedDownload.RemoteMovie);
}
@ -149,7 +149,7 @@ public TrackedDownload TrackDownload(DownloadClientDefinition downloadClient, Do
if (parsedMovieInfo != null)
{
trackedDownload.RemoteMovie = _parsingService.Map(parsedMovieInfo, "", null).RemoteMovie;
trackedDownload.RemoteMovie = _parsingService.Map(parsedMovieInfo, "", null);
}
}
}
@ -197,7 +197,7 @@ private void UpdateCachedItem(TrackedDownload trackedDownload)
{
var parsedMovieInfo = Parser.Parser.ParseMovieTitle(trackedDownload.DownloadItem.Title);
trackedDownload.RemoteMovie = parsedMovieInfo == null ? null : _parsingService.Map(parsedMovieInfo, "", null).RemoteMovie;
trackedDownload.RemoteMovie = parsedMovieInfo == null ? null : _parsingService.Map(parsedMovieInfo, "", null);
_aggregationService.Augment(trackedDownload.RemoteMovie);
}

View File

@ -10,6 +10,7 @@ namespace NzbDrone.Core.History
public class MovieHistory : ModelBase
{
public const string DOWNLOAD_CLIENT = "downloadClient";
public const string MOVIE_MATCH_TYPE = "movieMatchType";
public MovieHistory()
{

View File

@ -153,6 +153,7 @@ public void Handle(MovieGrabbedEvent message)
history.Data.Add("TmdbId", message.Movie.Release.TmdbId.ToString());
history.Data.Add("Protocol", ((int)message.Movie.Release.DownloadProtocol).ToString());
history.Data.Add("CustomFormatScore", message.Movie.CustomFormatScore.ToString());
history.Data.Add("MovieMatchType", message.Movie.MovieMatchType.ToString());
history.Data.Add("IndexerFlags", message.Movie.Release.IndexerFlags.ToString());
history.Data.Add("IndexerId", message.Movie.Release.IndexerId.ToString());

View File

@ -0,0 +1,24 @@
using NzbDrone.Core.Movies;
namespace NzbDrone.Core.Parser.Model
{
public class FindMovieResult
{
public Movie Movie { get; set; }
public MovieMatchType MatchType { get; set; }
public FindMovieResult(Movie movie, MovieMatchType matchType)
{
Movie = movie;
MatchType = matchType;
}
}
public enum MovieMatchType
{
Unknown = 0,
Title = 1,
Alias = 2,
Id = 3
}
}

View File

@ -12,8 +12,8 @@ public class RemoteMovie
public ParsedMovieInfo ParsedMovieInfo { get; set; }
public List<CustomFormat> CustomFormats { get; set; }
public int CustomFormatScore { get; set; }
public MovieMatchType MovieMatchType { get; set; }
public Movie Movie { get; set; }
public MappingResultType MappingResult { get; set; }
public bool DownloadAllowed { get; set; }
public TorrentSeedConfiguration SeedConfiguration { get; set; }
public List<Language> Languages { get; set; }

View File

@ -13,7 +13,7 @@ namespace NzbDrone.Core.Parser
public interface IParsingService
{
Movie GetMovie(string title);
MappingResult Map(ParsedMovieInfo parsedMovieInfo, string imdbId, SearchCriteriaBase searchCriteria = null);
RemoteMovie Map(ParsedMovieInfo parsedMovieInfo, string imdbId, SearchCriteriaBase searchCriteria = null);
ParsedMovieInfo ParseMovieInfo(string title, List<object> helpers);
ParsedMovieInfo ParseMinimalMovieInfo(string path, bool isDir = false);
ParsedMovieInfo ParseMinimalPathMovieInfo(string path);
@ -85,7 +85,7 @@ public Movie GetMovie(string title)
return _movieService.FindByTitle(title);
}
if (TryGetMovieByTitleAndOrYear(parsedMovieInfo, out var result) && result.MappingResultType == MappingResultType.Success)
if (TryGetMovieByTitleAndOrYear(parsedMovieInfo, out var result))
{
return result.Movie;
}
@ -93,24 +93,42 @@ public Movie GetMovie(string title)
return null;
}
public MappingResult Map(ParsedMovieInfo parsedMovieInfo, string imdbId, SearchCriteriaBase searchCriteria = null)
public RemoteMovie Map(ParsedMovieInfo parsedMovieInfo, string imdbId, SearchCriteriaBase searchCriteria = null)
{
var result = GetMovie(parsedMovieInfo, imdbId, searchCriteria);
if (result == null)
{
result = new MappingResult { MappingResultType = MappingResultType.Unknown };
result.Movie = null;
}
result.RemoteMovie.ParsedMovieInfo = parsedMovieInfo;
return result;
return Map(parsedMovieInfo, imdbId, null, searchCriteria);
}
private MappingResult GetMovie(ParsedMovieInfo parsedMovieInfo, string imdbId, SearchCriteriaBase searchCriteria)
public RemoteMovie Map(ParsedMovieInfo parsedMovieInfo, string imdbId, Movie movie, SearchCriteriaBase searchCriteria)
{
MappingResult result = null;
var remoteMovie = new RemoteMovie
{
ParsedMovieInfo = parsedMovieInfo
};
if (movie == null)
{
var movieMatch = FindMovie(parsedMovieInfo, imdbId, searchCriteria);
if (movieMatch != null)
{
movie = movieMatch.Movie;
remoteMovie.MovieMatchType = movieMatch.MatchType;
}
}
if (movie != null)
{
remoteMovie.Movie = movie;
}
remoteMovie.Languages = parsedMovieInfo.Languages;
return remoteMovie;
}
private FindMovieResult FindMovie(ParsedMovieInfo parsedMovieInfo, string imdbId, SearchCriteriaBase searchCriteria)
{
FindMovieResult result = null;
if (!string.IsNullOrWhiteSpace(imdbId) && imdbId != "0")
{
@ -140,30 +158,30 @@ private MappingResult GetMovie(ParsedMovieInfo parsedMovieInfo, string imdbId, S
return result;
}
private bool TryGetMovieByImDbId(ParsedMovieInfo parsedMovieInfo, string imdbId, out MappingResult result)
private bool TryGetMovieByImDbId(ParsedMovieInfo parsedMovieInfo, string imdbId, out FindMovieResult result)
{
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))
{
result = new MappingResult { Movie = movie, MappingResultType = MappingResultType.WrongYear };
result = new FindMovieResult(movie, MovieMatchType.Id);
return false;
}
if (movie != null)
{
result = new MappingResult { Movie = movie };
result = new FindMovieResult(movie, MovieMatchType.Id);
}
else
{
result = new MappingResult { Movie = movie, MappingResultType = MappingResultType.TitleNotFound };
result = new FindMovieResult(movie, MovieMatchType.Unknown);
}
return movie != null;
}
private bool TryGetMovieByTitleAndOrYear(ParsedMovieInfo parsedMovieInfo, out MappingResult result)
private bool TryGetMovieByTitleAndOrYear(ParsedMovieInfo parsedMovieInfo, out FindMovieResult result)
{
var candidates = _movieService.FindByTitleCandidates(parsedMovieInfo.MovieTitles, out var otherTitles);
@ -173,7 +191,7 @@ private bool TryGetMovieByTitleAndOrYear(ParsedMovieInfo parsedMovieInfo, out Ma
movieByTitleAndOrYear = _movieService.FindByTitle(parsedMovieInfo.MovieTitles, parsedMovieInfo.Year, otherTitles, candidates);
if (movieByTitleAndOrYear != null)
{
result = new MappingResult { Movie = movieByTitleAndOrYear };
result = new FindMovieResult(movieByTitleAndOrYear, MovieMatchType.Title);
return true;
}
@ -183,27 +201,27 @@ private bool TryGetMovieByTitleAndOrYear(ParsedMovieInfo parsedMovieInfo, out Ma
movieByTitleAndOrYear = _movieService.FindByTitle(parsedMovieInfo.MovieTitles, null, otherTitles, candidates);
if (movieByTitleAndOrYear != null)
{
result = new MappingResult { Movie = movieByTitleAndOrYear, MappingResultType = MappingResultType.WrongYear };
result = new FindMovieResult(movieByTitleAndOrYear, MovieMatchType.Title);
return false;
}
}
result = new MappingResult { Movie = movieByTitleAndOrYear, MappingResultType = MappingResultType.TitleNotFound };
result = new FindMovieResult(movieByTitleAndOrYear, MovieMatchType.Unknown);
return false;
}
movieByTitleAndOrYear = _movieService.FindByTitle(parsedMovieInfo.MovieTitles, null, otherTitles, candidates);
if (movieByTitleAndOrYear != null)
{
result = new MappingResult { Movie = movieByTitleAndOrYear };
result = new FindMovieResult(movieByTitleAndOrYear, MovieMatchType.Title);
return true;
}
result = new MappingResult { Movie = movieByTitleAndOrYear, MappingResultType = MappingResultType.TitleNotFound };
result = new FindMovieResult(movieByTitleAndOrYear, MovieMatchType.Unknown);
return false;
}
private bool TryGetMovieBySearchCriteria(ParsedMovieInfo parsedMovieInfo, SearchCriteriaBase searchCriteria, out MappingResult result)
private bool TryGetMovieBySearchCriteria(ParsedMovieInfo parsedMovieInfo, SearchCriteriaBase searchCriteria, out FindMovieResult result)
{
Movie possibleMovie = null;
@ -228,98 +246,17 @@ private bool TryGetMovieBySearchCriteria(ParsedMovieInfo parsedMovieInfo, Search
{
if (parsedMovieInfo.Year < 1800 || possibleMovie.MovieMetadata.Value.Year == parsedMovieInfo.Year || possibleMovie.MovieMetadata.Value.SecondaryYear == parsedMovieInfo.Year)
{
result = new MappingResult { Movie = possibleMovie, MappingResultType = MappingResultType.Success };
result = new FindMovieResult(possibleMovie, MovieMatchType.Title);
return true;
}
result = new MappingResult { Movie = possibleMovie, MappingResultType = MappingResultType.WrongYear };
result = new FindMovieResult(possibleMovie, MovieMatchType.Title);
return false;
}
result = new MappingResult { Movie = searchCriteria.Movie, MappingResultType = MappingResultType.WrongTitle };
result = new FindMovieResult(searchCriteria.Movie, MovieMatchType.Unknown);
return false;
}
}
public class MappingResult
{
public string Message
{
get
{
switch (MappingResultType)
{
case MappingResultType.Success:
return $"Successfully mapped release name {ReleaseName} to movie {Movie}";
case MappingResultType.NotParsable:
return $"Failed to find movie title and/or year in release name {ReleaseName}";
case MappingResultType.TitleNotFound:
return $"Could not find {RemoteMovie.ParsedMovieInfo.PrimaryMovieTitle}";
case MappingResultType.WrongYear:
var movieYears = new HashSet<int> { RemoteMovie.Movie.MovieMetadata.Value.Year, RemoteMovie.Movie.MovieMetadata.Value.SecondaryYear.GetValueOrDefault() };
return $"Failed to map movie, expected year {string.Join(", ", movieYears.Where(x => x > 0))}, but found {RemoteMovie.ParsedMovieInfo.Year}";
case MappingResultType.WrongTitle:
var comma = RemoteMovie.Movie.MovieMetadata.Value.AlternativeTitles.Count > 0 ? ", " : "";
return
$"Failed to map movie, found title(s) {string.Join(", ", RemoteMovie.ParsedMovieInfo.MovieTitles)}, expected one of: {RemoteMovie.Movie.MovieMetadata.Value.Title}{comma}{string.Join(", ", RemoteMovie.Movie.MovieMetadata.Value.AlternativeTitles)}";
default:
return $"Failed to map movie for unknown reasons";
}
}
}
public RemoteMovie RemoteMovie;
public MappingResultType MappingResultType { get; set; }
public Movie Movie
{
get
{
return RemoteMovie.Movie;
}
set
{
ParsedMovieInfo parsedInfo = null;
if (RemoteMovie != null)
{
parsedInfo = RemoteMovie.ParsedMovieInfo;
}
RemoteMovie = new RemoteMovie
{
Movie = value,
ParsedMovieInfo = parsedInfo
};
}
}
public string ReleaseName { get; set; }
public override string ToString()
{
return string.Format(Message, RemoteMovie.Movie);
}
public Rejection ToRejection()
{
switch (MappingResultType)
{
case MappingResultType.Success:
return null;
default:
return new Rejection(Message);
}
}
}
public enum MappingResultType
{
Unknown = -1,
Success = 0,
WrongYear = 2,
WrongTitle = 3,
TitleNotFound = 4,
NotParsable = 5,
}
}

View File

@ -45,14 +45,14 @@ public ParseResource Parse(string title)
var remoteMovie = _parsingService.Map(parsedMovieInfo, "");
_aggregationService.Augment(remoteMovie.RemoteMovie);
_aggregationService.Augment(remoteMovie);
if (remoteMovie != null)
{
return new ParseResource
{
Title = title,
ParsedMovieInfo = remoteMovie.RemoteMovie.ParsedMovieInfo,
ParsedMovieInfo = remoteMovie.ParsedMovieInfo,
Movie = remoteMovie.Movie.ToResource(_configService.AvailabilityDelay)
};
}