Fixed: (Rarbg) More reliable token handling and retry

Fixes #1148
pull/1149/head
Qstick 2 years ago
parent b8ca28d955
commit 3b7c59e9bb

@ -1,6 +1,11 @@
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Net.Http.Json;
using System.Threading.Tasks;
using System.Web;
using Newtonsoft.Json;
using NLog; using NLog;
using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
@ -8,7 +13,9 @@ using NzbDrone.Common.Http;
using NzbDrone.Core.Configuration; using NzbDrone.Core.Configuration;
using NzbDrone.Core.Exceptions; using NzbDrone.Core.Exceptions;
using NzbDrone.Core.Http.CloudFlare; using NzbDrone.Core.Http.CloudFlare;
using NzbDrone.Core.Indexers.Exceptions;
using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Indexers.Rarbg namespace NzbDrone.Core.Indexers.Rarbg
@ -95,6 +102,57 @@ namespace NzbDrone.Core.Indexers.Rarbg
return caps; return caps;
} }
protected override async Task<IndexerQueryResult> FetchPage(IndexerRequest request, IParseIndexerResponse parser)
{
var response = await FetchIndexerResponse(request);
// try and recover from token or rate limit errors
var jsonResponse = new HttpResponse<RarbgResponse>(response.HttpResponse);
if (jsonResponse.Resource.error_code.HasValue)
{
if (jsonResponse.Resource.error_code == 4 || jsonResponse.Resource.error_code == 2)
{
_logger.Debug("Invalid or expired token, refreshing token from Rarbg");
_tokenProvider.ExpireToken(Settings);
var newToken = _tokenProvider.GetToken(Settings);
var qs = HttpUtility.ParseQueryString(request.HttpRequest.Url.Query);
qs.Set("token", newToken);
request.HttpRequest.Url = request.Url.SetQuery(qs.GetQueryString());
response = await FetchIndexerResponse(request);
}
else if (jsonResponse.Resource.error_code == 5 || jsonResponse.Resource.rate_limit.HasValue)
{
_logger.Debug("Rarbg rate limit hit, retying request");
response = await FetchIndexerResponse(request);
}
}
try
{
var releases = parser.ParseResponse(response).ToList();
if (releases.Count == 0)
{
_logger.Trace(response.Content);
}
return new IndexerQueryResult
{
Releases = releases,
Response = response.HttpResponse
};
}
catch (Exception ex)
{
ex.WithData(response.HttpResponse, 128 * 1024);
_logger.Trace("Unexpected Response content ({0} bytes): {1}", response.HttpResponse.ResponseData.Length, response.HttpResponse.Content);
throw;
}
}
public override object RequestAction(string action, IDictionary<string, string> query) public override object RequestAction(string action, IDictionary<string, string> query)
{ {
if (action == "checkCaptcha") if (action == "checkCaptcha")

@ -41,9 +41,10 @@ namespace NzbDrone.Core.Indexers.Rarbg
{ {
if (jsonResponse.Resource.error_code == 20 || jsonResponse.Resource.error_code == 8 if (jsonResponse.Resource.error_code == 20 || jsonResponse.Resource.error_code == 8
|| jsonResponse.Resource.error_code == 9 || jsonResponse.Resource.error_code == 10 || jsonResponse.Resource.error_code == 9 || jsonResponse.Resource.error_code == 10
|| jsonResponse.Resource.error_code == 5) || jsonResponse.Resource.error_code == 5 || jsonResponse.Resource.error_code == 13
|| jsonResponse.Resource.error_code == 14)
{ {
// No results, rate limit, or imdbid not found // No results, rate limit, or imdbid/tvdb not found
return results; return results;
} }

@ -69,42 +69,36 @@ namespace NzbDrone.Core.Indexers.Rarbg
public IndexerPageableRequestChain GetSearchRequests(MovieSearchCriteria searchCriteria) public IndexerPageableRequestChain GetSearchRequests(MovieSearchCriteria searchCriteria)
{ {
var request = GetRequest(searchCriteria.SanitizedSearchTerm, searchCriteria.Categories, searchCriteria.FullImdbId, searchCriteria.TmdbId); var pageableRequests = new IndexerPageableRequestChain();
return GetRequestChain(request, 2); pageableRequests.Add(GetRequest(searchCriteria.SanitizedSearchTerm, searchCriteria.Categories, searchCriteria.FullImdbId, searchCriteria.TmdbId));
return pageableRequests;
} }
public IndexerPageableRequestChain GetSearchRequests(MusicSearchCriteria searchCriteria) public IndexerPageableRequestChain GetSearchRequests(MusicSearchCriteria searchCriteria)
{ {
var request = GetRequest(searchCriteria.SanitizedSearchTerm, searchCriteria.Categories); var pageableRequests = new IndexerPageableRequestChain();
return GetRequestChain(request, 2); pageableRequests.Add(GetRequest(searchCriteria.SanitizedSearchTerm, searchCriteria.Categories));
return pageableRequests;
} }
public IndexerPageableRequestChain GetSearchRequests(TvSearchCriteria searchCriteria) public IndexerPageableRequestChain GetSearchRequests(TvSearchCriteria searchCriteria)
{ {
var request = GetRequest(searchCriteria.SanitizedTvSearchString, searchCriteria.Categories, searchCriteria.FullImdbId, tvdbId: searchCriteria.TvdbId); var pageableRequests = new IndexerPageableRequestChain();
return GetRequestChain(request, 2); pageableRequests.Add(GetRequest(searchCriteria.SanitizedTvSearchString, searchCriteria.Categories, searchCriteria.FullImdbId, tvdbId: searchCriteria.TvdbId));
return pageableRequests;
} }
public IndexerPageableRequestChain GetSearchRequests(BookSearchCriteria searchCriteria) public IndexerPageableRequestChain GetSearchRequests(BookSearchCriteria searchCriteria)
{ {
var request = GetRequest(searchCriteria.SanitizedSearchTerm, searchCriteria.Categories); var pageableRequests = new IndexerPageableRequestChain();
return GetRequestChain(request, 2); pageableRequests.Add(GetRequest(searchCriteria.SanitizedSearchTerm, searchCriteria.Categories));
return pageableRequests;
} }
public IndexerPageableRequestChain GetSearchRequests(BasicSearchCriteria searchCriteria) public IndexerPageableRequestChain GetSearchRequests(BasicSearchCriteria searchCriteria)
{
var request = GetRequest(searchCriteria.SanitizedSearchTerm, searchCriteria.Categories);
return GetRequestChain(request, 2);
}
private IndexerPageableRequestChain GetRequestChain(IEnumerable<IndexerRequest> requests, int retry)
{ {
var pageableRequests = new IndexerPageableRequestChain(); var pageableRequests = new IndexerPageableRequestChain();
pageableRequests.Add(GetRequest(searchCriteria.SanitizedSearchTerm, searchCriteria.Categories));
for (int i = 0; i < retry; i++)
{
pageableRequests.AddTier(requests);
}
return pageableRequests; return pageableRequests;
} }

@ -7,6 +7,7 @@ namespace NzbDrone.Core.Indexers.Rarbg
{ {
public string error { get; set; } public string error { get; set; }
public int? error_code { get; set; } public int? error_code { get; set; }
public int? rate_limit { get; set; }
public List<RarbgTorrent> torrent_results { get; set; } public List<RarbgTorrent> torrent_results { get; set; }
} }

@ -3,14 +3,14 @@ using Newtonsoft.Json.Linq;
using NLog; using NLog;
using NzbDrone.Common.Cache; using NzbDrone.Common.Cache;
using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Extensions;
using NzbDrone.Common.Http; using NzbDrone.Common.Http;
namespace NzbDrone.Core.Indexers.Rarbg namespace NzbDrone.Core.Indexers.Rarbg
{ {
public interface IRarbgTokenProvider public interface IRarbgTokenProvider
{ {
string GetToken(RarbgSettings settings, string baseUrl); string GetToken(RarbgSettings settings);
void ExpireToken(RarbgSettings settings);
} }
public class RarbgTokenProvider : IRarbgTokenProvider public class RarbgTokenProvider : IRarbgTokenProvider
@ -26,12 +26,17 @@ namespace NzbDrone.Core.Indexers.Rarbg
_logger = logger; _logger = logger;
} }
public string GetToken(RarbgSettings settings, string baseUrl) public void ExpireToken(RarbgSettings settings)
{ {
return _tokenCache.Get(baseUrl, _tokenCache.Remove(settings.BaseUrl);
}
public string GetToken(RarbgSettings settings)
{
return _tokenCache.Get(settings.BaseUrl,
() => () =>
{ {
var requestBuilder = new HttpRequestBuilder(baseUrl.Trim('/')) var requestBuilder = new HttpRequestBuilder(settings.BaseUrl.Trim('/'))
.WithRateLimit(3.0) .WithRateLimit(3.0)
.Resource($"/pubapi_v2.php?get_token=get_token&app_id={BuildInfo.AppName}") .Resource($"/pubapi_v2.php?get_token=get_token&app_id={BuildInfo.AppName}")
.Accept(HttpAccept.Json); .Accept(HttpAccept.Json);

Loading…
Cancel
Save