diff --git a/frontend/src/Settings/Applications/Applications/Application.js b/frontend/src/Settings/Applications/Applications/Application.js
index 4573d8357..2d8280617 100644
--- a/frontend/src/Settings/Applications/Applications/Application.js
+++ b/frontend/src/Settings/Applications/Applications/Application.js
@@ -71,7 +71,7 @@ class Application extends Component {
{
syncLevel === 'addOnly' &&
}
diff --git a/frontend/src/Settings/Applications/Applications/EditApplicationModalContent.js b/frontend/src/Settings/Applications/Applications/EditApplicationModalContent.js
index 4893b5af1..5acc84309 100644
--- a/frontend/src/Settings/Applications/Applications/EditApplicationModalContent.js
+++ b/frontend/src/Settings/Applications/Applications/EditApplicationModalContent.js
@@ -19,7 +19,7 @@ import styles from './EditApplicationModalContent.css';
const syncLevelOptions = [
{ key: 'disabled', value: 'Disabled' },
- { key: 'addOnly', value: 'Add Only' },
+ { key: 'addOnly', value: 'Add and Remove Only' },
{ key: 'fullSync', value: 'Full Sync' }
];
diff --git a/src/NzbDrone.Core/Applications/ApplicationService.cs b/src/NzbDrone.Core/Applications/ApplicationService.cs
index 720c35b25..de15de6c0 100644
--- a/src/NzbDrone.Core/Applications/ApplicationService.cs
+++ b/src/NzbDrone.Core/Applications/ApplicationService.cs
@@ -4,6 +4,7 @@ using System.Linq;
using System.Net;
using NLog;
using NzbDrone.Common.Http;
+using NzbDrone.Core.Configuration.Events;
using NzbDrone.Core.Indexers;
using NzbDrone.Core.Messaging.Commands;
using NzbDrone.Core.Messaging.Events;
@@ -15,6 +16,7 @@ namespace NzbDrone.Core.Applications
IHandleAsync>,
IHandleAsync>,
IHandleAsync>,
+ IHandleAsync,
IExecute
{
private readonly IApplicationFactory _applicationsFactory;
@@ -40,8 +42,9 @@ namespace NzbDrone.Core.Applications
if (appDefinition.Enable)
{
var app = _applicationsFactory.GetInstance(appDefinition);
+ var indexers = _indexerFactory.Enabled().Select(i => (IndexerDefinition)i.Definition).ToList();
- SyncIndexers(new List { app });
+ SyncIndexers(new List { app }, indexers);
}
}
@@ -57,8 +60,7 @@ namespace NzbDrone.Core.Applications
public void HandleAsync(ProviderDeletedEvent message)
{
- var enabledApps = _applicationsFactory.SyncEnabled()
- .Where(n => ((ApplicationDefinition)n.Definition).SyncLevel == ApplicationSyncLevel.FullSync);
+ var enabledApps = _applicationsFactory.SyncEnabled();
foreach (var app in enabledApps)
{
@@ -69,39 +71,54 @@ namespace NzbDrone.Core.Applications
public void HandleAsync(ProviderUpdatedEvent message)
{
var enabledApps = _applicationsFactory.SyncEnabled()
- .Where(n => ((ApplicationDefinition)n.Definition).SyncLevel == ApplicationSyncLevel.FullSync);
+ .Where(n => ((ApplicationDefinition)n.Definition).SyncLevel == ApplicationSyncLevel.FullSync)
+ .ToList();
- foreach (var app in enabledApps)
- {
- ExecuteAction(a => a.UpdateIndexer((IndexerDefinition)message.Definition), app);
- }
+ SyncIndexers(enabledApps, new List { (IndexerDefinition)message.Definition });
}
- public void Execute(ApplicationIndexerSyncCommand message)
+ public void HandleAsync(ApiKeyChangedEvent message)
{
var enabledApps = _applicationsFactory.SyncEnabled();
- SyncIndexers(enabledApps);
+ var indexers = _indexerFactory.AllProviders().Select(i => (IndexerDefinition)i.Definition).ToList();
+
+ SyncIndexers(enabledApps, indexers);
}
- private void SyncIndexers(List applications)
+ public void Execute(ApplicationIndexerSyncCommand message)
{
- var indexers = _indexerFactory.Enabled();
+ var enabledApps = _applicationsFactory.SyncEnabled();
+ var indexers = _indexerFactory.AllProviders().Select(i => (IndexerDefinition)i.Definition).ToList();
+
+ SyncIndexers(enabledApps, indexers);
+ }
+
+ private void SyncIndexers(List applications, List indexers)
+ {
foreach (var app in applications)
{
var indexerMappings = _appIndexerMapService.GetMappingsForApp(app.Definition.Id);
foreach (var indexer in indexers)
{
- if (indexerMappings.Any(x => x.IndexerId == indexer.Definition.Id))
+ var definition = indexer;
+
+ if (indexerMappings.Any(x => x.IndexerId == definition.Id))
{
- continue;
+ if (((ApplicationDefinition)app.Definition).SyncLevel == ApplicationSyncLevel.FullSync)
+ {
+ ExecuteAction(a => a.UpdateIndexer(definition), app);
+ }
+ }
+ else
+ {
+ if (indexer.Enable)
+ {
+ ExecuteAction(a => a.AddIndexer(definition), app);
+ }
}
-
- var definition = (IndexerDefinition)indexer.Definition;
-
- ExecuteAction(a => a.AddIndexer(definition), app);
}
}
}
@@ -156,7 +173,7 @@ namespace NzbDrone.Core.Applications
catch (Exception ex)
{
_applicationStatusService.RecordFailure(application.Definition.Id);
- _logger.Error(ex, "An error occurred while talking to application.");
+ _logger.Error(ex, "An error occurred while talking to remote application.");
}
}
}
diff --git a/src/NzbDrone.Core/Applications/Lidarr/Lidarr.cs b/src/NzbDrone.Core/Applications/Lidarr/Lidarr.cs
index aa6c1c819..9e7cba5f4 100644
--- a/src/NzbDrone.Core/Applications/Lidarr/Lidarr.cs
+++ b/src/NzbDrone.Core/Applications/Lidarr/Lidarr.cs
@@ -40,11 +40,7 @@ namespace NzbDrone.Core.Applications.Lidarr
{
if (indexer.Capabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any())
{
- var schema = _schemaCache.Get(Definition.Settings.ToJson(), () => _lidarrV1Proxy.GetIndexerSchema(Settings), TimeSpan.FromDays(7));
- var newznab = schema.Where(i => i.Implementation == "Newznab").First();
- var torznab = schema.Where(i => i.Implementation == "Torznab").First();
-
- var lidarrIndexer = BuildLidarrIndexer(indexer, indexer.Protocol == DownloadProtocol.Usenet ? newznab : torznab);
+ var lidarrIndexer = BuildLidarrIndexer(indexer, indexer.Protocol);
var remoteIndexer = _lidarrV1Proxy.AddIndexer(lidarrIndexer, Settings);
_appIndexerMapService.Insert(new AppIndexerMap { AppId = Definition.Id, IndexerId = indexer.Id, RemoteIndexerId = remoteIndexer.Id });
@@ -67,19 +63,50 @@ namespace NzbDrone.Core.Applications.Lidarr
public override void UpdateIndexer(IndexerDefinition indexer)
{
- //Use the Id mapping here to delete the correct indexer
- throw new System.NotImplementedException();
+ _logger.Debug("Updating indexer {0}[{1}]", indexer.Name, indexer.Id);
+
+ var appMappings = _appIndexerMapService.GetMappingsForApp(Definition.Id);
+ var indexerMapping = appMappings.FirstOrDefault(m => m.IndexerId == indexer.Id);
+
+ var readarrIndexer = BuildLidarrIndexer(indexer, indexer.Protocol, indexerMapping?.RemoteIndexerId ?? 0);
+
+ var remoteIndexer = _lidarrV1Proxy.GetIndexer(indexerMapping.RemoteIndexerId, Settings);
+
+ if (remoteIndexer != null)
+ {
+ _logger.Debug("Remote indexer found, syncing with current settings");
+
+ if (!readarrIndexer.Equals(remoteIndexer))
+ {
+ _lidarrV1Proxy.UpdateIndexer(readarrIndexer, Settings);
+ }
+ }
+ else
+ {
+ _logger.Debug("Remote indexer not found, re-adding indexer to Lidarr");
+ readarrIndexer.Id = 0;
+
+ var newRemoteIndexer = _lidarrV1Proxy.AddIndexer(readarrIndexer, Settings);
+ _appIndexerMapService.Delete(indexerMapping.Id);
+ _appIndexerMapService.Insert(new AppIndexerMap { AppId = Definition.Id, IndexerId = indexer.Id, RemoteIndexerId = newRemoteIndexer.Id });
+ }
}
- private LidarrIndexer BuildLidarrIndexer(IndexerDefinition indexer, LidarrIndexer schema)
+ private LidarrIndexer BuildLidarrIndexer(IndexerDefinition indexer, DownloadProtocol protocol, int id = 0)
{
+ var schemas = _schemaCache.Get(Definition.Settings.ToJson(), () => _lidarrV1Proxy.GetIndexerSchema(Settings), TimeSpan.FromDays(7));
+ var newznab = schemas.Where(i => i.Implementation == "Newznab").First();
+ var torznab = schemas.Where(i => i.Implementation == "Torznab").First();
+
+ var schema = protocol == DownloadProtocol.Usenet ? newznab : torznab;
+
var lidarrIndexer = new LidarrIndexer
{
Id = 0,
Name = $"{indexer.Name} (Prowlarr)",
- EnableRss = true,
- EnableAutomaticSearch = true,
- EnableInteractiveSearch = true,
+ EnableRss = indexer.Enable,
+ EnableAutomaticSearch = indexer.Enable,
+ EnableInteractiveSearch = indexer.Enable,
Priority = indexer.Priority,
Implementation = indexer.Protocol == DownloadProtocol.Usenet ? "Newznab" : "Torznab",
ConfigContract = schema.ConfigContract,
diff --git a/src/NzbDrone.Core/Applications/Lidarr/LidarrIndexer.cs b/src/NzbDrone.Core/Applications/Lidarr/LidarrIndexer.cs
index 3d4d9f25f..ef92105fe 100644
--- a/src/NzbDrone.Core/Applications/Lidarr/LidarrIndexer.cs
+++ b/src/NzbDrone.Core/Applications/Lidarr/LidarrIndexer.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
+using System.Linq;
namespace NzbDrone.Core.Applications.Lidarr
{
@@ -16,5 +17,26 @@ namespace NzbDrone.Core.Applications.Lidarr
public string InfoLink { get; set; }
public HashSet Tags { get; set; }
public List Fields { get; set; }
+
+ public bool Equals(LidarrIndexer other)
+ {
+ if (ReferenceEquals(null, other))
+ {
+ return false;
+ }
+
+ var baseUrl = (string)Fields.FirstOrDefault(x => x.Name == "baseUrl").Value == (string)other.Fields.FirstOrDefault(x => x.Name == "baseUrl").Value;
+ var apiPath = (string)Fields.FirstOrDefault(x => x.Name == "apiPath").Value == (string)other.Fields.FirstOrDefault(x => x.Name == "apiPath").Value;
+ var apiKey = (string)Fields.FirstOrDefault(x => x.Name == "apiKey").Value == (string)other.Fields.FirstOrDefault(x => x.Name == "apiKey").Value;
+
+ return other.EnableRss == EnableRss &&
+ other.EnableAutomaticSearch == EnableAutomaticSearch &&
+ other.EnableInteractiveSearch == EnableAutomaticSearch &&
+ other.Name == Name &&
+ other.Implementation == Implementation &&
+ other.Priority == Priority &&
+ other.Id == Id &&
+ apiKey && apiPath && baseUrl;
+ }
}
}
diff --git a/src/NzbDrone.Core/Applications/Lidarr/LidarrV1Proxy.cs b/src/NzbDrone.Core/Applications/Lidarr/LidarrV1Proxy.cs
index adc72a12a..a0cacc605 100644
--- a/src/NzbDrone.Core/Applications/Lidarr/LidarrV1Proxy.cs
+++ b/src/NzbDrone.Core/Applications/Lidarr/LidarrV1Proxy.cs
@@ -13,8 +13,10 @@ namespace NzbDrone.Core.Applications.Lidarr
{
LidarrIndexer AddIndexer(LidarrIndexer indexer, LidarrSettings settings);
List GetIndexers(LidarrSettings settings);
+ LidarrIndexer GetIndexer(int indexerId, LidarrSettings settings);
List GetIndexerSchema(LidarrSettings settings);
void RemoveIndexer(int indexerId, LidarrSettings settings);
+ LidarrIndexer UpdateIndexer(LidarrIndexer indexer, LidarrSettings settings);
ValidationFailure Test(LidarrSettings settings);
}
@@ -41,6 +43,24 @@ namespace NzbDrone.Core.Applications.Lidarr
return Execute>(request);
}
+ public LidarrIndexer GetIndexer(int indexerId, LidarrSettings settings)
+ {
+ try
+ {
+ var request = BuildRequest(settings, $"/api/v1/indexer/{indexerId}", HttpMethod.GET);
+ return Execute(request);
+ }
+ catch (HttpException ex)
+ {
+ if (ex.Response.StatusCode != HttpStatusCode.NotFound)
+ {
+ throw;
+ }
+ }
+
+ return null;
+ }
+
public void RemoveIndexer(int indexerId, LidarrSettings settings)
{
var request = BuildRequest(settings, $"/api/v1/indexer/{indexerId}", HttpMethod.DELETE);
@@ -62,6 +82,15 @@ namespace NzbDrone.Core.Applications.Lidarr
return Execute(request);
}
+ public LidarrIndexer UpdateIndexer(LidarrIndexer indexer, LidarrSettings settings)
+ {
+ var request = BuildRequest(settings, $"/api/v1/indexer/{indexer.Id}", HttpMethod.PUT);
+
+ request.SetContent(indexer.ToJson());
+
+ return Execute(request);
+ }
+
public ValidationFailure Test(LidarrSettings settings)
{
try
diff --git a/src/NzbDrone.Core/Applications/Radarr/Radarr.cs b/src/NzbDrone.Core/Applications/Radarr/Radarr.cs
index 3e9225e87..21ffa7f74 100644
--- a/src/NzbDrone.Core/Applications/Radarr/Radarr.cs
+++ b/src/NzbDrone.Core/Applications/Radarr/Radarr.cs
@@ -40,11 +40,7 @@ namespace NzbDrone.Core.Applications.Radarr
{
if (indexer.Capabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any())
{
- var schema = _schemaCache.Get(Definition.Settings.ToJson(), () => _radarrV3Proxy.GetIndexerSchema(Settings), TimeSpan.FromDays(7));
- var newznab = schema.Where(i => i.Implementation == "Newznab").First();
- var torznab = schema.Where(i => i.Implementation == "Torznab").First();
-
- var radarrIndexer = BuildRadarrIndexer(indexer, indexer.Protocol == DownloadProtocol.Usenet ? newznab : torznab);
+ var radarrIndexer = BuildRadarrIndexer(indexer, indexer.Protocol);
var remoteIndexer = _radarrV3Proxy.AddIndexer(radarrIndexer, Settings);
_appIndexerMapService.Insert(new AppIndexerMap { AppId = Definition.Id, IndexerId = indexer.Id, RemoteIndexerId = remoteIndexer.Id });
@@ -67,19 +63,50 @@ namespace NzbDrone.Core.Applications.Radarr
public override void UpdateIndexer(IndexerDefinition indexer)
{
- //Use the Id mapping here to delete the correct indexer
- throw new System.NotImplementedException();
+ _logger.Debug("Updating indexer {0}[{1}]", indexer.Name, indexer.Id);
+
+ var appMappings = _appIndexerMapService.GetMappingsForApp(Definition.Id);
+ var indexerMapping = appMappings.FirstOrDefault(m => m.IndexerId == indexer.Id);
+
+ var radarrIndexer = BuildRadarrIndexer(indexer, indexer.Protocol, indexerMapping?.RemoteIndexerId ?? 0);
+
+ var remoteIndexer = _radarrV3Proxy.GetIndexer(indexerMapping.RemoteIndexerId, Settings);
+
+ if (remoteIndexer != null)
+ {
+ _logger.Debug("Remote indexer found, syncing with current settings");
+
+ if (!radarrIndexer.Equals(remoteIndexer))
+ {
+ _radarrV3Proxy.UpdateIndexer(radarrIndexer, Settings);
+ }
+ }
+ else
+ {
+ _logger.Debug("Remote indexer not found, re-adding indexer to Radarr");
+ radarrIndexer.Id = 0;
+
+ var newRemoteIndexer = _radarrV3Proxy.AddIndexer(radarrIndexer, Settings);
+ _appIndexerMapService.Delete(indexerMapping.Id);
+ _appIndexerMapService.Insert(new AppIndexerMap { AppId = Definition.Id, IndexerId = indexer.Id, RemoteIndexerId = newRemoteIndexer.Id });
+ }
}
- private RadarrIndexer BuildRadarrIndexer(IndexerDefinition indexer, RadarrIndexer schema)
+ private RadarrIndexer BuildRadarrIndexer(IndexerDefinition indexer, DownloadProtocol protocol, int id = 0)
{
+ var schemas = _schemaCache.Get(Definition.Settings.ToJson(), () => _radarrV3Proxy.GetIndexerSchema(Settings), TimeSpan.FromDays(7));
+ var newznab = schemas.Where(i => i.Implementation == "Newznab").First();
+ var torznab = schemas.Where(i => i.Implementation == "Torznab").First();
+
+ var schema = protocol == DownloadProtocol.Usenet ? newznab : torznab;
+
var radarrIndexer = new RadarrIndexer
{
- Id = 0,
+ Id = id,
Name = $"{indexer.Name} (Prowlarr)",
- EnableRss = true,
- EnableAutomaticSearch = true,
- EnableInteractiveSearch = true,
+ EnableRss = indexer.Enable,
+ EnableAutomaticSearch = indexer.Enable,
+ EnableInteractiveSearch = indexer.Enable,
Priority = indexer.Priority,
Implementation = indexer.Protocol == DownloadProtocol.Usenet ? "Newznab" : "Torznab",
ConfigContract = schema.ConfigContract,
diff --git a/src/NzbDrone.Core/Applications/Radarr/RadarrIndexer.cs b/src/NzbDrone.Core/Applications/Radarr/RadarrIndexer.cs
index 20c5d0567..0d5367152 100644
--- a/src/NzbDrone.Core/Applications/Radarr/RadarrIndexer.cs
+++ b/src/NzbDrone.Core/Applications/Radarr/RadarrIndexer.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
+using System.Linq;
namespace NzbDrone.Core.Applications.Radarr
{
@@ -16,5 +17,26 @@ namespace NzbDrone.Core.Applications.Radarr
public string InfoLink { get; set; }
public HashSet Tags { get; set; }
public List Fields { get; set; }
+
+ public bool Equals(RadarrIndexer other)
+ {
+ if (ReferenceEquals(null, other))
+ {
+ return false;
+ }
+
+ var baseUrl = (string)Fields.FirstOrDefault(x => x.Name == "baseUrl").Value == (string)other.Fields.FirstOrDefault(x => x.Name == "baseUrl").Value;
+ var apiPath = (string)Fields.FirstOrDefault(x => x.Name == "apiPath").Value == (string)other.Fields.FirstOrDefault(x => x.Name == "apiPath").Value;
+ var apiKey = (string)Fields.FirstOrDefault(x => x.Name == "apiKey").Value == (string)other.Fields.FirstOrDefault(x => x.Name == "apiKey").Value;
+
+ return other.EnableRss == EnableRss &&
+ other.EnableAutomaticSearch == EnableAutomaticSearch &&
+ other.EnableInteractiveSearch == EnableAutomaticSearch &&
+ other.Name == Name &&
+ other.Implementation == Implementation &&
+ other.Priority == Priority &&
+ other.Id == Id &&
+ apiKey && apiPath && baseUrl;
+ }
}
}
diff --git a/src/NzbDrone.Core/Applications/Radarr/RadarrV3Proxy.cs b/src/NzbDrone.Core/Applications/Radarr/RadarrV3Proxy.cs
index 54aef898d..a2f7087e5 100644
--- a/src/NzbDrone.Core/Applications/Radarr/RadarrV3Proxy.cs
+++ b/src/NzbDrone.Core/Applications/Radarr/RadarrV3Proxy.cs
@@ -13,8 +13,10 @@ namespace NzbDrone.Core.Applications.Radarr
{
RadarrIndexer AddIndexer(RadarrIndexer indexer, RadarrSettings settings);
List GetIndexers(RadarrSettings settings);
+ RadarrIndexer GetIndexer(int indexerId, RadarrSettings settings);
List GetIndexerSchema(RadarrSettings settings);
void RemoveIndexer(int indexerId, RadarrSettings settings);
+ RadarrIndexer UpdateIndexer(RadarrIndexer indexer, RadarrSettings settings);
ValidationFailure Test(RadarrSettings settings);
}
@@ -41,6 +43,24 @@ namespace NzbDrone.Core.Applications.Radarr
return Execute>(request);
}
+ public RadarrIndexer GetIndexer(int indexerId, RadarrSettings settings)
+ {
+ try
+ {
+ var request = BuildRequest(settings, $"/api/v3/indexer/{indexerId}", HttpMethod.GET);
+ return Execute(request);
+ }
+ catch (HttpException ex)
+ {
+ if (ex.Response.StatusCode != HttpStatusCode.NotFound)
+ {
+ throw;
+ }
+ }
+
+ return null;
+ }
+
public void RemoveIndexer(int indexerId, RadarrSettings settings)
{
var request = BuildRequest(settings, $"/api/v3/indexer/{indexerId}", HttpMethod.DELETE);
@@ -62,6 +82,15 @@ namespace NzbDrone.Core.Applications.Radarr
return Execute(request);
}
+ public RadarrIndexer UpdateIndexer(RadarrIndexer indexer, RadarrSettings settings)
+ {
+ var request = BuildRequest(settings, $"/api/v3/indexer/{indexer.Id}", HttpMethod.PUT);
+
+ request.SetContent(indexer.ToJson());
+
+ return Execute(request);
+ }
+
public ValidationFailure Test(RadarrSettings settings)
{
try
diff --git a/src/NzbDrone.Core/Applications/Readarr/Readarr.cs b/src/NzbDrone.Core/Applications/Readarr/Readarr.cs
index 45839d424..2a19d7414 100644
--- a/src/NzbDrone.Core/Applications/Readarr/Readarr.cs
+++ b/src/NzbDrone.Core/Applications/Readarr/Readarr.cs
@@ -40,11 +40,7 @@ namespace NzbDrone.Core.Applications.Readarr
{
if (indexer.Capabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any())
{
- var schema = _schemaCache.Get(Definition.Settings.ToJson(), () => _readarrV1Proxy.GetIndexerSchema(Settings), TimeSpan.FromDays(7));
- var newznab = schema.Where(i => i.Implementation == "Newznab").First();
- var torznab = schema.Where(i => i.Implementation == "Torznab").First();
-
- var readarrIndexer = BuildReadarrIndexer(indexer, indexer.Protocol == DownloadProtocol.Usenet ? newznab : torznab);
+ var readarrIndexer = BuildReadarrIndexer(indexer, indexer.Protocol);
var remoteIndexer = _readarrV1Proxy.AddIndexer(readarrIndexer, Settings);
_appIndexerMapService.Insert(new AppIndexerMap { AppId = Definition.Id, IndexerId = indexer.Id, RemoteIndexerId = remoteIndexer.Id });
@@ -67,19 +63,50 @@ namespace NzbDrone.Core.Applications.Readarr
public override void UpdateIndexer(IndexerDefinition indexer)
{
- //Use the Id mapping here to delete the correct indexer
- throw new System.NotImplementedException();
+ _logger.Debug("Updating indexer {0}[{1}]", indexer.Name, indexer.Id);
+
+ var appMappings = _appIndexerMapService.GetMappingsForApp(Definition.Id);
+ var indexerMapping = appMappings.FirstOrDefault(m => m.IndexerId == indexer.Id);
+
+ var readarrIndexer = BuildReadarrIndexer(indexer, indexer.Protocol, indexerMapping?.RemoteIndexerId ?? 0);
+
+ var remoteIndexer = _readarrV1Proxy.GetIndexer(indexerMapping.RemoteIndexerId, Settings);
+
+ if (remoteIndexer != null)
+ {
+ _logger.Debug("Remote indexer found, syncing with current settings");
+
+ if (!readarrIndexer.Equals(remoteIndexer))
+ {
+ _readarrV1Proxy.UpdateIndexer(readarrIndexer, Settings);
+ }
+ }
+ else
+ {
+ _logger.Debug("Remote indexer not found, re-adding indexer to Readarr");
+ readarrIndexer.Id = 0;
+
+ var newRemoteIndexer = _readarrV1Proxy.AddIndexer(readarrIndexer, Settings);
+ _appIndexerMapService.Delete(indexerMapping.Id);
+ _appIndexerMapService.Insert(new AppIndexerMap { AppId = Definition.Id, IndexerId = indexer.Id, RemoteIndexerId = newRemoteIndexer.Id });
+ }
}
- private ReadarrIndexer BuildReadarrIndexer(IndexerDefinition indexer, ReadarrIndexer schema)
+ private ReadarrIndexer BuildReadarrIndexer(IndexerDefinition indexer, DownloadProtocol protocol, int id = 0)
{
+ var schemas = _schemaCache.Get(Definition.Settings.ToJson(), () => _readarrV1Proxy.GetIndexerSchema(Settings), TimeSpan.FromDays(7));
+ var newznab = schemas.Where(i => i.Implementation == "Newznab").First();
+ var torznab = schemas.Where(i => i.Implementation == "Torznab").First();
+
+ var schema = protocol == DownloadProtocol.Usenet ? newznab : torznab;
+
var readarrIndexer = new ReadarrIndexer
{
Id = 0,
Name = $"{indexer.Name} (Prowlarr)",
- EnableRss = true,
- EnableAutomaticSearch = true,
- EnableInteractiveSearch = true,
+ EnableRss = indexer.Enable,
+ EnableAutomaticSearch = indexer.Enable,
+ EnableInteractiveSearch = indexer.Enable,
Priority = indexer.Priority,
Implementation = indexer.Protocol == DownloadProtocol.Usenet ? "Newznab" : "Torznab",
ConfigContract = schema.ConfigContract,
diff --git a/src/NzbDrone.Core/Applications/Readarr/ReadarrIndexer.cs b/src/NzbDrone.Core/Applications/Readarr/ReadarrIndexer.cs
index b9ac674a0..360147c96 100644
--- a/src/NzbDrone.Core/Applications/Readarr/ReadarrIndexer.cs
+++ b/src/NzbDrone.Core/Applications/Readarr/ReadarrIndexer.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
+using System.Linq;
namespace NzbDrone.Core.Applications.Readarr
{
@@ -16,5 +17,26 @@ namespace NzbDrone.Core.Applications.Readarr
public string InfoLink { get; set; }
public HashSet Tags { get; set; }
public List Fields { get; set; }
+
+ public bool Equals(ReadarrIndexer other)
+ {
+ if (ReferenceEquals(null, other))
+ {
+ return false;
+ }
+
+ var baseUrl = (string)Fields.FirstOrDefault(x => x.Name == "baseUrl").Value == (string)other.Fields.FirstOrDefault(x => x.Name == "baseUrl").Value;
+ var apiPath = (string)Fields.FirstOrDefault(x => x.Name == "apiPath").Value == (string)other.Fields.FirstOrDefault(x => x.Name == "apiPath").Value;
+ var apiKey = (string)Fields.FirstOrDefault(x => x.Name == "apiKey").Value == (string)other.Fields.FirstOrDefault(x => x.Name == "apiKey").Value;
+
+ return other.EnableRss == EnableRss &&
+ other.EnableAutomaticSearch == EnableAutomaticSearch &&
+ other.EnableInteractiveSearch == EnableAutomaticSearch &&
+ other.Name == Name &&
+ other.Implementation == Implementation &&
+ other.Priority == Priority &&
+ other.Id == Id &&
+ apiKey && apiPath && baseUrl;
+ }
}
}
diff --git a/src/NzbDrone.Core/Applications/Readarr/ReadarrV1Proxy.cs b/src/NzbDrone.Core/Applications/Readarr/ReadarrV1Proxy.cs
index f39c4f34b..eaffae394 100644
--- a/src/NzbDrone.Core/Applications/Readarr/ReadarrV1Proxy.cs
+++ b/src/NzbDrone.Core/Applications/Readarr/ReadarrV1Proxy.cs
@@ -13,8 +13,10 @@ namespace NzbDrone.Core.Applications.Readarr
{
ReadarrIndexer AddIndexer(ReadarrIndexer indexer, ReadarrSettings settings);
List GetIndexers(ReadarrSettings settings);
+ ReadarrIndexer GetIndexer(int indexerId, ReadarrSettings settings);
List GetIndexerSchema(ReadarrSettings settings);
void RemoveIndexer(int indexerId, ReadarrSettings settings);
+ ReadarrIndexer UpdateIndexer(ReadarrIndexer indexer, ReadarrSettings settings);
ValidationFailure Test(ReadarrSettings settings);
}
@@ -41,6 +43,24 @@ namespace NzbDrone.Core.Applications.Readarr
return Execute>(request);
}
+ public ReadarrIndexer GetIndexer(int indexerId, ReadarrSettings settings)
+ {
+ try
+ {
+ var request = BuildRequest(settings, $"/api/v1/indexer/{indexerId}", HttpMethod.GET);
+ return Execute(request);
+ }
+ catch (HttpException ex)
+ {
+ if (ex.Response.StatusCode != HttpStatusCode.NotFound)
+ {
+ throw;
+ }
+ }
+
+ return null;
+ }
+
public void RemoveIndexer(int indexerId, ReadarrSettings settings)
{
var request = BuildRequest(settings, $"/api/v1/indexer/{indexerId}", HttpMethod.DELETE);
@@ -62,6 +82,15 @@ namespace NzbDrone.Core.Applications.Readarr
return Execute(request);
}
+ public ReadarrIndexer UpdateIndexer(ReadarrIndexer indexer, ReadarrSettings settings)
+ {
+ var request = BuildRequest(settings, $"/api/v1/indexer/{indexer.Id}", HttpMethod.PUT);
+
+ request.SetContent(indexer.ToJson());
+
+ return Execute(request);
+ }
+
public ValidationFailure Test(ReadarrSettings settings)
{
try
diff --git a/src/NzbDrone.Core/Applications/Sonarr/Sonarr.cs b/src/NzbDrone.Core/Applications/Sonarr/Sonarr.cs
index 35b14077f..86b7bc582 100644
--- a/src/NzbDrone.Core/Applications/Sonarr/Sonarr.cs
+++ b/src/NzbDrone.Core/Applications/Sonarr/Sonarr.cs
@@ -40,11 +40,7 @@ namespace NzbDrone.Core.Applications.Sonarr
{
if (indexer.Capabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any())
{
- var schema = _schemaCache.Get(Definition.Settings.ToJson(), () => _sonarrV3Proxy.GetIndexerSchema(Settings), TimeSpan.FromDays(7));
- var newznab = schema.Where(i => i.Implementation == "Newznab").First();
- var torznab = schema.Where(i => i.Implementation == "Torznab").First();
-
- var sonarrIndexer = BuildSonarrIndexer(indexer, indexer.Protocol == DownloadProtocol.Usenet ? newznab : torznab);
+ var sonarrIndexer = BuildSonarrIndexer(indexer, indexer.Protocol);
var remoteIndexer = _sonarrV3Proxy.AddIndexer(sonarrIndexer, Settings);
_appIndexerMapService.Insert(new AppIndexerMap { AppId = Definition.Id, IndexerId = indexer.Id, RemoteIndexerId = remoteIndexer.Id });
@@ -67,19 +63,50 @@ namespace NzbDrone.Core.Applications.Sonarr
public override void UpdateIndexer(IndexerDefinition indexer)
{
- //Use the Id mapping here to delete the correct indexer
- throw new System.NotImplementedException();
+ _logger.Debug("Updating indexer {0}[{1}]", indexer.Name, indexer.Id);
+
+ var appMappings = _appIndexerMapService.GetMappingsForApp(Definition.Id);
+ var indexerMapping = appMappings.FirstOrDefault(m => m.IndexerId == indexer.Id);
+
+ var sonarrIndexer = BuildSonarrIndexer(indexer, indexer.Protocol, indexerMapping?.RemoteIndexerId ?? 0);
+
+ var remoteIndexer = _sonarrV3Proxy.GetIndexer(indexerMapping.RemoteIndexerId, Settings);
+
+ if (remoteIndexer != null)
+ {
+ _logger.Debug("Remote indexer found, syncing with current settings");
+
+ if (!sonarrIndexer.Equals(remoteIndexer))
+ {
+ _sonarrV3Proxy.UpdateIndexer(sonarrIndexer, Settings);
+ }
+ }
+ else
+ {
+ _logger.Debug("Remote indexer not found, re-adding indexer to Sonarr");
+ sonarrIndexer.Id = 0;
+
+ var newRemoteIndexer = _sonarrV3Proxy.AddIndexer(sonarrIndexer, Settings);
+ _appIndexerMapService.Delete(indexerMapping.Id);
+ _appIndexerMapService.Insert(new AppIndexerMap { AppId = Definition.Id, IndexerId = indexer.Id, RemoteIndexerId = newRemoteIndexer.Id });
+ }
}
- private SonarrIndexer BuildSonarrIndexer(IndexerDefinition indexer, SonarrIndexer schema)
+ private SonarrIndexer BuildSonarrIndexer(IndexerDefinition indexer, DownloadProtocol protocol, int id = 0)
{
+ var schemas = _schemaCache.Get(Definition.Settings.ToJson(), () => _sonarrV3Proxy.GetIndexerSchema(Settings), TimeSpan.FromDays(7));
+ var newznab = schemas.Where(i => i.Implementation == "Newznab").First();
+ var torznab = schemas.Where(i => i.Implementation == "Torznab").First();
+
+ var schema = protocol == DownloadProtocol.Usenet ? newznab : torznab;
+
var sonarrIndexer = new SonarrIndexer
{
Id = 0,
Name = $"{indexer.Name} (Prowlarr)",
- EnableRss = true,
- EnableAutomaticSearch = true,
- EnableInteractiveSearch = true,
+ EnableRss = indexer.Enable,
+ EnableAutomaticSearch = indexer.Enable,
+ EnableInteractiveSearch = indexer.Enable,
Priority = indexer.Priority,
Implementation = indexer.Protocol == DownloadProtocol.Usenet ? "Newznab" : "Torznab",
ConfigContract = schema.ConfigContract,
diff --git a/src/NzbDrone.Core/Applications/Sonarr/SonarrIndexer.cs b/src/NzbDrone.Core/Applications/Sonarr/SonarrIndexer.cs
index 0f7af2a28..840a4430f 100644
--- a/src/NzbDrone.Core/Applications/Sonarr/SonarrIndexer.cs
+++ b/src/NzbDrone.Core/Applications/Sonarr/SonarrIndexer.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
+using System.Linq;
namespace NzbDrone.Core.Applications.Sonarr
{
@@ -16,5 +17,26 @@ namespace NzbDrone.Core.Applications.Sonarr
public string InfoLink { get; set; }
public HashSet Tags { get; set; }
public List Fields { get; set; }
+
+ public bool Equals(SonarrIndexer other)
+ {
+ if (ReferenceEquals(null, other))
+ {
+ return false;
+ }
+
+ var baseUrl = (string)Fields.FirstOrDefault(x => x.Name == "baseUrl").Value == (string)other.Fields.FirstOrDefault(x => x.Name == "baseUrl").Value;
+ var apiPath = (string)Fields.FirstOrDefault(x => x.Name == "apiPath").Value == (string)other.Fields.FirstOrDefault(x => x.Name == "apiPath").Value;
+ var apiKey = (string)Fields.FirstOrDefault(x => x.Name == "apiKey").Value == (string)other.Fields.FirstOrDefault(x => x.Name == "apiKey").Value;
+
+ return other.EnableRss == EnableRss &&
+ other.EnableAutomaticSearch == EnableAutomaticSearch &&
+ other.EnableInteractiveSearch == EnableAutomaticSearch &&
+ other.Name == Name &&
+ other.Implementation == Implementation &&
+ other.Priority == Priority &&
+ other.Id == Id &&
+ apiKey && apiPath && baseUrl;
+ }
}
}
diff --git a/src/NzbDrone.Core/Applications/Sonarr/SonarrV3Proxy.cs b/src/NzbDrone.Core/Applications/Sonarr/SonarrV3Proxy.cs
index fd0731a63..2d8779db1 100644
--- a/src/NzbDrone.Core/Applications/Sonarr/SonarrV3Proxy.cs
+++ b/src/NzbDrone.Core/Applications/Sonarr/SonarrV3Proxy.cs
@@ -13,8 +13,10 @@ namespace NzbDrone.Core.Applications.Sonarr
{
SonarrIndexer AddIndexer(SonarrIndexer indexer, SonarrSettings settings);
List GetIndexers(SonarrSettings settings);
+ SonarrIndexer GetIndexer(int indexerId, SonarrSettings settings);
List GetIndexerSchema(SonarrSettings settings);
void RemoveIndexer(int indexerId, SonarrSettings settings);
+ SonarrIndexer UpdateIndexer(SonarrIndexer indexer, SonarrSettings settings);
ValidationFailure Test(SonarrSettings settings);
}
@@ -41,6 +43,24 @@ namespace NzbDrone.Core.Applications.Sonarr
return Execute>(request);
}
+ public SonarrIndexer GetIndexer(int indexerId, SonarrSettings settings)
+ {
+ try
+ {
+ var request = BuildRequest(settings, $"/api/v1/indexer/{indexerId}", HttpMethod.GET);
+ return Execute(request);
+ }
+ catch (HttpException ex)
+ {
+ if (ex.Response.StatusCode != HttpStatusCode.NotFound)
+ {
+ throw;
+ }
+ }
+
+ return null;
+ }
+
public void RemoveIndexer(int indexerId, SonarrSettings settings)
{
var request = BuildRequest(settings, $"/api/v3/indexer/{indexerId}", HttpMethod.DELETE);
@@ -62,6 +82,15 @@ namespace NzbDrone.Core.Applications.Sonarr
return Execute(request);
}
+ public SonarrIndexer UpdateIndexer(SonarrIndexer indexer, SonarrSettings settings)
+ {
+ var request = BuildRequest(settings, $"/api/v3/indexer/{indexer.Id}", HttpMethod.PUT);
+
+ request.SetContent(indexer.ToJson());
+
+ return Execute(request);
+ }
+
public ValidationFailure Test(SonarrSettings settings)
{
try
diff --git a/src/NzbDrone.Core/Configuration/ConfigFileProvider.cs b/src/NzbDrone.Core/Configuration/ConfigFileProvider.cs
index 2c9e9340c..45f2366b4 100644
--- a/src/NzbDrone.Core/Configuration/ConfigFileProvider.cs
+++ b/src/NzbDrone.Core/Configuration/ConfigFileProvider.cs
@@ -370,6 +370,7 @@ namespace NzbDrone.Core.Configuration
public void Execute(ResetApiKeyCommand message)
{
SetValue("ApiKey", GenerateApiKey());
+ _eventAggregator.PublishEvent(new ApiKeyChangedEvent());
}
}
}
diff --git a/src/NzbDrone.Core/Configuration/Events/ApiKeyChangedEvent.cs b/src/NzbDrone.Core/Configuration/Events/ApiKeyChangedEvent.cs
new file mode 100644
index 000000000..86e79bb41
--- /dev/null
+++ b/src/NzbDrone.Core/Configuration/Events/ApiKeyChangedEvent.cs
@@ -0,0 +1,8 @@
+using NzbDrone.Common.Messaging;
+
+namespace NzbDrone.Core.Configuration.Events
+{
+ public class ApiKeyChangedEvent : IEvent
+ {
+ }
+}
diff --git a/src/NzbDrone.Core/Indexers/IndexerFactory.cs b/src/NzbDrone.Core/Indexers/IndexerFactory.cs
index ecec57ff0..429910e82 100644
--- a/src/NzbDrone.Core/Indexers/IndexerFactory.cs
+++ b/src/NzbDrone.Core/Indexers/IndexerFactory.cs
@@ -15,6 +15,7 @@ namespace NzbDrone.Core.Indexers
public interface IIndexerFactory : IProviderFactory
{
List Enabled(bool filterBlockedIndexers = true);
+ List AllProviders(bool filterBlockedIndexers = true);
void DeleteIndexers(List indexerIds);
}
@@ -188,6 +189,18 @@ namespace NzbDrone.Core.Indexers
return enabledIndexers.ToList();
}
+ public List AllProviders(bool filterBlockedIndexers = true)
+ {
+ var enabledIndexers = All().Select(GetInstance);
+
+ if (filterBlockedIndexers)
+ {
+ return FilterBlockedIndexers(enabledIndexers).ToList();
+ }
+
+ return enabledIndexers.ToList();
+ }
+
private IEnumerable FilterBlockedIndexers(IEnumerable indexers)
{
var blockedIndexers = _indexerStatusService.GetBlockedProviders().ToDictionary(v => v.ProviderId, v => v);
diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json
index 28755adf1..6edff7f27 100644
--- a/src/NzbDrone.Core/Localization/Core/en.json
+++ b/src/NzbDrone.Core/Localization/Core/en.json
@@ -3,11 +3,11 @@
"AcceptConfirmationModal": "Accept Confirmation Modal",
"Actions": "Actions",
"Added": "Added",
+ "AddedToDownloadClient": "Release added to client",
"AddIndexer": "Add Indexer",
"AddingTag": "Adding tag",
"AddNewIndexer": "Add New Indexer",
"AddToDownloadClient": "Add release to download client",
- "AddedToDownloadClient": "Release added to client",
"Age": "Age",
"All": "All",
"AllIndexersHiddenDueToFilter": "All indexers are hidden due to applied filter.",
@@ -66,6 +66,8 @@
"DBMigration": "DB Migration",
"DelayProfile": "Delay Profile",
"Delete": "Delete",
+ "DeleteApplication": "Delete Application",
+ "DeleteApplicationMessageText": "Are you sure you want to delete the application '{0}'?",
"DeleteBackup": "Delete Backup",
"DeleteBackupMessageText": "Are you sure you want to delete the backup '{0}'?",
"DeleteIndexer": "Delete Indexer",