mirror of
https://github.com/fergalmoran/Readarr.git
synced 2025-12-28 04:17:31 +00:00
Fixed: Goodreads import lists
This commit is contained in:
@@ -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()
|
||||||
|
|||||||
Reference in New Issue
Block a user