paapi 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a4bac67043fb32a957f0b015eb468efbcc852b9e5285940ff152bdc012b4c751
4
- data.tar.gz: e4f35c14a82bf615d95167b869cb7b73c69cc85e7f05bd0ef1c37a96556b5b78
3
+ metadata.gz: c51a902c63c17b386688df97e49c8b201fb3309de82ace4b9e9b5d9f420923ff
4
+ data.tar.gz: c312da6d5bfb22c21b43f5449e616c48fcf661dfd08e9e4b2e106512c6c5575d
5
5
  SHA512:
6
- metadata.gz: 5943daef94869da7e96ca4d1b1b35fdd98f58f90bcebd7a00c24e1b11baf32cc5488986104b2d8edc95637076630437aaa2a5467683a8ca219e8a2a31b99aed4
7
- data.tar.gz: 7dd1fd49d4c63a6e6ff67d2881137f0c7bd5c0fe6e166a917929b3f08d69f1a31dbbf63d3d5720f75fce53f3ff67fe0b5b3d097858eff99c362e0731fed68aec
6
+ metadata.gz: f76777564d20118875ecb809a5c32c88a7d58245b3012947a4a55ac150e182e88cf34179de9e60999dd03b404cd9dea136346e12aec7199161ab122bf62f6f00
7
+ data.tar.gz: b2c64410108d2d2e4ce5e8bed0a1da8eee6d4fff83fd3c176b737e771d030cb5972c6e9cf84a3b26de2673f6b15116a622b7d3423b1bde252fbfd66c97e1dcdc
data/README.md CHANGED
@@ -2,7 +2,9 @@
2
2
 
3
3
  `paapi` is a slim wrapper around [Amazon's Product Advertising API 5.0](https://webservices.amazon.com/paapi5/documentation/).
4
4
 
5
- This gem is under development and currently incomplete.
5
+ This gem is under heavy development and currently incomplete.
6
+
7
+ [![Build Status](https://travis-ci.org/dkam/paapi.svg?branch=master)](https://travis-ci.org/dkam/paapi)
6
8
 
7
9
  ## Installation
8
10
 
@@ -24,7 +26,7 @@ Or install it yourself as:
24
26
 
25
27
  ### Configuration
26
28
 
27
- The library can be initialised with a Rails initializer such as
29
+ The library can be configured with an initializer. For Rails, create the file `config/initializers/paapi.rb`
28
30
 
29
31
  ```ruby
30
32
  Paapi.configure do |config|
@@ -83,6 +85,8 @@ gv = client.get_variations(asin: 'B00422MCUS')
83
85
 
84
86
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
85
87
 
88
+ If you create a file `config.rb`, it will be loaded by `bin/console`, allowing you to configure keys and markets.
89
+
86
90
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
87
91
 
88
92
  ## Contributing
data/bin/console CHANGED
@@ -11,4 +11,5 @@ require 'paapi'
11
11
  # Pry.start
12
12
 
13
13
  require 'irb'
14
+ load 'config.rb' if File.exist? 'config.rb'
14
15
  IRB.start(__FILE__)
data/lib/paapi/client.rb CHANGED
@@ -1,8 +1,9 @@
1
1
  require 'http'
2
+ require 'aws-sigv4'
2
3
 
3
4
  module Paapi
4
5
  class Client
5
- include AwsRequest
6
+
6
7
  attr_accessor :partner_tag, :marketplace, :resources
7
8
  attr_reader :partner_type, :access_key, :secret_key, :market
8
9
 
@@ -14,13 +15,14 @@ module Paapi
14
15
  partner_type: DEFAULT_PARTNER_TYPE
15
16
  )
16
17
  raise ArgumentError unless MARKETPLACES.keys.include?(market.to_sym)
18
+
17
19
  @access_key = access_key
18
20
  @secret_key = secret_key
19
21
  @partner_type = partner_type
20
22
  @resources = resources unless resources.nil?
21
23
 
22
24
  self.market = market
23
- @partner_tag = partner_tag if !partner_tag.nil?
25
+ @partner_tag = partner_tag if !partner_tag.nil?
24
26
  end
25
27
 
26
28
  def market=(a_market)
@@ -33,23 +35,14 @@ module Paapi
33
35
 
34
36
  def get_items(item_ids:, **options)
35
37
  payload = { ItemIds: Array(item_ids), Resources: @resources }
36
-
37
- res = do_request(op: :get_items, payload: payload)
38
-
39
- # Errors, ItemResults -> Items -> Item
40
- return Response.new(res)
38
+ request(op: :get_items, payload: payload)
41
39
  end
42
40
 
43
41
  def get_variations(asin:, **options )
44
42
  payload = { ASIN: asin, Resources: @resources }
45
-
46
- res = do_request(op: :get_variations, payload: payload)
47
-
48
- # Errors, VariationsResult->Items
49
- Response.new(res)
43
+ request(op: :get_variations, payload: payload)
50
44
  end
51
45
 
52
-
53
46
  # TODO: Currently we assume Keywords, but we need one of the follow: [Keywords Actor Artist Author Brand Title ]
54
47
  def search_items(keywords: nil, **options )
55
48
  raise ArgumentError("Missing keywords") unless (options.keys | SEARCH_PARAMS).length.positive?
@@ -58,18 +51,56 @@ module Paapi
58
51
 
59
52
  payload = { Keywords: keywords, Resources: @resources, ItemCount: 10, ItemPage: 1, SearchIndex: search_index }.merge(options)
60
53
 
61
- res = do_request(op: :search_items, payload: payload)
62
-
63
- Response.new(res)
54
+ request(op: :search_items, payload: payload)
64
55
  end
65
56
 
66
57
  def get_browse_nodes(browse_node_ids:, **options)
67
- resources = ['BrowseNodes.Ancestor', 'BrowseNodes.Children']
68
58
  payload = { BrowseNodeIds: Array(browse_node_ids), Resources: @resources }.merge(options)
69
-
70
- res = do_request(op: :get_browse_nodes, payload: payload)
71
-
72
- Response.new(res)
59
+ request(op: :get_browse_nodes, payload: payload)
60
+ end
61
+
62
+ private
63
+
64
+ def request(op:, payload:)
65
+ raise ArguemntError unless Paapi::OPERATIONS.keys.include?(op)
66
+
67
+ operation = OPERATIONS[op]
68
+
69
+ headers = {
70
+ 'X-Amz-Target' => "com.amazon.paapi5.v1.ProductAdvertisingAPIv1.#{operation.target_name}",
71
+ 'Content-Encoding' => 'amz-1.0',
72
+ }
73
+
74
+ default_payload = {
75
+ 'PartnerTag' => partner_tag,
76
+ 'PartnerType' => partner_type,
77
+ 'Marketplace' => marketplace.site
78
+ }
79
+
80
+ payload = default_payload.merge(payload)
81
+
82
+ endpoint = "https://#{marketplace.host}/paapi5/#{operation.endpoint_suffix}"
83
+
84
+ signer = Aws::Sigv4::Signer.new(
85
+ service: operation.service,
86
+ region: marketplace.region,
87
+ access_key_id: access_key,
88
+ secret_access_key: secret_key,
89
+ http_method: operation.http_method,
90
+ endpoint: marketplace.host
91
+ )
92
+
93
+ signature = signer.sign_request(http_method: operation.http_method, url: endpoint, headers: headers, body: payload.to_json)
94
+
95
+ headers['Host'] = marketplace.host
96
+ headers['X-Amz-Date'] = signature.headers['x-amz-date']
97
+ headers['X-Amz-Content-Sha256']= signature.headers['x-amz-content-sha256']
98
+ headers['Authorization'] = signature.headers['authorization']
99
+ headers['Content-Type'] = 'application/json; charset=utf-8'
100
+
101
+ Response.new( HTTP.headers(headers).post(endpoint, json: payload ) )
73
102
  end
74
103
  end
104
+
105
+
75
106
  end
data/lib/paapi/item.rb CHANGED
@@ -2,9 +2,13 @@ require 'nameable'
2
2
 
3
3
  module Paapi
4
4
  class Item
5
- attr_accessor :raw
5
+ attr_accessor :hash
6
6
  def initialize(data)
7
- @raw = data
7
+ @hash = data
8
+ end
9
+
10
+ def listings
11
+ get(['Offers', 'Listings']).map {|d| Listing.new(d)}
8
12
  end
9
13
 
10
14
  def asin
@@ -22,20 +26,20 @@ module Paapi
22
26
  def title
23
27
  get(%w{ItemInfo Title DisplayValue})
24
28
  end
25
-
29
+
26
30
  def manufacturer
27
31
  get(%w{ItemInfo ByLineInfo Manufacturer DisplayValue})
28
32
  end
29
-
33
+
30
34
  def publisher
31
35
  manufacturer
32
36
  end
33
-
37
+
34
38
  def publication_date
35
39
  d = get(%w{ItemInfo ContentInfo PublicationDate DisplayValue})
36
40
  return d.nil? ? nil : Date.parse(d)
37
41
  end
38
-
42
+
39
43
  def release_date
40
44
  d = get(%w{ItemInfo ProductInfo ReleaseDate DisplayValue})
41
45
  return d.nil? ? nil : Date.parse(d)
@@ -44,33 +48,33 @@ module Paapi
44
48
  def contributors
45
49
  get(%w{ItemInfo ByLineInfo Contributors})
46
50
  end
47
-
51
+
48
52
  def contributors_of(kind)
49
- contributors&.select { |e| e['Role'] == kind }&.map { |e| Nameable(e['Name'])}
53
+ contributors&.select { |e| e['Role'] == kind.to_s.gsub(/([[:alpha:]]+)/) { |w| w.capitalize } }&.map { |e| Nameable(e['Name'])}
50
54
  end
51
-
55
+
56
+ def actors
57
+ contributors_of 'Actor'
58
+ end
59
+
60
+ def artists
61
+ contributors_of 'Artist'
62
+ end
63
+
52
64
  def authors
53
65
  contributors_of 'Author'
54
66
  end
55
-
67
+
56
68
  def illustrators
57
69
  contributors_of 'Illustrator'
58
70
  end
59
-
60
- def actors
61
- contributors_of 'Actor'
62
- end
63
71
 
64
72
  def narrators
65
73
  contributors_of 'Narrator'
66
74
  end
67
-
68
- def publishers
69
- contributors_of 'Publisher'
70
- end
71
75
 
72
- def release_date
73
- get(%w{ItemInfo ReleaseDate})
76
+ def publishers
77
+ contributors_of 'Publisher'
74
78
  end
75
79
 
76
80
  def eans
@@ -84,7 +88,7 @@ module Paapi
84
88
  def features
85
89
  get(%w{ItemInfo Features DisplayValues})&.join(' ')
86
90
  end
87
-
91
+
88
92
  def brand
89
93
  get(%w{ItemInfo ByLineInfo Brand DisplayValue})
90
94
  end
@@ -93,6 +97,10 @@ module Paapi
93
97
  get(%w{ItemInfo ManufactureInfo ItemPartNumber DisplayValue})
94
98
  end
95
99
 
100
+ def model
101
+ get(%w{ItemInfo ManufactureInfo Model})
102
+ end
103
+
96
104
  def package
97
105
  get(%w{ItemInfo TechnicalInfo Formats DisplayValues})
98
106
  end
@@ -102,12 +110,12 @@ module Paapi
102
110
  end
103
111
 
104
112
  def get(keys)
105
- @raw.dig(*keys)
113
+ @hash.dig(*keys)
106
114
  end
107
-
115
+
108
116
  def self.to_items(data)
109
117
  data.map {|d| Item.new(d)}
110
118
  end
111
-
119
+
112
120
  end
113
121
  end
@@ -2,41 +2,25 @@ require 'json'
2
2
 
3
3
  module Paapi
4
4
  class Response
5
- attr_reader :http_response, :data, :datas, :doc, :items
5
+ attr_reader :http_response, :json, :datas, :doc, :items
6
6
 
7
7
  def initialize(response)
8
8
  @http_response = response
9
- @data = JSON.parse(response.body.to_s)
10
-
11
- @datas = symbolise(JSON.parse(response.body.to_s))
12
- @doc = JSON.parse(@datas.to_json, object_class: OpenStruct)
9
+ @json = JSON.parse(response.body.to_s)
13
10
 
14
- @items_data = @data.dig('ItemsResult', 'Items')
15
- @items_data ||= @data.dig('SearchResult', 'Items')
11
+ @items_data = @json.dig('ItemsResult', 'Items')
12
+ @items_data ||= @json.dig('SearchResult', 'Items')
16
13
  @items_data ||= []
17
-
14
+
18
15
  @items = @items_data.map {|d| Item.new(d)}
19
16
 
20
17
  end
21
-
22
- def snake_case(s)
23
- return s.downcase if s.match(/\A[A-Z]+\z/)
24
- s.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').
25
- gsub(/([a-z])([A-Z])/, '\1_\2').
26
- downcase
27
- end
28
-
29
- def symbolise(obj)
30
- if obj.is_a? Hash
31
- return obj.inject({}) do |memo, (k, v)|
32
- memo.tap { |m| m[snake_case(k)] = symbolise(v) }
33
- end
34
- elsif obj.is_a? Array
35
- return obj.map { |memo| symbolise(memo) }
36
- end
37
- obj
18
+
19
+ def result_count
20
+ @json.dig('SearchResult', 'TotalResultCount')
38
21
  end
39
22
 
40
-
23
+
24
+
41
25
  end
42
26
  end
data/lib/paapi/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Paapi
2
- VERSION = '0.0.3'
2
+ VERSION = '0.0.4'
3
3
  end
data/lib/paapi.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  require 'paapi/version'
2
2
 
3
- require 'paapi/aws_request'
4
3
  require 'paapi/client'
5
4
  require 'paapi/item'
6
5
  require 'paapi/response'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: paapi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dan Milne
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-09-19 00:00:00.000000000 Z
11
+ date: 2019-10-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -138,7 +138,6 @@ files:
138
138
  - bin/console
139
139
  - bin/setup
140
140
  - lib/paapi.rb
141
- - lib/paapi/aws_request.rb
142
141
  - lib/paapi/client.rb
143
142
  - lib/paapi/item.rb
144
143
  - lib/paapi/response.rb
@@ -1,47 +0,0 @@
1
- require 'http'
2
- require 'aws-sigv4'
3
-
4
- # https://webservices.amazon.com/paapi5/documentation/common-request-parameters.html
5
- module Paapi
6
- module AwsRequest
7
- def do_request(op:, payload:)
8
- raise ArguemntError unless Paapi::OPERATIONS.keys.include?(op)
9
-
10
- operation = OPERATIONS[op]
11
-
12
- headers = {
13
- 'X-Amz-Target' => "com.amazon.paapi5.v1.ProductAdvertisingAPIv1.#{operation.target_name}",
14
- 'Content-Encoding' => 'amz-1.0',
15
- }
16
-
17
- default_payload = {
18
- 'PartnerTag' => partner_tag,
19
- 'PartnerType' => partner_type,
20
- 'Marketplace' => marketplace.site
21
- }
22
-
23
- payload = default_payload.merge(payload)
24
-
25
- endpoint = "https://#{marketplace.host}/paapi5/#{operation.endpoint_suffix}"
26
-
27
- signer = Aws::Sigv4::Signer.new(
28
- service: operation.service,
29
- region: marketplace.region,
30
- access_key_id: access_key,
31
- secret_access_key: secret_key,
32
- http_method: operation.http_method,
33
- endpoint: marketplace.host
34
- )
35
-
36
- signature = signer.sign_request(http_method: operation.http_method, url: endpoint, headers: headers, body: payload.to_json)
37
-
38
- headers['Host'] = marketplace.host
39
- headers['X-Amz-Date'] = signature.headers['x-amz-date']
40
- headers['X-Amz-Content-Sha256']= signature.headers['x-amz-content-sha256']
41
- headers['Authorization'] = signature.headers['authorization']
42
- headers['Content-Type'] = 'application/json; charset=utf-8'
43
-
44
- HTTP.headers(headers).post(endpoint, json: payload )
45
- end
46
- end
47
- end