class DmgAndroidApi::Android::Leaderboard

Constants

CATEGORIES
IDENTIFIERS

Attributes

category[R]
hydra[R]
identifier[R]

Public Class Methods

new(identifier, category=nil, options={}) click to toggle source
# File lib/dmg_android_api/android/leaderboard.rb, line 71
def initialize(identifier, category=nil, options={})
  @identifier = identifier
  @category = category
  @hydra = options[:hydra] || DmgAndroidApi.hydra
  @request_opts = options[:request_opts] || {}
  @parsed_results = []
end
parse(html) click to toggle source
# File lib/dmg_android_api/android/leaderboard.rb, line 8
def self.parse(html)
  if html.include?('<title>Editor&#39;s Choice')
    parse_editors_choice_page(html)
  else
    parse_normal_page(html)
  end
end
parse_editors_choice_page(html) click to toggle source
# File lib/dmg_android_api/android/leaderboard.rb, line 51
def self.parse_editors_choice_page(html)
  results = []

  doc = Nokogiri::HTML(html)

  doc.css('.fsg-snippet').each do |snippet_node|
    result = {}

    result[:title]      = snippet_node.css('.title').text
    result[:price_usd]  = nil
    result[:developer]  = snippet_node.css('.attribution').text
    result[:market_id]  = snippet_node.attributes['data-docid'].text
    result[:market_url] = "https://play.google.com/store/apps/details?id=#{result[:market_id]}&hl=en"

    results << result
  end

  results
end
parse_normal_page(html) click to toggle source
# File lib/dmg_android_api/android/leaderboard.rb, line 16
def self.parse_normal_page(html)
  results = []
  doc = Nokogiri::HTML(html)
  doc.css('.card').each do |snippet_node|
    result = {}

    details_node = snippet_node.css('.details')


    unless snippet_node.css('.reason-set').empty?

      ratings_node = snippet_node.css('.reason-set').css('.stars-container')
      price_node   = snippet_node.css('.reason-set').css('.price-container')

      ratings_season_node = ratings_node.css('.reason-set-star-rating').css('.tiny-star')
      current_rating      = ratings_season_node.css('.current-rating')
      result[:stars] = current_rating.text
      result[:price_usd] = price_node.css('.buy-button-container').css('.buy').text
    else
      result[:stars] = nil
    end

    result[:title] = details_node.css('.title').text
    result[:developer]  = details_node.css('.subtitle-container').children.first.text
    result[:market_id]  = snippet_node.attributes['data-docid'].text
    result[:market_url] = "https://play.google.com/store/apps/details?id=#{result[:market_id]}&hl=en"

    result[:price_usd] = '$0.00' if result[:price_usd] == 'Free'

    results << result
  end

  results
end

Public Instance Methods

enqueue_update(options={}) click to toggle source
# File lib/dmg_android_api/android/leaderboard.rb, line 99
def enqueue_update(options={})
  if @identifier.to_s.downcase == 'editors_choice' && category == nil
    url = 'https://play.google.com/store/apps/collection/editors_choice?&hl=en'
    process_page(url, 1)
  else
    min_rank = options[:min_rank] || 1
    max_rank = options[:max_rank] || 500

    min_page = rank_to_page(min_rank)
    max_page = rank_to_page(max_rank)

    @parsed_results = []

    urls = market_urls(:min_page => min_page, :max_page => max_page)
    urls.each_index{ |i| process_page(urls[i], i+1) }
  end

  self
end
market_urls(options={}) click to toggle source
# File lib/dmg_android_api/android/leaderboard.rb, line 79
def market_urls(options={})
  results = []

  min_page = options[:min_page] || 1
  max_page = options[:max_page] || 10

  (min_page..max_page).each do |page|
    start_val = (page - 1) * 46

    url = 'https://play.google.com/store/apps'
    url << "/category/#{category.to_s.upcase}" if category
    url << "/collection/#{identifier.to_s}?"
    url << "start=#{start_val}"
    url << "&num=46&hl=en"
    results << url
  end

  results
end
rank_to_page(rank) click to toggle source
# File lib/dmg_android_api/android/leaderboard.rb, line 126
def rank_to_page(rank)
  ((rank - 1) / 24) + 1
end
results() click to toggle source
# File lib/dmg_android_api/android/leaderboard.rb, line 130
def results
  raise 'Results do not exist yet.' unless @parsed_results
  @parsed_results.reject{ |page| page.nil? || page.empty? }.flatten
end
update(options={}) click to toggle source
# File lib/dmg_android_api/android/leaderboard.rb, line 119
def update(options={})
  enqueue_update(options)
  @hydra.run

  self
end

Private Instance Methods

process_page(url, page_num) click to toggle source
# File lib/dmg_android_api/android/leaderboard.rb, line 136
def process_page(url, page_num)
  request = Typhoeus::Request.new(url, @request_opts)
  request.on_complete do |response|
    # HACK: Typhoeus <= 0.4.2 returns a response, 0.5.0pre returns the request.
    response = response.response if response.is_a?(Typhoeus::Request)
    result = Leaderboard.parse(response.body)
    update_callback(result, page_num)
  end
  @hydra.queue(request)
end
update_callback(result, page) click to toggle source
# File lib/dmg_android_api/android/leaderboard.rb, line 147
def update_callback(result, page)
  @parsed_results[page] = result
end