コード例 #1
0
        // 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);
        }
コード例 #2
0
        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));
                }
            }
        }
コード例 #3
0
        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);
                }
            }
        }