mirror of
https://github.com/Prowlarr/Prowlarr.git
synced 2026-04-18 21:55:12 -04:00
New: Import from Another Radarr Instance
Co-Authored-By: Leonardo Galli <galli-leo@users.noreply.github.com>
This commit is contained in:
@@ -51,7 +51,7 @@ namespace NzbDrone.Core.NetImport
|
|||||||
|
|
||||||
public List<INetImport> Discoverable()
|
public List<INetImport> Discoverable()
|
||||||
{
|
{
|
||||||
var enabledImporters = GetAvailableProviders().Where(n => (n.GetType() == typeof(Radarr.RadarrLists) || n.GetType() == typeof(TMDb.Popular.TMDbPopularImport)));
|
var enabledImporters = GetAvailableProviders().Where(n => (n.GetType() == typeof(RadarrList.RadarrListImport) || n.GetType() == typeof(TMDb.Popular.TMDbPopularImport)));
|
||||||
var indexers = FilterBlockedIndexers(enabledImporters);
|
var indexers = FilterBlockedIndexers(enabledImporters);
|
||||||
return indexers.ToList();
|
return indexers.ToList();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.NetImport.Radarr
|
||||||
|
{
|
||||||
|
public class RadarrMovie
|
||||||
|
{
|
||||||
|
public string Title { get; set; }
|
||||||
|
public string SortTitle { get; set; }
|
||||||
|
public int TmdbId { get; set; }
|
||||||
|
public string Overview { get; set; }
|
||||||
|
public List<MediaCover.MediaCover> Images { get; set; }
|
||||||
|
public bool Monitored { get; set; }
|
||||||
|
public DateTime InCinemas { get; set; }
|
||||||
|
public DateTime PhysicalRelease { get; set; }
|
||||||
|
public int Year { get; set; }
|
||||||
|
public string TitleSlug { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
using NLog;
|
||||||
|
using NzbDrone.Common.Http;
|
||||||
|
using NzbDrone.Core.Configuration;
|
||||||
|
using NzbDrone.Core.Parser;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.NetImport.Radarr
|
||||||
|
{
|
||||||
|
public class RadarrImport : HttpNetImportBase<RadarrSettings>
|
||||||
|
{
|
||||||
|
public override string Name => "Radarr";
|
||||||
|
public override bool Enabled => true;
|
||||||
|
public override bool EnableAuto => false;
|
||||||
|
|
||||||
|
public override NetImportType ListType => NetImportType.Other;
|
||||||
|
|
||||||
|
public RadarrImport(IHttpClient httpClient,
|
||||||
|
IConfigService configService,
|
||||||
|
IParsingService parsingService,
|
||||||
|
Logger logger)
|
||||||
|
: base(httpClient, configService, parsingService, logger)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override INetImportRequestGenerator GetRequestGenerator()
|
||||||
|
{
|
||||||
|
return new RadarrRequestGenerator()
|
||||||
|
{
|
||||||
|
Settings = Settings,
|
||||||
|
Logger = _logger,
|
||||||
|
HttpClient = _httpClient
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IParseNetImportResponse GetParser()
|
||||||
|
{
|
||||||
|
return new RadarrParser(Settings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,69 +1,53 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Newtonsoft.Json;
|
using System.Linq;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Serializer;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Core.Movies;
|
||||||
using NzbDrone.Core.MetadataSource;
|
|
||||||
using NzbDrone.Core.MetadataSource.RadarrAPI;
|
|
||||||
using NzbDrone.Core.MetadataSource.SkyHook.Resource;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.NetImport.Radarr
|
namespace NzbDrone.Core.NetImport.Radarr
|
||||||
{
|
{
|
||||||
public class RadarrParser : IParseNetImportResponse
|
public class RadarrParser : IParseNetImportResponse
|
||||||
{
|
{
|
||||||
private readonly RadarrSettings _settings;
|
private readonly RadarrSettings _settings;
|
||||||
private readonly ISearchForNewMovie _skyhookProxy;
|
public RadarrParser(RadarrSettings settings)
|
||||||
private NetImportResponse _importResponse;
|
|
||||||
|
|
||||||
public RadarrParser(RadarrSettings settings, ISearchForNewMovie skyhookProxy)
|
|
||||||
{
|
{
|
||||||
_skyhookProxy = skyhookProxy;
|
|
||||||
_settings = settings;
|
_settings = settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IList<Movies.Movie> ParseResponse(NetImportResponse importResponse)
|
public IList<Movie> ParseResponse(NetImportResponse netMovieImporterResponse)
|
||||||
{
|
{
|
||||||
_importResponse = importResponse;
|
var remoteMovies = Json.Deserialize<List<RadarrMovie>>(netMovieImporterResponse.Content);
|
||||||
|
|
||||||
var movies = new List<Movies.Movie>();
|
var movies = new List<Movie>();
|
||||||
|
|
||||||
if (!PreProcess(_importResponse))
|
foreach (var remoteMovie in remoteMovies)
|
||||||
{
|
{
|
||||||
return movies;
|
movies.Add(new Movie
|
||||||
|
{
|
||||||
|
TmdbId = remoteMovie.TmdbId,
|
||||||
|
Title = remoteMovie.Title,
|
||||||
|
SortTitle = remoteMovie.SortTitle,
|
||||||
|
TitleSlug = remoteMovie.TitleSlug,
|
||||||
|
Overview = remoteMovie.Overview,
|
||||||
|
Images = remoteMovie.Images.Select(x => MapImage(x, _settings.BaseUrl)).ToList(),
|
||||||
|
Monitored = remoteMovie.Monitored,
|
||||||
|
PhysicalRelease = remoteMovie.PhysicalRelease,
|
||||||
|
InCinemas = remoteMovie.InCinemas,
|
||||||
|
Year = remoteMovie.Year
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var jsonResponse = JsonConvert.DeserializeObject<List<MovieResult>>(_importResponse.Content);
|
return movies;
|
||||||
|
|
||||||
// no movies were return
|
|
||||||
if (jsonResponse == null)
|
|
||||||
{
|
|
||||||
return movies;
|
|
||||||
}
|
|
||||||
|
|
||||||
return jsonResponse.SelectList(_skyhookProxy.MapMovie);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual bool PreProcess(NetImportResponse netImportResponse)
|
private static MediaCover.MediaCover MapImage(MediaCover.MediaCover arg, string baseUrl)
|
||||||
{
|
{
|
||||||
try
|
var newImage = new MediaCover.MediaCover
|
||||||
{
|
{
|
||||||
var error = JsonConvert.DeserializeObject<RadarrError>(netImportResponse.HttpResponse.Content);
|
Url = string.Format("{0}{1}", baseUrl, arg.Url),
|
||||||
|
CoverType = arg.CoverType
|
||||||
|
};
|
||||||
|
|
||||||
if (error != null && error.Errors != null && error.Errors.Count != 0)
|
return newImage;
|
||||||
{
|
|
||||||
throw new RadarrAPIException(error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (JsonSerializationException)
|
|
||||||
{
|
|
||||||
//No error!
|
|
||||||
}
|
|
||||||
|
|
||||||
if (netImportResponse.HttpResponse.StatusCode != System.Net.HttpStatusCode.OK)
|
|
||||||
{
|
|
||||||
throw new HttpException(netImportResponse.HttpRequest, netImportResponse.HttpResponse);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Extensions;
|
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
|
|
||||||
namespace NzbDrone.Core.NetImport.Radarr
|
namespace NzbDrone.Core.NetImport.Radarr
|
||||||
@@ -12,24 +10,24 @@ namespace NzbDrone.Core.NetImport.Radarr
|
|||||||
public IHttpClient HttpClient { get; set; }
|
public IHttpClient HttpClient { get; set; }
|
||||||
public Logger Logger { get; set; }
|
public Logger Logger { get; set; }
|
||||||
|
|
||||||
public int MaxPages { get; set; }
|
|
||||||
|
|
||||||
public RadarrRequestGenerator()
|
public RadarrRequestGenerator()
|
||||||
{
|
{
|
||||||
MaxPages = 3;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual NetImportPageableRequestChain GetMovies()
|
public virtual NetImportPageableRequestChain GetMovies()
|
||||||
{
|
{
|
||||||
var pageableRequests = new NetImportPageableRequestChain();
|
var pageableRequests = new NetImportPageableRequestChain();
|
||||||
|
|
||||||
var baseUrl = $"{Settings.APIURL.TrimEnd("/")}";
|
var baseUrl = Settings.BaseUrl.TrimEnd('/');
|
||||||
|
|
||||||
var request = new NetImportRequest($"{baseUrl}{Settings.Path}", HttpAccept.Json);
|
var request = new NetImportRequest($"{baseUrl}/api/v3/movie", HttpAccept.Json);
|
||||||
|
|
||||||
|
request.HttpRequest.Headers["X-Api-Key"] = Settings.ApiKey;
|
||||||
|
|
||||||
request.HttpRequest.SuppressHttpError = true;
|
request.HttpRequest.SuppressHttpError = true;
|
||||||
|
|
||||||
pageableRequests.Add(new List<NetImportRequest> { request });
|
pageableRequests.Add(new List<NetImportRequest> { request });
|
||||||
|
|
||||||
return pageableRequests;
|
return pageableRequests;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ namespace NzbDrone.Core.NetImport.Radarr
|
|||||||
{
|
{
|
||||||
public RadarrSettingsValidator()
|
public RadarrSettingsValidator()
|
||||||
{
|
{
|
||||||
RuleFor(c => c.APIURL).ValidRootUrl();
|
RuleFor(c => c.BaseUrl).ValidRootUrl();
|
||||||
|
RuleFor(c => c.ApiKey).NotEmpty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -19,15 +20,15 @@ namespace NzbDrone.Core.NetImport.Radarr
|
|||||||
|
|
||||||
public RadarrSettings()
|
public RadarrSettings()
|
||||||
{
|
{
|
||||||
APIURL = "https://api.radarr.video/v2";
|
BaseUrl = "";
|
||||||
Path = "";
|
ApiKey = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
[FieldDefinition(0, Label = "Radarr API URL", HelpText = "Link to to Radarr API URL. Use https://staging.api.radarr.video if you are on nightly.")]
|
[FieldDefinition(0, Label = "Full URL", HelpText = "URL, including port, of the Radarr V3 instance to import from")]
|
||||||
public string APIURL { get; set; }
|
public string BaseUrl { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(1, Label = "Path to list", HelpText = "Path to the list proxied by the Radarr API. Check the wiki for available lists.")]
|
[FieldDefinition(1, Label = "API Key", HelpText = "Apikey of the Radarr V3 instance to import from")]
|
||||||
public string Path { get; set; }
|
public string ApiKey { get; set; }
|
||||||
|
|
||||||
public NzbDroneValidationResult Validate()
|
public NzbDroneValidationResult Validate()
|
||||||
{
|
{
|
||||||
|
|||||||
+10
-10
@@ -6,19 +6,19 @@ using NzbDrone.Core.MetadataSource;
|
|||||||
using NzbDrone.Core.Parser;
|
using NzbDrone.Core.Parser;
|
||||||
using NzbDrone.Core.ThingiProvider;
|
using NzbDrone.Core.ThingiProvider;
|
||||||
|
|
||||||
namespace NzbDrone.Core.NetImport.Radarr
|
namespace NzbDrone.Core.NetImport.RadarrList
|
||||||
{
|
{
|
||||||
public class RadarrLists : HttpNetImportBase<RadarrSettings>
|
public class RadarrListImport : HttpNetImportBase<RadarrListSettings>
|
||||||
{
|
{
|
||||||
|
private readonly ISearchForNewMovie _skyhookProxy;
|
||||||
|
|
||||||
public override string Name => "Radarr Lists";
|
public override string Name => "Radarr Lists";
|
||||||
|
|
||||||
public override NetImportType ListType => NetImportType.Other;
|
public override NetImportType ListType => NetImportType.Other;
|
||||||
public override bool Enabled => true;
|
public override bool Enabled => true;
|
||||||
public override bool EnableAuto => false;
|
public override bool EnableAuto => false;
|
||||||
|
|
||||||
private readonly ISearchForNewMovie _skyhookProxy;
|
public RadarrListImport(IHttpClient httpClient,
|
||||||
|
|
||||||
public RadarrLists(IHttpClient httpClient,
|
|
||||||
IConfigService configService,
|
IConfigService configService,
|
||||||
IParsingService parsingService,
|
IParsingService parsingService,
|
||||||
ISearchForNewMovie skyhookProxy,
|
ISearchForNewMovie skyhookProxy,
|
||||||
@@ -44,7 +44,7 @@ namespace NzbDrone.Core.NetImport.Radarr
|
|||||||
EnableAuto = true,
|
EnableAuto = true,
|
||||||
ProfileId = 1,
|
ProfileId = 1,
|
||||||
Implementation = GetType().Name,
|
Implementation = GetType().Name,
|
||||||
Settings = new RadarrSettings { Path = "/imdb/top250" },
|
Settings = new RadarrListSettings { Path = "/imdb/top250" },
|
||||||
};
|
};
|
||||||
yield return new NetImportDefinition
|
yield return new NetImportDefinition
|
||||||
{
|
{
|
||||||
@@ -53,7 +53,7 @@ namespace NzbDrone.Core.NetImport.Radarr
|
|||||||
EnableAuto = true,
|
EnableAuto = true,
|
||||||
ProfileId = 1,
|
ProfileId = 1,
|
||||||
Implementation = GetType().Name,
|
Implementation = GetType().Name,
|
||||||
Settings = new RadarrSettings { Path = "/imdb/popular" },
|
Settings = new RadarrListSettings { Path = "/imdb/popular" },
|
||||||
};
|
};
|
||||||
yield return new NetImportDefinition
|
yield return new NetImportDefinition
|
||||||
{
|
{
|
||||||
@@ -62,14 +62,14 @@ namespace NzbDrone.Core.NetImport.Radarr
|
|||||||
EnableAuto = true,
|
EnableAuto = true,
|
||||||
ProfileId = 1,
|
ProfileId = 1,
|
||||||
Implementation = GetType().Name,
|
Implementation = GetType().Name,
|
||||||
Settings = new RadarrSettings { Path = "/imdb/list?listId=LISTID" },
|
Settings = new RadarrListSettings { Path = "/imdb/list?listId=LISTID" },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override INetImportRequestGenerator GetRequestGenerator()
|
public override INetImportRequestGenerator GetRequestGenerator()
|
||||||
{
|
{
|
||||||
return new RadarrRequestGenerator()
|
return new RadarrListRequestGenerator()
|
||||||
{
|
{
|
||||||
Settings = Settings,
|
Settings = Settings,
|
||||||
Logger = _logger,
|
Logger = _logger,
|
||||||
@@ -79,7 +79,7 @@ namespace NzbDrone.Core.NetImport.Radarr
|
|||||||
|
|
||||||
public override IParseNetImportResponse GetParser()
|
public override IParseNetImportResponse GetParser()
|
||||||
{
|
{
|
||||||
return new RadarrParser(Settings, _skyhookProxy);
|
return new RadarrListParser(_skyhookProxy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using NzbDrone.Common.Extensions;
|
||||||
|
using NzbDrone.Common.Http;
|
||||||
|
using NzbDrone.Core.MetadataSource;
|
||||||
|
using NzbDrone.Core.MetadataSource.RadarrAPI;
|
||||||
|
using NzbDrone.Core.MetadataSource.SkyHook.Resource;
|
||||||
|
using NzbDrone.Core.Movies;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.NetImport.RadarrList
|
||||||
|
{
|
||||||
|
public class RadarrListParser : IParseNetImportResponse
|
||||||
|
{
|
||||||
|
private readonly ISearchForNewMovie _skyhookProxy;
|
||||||
|
|
||||||
|
public RadarrListParser(ISearchForNewMovie skyhookProxy)
|
||||||
|
{
|
||||||
|
_skyhookProxy = skyhookProxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IList<Movie> ParseResponse(NetImportResponse netMovieImporterResponse)
|
||||||
|
{
|
||||||
|
var importResponse = netMovieImporterResponse;
|
||||||
|
|
||||||
|
var movies = new List<Movie>();
|
||||||
|
|
||||||
|
if (!PreProcess(importResponse))
|
||||||
|
{
|
||||||
|
return movies;
|
||||||
|
}
|
||||||
|
|
||||||
|
var jsonResponse = JsonConvert.DeserializeObject<List<MovieResult>>(importResponse.Content);
|
||||||
|
|
||||||
|
// no movies were return
|
||||||
|
if (jsonResponse == null)
|
||||||
|
{
|
||||||
|
return movies;
|
||||||
|
}
|
||||||
|
|
||||||
|
return jsonResponse.SelectList(_skyhookProxy.MapMovie);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual bool PreProcess(NetImportResponse netImportResponse)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var error = JsonConvert.DeserializeObject<RadarrError>(netImportResponse.HttpResponse.Content);
|
||||||
|
|
||||||
|
if (error != null && error.Errors != null && error.Errors.Count != 0)
|
||||||
|
{
|
||||||
|
throw new RadarrAPIException(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (JsonSerializationException)
|
||||||
|
{
|
||||||
|
//No error!
|
||||||
|
}
|
||||||
|
|
||||||
|
if (netImportResponse.HttpResponse.StatusCode != System.Net.HttpStatusCode.OK)
|
||||||
|
{
|
||||||
|
throw new HttpException(netImportResponse.HttpRequest, netImportResponse.HttpResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using NLog;
|
||||||
|
using NzbDrone.Common.Extensions;
|
||||||
|
using NzbDrone.Common.Http;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.NetImport.RadarrList
|
||||||
|
{
|
||||||
|
public class RadarrListRequestGenerator : INetImportRequestGenerator
|
||||||
|
{
|
||||||
|
public RadarrListSettings Settings { get; set; }
|
||||||
|
public IHttpClient HttpClient { get; set; }
|
||||||
|
public Logger Logger { get; set; }
|
||||||
|
|
||||||
|
public int MaxPages { get; set; }
|
||||||
|
|
||||||
|
public RadarrListRequestGenerator()
|
||||||
|
{
|
||||||
|
MaxPages = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual NetImportPageableRequestChain GetMovies()
|
||||||
|
{
|
||||||
|
var pageableRequests = new NetImportPageableRequestChain();
|
||||||
|
|
||||||
|
var baseUrl = $"{Settings.APIURL.TrimEnd("/")}";
|
||||||
|
|
||||||
|
var request = new NetImportRequest($"{baseUrl}{Settings.Path}", HttpAccept.Json);
|
||||||
|
|
||||||
|
request.HttpRequest.SuppressHttpError = true;
|
||||||
|
|
||||||
|
pageableRequests.Add(new List<NetImportRequest> { request });
|
||||||
|
return pageableRequests;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
using FluentValidation;
|
||||||
|
using NzbDrone.Core.Annotations;
|
||||||
|
using NzbDrone.Core.ThingiProvider;
|
||||||
|
using NzbDrone.Core.Validation;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.NetImport.RadarrList
|
||||||
|
{
|
||||||
|
public class RadarrSettingsValidator : AbstractValidator<RadarrListSettings>
|
||||||
|
{
|
||||||
|
public RadarrSettingsValidator()
|
||||||
|
{
|
||||||
|
RuleFor(c => c.APIURL).ValidRootUrl();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RadarrListSettings : IProviderConfig
|
||||||
|
{
|
||||||
|
private static readonly RadarrSettingsValidator Validator = new RadarrSettingsValidator();
|
||||||
|
|
||||||
|
public RadarrListSettings()
|
||||||
|
{
|
||||||
|
APIURL = "https://api.radarr.video/v2";
|
||||||
|
Path = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
[FieldDefinition(0, Label = "Radarr API URL", HelpText = "Link to to Radarr API URL. Use https://staging.api.radarr.video if you are on nightly.")]
|
||||||
|
public string APIURL { get; set; }
|
||||||
|
|
||||||
|
[FieldDefinition(1, Label = "Path to list", HelpText = "Path to the list proxied by the Radarr API. Check the wiki for available lists.")]
|
||||||
|
public string Path { get; set; }
|
||||||
|
|
||||||
|
public NzbDroneValidationResult Validate()
|
||||||
|
{
|
||||||
|
return new NzbDroneValidationResult(Validator.Validate(this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user