dmg_android_api 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f00475c072f0b51f86bf9a47fabccbdde1aeed92
4
+ data.tar.gz: 9227bd5ee02738b4019c7dc2b0af8bff85c5332e
5
+ SHA512:
6
+ metadata.gz: 3787fe315a5766ea665e39d365ace862f6af3e5010ef1e474910b1bd3bfb11186be5489841856425799c6a9960220acf03a44e3865da27c3957f4c2019ac03f9
7
+ data.tar.gz: a9ee189e59a4a8b0ebc971a63a08c19144598dcd946db6ed58bfee4969dc8a50a7a22b993372b144fa45a9cdd95ad415a651bc41bc1ff6722fc8f74ef1306549
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,15 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'typhoeus'
4
+ gem 'nokogiri'
5
+
6
+ group :development do
7
+ gem 'rspec', '~> 2.8.0'
8
+ gem 'bundler', '~> 1.3.5'
9
+ gem 'jeweler', '~> 1.6.4'
10
+ gem 'simplecov', '>= 0'
11
+ gem 'rdoc', '>= 3.9.4'
12
+ gem 'guard', '~> 1.2.3'
13
+ gem 'guard-rspec', '~> 1.1.0'
14
+ gem 'growl'
15
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Nhat Anh Nguyen
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # DmgAndroidApi
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'dmg_android_api'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install dmg_android_api
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ require 'dmg_android_api/version'
6
+
7
+
8
+ Gem::Specification.new do |spec|
9
+ spec.name = "dmg_android_api"
10
+ spec.version = DmgAndroidApi::VERSION
11
+ spec.authors = ["Nhat Anh Nguyen"]
12
+ spec.email = ["n.nguyen@thisisdmg.com"]
13
+ spec.description = %q{DMG Android Api}
14
+ spec.summary = %q{DMG Android Api}
15
+ spec.homepage = "http://www.thisisdmg.com"
16
+ spec.license = "MIT"
17
+
18
+ spec.files = `git ls-files`.split($/)
19
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
20
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
21
+ spec.require_paths = ["lib"]
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.3"
24
+ spec.add_development_dependency "rake"
25
+ end
@@ -0,0 +1,221 @@
1
+ module DmgAndroidApi
2
+ module Android
3
+
4
+ class App
5
+ MARKET_ATTRIBUTES = [:title, :rating, :updated, :current_version, :requires_android,
6
+ :category, :installs, :size, :price, :content_rating, :description,
7
+ :votes, :developer, :more_from_developer, :users_also_installed,
8
+ :related, :banner_icon_url, :banner_image_url, :website_url, :email,
9
+ :youtube_video_ids, :screenshot_urls, :whats_new, :permissions,
10
+ :rating_distribution, :html]
11
+
12
+ attr_reader :app_id
13
+ attr_reader *MARKET_ATTRIBUTES
14
+ attr_reader :hydra
15
+ attr_reader :callback
16
+ attr_reader :error
17
+
18
+ def self.parse(html)
19
+ result = {}
20
+
21
+ doc = Nokogiri::HTML(html)
22
+
23
+ extra_info = doc.css('.meta-info')
24
+
25
+ extra_info.each do |info|
26
+
27
+ field_name = info.css('.title').text
28
+
29
+ case field_name
30
+ when 'Updated'
31
+ result[:updated] = info.css('.content').text
32
+ when 'Current Version'
33
+ result[:current_version] = info.css('.content').text
34
+ when 'Requires Android'
35
+ result[:requires_android] = info.css('.content').text
36
+ when 'Category'
37
+ result[:category] = info.css('.content').text
38
+ when 'Installs'
39
+ result[:installs] = info.css('.content').text
40
+ when 'Size'
41
+ result[:size] = info.css('.content').text
42
+ when 'Content Rating'
43
+ result[:content_rating] = info.css('.content').text
44
+ end
45
+ end
46
+ result[:description] = doc.css('.text-body div').first.inner_html
47
+
48
+ result[:title] = doc.css('.document-title').first.text
49
+
50
+ rating_elem = doc.css('.score')
51
+ result[:rating] = rating_elem.text unless rating_elem.empty?
52
+
53
+ votes_elem = doc.css('.reviews-num')
54
+ result[:votes] = votes_elem.text unless votes_elem.empty?
55
+
56
+ result[:developer] = doc.css('.document-subtitle.primary').text
57
+
58
+ result[:more_from_developer] = []
59
+ result[:users_also_installed] = []
60
+ result[:related] = []
61
+
62
+ if similar_elem = doc.css('.doc-similar').first
63
+ similar_elem.children.each do |similar_elem_child|
64
+ assoc_app_type = similar_elem_child.attributes['data-analyticsid'].text
65
+
66
+ next unless %w(more-from-developer users-also-installed related).include?(assoc_app_type)
67
+
68
+ assoc_app_type = assoc_app_type.gsub('-', '_').to_sym
69
+ result[assoc_app_type] ||= []
70
+
71
+ similar_elem_child.css('.app-left-column-related-snippet-container').each do |app_elem|
72
+ assoc_app = {}
73
+
74
+ assoc_app[:app_id] = app_elem.attributes['data-docid'].text
75
+
76
+ result[assoc_app_type] << assoc_app
77
+ end
78
+ end
79
+ end
80
+
81
+ result[:banner_icon_url] = doc.css('.cover-container img').first.attributes['src'].value
82
+
83
+ if image_elem = doc.css('.doc-banner-image-container img').first
84
+ result[:banner_image_url] = image_elem.attributes['src'].value
85
+ else
86
+ result[:banner_image_url] = nil
87
+ end
88
+
89
+ if website_elem = doc.css('a').select{ |l| l.text.include?("Visit Developer's Website")}.first
90
+ redirect_url = website_elem.attribute('href').value
91
+
92
+ if q_param = URI(redirect_url).query.split('&').select{ |p| p =~ /q=/ }.first
93
+ actual_url = q_param.gsub('q=', '')
94
+ end
95
+
96
+ result[:website_url] = actual_url
97
+ end
98
+
99
+ if email_elem = doc.css('a').select{ |l| l.text.include?("Email Developer")}.first
100
+ result[:email] = email_elem.attribute('href').value.gsub(/^mailto:/, '')
101
+ end
102
+
103
+ unless (video_section_elem = doc.css('.doc-video-section')).empty?
104
+ urls = video_section_elem.children.css('embed').map{ |e| e.attribute('src').value }
105
+ result[:youtube_video_ids] = urls.map{ |u| /youtube\.com\/v\/(.*)\?/.match(u)[1] }
106
+ else
107
+ result[:youtube_video_ids] = []
108
+ end
109
+
110
+
111
+ screenshots = doc.css('.thumbnails img')
112
+
113
+ if screenshots && screenshots.length > 0
114
+ result[:screenshot_urls] = screenshots.map { |s| s.attributes['src'].value }
115
+ else
116
+ result[:screenshot_urls] = []
117
+ end
118
+
119
+ recent_changes = doc.css('.recent-change')
120
+ result[:whats_new] = ''
121
+ recent_changes.each do |change|
122
+
123
+ result[:whats_new] << change.text
124
+ result[:whats_new] << '<br>'
125
+
126
+ end
127
+ result[:permissions] = permissions = []
128
+ perm_types = ['dangerous', 'safe']
129
+ perm_types.each do |type|
130
+ doc.css("#doc-permissions-#{type} .doc-permission-group").each do |group_elem|
131
+ title = group_elem.css('.doc-permission-group-title').text
132
+ group_elem.css('.doc-permission-description').each do |desc_elem|
133
+ #permissions << { :security => type, :group => title, :description => desc_elem.text }
134
+ end
135
+ descriptions = group_elem.css('.doc-permission-description').map { |e| e.text }
136
+ descriptions_full = group_elem.css('.doc-permission-description-full').map { |e| e.text }
137
+ (0...descriptions.length).each do |i|
138
+ desc = descriptions[i]
139
+ desc_full = descriptions_full[i]
140
+ permissions << { :security => type, :group => title, :description => desc, :description_full => desc_full }
141
+ end
142
+ end
143
+ end
144
+
145
+ result[:rating_distribution] = { 5 => nil, 4 => nil, 3 => nil, 2 => nil, 1 => nil }
146
+
147
+ if (histogram = doc.css('div.histogram-table').first)
148
+ cur_index = 5
149
+ histogram.css('tr').each do |e|
150
+ result[:rating_distribution][cur_index] = e.children.last.inner_text.gsub(/[^0-9]/, '').to_i
151
+ cur_index -= 1
152
+ end
153
+ end
154
+
155
+ result[:html] = html
156
+
157
+ result
158
+ end
159
+
160
+ def initialize(app_id, options={})
161
+ @app_id = app_id
162
+ @hydra = options[:hydra] || DmgAndroidApi.hydra
163
+ @request_opts = options[:request_opts] || {}
164
+ @callback = nil
165
+ @error = nil
166
+ end
167
+
168
+ def market_url
169
+ "https://play.google.com/store/apps/details?id=#{@app_id}&hl=en"
170
+ end
171
+
172
+ def update
173
+ resp = Typhoeus::Request.get(market_url, @request_opts)
174
+ result = App.parse(resp.body)
175
+ update_callback(result)
176
+
177
+ self
178
+ end
179
+
180
+ def enqueue_update(&block)
181
+ @callback = block
182
+ @error = nil
183
+
184
+ request = Typhoeus::Request.new(market_url, @request_opts)
185
+
186
+ request.on_complete do |response|
187
+ # HACK: Typhoeus <= 0.4.2 returns a response, 0.5.0pre returns the request.
188
+ response = response.response if response.is_a?(Typhoeus::Request)
189
+
190
+ result = nil
191
+
192
+ begin
193
+ result = App.parse(response.body)
194
+ rescue Exception => e
195
+ @error = e
196
+ end
197
+
198
+ update_callback(result)
199
+ end
200
+
201
+ hydra.queue(request)
202
+
203
+ self
204
+ end
205
+
206
+ private
207
+ def update_callback(result)
208
+ unless @error
209
+ MARKET_ATTRIBUTES.each do |a|
210
+ attr_name = "@#{a}"
211
+ attr_value = result[a]
212
+ instance_variable_set(attr_name, attr_value)
213
+ end
214
+ end
215
+
216
+ @callback.call(self) if @callback
217
+ end
218
+ end
219
+
220
+ end
221
+ end
@@ -0,0 +1,33 @@
1
+ module DmgAndroidApi
2
+ module Android
3
+
4
+ # Developer pages are extremely similar to leaderboard pages.
5
+ # Amazingly, this inheritence hack works!
6
+ class Developer < DmgAndroidApi::Android::Leaderboard
7
+ def initialze(developer, options={})
8
+ super(query, nil, options)
9
+ end
10
+
11
+ def market_urls(options={})
12
+ results = []
13
+
14
+ min_page = options[:min_page] || 1
15
+ max_page = options[:max_page] || 25
16
+
17
+ (min_page..max_page).each do |page|
18
+ start_val = (page - 1) * 12
19
+
20
+ url = "https://play.google.com/store/apps/developer?"
21
+ url << "id=#{URI.escape(identifier)}&"
22
+ url << "start=#{start_val}&"
23
+ url << "num=12&hl=en"
24
+
25
+ results << url
26
+ end
27
+
28
+ results
29
+ end
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,59 @@
1
+ module DmgAndroidApi
2
+ module Android
3
+
4
+ class Leaderboard
5
+ IDENTIFIERS = [
6
+ :editors_choice,
7
+ :featured,
8
+ :movers_shakers,
9
+ :tablet_featured,
10
+ :topgrossing,
11
+ :topselling_free,
12
+ :topselling_new_free,
13
+ :topselling_new_paid,
14
+ :topselling_paid,
15
+ :topselling_paid_game
16
+ ]
17
+
18
+ CATEGORIES = [
19
+ :application,
20
+ :app_wallpaper,
21
+ :app_widgets,
22
+ :arcade,
23
+ :books_and_reference,
24
+ :brain,
25
+ :business,
26
+ :cards,
27
+ :casual,
28
+ :comics,
29
+ :communication,
30
+ :education,
31
+ :entertainment,
32
+ :finance,
33
+ :game,
34
+ :game_wallpaper,
35
+ :game_widgets,
36
+ :health_and_fitness,
37
+ :libraries_and_demo,
38
+ :lifestyle,
39
+ :media_and_video,
40
+ :medical,
41
+ :music_and_audio,
42
+ :news_and_magazines,
43
+ :personalization,
44
+ :photography,
45
+ :productivity,
46
+ :racing,
47
+ :shopping,
48
+ :social,
49
+ :sports,
50
+ :sports_games,
51
+ :tools,
52
+ :transportation,
53
+ :travel_and_local,
54
+ :weather
55
+ ]
56
+ end
57
+
58
+ end
59
+ end
@@ -0,0 +1,153 @@
1
+ module DmgAndroidApi
2
+ module Android
3
+
4
+ class Leaderboard
5
+ attr_reader :identifier, :category
6
+ attr_reader :hydra
7
+
8
+ def self.parse(html)
9
+ if html.include?('<title>Editor&#39;s Choice')
10
+ parse_editors_choice_page(html)
11
+ else
12
+ parse_normal_page(html)
13
+ end
14
+ end
15
+
16
+ def self.parse_normal_page(html)
17
+ results = []
18
+ doc = Nokogiri::HTML(html)
19
+ doc.css('.card').each do |snippet_node|
20
+ result = {}
21
+
22
+ details_node = snippet_node.css('.details')
23
+
24
+
25
+ unless snippet_node.css('.reason-set').empty?
26
+
27
+ ratings_node = snippet_node.css('.reason-set').css('.stars-container')
28
+ price_node = snippet_node.css('.reason-set').css('.price-container')
29
+
30
+ ratings_season_node = ratings_node.css('.reason-set-star-rating').css('.tiny-star')
31
+ current_rating = ratings_season_node.css('.current-rating')
32
+ result[:stars] = current_rating.text
33
+ result[:price_usd] = price_node.css('.buy-button-container').css('.buy').text
34
+ else
35
+ result[:stars] = nil
36
+ end
37
+
38
+ result[:title] = details_node.css('.title').text
39
+ result[:developer] = details_node.css('.subtitle-container').children.first.text
40
+ result[:market_id] = snippet_node.attributes['data-docid'].text
41
+ result[:market_url] = "https://play.google.com/store/apps/details?id=#{result[:market_id]}&hl=en"
42
+
43
+ result[:price_usd] = '$0.00' if result[:price_usd] == 'Free'
44
+
45
+ results << result
46
+ end
47
+
48
+ results
49
+ end
50
+
51
+ def self.parse_editors_choice_page(html)
52
+ results = []
53
+
54
+ doc = Nokogiri::HTML(html)
55
+
56
+ doc.css('.fsg-snippet').each do |snippet_node|
57
+ result = {}
58
+
59
+ result[:title] = snippet_node.css('.title').text
60
+ result[:price_usd] = nil
61
+ result[:developer] = snippet_node.css('.attribution').text
62
+ result[:market_id] = snippet_node.attributes['data-docid'].text
63
+ result[:market_url] = "https://play.google.com/store/apps/details?id=#{result[:market_id]}&hl=en"
64
+
65
+ results << result
66
+ end
67
+
68
+ results
69
+ end
70
+
71
+ def initialize(identifier, category=nil, options={})
72
+ @identifier = identifier
73
+ @category = category
74
+ @hydra = options[:hydra] || DmgAndroidApi.hydra
75
+ @request_opts = options[:request_opts] || {}
76
+ @parsed_results = []
77
+ end
78
+
79
+ def market_urls(options={})
80
+ results = []
81
+
82
+ min_page = options[:min_page] || 1
83
+ max_page = options[:max_page] || 10
84
+
85
+ (min_page..max_page).each do |page|
86
+ start_val = (page - 1) * 46
87
+
88
+ url = 'https://play.google.com/store/apps'
89
+ url << "/category/#{category.to_s.upcase}" if category
90
+ url << "/collection/#{identifier.to_s}?"
91
+ url << "start=#{start_val}"
92
+ url << "&num=46&hl=en"
93
+ results << url
94
+ end
95
+
96
+ results
97
+ end
98
+
99
+ def enqueue_update(options={})
100
+ if @identifier.to_s.downcase == 'editors_choice' && category == nil
101
+ url = 'https://play.google.com/store/apps/collection/editors_choice?&hl=en'
102
+ process_page(url, 1)
103
+ else
104
+ min_rank = options[:min_rank] || 1
105
+ max_rank = options[:max_rank] || 500
106
+
107
+ min_page = rank_to_page(min_rank)
108
+ max_page = rank_to_page(max_rank)
109
+
110
+ @parsed_results = []
111
+
112
+ urls = market_urls(:min_page => min_page, :max_page => max_page)
113
+ urls.each_index{ |i| process_page(urls[i], i+1) }
114
+ end
115
+
116
+ self
117
+ end
118
+
119
+ def update(options={})
120
+ enqueue_update(options)
121
+ @hydra.run
122
+
123
+ self
124
+ end
125
+
126
+ def rank_to_page(rank)
127
+ ((rank - 1) / 24) + 1
128
+ end
129
+
130
+ def results
131
+ raise 'Results do not exist yet.' unless @parsed_results
132
+ @parsed_results.reject{ |page| page.nil? || page.empty? }.flatten
133
+ end
134
+
135
+ private
136
+ def process_page(url, page_num)
137
+ request = Typhoeus::Request.new(url, @request_opts)
138
+ request.on_complete do |response|
139
+ # HACK: Typhoeus <= 0.4.2 returns a response, 0.5.0pre returns the request.
140
+ response = response.response if response.is_a?(Typhoeus::Request)
141
+ result = Leaderboard.parse(response.body)
142
+ update_callback(result, page_num)
143
+ end
144
+ @hydra.queue(request)
145
+ end
146
+
147
+ def update_callback(result, page)
148
+ @parsed_results[page] = result
149
+ end
150
+ end
151
+
152
+ end
153
+ end
@@ -0,0 +1,31 @@
1
+ module DmgAndroidApi
2
+ module Android
3
+
4
+ # Search query pages are extremely similar to leaderboard pages.
5
+ # Amazingly, this inheritence hack works!
6
+ class SearchQuery < DmgAndroidApi::Android::Leaderboard
7
+ def initialze(query, options={})
8
+ super(query, nil, options)
9
+ end
10
+
11
+ def market_urls(options={})
12
+ results = []
13
+ min_page = options[:min_page] || 1
14
+ max_page = 9
15
+ (min_page..max_page).each do |page|
16
+ start_val = (page - 1) * 46
17
+
18
+ url = "https://play.google.com/store/search?"
19
+ url << "q=#{URI.escape(identifier)}&"
20
+ url << "c=apps&start=#{start_val}&"
21
+ url << "num=46&hl=en"
22
+
23
+ results << url
24
+ end
25
+
26
+ results
27
+ end
28
+ end
29
+
30
+ end
31
+ end
@@ -0,0 +1,3 @@
1
+ module DmgAndroidApi
2
+ VERSION = "0.0.4"
3
+ end
@@ -0,0 +1,18 @@
1
+ require "dmg_android_api/version"
2
+
3
+ require 'uri'
4
+
5
+ require 'typhoeus'
6
+ require 'nokogiri'
7
+
8
+ require 'dmg_android_api/android/app'
9
+ require 'dmg_android_api/android/leaderboard/constants'
10
+ require 'dmg_android_api/android/leaderboard'
11
+ require 'dmg_android_api/android/search_query'
12
+ require 'dmg_android_api/android/developer'
13
+
14
+ module DmgAndroidApi
15
+ def self.hydra
16
+ @hydra ||= Typhoeus::Hydra.new(:max_concurrency => 5)
17
+ end
18
+ end
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dmg_android_api
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.4
5
+ platform: ruby
6
+ authors:
7
+ - Nhat Anh Nguyen
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-07-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: DMG Android Api
42
+ email:
43
+ - n.nguyen@thisisdmg.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - .gitignore
49
+ - Gemfile
50
+ - LICENSE.txt
51
+ - README.md
52
+ - Rakefile
53
+ - dmg_android_api.gemspec
54
+ - lib/dmg_android_api.rb
55
+ - lib/dmg_android_api/android/app.rb
56
+ - lib/dmg_android_api/android/developer.rb
57
+ - lib/dmg_android_api/android/leaderboard.rb
58
+ - lib/dmg_android_api/android/leaderboard/constants.rb
59
+ - lib/dmg_android_api/android/search_query.rb
60
+ - lib/dmg_android_api/version.rb
61
+ homepage: http://www.thisisdmg.com
62
+ licenses:
63
+ - MIT
64
+ metadata: {}
65
+ post_install_message:
66
+ rdoc_options: []
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - '>='
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - '>='
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ requirements: []
80
+ rubyforge_project:
81
+ rubygems_version: 2.0.5
82
+ signing_key:
83
+ specification_version: 4
84
+ summary: DMG Android Api
85
+ test_files: []