// TODO: Review this... public async Task <bool> Generate() { string outputDir; try { if (_settings.Android) { outputDir = _settings.OutDir + @"\Android\" + _curBook.asin; Directory.CreateDirectory(outputDir); } else { outputDir = _settings.UseSubDirectories ? Functions.GetBookOutputDirectory(_curBook.author, _curBook.sidecarName, true) : _settings.OutDir; } } catch (Exception ex) { Logger.Log("An error occurred creating output directory: " + ex.Message + "\r\nFiles will be placed in the default output directory."); outputDir = _settings.OutDir; } string ApPath = outputDir + @"\AuthorProfile.profile." + _curBook.asin + ".asc"; if (!Properties.Settings.Default.overwrite && File.Exists(ApPath)) { Logger.Log("AuthorProfile file already exists... Skipping!\r\n" + "Please review the settings page if you want to overwite any existing files."); return(false); } DataSources.AuthorSearchResults searchResults = null; // Attempt to download from the alternate site, if present. If it fails in some way, try .com // If the .com search crashes, it will crash back to the caller in frmMain try { searchResults = await DataSources.Amazon.SearchAuthor(_curBook, _settings.AmazonTld); } catch (Exception ex) { Logger.Log("Error searching Amazon." + _settings.AmazonTld + ": " + ex.Message + "\r\n" + ex.StackTrace); } finally { if (searchResults == null) { Logger.Log(String.Format("Failed to find {0} on Amazon." + _settings.AmazonTld, _curBook.author)); if (_settings.AmazonTld != "com") { Logger.Log("Trying again with Amazon.com."); _settings.AmazonTld = "com"; searchResults = await DataSources.Amazon.SearchAuthor(_curBook, _settings.AmazonTld); } } } if (searchResults == null) { return(false); // Already logged error in search function } authorAsin = searchResults.authorAsin; if (Properties.Settings.Default.saveHtml) { try { Logger.Log("Saving author's Amazon webpage..."); File.WriteAllText(Environment.CurrentDirectory + String.Format(@"\dmp\{0}.authorpageHtml.txt", _curBook.asin), searchResults.authorHtmlDoc.DocumentNode.InnerHtml); } catch (Exception ex) { Logger.Log(String.Format("An error occurred saving authorpageHtml.txt: {0}", ex.Message)); } } // Try to find author's biography string bioFile = Environment.CurrentDirectory + @"\ext\" + authorAsin + ".bio"; if (_settings.SaveBio && File.Exists(bioFile)) { if (!readBio(bioFile)) { return(false); } } if (BioTrimmed == "") { // TODO: Let users edit bio in same style as chapters and aliases HtmlNode bio = DataSources.Amazon.GetBioNode(searchResults, _settings.AmazonTld); //Trim authour biography to less than 1000 characters and/or replace more problematic characters. if (bio?.InnerText.Trim().Length > 0) { if (bio.InnerText.Length > 1000) { int lastPunc = bio.InnerText.LastIndexOfAny(new [] { '.', '!', '?' }); int lastSpace = bio.InnerText.LastIndexOf(' '); if (lastPunc > lastSpace) { BioTrimmed = bio.InnerText.Substring(0, lastPunc + 1); } else { BioTrimmed = bio.InnerText.Substring(0, lastSpace) + '\u2026'; } } else { BioTrimmed = bio.InnerText; } BioTrimmed = BioTrimmed.Clean(); Logger.Log("Author biography found on Amazon!"); } } else { File.WriteAllText(bioFile, String.Empty); if (System.Windows.Forms.DialogResult.Yes == System.Windows.Forms.MessageBox.Show( "No author biography found on Amazon!\r\nWould you like to create a biography?", "Biography", System.Windows.Forms.MessageBoxButtons.YesNo, System.Windows.Forms.MessageBoxIcon.Question, System.Windows.Forms.MessageBoxDefaultButton.Button2)) { Functions.RunNotepad(bioFile); if (!readBio(bioFile)) { return(false); } } else { BioTrimmed = "No author biography found on Amazon!"; Logger.Log("An error occurred finding the author biography on Amazon."); } } if (_settings.SaveBio) { if (!File.Exists(bioFile)) { try { Logger.Log("Saving biography to " + bioFile); using (var streamWriter = new StreamWriter(bioFile, false, System.Text.Encoding.UTF8)) { streamWriter.Write(BioTrimmed); } } catch (Exception ex) { Logger.Log("An error occurred while writing biography.\r\n" + ex.Message + "\r\n" + ex.StackTrace); return(false); } } if (System.Windows.Forms.DialogResult.Yes == System.Windows.Forms.MessageBox.Show("Would you like to open the biography file in notepad for editing?", "Biography", System.Windows.Forms.MessageBoxButtons.YesNo, System.Windows.Forms.MessageBoxIcon.Question, System.Windows.Forms.MessageBoxDefaultButton.Button2)) { Functions.RunNotepad(bioFile); if (!readBio(bioFile)) { return(false); } } } // Try to download Author image HtmlNode imageXpath = DataSources.Amazon.GetAuthorImageNode(searchResults, _settings.AmazonTld); authorImageUrl = Regex.Replace(imageXpath.GetAttributeValue("src", ""), @"_.*?_\.", string.Empty); // cleanup to match retail file image links if (authorImageUrl.Contains(@"https://images-na.ssl-images-amazon")) { authorImageUrl = authorImageUrl.Replace(@"https://images-na.ssl-images-amazon", @"http://ecx.images-amazon"); } _curBook.authorImageUrl = authorImageUrl; Bitmap ApAuthorImage; try { Logger.Log("Downloading author image..."); ApAuthorImage = await HttpDownloader.GetImage(authorImageUrl); Logger.Log("Grayscale base64-encoded author image created!"); } catch (Exception ex) { Logger.Log(String.Format("An error occurred downloading the author image: {0}", ex.Message)); return(false); } Logger.Log("Gathering author's other books..."); var bookList = DataSources.Amazon.GetAuthorBooks(searchResults, _curBook.title, _curBook.author, _settings.AmazonTld) ?? DataSources.Amazon.GetAuthorBooksNew(searchResults, _curBook.title, _curBook.author, _settings.AmazonTld); if (bookList != null) { Logger.Log("Gathering metadata for other books..."); var bookBag = new ConcurrentBag <BookInfo>(); await bookList.ParallelForEachAsync(async book => { // TODO: retry a couple times if one fails maybe try { //Gather book desc, image url, etc, if using new format if (_settings.UseNewVersion) { await book.GetAmazonInfo(book.amazonUrl); } bookBag.Add(book); } catch (Exception ex) { Logger.Log(String.Format("An error occurred gathering metadata for other books: {0}\r\nURL: {1}\r\nBook: {2}", ex.Message, book.amazonUrl, book.title)); throw; } }); otherBooks.AddRange(bookBag); } else { Logger.Log("Unable to find other books by this author. If there should be some, check the Amazon URL to ensure it is correct."); } Logger.Log("Writing Author Profile to file..."); var authorOtherBooks = otherBooks.Select(book => new Model.AuthorProfile.Book { E = 1, Asin = book.asin, Title = book.title }).ToArray(); var ap = new Model.AuthorProfile { Asin = _curBook.asin, CreationDate = Functions.UnixTimestampSeconds(), OtherBooks = authorOtherBooks, Authors = new [] { new Model.AuthorProfile.Author { Asin = authorAsin, Bio = BioTrimmed, ImageHeight = ApAuthorImage.Height, Name = _curBook.author, OtherBookAsins = otherBooks.Select(book => book.asin).ToArray(), Picture = Functions.ImageToBase64(ApAuthorImage, ImageFormat.Jpeg) } } }; string authorProfileOutput = JsonConvert.SerializeObject(ap); try { File.WriteAllText(ApPath, authorProfileOutput); Logger.Log("Author Profile file created successfully!\r\nSaved to " + ApPath); } catch (Exception ex) { Logger.Log("An error occurred while writing the Author Profile file: " + ex.Message + "\r\n" + ex.StackTrace); return(false); } ApTitle = "About " + _curBook.author; ApSubTitle = "Kindle Books By " + _curBook.author; EaSubTitle = "More Books By " + _curBook.author; return(true); }
public async Task Populate(string inputFile) { string input; using (StreamReader streamReader = new StreamReader(inputFile, Encoding.UTF8)) input = streamReader.ReadToEnd(); ilOtherBooks.Images.Clear(); dgvOtherBooks.Rows.Clear(); JObject sa = JObject.Parse(input); var tempData = sa["data"]["seriesPosition"]; if (tempData != null) { string position = tempData["positionInSeries"].ToString(); string total = tempData["totalInSeries"].ToString(); string name = tempData["seriesName"].ToString(); lblSeries.Text = $"This is book {position} of {total} in {name}"; if (position == "1") { pbPreviousCover.Visible = false; lblPreviousHeading.Visible = false; lblPreviousTitle.Visible = false; lblSeries.Left = 12; lblSeries.Width = 312; } else { lblSeries.Left = 80; lblSeries.Width = 244; pbPreviousCover.Visible = true; lblPreviousHeading.Visible = true; lblPreviousTitle.Visible = true; } } else { lblSeries.Text = "This book is not part of a series..."; pbPreviousCover.Image = Resources.missing_image; lblPreviousHeading.Visible = false; lblPreviousTitle.Visible = false; } tempData = sa["data"]["popularHighlightsText"]?["localizedText"]?["en-US"]; if (tempData != null) { Match popularHighlightsText = Regex.Match(tempData.ToString(), @"((\d+) passages have been highlighted (\d+) times)"); if (popularHighlightsText.Success) { lblHighlights.Text = popularHighlightsText.Groups[1].Value; } } tempData = sa["data"]["bookDescription"]; if (tempData != null) { lblTitle.Text = tempData["title"].ToString(); lblAuthor.Text = tempData["authors"][0].ToString(); titlePopup = lblAuthor.Text; lblDescription.Text = tempData["description"].ToString(); descriptionPopup = lblDescription.Text; Match rating = Regex.Match(tempData["amazonRating"].ToString(), @"(\d+)"); if (rating.Success) { pbRating.Image = (Image)Resources.ResourceManager.GetObject($"STAR{rating.Groups[1].Value}"); } lblVotes.Text = $"({tempData["numberOfReviews"]} votes)"; } tempData = sa["data"]["authorBios"]?["authors"]?[0]; if (tempData != null) { string imageUrl = tempData["imageUrl"]?.ToString() ?? ""; if (imageUrl != "") { pbAuthorImage.Image = Functions.MakeGrayscale3(await HttpDownloader.GetImage(imageUrl)); } lblBiography.Text = tempData["bio"]?.ToString(); biographyPopup = lblBiography.Text; } tempData = sa["data"]["authorRecs"]?["recommendations"]; if (tempData != null) { // TODO: Figure out why otherBooks is here but not used //var otherBooks = new List<Tuple<string, string, string, string>>(); foreach (var rec in tempData) { string imageUrl = rec["imageUrl"]?.ToString() ?? ""; string author = rec["authors"][0].ToString(); string title = rec["title"].ToString(); //otherBooks.Add(new Tuple<string, string, string, string>(rec["asin"].ToString(), title, author, imageUrl)); if (imageUrl != "") { ilOtherBooks.Images.Add(Functions.MakeGrayscale3(await HttpDownloader.GetImage(imageUrl))); } dgvOtherBooks.Rows.Add(ilOtherBooks.Images[ilOtherBooks.Images.Count - 1], $"{title}\n{author}"); } } tempData = sa["data"]["readingTime"]; if (tempData != null) { lblReadingTime.Text = $"{tempData["hours"]} hours and {tempData["minutes"]} minutes to read"; tempData = sa["data"]["readingPages"]; if (tempData != null) { lblReadingTime.Text = $"{lblReadingTime.Text} ({tempData["pagesInBook"]} pages)"; } } tempData = sa["data"]["previousBookInTheSeries"]; if (tempData != null) { lblPreviousTitle.Text = tempData["title"].ToString(); string imageUrl = tempData["imageUrl"]?.ToString() ?? ""; if (imageUrl != "") { pbPreviousCover.Image = Functions.MakeGrayscale3(await HttpDownloader.GetImage(imageUrl)); } } }
public async Task Populate(string inputFile) { string input; using (StreamReader streamReader = new StreamReader(inputFile, Encoding.UTF8)) input = streamReader.ReadToEnd(); ilauthorRecs.Images.Clear(); lvAuthorRecs.Items.Clear(); ilcustomersWhoBoughtRecs.Images.Clear(); lvCustomersWhoBoughtRecs.Items.Clear(); JObject ea = JObject.Parse(input); var tempData = ea["data"]["nextBook"]; if (tempData != null) { lblNextTitle.Text = tempData["title"].ToString(); lblNextAuthor.Text = tempData["authors"][0].ToString(); string imageUrl = tempData["imageUrl"]?.ToString(); if (!string.IsNullOrEmpty(imageUrl)) { pbNextCover.Image = Functions.MakeGrayscale3(await HttpDownloader.GetImage(imageUrl)); } } else { pbNextCover.Visible = false; lblNextTitle.Visible = false; lblNextAuthor.Visible = false; lblNotInSeries.Visible = true; } tempData = ea["data"]["authorRecs"]["recommendations"]; if (tempData != null) { foreach (var rec in tempData) { string imageUrl = rec["imageUrl"]?.ToString(); if (!string.IsNullOrEmpty(imageUrl)) { ilauthorRecs.Images.Add(Functions.MakeGrayscale3(await HttpDownloader.GetImage(imageUrl))); } } ListViewItem_SetSpacing(lvAuthorRecs, 60 + 7, 90 + 7); for (int i = 0; i < ilauthorRecs.Images.Count; i++) { ListViewItem item = new ListViewItem { ImageIndex = i }; lvAuthorRecs.Items.Add(item); } } tempData = ea["data"]["customersWhoBoughtRecs"]["recommendations"]; if (tempData != null) { foreach (var rec in tempData) { var imageUrl = rec["imageUrl"]?.ToString(); if (!string.IsNullOrEmpty(imageUrl)) { ilcustomersWhoBoughtRecs.Images.Add(Functions.MakeGrayscale3(await HttpDownloader.GetImage(imageUrl))); } } ListViewItem_SetSpacing(lvCustomersWhoBoughtRecs, 60 + 7, 90 + 7); for (int i = 0; i < ilcustomersWhoBoughtRecs.Images.Count; i++) { var item = new ListViewItem { ImageIndex = i }; lvCustomersWhoBoughtRecs.Items.Add(item); } } }