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,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
@@ -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
@@ -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
@@ -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
@@ -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