Class: MarketBot::Android::Leaderboard

Inherits:
Object
  • Object
show all
Defined in:
lib/market_bot/android/leaderboard.rb,
lib/market_bot/android/leaderboard/constants.rb

Constant Summary collapse

IDENTIFIERS =
[
  :apps_editors_choice,
  :apps_featured,
  :apps_movers_shakers,
  :apps_tablet_featured,
  :apps_topgrossing,
  :apps_topselling_free,
  :apps_topselling_new_free,
  :apps_topselling_new_paid,
  :apps_topselling_paid,
  :apps_topselling_paid_game
]
CATEGORIES =
[
  :application,
  :app_wallpaper,
  :app_widgets,
  :arcade,
  :books_and_reference,
  :brain,
  :business,
  :cards,
  :casual,
  :comics,
  :communication,
  :education,
  :entertainment,
  :finance,
  :game,
  :game_wallpaper,
  :game_widgets,
  :health_and_fitness,
  :libraries_and_demo,
  :lifestyle,
  :media_and_video,
  :medical,
  :music_and_audio,
  :news_and_magazines,
  :personalization,
  :photography,
  :productivity,
  :racing,
  :shopping,
  :social,
  :sports,
  :sports_games,
  :tools,
  :transportation,
  :travel_and_local,
  :weather
]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(identifier, category = nil, options = {}) ⇒ Leaderboard

Returns a new instance of Leaderboard.



66
67
68
69
70
71
# File 'lib/market_bot/android/leaderboard.rb', line 66

def initialize(identifier, category=nil, options={})
  @identifier = identifier
  @category = category
  @hydra = options[:hydra] || Typhoeus::Hydra.hydra
  @parsed_results = []
end

Instance Attribute Details

#categoryObject (readonly)

Returns the value of attribute category.



5
6
7
# File 'lib/market_bot/android/leaderboard.rb', line 5

def category
  @category
end

#hydraObject (readonly)

Returns the value of attribute hydra.



6
7
8
# File 'lib/market_bot/android/leaderboard.rb', line 6

def hydra
  @hydra
end

#identifierObject (readonly)

Returns the value of attribute identifier.



5
6
7
# File 'lib/market_bot/android/leaderboard.rb', line 5

def identifier
  @identifier
end

Class Method Details

.parse(html) ⇒ Object



8
9
10
11
12
13
14
# File 'lib/market_bot/android/leaderboard.rb', line 8

def self.parse(html)
  if html.include?('<title>Editors&#39; Choice - Android Market</title>')
    parse_editors_choice_page(html)
  else
    parse_normal_page(html)
  end
end

.parse_editors_choice_page(html) ⇒ Object



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/market_bot/android/leaderboard.rb', line 46

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('.goog-inline-block').text
    result[:market_id]  = snippet_node.attributes['data-docid'].text
    result[:market_url] = "https://market.android.com/details?id=#{result[:market_id]}"

    results << result
  end

  results
end

.parse_normal_page(html) ⇒ Object



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/market_bot/android/leaderboard.rb', line 16

def self.parse_normal_page(html)
  results = []
  doc = Nokogiri::HTML(html)

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

    details_node = snippet_node.css('.details')

    unless snippet_node.css('.ratings').empty?
      stars_text = snippet_node.css('.ratings').first.attributes['title'].value
      result[:stars] = /Rating: (.+) stars .*/.match(stars_text)[1]
    else
      result[:stars] = nil
    end

    result[:title] = details_node.css('.title').first.attributes['title'].to_s
    result[:price_usd] = details_node.css('.buy-button-price').children.first.text.gsub(' Buy', '')
    result[:developer] = details_node.css('.attribution').children.first.text
    result[:market_id] = details_node.css('.title').first.attributes['href'].to_s.gsub('/details?id=', '').gsub(/&feature=.*$/, '')
    result[:market_url] = "https://market.android.com/details?id=#{result[:market_id]}"

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

    results << result
  end

  results
end

Instance Method Details

#enqueue_update(options = {}) ⇒ Object



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/market_bot/android/leaderboard.rb', line 93

def enqueue_update(options={})
  if @identifier.to_s.downcase == 'apps_editors_choice' && category == nil
    url = 'https://market.android.com/details?id=apps_editors_choice'
    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 = {}) ⇒ Object



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/market_bot/android/leaderboard.rb', line 73

def market_urls(options={})
  results = []

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

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

    url = 'https://market.android.com/details?id=' + identifier.to_s
    url << "&cat=#{category.to_s.upcase}" if category
    url << "&start=#{start_val}"
    url << "&num=24"

    results << url
  end

  results
end

#rank_to_page(rank) ⇒ Object



120
121
122
# File 'lib/market_bot/android/leaderboard.rb', line 120

def rank_to_page(rank)
  ((rank - 1) / 24) + 1
end

#resultsObject



124
125
126
127
# File 'lib/market_bot/android/leaderboard.rb', line 124

def results
  raise 'Results do not exist yet.' unless @parsed_results
  @parsed_results.reject{ |page| page.nil? || page.empty? }.flatten
end

#update(options = {}) ⇒ Object



113
114
115
116
117
118
# File 'lib/market_bot/android/leaderboard.rb', line 113

def update(options={})
  enqueue_update(options)
  @hydra.run

  self
end