From a84e4e694961d395d0213fa2657f099eaa83b72c Mon Sep 17 00:00:00 2001 From: Dan Milne Date: Fri, 20 Sep 2019 08:17:42 +1000 Subject: [PATCH] Update readme --- README.md | 4 ++-- lib/paapi.rb | 5 ++++ lib/paapi/client.rb | 15 ++++++++---- lib/paapi/item.rb | 54 ++++++++++++++++++++++++++++++++++++++++--- lib/paapi/response.rb | 35 ++++++++++++++++++++++++++-- lib/paapi/version.rb | 2 +- 6 files changed, 102 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index c5cdd78..1b14719 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ `paapi` is a slim wrapper around [Amazon's Product Advertising API 5.0](https://webservices.amazon.com/paapi5/documentation/). -This gem is under development and currently incomplete. +This gem is under heavy development and currently incomplete. ## Installation @@ -24,7 +24,7 @@ Or install it yourself as: ### Configuration -The library can be initialised with a Rails initializer such as +The library can be configured with an initializer. For Rails, create the file `config/initializers/paapi.rb` ```ruby Paapi.configure do |config| diff --git a/lib/paapi.rb b/lib/paapi.rb index 80c4d88..c2cb44e 100644 --- a/lib/paapi.rb +++ b/lib/paapi.rb @@ -81,4 +81,9 @@ module Paapi end alias_method :config, :configure end + + def symbolize_keys(hash) + Hash[hash.map{|k,v| v.is_a?(Hash) ? [k.to_sym, symbolize_keys(v)] : [k.to_sym, v] }] + end end + diff --git a/lib/paapi/client.rb b/lib/paapi/client.rb index 315f3b9..f44df07 100644 --- a/lib/paapi/client.rb +++ b/lib/paapi/client.rb @@ -36,20 +36,25 @@ module Paapi res = do_request(op: :get_items, payload: payload) - Response.new(res) + # Errors, ItemResults -> Items -> Item + return Response.new(res) end def get_variations(asin:, **options ) payload = { ASIN: asin, Resources: @resources } res = do_request(op: :get_variations, payload: payload) - Response.new(res) + + # Errors, VariationsResult->Items + Response.new(res) end - def search_items(keywords:, **options ) - search_index = 'All' - # %i[Keywords Actor Artist Author Brand Title ] + # TODO: Currently we assume Keywords, but we need one of the follow: [Keywords Actor Artist Author Brand Title ] + def search_items(keywords: nil, **options ) + raise ArgumentError("Missing keywords") unless (options.keys | SEARCH_PARAMS).length.positive? + + search_index = options.dig(:SearchIndex) ||'All' payload = { Keywords: keywords, Resources: @resources, ItemCount: 10, ItemPage: 1, SearchIndex: search_index }.merge(options) diff --git a/lib/paapi/item.rb b/lib/paapi/item.rb index 9b8fb4c..e17cef4 100644 --- a/lib/paapi/item.rb +++ b/lib/paapi/item.rb @@ -1,3 +1,5 @@ +require 'nameable' + module Paapi class Item attr_accessor :raw @@ -20,13 +22,51 @@ module Paapi def title get(%w{ItemInfo Title DisplayValue}) end + + def manufacturer + get(%w{ItemInfo ByLineInfo Manufacturer DisplayValue}) + end + + def publisher + manufacturer + end + + def publication_date + d = get(%w{ItemInfo ContentInfo PublicationDate DisplayValue}) + return d.nil? ? nil : Date.parse(d) + end + + def release_date + d = get(%w{ItemInfo ProductInfo ReleaseDate DisplayValue}) + return d.nil? ? nil : Date.parse(d) + end def contributors get(%w{ItemInfo ByLineInfo Contributors}) end - + + def contributors_of(kind) + contributors&.select { |e| e['Role'] == kind }&.map { |e| Nameable(e['Name'])} + end + def authors - a = contributors.select { |e| e['Role'] == 'Author' }.map { |e| Nameable(e['Name'])} + contributors_of 'Author' + end + + def illustrators + contributors_of 'Illustrator' + end + + def actors + contributors_of 'Actor' + end + + def narrators + contributors_of 'Narrator' + end + + def publishers + contributors_of 'Publisher' end def release_date @@ -44,6 +84,10 @@ module Paapi def features get(%w{ItemInfo Features DisplayValues})&.join(' ') end + + def brand + get(%w{ItemInfo ByLineInfo Brand DisplayValue}) + end def part_number get(%w{ItemInfo ManufactureInfo ItemPartNumber DisplayValue}) @@ -60,6 +104,10 @@ module Paapi def get(keys) @raw.dig(*keys) end - + + def self.to_items(data) + data.map {|d| Item.new(d)} + end + end end \ No newline at end of file diff --git a/lib/paapi/response.rb b/lib/paapi/response.rb index 8752477..6e12706 100644 --- a/lib/paapi/response.rb +++ b/lib/paapi/response.rb @@ -2,10 +2,41 @@ require 'json' module Paapi class Response - attr_reader :http_response, :data + attr_reader :http_response, :data, :datas, :doc, :items + def initialize(response) @http_response = response - @data = JSON.parse( response.body.to_s ) + @data = JSON.parse(response.body.to_s) + + @datas = symbolise(JSON.parse(response.body.to_s)) + @doc = JSON.parse(@datas.to_json, object_class: OpenStruct) + + @items_data = @data.dig('ItemsResult', 'Items') + @items_data ||= @data.dig('SearchResult', 'Items') + @items_data ||= [] + + @items = @items_data.map {|d| Item.new(d)} + end + + def snake_case(s) + return s.downcase if s.match(/\A[A-Z]+\z/) + s.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2'). + gsub(/([a-z])([A-Z])/, '\1_\2'). + downcase + end + + def symbolise(obj) + if obj.is_a? Hash + return obj.inject({}) do |memo, (k, v)| + memo.tap { |m| m[snake_case(k)] = symbolise(v) } + end + elsif obj.is_a? Array + return obj.map { |memo| symbolise(memo) } + end + obj + end + + end end \ No newline at end of file diff --git a/lib/paapi/version.rb b/lib/paapi/version.rb index 098f67a..187e67d 100644 --- a/lib/paapi/version.rb +++ b/lib/paapi/version.rb @@ -1,3 +1,3 @@ module Paapi - VERSION = '0.0.2' + VERSION = '0.0.3' end