awis-sdk-ruby_ 1.1.1p1

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.
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Awis
4
+ module Models
5
+ class Base
6
+ attr_accessor :response, :status_code, :request_id
7
+
8
+ def loading_response(response)
9
+ Awis::Utils::XML.new(response.response_body)
10
+ end
11
+
12
+ def root_node_name
13
+ "/aws:#{action_name}Response/aws:Response/aws:#{action_name}Result/aws:Alexa"
14
+ end
15
+
16
+ def action_name
17
+ self.class.name.split(/\:\:/)[-1]
18
+ end
19
+
20
+ def relationship_collections(item_object, items, items_count, kclass)
21
+ return if items.empty?
22
+
23
+ all_items = {}.array_slice_merge!(:item, items, items_count)
24
+ all_items.map { |item| item_object << kclass.new(item) }
25
+ end
26
+
27
+ def success?
28
+ status_code == 'Success'
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Awis
4
+ module Models
5
+ class BaseEntity
6
+ include Utils::Variable
7
+
8
+ def initialize(options)
9
+ custom_instance_variables(options)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,120 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Awis
4
+ module Models
5
+ class CategoryBrowse < Base
6
+ attr_accessor :categories, :language_categories, :related_categories, :letter_bars
7
+
8
+ def initialize(response)
9
+ @categories = []
10
+ @language_categories = []
11
+ @related_categories = []
12
+ @letter_bars = []
13
+
14
+ setup_data! loading_response(response)
15
+ end
16
+
17
+ # rubocop:disable Metrics/AbcSize
18
+ # rubocop:disable Metrics/CyclomaticComplexity
19
+ # rubocop:disable Metrics/PerceivedComplexity
20
+ # rubocop:disable Metrics/MethodLength
21
+ # rubocop:disable Metrics/BlockLength
22
+ def setup_data!(response)
23
+ categories = []
24
+ language_categories = []
25
+ related_categories = []
26
+ letter_bars = []
27
+
28
+ response.each_node do |node, path|
29
+ text = node.inner_xml
30
+ text = text.to_i if text.to_i.to_s == text
31
+ text = nil if text.class == String && text.empty?
32
+
33
+ if node.name == 'aws:RequestId'
34
+ @request_id ||= text
35
+ elsif node.name == 'aws:StatusCode'
36
+ @status_code ||= text
37
+ elsif node.name == 'aws:Path' && path == "#{category_node_name}/aws:Path"
38
+ categories << { path: text }
39
+ elsif node.name == 'aws:Title' && path == "#{category_node_name}/aws:Title"
40
+ categories << { title: text }
41
+ elsif node.name == 'aws:SubCategoryCount' && path == "#{category_node_name}/aws:SubCategoryCount"
42
+ categories << { sub_category_count: text }
43
+ elsif node.name == 'aws:TotalListingCount' && path == "#{category_node_name}/aws:TotalListingCount"
44
+ categories << { total_listing_count: text }
45
+ elsif node.name == 'aws:Path' && path == "#{language_category_node_name}/aws:Path"
46
+ language_categories << { path: text }
47
+ elsif node.name == 'aws:Title' && path == "#{language_category_node_name}/aws:Title"
48
+ language_categories << { title: text }
49
+ elsif node.name == 'aws:SubCategoryCount' && path == "#{language_category_node_name}/aws:SubCategoryCount"
50
+ language_categories << { sub_category_count: text }
51
+ elsif node.name == 'aws:TotalListingCount' && path == "#{language_category_node_name}/aws:TotalListingCount"
52
+ language_categories << { total_listing_count: text }
53
+ elsif node.name == 'aws:Path' && path == "#{related_category_node_name}/aws:Path"
54
+ related_categories << { path: text }
55
+ elsif node.name == 'aws:Title' && path == "#{related_category_node_name}/aws:Title"
56
+ related_categories << { title: text }
57
+ elsif node.name == 'aws:SubCategoryCount' && path == "#{related_category_node_name}/aws:SubCategoryCount"
58
+ related_categories << { sub_category_count: text }
59
+ elsif node.name == 'aws:TotalListingCount' && path == "#{related_category_node_name}/aws:TotalListingCount"
60
+ related_categories << { total_listing_count: text }
61
+ elsif node.name == 'aws:Path' && path == "#{letter_bars_node_name}/aws:Path"
62
+ letter_bars << { path: text }
63
+ elsif node.name == 'aws:Title' && path == "#{letter_bars_node_name}/aws:Title"
64
+ letter_bars << { title: text }
65
+ elsif node.name == 'aws:SubCategoryCount' && path == "#{letter_bars_node_name}/aws:SubCategoryCount"
66
+ letter_bars << { sub_category_count: text }
67
+ elsif node.name == 'aws:TotalListingCount' && path == "#{letter_bars_node_name}/aws:TotalListingCount"
68
+ letter_bars << { total_listing_count: text }
69
+ end
70
+ end
71
+
72
+ relationship_collections(@categories, categories, 4, Category)
73
+ relationship_collections(@language_categories, language_categories, 4, LanguageCategory)
74
+ relationship_collections(@related_categories, related_categories, 4, RelatedCategory)
75
+ relationship_collections(@letter_bars, letter_bars, 4, LetterBar)
76
+ end
77
+ # rubocop:enable Metrics/AbcSize
78
+ # rubocop:enable Metrics/CyclomaticComplexity
79
+ # rubocop:enable Metrics/PerceivedComplexity
80
+ # rubocop:enable Metrics/MethodLength
81
+ # rubocop:enable Metrics/BlockLength
82
+
83
+ def base_node_name
84
+ "#{root_node_name}/aws:CategoryBrowse"
85
+ end
86
+
87
+ def category_node_name
88
+ "#{base_node_name}/aws:Categories/aws:Category"
89
+ end
90
+
91
+ def language_category_node_name
92
+ "#{base_node_name}/aws:LanguageCategories/aws:Category"
93
+ end
94
+
95
+ def related_category_node_name
96
+ "#{base_node_name}/aws:RelatedCategories/aws:Category"
97
+ end
98
+
99
+ def letter_bars_node_name
100
+ "#{base_node_name}/aws:LetterBars/aws:Category"
101
+ end
102
+ end
103
+
104
+ class Category < BaseEntity
105
+ attr_accessor :path, :title, :sub_category_count, :total_listing_count
106
+ end
107
+
108
+ class LanguageCategory < BaseEntity
109
+ attr_accessor :path, :title, :sub_category_count, :total_listing_count
110
+ end
111
+
112
+ class RelatedCategory < BaseEntity
113
+ attr_accessor :path, :title, :sub_category_count, :total_listing_count
114
+ end
115
+
116
+ class LetterBar < BaseEntity
117
+ attr_accessor :path, :title, :sub_category_count, :total_listing_count
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Awis
4
+ module Models
5
+ class CategoryListings < Base
6
+ attr_accessor :count, :recursive_count, :listings
7
+
8
+ def initialize(response)
9
+ @listings = []
10
+ setup_data! loading_response(response)
11
+ end
12
+
13
+ def setup_data!(response)
14
+ category_listings = []
15
+
16
+ response.each_node do |node, path|
17
+ text = node.inner_xml
18
+ text = text.to_i if text.to_i.to_s == text
19
+ text = nil if text.class == String && text.empty?
20
+
21
+ if node.name == 'aws:RequestId'
22
+ @request_id ||= text
23
+ elsif node.name == 'aws:StatusCode'
24
+ @status_code ||= text
25
+ elsif node.name == 'aws:Count'
26
+ @count ||= text
27
+ elsif node.name == 'aws:RecursiveCount'
28
+ @recursive_count ||= text
29
+ elsif node.name == 'aws:DataUrl' && path == "#{base_node_name}/aws:DataUrl"
30
+ category_listings << { data_url: text }
31
+ elsif node.name == 'aws:Title' && path == "#{base_node_name}/aws:Title"
32
+ category_listings << { title: text }
33
+ elsif node.name == 'aws:PopularityRank' && path == "#{base_node_name}/aws:PopularityRank"
34
+ category_listings << { popularity_rank: text }
35
+ elsif node.name == 'aws:Description' && path == "#{base_node_name}/aws:Description"
36
+ category_listings << { description: text }
37
+ end
38
+ end
39
+
40
+ relationship_collections(@listings, category_listings, 4, Listing)
41
+ end
42
+
43
+ def base_node_name
44
+ "#{root_node_name}/aws:CategoryListings/aws:Listings/aws:Listing"
45
+ end
46
+ end
47
+
48
+ class Listing < BaseEntity
49
+ attr_accessor :data_url, :title, :popularity_rank, :description
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Awis
4
+ module Models
5
+ class SitesLinkingIn < Base
6
+ attr_accessor :sites
7
+
8
+ def initialize(response)
9
+ @sites = []
10
+ setup_data! loading_response(response)
11
+ end
12
+
13
+ def setup_data!(response)
14
+ sites = []
15
+
16
+ response.each_node do |node, _path|
17
+ text = node.inner_xml
18
+ text = nil if text.class == String && text.empty?
19
+
20
+ if node.name == 'aws:RequestId'
21
+ @request_id ||= text
22
+ elsif node.name == 'aws:StatusCode'
23
+ @status_code ||= text
24
+ elsif node.name == 'aws:Title'
25
+ sites << { title: text }
26
+ elsif node.name == 'aws:Url'
27
+ sites << { url: text }
28
+ end
29
+ end
30
+
31
+ relationship_collections(@sites, sites, 2, Site)
32
+ end
33
+ end
34
+
35
+ class Site < BaseEntity
36
+ attr_accessor :title, :url
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Awis
4
+ module Models
5
+ class TrafficHistory < Base
6
+ attr_accessor :range, :site, :start, :historical_data
7
+
8
+ def initialize(response)
9
+ @historical_data = []
10
+ setup_data! loading_response(response)
11
+ end
12
+
13
+ # rubocop:disable Metrics/AbcSize
14
+ # rubocop:disable Metrics/CyclomaticComplexity
15
+ # rubocop:disable Metrics/PerceivedComplexity
16
+ def setup_data!(response)
17
+ datas = []
18
+
19
+ response.each_node do |node, path|
20
+ text = node.inner_xml
21
+ text = text.to_i if text.to_i.to_s == text
22
+ text = nil if text.class == String && text.empty?
23
+
24
+ if node.name == 'aws:RequestId'
25
+ @request_id ||= text
26
+ elsif node.name == 'aws:StatusCode'
27
+ @status_code ||= text
28
+ elsif node.name == 'aws:Range'
29
+ @range ||= text
30
+ elsif node.name == 'aws:Site'
31
+ @site ||= text
32
+ elsif node.name == 'aws:Start'
33
+ @start ||= text
34
+ elsif node.name == 'aws:Date' && path == "#{base_node_name}/aws:Date"
35
+ datas << { date: text }
36
+ elsif node.name == 'aws:PerMillion' && path == "#{base_node_name}/aws:PageViews/aws:PerMillion"
37
+ datas << { page_views_per_million: text }
38
+ elsif node.name == 'aws:PerUser' && path == "#{base_node_name}/aws:PageViews/aws:PerUser"
39
+ datas << { page_views_per_user: text }
40
+ elsif node.name == 'aws:Rank' && path == "#{base_node_name}/aws:Rank"
41
+ datas << { rank: text }
42
+ elsif node.name == 'aws:PerMillion' && path == "#{base_node_name}/aws:Reach/aws:PerMillion"
43
+ datas << { reach_per_million: text }
44
+ end
45
+ end
46
+
47
+ relationship_collections(@historical_data, datas, 5, HistoricalData)
48
+ end
49
+ # rubocop:enable Metrics/AbcSize
50
+ # rubocop:enable Metrics/CyclomaticComplexity
51
+ # rubocop:enable Metrics/PerceivedComplexity
52
+
53
+ def base_node_name
54
+ "#{root_node_name}/aws:TrafficHistory/aws:HistoricalData/aws:Data"
55
+ end
56
+ end
57
+
58
+ class HistoricalData < BaseEntity
59
+ attr_accessor :date, :page_views_per_million, :page_views_per_user, :rank, :reach_per_million
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,392 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Awis
4
+ module Models
5
+ class UrlInfo < Base
6
+ attr_accessor :data_url, :rank, :asin, :contact_info, :content_data, :usage_statistics, :related_links,
7
+ :categories, :xml, :contributing_subdomains, :rank_by_country
8
+
9
+ def initialize(response)
10
+ @usage_statistics = []
11
+ @related_links = []
12
+ @categories = []
13
+ @contributing_subdomains = []
14
+ @rank_by_country = []
15
+
16
+ setup_data! loading_response(response)
17
+ end
18
+
19
+ def setup_data!(response)
20
+ @xml = response
21
+ content_data = {
22
+ owned_domains: []
23
+ }
24
+ contact_info = {
25
+ phone_numbers: []
26
+ }
27
+ statistics = []
28
+ related_related_links = []
29
+ category_data = []
30
+ rank_by_country = []
31
+ contributing_subdomains = []
32
+
33
+ response.each_node do |node, path|
34
+ text = node.inner_xml
35
+ candidate_text = text.delete(',')
36
+ value = if integer_value?(candidate_text) && node.name != 'aws:Delta'
37
+ candidate_text.to_i
38
+ elsif float_value?(candidate_text)
39
+ candidate_text.to_f
40
+ elsif text.is_a?(String) && text.empty?
41
+ nil
42
+ else
43
+ text
44
+ end
45
+
46
+ if node.name == 'aws:RequestId'
47
+ @request_id ||= value
48
+ elsif node.name == 'aws:StatusCode'
49
+ @status_code ||= value
50
+ elsif node.name == 'aws:DataUrl' && path == "#{traffic_node_name}/aws:DataUrl"
51
+ @data_url = value
52
+ elsif node.name == 'aws:Asin' && path == "#{traffic_node_name}/aws:Asin"
53
+ @asin = value
54
+ elsif node.name == 'aws:Rank' && path == "#{traffic_node_name}/aws:Rank"
55
+ @rank = value
56
+ elsif node.name == 'aws:DataUrl' && path == "#{content_node_name}/aws:DataUrl"
57
+ content_data[:data_url] = value
58
+ elsif node.name == 'aws:Title' && path == "#{content_node_name}/aws:SiteData/aws:Title"
59
+ content_data[:site_title] = value
60
+ elsif node.name == 'aws:Description'
61
+ content_data[:site_description] = value
62
+ elsif node.name == 'aws:MedianLoadTime'
63
+ content_data[:speed_median_load_time] = value
64
+ elsif node.name == 'aws:Percentile'
65
+ content_data[:speed_percentile] = value
66
+ elsif node.name == 'aws:AdultContent'
67
+ content_data[:adult_content] = value
68
+ elsif node.name == 'aws:Locale'
69
+ content_data[:language_locale] = value
70
+ elsif node.name == 'aws:LinksInCount'
71
+ content_data[:links_in_count] = value
72
+ elsif node.name == 'aws:Domain' && path == "#{content_node_name}/aws:OwnedDomains/aws:OwnedDomain/aws:Domain"
73
+ content_data[:owned_domains] << { domain: value }
74
+ elsif node.name == 'aws:Title' && path == "#{content_node_name}/aws:OwnedDomains/aws:OwnedDomain/aws:Title"
75
+ content_data[:owned_domains] << { title: value }
76
+ elsif node.name == 'aws:OnlineSince'
77
+ content_data[:online_since] = value
78
+ elsif node.name == 'aws:DataUrl' && path == "#{root_node_name}/aws:ContactInfo/aws:DataUrl"
79
+ contact_info[:data_url] = value
80
+ elsif node.name == 'aws:OwnerName'
81
+ contact_info[:owner_name] = value
82
+ elsif node.name == 'aws:Email'
83
+ contact_info[:email] = value
84
+ elsif node.name == 'aws:PhysicalAddress'
85
+ contact_info[:physical_address] = value
86
+ elsif node.name == 'aws:CompanyStockTicker'
87
+ contact_info[:company_stock_ticker] = value
88
+ elsif node.name == 'aws:PhoneNumber'
89
+ contact_info[:phone_numbers] << value
90
+ elsif node.name == 'aws:DataUrl' && path == "#{related_links_node_name}/aws:DataUrl"
91
+ related_related_links << { data_url: value }
92
+ elsif node.name == 'aws:NavigableUrl' && path == "#{related_links_node_name}/aws:NavigableUrl"
93
+ related_related_links << { navigable_url: value }
94
+ elsif node.name == 'aws:Title' && path == "#{related_links_node_name}/aws:Title"
95
+ related_related_links << { title: value }
96
+ elsif node.name == 'aws:Title' && path == "#{categories_node_name}/aws:Title"
97
+ category_data << { title: value }
98
+ elsif node.name == 'aws:AbsolutePath' && path == "#{categories_node_name}/aws:AbsolutePath"
99
+ category_data << { absolute_path: value }
100
+ elsif node.name == 'aws:Months' && path == "#{statistic_node_name}/aws:TimeRange/aws:Months"
101
+ statistics << { time_range_months: value }
102
+ elsif node.name == 'aws:Days' && path == "#{statistic_node_name}/aws:TimeRange/aws:Days"
103
+ statistics << { time_range_days: value }
104
+ elsif node.name == 'aws:Value' && path == "#{statistic_node_name}/aws:Rank/aws:Value"
105
+ statistics << { rank_value: value }
106
+ elsif node.name == 'aws:Delta' && path == "#{statistic_node_name}/aws:Rank/aws:Delta"
107
+ statistics << { rank_delta: value }
108
+ elsif node.name == 'aws:Value' && path == "#{statistic_node_name}/aws:Reach/aws:Rank/aws:Value"
109
+ statistics << { reach_rank_value: value }
110
+ elsif node.name == 'aws:Delta' && path == "#{statistic_node_name}/aws:Reach/aws:Rank/aws:Delta"
111
+ statistics << { reach_rank_delta: value }
112
+ elsif node.name == 'aws:Value' && path == "#{statistic_node_name}/aws:Reach/aws:PerMillion/aws:Value"
113
+ statistics << { reach_per_million_value: value }
114
+ elsif node.name == 'aws:Delta' && path == "#{statistic_node_name}/aws:Reach/aws:PerMillion/aws:Delta"
115
+ statistics << { reach_per_million_delta: value }
116
+ elsif node.name == 'aws:Value' && path == "#{statistic_node_name}/aws:PageViews/aws:PerMillion/aws:Value"
117
+ statistics << { page_views_per_million_value: value }
118
+ elsif node.name == 'aws:Delta' && path == "#{statistic_node_name}/aws:PageViews/aws:PerMillion/aws:Delta"
119
+ statistics << { page_views_per_million_delta: value }
120
+ elsif node.name == 'aws:Value' && path == "#{statistic_node_name}/aws:PageViews/aws:Rank/aws:Value"
121
+ statistics << { page_views_rank_value: value }
122
+ elsif node.name == 'aws:Delta' && path == "#{statistic_node_name}/aws:PageViews/aws:Rank/aws:Delta"
123
+ statistics << { page_views_rank_delta: value }
124
+ elsif node.name == 'aws:Value' && path == "#{statistic_node_name}/aws:PageViews/aws:PerUser/aws:Value"
125
+ statistics << { page_views_per_user_value: value }
126
+ elsif node.name == 'aws:Delta' && path == "#{statistic_node_name}/aws:PageViews/aws:PerUser/aws:Delta"
127
+ statistics << { page_views_per_user_delta: value }
128
+ elsif node.name == 'aws:Country' && path == rank_by_country_node_name
129
+ rank_by_country << { country_code: node.attributes['Code'] }
130
+ elsif node.name == 'aws:Rank' && path == "#{rank_by_country_node_name}/aws:Rank"
131
+ rank_by_country << { rank: value }
132
+ elsif node.name == 'aws:PageViews' && path == "#{rank_by_country_node_name}/aws:Contribution/aws:PageViews"
133
+ rank_by_country << { contribution_page_views: value }
134
+ elsif node.name == 'aws:Users' && path == "#{rank_by_country_node_name}/aws:Contribution/aws:Users"
135
+ rank_by_country << { contribution_users: value }
136
+ elsif node.name == 'aws:DataUrl' && path == "#{contributing_subdomains_node_name}/aws:DataUrl"
137
+ contributing_subdomains << { data_url: value }
138
+ elsif node.name == 'aws:Months' && path == "#{contributing_subdomains_node_name}/aws:TimeRange/aws:Months"
139
+ contributing_subdomains << { time_range_months: value }
140
+ elsif node.name == 'aws:Percentage' && path == "#{contributing_subdomains_node_name}/aws:Reach/aws:Percentage"
141
+ contributing_subdomains << { reach_percentage: value }
142
+ elsif node.name == 'aws:Percentage' && path == "#{contributing_subdomains_node_name}/aws:PageViews/aws:Percentage"
143
+ contributing_subdomains << { page_views_percentage: value }
144
+ elsif node.name == 'aws:PerUser' && path == "#{contributing_subdomains_node_name}/aws:PageViews/aws:PerUser"
145
+ contributing_subdomains << { page_views_per_user: value }
146
+ end
147
+ end
148
+
149
+ init_entity_data('content_data', content_data, ContentData)
150
+ init_entity_data('contact_info', contact_info, ContactInfo)
151
+
152
+ relationship_collections(@usage_statistics, statistics, 13, UsageStatistic)
153
+ relationship_collections(@related_links, related_related_links, 3, RelatedLink)
154
+ relationship_collections(@categories, category_data, 3, CategoryData)
155
+ relationship_collections(@rank_by_country, rank_by_country, 4, RankByCountry)
156
+ relationship_collections(@contributing_subdomains, contributing_subdomains, 5, ContributingSubdomain)
157
+ end
158
+
159
+ def is_404?
160
+ success? && rank == 404
161
+ end
162
+
163
+ def init_entity_data(attr_name, data, kclass)
164
+ return if data.empty?
165
+
166
+ instance_variable_set("@#{attr_name}", kclass.new(data))
167
+ end
168
+
169
+ def content_node_name
170
+ "#{root_node_name}/aws:ContentData"
171
+ end
172
+
173
+ def related_node_name
174
+ "#{root_node_name}/aws:Related"
175
+ end
176
+
177
+ def related_links_node_name
178
+ "#{related_node_name}/aws:RelatedLinks/aws:RelatedLink"
179
+ end
180
+
181
+ def categories_node_name
182
+ "#{related_node_name}/aws:Categories/aws:CategoryData"
183
+ end
184
+
185
+ def traffic_node_name
186
+ "#{root_node_name}/aws:TrafficData"
187
+ end
188
+
189
+ def statistic_node_name
190
+ "#{traffic_node_name}/aws:UsageStatistics/aws:UsageStatistic"
191
+ end
192
+
193
+ def contributing_subdomains_node_name
194
+ "#{traffic_node_name}/aws:ContributingSubdomains/aws:ContributingSubdomain"
195
+ end
196
+
197
+ def rank_by_country_node_name
198
+ "#{traffic_node_name}/aws:RankByCountry/aws:Country"
199
+ end
200
+
201
+ def has_data?
202
+ !@rank.nil?
203
+ end
204
+
205
+ def geos_sorted
206
+ rank_by_country.select { |rbc| !rbc.rank.nil? && !rbc.contribution_page_views.nil? }.
207
+ sort_by { |rbc| - rbc.contribution_page_views.round }.
208
+ map { |rbc| { rbc.country_code => rbc.contribution_page_views.round } }
209
+ end
210
+
211
+ def geos_hash
212
+ @geos_hash ||= geos_sorted.reduce({}, :merge)
213
+ end
214
+
215
+ def domains
216
+ content_data.owned_domains.map(&:domain)
217
+ end
218
+
219
+ def contributing_hostnames
220
+ contributing_subdomains.map(&:data_url).reject { |hostname| hostname == 'OTHER' }
221
+ end
222
+
223
+ def pvs_per_user
224
+ usage_statistics.first.page_views_per_user_value
225
+ end
226
+
227
+ def pvs_rank
228
+ usage_statistics.first.page_views_rank_value
229
+ end
230
+
231
+ def get_pvs_per_mil
232
+ usage_statistics.first.page_views_per_million_value
233
+ end
234
+
235
+ def speed_percentile
236
+ content_data.speed_percentile
237
+ end
238
+
239
+ def get_median_load_time
240
+ content_data.speed_median_load_time
241
+ end
242
+
243
+ def daily_GDN_page_views
244
+ if rank
245
+ alexa_gdn.each do |max_pvs, gdn_range|
246
+ return gdn_range if rank > max_pvs
247
+ end
248
+ end
249
+ end
250
+
251
+ def speed_rating
252
+ if get_median_load_time
253
+ alexa_speed_rating.each do |max_load_time, rating|
254
+ return rating if get_median_load_time > max_load_time
255
+ end
256
+ end
257
+ 'AVERAGE ( < 5s)'
258
+ end
259
+
260
+ def alexa_speed_rating
261
+ {
262
+ 2200 => 'POOR ( > 5s)',
263
+ 1200 => 'AVERAGE ( < 5s)',
264
+ 0 => 'GOOD ( < 3s)'
265
+ }
266
+ end
267
+
268
+ def rank_page_view
269
+ {
270
+ 20000 => '< 1K',
271
+ 5000 => '1K - 10K',
272
+ 3000 => '10K - 100K',
273
+ 1900 => '100K - 500K',
274
+ 1300 => '500K - 1M',
275
+ 850 => '2M - 5M',
276
+ 550 => '5M - 10M',
277
+ 350 => '10M - 20M',
278
+ 200 => '20M - 50M',
279
+ 100 => '50M - 100M',
280
+ 28 => '100M+'
281
+ }
282
+ end
283
+
284
+ def alexa_gdn
285
+ {
286
+ 250000 => '< 1K',
287
+ 100000 => '1K - 10K',
288
+ 50000 => '10K - 100K',
289
+ 20000 => '100K - 500K',
290
+ 10000 => '500K - 1M',
291
+ 5000 => '1M - 2M',
292
+ 2000 => '2M - 5M',
293
+ 1000 => '5M - 10M',
294
+ 500 => '10M - 20M',
295
+ 150 => '20M - 50M',
296
+ 30 => '50M - 100M',
297
+ 0 => '100M+'
298
+ }
299
+ end
300
+
301
+ private
302
+
303
+ def integer_value?(text)
304
+ text.to_i.to_s == text
305
+ end
306
+
307
+ def float_value?(text)
308
+ !!Float(text.delete('%'))
309
+ rescue ::StandardError
310
+ false
311
+ end
312
+ end
313
+
314
+ class ContentData < BaseEntity
315
+ attr_accessor :data_url, :site_title, :site_description, :online_since, :speed_median_load_time, :speed_percentile, :adult_content,
316
+ :language_locale, :links_in_count, :owned_domains
317
+
318
+ def initialize(options)
319
+ @owned_domains = []
320
+ owned_domain_objects = options.delete(:owned_domains)
321
+ super(options)
322
+ owned_domains_relationship_collections(@owned_domains, owned_domain_objects, 2, OwnedDomain)
323
+ end
324
+
325
+ def owned_domains_relationship_collections(item_object, items, items_count, kclass)
326
+ return if items.empty?
327
+
328
+ all_items = {}.array_slice_merge!(:item, items, items_count)
329
+ all_items.map { |item| item_object << kclass.new(item) }
330
+ end
331
+ end
332
+
333
+ class OwnedDomain < BaseEntity
334
+ attr_accessor :domain, :title
335
+ end
336
+
337
+ class ContactInfo < BaseEntity
338
+ attr_accessor :data_url, :owner_name, :email, :physical_address, :company_stock_ticker, :phone_numbers
339
+
340
+ def initialize(options)
341
+ phone_numbers = options.delete(:phone_numbers)
342
+ super(options)
343
+ phone_number_collections(phone_numbers)
344
+ end
345
+
346
+ def phone_number_collections(phone_numbers)
347
+ return @phone_numbers = [] if phone_numbers.nil? || phone_numbers.empty?
348
+
349
+ phone_numbers.map { |item| @phone_numbers << PhoneNumber.new(item) }
350
+ end
351
+ end
352
+
353
+ class PhoneNumber < BaseEntity
354
+ attr_accessor :number
355
+ end
356
+
357
+ class RelatedLink < BaseEntity
358
+ attr_accessor :data_url, :navigable_url, :title
359
+ end
360
+
361
+ class CategoryData < BaseEntity
362
+ attr_accessor :title, :absolute_path
363
+ end
364
+
365
+ class UsageStatistic < BaseEntity
366
+ attr_accessor :time_range_months, :time_range_days, :rank_value, :rank_delta,
367
+ :reach_rank_value, :reach_rank_delta,
368
+ :reach_per_million_value, :reach_per_million_delta,
369
+ :page_views_per_million_value, :page_views_per_million_delta,
370
+ :page_views_rank_value, :page_views_rank_delta,
371
+ :page_views_per_user_value, :page_views_per_user_delta
372
+
373
+ def range_type
374
+ return 'month' unless time_range_months.nil? || time_range_months.empty?
375
+
376
+ 'day'
377
+ end
378
+
379
+ def range_count
380
+ (time_range_months || time_range_days)
381
+ end
382
+ end
383
+
384
+ class ContributingSubdomain < BaseEntity
385
+ attr_accessor :data_url, :time_range_months, :reach_percentage, :page_views_percentage, :page_views_per_user
386
+ end
387
+
388
+ class RankByCountry < BaseEntity
389
+ attr_accessor :country_code, :rank, :contribution_page_views, :contribution_users
390
+ end
391
+ end
392
+ end