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.
- 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,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Awis
|
4
|
+
module API
|
5
|
+
class CategoryBrowse < Base
|
6
|
+
DEFAULT_RESPONSE_GROUP = %w[categories related_categories language_categories letter_bars].freeze
|
7
|
+
|
8
|
+
def load_request_uri(arguments = {})
|
9
|
+
validation_arguments!(arguments)
|
10
|
+
|
11
|
+
super(params)
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def before_validation_arguments(arguments)
|
17
|
+
raise ArgumentError, "Invalid arguments. should be like { path: 'Top/Arts' }" unless arguments.is_a?(Hash)
|
18
|
+
raise ArgumentError, 'Invalid arguments. the path must be configured.' unless arguments.key?(:path)
|
19
|
+
end
|
20
|
+
|
21
|
+
def validation_arguments!(arguments)
|
22
|
+
before_validation_arguments(arguments)
|
23
|
+
|
24
|
+
@arguments = arguments
|
25
|
+
@arguments[:response_group] = Array(arguments.fetch(:response_group, DEFAULT_RESPONSE_GROUP))
|
26
|
+
@arguments[:descriptions] = arguments.fetch(:descriptions, true)
|
27
|
+
end
|
28
|
+
|
29
|
+
def params
|
30
|
+
{
|
31
|
+
'Action' => action_name,
|
32
|
+
'ResponseGroup' => response_groups,
|
33
|
+
'Path' => arguments[:path],
|
34
|
+
'Descriptions' => request_description_params
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
def response_groups
|
39
|
+
arguments[:response_group].sort.map { |group| camelize(group) }.join(',')
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Awis
|
4
|
+
module API
|
5
|
+
class CategoryListings < Base
|
6
|
+
DEFAULT_RESPONSE_GROUP = %w[listings].freeze
|
7
|
+
|
8
|
+
def load_request_uri(arguments = {})
|
9
|
+
validation_arguments!(arguments)
|
10
|
+
|
11
|
+
super(params)
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def before_validation_arguments(arguments)
|
17
|
+
raise ArgumentError, "Invalid arguments. should be like { path: '/Top/Games/Card_Games' }" unless arguments.is_a?(Hash)
|
18
|
+
raise ArgumentError, 'Invalid arguments. the path must be configured.' unless arguments.key?(:path)
|
19
|
+
end
|
20
|
+
|
21
|
+
def validation_arguments!(arguments)
|
22
|
+
before_validation_arguments(arguments)
|
23
|
+
|
24
|
+
@arguments = arguments
|
25
|
+
@arguments[:sort_by] = arguments.fetch(:sort_by, 'popularity')
|
26
|
+
@arguments[:recursive] = arguments.fetch(:recursive, true)
|
27
|
+
@arguments[:descriptions] = arguments.fetch(:descriptions, true)
|
28
|
+
@arguments[:start] = arguments.fetch(:start, 0)
|
29
|
+
@arguments[:count] = arguments.fetch(:count, 20)
|
30
|
+
end
|
31
|
+
|
32
|
+
def params
|
33
|
+
{
|
34
|
+
'Action' => action_name,
|
35
|
+
'ResponseGroup' => response_groups,
|
36
|
+
'Path' => arguments[:path],
|
37
|
+
'Recursive' => recursive_param,
|
38
|
+
'Descriptions' => request_description_params,
|
39
|
+
'SortBy' => sort_by_param,
|
40
|
+
'Count' => arguments[:count],
|
41
|
+
'Start' => arguments[:start]
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
def recursive_param
|
46
|
+
arguments[:recursive].to_s.capitalize
|
47
|
+
end
|
48
|
+
|
49
|
+
def sort_by_param
|
50
|
+
camelize(arguments[:sort_by])
|
51
|
+
end
|
52
|
+
|
53
|
+
def response_groups
|
54
|
+
DEFAULT_RESPONSE_GROUP.map { |group| camelize(group) }.join(',')
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Awis
|
4
|
+
module API
|
5
|
+
class SitesLinkingIn < Base
|
6
|
+
DEFAULT_RESPONSE_GROUP = %w[sites_linking_in].freeze
|
7
|
+
|
8
|
+
def load_request_uri(arguments = {})
|
9
|
+
validation_arguments!(arguments)
|
10
|
+
|
11
|
+
super(params)
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def validation_arguments!(arguments)
|
17
|
+
before_validation_arguments(arguments)
|
18
|
+
|
19
|
+
@arguments = arguments
|
20
|
+
@arguments[:count] = arguments.fetch(:count, 20)
|
21
|
+
@arguments[:start] = arguments.fetch(:start, 0)
|
22
|
+
end
|
23
|
+
|
24
|
+
def params
|
25
|
+
{
|
26
|
+
'Action' => action_name,
|
27
|
+
'Url' => arguments[:url],
|
28
|
+
'ResponseGroup' => response_groups,
|
29
|
+
'Count' => arguments[:count],
|
30
|
+
'Start' => arguments[:start]
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
34
|
+
def response_groups
|
35
|
+
DEFAULT_RESPONSE_GROUP.map { |group| camelize(group) }.join(',')
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Awis
|
4
|
+
module API
|
5
|
+
class TrafficHistory < Base
|
6
|
+
DEFAULT_RESPONSE_GROUP = %w[history].freeze
|
7
|
+
|
8
|
+
def load_request_uri(arguments = {})
|
9
|
+
validation_arguments!(arguments)
|
10
|
+
|
11
|
+
super(params)
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def params
|
17
|
+
{
|
18
|
+
'Action' => action_name,
|
19
|
+
'Url' => arguments[:url],
|
20
|
+
'ResponseGroup' => response_groups,
|
21
|
+
'Range' => arguments[:range],
|
22
|
+
'Start' => start_date
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
def validation_arguments!(arguments)
|
27
|
+
before_validation_arguments(arguments)
|
28
|
+
|
29
|
+
@arguments = arguments
|
30
|
+
@arguments[:range] = arguments.fetch(:range, 31)
|
31
|
+
@arguments[:start] = arguments.fetch(:start) { Time.now - (3600 * 24 * @arguments[:range].to_i) }
|
32
|
+
end
|
33
|
+
|
34
|
+
def start_date
|
35
|
+
arguments[:start].respond_to?(:strftime) ? arguments[:start].strftime('%Y%m%d') : arguments[:start]
|
36
|
+
end
|
37
|
+
|
38
|
+
def response_groups
|
39
|
+
DEFAULT_RESPONSE_GROUP.map { |group| camelize(group) }.join(',')
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Awis
|
4
|
+
module API
|
5
|
+
class UrlInfo < Base
|
6
|
+
DEFAULT_RESPONSE_GROUP = %w[
|
7
|
+
related_links categories rank rank_by_country usage_stats
|
8
|
+
adult_content speed language owned_domains links_in_count site_data
|
9
|
+
].freeze
|
10
|
+
|
11
|
+
def load_request_uri(arguments = {})
|
12
|
+
validation_arguments!(arguments)
|
13
|
+
|
14
|
+
super(params)
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def validation_arguments!(arguments)
|
20
|
+
before_validation_arguments(arguments)
|
21
|
+
|
22
|
+
@arguments = arguments
|
23
|
+
@arguments[:response_group] = Array(arguments.fetch(:response_group, DEFAULT_RESPONSE_GROUP))
|
24
|
+
end
|
25
|
+
|
26
|
+
def params
|
27
|
+
{
|
28
|
+
'Action' => action_name,
|
29
|
+
'Url' => arguments[:url],
|
30
|
+
'ResponseGroup' => response_groups
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
34
|
+
def response_groups
|
35
|
+
arguments[:response_group].sort.map { |group| camelize(group) }.join(',')
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/awis/client.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Awis
|
4
|
+
class Client
|
5
|
+
def initialize
|
6
|
+
raise CertificateError, 'Amazon access certificate is missing!' if Awis.config.access_key_id.nil? || Awis.config.secret_access_key.nil?
|
7
|
+
end
|
8
|
+
|
9
|
+
def url_info(args)
|
10
|
+
parse_response_with_request('UrlInfo', args)
|
11
|
+
end
|
12
|
+
|
13
|
+
def traffic_history(args)
|
14
|
+
parse_response_with_request('TrafficHistory', args)
|
15
|
+
end
|
16
|
+
|
17
|
+
def sites_linking_in(args)
|
18
|
+
parse_response_with_request('SitesLinkingIn', args)
|
19
|
+
end
|
20
|
+
|
21
|
+
def category_browse(args)
|
22
|
+
parse_response_with_request('CategoryBrowse', args)
|
23
|
+
end
|
24
|
+
|
25
|
+
def category_listings(args)
|
26
|
+
parse_response_with_request('CategoryListings', args)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def parse_response_with_request(kclass, args)
|
32
|
+
case kclass
|
33
|
+
when 'UrlInfo'
|
34
|
+
Models::UrlInfo.new API::UrlInfo.new.fetch(args)
|
35
|
+
when 'SitesLinkingIn'
|
36
|
+
Models::SitesLinkingIn.new API::SitesLinkingIn.new.fetch(args)
|
37
|
+
when 'TrafficHistory'
|
38
|
+
Models::TrafficHistory.new API::TrafficHistory.new.fetch(args)
|
39
|
+
when 'CategoryBrowse'
|
40
|
+
Models::CategoryBrowse.new API::CategoryBrowse.new.fetch(args)
|
41
|
+
when 'CategoryListings'
|
42
|
+
Models::CategoryListings.new API::CategoryListings.new.fetch(args)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/lib/awis/config.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'singleton'
|
4
|
+
|
5
|
+
module Awis
|
6
|
+
class Config
|
7
|
+
include Singleton
|
8
|
+
attr_accessor :access_key_id, :secret_access_key, :proxy, :debug, :protocol,
|
9
|
+
:timeout, :open_timeout, :logger
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.config
|
13
|
+
yield Config.instance if block_given?
|
14
|
+
|
15
|
+
Config.instance
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'cgi'
|
4
|
+
require 'aws-sigv4'
|
5
|
+
require 'net/https'
|
6
|
+
|
7
|
+
module Awis
|
8
|
+
class Connection
|
9
|
+
attr_accessor :debug, :protocol
|
10
|
+
attr_reader :params, :secret_access_key, :access_key_id
|
11
|
+
|
12
|
+
HEADERS = {
|
13
|
+
'accept' => 'application/xml',
|
14
|
+
'content-type' => 'application/xml',
|
15
|
+
'user-agent' => "awis-sdk-ruby v#{Awis::VERSION}"
|
16
|
+
}.freeze
|
17
|
+
|
18
|
+
def initialize(options = {})
|
19
|
+
@secret_access_key = options.fetch(:secret_access_key, Awis.config.secret_access_key)
|
20
|
+
@access_key_id = options.fetch(:access_key_id, Awis.config.access_key_id)
|
21
|
+
raise CertificateError, 'Amazon access certificate is missing!' if @secret_access_key.nil? || @access_key_id.nil?
|
22
|
+
|
23
|
+
setup_options!
|
24
|
+
end
|
25
|
+
|
26
|
+
def setup_options!
|
27
|
+
@debug = Awis.config.debug || false
|
28
|
+
@protocol = Awis.config.protocol || 'https'
|
29
|
+
@timeout = Awis.config.timeout || 10
|
30
|
+
@open_timeout = Awis.config.open_timeout || 10
|
31
|
+
end
|
32
|
+
|
33
|
+
def get(params = {})
|
34
|
+
@params = params
|
35
|
+
handle_response(request).body
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def handle_response(response)
|
41
|
+
case response
|
42
|
+
when Net::HTTPSuccess
|
43
|
+
response
|
44
|
+
else
|
45
|
+
handle_error_response(response)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def handle_error_response(response)
|
50
|
+
case response.code.to_i
|
51
|
+
when 300...600
|
52
|
+
if response.body.nil?
|
53
|
+
raise ResponseError.new(nil, response)
|
54
|
+
else
|
55
|
+
error_message = MultiXml.parse(response.body).deep_find('ErrorCode')
|
56
|
+
raise ResponseError.new(error_message, response)
|
57
|
+
end
|
58
|
+
else
|
59
|
+
raise ResponseError.new("Unknown code: #{response.code}", response)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def request
|
64
|
+
req = Net::HTTP::Get.new(uri)
|
65
|
+
headers.each do |key, value|
|
66
|
+
req[key] = value
|
67
|
+
end
|
68
|
+
Net::HTTP.start(
|
69
|
+
uri.hostname,
|
70
|
+
uri.port,
|
71
|
+
use_ssl: uri.scheme == 'https',
|
72
|
+
ssl_timeout: @timeout,
|
73
|
+
open_timeout: @open_timeout
|
74
|
+
) do |http|
|
75
|
+
http.request(req)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def uri
|
80
|
+
@uri ||= URI.parse("#{protocol}://#{Awis::SERVICE_HOST}/#{Awis::SERVICE_PATH}?#{query}")
|
81
|
+
end
|
82
|
+
|
83
|
+
def headers
|
84
|
+
HEADERS.merge(auth_headers)
|
85
|
+
end
|
86
|
+
|
87
|
+
def auth_headers
|
88
|
+
signer.sign_request(
|
89
|
+
http_method: 'GET',
|
90
|
+
headers: HEADERS,
|
91
|
+
url: uri.to_s
|
92
|
+
).headers
|
93
|
+
end
|
94
|
+
|
95
|
+
def signer
|
96
|
+
Aws::Sigv4::Signer.new(
|
97
|
+
service: Awis::SERVICE_NAME,
|
98
|
+
region: Awis::SERVICE_REGION,
|
99
|
+
access_key_id: access_key_id,
|
100
|
+
secret_access_key: secret_access_key
|
101
|
+
)
|
102
|
+
end
|
103
|
+
|
104
|
+
def query
|
105
|
+
params.map do |key, value|
|
106
|
+
"#{key}=#{CGI.escape(value.to_s)}"
|
107
|
+
end.sort!.join('&')
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Awis
|
4
|
+
# Awis exceptions can be caught by rescuing: Awis::StandardError
|
5
|
+
|
6
|
+
class CertificateError < StandardError; end
|
7
|
+
|
8
|
+
class ResponseError < StandardError
|
9
|
+
attr_reader :response
|
10
|
+
|
11
|
+
def initialize(message, response)
|
12
|
+
@response = response
|
13
|
+
super(message)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/awis/hash.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Hash
|
4
|
+
def array_slice_merge!(key, array, count)
|
5
|
+
self[key] = array.each_slice(count).collect { |e| e.reduce({}, :merge) }
|
6
|
+
end
|
7
|
+
|
8
|
+
def deep_find(key, object = self, found = nil)
|
9
|
+
return object[key] if object.respond_to?(:key?) && object.key?(key)
|
10
|
+
return found unless object.is_a?(Enumerable)
|
11
|
+
|
12
|
+
object.find { |*a| found = deep_find(key, a.last) }
|
13
|
+
found
|
14
|
+
end
|
15
|
+
end
|
data/lib/awis/models.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Awis
|
4
|
+
module Models
|
5
|
+
autoload :Base, 'awis/models/base'
|
6
|
+
autoload :BaseEntity, 'awis/models/base_entity'
|
7
|
+
autoload :UrlInfo, 'awis/models/url_info'
|
8
|
+
autoload :TrafficHistory, 'awis/models/traffic_history'
|
9
|
+
autoload :SitesLinkingIn, 'awis/models/sites_linking_in'
|
10
|
+
autoload :CategoryListings, 'awis/models/category_listings'
|
11
|
+
autoload :CategoryBrowse, 'awis/models/category_browse'
|
12
|
+
end
|
13
|
+
end
|