mirror of
https://github.com/Sonarr/Sonarr.git
synced 2025-04-24 22:37:06 -04:00
parent
cfb7494992
commit
acc901455b
23 changed files with 204 additions and 103 deletions
|
@ -1,4 +1,4 @@
|
||||||
using NzbDrone.Core.Indexers;
|
using NzbDrone.Core.Indexers;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Indexers
|
namespace NzbDrone.Api.Indexers
|
||||||
{
|
{
|
||||||
|
@ -14,7 +14,7 @@ namespace NzbDrone.Api.Indexers
|
||||||
base.MapToResource(resource, definition);
|
base.MapToResource(resource, definition);
|
||||||
|
|
||||||
resource.EnableRss = definition.EnableRss;
|
resource.EnableRss = definition.EnableRss;
|
||||||
resource.EnableSearch = definition.EnableSearch;
|
resource.EnableSearch = definition.EnableAutomaticSearch || definition.EnableInteractiveSearch;
|
||||||
resource.SupportsRss = definition.SupportsRss;
|
resource.SupportsRss = definition.SupportsRss;
|
||||||
resource.SupportsSearch = definition.SupportsSearch;
|
resource.SupportsSearch = definition.SupportsSearch;
|
||||||
resource.Protocol = definition.Protocol;
|
resource.Protocol = definition.Protocol;
|
||||||
|
@ -25,7 +25,8 @@ namespace NzbDrone.Api.Indexers
|
||||||
base.MapToModel(definition, resource);
|
base.MapToModel(definition, resource);
|
||||||
|
|
||||||
definition.EnableRss = resource.EnableRss;
|
definition.EnableRss = resource.EnableRss;
|
||||||
definition.EnableSearch = resource.EnableSearch;
|
definition.EnableAutomaticSearch = resource.EnableSearch;
|
||||||
|
definition.EnableInteractiveSearch = resource.EnableSearch;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Validate(IndexerDefinition definition, bool includeWarnings)
|
protected override void Validate(IndexerDefinition definition, bool includeWarnings)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using NzbDrone.Core.Indexers;
|
using NzbDrone.Core.Indexers;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Indexers
|
namespace NzbDrone.Api.Indexers
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using FluentValidation;
|
using FluentValidation;
|
||||||
using Nancy;
|
using Nancy;
|
||||||
|
@ -89,7 +89,7 @@ namespace NzbDrone.Api.Indexers
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var decisions = _nzbSearchService.EpisodeSearch(episodeId, true);
|
var decisions = _nzbSearchService.EpisodeSearch(episodeId, true, true);
|
||||||
var prioritizedDecisions = _prioritizeDownloadDecision.PrioritizeDecisions(decisions);
|
var prioritizedDecisions = _prioritizeDownloadDecision.PrioritizeDecisions(decisions);
|
||||||
|
|
||||||
return MapDecisions(prioritizedDecisions);
|
return MapDecisions(prioritizedDecisions);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using NzbDrone.Common.Serializer;
|
using NzbDrone.Common.Serializer;
|
||||||
|
@ -28,11 +28,12 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||||
ApiPath = "/feed/nabapi"
|
ApiPath = "/feed/nabapi"
|
||||||
|
|
||||||
}.ToJson(),
|
}.ToJson(),
|
||||||
ConfigContract = impl + "Settings"
|
ConfigContract = impl + "Settings",
|
||||||
|
EnableInteractiveSearch = false
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
var items = db.Query<IndexerDefinition90>("SELECT * FROM Indexers");
|
var items = db.Query<IndexerDefinition121>("SELECT * FROM Indexers");
|
||||||
|
|
||||||
items.Should().HaveCount(1);
|
items.Should().HaveCount(1);
|
||||||
items.First().Settings.ToObject<NewznabSettings121>().BaseUrl.Should().Be(baseUrl.Replace("animetosho", "feed.animetosho"));
|
items.First().Settings.ToObject<NewznabSettings121>().BaseUrl.Should().Be(baseUrl.Replace("animetosho", "feed.animetosho"));
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Moq;
|
using Moq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using NzbDrone.Core.HealthCheck.Checks;
|
using NzbDrone.Core.HealthCheck.Checks;
|
||||||
|
@ -20,7 +20,11 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks
|
||||||
.Returns(new List<IIndexer>());
|
.Returns(new List<IIndexer>());
|
||||||
|
|
||||||
Mocker.GetMock<IIndexerFactory>()
|
Mocker.GetMock<IIndexerFactory>()
|
||||||
.Setup(s => s.SearchEnabled(It.IsAny<bool>()))
|
.Setup(s => s.AutomaticSearchEnabled(It.IsAny<bool>()))
|
||||||
|
.Returns(new List<IIndexer>());
|
||||||
|
|
||||||
|
Mocker.GetMock<IIndexerFactory>()
|
||||||
|
.Setup(s => s.InteractiveSearchEnabled(It.IsAny<bool>()))
|
||||||
.Returns(new List<IIndexer>());
|
.Returns(new List<IIndexer>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,17 +39,28 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks
|
||||||
.Returns(new List<IIndexer> { _indexerMock.Object });
|
.Returns(new List<IIndexer> { _indexerMock.Object });
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenSearchEnabled()
|
private void GivenAutomaticSearchEnabled()
|
||||||
{
|
{
|
||||||
Mocker.GetMock<IIndexerFactory>()
|
Mocker.GetMock<IIndexerFactory>()
|
||||||
.Setup(s => s.SearchEnabled(It.IsAny<bool>()))
|
.Setup(s => s.AutomaticSearchEnabled(It.IsAny<bool>()))
|
||||||
|
.Returns(new List<IIndexer> { _indexerMock.Object });
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenInteractiveSearchEnabled()
|
||||||
|
{
|
||||||
|
Mocker.GetMock<IIndexerFactory>()
|
||||||
|
.Setup(s => s.InteractiveSearchEnabled(It.IsAny<bool>()))
|
||||||
.Returns(new List<IIndexer> { _indexerMock.Object });
|
.Returns(new List<IIndexer> { _indexerMock.Object });
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenSearchFiltered()
|
private void GivenSearchFiltered()
|
||||||
{
|
{
|
||||||
Mocker.GetMock<IIndexerFactory>()
|
Mocker.GetMock<IIndexerFactory>()
|
||||||
.Setup(s => s.SearchEnabled(false))
|
.Setup(s => s.AutomaticSearchEnabled(false))
|
||||||
|
.Returns(new List<IIndexer> { _indexerMock.Object });
|
||||||
|
|
||||||
|
Mocker.GetMock<IIndexerFactory>()
|
||||||
|
.Setup(s => s.InteractiveSearchEnabled(false))
|
||||||
.Returns(new List<IIndexer> { _indexerMock.Object });
|
.Returns(new List<IIndexer> { _indexerMock.Object });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,14 +79,33 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_return_ok_when_search_is_enabled()
|
public void should_return_ok_when_automatic_and__search_is_enabled()
|
||||||
{
|
{
|
||||||
GivenIndexer(false, true);
|
GivenIndexer(false, true);
|
||||||
GivenSearchEnabled();
|
GivenAutomaticSearchEnabled();
|
||||||
|
GivenInteractiveSearchEnabled();
|
||||||
|
|
||||||
Subject.Check().ShouldBeOk();
|
Subject.Check().ShouldBeOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_warning_when_only_automatic_search_is_enabled()
|
||||||
|
{
|
||||||
|
GivenIndexer(false, true);
|
||||||
|
GivenAutomaticSearchEnabled();
|
||||||
|
|
||||||
|
Subject.Check().ShouldBeWarning();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_warning_when_only_interactive_search_is_enabled()
|
||||||
|
{
|
||||||
|
GivenIndexer(false, true);
|
||||||
|
GivenInteractiveSearchEnabled();
|
||||||
|
|
||||||
|
Subject.Check().ShouldBeWarning();
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_return_warning_if_search_is_supported_but_disabled()
|
public void should_return_warning_if_search_is_supported_but_disabled()
|
||||||
{
|
{
|
||||||
|
@ -80,6 +114,7 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks
|
||||||
Subject.Check().ShouldBeWarning();
|
Subject.Check().ShouldBeWarning();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_return_filter_warning_if_search_is_enabled_but_filtered()
|
public void should_return_filter_warning_if_search_is_enabled_but_filtered()
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using FizzWare.NBuilder;
|
using FizzWare.NBuilder;
|
||||||
|
@ -29,7 +29,7 @@ namespace NzbDrone.Core.Test.IndexerSearchTests
|
||||||
_mockIndexer.SetupGet(s => s.SupportsSearch).Returns(true);
|
_mockIndexer.SetupGet(s => s.SupportsSearch).Returns(true);
|
||||||
|
|
||||||
Mocker.GetMock<IIndexerFactory>()
|
Mocker.GetMock<IIndexerFactory>()
|
||||||
.Setup(s => s.SearchEnabled(true))
|
.Setup(s => s.AutomaticSearchEnabled(true))
|
||||||
.Returns(new List<IIndexer> { _mockIndexer.Object });
|
.Returns(new List<IIndexer> { _mockIndexer.Object });
|
||||||
|
|
||||||
Mocker.GetMock<IMakeDownloadDecision>()
|
Mocker.GetMock<IMakeDownloadDecision>()
|
||||||
|
@ -136,7 +136,7 @@ namespace NzbDrone.Core.Test.IndexerSearchTests
|
||||||
|
|
||||||
var allCriteria = WatchForSearchCriteria();
|
var allCriteria = WatchForSearchCriteria();
|
||||||
|
|
||||||
Subject.EpisodeSearch(_xemEpisodes.First(), true);
|
Subject.EpisodeSearch(_xemEpisodes.First(), true, false);
|
||||||
|
|
||||||
var criteria = allCriteria.OfType<SingleEpisodeSearchCriteria>().ToList();
|
var criteria = allCriteria.OfType<SingleEpisodeSearchCriteria>().ToList();
|
||||||
|
|
||||||
|
@ -152,7 +152,7 @@ namespace NzbDrone.Core.Test.IndexerSearchTests
|
||||||
|
|
||||||
var allCriteria = WatchForSearchCriteria();
|
var allCriteria = WatchForSearchCriteria();
|
||||||
|
|
||||||
Subject.SeasonSearch(_xemSeries.Id, 1, false, true);
|
Subject.SeasonSearch(_xemSeries.Id, 1, false, true, false);
|
||||||
|
|
||||||
var criteria = allCriteria.OfType<SeasonSearchCriteria>().ToList();
|
var criteria = allCriteria.OfType<SeasonSearchCriteria>().ToList();
|
||||||
|
|
||||||
|
@ -167,7 +167,7 @@ namespace NzbDrone.Core.Test.IndexerSearchTests
|
||||||
|
|
||||||
var allCriteria = WatchForSearchCriteria();
|
var allCriteria = WatchForSearchCriteria();
|
||||||
|
|
||||||
Subject.SeasonSearch(_xemSeries.Id, 2, false, true);
|
Subject.SeasonSearch(_xemSeries.Id, 2, false, true, false);
|
||||||
|
|
||||||
var criteria = allCriteria.OfType<SeasonSearchCriteria>().ToList();
|
var criteria = allCriteria.OfType<SeasonSearchCriteria>().ToList();
|
||||||
|
|
||||||
|
@ -183,7 +183,7 @@ namespace NzbDrone.Core.Test.IndexerSearchTests
|
||||||
|
|
||||||
var allCriteria = WatchForSearchCriteria();
|
var allCriteria = WatchForSearchCriteria();
|
||||||
|
|
||||||
Subject.SeasonSearch(_xemSeries.Id, 4, false, true);
|
Subject.SeasonSearch(_xemSeries.Id, 4, false, true, false);
|
||||||
|
|
||||||
var criteria1 = allCriteria.OfType<SeasonSearchCriteria>().ToList();
|
var criteria1 = allCriteria.OfType<SeasonSearchCriteria>().ToList();
|
||||||
var criteria2 = allCriteria.OfType<SingleEpisodeSearchCriteria>().ToList();
|
var criteria2 = allCriteria.OfType<SingleEpisodeSearchCriteria>().ToList();
|
||||||
|
@ -203,7 +203,7 @@ namespace NzbDrone.Core.Test.IndexerSearchTests
|
||||||
|
|
||||||
var allCriteria = WatchForSearchCriteria();
|
var allCriteria = WatchForSearchCriteria();
|
||||||
|
|
||||||
Subject.SeasonSearch(_xemSeries.Id, 7, false, true);
|
Subject.SeasonSearch(_xemSeries.Id, 7, false, true, false);
|
||||||
|
|
||||||
var criteria = allCriteria.OfType<SeasonSearchCriteria>().ToList();
|
var criteria = allCriteria.OfType<SeasonSearchCriteria>().ToList();
|
||||||
|
|
||||||
|
@ -221,7 +221,7 @@ namespace NzbDrone.Core.Test.IndexerSearchTests
|
||||||
var seasonNumber = 1;
|
var seasonNumber = 1;
|
||||||
var allCriteria = WatchForSearchCriteria();
|
var allCriteria = WatchForSearchCriteria();
|
||||||
|
|
||||||
Subject.SeasonSearch(_xemSeries.Id, seasonNumber, true, true);
|
Subject.SeasonSearch(_xemSeries.Id, seasonNumber, true, true, false);
|
||||||
|
|
||||||
var criteria = allCriteria.OfType<AnimeEpisodeSearchCriteria>().ToList();
|
var criteria = allCriteria.OfType<AnimeEpisodeSearchCriteria>().ToList();
|
||||||
|
|
||||||
|
@ -239,7 +239,7 @@ namespace NzbDrone.Core.Test.IndexerSearchTests
|
||||||
var seasonNumber = 1;
|
var seasonNumber = 1;
|
||||||
var allCriteria = WatchForSearchCriteria();
|
var allCriteria = WatchForSearchCriteria();
|
||||||
|
|
||||||
Subject.SeasonSearch(_xemSeries.Id, seasonNumber, false, true);
|
Subject.SeasonSearch(_xemSeries.Id, seasonNumber, false, true, false);
|
||||||
|
|
||||||
var criteria = allCriteria.OfType<AnimeEpisodeSearchCriteria>().ToList();
|
var criteria = allCriteria.OfType<AnimeEpisodeSearchCriteria>().ToList();
|
||||||
|
|
||||||
|
@ -256,7 +256,7 @@ namespace NzbDrone.Core.Test.IndexerSearchTests
|
||||||
var seasonNumber = 1;
|
var seasonNumber = 1;
|
||||||
var allCriteria = WatchForSearchCriteria();
|
var allCriteria = WatchForSearchCriteria();
|
||||||
|
|
||||||
Subject.SeasonSearch(_xemSeries.Id, seasonNumber, true, true);
|
Subject.SeasonSearch(_xemSeries.Id, seasonNumber, true, true, false);
|
||||||
|
|
||||||
var criteria = allCriteria.OfType<AnimeEpisodeSearchCriteria>().ToList();
|
var criteria = allCriteria.OfType<AnimeEpisodeSearchCriteria>().ToList();
|
||||||
|
|
||||||
|
@ -274,7 +274,7 @@ namespace NzbDrone.Core.Test.IndexerSearchTests
|
||||||
|
|
||||||
var allCriteria = WatchForSearchCriteria();
|
var allCriteria = WatchForSearchCriteria();
|
||||||
|
|
||||||
Subject.SeasonSearch(_xemSeries.Id, 1, false, true);
|
Subject.SeasonSearch(_xemSeries.Id, 1, false, true, false);
|
||||||
|
|
||||||
var criteria = allCriteria.OfType<DailySeasonSearchCriteria>().ToList();
|
var criteria = allCriteria.OfType<DailySeasonSearchCriteria>().ToList();
|
||||||
|
|
||||||
|
@ -293,7 +293,7 @@ namespace NzbDrone.Core.Test.IndexerSearchTests
|
||||||
|
|
||||||
var allCriteria = WatchForSearchCriteria();
|
var allCriteria = WatchForSearchCriteria();
|
||||||
|
|
||||||
Subject.SeasonSearch(_xemSeries.Id, 1, false, true);
|
Subject.SeasonSearch(_xemSeries.Id, 1, false, true, false);
|
||||||
|
|
||||||
var criteria1 = allCriteria.OfType<DailySeasonSearchCriteria>().ToList();
|
var criteria1 = allCriteria.OfType<DailySeasonSearchCriteria>().ToList();
|
||||||
var criteria2 = allCriteria.OfType<DailyEpisodeSearchCriteria>().ToList();
|
var criteria2 = allCriteria.OfType<DailyEpisodeSearchCriteria>().ToList();
|
||||||
|
@ -316,7 +316,7 @@ namespace NzbDrone.Core.Test.IndexerSearchTests
|
||||||
|
|
||||||
var allCriteria = WatchForSearchCriteria();
|
var allCriteria = WatchForSearchCriteria();
|
||||||
|
|
||||||
Subject.SeasonSearch(_xemSeries.Id, 1, false, true);
|
Subject.SeasonSearch(_xemSeries.Id, 1, false, true, false);
|
||||||
|
|
||||||
var criteria1 = allCriteria.OfType<DailySeasonSearchCriteria>().ToList();
|
var criteria1 = allCriteria.OfType<DailySeasonSearchCriteria>().ToList();
|
||||||
var criteria2 = allCriteria.OfType<DailyEpisodeSearchCriteria>().ToList();
|
var criteria2 = allCriteria.OfType<DailyEpisodeSearchCriteria>().ToList();
|
||||||
|
@ -332,7 +332,7 @@ namespace NzbDrone.Core.Test.IndexerSearchTests
|
||||||
|
|
||||||
var allCriteria = WatchForSearchCriteria();
|
var allCriteria = WatchForSearchCriteria();
|
||||||
|
|
||||||
Subject.SeasonSearch(_xemSeries.Id, 7, false, true);
|
Subject.SeasonSearch(_xemSeries.Id, 7, false, true, false);
|
||||||
|
|
||||||
Mocker.GetMock<ISceneMappingService>()
|
Mocker.GetMock<ISceneMappingService>()
|
||||||
.Verify(v => v.GetSceneNames(_xemSeries.Id, It.Is<List<int>>(l => l.Contains(7)), It.Is<List<int>>(l => l.Contains(7))), Times.Once());
|
.Verify(v => v.GetSceneNames(_xemSeries.Id, It.Is<List<int>>(l => l.Contains(7)), It.Is<List<int>>(l => l.Contains(7))), Times.Once());
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using Moq;
|
using Moq;
|
||||||
|
@ -32,7 +32,7 @@ namespace NzbDrone.Core.Test.IndexerSearchTests
|
||||||
.Returns(_series);
|
.Returns(_series);
|
||||||
|
|
||||||
Mocker.GetMock<ISearchForNzb>()
|
Mocker.GetMock<ISearchForNzb>()
|
||||||
.Setup(s => s.SeasonSearch(_series.Id, It.IsAny<int>(), false, true))
|
.Setup(s => s.SeasonSearch(_series.Id, It.IsAny<int>(), false, true, false))
|
||||||
.Returns(new List<DownloadDecision>());
|
.Returns(new List<DownloadDecision>());
|
||||||
|
|
||||||
Mocker.GetMock<IProcessDownloadDecisions>()
|
Mocker.GetMock<IProcessDownloadDecisions>()
|
||||||
|
@ -52,7 +52,7 @@ namespace NzbDrone.Core.Test.IndexerSearchTests
|
||||||
Subject.Execute(new SeriesSearchCommand { SeriesId = _series.Id, Trigger = CommandTrigger.Manual });
|
Subject.Execute(new SeriesSearchCommand { SeriesId = _series.Id, Trigger = CommandTrigger.Manual });
|
||||||
|
|
||||||
Mocker.GetMock<ISearchForNzb>()
|
Mocker.GetMock<ISearchForNzb>()
|
||||||
.Verify(v => v.SeasonSearch(_series.Id, It.IsAny<int>(), false, true), Times.Exactly(_series.Seasons.Count(s => s.Monitored)));
|
.Verify(v => v.SeasonSearch(_series.Id, It.IsAny<int>(), false, true, false), Times.Exactly(_series.Seasons.Count(s => s.Monitored)));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -68,9 +68,9 @@ namespace NzbDrone.Core.Test.IndexerSearchTests
|
||||||
};
|
};
|
||||||
|
|
||||||
Mocker.GetMock<ISearchForNzb>()
|
Mocker.GetMock<ISearchForNzb>()
|
||||||
.Setup(s => s.SeasonSearch(_series.Id, It.IsAny<int>(), false, true))
|
.Setup(s => s.SeasonSearch(_series.Id, It.IsAny<int>(), false, true, false))
|
||||||
.Returns(new List<DownloadDecision>())
|
.Returns(new List<DownloadDecision>())
|
||||||
.Callback<int, int, bool, bool>((seriesId, seasonNumber, missingOnly, userInvokedSearch) => seasonOrder.Add(seasonNumber));
|
.Callback<int, int, bool, bool, bool>((seriesId, seasonNumber, missingOnly, userInvokedSearch, interactiveSearch) => seasonOrder.Add(seasonNumber));
|
||||||
|
|
||||||
Subject.Execute(new SeriesSearchCommand { SeriesId = _series.Id, Trigger = CommandTrigger.Manual });
|
Subject.Execute(new SeriesSearchCommand { SeriesId = _series.Id, Trigger = CommandTrigger.Manual });
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
using FluentMigrator;
|
||||||
|
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Datastore.Migration
|
||||||
|
{
|
||||||
|
[Migration(119)]
|
||||||
|
public class separate_automatic_and_interactive_searches : NzbDroneMigrationBase
|
||||||
|
{
|
||||||
|
protected override void MainDbUpgrade()
|
||||||
|
{
|
||||||
|
Rename.Column("EnableSearch").OnTable("Indexers").To("EnableAutomaticSearch");
|
||||||
|
Alter.Table("Indexers").AddColumn("EnableInteractiveSearch").AsBoolean().Nullable();
|
||||||
|
|
||||||
|
Execute.Sql("UPDATE Indexers SET EnableInteractiveSearch = EnableAutomaticSearch");
|
||||||
|
|
||||||
|
Alter.Table("Indexers").AlterColumn("EnableInteractiveSearch").AsBoolean().NotNullable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
using FluentMigrator;
|
using FluentMigrator;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using NzbDrone.Core.Datastore.Migration.Framework;
|
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||||
|
|
||||||
|
@ -13,6 +13,18 @@ namespace NzbDrone.Core.Datastore.Migration
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class IndexerDefinition121
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
public JObject Settings { get; set; }
|
||||||
|
public string Implementation { get; set; }
|
||||||
|
public string ConfigContract { get; set; }
|
||||||
|
public bool EnableRss { get; set; }
|
||||||
|
public bool EnableAutomaticSearch { get; set; }
|
||||||
|
public bool EnableInteractiveSearch { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
public class NewznabSettings121
|
public class NewznabSettings121
|
||||||
{
|
{
|
||||||
public string BaseUrl { get; set; }
|
public string BaseUrl { get; set; }
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Core.Indexers;
|
using NzbDrone.Core.Indexers;
|
||||||
using NzbDrone.Core.ThingiProvider.Events;
|
using NzbDrone.Core.ThingiProvider.Events;
|
||||||
|
@ -19,14 +19,21 @@ namespace NzbDrone.Core.HealthCheck.Checks
|
||||||
|
|
||||||
public override HealthCheck Check()
|
public override HealthCheck Check()
|
||||||
{
|
{
|
||||||
var enabled = _indexerFactory.SearchEnabled(false);
|
var automaticSearchEnabled = _indexerFactory.AutomaticSearchEnabled(false);
|
||||||
|
|
||||||
if (enabled.Empty())
|
if (automaticSearchEnabled.Empty())
|
||||||
{
|
{
|
||||||
return new HealthCheck(GetType(), HealthCheckResult.Warning, "No indexers available with Search enabled, Sonarr will not provide any search results");
|
return new HealthCheck(GetType(), HealthCheckResult.Warning, "No indexers available with Automatic Search enabled, Sonarr will not provide any automatic search results");
|
||||||
}
|
}
|
||||||
|
|
||||||
var active = _indexerFactory.SearchEnabled(true);
|
var interactiveSearchEnabled = _indexerFactory.InteractiveSearchEnabled(false);
|
||||||
|
|
||||||
|
if (interactiveSearchEnabled.Empty())
|
||||||
|
{
|
||||||
|
return new HealthCheck(GetType(), HealthCheckResult.Warning, "No indexers available with Interactive Search enabled, Sonarr will not provide any interactive search results");
|
||||||
|
}
|
||||||
|
|
||||||
|
var active = _indexerFactory.AutomaticSearchEnabled(true);
|
||||||
|
|
||||||
if (active.Empty())
|
if (active.Empty())
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,6 +18,7 @@ namespace NzbDrone.Core.IndexerSearch.Definitions
|
||||||
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; }
|
||||||
|
public virtual bool InteractiveSearch { get; set; }
|
||||||
|
|
||||||
public List<string> QueryTitles => SceneTitles.Select(GetQueryTitle).Distinct().ToList();
|
public List<string> QueryTitles => SceneTitles.Select(GetQueryTitle).Distinct().ToList();
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
|
@ -55,7 +55,7 @@ namespace NzbDrone.Core.IndexerSearch
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
decisions = _nzbSearchService.SeasonSearch(series.Key, season.Key, true, userInvokedSearch);
|
decisions = _nzbSearchService.SeasonSearch(series.Key, season.Key, true, userInvokedSearch, false);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -68,7 +68,7 @@ namespace NzbDrone.Core.IndexerSearch
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
decisions = _nzbSearchService.EpisodeSearch(season.First(), userInvokedSearch);
|
decisions = _nzbSearchService.EpisodeSearch(season.First(), userInvokedSearch, false);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -90,7 +90,7 @@ namespace NzbDrone.Core.IndexerSearch
|
||||||
{
|
{
|
||||||
foreach (var episodeId in message.EpisodeIds)
|
foreach (var episodeId in message.EpisodeIds)
|
||||||
{
|
{
|
||||||
var decisions = _nzbSearchService.EpisodeSearch(episodeId, message.Trigger == CommandTrigger.Manual);
|
var decisions = _nzbSearchService.EpisodeSearch(episodeId, message.Trigger == CommandTrigger.Manual, false);
|
||||||
var processed = _processDownloadDecisions.ProcessDecisions(decisions);
|
var processed = _processDownloadDecisions.ProcessDecisions(decisions);
|
||||||
|
|
||||||
_logger.ProgressInfo("Episode search completed. {0} reports downloaded.", processed.Grabbed.Count);
|
_logger.ProgressInfo("Episode search completed. {0} reports downloaded.", processed.Grabbed.Count);
|
||||||
|
|
|
@ -18,9 +18,9 @@ namespace NzbDrone.Core.IndexerSearch
|
||||||
{
|
{
|
||||||
public interface ISearchForNzb
|
public interface ISearchForNzb
|
||||||
{
|
{
|
||||||
List<DownloadDecision> EpisodeSearch(int episodeId, bool userInvokedSearch);
|
List<DownloadDecision> EpisodeSearch(int episodeId, bool userInvokedSearch, bool interactiveSearch);
|
||||||
List<DownloadDecision> EpisodeSearch(Episode episode, bool userInvokedSearch);
|
List<DownloadDecision> EpisodeSearch(Episode episode, bool userInvokedSearch, bool interactiveSearch);
|
||||||
List<DownloadDecision> SeasonSearch(int seriesId, int seasonNumber, bool missingOnly, bool userInvokedSearch);
|
List<DownloadDecision> SeasonSearch(int seriesId, int seasonNumber, bool missingOnly, bool userInvokedSearch, bool interactiveSearch);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class NzbSearchService : ISearchForNzb
|
public class NzbSearchService : ISearchForNzb
|
||||||
|
@ -47,14 +47,14 @@ namespace NzbDrone.Core.IndexerSearch
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<DownloadDecision> EpisodeSearch(int episodeId, bool userInvokedSearch)
|
public List<DownloadDecision> EpisodeSearch(int episodeId, bool userInvokedSearch, bool interactiveSearch)
|
||||||
{
|
{
|
||||||
var episode = _episodeService.GetEpisode(episodeId);
|
var episode = _episodeService.GetEpisode(episodeId);
|
||||||
|
|
||||||
return EpisodeSearch(episode, userInvokedSearch);
|
return EpisodeSearch(episode, userInvokedSearch, interactiveSearch);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<DownloadDecision> EpisodeSearch(Episode episode, bool userInvokedSearch)
|
public List<DownloadDecision> EpisodeSearch(Episode episode, bool userInvokedSearch, bool interactiveSearch)
|
||||||
{
|
{
|
||||||
var series = _seriesService.GetSeries(episode.SeriesId);
|
var series = _seriesService.GetSeries(episode.SeriesId);
|
||||||
|
|
||||||
|
@ -65,23 +65,23 @@ namespace NzbDrone.Core.IndexerSearch
|
||||||
throw new InvalidOperationException("Daily episode is missing AirDate. Try to refresh series info.");
|
throw new InvalidOperationException("Daily episode is missing AirDate. Try to refresh series info.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return SearchDaily(series, episode, userInvokedSearch);
|
return SearchDaily(series, episode, userInvokedSearch, interactiveSearch);
|
||||||
}
|
}
|
||||||
if (series.SeriesType == SeriesTypes.Anime)
|
if (series.SeriesType == SeriesTypes.Anime)
|
||||||
{
|
{
|
||||||
return SearchAnime(series, episode, userInvokedSearch);
|
return SearchAnime(series, episode, userInvokedSearch, interactiveSearch);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (episode.SeasonNumber == 0)
|
if (episode.SeasonNumber == 0)
|
||||||
{
|
{
|
||||||
// search for special episodes in season 0
|
// search for special episodes in season 0
|
||||||
return SearchSpecial(series, new List<Episode> { episode }, userInvokedSearch);
|
return SearchSpecial(series, new List<Episode> { episode }, userInvokedSearch, interactiveSearch);
|
||||||
}
|
}
|
||||||
|
|
||||||
return SearchSingle(series, episode, userInvokedSearch);
|
return SearchSingle(series, episode, userInvokedSearch, interactiveSearch);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<DownloadDecision> SeasonSearch(int seriesId, int seasonNumber, bool missingOnly, bool userInvokedSearch)
|
public List<DownloadDecision> SeasonSearch(int seriesId, int seasonNumber, bool missingOnly, bool userInvokedSearch, bool interactiveSearch)
|
||||||
{
|
{
|
||||||
var series = _seriesService.GetSeries(seriesId);
|
var series = _seriesService.GetSeries(seriesId);
|
||||||
var episodes = _episodeService.GetEpisodesBySeason(seriesId, seasonNumber);
|
var episodes = _episodeService.GetEpisodesBySeason(seriesId, seasonNumber);
|
||||||
|
@ -93,18 +93,18 @@ namespace NzbDrone.Core.IndexerSearch
|
||||||
|
|
||||||
if (series.SeriesType == SeriesTypes.Anime)
|
if (series.SeriesType == SeriesTypes.Anime)
|
||||||
{
|
{
|
||||||
return SearchAnimeSeason(series, episodes, userInvokedSearch);
|
return SearchAnimeSeason(series, episodes, userInvokedSearch, interactiveSearch);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (series.SeriesType == SeriesTypes.Daily)
|
if (series.SeriesType == SeriesTypes.Daily)
|
||||||
{
|
{
|
||||||
return SearchDailySeason(series, episodes, userInvokedSearch);
|
return SearchDailySeason(series, episodes, userInvokedSearch, interactiveSearch);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (seasonNumber == 0)
|
if (seasonNumber == 0)
|
||||||
{
|
{
|
||||||
// search for special episodes in season 0
|
// search for special episodes in season 0
|
||||||
return SearchSpecial(series, episodes, userInvokedSearch);
|
return SearchSpecial(series, episodes, userInvokedSearch, interactiveSearch);
|
||||||
}
|
}
|
||||||
|
|
||||||
var downloadDecisions = new List<DownloadDecision>();
|
var downloadDecisions = new List<DownloadDecision>();
|
||||||
|
@ -125,7 +125,7 @@ namespace NzbDrone.Core.IndexerSearch
|
||||||
if (sceneSeasonEpisodes.Count() == 1)
|
if (sceneSeasonEpisodes.Count() == 1)
|
||||||
{
|
{
|
||||||
var episode = sceneSeasonEpisodes.First();
|
var episode = sceneSeasonEpisodes.First();
|
||||||
var searchSpec = Get<SingleEpisodeSearchCriteria>(series, sceneSeasonEpisodes.ToList(), userInvokedSearch);
|
var searchSpec = Get<SingleEpisodeSearchCriteria>(series, sceneSeasonEpisodes.ToList(), userInvokedSearch, interactiveSearch);
|
||||||
|
|
||||||
searchSpec.SeasonNumber = sceneSeasonEpisodes.Key;
|
searchSpec.SeasonNumber = sceneSeasonEpisodes.Key;
|
||||||
searchSpec.MonitoredEpisodesOnly = true;
|
searchSpec.MonitoredEpisodesOnly = true;
|
||||||
|
@ -144,7 +144,7 @@ namespace NzbDrone.Core.IndexerSearch
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var searchSpec = Get<SeasonSearchCriteria>(series, sceneSeasonEpisodes.ToList(), userInvokedSearch);
|
var searchSpec = Get<SeasonSearchCriteria>(series, sceneSeasonEpisodes.ToList(), userInvokedSearch, interactiveSearch);
|
||||||
searchSpec.SeasonNumber = sceneSeasonEpisodes.Key;
|
searchSpec.SeasonNumber = sceneSeasonEpisodes.Key;
|
||||||
|
|
||||||
var decisions = Dispatch(indexer => indexer.Fetch(searchSpec), searchSpec);
|
var decisions = Dispatch(indexer => indexer.Fetch(searchSpec), searchSpec);
|
||||||
|
@ -154,7 +154,7 @@ namespace NzbDrone.Core.IndexerSearch
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var searchSpec = Get<SeasonSearchCriteria>(series, episodes, userInvokedSearch);
|
var searchSpec = Get<SeasonSearchCriteria>(series, episodes, userInvokedSearch, interactiveSearch);
|
||||||
searchSpec.SeasonNumber = seasonNumber;
|
searchSpec.SeasonNumber = seasonNumber;
|
||||||
|
|
||||||
var decisions = Dispatch(indexer => indexer.Fetch(searchSpec), searchSpec);
|
var decisions = Dispatch(indexer => indexer.Fetch(searchSpec), searchSpec);
|
||||||
|
@ -164,9 +164,9 @@ namespace NzbDrone.Core.IndexerSearch
|
||||||
return downloadDecisions;
|
return downloadDecisions;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<DownloadDecision> SearchSingle(Series series, Episode episode, bool userInvokedSearch)
|
private List<DownloadDecision> SearchSingle(Series series, Episode episode, bool userInvokedSearch, bool interactiveSearch)
|
||||||
{
|
{
|
||||||
var searchSpec = Get<SingleEpisodeSearchCriteria>(series, new List<Episode> { episode }, userInvokedSearch);
|
var searchSpec = Get<SingleEpisodeSearchCriteria>(series, new List<Episode> { episode }, userInvokedSearch, interactiveSearch);
|
||||||
|
|
||||||
if (series.UseSceneNumbering && episode.SceneSeasonNumber.HasValue && episode.SceneEpisodeNumber.HasValue)
|
if (series.UseSceneNumbering && episode.SceneSeasonNumber.HasValue && episode.SceneEpisodeNumber.HasValue)
|
||||||
{
|
{
|
||||||
|
@ -182,18 +182,18 @@ namespace NzbDrone.Core.IndexerSearch
|
||||||
return Dispatch(indexer => indexer.Fetch(searchSpec), searchSpec);
|
return Dispatch(indexer => indexer.Fetch(searchSpec), searchSpec);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<DownloadDecision> SearchDaily(Series series, Episode episode, bool userInvokedSearch)
|
private List<DownloadDecision> SearchDaily(Series series, Episode episode, bool userInvokedSearch, bool interactiveSearch)
|
||||||
{
|
{
|
||||||
var airDate = DateTime.ParseExact(episode.AirDate, Episode.AIR_DATE_FORMAT, CultureInfo.InvariantCulture);
|
var airDate = DateTime.ParseExact(episode.AirDate, Episode.AIR_DATE_FORMAT, CultureInfo.InvariantCulture);
|
||||||
var searchSpec = Get<DailyEpisodeSearchCriteria>(series, new List<Episode> { episode }, userInvokedSearch);
|
var searchSpec = Get<DailyEpisodeSearchCriteria>(series, new List<Episode> { episode }, userInvokedSearch, interactiveSearch);
|
||||||
searchSpec.AirDate = airDate;
|
searchSpec.AirDate = airDate;
|
||||||
|
|
||||||
return Dispatch(indexer => indexer.Fetch(searchSpec), searchSpec);
|
return Dispatch(indexer => indexer.Fetch(searchSpec), searchSpec);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<DownloadDecision> SearchAnime(Series series, Episode episode, bool userInvokedSearch)
|
private List<DownloadDecision> SearchAnime(Series series, Episode episode, bool userInvokedSearch, bool interactiveSearch)
|
||||||
{
|
{
|
||||||
var searchSpec = Get<AnimeEpisodeSearchCriteria>(series, new List<Episode> { episode }, userInvokedSearch);
|
var searchSpec = Get<AnimeEpisodeSearchCriteria>(series, new List<Episode> { episode }, userInvokedSearch, interactiveSearch);
|
||||||
|
|
||||||
if (episode.SceneAbsoluteEpisodeNumber.HasValue)
|
if (episode.SceneAbsoluteEpisodeNumber.HasValue)
|
||||||
{
|
{
|
||||||
|
@ -211,9 +211,9 @@ namespace NzbDrone.Core.IndexerSearch
|
||||||
return Dispatch(indexer => indexer.Fetch(searchSpec), searchSpec);
|
return Dispatch(indexer => indexer.Fetch(searchSpec), searchSpec);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<DownloadDecision> SearchSpecial(Series series, List<Episode> episodes, bool userInvokedSearch)
|
private List<DownloadDecision> SearchSpecial(Series series, List<Episode> episodes, bool userInvokedSearch, bool interactiveSearch)
|
||||||
{
|
{
|
||||||
var searchSpec = Get<SpecialEpisodeSearchCriteria>(series, episodes, userInvokedSearch);
|
var searchSpec = Get<SpecialEpisodeSearchCriteria>(series, episodes, userInvokedSearch, interactiveSearch);
|
||||||
// build list of queries for each episode in the form: "<series> <episode-title>"
|
// build list of queries for each episode in the form: "<series> <episode-title>"
|
||||||
searchSpec.EpisodeQueryTitles = episodes.Where(e => !string.IsNullOrWhiteSpace(e.Title))
|
searchSpec.EpisodeQueryTitles = episodes.Where(e => !string.IsNullOrWhiteSpace(e.Title))
|
||||||
.SelectMany(e => searchSpec.QueryTitles.Select(title => title + " " + SearchCriteriaBase.GetQueryTitle(e.Title)))
|
.SelectMany(e => searchSpec.QueryTitles.Select(title => title + " " + SearchCriteriaBase.GetQueryTitle(e.Title)))
|
||||||
|
@ -222,19 +222,19 @@ namespace NzbDrone.Core.IndexerSearch
|
||||||
return Dispatch(indexer => indexer.Fetch(searchSpec), searchSpec);
|
return Dispatch(indexer => indexer.Fetch(searchSpec), searchSpec);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<DownloadDecision> SearchAnimeSeason(Series series, List<Episode> episodes, bool userInvokedSearch)
|
private List<DownloadDecision> SearchAnimeSeason(Series series, List<Episode> episodes, bool userInvokedSearch, bool interactiveSearch)
|
||||||
{
|
{
|
||||||
var downloadDecisions = new List<DownloadDecision>();
|
var downloadDecisions = new List<DownloadDecision>();
|
||||||
|
|
||||||
foreach (var episode in episodes.Where(e => e.Monitored))
|
foreach (var episode in episodes.Where(e => e.Monitored))
|
||||||
{
|
{
|
||||||
downloadDecisions.AddRange(SearchAnime(series, episode, userInvokedSearch));
|
downloadDecisions.AddRange(SearchAnime(series, episode, userInvokedSearch, interactiveSearch));
|
||||||
}
|
}
|
||||||
|
|
||||||
return downloadDecisions;
|
return downloadDecisions;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<DownloadDecision> SearchDailySeason(Series series, List<Episode> episodes, bool userInvokedSearch)
|
private List<DownloadDecision> SearchDailySeason(Series series, List<Episode> episodes, bool userInvokedSearch, bool interactiveSearch)
|
||||||
{
|
{
|
||||||
var downloadDecisions = new List<DownloadDecision>();
|
var downloadDecisions = new List<DownloadDecision>();
|
||||||
foreach (var yearGroup in episodes.Where(v => v.Monitored && v.AirDate.IsNotNullOrWhiteSpace())
|
foreach (var yearGroup in episodes.Where(v => v.Monitored && v.AirDate.IsNotNullOrWhiteSpace())
|
||||||
|
@ -244,21 +244,21 @@ namespace NzbDrone.Core.IndexerSearch
|
||||||
|
|
||||||
if (yearEpisodes.Count > 1)
|
if (yearEpisodes.Count > 1)
|
||||||
{
|
{
|
||||||
var searchSpec = Get<DailySeasonSearchCriteria>(series, yearEpisodes, userInvokedSearch);
|
var searchSpec = Get<DailySeasonSearchCriteria>(series, yearEpisodes, userInvokedSearch, interactiveSearch);
|
||||||
searchSpec.Year = yearGroup.Key;
|
searchSpec.Year = yearGroup.Key;
|
||||||
|
|
||||||
downloadDecisions.AddRange(Dispatch(indexer => indexer.Fetch(searchSpec), searchSpec));
|
downloadDecisions.AddRange(Dispatch(indexer => indexer.Fetch(searchSpec), searchSpec));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
downloadDecisions.AddRange(SearchDaily(series, yearEpisodes.First(), userInvokedSearch));
|
downloadDecisions.AddRange(SearchDaily(series, yearEpisodes.First(), userInvokedSearch, interactiveSearch));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return downloadDecisions;
|
return downloadDecisions;
|
||||||
}
|
}
|
||||||
|
|
||||||
private TSpec Get<TSpec>(Series series, List<Episode> episodes, bool userInvokedSearch) where TSpec : SearchCriteriaBase, new()
|
private TSpec Get<TSpec>(Series series, List<Episode> episodes, bool userInvokedSearch, bool interactiveSearch) where TSpec : SearchCriteriaBase, new()
|
||||||
{
|
{
|
||||||
var spec = new TSpec();
|
var spec = new TSpec();
|
||||||
|
|
||||||
|
@ -274,13 +274,17 @@ namespace NzbDrone.Core.IndexerSearch
|
||||||
|
|
||||||
spec.Episodes = episodes;
|
spec.Episodes = episodes;
|
||||||
spec.UserInvokedSearch = userInvokedSearch;
|
spec.UserInvokedSearch = userInvokedSearch;
|
||||||
|
spec.InteractiveSearch = interactiveSearch;
|
||||||
|
|
||||||
return spec;
|
return spec;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<DownloadDecision> Dispatch(Func<IIndexer, IEnumerable<ReleaseInfo>> searchAction, SearchCriteriaBase criteriaBase)
|
private List<DownloadDecision> Dispatch(Func<IIndexer, IEnumerable<ReleaseInfo>> searchAction, SearchCriteriaBase criteriaBase)
|
||||||
{
|
{
|
||||||
var indexers = _indexerFactory.SearchEnabled();
|
var indexers = criteriaBase.InteractiveSearch ?
|
||||||
|
_indexerFactory.InteractiveSearchEnabled() :
|
||||||
|
_indexerFactory.AutomaticSearchEnabled();
|
||||||
|
|
||||||
var reports = new List<ReleaseInfo>();
|
var reports = new List<ReleaseInfo>();
|
||||||
|
|
||||||
_logger.ProgressInfo("Searching {0} indexers for {1}", indexers.Count, criteriaBase);
|
_logger.ProgressInfo("Searching {0} indexers for {1}", indexers.Count, criteriaBase);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Instrumentation.Extensions;
|
using NzbDrone.Common.Instrumentation.Extensions;
|
||||||
using NzbDrone.Core.Download;
|
using NzbDrone.Core.Download;
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
using NzbDrone.Core.Messaging.Commands;
|
||||||
|
@ -22,7 +22,7 @@ namespace NzbDrone.Core.IndexerSearch
|
||||||
|
|
||||||
public void Execute(SeasonSearchCommand message)
|
public void Execute(SeasonSearchCommand message)
|
||||||
{
|
{
|
||||||
var decisions = _nzbSearchService.SeasonSearch(message.SeriesId, message.SeasonNumber, false, message.Trigger == CommandTrigger.Manual);
|
var decisions = _nzbSearchService.SeasonSearch(message.SeriesId, message.SeasonNumber, false, message.Trigger == CommandTrigger.Manual, false);
|
||||||
var processed = _processDownloadDecisions.ProcessDecisions(decisions);
|
var processed = _processDownloadDecisions.ProcessDecisions(decisions);
|
||||||
|
|
||||||
_logger.ProgressInfo("Season search completed. {0} reports downloaded.", processed.Grabbed.Count);
|
_logger.ProgressInfo("Season search completed. {0} reports downloaded.", processed.Grabbed.Count);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Instrumentation.Extensions;
|
using NzbDrone.Common.Instrumentation.Extensions;
|
||||||
using NzbDrone.Core.Download;
|
using NzbDrone.Core.Download;
|
||||||
|
@ -39,7 +39,7 @@ namespace NzbDrone.Core.IndexerSearch
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var decisions = _nzbSearchService.SeasonSearch(message.SeriesId, season.SeasonNumber, false, message.Trigger == CommandTrigger.Manual);
|
var decisions = _nzbSearchService.SeasonSearch(message.SeriesId, season.SeasonNumber, false, message.Trigger == CommandTrigger.Manual, false);
|
||||||
downloadedCount += _processDownloadDecisions.ProcessDecisions(decisions).Grabbed.Count;
|
downloadedCount += _processDownloadDecisions.ProcessDecisions(decisions).Grabbed.Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using FluentValidation.Results;
|
using FluentValidation.Results;
|
||||||
|
@ -48,7 +48,8 @@ namespace NzbDrone.Core.Indexers
|
||||||
{
|
{
|
||||||
Name = GetType().Name,
|
Name = GetType().Name,
|
||||||
EnableRss = config.Validate().IsValid && SupportsRss,
|
EnableRss = config.Validate().IsValid && SupportsRss,
|
||||||
EnableSearch = config.Validate().IsValid && SupportsSearch,
|
EnableAutomaticSearch = config.Validate().IsValid && SupportsSearch,
|
||||||
|
EnableInteractiveSearch = config.Validate().IsValid && SupportsSearch,
|
||||||
Implementation = GetType().Name,
|
Implementation = GetType().Name,
|
||||||
Settings = config
|
Settings = config
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,16 +1,17 @@
|
||||||
using NzbDrone.Core.ThingiProvider;
|
using NzbDrone.Core.ThingiProvider;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Indexers
|
namespace NzbDrone.Core.Indexers
|
||||||
{
|
{
|
||||||
public class IndexerDefinition : ProviderDefinition
|
public class IndexerDefinition : ProviderDefinition
|
||||||
{
|
{
|
||||||
public bool EnableRss { get; set; }
|
public bool EnableRss { get; set; }
|
||||||
public bool EnableSearch { get; set; }
|
public bool EnableAutomaticSearch { get; set; }
|
||||||
|
public bool EnableInteractiveSearch { get; set; }
|
||||||
public DownloadProtocol Protocol { get; set; }
|
public DownloadProtocol Protocol { get; set; }
|
||||||
public bool SupportsRss { get; set; }
|
public bool SupportsRss { get; set; }
|
||||||
public bool SupportsSearch { get; set; }
|
public bool SupportsSearch { get; set; }
|
||||||
|
|
||||||
public override bool Enable => EnableRss || EnableSearch;
|
public override bool Enable => EnableRss || EnableAutomaticSearch || EnableInteractiveSearch;
|
||||||
|
|
||||||
public IndexerStatus Status { get; set; }
|
public IndexerStatus Status { get; set; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using FluentValidation.Results;
|
using FluentValidation.Results;
|
||||||
using NLog;
|
using NLog;
|
||||||
|
@ -11,7 +11,8 @@ namespace NzbDrone.Core.Indexers
|
||||||
public interface IIndexerFactory : IProviderFactory<IIndexer, IndexerDefinition>
|
public interface IIndexerFactory : IProviderFactory<IIndexer, IndexerDefinition>
|
||||||
{
|
{
|
||||||
List<IIndexer> RssEnabled(bool filterBlockedIndexers = true);
|
List<IIndexer> RssEnabled(bool filterBlockedIndexers = true);
|
||||||
List<IIndexer> SearchEnabled(bool filterBlockedIndexers = true);
|
List<IIndexer> AutomaticSearchEnabled(bool filterBlockedIndexers = true);
|
||||||
|
List<IIndexer> InteractiveSearchEnabled(bool filterBlockedIndexers = true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class IndexerFactory : ProviderFactory<IIndexer, IndexerDefinition>, IIndexerFactory
|
public class IndexerFactory : ProviderFactory<IIndexer, IndexerDefinition>, IIndexerFactory
|
||||||
|
@ -57,9 +58,21 @@ namespace NzbDrone.Core.Indexers
|
||||||
return enabledIndexers.ToList();
|
return enabledIndexers.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<IIndexer> SearchEnabled(bool filterBlockedIndexers = true)
|
public List<IIndexer> AutomaticSearchEnabled(bool filterBlockedIndexers = true)
|
||||||
{
|
{
|
||||||
var enabledIndexers = GetAvailableProviders().Where(n => ((IndexerDefinition)n.Definition).EnableSearch);
|
var enabledIndexers = GetAvailableProviders().Where(n => ((IndexerDefinition)n.Definition).EnableAutomaticSearch);
|
||||||
|
|
||||||
|
if (filterBlockedIndexers)
|
||||||
|
{
|
||||||
|
return FilterBlockedIndexers(enabledIndexers).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
return enabledIndexers.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<IIndexer> InteractiveSearchEnabled(bool filterBlockedIndexers = true)
|
||||||
|
{
|
||||||
|
var enabledIndexers = GetAvailableProviders().Where(n => ((IndexerDefinition)n.Definition).EnableInteractiveSearch);
|
||||||
|
|
||||||
if (filterBlockedIndexers)
|
if (filterBlockedIndexers)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using FluentValidation.Results;
|
using FluentValidation.Results;
|
||||||
|
@ -67,7 +67,8 @@ namespace NzbDrone.Core.Indexers.Newznab
|
||||||
return new IndexerDefinition
|
return new IndexerDefinition
|
||||||
{
|
{
|
||||||
EnableRss = false,
|
EnableRss = false,
|
||||||
EnableSearch = false,
|
EnableAutomaticSearch = false,
|
||||||
|
EnableInteractiveSearch = false,
|
||||||
Name = name,
|
Name = name,
|
||||||
Implementation = GetType().Name,
|
Implementation = GetType().Name,
|
||||||
Settings = settings,
|
Settings = settings,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using FluentValidation.Results;
|
using FluentValidation.Results;
|
||||||
|
@ -56,7 +56,8 @@ namespace NzbDrone.Core.Indexers.Torznab
|
||||||
return new IndexerDefinition
|
return new IndexerDefinition
|
||||||
{
|
{
|
||||||
EnableRss = false,
|
EnableRss = false,
|
||||||
EnableSearch = false,
|
EnableAutomaticSearch = false,
|
||||||
|
EnableInteractiveSearch = false,
|
||||||
Name = name,
|
Name = name,
|
||||||
Implementation = GetType().Name,
|
Implementation = GetType().Name,
|
||||||
Settings = settings,
|
Settings = settings,
|
||||||
|
|
|
@ -244,6 +244,7 @@
|
||||||
<Compile Include="Datastore\Migration\043_convert_config_to_download_clients.cs" />
|
<Compile Include="Datastore\Migration\043_convert_config_to_download_clients.cs" />
|
||||||
<Compile Include="Datastore\Migration\044_fix_xbmc_episode_metadata.cs" />
|
<Compile Include="Datastore\Migration\044_fix_xbmc_episode_metadata.cs" />
|
||||||
<Compile Include="Datastore\Migration\120_update_series_episodes_history_indexes.cs" />
|
<Compile Include="Datastore\Migration\120_update_series_episodes_history_indexes.cs" />
|
||||||
|
<Compile Include="Datastore\Migration\119_separate_automatic_and_interactive_searches.cs" />
|
||||||
<Compile Include="Datastore\Migration\118_add_history_eventType_index.cs" />
|
<Compile Include="Datastore\Migration\118_add_history_eventType_index.cs" />
|
||||||
<Compile Include="Datastore\Migration\123_add_history_seriesId_index.cs" />
|
<Compile Include="Datastore\Migration\123_add_history_seriesId_index.cs" />
|
||||||
<Compile Include="Datastore\Migration\045_add_indexes.cs" />
|
<Compile Include="Datastore\Migration\045_add_indexes.cs" />
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
using NzbDrone.Core.Indexers;
|
using NzbDrone.Core.Indexers;
|
||||||
|
|
||||||
namespace Sonarr.Api.V3.Indexers
|
namespace Sonarr.Api.V3.Indexers
|
||||||
{
|
{
|
||||||
public class IndexerResource : ProviderResource
|
public class IndexerResource : ProviderResource
|
||||||
{
|
{
|
||||||
public bool EnableRss { get; set; }
|
public bool EnableRss { get; set; }
|
||||||
public bool EnableSearch { get; set; }
|
public bool EnableAutomaticSearch { get; set; }
|
||||||
|
public bool EnableInteractiveSearch { get; set; }
|
||||||
public bool SupportsRss { get; set; }
|
public bool SupportsRss { get; set; }
|
||||||
public bool SupportsSearch { get; set; }
|
public bool SupportsSearch { get; set; }
|
||||||
public DownloadProtocol Protocol { get; set; }
|
public DownloadProtocol Protocol { get; set; }
|
||||||
|
@ -20,7 +21,8 @@ namespace Sonarr.Api.V3.Indexers
|
||||||
var resource = base.ToResource(definition);
|
var resource = base.ToResource(definition);
|
||||||
|
|
||||||
resource.EnableRss = definition.EnableRss;
|
resource.EnableRss = definition.EnableRss;
|
||||||
resource.EnableSearch = definition.EnableSearch;
|
resource.EnableAutomaticSearch = definition.EnableAutomaticSearch;
|
||||||
|
resource.EnableInteractiveSearch = definition.EnableInteractiveSearch;
|
||||||
resource.SupportsRss = definition.SupportsRss;
|
resource.SupportsRss = definition.SupportsRss;
|
||||||
resource.SupportsSearch = definition.SupportsSearch;
|
resource.SupportsSearch = definition.SupportsSearch;
|
||||||
resource.Protocol = definition.Protocol;
|
resource.Protocol = definition.Protocol;
|
||||||
|
@ -35,7 +37,8 @@ namespace Sonarr.Api.V3.Indexers
|
||||||
var definition = base.ToModel(resource);
|
var definition = base.ToModel(resource);
|
||||||
|
|
||||||
definition.EnableRss = resource.EnableRss;
|
definition.EnableRss = resource.EnableRss;
|
||||||
definition.EnableSearch = resource.EnableSearch;
|
definition.EnableAutomaticSearch = resource.EnableAutomaticSearch;
|
||||||
|
definition.EnableInteractiveSearch = resource.EnableInteractiveSearch;
|
||||||
|
|
||||||
return definition;
|
return definition;
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,7 +91,7 @@ namespace Sonarr.Api.V3.Indexers
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var decisions = _nzbSearchService.EpisodeSearch(episodeId, true);
|
var decisions = _nzbSearchService.EpisodeSearch(episodeId, true, true);
|
||||||
var prioritizedDecisions = _prioritizeDownloadDecision.PrioritizeDecisions(decisions);
|
var prioritizedDecisions = _prioritizeDownloadDecision.PrioritizeDecisions(decisions);
|
||||||
|
|
||||||
return MapDecisions(prioritizedDecisions);
|
return MapDecisions(prioritizedDecisions);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue