class Alexandria::BookProviders::BarnesAndNobleProvider

Constants

BASE_ISBN_SEARCH_URL
BASE_SEARCH_URL
SITE

Public Class Methods

new() click to toggle source
Calls superclass method
# File lib/alexandria/book_providers/barnes_and_noble.rb, line 47
def initialize
  super("BarnesAndNoble", "BarnesAndNoble")
  @agent = nil
  prefs.read
end

Public Instance Methods

agent() click to toggle source
# File lib/alexandria/book_providers/barnes_and_noble.rb, line 53
def agent
  @agent ||= Alexandria::WWWAgent.new
  @agent
end
create_search_uri(search_type, search_term) click to toggle source
# File lib/alexandria/book_providers/barnes_and_noble.rb, line 102
def create_search_uri(search_type, search_term)
  (search_type_code = {
    SEARCH_BY_AUTHORS => "ATH",
    SEARCH_BY_TITLE   => "TTL",
    SEARCH_BY_KEYWORD => "WRD" # SEARCH_BY_PUBLISHER => 'PBL' # not implemented
  }[search_type]) || ""
  if search_type == SEARCH_BY_ISBN
    BASE_ISBN_SEARCH_URL % Library.canonicalise_ean(search_term) # isbn-13
  else
    search_term_encoded = CGI.escape(search_term)
    format(BASE_SEARCH_URL, search_type_code, search_term_encoded)
  end
end
fetch_redirectly(uri_str, limit = 5) click to toggle source
# File lib/alexandria/book_providers/barnes_and_noble.rb, line 58
def fetch_redirectly(uri_str, limit = 5)
  raise NoResultsError, _("HTTP redirect too deep") if limit.zero?

  if limit < 10
    sleep 0.1
    log.debug { "Redirectly :: #{uri_str}" }
  else
    log.debug { "Fetching   :: #{uri_str}" }
  end
  response = agent.get(uri_str)
  log.debug { response.inspect }
  case response
  when Net::HTTPSuccess then response
  when Net::HTTPRedirection
    redirect = URI.parse response["Location"]
    redirect = URI.parse(uri_str) + redirect if redirect.relative?
    fetch_redirectly(redirect.to_s, (limit - 1))
  else
    response.error!
  end
end
get_book_from_search_result(result) click to toggle source
# File lib/alexandria/book_providers/barnes_and_noble.rb, line 116
def get_book_from_search_result(result)
  log.debug { "Fetching book from #{result[:url]}" }
  html_data = transport.get_response(URI.parse(result[:url]))
  parse_result_data(html_data.body)
end
parse_result_data(html, _search_isbn = nil, _recursing = false) click to toggle source
# File lib/alexandria/book_providers/barnes_and_noble.rb, line 148
def parse_result_data(html, _search_isbn = nil, _recursing = false)
  doc = html_to_doc(html)
  begin
    book_data = {}

    dl = (doc / "dl").first
    dts = dl.children_of_type("dt")
    dts.each do |dt|
      value = dt.next_sibling.inner_text
      case dt.inner_text
      when /ISBN-13/
        book_data[:isbn] = Library.canonicalise_ean(value)
      when /Publisher/
        book_data[:publisher] = value
      when /Publication data/
        value =~ /\d{2}.\d{2}.(\d{4})/
        year = Regexp.last_match[1]
        book_data[:publisher] = year
      end
    end

    meta = doc / "meta"
    meta.each do |it|
      attrs = it.attributes
      property = attrs["property"]
      next unless property

      case property
      when "og:title"
        book_data[:title] = attrs["content"]
      when "og:image"
        book_data[:image_url] = attrs["content"]
      end
    end

    author_links = doc / "span.contributors a"
    authors = author_links.map(&:inner_text)
    book_data[:authors] = authors

    book_data[:binding] = ""
    selected_format = (doc / "#availableFormats li.selected a.tabTitle").first
    book_data[:binding] = selected_format.inner_text if selected_format

    book = Book.new(book_data[:title], book_data[:authors],
                    book_data[:isbn], book_data[:publisher],
                    book_data[:publication_year],
                    book_data[:binding])
    [book, book_data[:image_url]]
  rescue StandardError => ex
    raise ex if ex.instance_of? NoResultsError

    trace = ex.backtrace.join("\n> ")
    log.warn do
      "Failed parsing search results for BarnesAndNoble " \
      "#{ex.message} #{trace}"
    end
    raise NoResultsError
  end
end
parse_search_result_data(html) click to toggle source
# File lib/alexandria/book_providers/barnes_and_noble.rb, line 122
def parse_search_result_data(html)
  doc = html_to_doc(html)
  book_search_results = []
  begin
    result_divs = doc / 'div[@class*="book-container"]'
    result_divs.each do |div|
      result = {}
      # img = div % 'div.book-image/a/img'
      # result[:image_url] = img['src'] if img
      title_header = div % "h2"
      title_links = title_header / "a"
      result[:title] = title_links.first.inner_text
      result[:url] = title_links.first["href"]

      book_search_results << result
    end
  rescue StandardError => ex
    trace = ex.backtrace.join("\n> ")
    log.warn do
      "Failed parsing search results for Barnes & Noble " \
      "#{ex.message} #{trace}"
    end
  end
  book_search_results
end
url(book) click to toggle source
# File lib/alexandria/book_providers/barnes_and_noble.rb, line 95
def url(book)
  create_search_uri(SEARCH_BY_ISBN, book.isbn)
rescue StandardError => ex
  log.warn { "Cannot create url for book #{book}; #{ex.message}" }
  nil
end