awis-sdk-ruby_ 1.1.1p1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/.rubocop.yml +87 -0
- data/.travis.yml +12 -0
- data/Gemfile +8 -0
- data/README.md +179 -0
- data/Rakefile +13 -0
- data/awis.gemspec +35 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/lib/awis.rb +22 -0
- data/lib/awis/api.rb +12 -0
- data/lib/awis/api/base.rb +54 -0
- data/lib/awis/api/category_browse.rb +43 -0
- data/lib/awis/api/category_listings.rb +58 -0
- data/lib/awis/api/sites_linking_in.rb +39 -0
- data/lib/awis/api/traffic_history.rb +43 -0
- data/lib/awis/api/url_info.rb +39 -0
- data/lib/awis/client.rb +46 -0
- data/lib/awis/config.rb +17 -0
- data/lib/awis/connection.rb +110 -0
- data/lib/awis/exceptions.rb +16 -0
- data/lib/awis/hash.rb +15 -0
- data/lib/awis/models.rb +13 -0
- data/lib/awis/models/base.rb +32 -0
- data/lib/awis/models/base_entity.rb +13 -0
- data/lib/awis/models/category_browse.rb +120 -0
- data/lib/awis/models/category_listings.rb +52 -0
- data/lib/awis/models/sites_linking_in.rb +39 -0
- data/lib/awis/models/traffic_history.rb +62 -0
- data/lib/awis/models/url_info.rb +392 -0
- data/lib/awis/utils.rb +10 -0
- data/lib/awis/utils/extra.rb +13 -0
- data/lib/awis/utils/hash.rb +11 -0
- data/lib/awis/utils/variable.rb +15 -0
- data/lib/awis/utils/xml.rb +38 -0
- data/lib/awis/version.rb +5 -0
- metadata +190 -0
@@ -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,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
|