1
0
mirror of https://github.com/Sonarr/Sonarr.git synced 2024-10-29 23:12:39 +01:00

New: Match search releases using IMDb ID if available

This commit is contained in:
Bogdan 2024-08-11 18:46:46 +03:00 committed by GitHub
parent 0877a6718d
commit 363f8fc347
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 181 additions and 66 deletions

View File

@ -64,7 +64,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
};
Mocker.GetMock<IParsingService>()
.Setup(c => c.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<SearchCriteriaBase>()))
.Setup(c => c.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<string>(), It.IsAny<SearchCriteriaBase>()))
.Returns(_remoteEpisode);
}
@ -154,7 +154,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
Subject.GetRssDecision(_reports).ToList();
Mocker.GetMock<IParsingService>().Verify(c => c.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<SearchCriteriaBase>()), Times.Never());
Mocker.GetMock<IParsingService>().Verify(c => c.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<string>(), It.IsAny<SearchCriteriaBase>()), Times.Never());
_pass1.Verify(c => c.IsSatisfiedBy(It.IsAny<RemoteEpisode>(), null), Times.Never());
_pass2.Verify(c => c.IsSatisfiedBy(It.IsAny<RemoteEpisode>(), null), Times.Never());
@ -169,7 +169,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
var results = Subject.GetRssDecision(_reports).ToList();
Mocker.GetMock<IParsingService>().Verify(c => c.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<SearchCriteriaBase>()), Times.Never());
Mocker.GetMock<IParsingService>().Verify(c => c.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<string>(), It.IsAny<SearchCriteriaBase>()), Times.Never());
_pass1.Verify(c => c.IsSatisfiedBy(It.IsAny<RemoteEpisode>(), null), Times.Never());
_pass2.Verify(c => c.IsSatisfiedBy(It.IsAny<RemoteEpisode>(), null), Times.Never());
@ -186,7 +186,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
Subject.GetSearchDecision(_reports, new SingleEpisodeSearchCriteria()).ToList();
Mocker.GetMock<IParsingService>().Verify(c => c.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<SearchCriteriaBase>()), Times.Never());
Mocker.GetMock<IParsingService>().Verify(c => c.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<string>(), It.IsAny<SearchCriteriaBase>()), Times.Never());
_pass1.Verify(c => c.IsSatisfiedBy(It.IsAny<RemoteEpisode>(), null), Times.Never());
_pass2.Verify(c => c.IsSatisfiedBy(It.IsAny<RemoteEpisode>(), null), Times.Never());
@ -212,7 +212,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
{
GivenSpecifications(_pass1);
Mocker.GetMock<IParsingService>().Setup(c => c.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<SearchCriteriaBase>()))
Mocker.GetMock<IParsingService>().Setup(c => c.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<string>(), It.IsAny<SearchCriteriaBase>()))
.Throws<TestException>();
_reports = new List<ReleaseInfo>
@ -224,7 +224,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
Subject.GetRssDecision(_reports);
Mocker.GetMock<IParsingService>().Verify(c => c.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<SearchCriteriaBase>()), Times.Exactly(_reports.Count));
Mocker.GetMock<IParsingService>().Verify(c => c.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<string>(), It.IsAny<SearchCriteriaBase>()), Times.Exactly(_reports.Count));
ExceptionVerification.ExpectedErrors(3);
}
@ -263,8 +263,8 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
}).ToList();
Mocker.GetMock<IParsingService>()
.Setup(v => v.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<SearchCriteriaBase>()))
.Returns<ParsedEpisodeInfo, int, int, SearchCriteriaBase>((p, tvdbid, tvrageid, c) =>
.Setup(v => v.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<string>(), It.IsAny<SearchCriteriaBase>()))
.Returns<ParsedEpisodeInfo, int, int, string, SearchCriteriaBase>((p, _, _, _, _) =>
new RemoteEpisode
{
DownloadAllowed = true,
@ -318,7 +318,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
{
GivenSpecifications(_pass1);
Mocker.GetMock<IParsingService>().Setup(c => c.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<SearchCriteriaBase>()))
Mocker.GetMock<IParsingService>().Setup(c => c.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<string>(), It.IsAny<SearchCriteriaBase>()))
.Throws<TestException>();
_reports = new List<ReleaseInfo>

View File

@ -10,7 +10,6 @@ using NzbDrone.Common.Http;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Download;
using NzbDrone.Core.Indexers;
using NzbDrone.Core.IndexerSearch.Definitions;
using NzbDrone.Core.Localization;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
@ -35,7 +34,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests
.Returns(30);
Mocker.GetMock<IParsingService>()
.Setup(s => s.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>(), It.IsAny<int>(), (SearchCriteriaBase)null))
.Setup(s => s.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<string>(), null))
.Returns(() => CreateRemoteEpisode());
Mocker.GetMock<IHttpClient>()

View File

@ -118,7 +118,7 @@ namespace NzbDrone.Core.Test.Download.TrackedDownloads
.Returns(remoteEpisode);
Mocker.GetMock<IParsingService>()
.Setup(s => s.ParseSpecialEpisodeTitle(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<string>(), It.IsAny<int>(), It.IsAny<int>(), null))
.Setup(s => s.ParseSpecialEpisodeTitle(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<string>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<string>(), null))
.Returns(remoteEpisode.ParsedEpisodeInfo);
var client = new DownloadClientDefinition()
@ -169,7 +169,7 @@ namespace NzbDrone.Core.Test.Download.TrackedDownloads
};
Mocker.GetMock<IParsingService>()
.Setup(s => s.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>(), It.IsAny<int>(), null))
.Setup(s => s.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<string>(), null))
.Returns(remoteEpisode);
Mocker.GetMock<IHistoryService>()
@ -199,7 +199,7 @@ namespace NzbDrone.Core.Test.Download.TrackedDownloads
Subject.GetTrackedDownloads().Should().HaveCount(1);
Mocker.GetMock<IParsingService>()
.Setup(s => s.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>(), It.IsAny<int>(), null))
.Setup(s => s.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<string>(), null))
.Returns(default(RemoteEpisode));
Subject.Handle(new EpisodeInfoRefreshedEvent(remoteEpisode.Series, new List<Episode>(), new List<Episode>(), remoteEpisode.Episodes));
@ -228,7 +228,7 @@ namespace NzbDrone.Core.Test.Download.TrackedDownloads
};
Mocker.GetMock<IParsingService>()
.Setup(s => s.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>(), It.IsAny<int>(), null))
.Setup(s => s.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<string>(), null))
.Returns(default(RemoteEpisode));
Mocker.GetMock<IHistoryService>()
@ -258,7 +258,7 @@ namespace NzbDrone.Core.Test.Download.TrackedDownloads
Subject.GetTrackedDownloads().Should().HaveCount(1);
Mocker.GetMock<IParsingService>()
.Setup(s => s.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>(), It.IsAny<int>(), null))
.Setup(s => s.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<string>(), null))
.Returns(default(RemoteEpisode));
Subject.Handle(new EpisodeInfoRefreshedEvent(remoteEpisode.Series, new List<Episode>(), new List<Episode>(), remoteEpisode.Episodes));
@ -287,7 +287,7 @@ namespace NzbDrone.Core.Test.Download.TrackedDownloads
};
Mocker.GetMock<IParsingService>()
.Setup(s => s.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>(), It.IsAny<int>(), null))
.Setup(s => s.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<string>(), null))
.Returns(default(RemoteEpisode));
Mocker.GetMock<IHistoryService>()
@ -317,7 +317,7 @@ namespace NzbDrone.Core.Test.Download.TrackedDownloads
Subject.GetTrackedDownloads().Should().HaveCount(1);
Mocker.GetMock<IParsingService>()
.Setup(s => s.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>(), It.IsAny<int>(), null))
.Setup(s => s.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<string>(), null))
.Returns(default(RemoteEpisode));
Subject.Handle(new SeriesDeletedEvent(new List<Series> { remoteEpisode.Series }, true, true));

View File

@ -233,11 +233,11 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Specifications
GivenEpisodes(actualInfo, actualInfo.EpisodeNumbers);
Mocker.GetMock<IParsingService>()
.Setup(v => v.ParseSpecialEpisodeTitle(fileInfo, It.IsAny<string>(), 0, 0, null))
.Setup(v => v.ParseSpecialEpisodeTitle(fileInfo, It.IsAny<string>(), 0, 0, null, null))
.Returns(actualInfo);
Mocker.GetMock<IParsingService>()
.Setup(v => v.ParseSpecialEpisodeTitle(folderInfo, It.IsAny<string>(), 0, 0, null))
.Setup(v => v.ParseSpecialEpisodeTitle(folderInfo, It.IsAny<string>(), 0, 0, null, null))
.Returns(actualInfo);
Subject.IsSatisfiedBy(localEpisode, null).Accepted.Should().BeTrue();

View File

@ -91,7 +91,7 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
GivenDailySeries();
GivenDailyParseResult();
Subject.Map(_parsedEpisodeInfo, _series.TvdbId, _series.TvRageId);
Subject.Map(_parsedEpisodeInfo, _series.TvdbId, _series.TvRageId, _series.ImdbId);
Mocker.GetMock<IEpisodeService>()
.Verify(v => v.FindEpisode(It.IsAny<int>(), It.IsAny<string>(), null), Times.Once());
@ -103,7 +103,7 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
GivenDailySeries();
GivenDailyParseResult();
Subject.Map(_parsedEpisodeInfo, _series.TvdbId, _series.TvRageId, _singleEpisodeSearchCriteria);
Subject.Map(_parsedEpisodeInfo, _series.TvdbId, _series.TvRageId, _series.ImdbId, _singleEpisodeSearchCriteria);
Mocker.GetMock<IEpisodeService>()
.Verify(v => v.FindEpisode(It.IsAny<int>(), It.IsAny<string>(), null), Times.Never());
@ -115,7 +115,7 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
GivenDailySeries();
_parsedEpisodeInfo.AirDate = DateTime.Today.AddDays(-5).ToString(Episode.AIR_DATE_FORMAT);
Subject.Map(_parsedEpisodeInfo, _series.TvdbId, _series.TvRageId, _singleEpisodeSearchCriteria);
Subject.Map(_parsedEpisodeInfo, _series.TvdbId, _series.TvRageId, _series.ImdbId, _singleEpisodeSearchCriteria);
Mocker.GetMock<IEpisodeService>()
.Verify(v => v.FindEpisode(It.IsAny<int>(), It.IsAny<string>(), null), Times.Once());
@ -128,7 +128,7 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
GivenDailyParseResult();
_parsedEpisodeInfo.DailyPart = 1;
Subject.Map(_parsedEpisodeInfo, _series.TvdbId, _series.TvRageId);
Subject.Map(_parsedEpisodeInfo, _series.TvdbId, _series.TvRageId, _series.ImdbId);
Mocker.GetMock<IEpisodeService>()
.Verify(v => v.FindEpisode(It.IsAny<int>(), It.IsAny<string>(), 1), Times.Once());
@ -143,7 +143,7 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
.Setup(s => s.FindEpisodesBySceneNumbering(It.IsAny<int>(), It.IsAny<int>()))
.Returns(new List<Episode>());
Subject.Map(_parsedEpisodeInfo, _series.TvdbId, _series.TvRageId, _singleEpisodeSearchCriteria);
Subject.Map(_parsedEpisodeInfo, _series.TvdbId, _series.TvRageId, _series.ImdbId, _singleEpisodeSearchCriteria);
Mocker.GetMock<IEpisodeService>()
.Verify(v => v.FindEpisode(It.IsAny<int>(), It.IsAny<string>(), null), Times.Never());
@ -154,7 +154,7 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
{
GivenSceneNumberingSeries();
Subject.Map(_parsedEpisodeInfo, _series.TvdbId, _series.TvRageId);
Subject.Map(_parsedEpisodeInfo, _series.TvdbId, _series.TvRageId, _series.ImdbId);
Mocker.GetMock<IEpisodeService>()
.Verify(v => v.FindEpisodesBySceneNumbering(It.IsAny<int>(), It.IsAny<int>(), It.IsAny<int>()), Times.Once());
@ -165,7 +165,7 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
{
GivenSceneNumberingSeries();
Subject.Map(_parsedEpisodeInfo, _series.TvdbId, _series.TvRageId, _singleEpisodeSearchCriteria);
Subject.Map(_parsedEpisodeInfo, _series.TvdbId, _series.TvRageId, _series.ImdbId, _singleEpisodeSearchCriteria);
Mocker.GetMock<IEpisodeService>()
.Verify(v => v.FindEpisodesBySceneNumbering(It.IsAny<int>(), It.IsAny<int>(), It.IsAny<int>()), Times.Never());
@ -177,7 +177,7 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
GivenSceneNumberingSeries();
_episodes.First().SceneEpisodeNumber = 10;
Subject.Map(_parsedEpisodeInfo, _series.TvdbId, _series.TvRageId, _singleEpisodeSearchCriteria);
Subject.Map(_parsedEpisodeInfo, _series.TvdbId, _series.TvRageId, _series.ImdbId, _singleEpisodeSearchCriteria);
Mocker.GetMock<IEpisodeService>()
.Verify(v => v.FindEpisodesBySceneNumbering(It.IsAny<int>(), It.IsAny<int>(), It.IsAny<int>()), Times.Once());
@ -186,7 +186,7 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
[Test]
public void should_find_episode()
{
Subject.Map(_parsedEpisodeInfo, _series.TvdbId, _series.TvRageId);
Subject.Map(_parsedEpisodeInfo, _series.TvdbId, _series.TvRageId, _series.ImdbId);
Mocker.GetMock<IEpisodeService>()
.Verify(v => v.FindEpisode(It.IsAny<int>(), It.IsAny<int>(), It.IsAny<int>()), Times.Once());
@ -195,7 +195,7 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
[Test]
public void should_match_episode_with_search_criteria()
{
Subject.Map(_parsedEpisodeInfo, _series.TvdbId, _series.TvRageId, _singleEpisodeSearchCriteria);
Subject.Map(_parsedEpisodeInfo, _series.TvdbId, _series.TvRageId, _series.ImdbId, _singleEpisodeSearchCriteria);
Mocker.GetMock<IEpisodeService>()
.Verify(v => v.FindEpisode(It.IsAny<int>(), It.IsAny<int>(), It.IsAny<int>()), Times.Never());
@ -206,7 +206,7 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
{
_episodes.First().EpisodeNumber = 10;
Subject.Map(_parsedEpisodeInfo, _series.TvdbId, _series.TvRageId, _singleEpisodeSearchCriteria);
Subject.Map(_parsedEpisodeInfo, _series.TvdbId, _series.TvRageId, _series.ImdbId, _singleEpisodeSearchCriteria);
Mocker.GetMock<IEpisodeService>()
.Verify(v => v.FindEpisode(It.IsAny<int>(), It.IsAny<int>(), It.IsAny<int>()), Times.Once());
@ -537,7 +537,7 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
.With(e => e.EpisodeNumber = 1)
.Build());
Subject.Map(_parsedEpisodeInfo, _series.TvdbId, _series.TvRageId);
Subject.Map(_parsedEpisodeInfo, _series.TvdbId, _series.TvRageId, _series.ImdbId);
Mocker.GetMock<IEpisodeService>()
.Verify(v => v.FindEpisode(_series.TvdbId, 0, 1), Times.Once());
@ -555,7 +555,7 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
.Setup(s => s.FindEpisodeByTitle(_series.TvdbId, 0, _parsedEpisodeInfo.ReleaseTitle))
.Returns((Episode)null);
Subject.Map(_parsedEpisodeInfo, _series.TvdbId, _series.TvRageId);
Subject.Map(_parsedEpisodeInfo, _series.TvdbId, _series.TvRageId, _series.ImdbId);
Mocker.GetMock<IEpisodeService>()
.Verify(v => v.FindEpisode(_series.TvdbId, _parsedEpisodeInfo.SeasonNumber, _parsedEpisodeInfo.EpisodeNumbers.First()), Times.Once());

View File

@ -86,7 +86,7 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
{
GivenMatchBySeriesTitle();
Subject.Map(_parsedEpisodeInfo, _series.TvdbId, _series.TvRageId);
Subject.Map(_parsedEpisodeInfo, _series.TvdbId, _series.TvRageId, _series.ImdbId);
Mocker.GetMock<ISeriesService>()
.Verify(v => v.FindByTitle(It.IsAny<string>()), Times.Once());
@ -97,7 +97,7 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
{
GivenMatchByTvdbId();
Subject.Map(_parsedEpisodeInfo, _series.TvdbId, _series.TvRageId);
Subject.Map(_parsedEpisodeInfo, _series.TvdbId, _series.TvRageId, _series.ImdbId);
Mocker.GetMock<ISeriesService>()
.Verify(v => v.FindByTvdbId(It.IsAny<int>()), Times.Once());
@ -108,7 +108,7 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
{
GivenMatchByTvRageId();
Subject.Map(_parsedEpisodeInfo, 0, _series.TvRageId);
Subject.Map(_parsedEpisodeInfo, 0, _series.TvRageId, null);
Mocker.GetMock<ISeriesService>()
.Verify(v => v.FindByTvRageId(It.IsAny<int>()), Times.Once());
@ -123,7 +123,7 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
.Setup(v => v.FindSceneMapping(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<int>()))
.Returns(new SceneMapping { TvdbId = 10 });
var result = Subject.Map(_parsedEpisodeInfo, _series.TvdbId, _series.TvRageId);
var result = Subject.Map(_parsedEpisodeInfo, _series.TvdbId, _series.TvRageId, _series.ImdbId);
Mocker.GetMock<ISeriesService>()
.Verify(v => v.FindByTvRageId(It.IsAny<int>()), Times.Never());
@ -136,7 +136,7 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
{
GivenMatchBySeriesTitle();
Subject.Map(_parsedEpisodeInfo, _series.TvdbId, _series.TvRageId, _singleEpisodeSearchCriteria);
Subject.Map(_parsedEpisodeInfo, _series.TvdbId, _series.TvRageId, _series.ImdbId, _singleEpisodeSearchCriteria);
Mocker.GetMock<ISeriesService>()
.Verify(v => v.FindByTitle(It.IsAny<string>()), Times.Never());
@ -147,7 +147,7 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
{
GivenParseResultSeriesDoesntMatchSearchCriteria();
Subject.Map(_parsedEpisodeInfo, 10, 10, _singleEpisodeSearchCriteria);
Subject.Map(_parsedEpisodeInfo, 10, 10, null, _singleEpisodeSearchCriteria);
Mocker.GetMock<ISeriesService>()
.Verify(v => v.FindByTitle(It.IsAny<string>()), Times.Once());
@ -169,7 +169,7 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
.Setup(s => s.FindByTitle(_parsedEpisodeInfo.SeriesTitleInfo.TitleWithoutYear, _parsedEpisodeInfo.SeriesTitleInfo.Year))
.Returns(_series);
Subject.Map(_parsedEpisodeInfo, 10, 10, _singleEpisodeSearchCriteria);
Subject.Map(_parsedEpisodeInfo, 10, 10, null, _singleEpisodeSearchCriteria);
Mocker.GetMock<ISeriesService>()
.Verify(v => v.FindByTitle(It.IsAny<string>(), It.IsAny<int>()), Times.Once());
@ -180,7 +180,7 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
{
GivenParseResultSeriesDoesntMatchSearchCriteria();
Subject.Map(_parsedEpisodeInfo, 10, 10, _singleEpisodeSearchCriteria);
Subject.Map(_parsedEpisodeInfo, 10, 10, null, _singleEpisodeSearchCriteria);
Mocker.GetMock<ISeriesService>()
.Verify(v => v.FindByTvdbId(It.IsAny<int>()), Times.Once());
@ -191,7 +191,7 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
{
GivenParseResultSeriesDoesntMatchSearchCriteria();
Subject.Map(_parsedEpisodeInfo, 0, 10, _singleEpisodeSearchCriteria);
Subject.Map(_parsedEpisodeInfo, 0, 10, null, _singleEpisodeSearchCriteria);
Mocker.GetMock<ISeriesService>()
.Verify(v => v.FindByTvRageId(It.IsAny<int>()), Times.Once());
@ -202,12 +202,34 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
{
GivenParseResultSeriesDoesntMatchSearchCriteria();
Subject.Map(_parsedEpisodeInfo, 10, 10, _singleEpisodeSearchCriteria);
Subject.Map(_parsedEpisodeInfo, 10, 10, null, _singleEpisodeSearchCriteria);
Mocker.GetMock<ISeriesService>()
.Verify(v => v.FindByTvRageId(It.IsAny<int>()), Times.Never());
}
[Test]
public void should_FindByImdbId_when_search_criteria_and_FindByTitle_matching_fails()
{
GivenParseResultSeriesDoesntMatchSearchCriteria();
Subject.Map(_parsedEpisodeInfo, 0, 0, "tt12345", _singleEpisodeSearchCriteria);
Mocker.GetMock<ISeriesService>()
.Verify(v => v.FindByImdbId(It.IsAny<string>()), Times.Once());
}
[Test]
public void should_not_FindByImdbId_when_search_criteria_and_FindByTitle_matching_fails_and_tvdb_id_is_specified()
{
GivenParseResultSeriesDoesntMatchSearchCriteria();
Subject.Map(_parsedEpisodeInfo, 10, 10, "tt12345", _singleEpisodeSearchCriteria);
Mocker.GetMock<ISeriesService>()
.Verify(v => v.FindByImdbId(It.IsAny<string>()), Times.Never());
}
[Test]
public void should_use_tvdbid_matching_when_alias_is_found()
{
@ -215,7 +237,7 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
.Setup(s => s.FindTvdbId(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<int>()))
.Returns(_series.TvdbId);
Subject.Map(_parsedEpisodeInfo, _series.TvdbId, _series.TvRageId, _singleEpisodeSearchCriteria);
Subject.Map(_parsedEpisodeInfo, _series.TvdbId, _series.TvRageId, _series.ImdbId, _singleEpisodeSearchCriteria);
Mocker.GetMock<ISeriesService>()
.Verify(v => v.FindByTitle(It.IsAny<string>()), Times.Never());
@ -226,7 +248,7 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
{
GivenParseResultSeriesDoesntMatchSearchCriteria();
Subject.Map(_parsedEpisodeInfo, _series.TvdbId, _series.TvRageId, _singleEpisodeSearchCriteria);
Subject.Map(_parsedEpisodeInfo, _series.TvdbId, _series.TvRageId, _series.ImdbId, _singleEpisodeSearchCriteria);
Mocker.GetMock<ISeriesService>()
.Verify(v => v.FindByTitle(It.IsAny<string>()), Times.Never());

View File

@ -80,7 +80,7 @@ namespace NzbDrone.Core.DecisionEngine
if (parsedEpisodeInfo == null || parsedEpisodeInfo.IsPossibleSpecialEpisode)
{
var specialEpisodeInfo = _parsingService.ParseSpecialEpisodeTitle(parsedEpisodeInfo, report.Title, report.TvdbId, report.TvRageId, searchCriteria);
var specialEpisodeInfo = _parsingService.ParseSpecialEpisodeTitle(parsedEpisodeInfo, report.Title, report.TvdbId, report.TvRageId, report.ImdbId, searchCriteria);
if (specialEpisodeInfo != null)
{
@ -90,7 +90,7 @@ namespace NzbDrone.Core.DecisionEngine
if (parsedEpisodeInfo != null && !parsedEpisodeInfo.SeriesTitle.IsNullOrWhiteSpace())
{
var remoteEpisode = _parsingService.Map(parsedEpisodeInfo, report.TvdbId, report.TvRageId, searchCriteria);
var remoteEpisode = _parsingService.Map(parsedEpisodeInfo, report.TvdbId, report.TvRageId, report.ImdbId, searchCriteria);
remoteEpisode.Release = report;
if (remoteEpisode.Series == null)

View File

@ -119,7 +119,7 @@ namespace NzbDrone.Core.Download.TrackedDownloads
if (parsedEpisodeInfo != null)
{
trackedDownload.RemoteEpisode = _parsingService.Map(parsedEpisodeInfo, 0, 0);
trackedDownload.RemoteEpisode = _parsingService.Map(parsedEpisodeInfo, 0, 0, null);
_aggregationService.Augment(trackedDownload.RemoteEpisode);
}
@ -147,7 +147,7 @@ namespace NzbDrone.Core.Download.TrackedDownloads
// Try parsing the original source title and if that fails, try parsing it as a special
// TODO: Pass the TVDB ID and TVRage IDs in as well so we have a better chance for finding the item
parsedEpisodeInfo = Parser.Parser.ParseTitle(firstHistoryItem.SourceTitle) ??
_parsingService.ParseSpecialEpisodeTitle(parsedEpisodeInfo, firstHistoryItem.SourceTitle, 0, 0);
_parsingService.ParseSpecialEpisodeTitle(parsedEpisodeInfo, firstHistoryItem.SourceTitle, 0, 0, null);
if (parsedEpisodeInfo != null)
{
@ -234,7 +234,7 @@ namespace NzbDrone.Core.Download.TrackedDownloads
{
var parsedEpisodeInfo = Parser.Parser.ParseTitle(trackedDownload.DownloadItem.Title);
trackedDownload.RemoteEpisode = parsedEpisodeInfo == null ? null : _parsingService.Map(parsedEpisodeInfo, 0, 0);
trackedDownload.RemoteEpisode = parsedEpisodeInfo == null ? null : _parsingService.Map(parsedEpisodeInfo, 0, 0, null);
_aggregationService.Augment(trackedDownload.RemoteEpisode);
}

View File

@ -165,6 +165,7 @@ namespace NzbDrone.Core.History
history.Data.Add("Guid", message.Episode.Release.Guid);
history.Data.Add("TvdbId", message.Episode.Release.TvdbId.ToString());
history.Data.Add("TvRageId", message.Episode.Release.TvRageId.ToString());
history.Data.Add("ImdbId", message.Episode.Release.ImdbId);
history.Data.Add("Protocol", ((int)message.Episode.Release.DownloadProtocol).ToString());
history.Data.Add("CustomFormatScore", message.Episode.CustomFormatScore.ToString());
history.Data.Add("SeriesMatchType", message.Episode.SeriesMatchType.ToString());

View File

@ -95,6 +95,11 @@ namespace NzbDrone.Core.Indexers.BroadcastheNet
torrentInfo.TvRageId = torrent.TvrageID.Value;
}
if (torrent.ImdbID.IsNotNullOrWhiteSpace() && int.TryParse(torrent.ImdbID, out var imdbId) && imdbId > 0)
{
torrentInfo.ImdbId = $"tt{imdbId:D7}";
}
results.Add(torrentInfo);
}

View File

@ -38,7 +38,7 @@ namespace NzbDrone.Core.Indexers.FileList
{
var id = result.Id;
torrentInfos.Add(new TorrentInfo
var torrentInfo = new TorrentInfo
{
Guid = $"FileList-{id}",
Title = result.Name,
@ -48,9 +48,15 @@ namespace NzbDrone.Core.Indexers.FileList
Seeders = result.Seeders,
Peers = result.Leechers + result.Seeders,
PublishDate = result.UploadDate.ToUniversalTime(),
ImdbId = result.ImdbId,
IndexerFlags = GetIndexerFlags(result)
});
};
if (result.ImdbId is { Length: > 2 } && int.TryParse(result.ImdbId.TrimStart('t'), out var imdbId) && imdbId > 0)
{
torrentInfo.ImdbId = $"tt{imdbId:D7}";
}
torrentInfos.Add(torrentInfo);
}
return torrentInfos.ToArray();

View File

@ -90,6 +90,7 @@ namespace NzbDrone.Core.Indexers.Newznab
releaseInfo.TvdbId = GetTvdbId(item);
releaseInfo.TvRageId = GetTvRageId(item);
releaseInfo.ImdbId = GetImdbId(item);
return releaseInfo;
}
@ -182,6 +183,18 @@ namespace NzbDrone.Core.Indexers.Newznab
return 0;
}
protected virtual string GetImdbId(XElement item)
{
var imdbIdString = TryGetNewznabAttribute(item, "imdb");
if (!imdbIdString.IsNullOrWhiteSpace() && int.TryParse(imdbIdString, out var imdbId) && imdbId > 0)
{
return $"tt{imdbId:D7}";
}
return null;
}
protected string TryGetNewznabAttribute(XElement item, string key, string defaultValue = "")
{
var attrElement = item.Elements(ns + "attr").FirstOrDefault(e => e.Attribute("name").Value.Equals(key, StringComparison.OrdinalIgnoreCase));

View File

@ -83,6 +83,7 @@ namespace NzbDrone.Core.Indexers.Torznab
{
torrentInfo.TvdbId = GetTvdbId(item);
torrentInfo.TvRageId = GetTvRageId(item);
releaseInfo.ImdbId = GetImdbId(item);
torrentInfo.IndexerFlags = GetFlags(item);
}
@ -177,6 +178,18 @@ namespace NzbDrone.Core.Indexers.Torznab
return 0;
}
protected virtual string GetImdbId(XElement item)
{
var imdbIdString = TryGetTorznabAttribute(item, "imdb");
if (!imdbIdString.IsNullOrWhiteSpace() && int.TryParse(imdbIdString, out var imdbId) && imdbId > 0)
{
return $"tt{imdbId:D7}";
}
return null;
}
protected override string GetInfoHash(XElement item)
{
return TryGetTorznabAttribute(item, "infohash");

View File

@ -33,12 +33,12 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Specifications
if (fileInfo != null && fileInfo.IsPossibleSceneSeasonSpecial)
{
fileInfo = _parsingService.ParseSpecialEpisodeTitle(fileInfo, fileInfo.ReleaseTitle, localEpisode.Series.TvdbId, 0);
fileInfo = _parsingService.ParseSpecialEpisodeTitle(fileInfo, fileInfo.ReleaseTitle, localEpisode.Series.TvdbId, 0, null);
}
if (folderInfo != null && folderInfo.IsPossibleSceneSeasonSpecial)
{
folderInfo = _parsingService.ParseSpecialEpisodeTitle(folderInfo, folderInfo.ReleaseTitle, localEpisode.Series.TvdbId, 0);
folderInfo = _parsingService.ParseSpecialEpisodeTitle(folderInfo, folderInfo.ReleaseTitle, localEpisode.Series.TvdbId, 0, null);
}
if (folderInfo == null)

View File

@ -103,6 +103,7 @@ namespace NzbDrone.Core.Parser.Model
stringBuilder.AppendLine("DownloadProtocol: " + DownloadProtocol ?? "Empty");
stringBuilder.AppendLine("TvdbId: " + TvdbId ?? "Empty");
stringBuilder.AppendLine("TvRageId: " + TvRageId ?? "Empty");
stringBuilder.AppendLine("ImdbId: " + ImdbId ?? "Empty");
stringBuilder.AppendLine("PublishDate: " + PublishDate ?? "Empty");
return stringBuilder.ToString();
default:

View File

@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using NLog;
@ -13,11 +14,11 @@ namespace NzbDrone.Core.Parser
public interface IParsingService
{
Series GetSeries(string title);
RemoteEpisode Map(ParsedEpisodeInfo parsedEpisodeInfo, int tvdbId, int tvRageId, SearchCriteriaBase searchCriteria = null);
RemoteEpisode Map(ParsedEpisodeInfo parsedEpisodeInfo, int tvdbId, int tvRageId, string imdbId, SearchCriteriaBase searchCriteria = null);
RemoteEpisode Map(ParsedEpisodeInfo parsedEpisodeInfo, Series series);
RemoteEpisode Map(ParsedEpisodeInfo parsedEpisodeInfo, int seriesId, IEnumerable<int> episodeIds);
List<Episode> GetEpisodes(ParsedEpisodeInfo parsedEpisodeInfo, Series series, bool sceneSource, SearchCriteriaBase searchCriteria = null);
ParsedEpisodeInfo ParseSpecialEpisodeTitle(ParsedEpisodeInfo parsedEpisodeInfo, string releaseTitle, int tvdbId, int tvRageId, SearchCriteriaBase searchCriteria = null);
ParsedEpisodeInfo ParseSpecialEpisodeTitle(ParsedEpisodeInfo parsedEpisodeInfo, string releaseTitle, int tvdbId, int tvRageId, string imdbId, SearchCriteriaBase searchCriteria = null);
ParsedEpisodeInfo ParseSpecialEpisodeTitle(ParsedEpisodeInfo parsedEpisodeInfo, string releaseTitle, Series series);
}
@ -115,14 +116,14 @@ namespace NzbDrone.Core.Parser
return foundSeries;
}
public RemoteEpisode Map(ParsedEpisodeInfo parsedEpisodeInfo, int tvdbId, int tvRageId, SearchCriteriaBase searchCriteria = null)
public RemoteEpisode Map(ParsedEpisodeInfo parsedEpisodeInfo, int tvdbId, int tvRageId, string imdbId, SearchCriteriaBase searchCriteria = null)
{
return Map(parsedEpisodeInfo, tvdbId, tvRageId, null, searchCriteria);
return Map(parsedEpisodeInfo, tvdbId, tvRageId, imdbId, null, searchCriteria);
}
public RemoteEpisode Map(ParsedEpisodeInfo parsedEpisodeInfo, Series series)
{
return Map(parsedEpisodeInfo, 0, 0, series, null);
return Map(parsedEpisodeInfo, 0, 0, null, series, null);
}
public RemoteEpisode Map(ParsedEpisodeInfo parsedEpisodeInfo, int seriesId, IEnumerable<int> episodeIds)
@ -135,7 +136,7 @@ namespace NzbDrone.Core.Parser
};
}
private RemoteEpisode Map(ParsedEpisodeInfo parsedEpisodeInfo, int tvdbId, int tvRageId, Series series, SearchCriteriaBase searchCriteria)
private RemoteEpisode Map(ParsedEpisodeInfo parsedEpisodeInfo, int tvdbId, int tvRageId, string imdbId, Series series, SearchCriteriaBase searchCriteria)
{
var sceneMapping = _sceneMappingService.FindSceneMapping(parsedEpisodeInfo.SeriesTitle, parsedEpisodeInfo.ReleaseTitle, parsedEpisodeInfo.SeasonNumber);
@ -171,7 +172,7 @@ namespace NzbDrone.Core.Parser
if (series == null)
{
var seriesMatch = FindSeries(parsedEpisodeInfo, tvdbId, tvRageId, sceneMapping, searchCriteria);
var seriesMatch = FindSeries(parsedEpisodeInfo, tvdbId, tvRageId, imdbId, sceneMapping, searchCriteria);
if (seriesMatch != null)
{
@ -210,7 +211,7 @@ namespace NzbDrone.Core.Parser
{
if (sceneSource)
{
var remoteEpisode = Map(parsedEpisodeInfo, 0, 0, series, searchCriteria);
var remoteEpisode = Map(parsedEpisodeInfo, 0, 0, null, series, searchCriteria);
return remoteEpisode.Episodes;
}
@ -272,7 +273,7 @@ namespace NzbDrone.Core.Parser
return GetStandardEpisodes(series, parsedEpisodeInfo, mappedSeasonNumber, sceneSource, searchCriteria);
}
public ParsedEpisodeInfo ParseSpecialEpisodeTitle(ParsedEpisodeInfo parsedEpisodeInfo, string releaseTitle, int tvdbId, int tvRageId, SearchCriteriaBase searchCriteria = null)
public ParsedEpisodeInfo ParseSpecialEpisodeTitle(ParsedEpisodeInfo parsedEpisodeInfo, string releaseTitle, int tvdbId, int tvRageId, string imdbId, SearchCriteriaBase searchCriteria = null)
{
if (searchCriteria != null)
{
@ -285,6 +286,11 @@ namespace NzbDrone.Core.Parser
{
return ParseSpecialEpisodeTitle(parsedEpisodeInfo, releaseTitle, searchCriteria.Series);
}
if (imdbId.IsNotNullOrWhiteSpace() && imdbId.Equals(searchCriteria.Series.ImdbId, StringComparison.Ordinal))
{
return ParseSpecialEpisodeTitle(parsedEpisodeInfo, releaseTitle, searchCriteria.Series);
}
}
var series = GetSeries(releaseTitle);
@ -304,6 +310,11 @@ namespace NzbDrone.Core.Parser
series = _seriesService.FindByTvRageId(tvRageId);
}
if (series == null && imdbId.IsNotNullOrWhiteSpace())
{
series = _seriesService.FindByImdbId(imdbId);
}
if (series == null)
{
_logger.Debug("No matching series {0}", releaseTitle);
@ -354,7 +365,7 @@ namespace NzbDrone.Core.Parser
return null;
}
private FindSeriesResult FindSeries(ParsedEpisodeInfo parsedEpisodeInfo, int tvdbId, int tvRageId, SceneMapping sceneMapping, SearchCriteriaBase searchCriteria)
private FindSeriesResult FindSeries(ParsedEpisodeInfo parsedEpisodeInfo, int tvdbId, int tvRageId, string imdbId, SceneMapping sceneMapping, SearchCriteriaBase searchCriteria)
{
Series series = null;
@ -406,6 +417,18 @@ namespace NzbDrone.Core.Parser
return new FindSeriesResult(searchCriteria.Series, SeriesMatchType.Id);
}
if (imdbId.IsNotNullOrWhiteSpace() && imdbId.Equals(searchCriteria.Series.ImdbId, StringComparison.Ordinal) && tvdbId <= 0)
{
_logger.Debug()
.Message("Found matching series by IMDb ID {0}, an alias may be needed for: {1}", imdbId, parsedEpisodeInfo.SeriesTitle)
.Property("ImdbId", imdbId)
.Property("ParsedEpisodeInfo", parsedEpisodeInfo)
.WriteSentryWarn("ImdbIdMatch", imdbId, parsedEpisodeInfo.SeriesTitle)
.Write();
return new FindSeriesResult(searchCriteria.Series, SeriesMatchType.Id);
}
}
var matchType = SeriesMatchType.Unknown;
@ -462,6 +485,23 @@ namespace NzbDrone.Core.Parser
}
}
if (series == null && imdbId.IsNotNullOrWhiteSpace() && tvdbId <= 0)
{
series = _seriesService.FindByImdbId(imdbId);
if (series != null)
{
_logger.Debug()
.Message("Found matching series by IMDb ID {0}, an alias may be needed for: {1}", imdbId, parsedEpisodeInfo.SeriesTitle)
.Property("ImdbId", imdbId)
.Property("ParsedEpisodeInfo", parsedEpisodeInfo)
.WriteSentryWarn("ImdbIdMatch", imdbId, parsedEpisodeInfo.SeriesTitle)
.Write();
matchType = SeriesMatchType.Id;
}
}
if (series == null)
{
_logger.Debug("No matching series {0}", parsedEpisodeInfo.SeriesTitle);

View File

@ -14,6 +14,7 @@ namespace NzbDrone.Core.Tv
List<Series> FindByTitleInexact(string cleanTitle);
Series FindByTvdbId(int tvdbId);
Series FindByTvRageId(int tvRageId);
Series FindByImdbId(string imdbId);
Series FindByPath(string path);
List<int> AllSeriesTvdbIds();
Dictionary<int, string> AllSeriesPaths();
@ -73,6 +74,11 @@ namespace NzbDrone.Core.Tv
return Query(s => s.TvRageId == tvRageId).SingleOrDefault();
}
public Series FindByImdbId(string imdbId)
{
return Query(s => s.ImdbId == imdbId).SingleOrDefault();
}
public Series FindByPath(string path)
{
return Query(s => s.Path == path)

View File

@ -17,6 +17,7 @@ namespace NzbDrone.Core.Tv
List<Series> AddSeries(List<Series> newSeries);
Series FindByTvdbId(int tvdbId);
Series FindByTvRageId(int tvRageId);
Series FindByImdbId(string imdbId);
Series FindByTitle(string title);
Series FindByTitle(string title, int year);
Series FindByTitleInexact(string title);
@ -94,6 +95,11 @@ namespace NzbDrone.Core.Tv
return _seriesRepository.FindByTvRageId(tvRageId);
}
public Series FindByImdbId(string imdbId)
{
return _seriesRepository.FindByImdbId(imdbId);
}
public Series FindByTitle(string title)
{
return _seriesRepository.FindByTitle(title.CleanSeriesTitle());

View File

@ -48,6 +48,7 @@ namespace Sonarr.Api.V3.Indexers
public bool Rejected { get; set; }
public int TvdbId { get; set; }
public int TvRageId { get; set; }
public string ImdbId { get; set; }
public IEnumerable<string> Rejections { get; set; }
public DateTime PublishDate { get; set; }
public string CommentUrl { get; set; }
@ -136,6 +137,7 @@ namespace Sonarr.Api.V3.Indexers
Rejected = model.Rejected,
TvdbId = releaseInfo.TvdbId,
TvRageId = releaseInfo.TvRageId,
ImdbId = releaseInfo.ImdbId,
Rejections = model.Rejections.Select(r => r.Reason).ToList(),
PublishDate = releaseInfo.PublishDate,
CommentUrl = releaseInfo.CommentUrl,
@ -194,6 +196,7 @@ namespace Sonarr.Api.V3.Indexers
model.DownloadProtocol = resource.Protocol;
model.TvdbId = resource.TvdbId;
model.TvRageId = resource.TvRageId;
model.ImdbId = resource.ImdbId;
model.PublishDate = resource.PublishDate.ToUniversalTime();
return model;

View File

@ -45,7 +45,7 @@ namespace Sonarr.Api.V3.Parse
};
}
var remoteEpisode = _parsingService.Map(parsedEpisodeInfo, 0, 0);
var remoteEpisode = _parsingService.Map(parsedEpisodeInfo, 0, 0, null);
if (remoteEpisode != null)
{