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.Common.Serializer;
using NzbDrone.Core.NetImport.ImportExclusions;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.MetadataSource.RadarrAPI;
namespace NzbDrone.Core.MetadataSource.SkyHook
{
@ -31,9 +33,12 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
private readonly IMovieService _movieService;
private readonly IPreDBService _predbService;
private readonly IImportExclusionsService _exclusionService;
private readonly IRadarrAPIClient _radarrAPI;
private readonly IHttpRequestBuilderFactory _apiBuilder;
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;
_requestBuilder = requestBuilder.SkyHookTvdb;
@ -42,6 +47,8 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
_movieService = movieService;
_predbService = predbService;
_exclusionService = exclusionService;
_radarrAPI = radarrAPI;
_logger = logger;
}
@ -362,55 +369,31 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
string allIds = string.Join(",", allMovies.Select(m => m.TmdbId));
string ignoredIds = string.Join(",", allExclusions.Select(ex => ex.TmdbId));
HttpRequest request;
List<MovieResult> results;
List<MovieResult> results = new List<MovieResult>();
/*if (action == "upcoming")
try
{
var lastWeek = DateTime.Now.AddDays(-7);
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)
results = _radarrAPI.DiscoverMovies(action, (request) =>
{
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);
}
private string StripTrailingTheFromTitle(string title)
@ -499,7 +482,7 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
_logger.Warn("Cleaned response: " + responseCleaned);
ImdbResource json = JsonConvert.DeserializeObject<ImdbResource>(responseCleaned);
ImdbResource json =Json Convert.DeserializeObject<ImdbResource>(responseCleaned);
_logger.Warn("Json object: " + json);

View File

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