Added: Custom Class for Radarr API requests. Also implements new error handling present on staging server.

This commit is contained in:
Leonardo Galli 2017-06-06 19:50:53 +02:00
parent f1873a9684
commit 7bbebe53a3
4 changed files with 176 additions and 45 deletions

View File

@ -0,0 +1,98 @@
using NzbDrone.Common.Http;
using NzbDrone.Core.Configuration;
using System;
using Newtonsoft.Json;
using System.Collections.Generic;
using NzbDrone.Core.MetadataSource.SkyHook.Resource;
namespace NzbDrone.Core.MetadataSource.RadarrAPI
{
public interface IRadarrAPIClient
{
IHttpRequestBuilderFactory RadarrAPI { get; }
List<MovieResult> DiscoverMovies(string action, Func<HttpRequest, HttpRequest> enhanceRequest);
}
public class RadarrAPIClient : IRadarrAPIClient
{
private readonly IHttpClient _httpClient;
public RadarrAPIClient(IConfigFileProvider configFile, IHttpClient httpClient)
{
_httpClient = httpClient;
if (configFile.Branch == "nightly")
{
RadarrAPI = new HttpRequestBuilder("https://staging.api.radarr.video/{route}/{action}")
.CreateFactory();
}
else
{
RadarrAPI = new HttpRequestBuilder("https://api.radarr.video/v2/{route}/{action}")
.CreateFactory();
}
}
private HttpResponse Execute(HttpRequest request)
{
if (request.Method == HttpMethod.GET)
{
return _httpClient.Get(request);
}
else if (request.Method == HttpMethod.POST)
{
return _httpClient.Post(request);
}
else
{
throw new NotImplementedException($"Method {request.Method} not implemented");
}
}
private T Execute<T>(HttpRequest request)
{
request.AllowAutoRedirect = true;
request.Headers.Accept = HttpAccept.Json.Value;
request.SuppressHttpError = true;
var response = Execute(request);
try
{
var error = JsonConvert.DeserializeObject<RadarrError>(response.Content);
if (error != null && error.Errors.Count != 0)
{
throw new RadarrAPIException(error);
}
}
catch (JsonSerializationException)
{
//No error!
}
if (response.StatusCode != System.Net.HttpStatusCode.OK)
{
throw new HttpException(request, response);
}
return JsonConvert.DeserializeObject<T>(response.Content);
}
public List<MovieResult> DiscoverMovies(string action, Func<HttpRequest, HttpRequest> enhanceRequest = null )
{
var request = RadarrAPI.Create().SetSegment("route", "discovery").SetSegment("action", action).Build();
if (enhanceRequest != null)
{
request = enhanceRequest(request);
}
return Execute<List<MovieResult>>(request);
}
public IHttpRequestBuilderFactory RadarrAPI { get; private set; }
}
}

View File

@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
namespace NzbDrone.Core.MetadataSource.RadarrAPI
{
public class Error
{
[JsonProperty("id")]
public string RayId { get; set; }
[JsonProperty("status")]
public int Status { get; set; }
[JsonProperty("title")]
public string Title { get; set; }
[JsonProperty("detail")]
public string Detail { get; set; }
}
public class RadarrError
{
[JsonProperty("errors")]
public IList<Error> Errors { get; set; }
}
public class RadarrAPIException : Exception
{
RadarrError APIErrors;
public RadarrAPIException(RadarrError apiError) : base(HumanReadable(apiError))
{
}
private static string HumanReadable(RadarrError APIErrors)
{
var firstError = APIErrors.Errors.First();
var details = string.Join("\n", APIErrors.Errors.Select(error =>
{
return $"{error.Title} ({error.Status}, RayId: {error.RayId}), Details: {error.Detail}";
}));
return $"Error while calling api: {firstError.Title}\nFull error(s): {details}";
}
}
}

View File

@ -17,6 +17,8 @@ using NzbDrone.Core.Parser;
using NzbDrone.Core.Profiles; using NzbDrone.Core.Profiles;
using NzbDrone.Common.Serializer; using NzbDrone.Common.Serializer;
using NzbDrone.Core.NetImport.ImportExclusions; using NzbDrone.Core.NetImport.ImportExclusions;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.MetadataSource.RadarrAPI;
namespace NzbDrone.Core.MetadataSource.SkyHook namespace NzbDrone.Core.MetadataSource.SkyHook
{ {
@ -31,9 +33,12 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
private readonly IMovieService _movieService; private readonly IMovieService _movieService;
private readonly IPreDBService _predbService; private readonly IPreDBService _predbService;
private readonly IImportExclusionsService _exclusionService; private readonly IImportExclusionsService _exclusionService;
private readonly IRadarrAPIClient _radarrAPI;
private readonly IHttpRequestBuilderFactory _apiBuilder;
public SkyHookProxy(IHttpClient httpClient, ISonarrCloudRequestBuilder requestBuilder, ITmdbConfigService configService, IMovieService movieService, public SkyHookProxy(IHttpClient httpClient, ISonarrCloudRequestBuilder requestBuilder, ITmdbConfigService configService, IMovieService movieService,
IPreDBService predbService, IImportExclusionsService exclusionService, Logger logger) IPreDBService predbService, IImportExclusionsService exclusionService, IRadarrAPIClient radarrAPI, Logger logger)
{ {
_httpClient = httpClient; _httpClient = httpClient;
_requestBuilder = requestBuilder.SkyHookTvdb; _requestBuilder = requestBuilder.SkyHookTvdb;
@ -42,6 +47,8 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
_movieService = movieService; _movieService = movieService;
_predbService = predbService; _predbService = predbService;
_exclusionService = exclusionService; _exclusionService = exclusionService;
_radarrAPI = radarrAPI;
_logger = logger; _logger = logger;
} }
@ -362,53 +369,29 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
string allIds = string.Join(",", allMovies.Select(m => m.TmdbId)); string allIds = string.Join(",", allMovies.Select(m => m.TmdbId));
string ignoredIds = string.Join(",", allExclusions.Select(ex => ex.TmdbId)); string ignoredIds = string.Join(",", allExclusions.Select(ex => ex.TmdbId));
HttpRequest request; List<MovieResult> results = new List<MovieResult>();
List<MovieResult> results;
/*if (action == "upcoming") try
{ {
var lastWeek = DateTime.Now.AddDays(-7); results = _radarrAPI.DiscoverMovies(action, (request) =>
var threeWeeks = DateTime.Now.AddDays(7 * 3);
request = _movieBuilder.Create().SetSegment("route", "discover")
.SetSegment("id", "movie")
.SetSegment("secondaryRoute", "")
.AddQueryParam("region", "us")
.AddQueryParam("with_release_type", "5|4|6")
.AddQueryParam("release_date.gte", lastWeek.ToString("yyyy-MM-dd"))
.AddQueryParam("sort_by", "popularity.desc")
.AddQueryParam("release_date.lte", threeWeeks.ToString("yyyy-MM-dd")).Build();
var response = _httpClient.Get<MovieSearchRoot>(request);
if (response.StatusCode != HttpStatusCode.OK)
{ {
throw new HttpException(request, response); request.AllowAutoRedirect = true;
} request.Method = HttpMethod.POST;
request.Headers.ContentType = "application/x-www-form-urlencoded";
request.SetContent($"tmdbIds={allIds}&ignoredIds={ignoredIds}");
return request;
});
results = response.Resource.results.ToList(); results = results.Where(m => allMovies.None(mo => mo.TmdbId == m.id) && allExclusions.None(ex => ex.TmdbId == m.id)).ToList();
}
catch (RadarrAPIException exception)
{
_logger.Error(exception, "Failed to discover movies for action {0}!", action);
}
catch (Exception exception)
{
_logger.Error(exception, "Failed to discover movies for action {0}!", action);
} }
else
{*/
request = new HttpRequestBuilder("https://api.radarr.video/{action}/").SetSegment("action", action).Build();
request.AllowAutoRedirect = true;
request.Method = HttpMethod.POST;
request.Headers.ContentType = "application/x-www-form-urlencoded";
request.SetContent($"tmdbids={allIds}&ignoredIds={ignoredIds}");
var response = _httpClient.Post<List<MovieResult>>(request);
if (response.StatusCode != HttpStatusCode.OK)
{
throw new HttpException(request, response);
}
results = response.Resource;
//}
results = results.Where(m => allMovies.None(mo => mo.TmdbId == m.id) && allExclusions.None(ex => ex.TmdbId == m.id)).ToList();
return results.SelectList(MapMovie); return results.SelectList(MapMovie);
} }
@ -499,7 +482,7 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
_logger.Warn("Cleaned response: " + responseCleaned); _logger.Warn("Cleaned response: " + responseCleaned);
ImdbResource json = JsonConvert.DeserializeObject<ImdbResource>(responseCleaned); ImdbResource json =Json Convert.DeserializeObject<ImdbResource>(responseCleaned);
_logger.Warn("Json object: " + json); _logger.Warn("Json object: " + json);

View File

@ -1285,6 +1285,8 @@
<Compile Include="NetImport\ImportExclusions\ImportExclusionsRepository.cs" /> <Compile Include="NetImport\ImportExclusions\ImportExclusionsRepository.cs" />
<Compile Include="NetImport\ImportExclusions\ImportExclusionsService.cs" /> <Compile Include="NetImport\ImportExclusions\ImportExclusionsService.cs" />
<Compile Include="Datastore\Migration\138_add_physical_release_note.cs" /> <Compile Include="Datastore\Migration\138_add_physical_release_note.cs" />
<Compile Include="MetadataSource\RadarrAPI\RadarrResources.cs" />
<Compile Include="MetadataSource\RadarrAPI\RadarrAPIClient.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<BootstrapperPackage Include=".NETFramework,Version=v4.0,Profile=Client"> <BootstrapperPackage Include=".NETFramework,Version=v4.0,Profile=Client">
@ -1356,6 +1358,7 @@
<ItemGroup /> <ItemGroup />
<ItemGroup> <ItemGroup>
<Folder Include="NetImport\ImportExclusions\" /> <Folder Include="NetImport\ImportExclusions\" />
<Folder Include="MetadataSource\RadarrAPI\" />
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup> <PropertyGroup>