Merge 56ea38f061
into 8b2223a9c4
commit
da7a7f4ac0
@ -0,0 +1,31 @@
|
||||
using System;
|
||||
using NzbDrone.Common.Exceptions;
|
||||
|
||||
namespace NzbDrone.Core.ImportLists.NYTimes
|
||||
{
|
||||
public class NYTimesException : NzbDroneException
|
||||
{
|
||||
public NYTimesException(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public NYTimesException(string message, params object[] args)
|
||||
: base(message, args)
|
||||
{
|
||||
}
|
||||
|
||||
public NYTimesException(string message, Exception innerException)
|
||||
: base(message, innerException)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class NYTimesAuthorizationException : NYTimesException
|
||||
{
|
||||
public NYTimesAuthorizationException(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,147 @@
|
||||
using FluentValidation.Results;
|
||||
using Newtonsoft.Json;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.Parser;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace NzbDrone.Core.ImportLists.NYTimes
|
||||
{
|
||||
public class NYTimesImport : ImportListBase<NYTimesSettings>
|
||||
{
|
||||
protected readonly IHttpClient _httpClient;
|
||||
|
||||
public override string Name => "New York Times";
|
||||
|
||||
public override ImportListType ListType => ImportListType.Other;
|
||||
public override TimeSpan MinRefreshInterval => TimeSpan.FromHours(12);
|
||||
|
||||
public NYTimesImport(IImportListStatusService importListStatusService,
|
||||
IConfigService configService,
|
||||
IParsingService parsingService,
|
||||
IHttpClient httpClient,
|
||||
Logger logger)
|
||||
: base(importListStatusService, configService, parsingService, logger)
|
||||
{
|
||||
_httpClient = httpClient;
|
||||
}
|
||||
|
||||
public List<NYTimesName> GetNames(NYTimesSettings settings)
|
||||
{
|
||||
if (settings.ApiKey.IsNullOrWhiteSpace())
|
||||
{
|
||||
return new List<NYTimesName>();
|
||||
}
|
||||
|
||||
var request = new HttpRequestBuilder(settings.BaseUrl)
|
||||
.Resource("/lists/names.json")
|
||||
.AddQueryParam("api-key", settings.ApiKey)
|
||||
.Build();
|
||||
|
||||
var response = _httpClient.Get(request);
|
||||
|
||||
var content = JsonConvert.DeserializeObject<NYTimesResponse<List<NYTimesName>>>(response.Content);
|
||||
|
||||
return content.Results;
|
||||
}
|
||||
|
||||
public List<NYTimesList> GetList(NYTimesSettings settings)
|
||||
{
|
||||
if (settings.ApiKey.IsNullOrWhiteSpace() || settings.ListName.IsNullOrWhiteSpace())
|
||||
{
|
||||
return new List<NYTimesList>();
|
||||
}
|
||||
|
||||
var request = new HttpRequestBuilder(settings.BaseUrl)
|
||||
.Resource("/lists.json")
|
||||
.AddQueryParam("api-key", settings.ApiKey)
|
||||
.AddQueryParam("list", settings.ListName)
|
||||
.Build();
|
||||
|
||||
var response = _httpClient.Get(request);
|
||||
|
||||
var content = JsonConvert.DeserializeObject<NYTimesResponse<List<NYTimesList>>>(response.Content);
|
||||
|
||||
return content.Results;
|
||||
}
|
||||
|
||||
public override IList<ImportListItemInfo> Fetch()
|
||||
{
|
||||
var books = new List<ImportListItemInfo>();
|
||||
|
||||
try
|
||||
{
|
||||
var lists = GetList(Settings);
|
||||
|
||||
foreach (var list in lists)
|
||||
{
|
||||
var book = list.BookDetails.FirstOrDefault();
|
||||
|
||||
books.Add(new ImportListItemInfo
|
||||
{
|
||||
Author = book.Author,
|
||||
Book = book.Title
|
||||
});
|
||||
}
|
||||
|
||||
_importListStatusService.RecordSuccess(Definition.Id);
|
||||
}
|
||||
catch
|
||||
{
|
||||
_logger.Warn("List Import Sync Task Failed for List [{0}]", Definition.Name);
|
||||
_importListStatusService.RecordFailure(Definition.Id);
|
||||
}
|
||||
|
||||
return CleanupListItems(books);
|
||||
}
|
||||
|
||||
protected override void Test(List<ValidationFailure> failures)
|
||||
{
|
||||
failures.AddIfNotNull(TestConnection());
|
||||
}
|
||||
|
||||
private ValidationFailure TestConnection()
|
||||
{
|
||||
try
|
||||
{
|
||||
GetNames(Settings);
|
||||
return null;
|
||||
}
|
||||
catch (HttpException ex)
|
||||
{
|
||||
_logger.Warn(ex, "New York Times Authentication Error");
|
||||
return new ValidationFailure(string.Empty, $"NYTimes authentication error: {ex.Message}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Warn(ex, "Unable to connect to NYTimes");
|
||||
|
||||
return new ValidationFailure(string.Empty, "Unable to connect to import list, check the log for more details");
|
||||
}
|
||||
}
|
||||
|
||||
public override object RequestAction(string action, IDictionary<string, string> query)
|
||||
{
|
||||
if (action == "getNames")
|
||||
{
|
||||
var names = GetNames(Settings);
|
||||
|
||||
return new
|
||||
{
|
||||
options = names.Select(name => new
|
||||
{
|
||||
Value = name.ListNameEncoded,
|
||||
Name = name.DisplayName
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
return new { };
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace NzbDrone.Core.ImportLists.NYTimes
|
||||
{
|
||||
public class NYTimesResponse<T>
|
||||
{
|
||||
public string Status { get; set; }
|
||||
public string Copyright { get; set; }
|
||||
[JsonProperty(PropertyName = "num_results")]
|
||||
public int NumResults { get; set; }
|
||||
[JsonProperty(PropertyName = "last_modified")]
|
||||
public string LastModified { get; set; }
|
||||
public T Results { get; set; }
|
||||
}
|
||||
|
||||
public class NYTimesName
|
||||
{
|
||||
[JsonProperty(PropertyName = "list_name")]
|
||||
public string ListName { get; set; }
|
||||
[JsonProperty(PropertyName = "display_name")]
|
||||
public string DisplayName { get; set; }
|
||||
[JsonProperty(PropertyName = "list_name_encoded")]
|
||||
public string ListNameEncoded { get; set; }
|
||||
[JsonProperty(PropertyName = "oldest_published_date")]
|
||||
public string OldestPublishedDate { get; set; }
|
||||
[JsonProperty(PropertyName = "newest_published_date")]
|
||||
public string NewestPublishedDate { get; set; }
|
||||
public string Updated { get; set; }
|
||||
}
|
||||
|
||||
public class NYTimesList
|
||||
{
|
||||
[JsonProperty(PropertyName = "list_name")]
|
||||
public string ListName { get; set; }
|
||||
[JsonProperty(PropertyName = "display_name")]
|
||||
public string DisplayName { get; set; }
|
||||
[JsonProperty(PropertyName = "bestsellers_date")]
|
||||
public string BestsellersDate { get; set; }
|
||||
[JsonProperty(PropertyName = "published_date")]
|
||||
public string PublishedDate { get; set; }
|
||||
public int Rank { get; set; }
|
||||
[JsonProperty(PropertyName = "rank_last_week")]
|
||||
public int RankLastWeek { get; set; }
|
||||
[JsonProperty(PropertyName = "weeks_on_list")]
|
||||
public int WeeksonList { get; set; }
|
||||
public int Asterisk { get; set; }
|
||||
public int Dagger { get; set; }
|
||||
[JsonProperty(PropertyName = "amazon_product_url")]
|
||||
public string AmazonProductUrl { get; set; }
|
||||
public object[] Isbns { get; set; }
|
||||
[JsonProperty(PropertyName = "book_details")]
|
||||
public List<NYTimesBook> BookDetails { get; set; }
|
||||
public object[] Reviews { get; set; }
|
||||
}
|
||||
|
||||
public class NYTimesBook
|
||||
{
|
||||
[JsonProperty(PropertyName = "age_group")]
|
||||
public string AgeGroup { get; set; }
|
||||
public string Author { get; set; }
|
||||
public string Contributor { get; set; }
|
||||
[JsonProperty(PropertyName = "contributor_note")]
|
||||
public string ContributorNote { get; set; }
|
||||
[JsonProperty(PropertyName = "created_date")]
|
||||
public string CreatedDate { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string Price { get; set; }
|
||||
[JsonProperty(PropertyName = "primary_isbn13")]
|
||||
public string PrimaryIsbn13 { get; set; }
|
||||
[JsonProperty(PropertyName = "primary_isbn10")]
|
||||
public string PrimaryIsbn10 { get; set; }
|
||||
public string Publisher { get; set; }
|
||||
public int Rank { get; set; }
|
||||
public string Title { get; set; }
|
||||
[JsonProperty(PropertyName = "updated_date")]
|
||||
public string UpdatedDate { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
using FluentValidation;
|
||||
using NzbDrone.Core.Annotations;
|
||||
using NzbDrone.Core.Validation;
|
||||
|
||||
namespace NzbDrone.Core.ImportLists.NYTimes
|
||||
{
|
||||
public class NYTimesSettingsValidator : AbstractValidator<NYTimesSettings>
|
||||
{
|
||||
public NYTimesSettingsValidator()
|
||||
{
|
||||
RuleFor(c => c.ApiKey).NotEmpty();
|
||||
RuleFor(c => c.ListName).NotEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
public class NYTimesSettings : IImportListSettings
|
||||
{
|
||||
private static readonly NYTimesSettingsValidator Validator = new ();
|
||||
public NYTimesSettings()
|
||||
{
|
||||
BaseUrl = "https://api.nytimes.com/svc/books/v3";
|
||||
}
|
||||
|
||||
public string BaseUrl { get; set; }
|
||||
|
||||
[FieldDefinition(0, Label = "API Key")]
|
||||
public string ApiKey { get; set; }
|
||||
|
||||
[FieldDefinition(1, Type = FieldType.Select, SelectOptionsProviderAction = "getNames", Label = "List Type", HelpText = "The name of the Times best sellers list")]
|
||||
public string ListName { get; set; }
|
||||
|
||||
public NzbDroneValidationResult Validate()
|
||||
{
|
||||
return new NzbDroneValidationResult(Validator.Validate(this));
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in new issue