From 086e3b32409b024a3a0297db2d270a68499e111a Mon Sep 17 00:00:00 2001 From: Qstick Date: Fri, 9 Oct 2020 21:47:27 -0400 Subject: [PATCH] Fixed: Don't Crash on Manual Grabs --- .../DecisionEngine/DownloadDecisionMaker.cs | 89 +++++++++++-------- src/Readarr.Api.V1/Indexers/ReleaseModule.cs | 64 ++++++++++++- 2 files changed, 114 insertions(+), 39 deletions(-) diff --git a/src/NzbDrone.Core/DecisionEngine/DownloadDecisionMaker.cs b/src/NzbDrone.Core/DecisionEngine/DownloadDecisionMaker.cs index 480669754..8c3c8dd99 100644 --- a/src/NzbDrone.Core/DecisionEngine/DownloadDecisionMaker.cs +++ b/src/NzbDrone.Core/DecisionEngine/DownloadDecisionMaker.cs @@ -85,53 +85,72 @@ namespace NzbDrone.Core.DecisionEngine } } - if (parsedBookInfo != null) + if (parsedBookInfo != null && !parsedBookInfo.AuthorName.IsNullOrWhiteSpace()) { - if (!parsedBookInfo.AuthorName.IsNullOrWhiteSpace()) + var remoteBook = _parsingService.Map(parsedBookInfo, searchCriteria); + + // try parsing again using the search criteria, in case it parsed but parsed incorrectly + if ((remoteBook.Author == null || remoteBook.Books.Empty()) && searchCriteria != null) { - var remoteBook = _parsingService.Map(parsedBookInfo, searchCriteria); + _logger.Debug("Author/Book null for {0}, reparsing with search criteria", report.Title); + var parsedBookInfoWithCriteria = Parser.Parser.ParseBookTitleWithSearchCriteria(report.Title, + searchCriteria.Author, + searchCriteria.Books); - // try parsing again using the search criteria, in case it parsed but parsed incorrectly - if ((remoteBook.Author == null || remoteBook.Books.Empty()) && searchCriteria != null) + if (parsedBookInfoWithCriteria != null && parsedBookInfoWithCriteria.AuthorName.IsNotNullOrWhiteSpace()) { - _logger.Debug("Author/Book null for {0}, reparsing with search criteria", report.Title); - var parsedBookInfoWithCriteria = Parser.Parser.ParseBookTitleWithSearchCriteria(report.Title, - searchCriteria.Author, - searchCriteria.Books); - - if (parsedBookInfoWithCriteria != null && parsedBookInfoWithCriteria.AuthorName.IsNotNullOrWhiteSpace()) - { - remoteBook = _parsingService.Map(parsedBookInfoWithCriteria, searchCriteria); - } + remoteBook = _parsingService.Map(parsedBookInfoWithCriteria, searchCriteria); } + } - remoteBook.Release = report; + remoteBook.Release = report; - if (remoteBook.Author == null) + if (remoteBook.Author == null) + { + decision = new DownloadDecision(remoteBook, new Rejection("Unknown Author")); + + // shove in the searched author in case of forced download in interactive search + if (searchCriteria != null) { - decision = new DownloadDecision(remoteBook, new Rejection("Unknown Author")); - - // shove in the searched author in case of forced download in interactive search - if (searchCriteria != null) - { - remoteBook.Author = searchCriteria.Author; - remoteBook.Books = searchCriteria.Books; - } + remoteBook.Author = searchCriteria.Author; + remoteBook.Books = searchCriteria.Books; } - else if (remoteBook.Books.Empty()) + } + else if (remoteBook.Books.Empty()) + { + decision = new DownloadDecision(remoteBook, new Rejection("Unable to parse books from release name")); + if (searchCriteria != null) { - decision = new DownloadDecision(remoteBook, new Rejection("Unable to parse books from release name")); - if (searchCriteria != null) - { - remoteBook.Books = searchCriteria.Books; - } + remoteBook.Books = searchCriteria.Books; } - else + } + else + { + _aggregationService.Augment(remoteBook); + remoteBook.DownloadAllowed = remoteBook.Books.Any(); + decision = GetDecisionForReport(remoteBook, searchCriteria); + } + } + + if (searchCriteria != null) + { + if (parsedBookInfo == null) + { + parsedBookInfo = new ParsedBookInfo { - _aggregationService.Augment(remoteBook); - remoteBook.DownloadAllowed = remoteBook.Books.Any(); - decision = GetDecisionForReport(remoteBook, searchCriteria); - } + Quality = QualityParser.ParseQuality(report.Title) + }; + } + + if (parsedBookInfo.AuthorName.IsNullOrWhiteSpace()) + { + var remoteBook = new RemoteBook + { + Release = report, + ParsedBookInfo = parsedBookInfo + }; + + decision = new DownloadDecision(remoteBook, new Rejection("Unable to parse release")); } } } diff --git a/src/Readarr.Api.V1/Indexers/ReleaseModule.cs b/src/Readarr.Api.V1/Indexers/ReleaseModule.cs index 365b478fd..ac0991b56 100644 --- a/src/Readarr.Api.V1/Indexers/ReleaseModule.cs +++ b/src/Readarr.Api.V1/Indexers/ReleaseModule.cs @@ -4,11 +4,14 @@ using FluentValidation; using Nancy; using NLog; using NzbDrone.Common.Cache; +using NzbDrone.Common.Extensions; +using NzbDrone.Core.Books; using NzbDrone.Core.DecisionEngine; using NzbDrone.Core.Download; using NzbDrone.Core.Exceptions; using NzbDrone.Core.Indexers; using NzbDrone.Core.IndexerSearch; +using NzbDrone.Core.Parser; using NzbDrone.Core.Parser.Model; using NzbDrone.Core.Validation; using HttpStatusCode = System.Net.HttpStatusCode; @@ -22,6 +25,9 @@ namespace Readarr.Api.V1.Indexers private readonly IMakeDownloadDecision _downloadDecisionMaker; private readonly IPrioritizeDownloadDecision _prioritizeDownloadDecision; private readonly IDownloadService _downloadService; + private readonly IAuthorService _authorService; + private readonly IBookService _bookService; + private readonly IParsingService _parsingService; private readonly Logger _logger; private readonly ICached _remoteBookCache; @@ -31,6 +37,9 @@ namespace Readarr.Api.V1.Indexers IMakeDownloadDecision downloadDecisionMaker, IPrioritizeDownloadDecision prioritizeDownloadDecision, IDownloadService downloadService, + IAuthorService authorService, + IBookService bookService, + IParsingService parsingService, ICacheManager cacheManager, Logger logger) { @@ -39,6 +48,9 @@ namespace Readarr.Api.V1.Indexers _downloadDecisionMaker = downloadDecisionMaker; _prioritizeDownloadDecision = prioritizeDownloadDecision; _downloadService = downloadService; + _authorService = authorService; + _bookService = bookService; + _parsingService = parsingService; _logger = logger; GetResourceAll = GetReleases; @@ -63,6 +75,52 @@ namespace Readarr.Api.V1.Indexers try { + if (remoteBook.Author == null) + { + if (release.BookId.HasValue) + { + var book = _bookService.GetBook(release.BookId.Value); + + remoteBook.Author = _authorService.GetAuthor(book.AuthorId); + remoteBook.Books = new List { book }; + } + else if (release.AuthorId.HasValue) + { + var author = _authorService.GetAuthor(release.AuthorId.Value); + var books = _parsingService.GetAlbums(remoteBook.ParsedBookInfo, author); + + if (books.Empty()) + { + throw new NzbDroneClientException(HttpStatusCode.NotFound, "Unable to parse books in the release"); + } + + remoteBook.Author = author; + remoteBook.Books = books; + } + else + { + throw new NzbDroneClientException(HttpStatusCode.NotFound, "Unable to find matching author and books"); + } + } + else if (remoteBook.Books.Empty()) + { + var books = _parsingService.GetAlbums(remoteBook.ParsedBookInfo, remoteBook.Author); + + if (books.Empty() && release.BookId.HasValue) + { + var book = _bookService.GetBook(release.BookId.Value); + + books = new List { book }; + } + + remoteBook.Books = books; + } + + if (remoteBook.Books.Empty()) + { + throw new NzbDroneClientException(HttpStatusCode.NotFound, "Unable to parse books in the release"); + } + _downloadService.DownloadReport(remoteBook); } catch (ReleaseDownloadException ex) @@ -101,9 +159,8 @@ namespace Readarr.Api.V1.Indexers catch (Exception ex) { _logger.Error(ex, "Book search failed"); + throw new NzbDroneClientException(HttpStatusCode.InternalServerError, ex.Message); } - - return new List(); } private List GetAuthorReleases(int authorId) @@ -118,9 +175,8 @@ namespace Readarr.Api.V1.Indexers catch (Exception ex) { _logger.Error(ex, "Author search failed"); + throw new NzbDroneClientException(HttpStatusCode.InternalServerError, ex.Message); } - - return new List(); } private List GetRss()