mirror of
https://github.com/Radarr/Radarr.git
synced 2024-11-04 10:02:40 +01:00
New: Trakt Auth per List
This commit is contained in:
parent
5e52a12287
commit
5d7804478b
@ -6,11 +6,8 @@ namespace NzbDrone.Api.Config
|
||||
public class NetImportConfigResource : RestResource
|
||||
{
|
||||
public int NetImportSyncInterval { get; set; }
|
||||
public string ListSyncLevel { get; set; }
|
||||
public string ImportExclusions { get; set; }
|
||||
public string TraktAuthToken { get; set; }
|
||||
public string TraktRefreshToken { get; set; }
|
||||
public int TraktTokenExpiry { get; set; }
|
||||
public string ListSyncLevel { get; set; }
|
||||
public string ImportExclusions { get; set; }
|
||||
}
|
||||
|
||||
public static class NetImportConfigResourceMapper
|
||||
@ -20,11 +17,8 @@ public static NetImportConfigResource ToResource(IConfigService model)
|
||||
return new NetImportConfigResource
|
||||
{
|
||||
NetImportSyncInterval = model.NetImportSyncInterval,
|
||||
ListSyncLevel = model.ListSyncLevel,
|
||||
ImportExclusions = model.ImportExclusions,
|
||||
TraktAuthToken = model.TraktAuthToken,
|
||||
TraktRefreshToken = model.TraktRefreshToken,
|
||||
TraktTokenExpiry = model.TraktTokenExpiry,
|
||||
ListSyncLevel = model.ListSyncLevel,
|
||||
ImportExclusions = model.ImportExclusions,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -119,45 +119,6 @@ public int NetImportSyncInterval
|
||||
set { SetValue("NetImportSyncInterval", value); }
|
||||
}
|
||||
|
||||
public string TraktAuthToken
|
||||
{
|
||||
get { return GetValue("TraktAuthToken", string.Empty); }
|
||||
|
||||
set { SetValue("TraktAuthToken", value); }
|
||||
}
|
||||
|
||||
public string TraktRefreshToken
|
||||
{
|
||||
get { return GetValue("TraktRefreshToken", string.Empty); }
|
||||
|
||||
set { SetValue("TraktRefreshToken", value); }
|
||||
}
|
||||
|
||||
public int TraktTokenExpiry
|
||||
{
|
||||
get { return GetValueInt("TraktTokenExpiry", 0); }
|
||||
|
||||
set { SetValue("TraktTokenExpiry", value); }
|
||||
}
|
||||
|
||||
public string NewTraktAuthToken
|
||||
{
|
||||
get { return GetValue("NewTraktAuthToken", string.Empty); }
|
||||
set { SetValue("NewTraktAuthToken", value); }
|
||||
}
|
||||
|
||||
public string NewTraktRefreshToken
|
||||
{
|
||||
get { return GetValue("NewTraktRefreshToken", string.Empty); }
|
||||
set { SetValue("NewTraktRefreshToken", value); }
|
||||
}
|
||||
|
||||
public int NewTraktTokenExpiry
|
||||
{
|
||||
get { return GetValueInt("NewTraktTokenExpiry", 0); }
|
||||
set { SetValue("NewTraktTokenExpiry", value); }
|
||||
}
|
||||
|
||||
public string ListSyncLevel
|
||||
{
|
||||
get { return GetValue("ListSyncLevel", "disabled"); }
|
||||
|
@ -66,12 +66,6 @@ public interface IConfigService
|
||||
int NetImportSyncInterval { get; set; }
|
||||
string ListSyncLevel { get; set; }
|
||||
string ImportExclusions { get; set; }
|
||||
string TraktAuthToken { get; set; }
|
||||
string TraktRefreshToken { get; set; }
|
||||
int TraktTokenExpiry { get; set; }
|
||||
string NewTraktAuthToken { get; set; }
|
||||
string NewTraktRefreshToken {get; set; }
|
||||
int NewTraktTokenExpiry { get; set; }
|
||||
|
||||
//UI
|
||||
int FirstDayOfWeek { get; set; }
|
||||
|
@ -7,7 +7,7 @@ namespace NzbDrone.Core.NetImport
|
||||
{
|
||||
public interface INetImportRepository : IProviderRepository<NetImportDefinition>
|
||||
{
|
||||
|
||||
void UpdateSettings(NetImportDefinition model);
|
||||
}
|
||||
|
||||
public class NetImportRepository : ProviderRepository<NetImportDefinition>, INetImportRepository
|
||||
@ -16,5 +16,10 @@ public NetImportRepository(IMainDatabase database, IEventAggregator eventAggrega
|
||||
: base(database, eventAggregator)
|
||||
{
|
||||
}
|
||||
|
||||
public void UpdateSettings(NetImportDefinition model)
|
||||
{
|
||||
SetFields(model, m => m.Settings);
|
||||
}
|
||||
}
|
||||
}
|
@ -2,6 +2,9 @@
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.Parser;
|
||||
using NzbDrone.Core.Validation;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace NzbDrone.Core.NetImport.Trakt
|
||||
{
|
||||
@ -11,13 +14,62 @@ public class TraktImport : HttpNetImportBase<TraktSettings>
|
||||
public override bool Enabled => true;
|
||||
public override bool EnableAuto => false;
|
||||
|
||||
public TraktImport(IHttpClient httpClient, IConfigService configService, IParsingService parsingService, Logger logger)
|
||||
private INetImportRepository _netImportRepository;
|
||||
|
||||
public TraktImport(INetImportRepository netImportRepository,
|
||||
IHttpClient httpClient,
|
||||
IConfigService configService,
|
||||
IParsingService parsingService,
|
||||
Logger logger)
|
||||
: base(httpClient, configService, parsingService, logger)
|
||||
{
|
||||
_netImportRepository = netImportRepository;
|
||||
}
|
||||
|
||||
private void RefreshToken()
|
||||
{
|
||||
_logger.Trace("Refreshing Token");
|
||||
|
||||
Settings.Validate().Filter("RefreshToken").ThrowOnError();
|
||||
|
||||
var request = new HttpRequestBuilder(Settings.RenewUri)
|
||||
.AddQueryParam("refresh", Settings.RefreshToken)
|
||||
.Build();
|
||||
|
||||
try
|
||||
{
|
||||
var response = _httpClient.Get<RefreshRequestResponse>(request);
|
||||
|
||||
if (response != null && response.Resource != null)
|
||||
{
|
||||
var token = response.Resource;
|
||||
Settings.AccessToken = token.access_token;
|
||||
Settings.Expires = DateTime.UtcNow.AddSeconds(token.expires_in);
|
||||
Settings.RefreshToken = token.refresh_token != null ? token.refresh_token : Settings.RefreshToken;
|
||||
|
||||
if (Definition.Id > 0)
|
||||
{
|
||||
_netImportRepository.UpdateSettings((NetImportDefinition)Definition);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (HttpException)
|
||||
{
|
||||
_logger.Warn($"Error refreshing trakt access token");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override INetImportRequestGenerator GetRequestGenerator()
|
||||
{
|
||||
Settings.Validate().Filter("AccessToken", "RefreshToken").ThrowOnError();
|
||||
_logger.Trace($"Access token expires at {Settings.Expires}");
|
||||
|
||||
if (Settings.Expires < DateTime.UtcNow.AddMinutes(5))
|
||||
{
|
||||
RefreshToken();
|
||||
}
|
||||
|
||||
return new TraktRequestGenerator() { Settings = Settings, _configService=_configService, HttpClient = _httpClient, };
|
||||
}
|
||||
|
||||
@ -25,5 +77,31 @@ public override IParseNetImportResponse GetParser()
|
||||
{
|
||||
return new TraktParser(Settings);
|
||||
}
|
||||
|
||||
public override object RequestAction(string action, IDictionary<string, string> query)
|
||||
{
|
||||
if (action == "startOAuth")
|
||||
{
|
||||
var request = new HttpRequestBuilder(Settings.OAuthUrl)
|
||||
.AddQueryParam("target", query["callbackUrl"])
|
||||
.Build();
|
||||
|
||||
return new
|
||||
{
|
||||
OauthUrl = request.Url.ToString()
|
||||
};
|
||||
}
|
||||
else if (action == "getOAuthToken")
|
||||
{
|
||||
return new
|
||||
{
|
||||
accessToken = query["access"],
|
||||
expires = DateTime.UtcNow.AddSeconds(4838400),
|
||||
refreshToken = query["refresh"],
|
||||
};
|
||||
}
|
||||
|
||||
return new { };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,11 +24,8 @@ public class TraktRequestGenerator : INetImportRequestGenerator
|
||||
public IHttpClient HttpClient { get; set; }
|
||||
public TraktSettings Settings { get; set; }
|
||||
|
||||
public string RadarrTraktUrl { get; set; }
|
||||
|
||||
public TraktRequestGenerator()
|
||||
{
|
||||
RadarrTraktUrl = "http://radarr.aeonlucid.com/v1/trakt/refresh?refresh=";
|
||||
}
|
||||
public virtual NetImportPageableRequestChain GetMovies()
|
||||
{
|
||||
@ -39,52 +36,6 @@ public virtual NetImportPageableRequestChain GetMovies()
|
||||
return pageableRequests;
|
||||
}
|
||||
|
||||
private void Authenticate()
|
||||
{
|
||||
if (_configService.TraktRefreshToken != string.Empty)
|
||||
{
|
||||
//tokens were overwritten with something other than nothing
|
||||
if (_configService.NewTraktTokenExpiry > _configService.TraktTokenExpiry)
|
||||
{
|
||||
//but our refreshedTokens are more current
|
||||
_configService.TraktAuthToken = _configService.NewTraktAuthToken;
|
||||
_configService.TraktRefreshToken = _configService.NewTraktRefreshToken;
|
||||
_configService.TraktTokenExpiry = _configService.NewTraktTokenExpiry;
|
||||
}
|
||||
|
||||
var unixTime = (int)DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds;
|
||||
|
||||
if (unixTime > _configService.TraktTokenExpiry)
|
||||
{
|
||||
var requestBuilder = new HttpRequestBuilder($"{RadarrTraktUrl + _configService.TraktRefreshToken}")
|
||||
{
|
||||
LogResponseContent = true
|
||||
};
|
||||
|
||||
requestBuilder.Method = HttpMethod.GET;
|
||||
|
||||
var authLoginRequest = requestBuilder
|
||||
.SetHeader("Content-Type", "application/json")
|
||||
.Accept(HttpAccept.Json)
|
||||
.Build();
|
||||
|
||||
var response = HttpClient.Execute(authLoginRequest);
|
||||
var result = Json.Deserialize<RefreshRequestResponse>(response.Content);
|
||||
|
||||
_configService.TraktAuthToken = result.access_token;
|
||||
_configService.TraktRefreshToken = result.refresh_token;
|
||||
|
||||
//lets have it expire in 8 weeks (4838400 seconds)
|
||||
_configService.TraktTokenExpiry = unixTime + 4838400;
|
||||
|
||||
//store the refreshed tokens in case they get overwritten by an old set of tokens
|
||||
_configService.NewTraktAuthToken = _configService.TraktAuthToken;
|
||||
_configService.NewTraktRefreshToken = _configService.TraktRefreshToken;
|
||||
_configService.NewTraktTokenExpiry = _configService.TraktTokenExpiry;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<NetImportRequest> GetMovies(string searchParameters)
|
||||
{
|
||||
var link = Settings.Link.Trim();
|
||||
@ -129,14 +80,14 @@ private IEnumerable<NetImportRequest> GetMovies(string searchParameters)
|
||||
break;
|
||||
}
|
||||
|
||||
Authenticate();
|
||||
|
||||
var request = new NetImportRequest($"{link}", HttpAccept.Json);
|
||||
|
||||
request.HttpRequest.Headers.Add("trakt-api-version", "2");
|
||||
request.HttpRequest.Headers.Add("trakt-api-key", "964f67b126ade0112c4ae1f0aea3a8fb03190f71117bd83af6a0560a99bc52e6"); //aeon
|
||||
if (_configService.TraktAuthToken.IsNotNullOrWhiteSpace())
|
||||
request.HttpRequest.Headers.Add("trakt-api-key", Settings.ClientId); //aeon
|
||||
|
||||
if (Settings.AccessToken.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
request.HttpRequest.Headers.Add("Authorization", "Bearer " + _configService.TraktAuthToken);
|
||||
request.HttpRequest.Headers.Add("Authorization", "Bearer " + Settings.AccessToken);
|
||||
}
|
||||
|
||||
yield return request;
|
||||
|
@ -3,6 +3,7 @@
|
||||
using NzbDrone.Core.Annotations;
|
||||
using NzbDrone.Core.ThingiProvider;
|
||||
using NzbDrone.Core.Validation;
|
||||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace NzbDrone.Core.NetImport.Trakt
|
||||
@ -13,6 +14,9 @@ public class TraktSettingsValidator : AbstractValidator<TraktSettings>
|
||||
public TraktSettingsValidator()
|
||||
{
|
||||
RuleFor(c => c.Link).ValidRootUrl();
|
||||
RuleFor(c => c.AccessToken).NotEmpty();
|
||||
RuleFor(c => c.RefreshToken).NotEmpty();
|
||||
RuleFor(c => c.Expires).NotEmpty();
|
||||
|
||||
// List name required for UserCustomList
|
||||
RuleFor(c => c.Listname)
|
||||
@ -59,6 +63,7 @@ public class TraktSettings : IProviderConfig
|
||||
public TraktSettings()
|
||||
{
|
||||
Link = "https://api.trakt.tv";
|
||||
SignIn = "startOAuth";
|
||||
ListType = (int)TraktListType.Popular;
|
||||
Username = "";
|
||||
Listname = "";
|
||||
@ -69,6 +74,20 @@ public TraktSettings()
|
||||
Limit = 100;
|
||||
}
|
||||
|
||||
public string OAuthUrl => "http://radarr.aeonlucid.com/v1/trakt/redirect";
|
||||
public string RenewUri => "http://radarr.aeonlucid.com/v1/trakt/refresh";
|
||||
public string ClientId => "964f67b126ade0112c4ae1f0aea3a8fb03190f71117bd83af6a0560a99bc52e6";
|
||||
public virtual string Scope => "";
|
||||
|
||||
[FieldDefinition(0, Label = "Access Token", Type = FieldType.Textbox, Hidden = HiddenType.Hidden)]
|
||||
public string AccessToken { get; set; }
|
||||
|
||||
[FieldDefinition(0, Label = "Refresh Token", Type = FieldType.Textbox, Hidden = HiddenType.Hidden)]
|
||||
public string RefreshToken { get; set; }
|
||||
|
||||
[FieldDefinition(0, Label = "Expires", Type = FieldType.Textbox, Hidden = HiddenType.Hidden)]
|
||||
public DateTime Expires { get; set; }
|
||||
|
||||
[FieldDefinition(0, Label = "Trakt API URL", HelpText = "Link to to Trakt API URL, do not change unless you know what you are doing.")]
|
||||
public string Link { get; set; }
|
||||
|
||||
@ -99,6 +118,9 @@ public TraktSettings()
|
||||
[FieldDefinition(9, Label = "Additional Parameters", HelpText = "Additional Trakt API parameters", Advanced = true)]
|
||||
public string TraktAdditionalParameters { get; set; }
|
||||
|
||||
[FieldDefinition(99, Label = "Authenticate with Trakt", Type = FieldType.OAuth)]
|
||||
public string SignIn { get; set; }
|
||||
|
||||
|
||||
public NzbDroneValidationResult Validate()
|
||||
{
|
||||
|
@ -8,9 +8,6 @@ public class NetImportConfigResource : RestResource
|
||||
public int NetImportSyncInterval { get; set; }
|
||||
public string ListSyncLevel { get; set; }
|
||||
public string ImportExclusions { get; set; }
|
||||
public string TraktAuthToken { get; set; }
|
||||
public string TraktRefreshToken { get; set; }
|
||||
public int TraktTokenExpiry { get; set; }
|
||||
}
|
||||
|
||||
public static class NetImportConfigResourceMapper
|
||||
@ -21,10 +18,7 @@ public static NetImportConfigResource ToResource(IConfigService model)
|
||||
{
|
||||
NetImportSyncInterval = model.NetImportSyncInterval,
|
||||
ListSyncLevel = model.ListSyncLevel,
|
||||
ImportExclusions = model.ImportExclusions,
|
||||
TraktAuthToken = model.TraktAuthToken,
|
||||
TraktRefreshToken = model.TraktRefreshToken,
|
||||
TraktTokenExpiry = model.TraktTokenExpiry,
|
||||
ImportExclusions = model.ImportExclusions
|
||||
};
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user