mirror of
https://github.com/Prowlarr/Prowlarr.git
synced 2025-09-17 17:14:18 +02:00
Basic Application Syncing
This commit is contained in:
11
src/NzbDrone.Core/Applications/AppIndexerMap.cs
Normal file
11
src/NzbDrone.Core/Applications/AppIndexerMap.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
using NzbDrone.Core.Datastore;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Applications
|
||||||
|
{
|
||||||
|
public class AppIndexerMap : ModelBase
|
||||||
|
{
|
||||||
|
public int IndexerId { get; set; }
|
||||||
|
public int AppId { get; set; }
|
||||||
|
public int RemoteIndexerId { get; set; }
|
||||||
|
}
|
||||||
|
}
|
30
src/NzbDrone.Core/Applications/AppIndexerMapRepository.cs
Normal file
30
src/NzbDrone.Core/Applications/AppIndexerMapRepository.cs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using NzbDrone.Core.Datastore;
|
||||||
|
using NzbDrone.Core.Messaging.Events;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Applications
|
||||||
|
{
|
||||||
|
public interface IAppIndexerMapRepository : IBasicRepository<AppIndexerMap>
|
||||||
|
{
|
||||||
|
List<AppIndexerMap> GetMappingsForApp(int appId);
|
||||||
|
void DeleteAllForApp(int appId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TagRepository : BasicRepository<AppIndexerMap>, IAppIndexerMapRepository
|
||||||
|
{
|
||||||
|
public TagRepository(IMainDatabase database, IEventAggregator eventAggregator)
|
||||||
|
: base(database, eventAggregator)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DeleteAllForApp(int appId)
|
||||||
|
{
|
||||||
|
Delete(x => x.AppId == appId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<AppIndexerMap> GetMappingsForApp(int appId)
|
||||||
|
{
|
||||||
|
return Query(x => x.AppId == appId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
37
src/NzbDrone.Core/Applications/AppIndexerMapService.cs
Normal file
37
src/NzbDrone.Core/Applications/AppIndexerMapService.cs
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Security.Cryptography.X509Certificates;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Applications
|
||||||
|
{
|
||||||
|
public interface IAppIndexerMapService
|
||||||
|
{
|
||||||
|
List<AppIndexerMap> GetMappingsForApp(int appId);
|
||||||
|
AppIndexerMap Insert(AppIndexerMap appIndexerMap);
|
||||||
|
void DeleteAllForApp(int appId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AppIndexerMapService : IAppIndexerMapService
|
||||||
|
{
|
||||||
|
private readonly IAppIndexerMapRepository _appIndexerMapRepository;
|
||||||
|
|
||||||
|
public AppIndexerMapService(IAppIndexerMapRepository appIndexerMapRepository)
|
||||||
|
{
|
||||||
|
_appIndexerMapRepository = appIndexerMapRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DeleteAllForApp(int appId)
|
||||||
|
{
|
||||||
|
_appIndexerMapRepository.DeleteAllForApp(appId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<AppIndexerMap> GetMappingsForApp(int appId)
|
||||||
|
{
|
||||||
|
return _appIndexerMapRepository.GetMappingsForApp(appId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AppIndexerMap Insert(AppIndexerMap appIndexerMap)
|
||||||
|
{
|
||||||
|
return _appIndexerMapRepository.Insert(appIndexerMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -1,13 +1,18 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using FluentValidation.Results;
|
using FluentValidation.Results;
|
||||||
|
using NLog;
|
||||||
|
using NzbDrone.Core.Indexers;
|
||||||
using NzbDrone.Core.ThingiProvider;
|
using NzbDrone.Core.ThingiProvider;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Applications
|
namespace NzbDrone.Core.Applications
|
||||||
{
|
{
|
||||||
public abstract class ApplicationBase<TSettings> : IApplications
|
public abstract class ApplicationBase<TSettings> : IApplication
|
||||||
where TSettings : IProviderConfig, new()
|
where TSettings : IProviderConfig, new()
|
||||||
{
|
{
|
||||||
|
protected readonly IAppIndexerMapService _appIndexerMapService;
|
||||||
|
protected readonly Logger _logger;
|
||||||
|
|
||||||
public abstract string Name { get; }
|
public abstract string Name { get; }
|
||||||
|
|
||||||
public Type ConfigContract => typeof(TSettings);
|
public Type ConfigContract => typeof(TSettings);
|
||||||
@@ -19,6 +24,12 @@ namespace NzbDrone.Core.Applications
|
|||||||
|
|
||||||
protected TSettings Settings => (TSettings)Definition.Settings;
|
protected TSettings Settings => (TSettings)Definition.Settings;
|
||||||
|
|
||||||
|
public ApplicationBase(IAppIndexerMapService appIndexerMapService, Logger logger)
|
||||||
|
{
|
||||||
|
_appIndexerMapService = appIndexerMapService;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return GetType().Name;
|
return GetType().Name;
|
||||||
@@ -40,6 +51,11 @@ namespace NzbDrone.Core.Applications
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract void AddIndexer(IndexerDefinition indexer);
|
||||||
|
public abstract void UpdateIndexer(IndexerDefinition indexer);
|
||||||
|
public abstract void RemoveIndexer(int indexerId);
|
||||||
|
public abstract void SyncIndexers();
|
||||||
|
|
||||||
public virtual object RequestAction(string action, IDictionary<string, string> query)
|
public virtual object RequestAction(string action, IDictionary<string, string> query)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
|
@@ -7,13 +7,13 @@ using NzbDrone.Core.ThingiProvider;
|
|||||||
|
|
||||||
namespace NzbDrone.Core.Applications
|
namespace NzbDrone.Core.Applications
|
||||||
{
|
{
|
||||||
public interface IApplicationsFactory : IProviderFactory<IApplications, ApplicationDefinition>
|
public interface IApplicationFactory : IProviderFactory<IApplication, ApplicationDefinition>
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ApplicationFactory : ProviderFactory<IApplications, ApplicationDefinition>, IApplicationsFactory
|
public class ApplicationFactory : ProviderFactory<IApplication, ApplicationDefinition>, IApplicationFactory
|
||||||
{
|
{
|
||||||
public ApplicationFactory(IApplicationsRepository providerRepository, IEnumerable<IApplications> providers, IContainer container, IEventAggregator eventAggregator, Logger logger)
|
public ApplicationFactory(IApplicationsRepository providerRepository, IEnumerable<IApplication> providers, IContainer container, IEventAggregator eventAggregator, Logger logger)
|
||||||
: base(providerRepository, providers, container, eventAggregator, logger)
|
: base(providerRepository, providers, container, eventAggregator, logger)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@@ -1,16 +1,65 @@
|
|||||||
using NLog;
|
using NLog;
|
||||||
|
using NzbDrone.Core.Indexers;
|
||||||
|
using NzbDrone.Core.Messaging.Events;
|
||||||
|
using NzbDrone.Core.ThingiProvider.Events;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Applications
|
namespace NzbDrone.Core.Applications
|
||||||
{
|
{
|
||||||
public class ApplicationService
|
public class ApplicationService : IHandle<ProviderAddedEvent<IIndexer>>, IHandle<ProviderDeletedEvent<IIndexer>>, IHandle<ProviderAddedEvent<IApplication>>, IHandle<ProviderUpdatedEvent<IIndexer>>
|
||||||
{
|
{
|
||||||
private readonly IApplicationsFactory _applicationsFactory;
|
private readonly IApplicationFactory _applicationsFactory;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
public ApplicationService(IApplicationsFactory applicationsFactory, Logger logger)
|
public ApplicationService(IApplicationFactory applicationsFactory, Logger logger)
|
||||||
{
|
{
|
||||||
_applicationsFactory = applicationsFactory;
|
_applicationsFactory = applicationsFactory;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sync Indexers on App Add if Sync Enabled
|
||||||
|
public void Handle(ProviderAddedEvent<IApplication> message)
|
||||||
|
{
|
||||||
|
var appDefinition = (ApplicationDefinition)message.Definition;
|
||||||
|
|
||||||
|
if (message.Definition.Enable)
|
||||||
|
{
|
||||||
|
var app = _applicationsFactory.GetInstance(appDefinition);
|
||||||
|
|
||||||
|
app.SyncIndexers();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Handle(ProviderAddedEvent<IIndexer> message)
|
||||||
|
{
|
||||||
|
var enabledApps = _applicationsFactory.GetAvailableProviders();
|
||||||
|
|
||||||
|
// TODO: Only apps with Sync enabled
|
||||||
|
foreach (var app in enabledApps)
|
||||||
|
{
|
||||||
|
app.AddIndexer((IndexerDefinition)message.Definition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Handle(ProviderDeletedEvent<IIndexer> message)
|
||||||
|
{
|
||||||
|
var enabledApps = _applicationsFactory.GetAvailableProviders();
|
||||||
|
|
||||||
|
// TODO: Only remove indexers when Sync is Full
|
||||||
|
foreach (var app in enabledApps)
|
||||||
|
{
|
||||||
|
app.RemoveIndexer(message.ProviderId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Handle(ProviderUpdatedEvent<IIndexer> message)
|
||||||
|
{
|
||||||
|
var enabledApps = _applicationsFactory.GetAvailableProviders();
|
||||||
|
|
||||||
|
// TODO: Only upate indexers when Sync is Full
|
||||||
|
foreach (var app in enabledApps)
|
||||||
|
{
|
||||||
|
app.UpdateIndexer((IndexerDefinition)message.Definition);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
13
src/NzbDrone.Core/Applications/IApplication.cs
Normal file
13
src/NzbDrone.Core/Applications/IApplication.cs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
using NzbDrone.Core.Indexers;
|
||||||
|
using NzbDrone.Core.ThingiProvider;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Applications
|
||||||
|
{
|
||||||
|
public interface IApplication : IProvider
|
||||||
|
{
|
||||||
|
void SyncIndexers();
|
||||||
|
void AddIndexer(IndexerDefinition indexer);
|
||||||
|
void UpdateIndexer(IndexerDefinition indexer);
|
||||||
|
void RemoveIndexer(int indexerId);
|
||||||
|
}
|
||||||
|
}
|
@@ -1,8 +0,0 @@
|
|||||||
using NzbDrone.Core.ThingiProvider;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Applications
|
|
||||||
{
|
|
||||||
public interface IApplications : IProvider
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,6 +1,9 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using FluentValidation.Results;
|
using FluentValidation.Results;
|
||||||
|
using NLog;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
|
using NzbDrone.Core.Indexers;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Applications.Radarr
|
namespace NzbDrone.Core.Applications.Radarr
|
||||||
{
|
{
|
||||||
@@ -9,10 +12,13 @@ namespace NzbDrone.Core.Applications.Radarr
|
|||||||
public override string Name => "Radarr";
|
public override string Name => "Radarr";
|
||||||
|
|
||||||
private readonly IRadarrV3Proxy _radarrV3Proxy;
|
private readonly IRadarrV3Proxy _radarrV3Proxy;
|
||||||
|
private readonly IIndexerFactory _indexerFactory;
|
||||||
|
|
||||||
public Radarr(IRadarrV3Proxy radarrV3Proxy)
|
public Radarr(IRadarrV3Proxy radarrV3Proxy, IIndexerFactory indexerFactory, IAppIndexerMapService appIndexerMapService, Logger logger)
|
||||||
|
: base(appIndexerMapService, logger)
|
||||||
{
|
{
|
||||||
_radarrV3Proxy = radarrV3Proxy;
|
_radarrV3Proxy = radarrV3Proxy;
|
||||||
|
_indexerFactory = indexerFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override ValidationResult Test()
|
public override ValidationResult Test()
|
||||||
@@ -23,5 +29,85 @@ namespace NzbDrone.Core.Applications.Radarr
|
|||||||
|
|
||||||
return new ValidationResult(failures);
|
return new ValidationResult(failures);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void AddIndexer(IndexerDefinition indexer)
|
||||||
|
{
|
||||||
|
var schema = _radarrV3Proxy.GetIndexerSchema(Settings);
|
||||||
|
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);
|
||||||
|
_appIndexerMapService.Insert(new AppIndexerMap { AppId = Definition.Id, IndexerId = indexer.Id, RemoteIndexerId = remoteIndexer.Id });
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void RemoveIndexer(int indexerId)
|
||||||
|
{
|
||||||
|
//Use the Id mapping here to delete the correct indexer
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void UpdateIndexer(IndexerDefinition indexer)
|
||||||
|
{
|
||||||
|
//Use the Id mapping here to delete the correct indexer
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SyncIndexers()
|
||||||
|
{
|
||||||
|
// Pull Schema so we get the field mapping right
|
||||||
|
var schema = _radarrV3Proxy.GetIndexerSchema(Settings);
|
||||||
|
var newznab = schema.Where(i => i.Implementation == "Newznab").First();
|
||||||
|
var torznab = schema.Where(i => i.Implementation == "Torznab").First();
|
||||||
|
|
||||||
|
// Pull existing indexers from Radarr
|
||||||
|
var indexers = _radarrV3Proxy.GetIndexers(Settings);
|
||||||
|
|
||||||
|
//Pull all local indexers (TODO only those that support movie categories.)
|
||||||
|
var prowlarrIndexers = _indexerFactory.GetAvailableProviders();
|
||||||
|
|
||||||
|
//Pull mapping so we can check the mapping to see what already exists.
|
||||||
|
var indexerMappings = _appIndexerMapService.GetMappingsForApp(Definition.Id);
|
||||||
|
|
||||||
|
//Add new Indexers
|
||||||
|
foreach (var indexer in prowlarrIndexers)
|
||||||
|
{
|
||||||
|
//Don't add if it already exists in our mappings for this app (TODO should we check that it exists remote?)
|
||||||
|
if (indexerMappings.Any(x => x.IndexerId == indexer.Definition.Id))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var definition = (IndexerDefinition)indexer.Definition;
|
||||||
|
|
||||||
|
var radarrIndexer = BuildRadarrIndexer(definition, definition.Protocol == DownloadProtocol.Usenet ? newznab : torznab);
|
||||||
|
|
||||||
|
var remoteIndexer = _radarrV3Proxy.AddIndexer(radarrIndexer, Settings);
|
||||||
|
_appIndexerMapService.Insert(new AppIndexerMap { AppId = Definition.Id, IndexerId = definition.Id, RemoteIndexerId = remoteIndexer.Id });
|
||||||
|
}
|
||||||
|
|
||||||
|
//Delete Indexers that need Deleting.
|
||||||
|
}
|
||||||
|
|
||||||
|
private RadarrIndexer BuildRadarrIndexer(IndexerDefinition indexer, RadarrIndexer schema)
|
||||||
|
{
|
||||||
|
var radarrIndexer = new RadarrIndexer
|
||||||
|
{
|
||||||
|
Id = 0,
|
||||||
|
Name = $"{indexer.Name} (Prowlarr)",
|
||||||
|
EnableRss = indexer.EnableRss,
|
||||||
|
EnableAutomaticSearch = indexer.EnableAutomaticSearch,
|
||||||
|
EnableInteractiveSearch = indexer.EnableInteractiveSearch,
|
||||||
|
Priority = indexer.Priority,
|
||||||
|
Implementation = indexer.Protocol == DownloadProtocol.Usenet ? "Newznab" : "Torznab",
|
||||||
|
ConfigContract = schema.ConfigContract,
|
||||||
|
Fields = schema.Fields,
|
||||||
|
};
|
||||||
|
|
||||||
|
radarrIndexer.Fields.FirstOrDefault(x => x.Name == "baseUrl").Value = $"{Settings.ProwlarrUrl}/api/v1/indexer/1/newznab";
|
||||||
|
|
||||||
|
return radarrIndexer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
28
src/NzbDrone.Core/Applications/Radarr/RadarrField.cs
Normal file
28
src/NzbDrone.Core/Applications/Radarr/RadarrField.cs
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Applications.Radarr
|
||||||
|
{
|
||||||
|
public class RadarrField
|
||||||
|
{
|
||||||
|
public int Order { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
public string Label { get; set; }
|
||||||
|
public string Unit { get; set; }
|
||||||
|
public string HelpText { get; set; }
|
||||||
|
public string HelpLink { get; set; }
|
||||||
|
public object Value { get; set; }
|
||||||
|
public string Type { get; set; }
|
||||||
|
public bool Advanced { get; set; }
|
||||||
|
public string Section { get; set; }
|
||||||
|
public string Hidden { get; set; }
|
||||||
|
|
||||||
|
public RadarrField Clone()
|
||||||
|
{
|
||||||
|
return (RadarrField)MemberwiseClone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
20
src/NzbDrone.Core/Applications/Radarr/RadarrIndexer.cs
Normal file
20
src/NzbDrone.Core/Applications/Radarr/RadarrIndexer.cs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Applications.Radarr
|
||||||
|
{
|
||||||
|
public class RadarrIndexer
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public bool EnableRss { get; set; }
|
||||||
|
public bool EnableAutomaticSearch { get; set; }
|
||||||
|
public bool EnableInteractiveSearch { get; set; }
|
||||||
|
public int Priority { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
public string ImplementationName { get; set; }
|
||||||
|
public string Implementation { get; set; }
|
||||||
|
public string ConfigContract { get; set; }
|
||||||
|
public string InfoLink { get; set; }
|
||||||
|
public HashSet<int> Tags { get; set; }
|
||||||
|
public List<RadarrField> Fields { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@@ -10,6 +10,7 @@ namespace NzbDrone.Core.Applications.Radarr
|
|||||||
public RadarrSettingsValidator()
|
public RadarrSettingsValidator()
|
||||||
{
|
{
|
||||||
RuleFor(c => c.BaseUrl).IsValidUrl();
|
RuleFor(c => c.BaseUrl).IsValidUrl();
|
||||||
|
RuleFor(c => c.ProwlarrUrl).IsValidUrl();
|
||||||
RuleFor(c => c.ApiKey).NotEmpty();
|
RuleFor(c => c.ApiKey).NotEmpty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -20,12 +21,17 @@ namespace NzbDrone.Core.Applications.Radarr
|
|||||||
|
|
||||||
public RadarrSettings()
|
public RadarrSettings()
|
||||||
{
|
{
|
||||||
|
ProwlarrUrl = "http://localhost:9696";
|
||||||
|
BaseUrl = "http://localhost:7878";
|
||||||
}
|
}
|
||||||
|
|
||||||
[FieldDefinition(0, Label = "Radarr Server", HelpText = "Radarr server URL, including http(s):// and port if needed")]
|
[FieldDefinition(0, Label = "Prowlarr Server", HelpText = "Prowlarr server URL as Radarr sees it, including http(s):// and port if needed")]
|
||||||
|
public string ProwlarrUrl { get; set; }
|
||||||
|
|
||||||
|
[FieldDefinition(1, Label = "Radarr Server", HelpText = "Radarr server URL, including http(s):// and port if needed")]
|
||||||
public string BaseUrl { get; set; }
|
public string BaseUrl { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(1, Label = "ApiKey", Privacy = PrivacyLevel.ApiKey, HelpText = "The ApiKey generated by Radarr in Settings/General")]
|
[FieldDefinition(2, Label = "ApiKey", Privacy = PrivacyLevel.ApiKey, HelpText = "The ApiKey generated by Radarr in Settings/General")]
|
||||||
public string ApiKey { get; set; }
|
public string ApiKey { get; set; }
|
||||||
|
|
||||||
public NzbDroneValidationResult Validate()
|
public NzbDroneValidationResult Validate()
|
||||||
|
@@ -1,15 +1,19 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using FluentValidation.Results;
|
using FluentValidation.Results;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Extensions;
|
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
|
using NzbDrone.Common.Serializer;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Applications.Radarr
|
namespace NzbDrone.Core.Applications.Radarr
|
||||||
{
|
{
|
||||||
public interface IRadarrV3Proxy
|
public interface IRadarrV3Proxy
|
||||||
{
|
{
|
||||||
|
RadarrIndexer AddIndexer(RadarrIndexer indexer, RadarrSettings settings);
|
||||||
|
List<RadarrIndexer> GetIndexers(RadarrSettings settings);
|
||||||
|
List<RadarrIndexer> GetIndexerSchema(RadarrSettings settings);
|
||||||
ValidationFailure Test(RadarrSettings settings);
|
ValidationFailure Test(RadarrSettings settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,7 +30,35 @@ namespace NzbDrone.Core.Applications.Radarr
|
|||||||
|
|
||||||
public RadarrStatus GetStatus(RadarrSettings settings)
|
public RadarrStatus GetStatus(RadarrSettings settings)
|
||||||
{
|
{
|
||||||
return Execute<RadarrStatus>("/api/v3/system/status", settings);
|
var request = BuildRequest(settings, "/api/v3/system/status", HttpMethod.GET);
|
||||||
|
return Execute<RadarrStatus>(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<RadarrIndexer> GetIndexers(RadarrSettings settings)
|
||||||
|
{
|
||||||
|
var request = BuildRequest(settings, "/api/v3/indexer", HttpMethod.GET);
|
||||||
|
return Execute<List<RadarrIndexer>>(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveIndexer(int indexerId, RadarrSettings settings)
|
||||||
|
{
|
||||||
|
var request = BuildRequest(settings, $"/api/v3/indexer/{indexerId}", HttpMethod.DELETE);
|
||||||
|
var response = _httpClient.Execute(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<RadarrIndexer> GetIndexerSchema(RadarrSettings settings)
|
||||||
|
{
|
||||||
|
var request = BuildRequest(settings, "/api/v3/indexer/schema", HttpMethod.GET);
|
||||||
|
return Execute<List<RadarrIndexer>>(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RadarrIndexer AddIndexer(RadarrIndexer indexer, RadarrSettings settings)
|
||||||
|
{
|
||||||
|
var request = BuildRequest(settings, "/api/v3/indexer", HttpMethod.POST);
|
||||||
|
|
||||||
|
request.SetContent(indexer.ToJson());
|
||||||
|
|
||||||
|
return Execute<RadarrIndexer>(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ValidationFailure Test(RadarrSettings settings)
|
public ValidationFailure Test(RadarrSettings settings)
|
||||||
@@ -55,20 +87,25 @@ namespace NzbDrone.Core.Applications.Radarr
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private TResource Execute<TResource>(string resource, RadarrSettings settings)
|
private HttpRequest BuildRequest(RadarrSettings settings, string resource, HttpMethod method)
|
||||||
where TResource : new()
|
|
||||||
{
|
{
|
||||||
if (settings.BaseUrl.IsNullOrWhiteSpace() || settings.ApiKey.IsNullOrWhiteSpace())
|
|
||||||
{
|
|
||||||
return new TResource();
|
|
||||||
}
|
|
||||||
|
|
||||||
var baseUrl = settings.BaseUrl.TrimEnd('/');
|
var baseUrl = settings.BaseUrl.TrimEnd('/');
|
||||||
|
|
||||||
var request = new HttpRequestBuilder(baseUrl).Resource(resource).Accept(HttpAccept.Json)
|
var request = new HttpRequestBuilder(baseUrl).Resource(resource)
|
||||||
.SetHeader("X-Api-Key", settings.ApiKey).Build();
|
.SetHeader("X-Api-Key", settings.ApiKey)
|
||||||
|
.Build();
|
||||||
|
|
||||||
var response = _httpClient.Get(request);
|
request.Headers.ContentType = "application/json";
|
||||||
|
|
||||||
|
request.Method = method;
|
||||||
|
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
|
||||||
|
private TResource Execute<TResource>(HttpRequest request)
|
||||||
|
where TResource : new()
|
||||||
|
{
|
||||||
|
var response = _httpClient.Execute(request);
|
||||||
|
|
||||||
var results = JsonConvert.DeserializeObject<TResource>(response.Content);
|
var results = JsonConvert.DeserializeObject<TResource>(response.Content);
|
||||||
|
|
||||||
|
@@ -48,6 +48,11 @@ namespace NzbDrone.Core.Datastore.Migration
|
|||||||
.WithColumn("Priority").AsInt32().NotNullable().WithDefaultValue(25)
|
.WithColumn("Priority").AsInt32().NotNullable().WithDefaultValue(25)
|
||||||
.WithColumn("Added").AsDateTime();
|
.WithColumn("Added").AsDateTime();
|
||||||
|
|
||||||
|
Create.TableForModel("ApplicationIndexerMapping")
|
||||||
|
.WithColumn("IndexerId").AsInt32()
|
||||||
|
.WithColumn("AppId").AsInt32()
|
||||||
|
.WithColumn("RemoteIndexerId").AsInt32();
|
||||||
|
|
||||||
Create.TableForModel("Applications")
|
Create.TableForModel("Applications")
|
||||||
.WithColumn("Name").AsString().Unique()
|
.WithColumn("Name").AsString().Unique()
|
||||||
.WithColumn("Implementation").AsString()
|
.WithColumn("Implementation").AsString()
|
||||||
|
@@ -61,6 +61,8 @@ namespace NzbDrone.Core.Datastore
|
|||||||
|
|
||||||
Mapper.Entity<Tag>("Tags").RegisterModel();
|
Mapper.Entity<Tag>("Tags").RegisterModel();
|
||||||
|
|
||||||
|
Mapper.Entity<AppIndexerMap>("ApplicationIndexerMapping").RegisterModel();
|
||||||
|
|
||||||
Mapper.Entity<User>("Users").RegisterModel();
|
Mapper.Entity<User>("Users").RegisterModel();
|
||||||
Mapper.Entity<CommandModel>("Commands").RegisterModel()
|
Mapper.Entity<CommandModel>("Commands").RegisterModel()
|
||||||
.Ignore(c => c.Message);
|
.Ignore(c => c.Message);
|
||||||
|
@@ -2,7 +2,7 @@ using NzbDrone.Core.Applications;
|
|||||||
|
|
||||||
namespace Prowlarr.Api.V1.Application
|
namespace Prowlarr.Api.V1.Application
|
||||||
{
|
{
|
||||||
public class ApplicationModule : ProviderModuleBase<ApplicationResource, IApplications, ApplicationDefinition>
|
public class ApplicationModule : ProviderModuleBase<ApplicationResource, IApplication, ApplicationDefinition>
|
||||||
{
|
{
|
||||||
public static readonly ApplicationResourceMapper ResourceMapper = new ApplicationResourceMapper();
|
public static readonly ApplicationResourceMapper ResourceMapper = new ApplicationResourceMapper();
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user