Fixed: Goodreads import lists

pull/43/head
ta264 5 years ago
parent 723beb9ca3
commit 5f2d57f33b

@ -16,7 +16,7 @@ import styles from './PlaylistInput.css';
const columns = [ const columns = [
{ {
name: 'name', name: 'name',
label: 'Playlist', label: 'Bookshelf',
isSortable: false, isSortable: false,
isVisible: true isVisible: true
} }
@ -125,7 +125,7 @@ class PlaylistInput extends Component {
{ {
isPopulated && !isFetching && user && !!items.length && isPopulated && !isFetching && user && !!items.length &&
<div className={className}> <div className={className}>
Select playlists to import from Goodreads user {user}. Select bookshelves to import from Goodreads user {user}.
<Table <Table
columns={columns} columns={columns}
selectAll={true} selectAll={true}

@ -31,6 +31,7 @@ namespace NzbDrone.Common.OAuth
/// <seealso cref="http://oauth.net/core/1.0#request_urls"/> /// <seealso cref="http://oauth.net/core/1.0#request_urls"/>
public virtual string RequestUrl { get; set; } public virtual string RequestUrl { get; set; }
public virtual Dictionary<string, string> Parameters { get; set; }
#if !WINRT #if !WINRT
public string GetAuthorizationHeader(NameValueCollection parameters) public string GetAuthorizationHeader(NameValueCollection parameters)

@ -43,7 +43,12 @@ namespace NzbDrone.Core.Test.ImportListTests
.Returns<int>(x => Builder<Book> .Returns<int>(x => Builder<Book>
.CreateListOfSize(1) .CreateListOfSize(1)
.TheFirst(1) .TheFirst(1)
.With(b => b.ForeignBookId = x.ToString()) .With(b => b.Editions = Builder<Edition>
.CreateListOfSize(1)
.TheFirst(1)
.With(e => e.ForeignEditionId = x.ToString())
.With(e => e.Monitored = true)
.BuildList())
.BuildList()); .BuildList());
Mocker.GetMock<IImportListFactory>() Mocker.GetMock<IImportListFactory>()
@ -74,26 +79,26 @@ namespace NzbDrone.Core.Test.ImportListTests
private void WithAuthorId() private void WithAuthorId()
{ {
_importListReports.First().ArtistMusicBrainzId = "f59c5520-5f46-4d2c-b2c4-822eabf53419"; _importListReports.First().AuthorGoodreadsId = "f59c5520-5f46-4d2c-b2c4-822eabf53419";
} }
private void WithBookId() private void WithBookId()
{ {
_importListReports.First().AlbumMusicBrainzId = "101"; _importListReports.First().EditionGoodreadsId = "101";
} }
private void WithExistingArtist() private void WithExistingArtist()
{ {
Mocker.GetMock<IAuthorService>() Mocker.GetMock<IAuthorService>()
.Setup(v => v.FindById(_importListReports.First().ArtistMusicBrainzId)) .Setup(v => v.FindById(_importListReports.First().AuthorGoodreadsId))
.Returns(new Author { ForeignAuthorId = _importListReports.First().ArtistMusicBrainzId }); .Returns(new Author { ForeignAuthorId = _importListReports.First().AuthorGoodreadsId });
} }
private void WithExistingAlbum() private void WithExistingAlbum()
{ {
Mocker.GetMock<IBookService>() Mocker.GetMock<IBookService>()
.Setup(v => v.FindById(_importListReports.First().AlbumMusicBrainzId)) .Setup(v => v.FindById(_importListReports.First().EditionGoodreadsId))
.Returns(new Book { ForeignBookId = _importListReports.First().AlbumMusicBrainzId }); .Returns(new Book { ForeignBookId = _importListReports.First().EditionGoodreadsId });
} }
private void WithExcludedArtist() private void WithExcludedArtist()

@ -23,10 +23,6 @@ namespace NzbDrone.Core.Test.MusicTests
[SetUp] [SetUp]
public void Setup() public void Setup()
{ {
_fakeAlbum = Builder<Book>
.CreateNew()
.Build();
_fakeArtist = Builder<Author> _fakeArtist = Builder<Author>
.CreateNew() .CreateNew()
.With(s => s.Path = null) .With(s => s.Path = null)
@ -36,6 +32,16 @@ namespace NzbDrone.Core.Test.MusicTests
private void GivenValidAlbum(string readarrId) private void GivenValidAlbum(string readarrId)
{ {
_fakeAlbum = Builder<Book>
.CreateNew()
.With(x => x.Editions = Builder<Edition>
.CreateListOfSize(1)
.TheFirst(1)
.With(e => e.ForeignEditionId = readarrId)
.With(e => e.Monitored = true)
.BuildList())
.Build();
Mocker.GetMock<IProvideBookInfo>() Mocker.GetMock<IProvideBookInfo>()
.Setup(s => s.GetBookInfo(readarrId)) .Setup(s => s.GetBookInfo(readarrId))
.Returns(Tuple.Create(_fakeArtist.Metadata.Value.ForeignAuthorId, .Returns(Tuple.Create(_fakeArtist.Metadata.Value.ForeignAuthorId,

@ -62,6 +62,7 @@ namespace NzbDrone.Core.Books
// Note it's a manual addition so it's not deleted on next refresh // Note it's a manual addition so it's not deleted on next refresh
book.AddOptions.AddType = BookAddType.Manual; book.AddOptions.AddType = BookAddType.Manual;
book.Editions.Value.Single(x => x.Monitored).ManualAdd = true;
// Add the author if necessary // Add the author if necessary
var dbAuthor = _authorService.FindById(book.AuthorMetadata.Value.ForeignAuthorId); var dbAuthor = _authorService.FindById(book.AuthorMetadata.Value.ForeignAuthorId);
@ -105,10 +106,11 @@ namespace NzbDrone.Core.Books
private Book AddSkyhookData(Book newBook) private Book AddSkyhookData(Book newBook)
{ {
var editionId = newBook.Editions.Value.Single(x => x.Monitored).ForeignEditionId;
Tuple<string, Book, List<AuthorMetadata>> tuple = null; Tuple<string, Book, List<AuthorMetadata>> tuple = null;
try try
{ {
tuple = _bookInfo.GetBookInfo(newBook.Editions.Value.Single(x => x.Monitored).ForeignEditionId); tuple = _bookInfo.GetBookInfo(editionId);
} }
catch (BookNotFoundException) catch (BookNotFoundException)
{ {
@ -123,6 +125,10 @@ namespace NzbDrone.Core.Books
newBook.UseMetadataFrom(tuple.Item2); newBook.UseMetadataFrom(tuple.Item2);
newBook.Added = DateTime.UtcNow; newBook.Added = DateTime.UtcNow;
newBook.Editions = tuple.Item2.Editions.Value;
newBook.Editions.Value.ForEach(x => x.Monitored = false);
newBook.Editions.Value.Single(x => x.ForeignEditionId == editionId).Monitored = true;
var metadata = tuple.Item3.Single(x => x.ForeignAuthorId == tuple.Item1); var metadata = tuple.Item3.Single(x => x.ForeignAuthorId == tuple.Item1);
newBook.AuthorMetadata = metadata; newBook.AuthorMetadata = metadata;

@ -255,6 +255,12 @@ namespace NzbDrone.Core.Books
monitored = children.Future; monitored = children.Future;
} }
if (monitored.Count == 0)
{
// there are no future children so nothing to do
return;
}
var toMonitor = monitored.OrderByDescending(x => _mediaFileService.GetFilesByEdition(x.Id).Count) var toMonitor = monitored.OrderByDescending(x => _mediaFileService.GetFilesByEdition(x.Id).Count)
.ThenByDescending(x => x.Ratings.Popularity) .ThenByDescending(x => x.Ratings.Popularity)
.First(); .First();

@ -51,7 +51,7 @@ namespace NzbDrone.Core.ImportLists.Goodreads
{ {
Author = x.Book.Authors.First().Name.CleanSpaces(), Author = x.Book.Authors.First().Name.CleanSpaces(),
Book = x.Book.TitleWithoutSeries.CleanSpaces(), Book = x.Book.TitleWithoutSeries.CleanSpaces(),
AlbumMusicBrainzId = x.Book.Uri.Replace("kca://book/", string.Empty) EditionGoodreadsId = x.Book.Id.ToString()
}).ToList(); }).ToList();
} }

@ -10,6 +10,7 @@ using NLog;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Common.Http; using NzbDrone.Common.Http;
using NzbDrone.Common.OAuth; using NzbDrone.Common.OAuth;
using NzbDrone.Common.Serializer;
using NzbDrone.Core.Configuration; using NzbDrone.Core.Configuration;
using NzbDrone.Core.Exceptions; using NzbDrone.Core.Exceptions;
using NzbDrone.Core.MetadataSource.Goodreads; using NzbDrone.Core.MetadataSource.Goodreads;
@ -37,7 +38,6 @@ namespace NzbDrone.Core.ImportLists.Goodreads
public string AccessToken => Settings.AccessToken; public string AccessToken => Settings.AccessToken;
protected HttpRequestBuilder RequestBuilder() => new HttpRequestBuilder("https://www.goodreads.com/{route}") protected HttpRequestBuilder RequestBuilder() => new HttpRequestBuilder("https://www.goodreads.com/{route}")
.AddQueryParam("key", "xQh8LhdTztb9u3cL26RqVg", true)
.AddQueryParam("_nc", "1") .AddQueryParam("_nc", "1")
.KeepAlive(); .KeepAlive();
@ -75,7 +75,7 @@ namespace NzbDrone.Core.ImportLists.Goodreads
throw new BadRequestException("QueryParam callbackUrl invalid."); throw new BadRequestException("QueryParam callbackUrl invalid.");
} }
var oAuthRequest = OAuthRequest.ForRequestToken(Settings.ConsumerKey, Settings.ConsumerSecret, query["callbackUrl"]); var oAuthRequest = OAuthRequest.ForRequestToken(null, null, query["callbackUrl"]);
oAuthRequest.RequestUrl = Settings.OAuthRequestTokenUrl; oAuthRequest.RequestUrl = Settings.OAuthRequestTokenUrl;
var qscoll = OAuthQuery(oAuthRequest); var qscoll = OAuthQuery(oAuthRequest);
@ -99,7 +99,7 @@ namespace NzbDrone.Core.ImportLists.Goodreads
throw new BadRequestException("Missing requestTokenSecret."); throw new BadRequestException("Missing requestTokenSecret.");
} }
var oAuthRequest = OAuthRequest.ForAccessToken(Settings.ConsumerKey, Settings.ConsumerSecret, query["oauth_token"], query["requestTokenSecret"], ""); var oAuthRequest = OAuthRequest.ForAccessToken(null, null, query["oauth_token"], query["requestTokenSecret"], "");
oAuthRequest.RequestUrl = Settings.OAuthAccessTokenUrl; oAuthRequest.RequestUrl = Settings.OAuthAccessTokenUrl;
var qscoll = OAuthQuery(oAuthRequest); var qscoll = OAuthQuery(oAuthRequest);
@ -123,22 +123,41 @@ namespace NzbDrone.Core.ImportLists.Goodreads
protected Common.Http.HttpResponse OAuthGet(HttpRequestBuilder builder) protected Common.Http.HttpResponse OAuthGet(HttpRequestBuilder builder)
{ {
var auth = OAuthRequest.ForProtectedResource(builder.Method.ToString(), Settings.ConsumerKey, Settings.ConsumerSecret, Settings.AccessToken, Settings.AccessTokenSecret); var auth = OAuthRequest.ForProtectedResource(builder.Method.ToString(), null, null, Settings.AccessToken, Settings.AccessTokenSecret);
var request = builder.Build(); var request = builder.Build();
request.LogResponseContent = true; request.LogResponseContent = true;
// we need the url without the query to sign // we need the url without the query to sign
auth.RequestUrl = request.Url.SetQuery(null).FullUri; auth.RequestUrl = request.Url.SetQuery(null).FullUri;
auth.Parameters = builder.QueryParams.ToDictionary(x => x.Key, x => x.Value);
var header = auth.GetAuthorizationHeader(builder.QueryParams.ToDictionary(x => x.Key, x => x.Value)); var header = GetAuthorizationHeader(auth);
request.Headers.Add("Authorization", header); request.Headers.Add("Authorization", header);
return _httpClient.Get(request); return _httpClient.Get(request);
} }
private string GetAuthorizationHeader(OAuthRequest oAuthRequest)
{
var request = new Common.Http.HttpRequest(Settings.SigningUrl)
{
Method = HttpMethod.POST,
};
request.Headers.Set("Content-Type", "application/json");
var payload = oAuthRequest.ToJson();
_logger.Trace(payload);
request.SetContent(payload);
var response = _httpClient.Post<AuthorizationHeader>(request).Resource;
return response.Authorization;
}
private NameValueCollection OAuthQuery(OAuthRequest oAuthRequest) private NameValueCollection OAuthQuery(OAuthRequest oAuthRequest)
{ {
var auth = oAuthRequest.GetAuthorizationHeader(); var auth = GetAuthorizationHeader(oAuthRequest);
var request = new Common.Http.HttpRequest(oAuthRequest.RequestUrl); var request = new Common.Http.HttpRequest(oAuthRequest.RequestUrl);
request.Headers.Add("Authorization", auth); request.Headers.Add("Authorization", auth);
var response = _httpClient.Get(request); var response = _httpClient.Get(request);
@ -148,9 +167,7 @@ namespace NzbDrone.Core.ImportLists.Goodreads
private Tuple<string, string> GetUser() private Tuple<string, string> GetUser()
{ {
var builder = RequestBuilder() var builder = RequestBuilder().SetSegment("route", $"api/auth_user");
.SetSegment("route", $"api/auth_user")
.AddQueryParam("key", Settings.ConsumerKey, true);
var httpResponse = OAuthGet(builder); var httpResponse = OAuthGet(builder);
@ -169,4 +186,9 @@ namespace NzbDrone.Core.ImportLists.Goodreads
return Tuple.Create(userId, userName); return Tuple.Create(userId, userName);
} }
} }
public class AuthorizationHeader
{
public string Authorization { get; set; }
}
} }

@ -49,9 +49,9 @@ namespace NzbDrone.Core.ImportLists.Goodreads
var result = reviews.Select(x => new ImportListItemInfo var result = reviews.Select(x => new ImportListItemInfo
{ {
Author = x.Book.Authors.First().Name.CleanSpaces(), Author = x.Book.Authors.First().Name.CleanSpaces(),
ArtistMusicBrainzId = x.Book.Authors.First().Id.ToString(), AuthorGoodreadsId = x.Book.Authors.First().Id.ToString(),
Book = x.Book.TitleWithoutSeries.CleanSpaces(), Book = x.Book.TitleWithoutSeries.CleanSpaces(),
AlbumMusicBrainzId = x.Book.Id.ToString() EditionGoodreadsId = x.Book.Id.ToString()
}).ToList(); }).ToList();
return CleanupListItems(result); return CleanupListItems(result);

@ -24,8 +24,7 @@ namespace NzbDrone.Core.ImportLists.Goodreads
public string BaseUrl { get; set; } public string BaseUrl { get; set; }
public string ConsumerKey => "xQh8LhdTztb9u3cL26RqVg"; public string SigningUrl => "https://auth.servarr.com/v1/goodreads/sign";
public string ConsumerSecret => "96aDA1lJRcS8KofYbw2jjkRk3wTNKypHAL2GeOgbPZw";
public string OAuthUrl => "https://www.goodreads.com/oauth/authorize"; public string OAuthUrl => "https://www.goodreads.com/oauth/authorize";
public string OAuthRequestTokenUrl => "https://www.goodreads.com/oauth/request_token"; public string OAuthRequestTokenUrl => "https://www.goodreads.com/oauth/request_token";
public string OAuthAccessTokenUrl => "https://www.goodreads.com/oauth/access_token"; public string OAuthAccessTokenUrl => "https://www.goodreads.com/oauth/access_token";

@ -97,18 +97,18 @@ namespace NzbDrone.Core.ImportLists
var importList = _importListFactory.Get(report.ImportListId); var importList = _importListFactory.Get(report.ImportListId);
if (report.Book.IsNotNullOrWhiteSpace() || report.AlbumMusicBrainzId.IsNotNullOrWhiteSpace()) if (report.Book.IsNotNullOrWhiteSpace() || report.EditionGoodreadsId.IsNotNullOrWhiteSpace())
{ {
if (report.AlbumMusicBrainzId.IsNullOrWhiteSpace() || report.ArtistMusicBrainzId.IsNullOrWhiteSpace()) if (report.EditionGoodreadsId.IsNullOrWhiteSpace() || report.AuthorGoodreadsId.IsNullOrWhiteSpace())
{ {
MapAlbumReport(report); MapAlbumReport(report);
} }
ProcessAlbumReport(importList, report, listExclusions, albumsToAdd); ProcessAlbumReport(importList, report, listExclusions, albumsToAdd);
} }
else if (report.Author.IsNotNullOrWhiteSpace() || report.ArtistMusicBrainzId.IsNotNullOrWhiteSpace()) else if (report.Author.IsNotNullOrWhiteSpace() || report.AuthorGoodreadsId.IsNotNullOrWhiteSpace())
{ {
if (report.ArtistMusicBrainzId.IsNullOrWhiteSpace()) if (report.AuthorGoodreadsId.IsNullOrWhiteSpace())
{ {
MapArtistReport(report); MapArtistReport(report);
} }
@ -137,9 +137,10 @@ namespace NzbDrone.Core.ImportLists
{ {
Book mappedAlbum; Book mappedAlbum;
if (report.AlbumMusicBrainzId.IsNotNullOrWhiteSpace() && int.TryParse(report.AlbumMusicBrainzId, out var goodreadsId)) if (report.EditionGoodreadsId.IsNotNullOrWhiteSpace() && int.TryParse(report.EditionGoodreadsId, out var goodreadsId))
{ {
mappedAlbum = _bookSearchService.SearchByGoodreadsId(goodreadsId).FirstOrDefault(x => int.TryParse(x.ForeignBookId, out var bookId) && bookId == goodreadsId); var search = _bookSearchService.SearchByGoodreadsId(goodreadsId);
mappedAlbum = search.FirstOrDefault(x => x.Editions.Value.Any(e => int.TryParse(e.ForeignEditionId, out var editionId) && editionId == goodreadsId));
} }
else else
{ {
@ -149,62 +150,71 @@ namespace NzbDrone.Core.ImportLists
// Break if we are looking for an book and cant find it. This will avoid us from adding the author and possibly getting it wrong. // Break if we are looking for an book and cant find it. This will avoid us from adding the author and possibly getting it wrong.
if (mappedAlbum == null) if (mappedAlbum == null)
{ {
_logger.Trace($"Nothing found for {report.AlbumMusicBrainzId}"); _logger.Trace($"Nothing found for {report.EditionGoodreadsId}");
report.AlbumMusicBrainzId = null; report.EditionGoodreadsId = null;
return; return;
} }
_logger.Trace($"Mapped {report.AlbumMusicBrainzId} to {mappedAlbum}"); _logger.Trace($"Mapped {report.EditionGoodreadsId} to {mappedAlbum}");
report.AlbumMusicBrainzId = mappedAlbum.ForeignBookId; report.EditionGoodreadsId = mappedAlbum.Editions.Value.Single(x => x.Monitored).ForeignEditionId;
report.BookGoodreadsId = mappedAlbum.ForeignBookId;
report.Book = mappedAlbum.Title; report.Book = mappedAlbum.Title;
report.Author = mappedAlbum.AuthorMetadata?.Value?.Name; report.Author = mappedAlbum.AuthorMetadata?.Value?.Name;
report.ArtistMusicBrainzId = mappedAlbum.AuthorMetadata?.Value?.ForeignAuthorId; report.AuthorGoodreadsId = mappedAlbum.AuthorMetadata?.Value?.ForeignAuthorId;
} }
private void ProcessAlbumReport(ImportListDefinition importList, ImportListItemInfo report, List<ImportListExclusion> listExclusions, List<Book> albumsToAdd) private void ProcessAlbumReport(ImportListDefinition importList, ImportListItemInfo report, List<ImportListExclusion> listExclusions, List<Book> albumsToAdd)
{ {
if (report.AlbumMusicBrainzId == null) if (report.EditionGoodreadsId == null)
{ {
return; return;
} }
// Check to see if book in DB // Check to see if book in DB
var existingAlbum = _bookService.FindById(report.AlbumMusicBrainzId); var existingAlbum = _bookService.FindById(report.EditionGoodreadsId);
if (existingAlbum != null) if (existingAlbum != null)
{ {
_logger.Debug("{0} [{1}] Rejected, Book Exists in DB", report.AlbumMusicBrainzId, report.Book); _logger.Debug("{0} [{1}] Rejected, Book Exists in DB", report.EditionGoodreadsId, report.Book);
return; return;
} }
// Check to see if book excluded // Check to see if book excluded
var excludedAlbum = listExclusions.SingleOrDefault(s => s.ForeignId == report.AlbumMusicBrainzId); var excludedAlbum = listExclusions.SingleOrDefault(s => s.ForeignId == report.EditionGoodreadsId);
if (excludedAlbum != null) if (excludedAlbum != null)
{ {
_logger.Debug("{0} [{1}] Rejected due to list exlcusion", report.AlbumMusicBrainzId, report.Book); _logger.Debug("{0} [{1}] Rejected due to list exlcusion", report.EditionGoodreadsId, report.Book);
return; return;
} }
// Check to see if author excluded // Check to see if author excluded
var excludedArtist = listExclusions.SingleOrDefault(s => s.ForeignId == report.ArtistMusicBrainzId); var excludedArtist = listExclusions.SingleOrDefault(s => s.ForeignId == report.AuthorGoodreadsId);
if (excludedArtist != null) if (excludedArtist != null)
{ {
_logger.Debug("{0} [{1}] Rejected due to list exlcusion for parent author", report.AlbumMusicBrainzId, report.Book); _logger.Debug("{0} [{1}] Rejected due to list exlcusion for parent author", report.EditionGoodreadsId, report.Book);
return; return;
} }
// Append Album if not already in DB or already on add list // Append Album if not already in DB or already on add list
if (albumsToAdd.All(s => s.ForeignBookId != report.AlbumMusicBrainzId)) if (albumsToAdd.All(s => s.ForeignBookId != report.EditionGoodreadsId))
{ {
var monitored = importList.ShouldMonitor != ImportListMonitorType.None; var monitored = importList.ShouldMonitor != ImportListMonitorType.None;
var toAdd = new Book var toAdd = new Book
{ {
ForeignBookId = report.AlbumMusicBrainzId, ForeignBookId = report.BookGoodreadsId,
Monitored = monitored, Monitored = monitored,
Editions = new List<Edition>
{
new Edition
{
ForeignEditionId = report.EditionGoodreadsId,
Monitored = true
}
},
Author = new Author Author = new Author
{ {
Monitored = monitored, Monitored = monitored,
@ -234,37 +244,37 @@ namespace NzbDrone.Core.ImportLists
{ {
var mappedArtist = _authorSearchService.SearchForNewAuthor(report.Author) var mappedArtist = _authorSearchService.SearchForNewAuthor(report.Author)
.FirstOrDefault(); .FirstOrDefault();
report.ArtistMusicBrainzId = mappedArtist?.Metadata.Value?.ForeignAuthorId; report.AuthorGoodreadsId = mappedArtist?.Metadata.Value?.ForeignAuthorId;
report.Author = mappedArtist?.Metadata.Value?.Name; report.Author = mappedArtist?.Metadata.Value?.Name;
} }
private void ProcessArtistReport(ImportListDefinition importList, ImportListItemInfo report, List<ImportListExclusion> listExclusions, List<Author> artistsToAdd) private void ProcessArtistReport(ImportListDefinition importList, ImportListItemInfo report, List<ImportListExclusion> listExclusions, List<Author> artistsToAdd)
{ {
if (report.ArtistMusicBrainzId == null) if (report.AuthorGoodreadsId == null)
{ {
return; return;
} }
// Check to see if author in DB // Check to see if author in DB
var existingArtist = _authorService.FindById(report.ArtistMusicBrainzId); var existingArtist = _authorService.FindById(report.AuthorGoodreadsId);
if (existingArtist != null) if (existingArtist != null)
{ {
_logger.Debug("{0} [{1}] Rejected, Author Exists in DB", report.ArtistMusicBrainzId, report.Author); _logger.Debug("{0} [{1}] Rejected, Author Exists in DB", report.AuthorGoodreadsId, report.Author);
return; return;
} }
// Check to see if author excluded // Check to see if author excluded
var excludedArtist = listExclusions.Where(s => s.ForeignId == report.ArtistMusicBrainzId).SingleOrDefault(); var excludedArtist = listExclusions.Where(s => s.ForeignId == report.AuthorGoodreadsId).SingleOrDefault();
if (excludedArtist != null) if (excludedArtist != null)
{ {
_logger.Debug("{0} [{1}] Rejected due to list exlcusion", report.ArtistMusicBrainzId, report.Author); _logger.Debug("{0} [{1}] Rejected due to list exlcusion", report.AuthorGoodreadsId, report.Author);
return; return;
} }
// Append Author if not already in DB or already on add list // Append Author if not already in DB or already on add list
if (artistsToAdd.All(s => s.Metadata.Value.ForeignAuthorId != report.ArtistMusicBrainzId)) if (artistsToAdd.All(s => s.Metadata.Value.ForeignAuthorId != report.AuthorGoodreadsId))
{ {
var monitored = importList.ShouldMonitor != ImportListMonitorType.None; var monitored = importList.ShouldMonitor != ImportListMonitorType.None;
@ -272,7 +282,7 @@ namespace NzbDrone.Core.ImportLists
{ {
Metadata = new AuthorMetadata Metadata = new AuthorMetadata
{ {
ForeignAuthorId = report.ArtistMusicBrainzId, ForeignAuthorId = report.AuthorGoodreadsId,
Name = report.Author Name = report.Author
}, },
Monitored = monitored, Monitored = monitored,

@ -36,7 +36,7 @@ namespace NzbDrone.Core.ImportLists.LazyLibrarianImport
{ {
Author = item.AuthorName, Author = item.AuthorName,
Book = item.BookName, Book = item.BookName,
AlbumMusicBrainzId = item.BookId EditionGoodreadsId = item.BookId
}); });
} }

@ -7,9 +7,10 @@ namespace NzbDrone.Core.Parser.Model
public int ImportListId { get; set; } public int ImportListId { get; set; }
public string ImportList { get; set; } public string ImportList { get; set; }
public string Author { get; set; } public string Author { get; set; }
public string ArtistMusicBrainzId { get; set; } public string AuthorGoodreadsId { get; set; }
public string Book { get; set; } public string Book { get; set; }
public string AlbumMusicBrainzId { get; set; } public string BookGoodreadsId { get; set; }
public string EditionGoodreadsId { get; set; }
public DateTime ReleaseDate { get; set; } public DateTime ReleaseDate { get; set; }
public override string ToString() public override string ToString()

Loading…
Cancel
Save