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:
parent
7527eff268
commit
875bf0c59e
@ -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);
|
||||
|
||||
|
@ -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>()))
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
@ -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>>());
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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; }
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -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());
|
||||
|
||||
|
24
src/NzbDrone.Core/Parser/Model/FindMovieResult.cs
Normal file
24
src/NzbDrone.Core/Parser/Model/FindMovieResult.cs
Normal 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
|
||||
}
|
||||
}
|
@ -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; }
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
};
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user