mirror of
https://github.com/Radarr/Radarr.git
synced 2026-04-16 21:15:33 -04:00
New: Link indexer to specific download client
This commit is contained in:
@@ -1,10 +1,11 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Download;
|
||||
using NzbDrone.Core.Download.Clients;
|
||||
using NzbDrone.Core.Indexers;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
|
||||
@@ -67,6 +68,17 @@ namespace NzbDrone.Core.Test.Download
|
||||
return mock;
|
||||
}
|
||||
|
||||
private void WithTorrentIndexer(int downloadClientId)
|
||||
{
|
||||
Mocker.GetMock<IIndexerFactory>()
|
||||
.Setup(v => v.Find(It.IsAny<int>()))
|
||||
.Returns(Builder<IndexerDefinition>
|
||||
.CreateNew()
|
||||
.With(v => v.Id = _nextId++)
|
||||
.With(v => v.DownloadClientId = downloadClientId)
|
||||
.Build());
|
||||
}
|
||||
|
||||
private void GivenBlockedClient(int id)
|
||||
{
|
||||
_blockedProviders.Add(new DownloadClientStatus
|
||||
@@ -223,5 +235,39 @@ namespace NzbDrone.Core.Test.Download
|
||||
client3.Definition.Id.Should().Be(2);
|
||||
client4.Definition.Id.Should().Be(3);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_always_choose_indexer_client()
|
||||
{
|
||||
WithUsenetClient();
|
||||
WithTorrentClient();
|
||||
WithTorrentClient();
|
||||
WithTorrentClient();
|
||||
WithTorrentIndexer(3);
|
||||
|
||||
var client1 = Subject.GetDownloadClient(DownloadProtocol.Torrent, 1);
|
||||
var client2 = Subject.GetDownloadClient(DownloadProtocol.Torrent, 1);
|
||||
var client3 = Subject.GetDownloadClient(DownloadProtocol.Torrent, 1);
|
||||
var client4 = Subject.GetDownloadClient(DownloadProtocol.Torrent, 1);
|
||||
var client5 = Subject.GetDownloadClient(DownloadProtocol.Torrent, 1);
|
||||
|
||||
client1.Definition.Id.Should().Be(3);
|
||||
client2.Definition.Id.Should().Be(3);
|
||||
client3.Definition.Id.Should().Be(3);
|
||||
client4.Definition.Id.Should().Be(3);
|
||||
client5.Definition.Id.Should().Be(3);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_fail_to_choose_client_when_indexer_reference_does_not_exist()
|
||||
{
|
||||
WithUsenetClient();
|
||||
WithTorrentClient();
|
||||
WithTorrentClient();
|
||||
WithTorrentClient();
|
||||
WithTorrentIndexer(5);
|
||||
|
||||
Assert.Throws<DownloadClientUnavailableException>(() => Subject.GetDownloadClient(DownloadProtocol.Torrent, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,8 +31,8 @@ namespace NzbDrone.Core.Test.Download
|
||||
.Returns(_downloadClients);
|
||||
|
||||
Mocker.GetMock<IProvideDownloadClient>()
|
||||
.Setup(v => v.GetDownloadClient(It.IsAny<DownloadProtocol>()))
|
||||
.Returns<DownloadProtocol>(v => _downloadClients.FirstOrDefault(d => d.Protocol == v));
|
||||
.Setup(v => v.GetDownloadClient(It.IsAny<DownloadProtocol>(), It.IsAny<int>()))
|
||||
.Returns<DownloadProtocol, int>((v, i) => _downloadClients.FirstOrDefault(d => d.Protocol == v));
|
||||
|
||||
var releaseInfo = Builder<ReleaseInfo>.CreateNew()
|
||||
.With(v => v.DownloadProtocol = DownloadProtocol.Usenet)
|
||||
|
||||
@@ -17,6 +17,7 @@ namespace NzbDrone.Core.Datastore
|
||||
IEnumerable<TModel> All();
|
||||
int Count();
|
||||
TModel Get(int id);
|
||||
TModel Find(int id);
|
||||
TModel Insert(TModel model);
|
||||
TModel Update(TModel model);
|
||||
TModel Upsert(TModel model);
|
||||
@@ -99,6 +100,13 @@ namespace NzbDrone.Core.Datastore
|
||||
return model;
|
||||
}
|
||||
|
||||
public TModel Find(int id)
|
||||
{
|
||||
var model = Query(c => c.Id == id).SingleOrDefault();
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
public IEnumerable<TModel> Get(IEnumerable<int> ids)
|
||||
{
|
||||
if (!ids.Any())
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
using FluentMigrator;
|
||||
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Datastore.Migration
|
||||
{
|
||||
[Migration(205)]
|
||||
public class download_client_per_indexer : NzbDroneMigrationBase
|
||||
{
|
||||
protected override void MainDbUpgrade()
|
||||
{
|
||||
Alter.Table("Indexers").AddColumn("DownloadClientId").AsInt32().WithDefaultValue(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,15 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Cache;
|
||||
using NzbDrone.Core.Download.Clients;
|
||||
using NzbDrone.Core.Indexers;
|
||||
|
||||
namespace NzbDrone.Core.Download
|
||||
{
|
||||
public interface IProvideDownloadClient
|
||||
{
|
||||
IDownloadClient GetDownloadClient(DownloadProtocol downloadProtocol);
|
||||
IDownloadClient GetDownloadClient(DownloadProtocol downloadProtocol, int indexerId = 0);
|
||||
IEnumerable<IDownloadClient> GetDownloadClients();
|
||||
IDownloadClient Get(int id);
|
||||
}
|
||||
@@ -18,17 +19,23 @@ namespace NzbDrone.Core.Download
|
||||
private readonly Logger _logger;
|
||||
private readonly IDownloadClientFactory _downloadClientFactory;
|
||||
private readonly IDownloadClientStatusService _downloadClientStatusService;
|
||||
private readonly IIndexerFactory _indexerFactory;
|
||||
private readonly ICached<int> _lastUsedDownloadClient;
|
||||
|
||||
public DownloadClientProvider(IDownloadClientStatusService downloadClientStatusService, IDownloadClientFactory downloadClientFactory, ICacheManager cacheManager, Logger logger)
|
||||
public DownloadClientProvider(IDownloadClientStatusService downloadClientStatusService,
|
||||
IDownloadClientFactory downloadClientFactory,
|
||||
IIndexerFactory indexerFactory,
|
||||
ICacheManager cacheManager,
|
||||
Logger logger)
|
||||
{
|
||||
_logger = logger;
|
||||
_downloadClientFactory = downloadClientFactory;
|
||||
_downloadClientStatusService = downloadClientStatusService;
|
||||
_indexerFactory = indexerFactory;
|
||||
_lastUsedDownloadClient = cacheManager.GetCache<int>(GetType(), "lastDownloadClientId");
|
||||
}
|
||||
|
||||
public IDownloadClient GetDownloadClient(DownloadProtocol downloadProtocol)
|
||||
public IDownloadClient GetDownloadClient(DownloadProtocol downloadProtocol, int indexerId = 0)
|
||||
{
|
||||
var availableProviders = _downloadClientFactory.GetAvailableProviders().Where(v => v.Protocol == downloadProtocol).ToList();
|
||||
|
||||
@@ -37,6 +44,18 @@ namespace NzbDrone.Core.Download
|
||||
return null;
|
||||
}
|
||||
|
||||
if (indexerId > 0)
|
||||
{
|
||||
var indexer = _indexerFactory.Find(indexerId);
|
||||
|
||||
if (indexer != null && indexer.DownloadClientId > 0)
|
||||
{
|
||||
var client = availableProviders.SingleOrDefault(d => d.Definition.Id == indexer.DownloadClientId);
|
||||
|
||||
return client ?? throw new DownloadClientUnavailableException($"Indexer specified download client is not available");
|
||||
}
|
||||
}
|
||||
|
||||
var blockedProviders = new HashSet<int>(_downloadClientStatusService.GetBlockedProviders().Select(v => v.ProviderId));
|
||||
|
||||
if (blockedProviders.Any())
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace NzbDrone.Core.Download
|
||||
Ensure.That(remoteMovie.Movie, () => remoteMovie.Movie).IsNotNull();
|
||||
|
||||
var downloadTitle = remoteMovie.Release.Title;
|
||||
var downloadClient = _downloadClientProvider.GetDownloadClient(remoteMovie.Release.DownloadProtocol);
|
||||
var downloadClient = _downloadClientProvider.GetDownloadClient(remoteMovie.Release.DownloadProtocol, remoteMovie.Release.IndexerId);
|
||||
|
||||
if (downloadClient == null)
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using NzbDrone.Core.ThingiProvider;
|
||||
using NzbDrone.Core.ThingiProvider;
|
||||
|
||||
namespace NzbDrone.Core.Indexers
|
||||
{
|
||||
@@ -7,6 +7,7 @@ namespace NzbDrone.Core.Indexers
|
||||
public bool EnableRss { get; set; }
|
||||
public bool EnableAutomaticSearch { get; set; }
|
||||
public bool EnableInteractiveSearch { get; set; }
|
||||
public int DownloadClientId { get; set; }
|
||||
public DownloadProtocol Protocol { get; set; }
|
||||
public bool SupportsRss { get; set; }
|
||||
public bool SupportsSearch { get; set; }
|
||||
|
||||
@@ -421,6 +421,7 @@
|
||||
"IncludeUnknownMovieItemsHelpText": "Show items without a movie in the queue. This could include removed movies or anything else in Radarr's category",
|
||||
"IncludeUnmonitored": "Include Unmonitored",
|
||||
"Indexer": "Indexer",
|
||||
"IndexerDownloadClientHelpText": "Specify which download client is used for grabs from this indexer",
|
||||
"IndexerFlags": "Indexer Flags",
|
||||
"IndexerLongTermStatusCheckAllClientMessage": "All indexers are unavailable due to failures for more than 6 hours",
|
||||
"IndexerLongTermStatusCheckSingleClientMessage": "Indexers unavailable due to failures for more than 6 hours: {0}",
|
||||
|
||||
@@ -9,6 +9,8 @@ namespace NzbDrone.Core.ThingiProvider
|
||||
{
|
||||
List<TProviderDefinition> All();
|
||||
List<TProvider> GetAvailableProviders();
|
||||
bool Exists(int id);
|
||||
TProviderDefinition Find(int id);
|
||||
TProviderDefinition Get(int id);
|
||||
TProviderDefinition Create(TProviderDefinition definition);
|
||||
void Update(TProviderDefinition definition);
|
||||
|
||||
@@ -92,11 +92,21 @@ namespace NzbDrone.Core.ThingiProvider
|
||||
return Active().Select(GetInstance).ToList();
|
||||
}
|
||||
|
||||
public bool Exists(int id)
|
||||
{
|
||||
return _providerRepository.Find(id) != null;
|
||||
}
|
||||
|
||||
public TProviderDefinition Get(int id)
|
||||
{
|
||||
return _providerRepository.Get(id);
|
||||
}
|
||||
|
||||
public TProviderDefinition Find(int id)
|
||||
{
|
||||
return _providerRepository.Find(id);
|
||||
}
|
||||
|
||||
public virtual TProviderDefinition Create(TProviderDefinition definition)
|
||||
{
|
||||
var addedDefinition = _providerRepository.Insert(definition);
|
||||
|
||||
@@ -11,6 +11,7 @@ namespace Radarr.Api.V3.Indexers
|
||||
public bool SupportsSearch { get; set; }
|
||||
public DownloadProtocol Protocol { get; set; }
|
||||
public int Priority { get; set; }
|
||||
public int DownloadClientId { get; set; }
|
||||
}
|
||||
|
||||
public class IndexerResourceMapper : ProviderResourceMapper<IndexerResource, IndexerDefinition>
|
||||
@@ -31,6 +32,7 @@ namespace Radarr.Api.V3.Indexers
|
||||
resource.SupportsSearch = definition.SupportsSearch;
|
||||
resource.Protocol = definition.Protocol;
|
||||
resource.Priority = definition.Priority;
|
||||
resource.DownloadClientId = definition.DownloadClientId;
|
||||
|
||||
return resource;
|
||||
}
|
||||
@@ -48,6 +50,7 @@ namespace Radarr.Api.V3.Indexers
|
||||
definition.EnableAutomaticSearch = resource.EnableAutomaticSearch;
|
||||
definition.EnableInteractiveSearch = resource.EnableInteractiveSearch;
|
||||
definition.Priority = resource.Priority;
|
||||
definition.DownloadClientId = resource.DownloadClientId;
|
||||
|
||||
return definition;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user