using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Xml.Linq;
namespace NzbDrone.Core.MetadataSource.Goodreads
{
///
/// This class models a single book as defined by the Goodreads API.
///
[DebuggerDisplay("{DebuggerDisplay,nq}")]
public sealed class BookResource : GoodreadsResource
{
public override string ElementName => "book";
///
/// The Goodreads Id for this book.
///
public long Id { get; private set; }
///
/// The title of this book.
///
public string Title { get; private set; }
public string TitleWithoutSeries { get; private set; }
///
/// The description of this book.
///
public string Description { get; private set; }
///
/// The ISBN of this book.
///
public string Isbn { get; private set; }
///
/// The ISBN13 of this book.
///
public string Isbn13 { get; private set; }
///
/// The ASIN of this book.
///
public string Asin { get; private set; }
///
/// The Kindle ASIN of this book.
///
public string KindleAsin { get; private set; }
///
/// The marketplace Id of this book.
///
public string MarketplaceId { get; private set; }
///
/// The country code of this book.
///
public string CountryCode { get; private set; }
///
/// The cover image for this book.
///
public string ImageUrl { get; private set; }
///
/// The date this book was published.
///
public DateTime? PublicationDate { get; private set; }
///
/// The publisher of this book.
///
public string Publisher { get; private set; }
///
/// The language code of this book.
///
public string LanguageCode { get; private set; }
///
/// Signifies if this is an eBook or not.
///
public bool IsEbook { get; private set; }
///
/// The average rating of this book by Goodreads users.
///
public decimal AverageRating { get; private set; }
///
/// The number of pages in this book.
///
public int Pages { get; private set; }
///
/// The format of this book.
///
public string Format { get; private set; }
///
/// Brief information about this edition of the book.
///
public string EditionInformation { get; private set; }
///
/// The count of all Goodreads ratings for this book.
///
public int RatingsCount { get; private set; }
///
/// The count of all reviews that contain text for this book.
///
public int TextReviewsCount { get; private set; }
///
/// The Goodreads Url for this book.
///
public string Url { get; private set; }
public string EditionsUrl { get; private set; }
///
/// The aggregate information for this work across all editions of the book.
///
public WorkResource Work { get; private set; }
///
/// The list of authors that worked on this book.
///
public IReadOnlyList Authors { get; private set; }
///
/// HTML and CSS for the Goodreads iFrame. Used to display the reviews for this book.
///
public string ReviewsWidget { get; private set; }
///
/// The most popular shelf names this book appears on. This is a
/// dictionary of shelf name -> count.
///
public IReadOnlyDictionary PopularShelves { get; private set; }
///
/// The list of book links tracked by Goodreads.
/// This is usually a list of libraries that the user can borrow the book from.
///
public IReadOnlyList BookLinks { get; private set; }
///
/// The list of buy links tracked by Goodreads.
/// This is usually a list of third-party sites that the
/// user can purchase the book from.
///
public IReadOnlyList BuyLinks { get; private set; }
///
/// Summary information about similar books to this one.
///
public IReadOnlyList SimilarBooks { get; private set; }
// TODO: parse series information once I get a better sense
// of what series are from the other API calls.
//// public List Series { get; private set; }
public override void Parse(XElement element)
{
Id = element.ElementAsLong("id");
Title = element.ElementAsString("title");
TitleWithoutSeries = element.ElementAsString("title_without_series");
Isbn = element.ElementAsString("isbn");
Isbn13 = element.ElementAsString("isbn13");
Asin = element.ElementAsString("asin");
KindleAsin = element.ElementAsString("kindle_asin");
MarketplaceId = element.ElementAsString("marketplace_id");
CountryCode = element.ElementAsString("country_code");
ImageUrl = element.ElementAsString("large_image_url") ??
element.ElementAsString("image_url") ??
element.ElementAsString("small_image_url");
PublicationDate = element.ElementAsMultiDateField("publication");
Publisher = element.ElementAsString("publisher");
LanguageCode = element.ElementAsString("language_code");
IsEbook = element.ElementAsBool("is_ebook");
Description = element.ElementAsString("description");
AverageRating = element.ElementAsDecimal("average_rating");
Pages = element.ElementAsInt("num_pages");
Format = element.ElementAsString("format");
EditionInformation = element.ElementAsString("edition_information");
RatingsCount = element.ElementAsInt("ratings_count");
TextReviewsCount = element.ElementAsInt("text_reviews_count");
Url = element.ElementAsString("link");
EditionsUrl = element.ElementAsString("editions_url");
ReviewsWidget = element.ElementAsString("reviews_widget");
var workElement = element.Element("work");
if (workElement != null)
{
Work = new WorkResource();
Work.Parse(workElement);
}
Authors = element.ParseChildren("authors", "author");
SimilarBooks = element.ParseChildren("similar_books", "book");
var bookLinks = element.ParseChildren("book_links", "book_link");
if (bookLinks != null)
{
bookLinks.ForEach(x => x.FixBookLink(Id));
BookLinks = bookLinks;
}
var buyLinks = element.ParseChildren("buy_links", "buy_link");
if (buyLinks != null)
{
buyLinks.ForEach(x => x.FixBookLink(Id));
BuyLinks = buyLinks;
}
var shelves = element.ParseChildren(
"popular_shelves",
"shelf",
(shelfElement) =>
{
var shelfName = shelfElement?.Attribute("name")?.Value;
var shelfCountValue = shelfElement?.Attribute("count")?.Value;
int.TryParse(shelfCountValue, out var shelfCount);
return new KeyValuePair(shelfName, shelfCount);
});
if (shelves != null)
{
PopularShelves = shelves.GroupBy(obj => obj.Key).ToDictionary(shelf => shelf.Key, shelf => shelf.Sum(x => x.Value));
}
}
}
}