/// <summary> /// Searches for the next and previous books in a series, if it is part of one. /// Modifies curBook.previousInSeries to contain the found book info. /// </summary> /// <returns>Next book in series</returns> public override async Task <BookInfo> GetNextInSeries(BookInfo curBook, AuthorProfile authorProfile, string TLD) { BookInfo nextBook = null; if (curBook.dataUrl == "") { return(null); } if (sourceHtmlDoc == null) { sourceHtmlDoc = new HtmlDocument(); sourceHtmlDoc.LoadHtml(await HttpDownloader.GetPageHtmlAsync(curBook.dataUrl)); } // Get title of next book Dictionary <string, BookInfo> seriesInfo = await GetNextInSeriesTitle(curBook); if (seriesInfo.TryGetValue("Next", out var book)) { // TODO: next and previous sections are the same... // Search author's other books for the book (assumes next in series was written by the same author...) // Returns the first one found, though there should probably not be more than 1 of the same name anyway nextBook = authorProfile.otherBooks.FirstOrDefault(bk => Regex.IsMatch(bk.title, $@"^{book.title}(?: \(.*\))?$")); if (nextBook == null) { // Attempt to search Amazon for the book instead // TODO: This should be elsewhere try { if (!string.IsNullOrEmpty(book.asin)) { nextBook = book; await nextBook.GetAmazonInfo($"https://www.amazon.{TLD}/dp/{book.asin}"); } else { nextBook = await Amazon.SearchBook(book.title, book.author, TLD); } if (nextBook == null && settings.promptASIN) { Logger.Log($"ASIN prompt for {book.title}..."); nextBook = new BookInfo(book.title, book.author, ""); frmAS.Text = "Next in Series"; frmAS.lblTitle.Text = book.title; frmAS.tbAsin.Text = ""; frmAS.ShowDialog(); Logger.Log($"ASIN supplied: {frmAS.tbAsin.Text}"); string Url = $"https://www.amazon.{TLD}/dp/{frmAS.tbAsin.Text}"; await nextBook.GetAmazonInfo(Url); nextBook.amazonUrl = Url; nextBook.asin = frmAS.tbAsin.Text; } } catch { Logger.Log($"Failed to find {book.title} on Amazon.{TLD}, trying again with Amazon.com."); TLD = "com"; nextBook = await Amazon.SearchBook(book.title, book.author, TLD); } if (nextBook != null) { await nextBook.GetAmazonInfo(nextBook.amazonUrl); //fill in desc, imageurl, and ratings } } if (nextBook == null) { Logger.Log("Book was found to be part of a series, but an error occurred finding the next book.\r\n" + "Please report this book and the Goodreads URL and output log to improve parsing (if it's a real book)."); } } else if (curBook.totalInSeries == 0) { Logger.Log("The book was not found to be part of a series."); } else if (curBook.seriesPosition != curBook.totalInSeries.ToString() && !curBook.seriesPosition?.Contains(".") == true) { Logger.Log("An error occurred finding the next book in series. The book may not be part of a series, or it is the latest release."); } if (seriesInfo.TryGetValue("Previous", out book)) { var prevBook = authorProfile.otherBooks.FirstOrDefault(bk => Regex.IsMatch(bk.title, $@"^{book.title}(?: \(.*\))?$")); if (book.asin != null) { prevBook = book; await prevBook.GetAmazonInfo($"https://www.amazon.{TLD}/dp/{book.asin}"); } else if (prevBook != null) { await prevBook.GetAmazonInfo(prevBook.amazonUrl); } if (prevBook == null && settings.promptASIN) { Logger.Log($"ASIN prompt for {book.title}..."); prevBook = new BookInfo(book.title, book.author, ""); frmAS.Text = "Previous in Series"; frmAS.lblTitle.Text = book.title; frmAS.tbAsin.Text = ""; frmAS.ShowDialog(); Logger.Log($"ASIN supplied: {frmAS.tbAsin.Text}"); string Url = $"https://www.amazon.{TLD}/dp/{frmAS.tbAsin.Text}"; await prevBook.GetAmazonInfo(Url); prevBook.amazonUrl = Url; prevBook.asin = frmAS.tbAsin.Text; } if (prevBook == null) { Logger.Log("Book was found to be part of a series, but an error occurred finding the previous book.\r\n" + "Please report this book and the Goodreads URL and output log to improve parsing."); } } return(nextBook); }
public override async Task <BookInfo> GetNextInSeries(BookInfo curBook, AuthorProfile authorProfile, string TLD) { BookInfo nextBook = null; if (curBook.dataUrl == "") { return(null); } if (sourceHtmlDoc == null) { sourceHtmlDoc = new HtmlDocument(); sourceHtmlDoc.LoadHtml(await HttpDownloader.GetPageHtmlAsync(curBook.dataUrl)); } // Get title of next book Dictionary <string, string> seriesInfo = await GetNextInSeriesTitle(curBook).ConfigureAwait(false); if (seriesInfo.TryGetValue("Next", out var title)) { // Search author's other books for the book (assumes next in series was written by the same author...) // Returns the first one found, though there should probably not be more than 1 of the same name anyway nextBook = authorProfile.otherBooks.FirstOrDefault(bk => bk.title == title); if (nextBook == null) { // Attempt to search Amazon for the book instead nextBook = await Amazon.SearchBook(title, curBook.author, TLD); if (nextBook != null) { await nextBook.GetAmazonInfo(nextBook.amazonUrl); //fill in desc, imageurl, and ratings } } // Try to fill in desc, imageurl, and ratings using Shelfari Kindle edition link instead if (nextBook == null) { HtmlDocument bookDoc = new HtmlDocument { OptionAutoCloseOnEnd = true }; bookDoc.LoadHtml(await HttpDownloader.GetPageHtmlAsync(seriesInfo["NextURL"])); Match match = Regex.Match(bookDoc.DocumentNode.InnerHtml, "('B[A-Z0-9]{9}')"); if (match.Success) { string cleanASIN = match.Value.Replace("'", String.Empty); nextBook = new BookInfo(title, curBook.author, cleanASIN); await nextBook.GetAmazonInfo("http://www.amazon.com/dp/" + cleanASIN); } } if (nextBook == null) { Logger.Log("Book was found to be part of a series, but an error occured finding the next book.\r\n" + "Please report this book and the Shelfari URL and output log to improve parsing."); } } else if (curBook.seriesPosition != curBook.totalInSeries.ToString()) { Logger.Log("An error occured finding the next book in series, the book may not be part of a series, or it is the latest release."); } if (seriesInfo.TryGetValue("Previous", out title)) { if (curBook.previousInSeries == null) { // Attempt to search Amazon for the book curBook.previousInSeries = await Amazon.SearchBook(title, curBook.author, TLD); if (curBook.previousInSeries != null) { await curBook.previousInSeries.GetAmazonInfo(curBook.previousInSeries.amazonUrl); //fill in desc, imageurl, and ratings } // Try to fill in desc, imageurl, and ratings using Shelfari Kindle edition link instead if (curBook.previousInSeries == null) { HtmlDocument bookDoc = new HtmlDocument() { OptionAutoCloseOnEnd = true }; bookDoc.LoadHtml(await HttpDownloader.GetPageHtmlAsync(seriesInfo["PreviousURL"])); Match match = Regex.Match(bookDoc.DocumentNode.InnerHtml, "('B[A-Z0-9]{9}')"); if (match.Success) { string cleanASIN = match.Value.Replace("'", String.Empty); curBook.previousInSeries = new BookInfo(title, curBook.author, cleanASIN); await curBook.previousInSeries.GetAmazonInfo("http://www.amazon.com/dp/" + cleanASIN); } } } else { Logger.Log("Book was found to be part of a series, but an error occured finding the next book.\r\n" + "Please report this book and the Shelfari URL and output log to improve parsing."); } } return(nextBook); }