private IEnumerable <DownloadDecision> GetBookDecisions(List <ReleaseInfo> reports, SearchCriteriaBase searchCriteria = null) { if (reports.Any()) { _logger.ProgressInfo("Processing {0} releases", reports.Count); } else { _logger.ProgressInfo("No results found"); } var reportNumber = 1; foreach (var report in reports) { DownloadDecision decision = null; _logger.ProgressTrace("Processing release {0}/{1}", reportNumber, reports.Count); _logger.Debug("Processing release '{0}' from '{1}'", report.Title, report.Indexer); try { var parsedBookInfo = Parser.Parser.ParseBookTitle(report.Title); if (parsedBookInfo == null) { if (searchCriteria != null) { parsedBookInfo = Parser.Parser.ParseBookTitleWithSearchCriteria(report.Title, searchCriteria.Author, searchCriteria.Books); } else { // try parsing fuzzy parsedBookInfo = _parsingService.ParseBookTitleFuzzy(report.Title); } } if (parsedBookInfo != null && !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) { _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.Release = report; // parse quality again with title and category if unknown if (remoteBook.ParsedBookInfo.Quality.Quality == Quality.Unknown) { remoteBook.ParsedBookInfo.Quality = QualityParser.ParseQuality(report.Title, null, report.Categories); } 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) { remoteBook.Author = searchCriteria.Author; remoteBook.Books = searchCriteria.Books; } } else if (remoteBook.Books.Empty()) { decision = new DownloadDecision(remoteBook, new Rejection("Unable to parse books from release name")); if (searchCriteria != null) { remoteBook.Books = searchCriteria.Books; } } else { _aggregationService.Augment(remoteBook); remoteBook.DownloadAllowed = remoteBook.Books.Any(); decision = GetDecisionForReport(remoteBook, searchCriteria); } } if (searchCriteria != null) { if (parsedBookInfo == null) { parsedBookInfo = new ParsedBookInfo { Quality = QualityParser.ParseQuality(report.Title, null, report.Categories) }; } if (parsedBookInfo.AuthorName.IsNullOrWhiteSpace()) { var remoteBook = new RemoteBook { Release = report, ParsedBookInfo = parsedBookInfo }; decision = new DownloadDecision(remoteBook, new Rejection("Unable to parse release")); } } if (searchCriteria != null) { if (parsedBookInfo == null) { parsedBookInfo = new ParsedBookInfo { Quality = QualityParser.ParseQuality(report.Title, null, report.Categories) }; } if (parsedBookInfo.AuthorName.IsNullOrWhiteSpace()) { var remoteBook = new RemoteBook { Release = report, ParsedBookInfo = parsedBookInfo }; decision = new DownloadDecision(remoteBook, new Rejection("Unable to parse release")); } } } catch (Exception e) { _logger.Error(e, "Couldn't process release."); var remoteBook = new RemoteBook { Release = report }; decision = new DownloadDecision(remoteBook, new Rejection("Unexpected error processing release")); } reportNumber++; if (decision != null) { if (decision.Rejections.Any()) { _logger.Debug("Release rejected for the following reasons: {0}", string.Join(", ", decision.Rejections)); } else { _logger.Debug("Release accepted"); } yield return(decision); } } }