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

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

@ -19,7 +19,7 @@ import styles from './EditApplicationModalContent.css';
const syncLevelOptions = [ const syncLevelOptions = [
{ key: 'disabled', value: 'Disabled' }, { key: 'disabled', value: 'Disabled' },
{ key: 'addOnly', value: 'Add Only' }, { key: 'addOnly', value: 'Add and Remove Only' },
{ key: 'fullSync', value: 'Full Sync' } { key: 'fullSync', value: 'Full Sync' }
]; ];

@ -4,6 +4,7 @@ using System.Linq;
using System.Net; using System.Net;
using NLog; using NLog;
using NzbDrone.Common.Http; using NzbDrone.Common.Http;
using NzbDrone.Core.Configuration.Events;
using NzbDrone.Core.Indexers; using NzbDrone.Core.Indexers;
using NzbDrone.Core.Messaging.Commands; using NzbDrone.Core.Messaging.Commands;
using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Messaging.Events;
@ -15,6 +16,7 @@ namespace NzbDrone.Core.Applications
IHandleAsync<ProviderDeletedEvent<IIndexer>>, IHandleAsync<ProviderDeletedEvent<IIndexer>>,
IHandleAsync<ProviderAddedEvent<IApplication>>, IHandleAsync<ProviderAddedEvent<IApplication>>,
IHandleAsync<ProviderUpdatedEvent<IIndexer>>, IHandleAsync<ProviderUpdatedEvent<IIndexer>>,
IHandleAsync<ApiKeyChangedEvent>,
IExecute<ApplicationIndexerSyncCommand> IExecute<ApplicationIndexerSyncCommand>
{ {
private readonly IApplicationFactory _applicationsFactory; private readonly IApplicationFactory _applicationsFactory;
@ -40,8 +42,9 @@ namespace NzbDrone.Core.Applications
if (appDefinition.Enable) if (appDefinition.Enable)
{ {
var app = _applicationsFactory.GetInstance(appDefinition); 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) public void HandleAsync(ProviderDeletedEvent<IIndexer> message)
{ {
var enabledApps = _applicationsFactory.SyncEnabled() var enabledApps = _applicationsFactory.SyncEnabled();
.Where(n => ((ApplicationDefinition)n.Definition).SyncLevel == ApplicationSyncLevel.FullSync);
foreach (var app in enabledApps) foreach (var app in enabledApps)
{ {
@ -69,42 +71,57 @@ namespace NzbDrone.Core.Applications
public void HandleAsync(ProviderUpdatedEvent<IIndexer> message) public void HandleAsync(ProviderUpdatedEvent<IIndexer> message)
{ {
var enabledApps = _applicationsFactory.SyncEnabled() 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) SyncIndexers(enabledApps, new List<IndexerDefinition> { (IndexerDefinition)message.Definition });
{
ExecuteAction(a => a.UpdateIndexer((IndexerDefinition)message.Definition), app);
} }
public void HandleAsync(ApiKeyChangedEvent message)
{
var enabledApps = _applicationsFactory.SyncEnabled();
var indexers = _indexerFactory.AllProviders().Select(i => (IndexerDefinition)i.Definition).ToList();
SyncIndexers(enabledApps, indexers);
} }
public void Execute(ApplicationIndexerSyncCommand message) public void Execute(ApplicationIndexerSyncCommand message)
{ {
var enabledApps = _applicationsFactory.SyncEnabled(); 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) private void SyncIndexers(List<IApplication> applications, List<IndexerDefinition> indexers)
{ {
var indexers = _indexerFactory.Enabled();
foreach (var app in applications) foreach (var app in applications)
{ {
var indexerMappings = _appIndexerMapService.GetMappingsForApp(app.Definition.Id); var indexerMappings = _appIndexerMapService.GetMappingsForApp(app.Definition.Id);
foreach (var indexer in indexers) 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))
{
if (((ApplicationDefinition)app.Definition).SyncLevel == ApplicationSyncLevel.FullSync)
{ {
continue; ExecuteAction(a => a.UpdateIndexer(definition), app);
} }
}
var definition = (IndexerDefinition)indexer.Definition; else
{
if (indexer.Enable)
{
ExecuteAction(a => a.AddIndexer(definition), app); ExecuteAction(a => a.AddIndexer(definition), app);
} }
} }
} }
}
}
private void ExecuteAction(Action<IApplication> applicationAction, IApplication application) private void ExecuteAction(Action<IApplication> applicationAction, IApplication application)
{ {
@ -156,7 +173,7 @@ namespace NzbDrone.Core.Applications
catch (Exception ex) catch (Exception ex)
{ {
_applicationStatusService.RecordFailure(application.Definition.Id); _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()) if (indexer.Capabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any())
{ {
var schema = _schemaCache.Get(Definition.Settings.ToJson(), () => _lidarrV1Proxy.GetIndexerSchema(Settings), TimeSpan.FromDays(7)); var lidarrIndexer = BuildLidarrIndexer(indexer, indexer.Protocol);
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 remoteIndexer = _lidarrV1Proxy.AddIndexer(lidarrIndexer, Settings); var remoteIndexer = _lidarrV1Proxy.AddIndexer(lidarrIndexer, Settings);
_appIndexerMapService.Insert(new AppIndexerMap { AppId = Definition.Id, IndexerId = indexer.Id, RemoteIndexerId = remoteIndexer.Id }); _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) public override void UpdateIndexer(IndexerDefinition indexer)
{ {
//Use the Id mapping here to delete the correct indexer _logger.Debug("Updating indexer {0}[{1}]", indexer.Name, indexer.Id);
throw new System.NotImplementedException();
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 var lidarrIndexer = new LidarrIndexer
{ {
Id = 0, Id = 0,
Name = $"{indexer.Name} (Prowlarr)", Name = $"{indexer.Name} (Prowlarr)",
EnableRss = true, EnableRss = indexer.Enable,
EnableAutomaticSearch = true, EnableAutomaticSearch = indexer.Enable,
EnableInteractiveSearch = true, EnableInteractiveSearch = indexer.Enable,
Priority = indexer.Priority, Priority = indexer.Priority,
Implementation = indexer.Protocol == DownloadProtocol.Usenet ? "Newznab" : "Torznab", Implementation = indexer.Protocol == DownloadProtocol.Usenet ? "Newznab" : "Torznab",
ConfigContract = schema.ConfigContract, ConfigContract = schema.ConfigContract,

@ -1,4 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
namespace NzbDrone.Core.Applications.Lidarr namespace NzbDrone.Core.Applications.Lidarr
{ {
@ -16,5 +17,26 @@ namespace NzbDrone.Core.Applications.Lidarr
public string InfoLink { get; set; } public string InfoLink { get; set; }
public HashSet<int> Tags { get; set; } public HashSet<int> Tags { get; set; }
public List<LidarrField> Fields { 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); LidarrIndexer AddIndexer(LidarrIndexer indexer, LidarrSettings settings);
List<LidarrIndexer> GetIndexers(LidarrSettings settings); List<LidarrIndexer> GetIndexers(LidarrSettings settings);
LidarrIndexer GetIndexer(int indexerId, LidarrSettings settings);
List<LidarrIndexer> GetIndexerSchema(LidarrSettings settings); List<LidarrIndexer> GetIndexerSchema(LidarrSettings settings);
void RemoveIndexer(int indexerId, LidarrSettings settings); void RemoveIndexer(int indexerId, LidarrSettings settings);
LidarrIndexer UpdateIndexer(LidarrIndexer indexer, LidarrSettings settings);
ValidationFailure Test(LidarrSettings settings); ValidationFailure Test(LidarrSettings settings);
} }
@ -41,6 +43,24 @@ namespace NzbDrone.Core.Applications.Lidarr
return Execute<List<LidarrIndexer>>(request); 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) public void RemoveIndexer(int indexerId, LidarrSettings settings)
{ {
var request = BuildRequest(settings, $"/api/v1/indexer/{indexerId}", HttpMethod.DELETE); var request = BuildRequest(settings, $"/api/v1/indexer/{indexerId}", HttpMethod.DELETE);
@ -62,6 +82,15 @@ namespace NzbDrone.Core.Applications.Lidarr
return Execute<LidarrIndexer>(request); 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) public ValidationFailure Test(LidarrSettings settings)
{ {
try try

@ -40,11 +40,7 @@ namespace NzbDrone.Core.Applications.Radarr
{ {
if (indexer.Capabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any()) if (indexer.Capabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any())
{ {
var schema = _schemaCache.Get(Definition.Settings.ToJson(), () => _radarrV3Proxy.GetIndexerSchema(Settings), TimeSpan.FromDays(7)); var radarrIndexer = BuildRadarrIndexer(indexer, indexer.Protocol);
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 remoteIndexer = _radarrV3Proxy.AddIndexer(radarrIndexer, Settings); var remoteIndexer = _radarrV3Proxy.AddIndexer(radarrIndexer, Settings);
_appIndexerMapService.Insert(new AppIndexerMap { AppId = Definition.Id, IndexerId = indexer.Id, RemoteIndexerId = remoteIndexer.Id }); _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) public override void UpdateIndexer(IndexerDefinition indexer)
{ {
//Use the Id mapping here to delete the correct indexer _logger.Debug("Updating indexer {0}[{1}]", indexer.Name, indexer.Id);
throw new System.NotImplementedException();
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 var radarrIndexer = new RadarrIndexer
{ {
Id = 0, Id = id,
Name = $"{indexer.Name} (Prowlarr)", Name = $"{indexer.Name} (Prowlarr)",
EnableRss = true, EnableRss = indexer.Enable,
EnableAutomaticSearch = true, EnableAutomaticSearch = indexer.Enable,
EnableInteractiveSearch = true, EnableInteractiveSearch = indexer.Enable,
Priority = indexer.Priority, Priority = indexer.Priority,
Implementation = indexer.Protocol == DownloadProtocol.Usenet ? "Newznab" : "Torznab", Implementation = indexer.Protocol == DownloadProtocol.Usenet ? "Newznab" : "Torznab",
ConfigContract = schema.ConfigContract, ConfigContract = schema.ConfigContract,

@ -1,4 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
namespace NzbDrone.Core.Applications.Radarr namespace NzbDrone.Core.Applications.Radarr
{ {
@ -16,5 +17,26 @@ namespace NzbDrone.Core.Applications.Radarr
public string InfoLink { get; set; } public string InfoLink { get; set; }
public HashSet<int> Tags { get; set; } public HashSet<int> Tags { get; set; }
public List<RadarrField> Fields { 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); RadarrIndexer AddIndexer(RadarrIndexer indexer, RadarrSettings settings);
List<RadarrIndexer> GetIndexers(RadarrSettings settings); List<RadarrIndexer> GetIndexers(RadarrSettings settings);
RadarrIndexer GetIndexer(int indexerId, RadarrSettings settings);
List<RadarrIndexer> GetIndexerSchema(RadarrSettings settings); List<RadarrIndexer> GetIndexerSchema(RadarrSettings settings);
void RemoveIndexer(int indexerId, RadarrSettings settings); void RemoveIndexer(int indexerId, RadarrSettings settings);
RadarrIndexer UpdateIndexer(RadarrIndexer indexer, RadarrSettings settings);
ValidationFailure Test(RadarrSettings settings); ValidationFailure Test(RadarrSettings settings);
} }
@ -41,6 +43,24 @@ namespace NzbDrone.Core.Applications.Radarr
return Execute<List<RadarrIndexer>>(request); 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) public void RemoveIndexer(int indexerId, RadarrSettings settings)
{ {
var request = BuildRequest(settings, $"/api/v3/indexer/{indexerId}", HttpMethod.DELETE); var request = BuildRequest(settings, $"/api/v3/indexer/{indexerId}", HttpMethod.DELETE);
@ -62,6 +82,15 @@ namespace NzbDrone.Core.Applications.Radarr
return Execute<RadarrIndexer>(request); 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) public ValidationFailure Test(RadarrSettings settings)
{ {
try try

@ -40,11 +40,7 @@ namespace NzbDrone.Core.Applications.Readarr
{ {
if (indexer.Capabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any()) if (indexer.Capabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any())
{ {
var schema = _schemaCache.Get(Definition.Settings.ToJson(), () => _readarrV1Proxy.GetIndexerSchema(Settings), TimeSpan.FromDays(7)); var readarrIndexer = BuildReadarrIndexer(indexer, indexer.Protocol);
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 remoteIndexer = _readarrV1Proxy.AddIndexer(readarrIndexer, Settings); var remoteIndexer = _readarrV1Proxy.AddIndexer(readarrIndexer, Settings);
_appIndexerMapService.Insert(new AppIndexerMap { AppId = Definition.Id, IndexerId = indexer.Id, RemoteIndexerId = remoteIndexer.Id }); _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) public override void UpdateIndexer(IndexerDefinition indexer)
{ {
//Use the Id mapping here to delete the correct indexer _logger.Debug("Updating indexer {0}[{1}]", indexer.Name, indexer.Id);
throw new System.NotImplementedException();
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 var readarrIndexer = new ReadarrIndexer
{ {
Id = 0, Id = 0,
Name = $"{indexer.Name} (Prowlarr)", Name = $"{indexer.Name} (Prowlarr)",
EnableRss = true, EnableRss = indexer.Enable,
EnableAutomaticSearch = true, EnableAutomaticSearch = indexer.Enable,
EnableInteractiveSearch = true, EnableInteractiveSearch = indexer.Enable,
Priority = indexer.Priority, Priority = indexer.Priority,
Implementation = indexer.Protocol == DownloadProtocol.Usenet ? "Newznab" : "Torznab", Implementation = indexer.Protocol == DownloadProtocol.Usenet ? "Newznab" : "Torznab",
ConfigContract = schema.ConfigContract, ConfigContract = schema.ConfigContract,

@ -1,4 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
namespace NzbDrone.Core.Applications.Readarr namespace NzbDrone.Core.Applications.Readarr
{ {
@ -16,5 +17,26 @@ namespace NzbDrone.Core.Applications.Readarr
public string InfoLink { get; set; } public string InfoLink { get; set; }
public HashSet<int> Tags { get; set; } public HashSet<int> Tags { get; set; }
public List<ReadarrField> Fields { 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); ReadarrIndexer AddIndexer(ReadarrIndexer indexer, ReadarrSettings settings);
List<ReadarrIndexer> GetIndexers(ReadarrSettings settings); List<ReadarrIndexer> GetIndexers(ReadarrSettings settings);
ReadarrIndexer GetIndexer(int indexerId, ReadarrSettings settings);
List<ReadarrIndexer> GetIndexerSchema(ReadarrSettings settings); List<ReadarrIndexer> GetIndexerSchema(ReadarrSettings settings);
void RemoveIndexer(int indexerId, ReadarrSettings settings); void RemoveIndexer(int indexerId, ReadarrSettings settings);
ReadarrIndexer UpdateIndexer(ReadarrIndexer indexer, ReadarrSettings settings);
ValidationFailure Test(ReadarrSettings settings); ValidationFailure Test(ReadarrSettings settings);
} }
@ -41,6 +43,24 @@ namespace NzbDrone.Core.Applications.Readarr
return Execute<List<ReadarrIndexer>>(request); 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) public void RemoveIndexer(int indexerId, ReadarrSettings settings)
{ {
var request = BuildRequest(settings, $"/api/v1/indexer/{indexerId}", HttpMethod.DELETE); var request = BuildRequest(settings, $"/api/v1/indexer/{indexerId}", HttpMethod.DELETE);
@ -62,6 +82,15 @@ namespace NzbDrone.Core.Applications.Readarr
return Execute<ReadarrIndexer>(request); 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) public ValidationFailure Test(ReadarrSettings settings)
{ {
try try

@ -40,11 +40,7 @@ namespace NzbDrone.Core.Applications.Sonarr
{ {
if (indexer.Capabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any()) if (indexer.Capabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any())
{ {
var schema = _schemaCache.Get(Definition.Settings.ToJson(), () => _sonarrV3Proxy.GetIndexerSchema(Settings), TimeSpan.FromDays(7)); var sonarrIndexer = BuildSonarrIndexer(indexer, indexer.Protocol);
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 remoteIndexer = _sonarrV3Proxy.AddIndexer(sonarrIndexer, Settings); var remoteIndexer = _sonarrV3Proxy.AddIndexer(sonarrIndexer, Settings);
_appIndexerMapService.Insert(new AppIndexerMap { AppId = Definition.Id, IndexerId = indexer.Id, RemoteIndexerId = remoteIndexer.Id }); _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) public override void UpdateIndexer(IndexerDefinition indexer)
{ {
//Use the Id mapping here to delete the correct indexer _logger.Debug("Updating indexer {0}[{1}]", indexer.Name, indexer.Id);
throw new System.NotImplementedException();
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 var sonarrIndexer = new SonarrIndexer
{ {
Id = 0, Id = 0,
Name = $"{indexer.Name} (Prowlarr)", Name = $"{indexer.Name} (Prowlarr)",
EnableRss = true, EnableRss = indexer.Enable,
EnableAutomaticSearch = true, EnableAutomaticSearch = indexer.Enable,
EnableInteractiveSearch = true, EnableInteractiveSearch = indexer.Enable,
Priority = indexer.Priority, Priority = indexer.Priority,
Implementation = indexer.Protocol == DownloadProtocol.Usenet ? "Newznab" : "Torznab", Implementation = indexer.Protocol == DownloadProtocol.Usenet ? "Newznab" : "Torznab",
ConfigContract = schema.ConfigContract, ConfigContract = schema.ConfigContract,

@ -1,4 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
namespace NzbDrone.Core.Applications.Sonarr namespace NzbDrone.Core.Applications.Sonarr
{ {
@ -16,5 +17,26 @@ namespace NzbDrone.Core.Applications.Sonarr
public string InfoLink { get; set; } public string InfoLink { get; set; }
public HashSet<int> Tags { get; set; } public HashSet<int> Tags { get; set; }
public List<SonarrField> Fields { 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); SonarrIndexer AddIndexer(SonarrIndexer indexer, SonarrSettings settings);
List<SonarrIndexer> GetIndexers(SonarrSettings settings); List<SonarrIndexer> GetIndexers(SonarrSettings settings);
SonarrIndexer GetIndexer(int indexerId, SonarrSettings settings);
List<SonarrIndexer> GetIndexerSchema(SonarrSettings settings); List<SonarrIndexer> GetIndexerSchema(SonarrSettings settings);
void RemoveIndexer(int indexerId, SonarrSettings settings); void RemoveIndexer(int indexerId, SonarrSettings settings);
SonarrIndexer UpdateIndexer(SonarrIndexer indexer, SonarrSettings settings);
ValidationFailure Test(SonarrSettings settings); ValidationFailure Test(SonarrSettings settings);
} }
@ -41,6 +43,24 @@ namespace NzbDrone.Core.Applications.Sonarr
return Execute<List<SonarrIndexer>>(request); 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) public void RemoveIndexer(int indexerId, SonarrSettings settings)
{ {
var request = BuildRequest(settings, $"/api/v3/indexer/{indexerId}", HttpMethod.DELETE); var request = BuildRequest(settings, $"/api/v3/indexer/{indexerId}", HttpMethod.DELETE);
@ -62,6 +82,15 @@ namespace NzbDrone.Core.Applications.Sonarr
return Execute<SonarrIndexer>(request); 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) public ValidationFailure Test(SonarrSettings settings)
{ {
try try

@ -370,6 +370,7 @@ namespace NzbDrone.Core.Configuration
public void Execute(ResetApiKeyCommand message) public void Execute(ResetApiKeyCommand message)
{ {
SetValue("ApiKey", GenerateApiKey()); 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> public interface IIndexerFactory : IProviderFactory<IIndexer, IndexerDefinition>
{ {
List<IIndexer> Enabled(bool filterBlockedIndexers = true); List<IIndexer> Enabled(bool filterBlockedIndexers = true);
List<IIndexer> AllProviders(bool filterBlockedIndexers = true);
void DeleteIndexers(List<int> indexerIds); void DeleteIndexers(List<int> indexerIds);
} }
@ -188,6 +189,18 @@ namespace NzbDrone.Core.Indexers
return enabledIndexers.ToList(); 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) private IEnumerable<IIndexer> FilterBlockedIndexers(IEnumerable<IIndexer> indexers)
{ {
var blockedIndexers = _indexerStatusService.GetBlockedProviders().ToDictionary(v => v.ProviderId, v => v); var blockedIndexers = _indexerStatusService.GetBlockedProviders().ToDictionary(v => v.ProviderId, v => v);

@ -3,11 +3,11 @@
"AcceptConfirmationModal": "Accept Confirmation Modal", "AcceptConfirmationModal": "Accept Confirmation Modal",
"Actions": "Actions", "Actions": "Actions",
"Added": "Added", "Added": "Added",
"AddedToDownloadClient": "Release added to client",
"AddIndexer": "Add Indexer", "AddIndexer": "Add Indexer",
"AddingTag": "Adding tag", "AddingTag": "Adding tag",
"AddNewIndexer": "Add New Indexer", "AddNewIndexer": "Add New Indexer",
"AddToDownloadClient": "Add release to download client", "AddToDownloadClient": "Add release to download client",
"AddedToDownloadClient": "Release added to client",
"Age": "Age", "Age": "Age",
"All": "All", "All": "All",
"AllIndexersHiddenDueToFilter": "All indexers are hidden due to applied filter.", "AllIndexersHiddenDueToFilter": "All indexers are hidden due to applied filter.",
@ -66,6 +66,8 @@
"DBMigration": "DB Migration", "DBMigration": "DB Migration",
"DelayProfile": "Delay Profile", "DelayProfile": "Delay Profile",
"Delete": "Delete", "Delete": "Delete",
"DeleteApplication": "Delete Application",
"DeleteApplicationMessageText": "Are you sure you want to delete the application '{0}'?",
"DeleteBackup": "Delete Backup", "DeleteBackup": "Delete Backup",
"DeleteBackupMessageText": "Are you sure you want to delete the backup '{0}'?", "DeleteBackupMessageText": "Are you sure you want to delete the backup '{0}'?",
"DeleteIndexer": "Delete Indexer", "DeleteIndexer": "Delete Indexer",

Loading…
Cancel
Save