pull/32/head
nitsua 3 years ago committed by Qstick
parent 77d93321c4
commit d9ef1c72c0

@ -71,7 +71,7 @@ class Application extends Component {
{
syncLevel === 'addOnly' &&
<Label kind={kinds.WARNING}>
Add Only
Add and Remove Only
</Label>
}

@ -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' }
];

@ -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<ProviderDeletedEvent<IIndexer>>,
IHandleAsync<ProviderAddedEvent<IApplication>>,
IHandleAsync<ProviderUpdatedEvent<IIndexer>>,
IHandleAsync<ApiKeyChangedEvent>,
IExecute<ApplicationIndexerSyncCommand>
{
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<IApplication> { app });
SyncIndexers(new List<IApplication> { app }, indexers);
}
}
@ -57,8 +60,7 @@ namespace NzbDrone.Core.Applications
public void HandleAsync(ProviderDeletedEvent<IIndexer> 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<IIndexer> 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> { (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<IApplication> 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<IApplication> applications, List<IndexerDefinition> 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.");
}
}
}

@ -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,

@ -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<int> Tags { get; set; }
public List<LidarrField> 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;
}
}
}

@ -13,8 +13,10 @@ namespace NzbDrone.Core.Applications.Lidarr
{
LidarrIndexer AddIndexer(LidarrIndexer indexer, LidarrSettings settings);
List<LidarrIndexer> GetIndexers(LidarrSettings settings);
LidarrIndexer GetIndexer(int indexerId, LidarrSettings settings);
List<LidarrIndexer> 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<List<LidarrIndexer>>(request);
}
public LidarrIndexer GetIndexer(int indexerId, LidarrSettings settings)
{
try
{
var request = BuildRequest(settings, $"/api/v1/indexer/{indexerId}", HttpMethod.GET);
return Execute<LidarrIndexer>(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<LidarrIndexer>(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<LidarrIndexer>(request);
}
public ValidationFailure Test(LidarrSettings settings)
{
try

@ -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,

@ -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<int> Tags { get; set; }
public List<RadarrField> 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;
}
}
}

@ -13,8 +13,10 @@ namespace NzbDrone.Core.Applications.Radarr
{
RadarrIndexer AddIndexer(RadarrIndexer indexer, RadarrSettings settings);
List<RadarrIndexer> GetIndexers(RadarrSettings settings);
RadarrIndexer GetIndexer(int indexerId, RadarrSettings settings);
List<RadarrIndexer> 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<List<RadarrIndexer>>(request);
}
public RadarrIndexer GetIndexer(int indexerId, RadarrSettings settings)
{
try
{
var request = BuildRequest(settings, $"/api/v3/indexer/{indexerId}", HttpMethod.GET);
return Execute<RadarrIndexer>(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<RadarrIndexer>(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<RadarrIndexer>(request);
}
public ValidationFailure Test(RadarrSettings settings)
{
try

@ -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,

@ -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<int> Tags { get; set; }
public List<ReadarrField> 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;
}
}
}

@ -13,8 +13,10 @@ namespace NzbDrone.Core.Applications.Readarr
{
ReadarrIndexer AddIndexer(ReadarrIndexer indexer, ReadarrSettings settings);
List<ReadarrIndexer> GetIndexers(ReadarrSettings settings);
ReadarrIndexer GetIndexer(int indexerId, ReadarrSettings settings);
List<ReadarrIndexer> 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<List<ReadarrIndexer>>(request);
}
public ReadarrIndexer GetIndexer(int indexerId, ReadarrSettings settings)
{
try
{
var request = BuildRequest(settings, $"/api/v1/indexer/{indexerId}", HttpMethod.GET);
return Execute<ReadarrIndexer>(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<ReadarrIndexer>(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<ReadarrIndexer>(request);
}
public ValidationFailure Test(ReadarrSettings settings)
{
try

@ -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,

@ -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<int> Tags { get; set; }
public List<SonarrField> 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;
}
}
}

@ -13,8 +13,10 @@ namespace NzbDrone.Core.Applications.Sonarr
{
SonarrIndexer AddIndexer(SonarrIndexer indexer, SonarrSettings settings);
List<SonarrIndexer> GetIndexers(SonarrSettings settings);
SonarrIndexer GetIndexer(int indexerId, SonarrSettings settings);
List<SonarrIndexer> 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<List<SonarrIndexer>>(request);
}
public SonarrIndexer GetIndexer(int indexerId, SonarrSettings settings)
{
try
{
var request = BuildRequest(settings, $"/api/v1/indexer/{indexerId}", HttpMethod.GET);
return Execute<SonarrIndexer>(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<SonarrIndexer>(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<SonarrIndexer>(request);
}
public ValidationFailure Test(SonarrSettings settings)
{
try

@ -370,6 +370,7 @@ namespace NzbDrone.Core.Configuration
public void Execute(ResetApiKeyCommand message)
{
SetValue("ApiKey", GenerateApiKey());
_eventAggregator.PublishEvent(new ApiKeyChangedEvent());
}
}
}

@ -0,0 +1,8 @@
using NzbDrone.Common.Messaging;
namespace NzbDrone.Core.Configuration.Events
{
public class ApiKeyChangedEvent : IEvent
{
}
}

@ -15,6 +15,7 @@ namespace NzbDrone.Core.Indexers
public interface IIndexerFactory : IProviderFactory<IIndexer, IndexerDefinition>
{
List<IIndexer> Enabled(bool filterBlockedIndexers = true);
List<IIndexer> AllProviders(bool filterBlockedIndexers = true);
void DeleteIndexers(List<int> indexerIds);
}
@ -188,6 +189,18 @@ namespace NzbDrone.Core.Indexers
return enabledIndexers.ToList();
}
public List<IIndexer> AllProviders(bool filterBlockedIndexers = true)
{
var enabledIndexers = All().Select(GetInstance);
if (filterBlockedIndexers)
{
return FilterBlockedIndexers(enabledIndexers).ToList();
}
return enabledIndexers.ToList();
}
private IEnumerable<IIndexer> FilterBlockedIndexers(IEnumerable<IIndexer> indexers)
{
var blockedIndexers = _indexerStatusService.GetBlockedProviders().ToDictionary(v => v.ProviderId, v => v);

@ -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",

Loading…
Cancel
Save