New: Searching for episodes with season level scene mapping now possible instead of only via RssSync (Newznab/Torznab only)

This commit is contained in:
Taloth Saldono 2020-04-17 00:24:07 +02:00
parent d6dd13a6be
commit 200aee52f7
13 changed files with 158 additions and 27 deletions

View File

@ -2,6 +2,7 @@ import PropTypes from 'prop-types';
import React from 'react'; import React from 'react';
import DescriptionList from 'Components/DescriptionList/DescriptionList'; import DescriptionList from 'Components/DescriptionList/DescriptionList';
import DescriptionListItem from 'Components/DescriptionList/DescriptionListItem'; import DescriptionListItem from 'Components/DescriptionList/DescriptionListItem';
import padNumber from 'Utilities/Number/padNumber';
import styles from './SceneInfo.css'; import styles from './SceneInfo.css';
function SceneInfo(props) { function SceneInfo(props) {
@ -60,6 +61,10 @@ function SceneInfo(props) {
key={alternateTitle.title} key={alternateTitle.title}
> >
{alternateTitle.title} {alternateTitle.title}
{
alternateTitle.sceneSeasonNumber !== -1 &&
<span> (S{padNumber(alternateTitle.sceneSeasonNumber, 2)})</span>
}
</div> </div>
); );
}) })

View File

@ -1,6 +1,8 @@
using System; using System;
using FluentAssertions; using FluentAssertions;
using Moq;
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Core.DataAugmentation.Scene;
using NzbDrone.Core.DecisionEngine.Specifications.Search; using NzbDrone.Core.DecisionEngine.Specifications.Search;
using NzbDrone.Core.IndexerSearch.Definitions; using NzbDrone.Core.IndexerSearch.Definitions;
using NzbDrone.Core.Parser.Model; using NzbDrone.Core.Parser.Model;
@ -23,6 +25,17 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.Search.SingleEpisodeSearchMatch
_searchCriteria.SeasonNumber = 5; _searchCriteria.SeasonNumber = 5;
_searchCriteria.EpisodeNumber = 1; _searchCriteria.EpisodeNumber = 1;
Mocker.GetMock<ISceneMappingService>()
.Setup(v => v.GetTvdbSeasonNumber(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<int>()))
.Returns<string, string, int>((s, r, i) => i);
}
private void GivenMapping(int sceneSeasonNumber, int seasonNumber)
{
Mocker.GetMock<ISceneMappingService>()
.Setup(v => v.GetTvdbSeasonNumber(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<int>()))
.Returns<string, string, int>((s, r, i) => i >= sceneSeasonNumber ? (seasonNumber + i - sceneSeasonNumber) : i);
} }
[Test] [Test]
@ -33,6 +46,26 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.Search.SingleEpisodeSearchMatch
Subject.IsSatisfiedBy(_remoteEpisode, _searchCriteria).Accepted.Should().BeFalse(); Subject.IsSatisfiedBy(_remoteEpisode, _searchCriteria).Accepted.Should().BeFalse();
} }
[Test]
public void should_return_true_if_season_matches_after_scenemapping()
{
_remoteEpisode.ParsedEpisodeInfo.SeasonNumber = 10;
GivenMapping(10, 5);
Subject.IsSatisfiedBy(_remoteEpisode, _searchCriteria).Accepted.Should().BeTrue();
}
[Test]
public void should_return_false_if_season_does_not_match_after_scenemapping()
{
_remoteEpisode.ParsedEpisodeInfo.SeasonNumber = 10;
GivenMapping(9, 5);
Subject.IsSatisfiedBy(_remoteEpisode, _searchCriteria).Accepted.Should().BeFalse();
}
[Test] [Test]
public void should_return_false_if_full_season_result_for_single_episode_search() public void should_return_false_if_full_season_result_for_single_episode_search()
{ {
@ -44,7 +77,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.Search.SingleEpisodeSearchMatch
[Test] [Test]
public void should_return_false_if_episode_number_does_not_match_search_criteria() public void should_return_false_if_episode_number_does_not_match_search_criteria()
{ {
_remoteEpisode.ParsedEpisodeInfo.EpisodeNumbers = new []{ 2 }; _remoteEpisode.ParsedEpisodeInfo.EpisodeNumbers = new[] { 2 };
Subject.IsSatisfiedBy(_remoteEpisode, _searchCriteria).Accepted.Should().BeFalse(); Subject.IsSatisfiedBy(_remoteEpisode, _searchCriteria).Accepted.Should().BeFalse();
} }

View File

@ -55,6 +55,10 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
Mocker.GetMock<ISeriesService>() Mocker.GetMock<ISeriesService>()
.Setup(s => s.FindByTitle(It.IsAny<string>())) .Setup(s => s.FindByTitle(It.IsAny<string>()))
.Returns(_series); .Returns(_series);
Mocker.GetMock<ISceneMappingService>()
.Setup(v => v.GetTvdbSeasonNumber(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<int>()))
.Returns<string, string, int>((s, r, i) => i);
} }
private void GivenDailySeries() private void GivenDailySeries()
@ -324,8 +328,8 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
const int tvdbSeasonNumber = 5; const int tvdbSeasonNumber = 5;
Mocker.GetMock<ISceneMappingService>() Mocker.GetMock<ISceneMappingService>()
.Setup(s => s.FindSceneMapping(_parsedEpisodeInfo.SeriesTitle, It.IsAny<string>())) .Setup(v => v.GetTvdbSeasonNumber(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<int>()))
.Returns(new SceneMapping { SeasonNumber = tvdbSeasonNumber, SceneSeasonNumber = _parsedEpisodeInfo.SeasonNumber }); .Returns<string, string, int>((s, r, i) => tvdbSeasonNumber);
Subject.GetEpisodes(_parsedEpisodeInfo, _series, true, null); Subject.GetEpisodes(_parsedEpisodeInfo, _series, true, null);

View File

@ -51,6 +51,10 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
SeasonNumber = _episodes.First().SeasonNumber, SeasonNumber = _episodes.First().SeasonNumber,
Episodes = _episodes Episodes = _episodes
}; };
Mocker.GetMock<ISceneMappingService>()
.Setup(v => v.GetTvdbSeasonNumber(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<int>()))
.Returns<string, string, int>((s, r, i) => i);
} }
private void GivenMatchBySeriesTitle() private void GivenMatchBySeriesTitle()

View File

@ -15,11 +15,13 @@ namespace NzbDrone.Core.DataAugmentation.Scene
public interface ISceneMappingService public interface ISceneMappingService
{ {
List<string> GetSceneNames(int tvdbId, List<int> seasonNumbers, List<int> sceneSeasonNumbers); List<string> GetSceneNames(int tvdbId, List<int> seasonNumbers, List<int> sceneSeasonNumbers);
List<SceneMapping> GetSceneMappings(int tvdbId, List<int> seasonNumbers);
int? FindTvdbId(string sceneTitle, string releaseTitle); int? FindTvdbId(string sceneTitle, string releaseTitle);
List<SceneMapping> FindByTvdbId(int tvdbId); List<SceneMapping> FindByTvdbId(int tvdbId);
SceneMapping FindSceneMapping(string sceneTitle, string releaseTitle); SceneMapping FindSceneMapping(string sceneTitle, string releaseTitle);
int? GetSceneSeasonNumber(string seriesTitle, string releaseTitle); int? GetSceneSeasonNumber(string seriesTitle, string releaseTitle);
int? GetTvdbSeasonNumber(string seriesTitle, string releaseTitle); int? GetTvdbSeasonNumber(string seriesTitle, string releaseTitle);
int GetTvdbSeasonNumber(string seriesTitle, string releaseTitle, int sceneSeasonNumber);
int? GetSceneSeasonNumber(int tvdbId, int seasonNumber); int? GetSceneSeasonNumber(int tvdbId, int seasonNumber);
} }
@ -66,6 +68,21 @@ namespace NzbDrone.Core.DataAugmentation.Scene
return FilterNonEnglish(names); return FilterNonEnglish(names);
} }
public List<SceneMapping> GetSceneMappings(int tvdbId, List<int> seasonNumbers)
{
var mappings = FindByTvdbId(tvdbId);
if (mappings == null)
{
return new List<SceneMapping>();
}
return mappings.Where(n => seasonNumbers.Contains(n.SeasonNumber ?? -1) &&
(n.SceneSeasonNumber ?? -1) != -1)
.Where(n => IsEnglish(n.SearchTerm))
.ToList();
}
public int? FindTvdbId(string seriesTitle) public int? FindTvdbId(string seriesTitle)
{ {
return FindTvdbId(seriesTitle, null); return FindTvdbId(seriesTitle, null);
@ -129,6 +146,20 @@ namespace NzbDrone.Core.DataAugmentation.Scene
return FindSceneMapping(seriesTitle, releaseTitle)?.SeasonNumber; return FindSceneMapping(seriesTitle, releaseTitle)?.SeasonNumber;
} }
public int GetTvdbSeasonNumber(string seriesTitle, string releaseTitle, int sceneSeasonNumber)
{
var sceneMapping = FindSceneMapping(seriesTitle, releaseTitle);
if (sceneMapping != null && sceneMapping.SeasonNumber.HasValue && sceneMapping.SeasonNumber.Value >= 0 &&
sceneMapping.SceneSeasonNumber <= sceneSeasonNumber)
{
var offset = sceneSeasonNumber - sceneMapping.SceneSeasonNumber.Value;
return sceneMapping.SeasonNumber.Value + offset;
}
return sceneSeasonNumber;
}
public int? GetSceneSeasonNumber(int tvdbId, int seasonNumber) public int? GetSceneSeasonNumber(int tvdbId, int seasonNumber)
{ {
var mappings = FindByTvdbId(tvdbId); var mappings = FindByTvdbId(tvdbId);
@ -266,7 +297,12 @@ namespace NzbDrone.Core.DataAugmentation.Scene
private List<string> FilterNonEnglish(List<string> titles) private List<string> FilterNonEnglish(List<string> titles)
{ {
return titles.Where(title => title.All(c => c <= 255)).ToList(); return titles.Where(IsEnglish).ToList();
}
private bool IsEnglish(string title)
{
return title.All(c => c <= 255);
} }
public void Handle(SeriesRefreshStartingEvent message) public void Handle(SeriesRefreshStartingEvent message)

View File

@ -104,7 +104,7 @@ namespace NzbDrone.Core.DecisionEngine
} }
else if (remoteEpisode.Episodes.Empty()) else if (remoteEpisode.Episodes.Empty())
{ {
decision = new DownloadDecision(remoteEpisode, new Rejection("Unable to parse episodes from release name")); decision = new DownloadDecision(remoteEpisode, new Rejection("Unable to identify correct episode(s) using release name and scene mappings"));
} }
else else
{ {

View File

@ -1,4 +1,5 @@
using NLog; using NLog;
using NzbDrone.Core.DataAugmentation.Scene;
using NzbDrone.Core.IndexerSearch.Definitions; using NzbDrone.Core.IndexerSearch.Definitions;
using NzbDrone.Core.Parser.Model; using NzbDrone.Core.Parser.Model;
@ -7,10 +8,12 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.Search
public class SeasonMatchSpecification : IDecisionEngineSpecification public class SeasonMatchSpecification : IDecisionEngineSpecification
{ {
private readonly Logger _logger; private readonly Logger _logger;
private readonly ISceneMappingService _sceneMappingService;
public SeasonMatchSpecification(Logger logger) public SeasonMatchSpecification(ISceneMappingService sceneMappingService, Logger logger)
{ {
_logger = logger; _logger = logger;
_sceneMappingService = sceneMappingService;
} }
public SpecificationPriority Priority => SpecificationPriority.Default; public SpecificationPriority Priority => SpecificationPriority.Default;
@ -26,7 +29,11 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.Search
var singleEpisodeSpec = searchCriteria as SeasonSearchCriteria; var singleEpisodeSpec = searchCriteria as SeasonSearchCriteria;
if (singleEpisodeSpec == null) return Decision.Accept(); if (singleEpisodeSpec == null) return Decision.Accept();
if (singleEpisodeSpec.SeasonNumber != remoteEpisode.ParsedEpisodeInfo.SeasonNumber) var seasonNumber = _sceneMappingService.GetTvdbSeasonNumber(remoteEpisode.ParsedEpisodeInfo.SeriesTitle,
remoteEpisode.ParsedEpisodeInfo.ReleaseTitle,
remoteEpisode.ParsedEpisodeInfo.SeasonNumber);
if (singleEpisodeSpec.SeasonNumber != seasonNumber)
{ {
_logger.Debug("Season number does not match searched season number, skipping."); _logger.Debug("Season number does not match searched season number, skipping.");
return Decision.Reject("Wrong season"); return Decision.Reject("Wrong season");

View File

@ -1,5 +1,6 @@
using System.Linq; using System.Linq;
using NLog; using NLog;
using NzbDrone.Core.DataAugmentation.Scene;
using NzbDrone.Core.IndexerSearch.Definitions; using NzbDrone.Core.IndexerSearch.Definitions;
using NzbDrone.Core.Parser.Model; using NzbDrone.Core.Parser.Model;
@ -8,10 +9,12 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.Search
public class SingleEpisodeSearchMatchSpecification : IDecisionEngineSpecification public class SingleEpisodeSearchMatchSpecification : IDecisionEngineSpecification
{ {
private readonly Logger _logger; private readonly Logger _logger;
private readonly ISceneMappingService _sceneMappingService;
public SingleEpisodeSearchMatchSpecification(Logger logger) public SingleEpisodeSearchMatchSpecification(ISceneMappingService sceneMappingService, Logger logger)
{ {
_logger = logger; _logger = logger;
_sceneMappingService = sceneMappingService;
} }
public SpecificationPriority Priority => SpecificationPriority.Default; public SpecificationPriority Priority => SpecificationPriority.Default;
@ -35,7 +38,11 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.Search
private Decision IsSatisfiedBy(RemoteEpisode remoteEpisode, SingleEpisodeSearchCriteria singleEpisodeSpec) private Decision IsSatisfiedBy(RemoteEpisode remoteEpisode, SingleEpisodeSearchCriteria singleEpisodeSpec)
{ {
if (singleEpisodeSpec.SeasonNumber != remoteEpisode.ParsedEpisodeInfo.SeasonNumber) var seasonNumber = _sceneMappingService.GetTvdbSeasonNumber(remoteEpisode.ParsedEpisodeInfo.SeriesTitle,
remoteEpisode.ParsedEpisodeInfo.ReleaseTitle,
remoteEpisode.ParsedEpisodeInfo.SeasonNumber);
if (singleEpisodeSpec.SeasonNumber != seasonNumber)
{ {
_logger.Debug("Season number does not match searched season number, skipping."); _logger.Debug("Season number does not match searched season number, skipping.");
return Decision.Reject("Wrong season"); return Decision.Reject("Wrong season");

View File

@ -3,6 +3,7 @@ using System.Linq;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using NzbDrone.Common.EnsureThat; using NzbDrone.Common.EnsureThat;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Core.DataAugmentation.Scene;
using NzbDrone.Core.Tv; using NzbDrone.Core.Tv;
namespace NzbDrone.Core.IndexerSearch.Definitions namespace NzbDrone.Core.IndexerSearch.Definitions
@ -15,6 +16,7 @@ namespace NzbDrone.Core.IndexerSearch.Definitions
public Series Series { get; set; } public Series Series { get; set; }
public List<string> SceneTitles { get; set; } public List<string> SceneTitles { get; set; }
public List<SceneMapping> SceneMappings { get; set; }
public List<Episode> Episodes { get; set; } public List<Episode> Episodes { get; set; }
public virtual bool MonitoredEpisodesOnly { get; set; } public virtual bool MonitoredEpisodesOnly { get; set; }
public virtual bool UserInvokedSearch { get; set; } public virtual bool UserInvokedSearch { get; set; }

View File

@ -280,6 +280,9 @@ namespace NzbDrone.Core.IndexerSearch
spec.SceneTitles = _sceneMapping.GetSceneNames(series.TvdbId, spec.SceneTitles = _sceneMapping.GetSceneNames(series.TvdbId,
episodes.Select(e => e.SeasonNumber).Distinct().ToList(), episodes.Select(e => e.SeasonNumber).Distinct().ToList(),
episodes.Select(e => e.SceneSeasonNumber ?? e.SeasonNumber).Distinct().ToList()); episodes.Select(e => e.SceneSeasonNumber ?? e.SeasonNumber).Distinct().ToList());
spec.SceneMappings = _sceneMapping.GetSceneMappings(series.TvdbId,
episodes.Select(e => e.SeasonNumber).Distinct().ToList());
if (!spec.SceneTitles.Contains(series.Title)) if (!spec.SceneTitles.Contains(series.Title))
{ {

View File

@ -32,6 +32,13 @@ namespace NzbDrone.Core.Indexers
_chains.Last().Add(new IndexerPageableRequest(request)); _chains.Last().Add(new IndexerPageableRequest(request));
} }
public void AddToTier(int tierIndex, IEnumerable<IndexerRequest> request)
{
if (request == null) return;
_chains[tierIndex].Add(new IndexerPageableRequest(request));
}
public void AddTier(IEnumerable<IndexerRequest> request) public void AddTier(IEnumerable<IndexerRequest> request)
{ {
AddTier(); AddTier();

View File

@ -1,7 +1,9 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Common.Http; using NzbDrone.Common.Http;
using NzbDrone.Core.DataAugmentation.Scene;
using NzbDrone.Core.IndexerSearch.Definitions; using NzbDrone.Core.IndexerSearch.Definitions;
namespace NzbDrone.Core.Indexers.Newznab namespace NzbDrone.Core.Indexers.Newznab
@ -128,11 +130,16 @@ namespace NzbDrone.Core.Indexers.Newznab
{ {
var pageableRequests = new IndexerPageableRequestChain(); var pageableRequests = new IndexerPageableRequestChain();
AddTvIdPageableRequests(pageableRequests, MaxPages, Settings.Categories, searchCriteria, AddTvIdPageableRequests(pageableRequests, Settings.Categories, searchCriteria,
string.Format("&season={0}&ep={1}", string.Format("&season={0}&ep={1}",
searchCriteria.SeasonNumber, searchCriteria.SeasonNumber,
searchCriteria.EpisodeNumber)); searchCriteria.EpisodeNumber));
AddSceneTitlePageableRequests(pageableRequests, Settings.Categories, searchCriteria,
m => string.Format("&season={0}&ep={1}",
m.SceneSeasonNumber,
searchCriteria.EpisodeNumber));
return pageableRequests; return pageableRequests;
} }
@ -140,10 +147,14 @@ namespace NzbDrone.Core.Indexers.Newznab
{ {
var pageableRequests = new IndexerPageableRequestChain(); var pageableRequests = new IndexerPageableRequestChain();
AddTvIdPageableRequests(pageableRequests, MaxPages, Settings.Categories, searchCriteria, AddTvIdPageableRequests(pageableRequests, Settings.Categories, searchCriteria,
string.Format("&season={0}", string.Format("&season={0}",
searchCriteria.SeasonNumber)); searchCriteria.SeasonNumber));
AddSceneTitlePageableRequests(pageableRequests, Settings.Categories, searchCriteria,
m => string.Format("&season={0}",
m.SceneSeasonNumber));
return pageableRequests; return pageableRequests;
} }
@ -151,7 +162,7 @@ namespace NzbDrone.Core.Indexers.Newznab
{ {
var pageableRequests = new IndexerPageableRequestChain(); var pageableRequests = new IndexerPageableRequestChain();
AddTvIdPageableRequests(pageableRequests, MaxPages, Settings.Categories, searchCriteria, AddTvIdPageableRequests(pageableRequests, Settings.Categories, searchCriteria,
string.Format("&season={0:yyyy}&ep={0:MM}/{0:dd}", string.Format("&season={0:yyyy}&ep={0:MM}/{0:dd}",
searchCriteria.AirDate)); searchCriteria.AirDate));
@ -162,7 +173,7 @@ namespace NzbDrone.Core.Indexers.Newznab
{ {
var pageableRequests = new IndexerPageableRequestChain(); var pageableRequests = new IndexerPageableRequestChain();
AddTvIdPageableRequests(pageableRequests, MaxPages, Settings.Categories, searchCriteria, AddTvIdPageableRequests(pageableRequests, Settings.Categories, searchCriteria,
string.Format("&season={0}", string.Format("&season={0}",
searchCriteria.Year)); searchCriteria.Year));
@ -207,7 +218,7 @@ namespace NzbDrone.Core.Indexers.Newznab
return pageableRequests; return pageableRequests;
} }
private void AddTvIdPageableRequests(IndexerPageableRequestChain chain, int maxPages, IEnumerable<int> categories, SearchCriteriaBase searchCriteria, string parameters) private void AddTvIdPageableRequests(IndexerPageableRequestChain chain, IEnumerable<int> categories, SearchCriteriaBase searchCriteria, string parameters)
{ {
var includeTvdbSearch = SupportsTvdbSearch && searchCriteria.Series.TvdbId > 0; var includeTvdbSearch = SupportsTvdbSearch && searchCriteria.Series.TvdbId > 0;
var includeImdbSearch = SupportsImdbSearch && searchCriteria.Series.ImdbId.IsNotNullOrWhiteSpace(); var includeImdbSearch = SupportsImdbSearch && searchCriteria.Series.ImdbId.IsNotNullOrWhiteSpace();
@ -237,29 +248,29 @@ namespace NzbDrone.Core.Indexers.Newznab
ids += "&tvmazeid=" + searchCriteria.Series.TvMazeId; ids += "&tvmazeid=" + searchCriteria.Series.TvMazeId;
} }
chain.Add(GetPagedRequests(maxPages, categories, "tvsearch", ids + parameters)); chain.Add(GetPagedRequests(MaxPages, categories, "tvsearch", ids + parameters));
} }
else else
{ {
if (includeTvdbSearch) if (includeTvdbSearch)
{ {
chain.Add(GetPagedRequests(maxPages, categories, "tvsearch", chain.Add(GetPagedRequests(MaxPages, categories, "tvsearch",
string.Format("&tvdbid={0}{1}", searchCriteria.Series.TvdbId, parameters))); string.Format("&tvdbid={0}{1}", searchCriteria.Series.TvdbId, parameters)));
} }
else if (includeImdbSearch) else if (includeImdbSearch)
{ {
chain.Add(GetPagedRequests(maxPages, categories, "tvsearch", chain.Add(GetPagedRequests(MaxPages, categories, "tvsearch",
string.Format("&imdbid={0}{1}", searchCriteria.Series.ImdbId, parameters))); string.Format("&imdbid={0}{1}", searchCriteria.Series.ImdbId, parameters)));
} }
else if (includeTvRageSearch) else if (includeTvRageSearch)
{ {
chain.Add(GetPagedRequests(maxPages, categories, "tvsearch", chain.Add(GetPagedRequests(MaxPages, categories, "tvsearch",
string.Format("&rid={0}{1}", searchCriteria.Series.TvRageId, parameters))); string.Format("&rid={0}{1}", searchCriteria.Series.TvRageId, parameters)));
} }
else if (includeTvMazeSearch) else if (includeTvMazeSearch)
{ {
chain.Add(GetPagedRequests(maxPages, categories, "tvsearch", chain.Add(GetPagedRequests(MaxPages, categories, "tvsearch",
string.Format("&tvmazeid={0}{1}", searchCriteria.Series.TvMazeId, parameters))); string.Format("&tvmazeid={0}{1}", searchCriteria.Series.TvMazeId, parameters)));
} }
} }
@ -277,6 +288,22 @@ namespace NzbDrone.Core.Indexers.Newznab
} }
} }
private void AddSceneTitlePageableRequests(IndexerPageableRequestChain chain, IEnumerable<int> categories, SearchCriteriaBase searchCriteria, Func<SceneMapping, string> parametersFunc)
{
foreach (var sceneMappingGroup in searchCriteria.SceneMappings.GroupBy(v => v.SceneSeasonNumber))
{
var parameters = parametersFunc(sceneMappingGroup.First());
foreach (var searchTerm in sceneMappingGroup.Select(v => v.SearchTerm).Distinct())
{
chain.AddToTier(0, GetPagedRequests(MaxPages, Settings.Categories, "tvsearch",
string.Format("&q={0}{1}",
NewsnabifyTitle(searchTerm),
parameters)));
}
}
}
private IEnumerable<IndexerRequest> GetPagedRequests(int maxPages, IEnumerable<int> categories, string searchType, string parameters) private IEnumerable<IndexerRequest> GetPagedRequests(int maxPages, IEnumerable<int> categories, string searchType, string parameters)
{ {
if (categories.Empty()) if (categories.Empty())

View File

@ -402,13 +402,9 @@ namespace NzbDrone.Core.Parser
if (sceneSource) if (sceneSource)
{ {
var sceneMapping = _sceneMappingService.FindSceneMapping(parsedEpisodeInfo.SeriesTitle, parsedEpisodeInfo.ReleaseTitle); seasonNumber = _sceneMappingService.GetTvdbSeasonNumber(parsedEpisodeInfo.SeriesTitle,
parsedEpisodeInfo.ReleaseTitle,
if (sceneMapping != null && sceneMapping.SeasonNumber.HasValue && sceneMapping.SeasonNumber.Value >= 0 && parsedEpisodeInfo.SeasonNumber);
sceneMapping.SceneSeasonNumber == seasonNumber)
{
seasonNumber = sceneMapping.SeasonNumber.Value;
}
} }
if (parsedEpisodeInfo.EpisodeNumbers == null) if (parsedEpisodeInfo.EpisodeNumbers == null)