bestbuy_api 0.1.0 → 1.0.0
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 +4 -4
- data/.reek.yml +3 -0
- data/.rubocop.yml +3 -1
- data/README.md +2 -0
- data/lib/bestbuy_api.rb +0 -2
- data/lib/bestbuy_api/category.rb +5 -7
- data/lib/bestbuy_api/criteria.rb +21 -15
- data/lib/bestbuy_api/model.rb +14 -1
- data/lib/bestbuy_api/params.rb +53 -0
- data/lib/bestbuy_api/product.rb +18 -17
- data/lib/bestbuy_api/request.rb +9 -66
- data/lib/bestbuy_api/response.rb +22 -0
- data/lib/bestbuy_api/store.rb +12 -11
- data/lib/bestbuy_api/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 30fe2e8e4bea5f47e2b7914ab5503254caad2b44196d2f78a1ce80a141cadbaa
|
4
|
+
data.tar.gz: 1748654ec2820ffec00ad63ecb5a9e4c4cfbd4831d0c662b61a1b526e8e288cb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a03f206f578e31ebf60120de11a6753aafdc78f884dd0f17dca2caaa11857ed3a125f6e68e2d098bbaf49f1a085cb8f470b3ab547c91be08f0344866b12d9c35
|
7
|
+
data.tar.gz: cb3fd58846fb529926735e7259808b12e6305f0a1f5127bbef81d91deda0fa312b1e581322b89999d82a6de674d6b43b5e913227f2256a702ef80359d21a8778
|
data/.reek.yml
ADDED
data/.rubocop.yml
CHANGED
data/README.md
CHANGED
data/lib/bestbuy_api.rb
CHANGED
@@ -3,8 +3,6 @@ require 'bestbuy_api/product'
|
|
3
3
|
require 'bestbuy_api/store'
|
4
4
|
require 'bestbuy_api/category'
|
5
5
|
|
6
|
-
# Handles BestBuy api queries. Documentation is located at
|
7
|
-
# https://bestbuyapis.github.io/api-documentation.
|
8
6
|
module BestbuyApi
|
9
7
|
class << self
|
10
8
|
attr_accessor :api_key
|
data/lib/bestbuy_api/category.rb
CHANGED
@@ -4,13 +4,11 @@ module BestbuyApi
|
|
4
4
|
# Defines the attributes for the categories api. Documentation is
|
5
5
|
# located at https://bestbuyapis.github.io/api-documentation/#categories-api.
|
6
6
|
class Category < Model
|
7
|
-
|
7
|
+
path 'categories'
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
subcategory_name: { kw: 'subCategories.name' }
|
14
|
-
}.freeze
|
9
|
+
attribute :id, search: true
|
10
|
+
attribute :name, search: true
|
11
|
+
attribute :subcategory_id, field: 'subCategories.id'
|
12
|
+
attribute :subcategory_name, field: 'subCategories.name'
|
15
13
|
end
|
16
14
|
end
|
data/lib/bestbuy_api/criteria.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
|
+
require_relative 'params'
|
2
|
+
require_relative 'request'
|
1
3
|
require 'forwardable'
|
2
4
|
|
3
5
|
module BestbuyApi
|
4
|
-
# Collect the parameters and validates the attributes
|
5
6
|
class Criteria
|
6
7
|
extend Forwardable
|
7
|
-
def_delegators :
|
8
|
+
def_delegators :response, :items, :pagination, :url
|
8
9
|
|
9
10
|
def initialize(klass)
|
10
11
|
@klass = klass
|
@@ -15,18 +16,14 @@ module BestbuyApi
|
|
15
16
|
end
|
16
17
|
|
17
18
|
def select(args)
|
18
|
-
|
19
|
-
attributes = @klass::ATTRIBUTES.select { |_k, v| v.key?(:read) ? v[:read] : true }
|
20
|
-
args.each { |k, _v| assert_keys(attributes.keys, k) }
|
19
|
+
assert_keys(args, @klass.attributes[:read])
|
21
20
|
|
22
21
|
criteria[:attributes] = args
|
23
22
|
self
|
24
23
|
end
|
25
24
|
|
26
25
|
def where(args)
|
27
|
-
|
28
|
-
attributes = @klass::ATTRIBUTES.select { |_k, v| v.key?(:search) && v[:search] }
|
29
|
-
args.each { |k, _v| assert_keys(attributes.keys, k) }
|
26
|
+
assert_keys(args, @klass.attributes[:search])
|
30
27
|
|
31
28
|
criteria[:conditions].merge!(args)
|
32
29
|
self
|
@@ -42,17 +39,26 @@ module BestbuyApi
|
|
42
39
|
self
|
43
40
|
end
|
44
41
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
@request ||= BestbuyApi::Request.new(@klass::PATH, @klass::ATTRIBUTES, criteria)
|
42
|
+
def response
|
43
|
+
params = Params.new(criteria, @klass.attributes)
|
44
|
+
request.find(params.structure)
|
49
45
|
end
|
50
46
|
|
51
|
-
|
52
|
-
return true if valid_keys.include?(key)
|
47
|
+
private
|
53
48
|
|
54
|
-
|
49
|
+
def assert_keys(args, attributes)
|
50
|
+
valid_keys = attributes.keys
|
51
|
+
args.each do |key, _v|
|
52
|
+
unless valid_keys.include?(key)
|
53
|
+
raise MissingAttributeError, "Unknown attribute: #{key.inspect}. Valid attributes are: " \
|
55
54
|
"#{valid_keys.map(&:inspect).join(', ')}"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def request
|
60
|
+
api_key = BestbuyApi.config.api_key
|
61
|
+
@request ||= Request.new(api_key, @klass.attributes[:path])
|
56
62
|
end
|
57
63
|
end
|
58
64
|
end
|
data/lib/bestbuy_api/model.rb
CHANGED
@@ -1,8 +1,21 @@
|
|
1
1
|
require_relative 'criteria'
|
2
2
|
|
3
3
|
module BestbuyApi
|
4
|
-
# Chains method calls to build up queries
|
5
4
|
class Model
|
5
|
+
def self.attributes
|
6
|
+
@attributes ||= { path: nil, read: {}, search: {} }
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.path(path = nil)
|
10
|
+
attributes[:path] = path
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.attribute(id, columns = { search: false, read: true })
|
14
|
+
row = { id => columns }
|
15
|
+
attributes[:read].merge!(row) unless columns[:read] == false
|
16
|
+
attributes[:search].merge!(row) unless columns[:search] == false
|
17
|
+
end
|
18
|
+
|
6
19
|
def self.select(*args)
|
7
20
|
Criteria.new(self).select(args.uniq)
|
8
21
|
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module BestbuyApi
|
2
|
+
class Params
|
3
|
+
def initialize(criteria, attributes)
|
4
|
+
@criteria = criteria
|
5
|
+
@attributes = attributes
|
6
|
+
end
|
7
|
+
|
8
|
+
def structure
|
9
|
+
{ slug: build_filters, query: build_response_options }
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def build_filters
|
15
|
+
collection = collect_search
|
16
|
+
collection.empty? ? '' : query_string(collection)
|
17
|
+
end
|
18
|
+
|
19
|
+
def build_response_options
|
20
|
+
query = @criteria.slice(:limit, :page)
|
21
|
+
query[:show] = collect_read
|
22
|
+
query
|
23
|
+
end
|
24
|
+
|
25
|
+
def collect_read
|
26
|
+
Array[@criteria[:attributes].map do |key|
|
27
|
+
elements = @attributes[:read]
|
28
|
+
if elements.key?(key)
|
29
|
+
attribute = elements[key]
|
30
|
+
attribute.key?(:field) ? attribute[:field] : key
|
31
|
+
end
|
32
|
+
end].join(',')
|
33
|
+
end
|
34
|
+
|
35
|
+
def collect_search
|
36
|
+
@criteria[:conditions].map do |key, value|
|
37
|
+
elements = @attributes[:search]
|
38
|
+
if elements.key?(key)
|
39
|
+
attribute = elements[key]
|
40
|
+
attribute.key?(:field) ? { attribute[:field] => value } : { key => value }
|
41
|
+
end
|
42
|
+
end.reduce({}, :merge)
|
43
|
+
end
|
44
|
+
|
45
|
+
def query_string(props)
|
46
|
+
search = props.delete('search')
|
47
|
+
uri = URI.encode_www_form(props)
|
48
|
+
search_query = "(search=#{search})" if search
|
49
|
+
uri = format("#{search_query}%<and>s", and: "&#{uri}") if search_query && uri
|
50
|
+
"(#{uri})"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/lib/bestbuy_api/product.rb
CHANGED
@@ -4,23 +4,24 @@ module BestbuyApi
|
|
4
4
|
# Defines the attributes for the products api. Documentation is
|
5
5
|
# located at https://bestbuyapis.github.io/api-documentation/#products-api.
|
6
6
|
class Product < Model
|
7
|
-
|
7
|
+
path 'products'
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
9
|
+
attribute :keyword, field: 'search', search: true, read: false
|
10
|
+
attribute :sku, search: true
|
11
|
+
attribute :category_id, field: 'categoryPath.id', search: true
|
12
|
+
attribute :category_name, field: 'categoryPath.name', search: true
|
13
|
+
attribute :condition, search: true
|
14
|
+
attribute :customer_rating, field: 'customerReviewAverage', search: true
|
15
|
+
attribute :manufacturer, search: true
|
16
|
+
attribute :regular_price, field: 'regularPrice'
|
17
|
+
attribute :sale_price, field: 'salePrice'
|
18
|
+
attribute :shipping_cost, field: 'shippingCost'
|
19
|
+
attribute :reviews_count, field: 'customerReviewCount'
|
20
|
+
attribute :discount, field: 'percentSavings'
|
21
|
+
attribute :free_shipping, field: 'freeShipping'
|
22
|
+
attribute :url
|
23
|
+
attribute :name
|
24
|
+
attribute :description
|
25
|
+
attribute :image
|
25
26
|
end
|
26
27
|
end
|
data/lib/bestbuy_api/request.rb
CHANGED
@@ -1,81 +1,24 @@
|
|
1
1
|
require 'httparty'
|
2
|
+
require_relative 'response'
|
2
3
|
|
3
4
|
module BestbuyApi
|
4
|
-
# Wrap HTTParty gem to query the api
|
5
5
|
class Request
|
6
6
|
include HTTParty
|
7
7
|
base_uri 'https://api.bestbuy.com/v1'
|
8
|
-
PAGE_VARS = %w[totalPages total currentPage].freeze
|
9
8
|
|
10
|
-
def initialize(
|
11
|
-
|
12
|
-
api_key = BestbuyApi.config.api_key
|
13
|
-
raise MissingApiKeyError, 'API Key is not defined' if api_key.nil?
|
9
|
+
def initialize(api_key, path)
|
10
|
+
raise MissingApiKeyError, 'API Key is not defined' if api_key.empty?
|
14
11
|
|
15
12
|
@path = path
|
16
|
-
@
|
17
|
-
@criteria = criteria
|
18
|
-
@query = { apiKey: api_key, format: 'json' }
|
13
|
+
@options = { apiKey: api_key, format: 'json' }
|
19
14
|
end
|
20
15
|
|
21
|
-
def
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
def pagination
|
26
|
-
response.select { |k| PAGE_VARS.include?(k) }
|
27
|
-
end
|
28
|
-
|
29
|
-
def url
|
30
|
-
response.request.last_uri.to_s
|
31
|
-
end
|
32
|
-
|
33
|
-
private
|
34
|
-
|
35
|
-
def response
|
36
|
-
@response ||= find
|
37
|
-
end
|
38
|
-
|
39
|
-
def find
|
40
|
-
response = self.class.get("/#{@path}#{slug}", query: params)
|
41
|
-
raise RequestError, "#{response.code} Request Error" if response.code != 200
|
42
|
-
|
43
|
-
response
|
44
|
-
end
|
45
|
-
|
46
|
-
# Collect attributes that are readable and substitute using kw or key
|
47
|
-
def slug
|
48
|
-
attributes = @attributes.select { |_k, v| v.key?(:search) && v[:search] }
|
49
|
-
opts = @criteria[:conditions].map do |k, v|
|
50
|
-
attributes[k].key?(:kw) ? { attributes[k][:kw] => v } : { k => v }
|
51
|
-
end
|
52
|
-
opts = opts.reduce({}, :merge)
|
53
|
-
|
54
|
-
encode_slug(opts)
|
55
|
-
end
|
56
|
-
|
57
|
-
# Collect attributes that are searchable and substitute using kw or key
|
58
|
-
def params
|
59
|
-
attributes = @attributes.select { |_k, v| v.key?(:read) ? v[:read] : true }
|
60
|
-
opts = Array[@criteria[:attributes].map do |k|
|
61
|
-
attributes[k].key?(:kw) ? attributes[k][:kw] : k
|
62
|
-
end].join(',')
|
63
|
-
|
64
|
-
join_fields(opts)
|
65
|
-
end
|
66
|
-
|
67
|
-
def encode_slug(opts)
|
68
|
-
search = opts.delete('search') if opts.key?('search')
|
69
|
-
slug = URI.encode_www_form(opts)
|
70
|
-
slug = format("(search=#{search})%<and>s", and: ("&#{slug}" unless slug.empty?)) if search
|
71
|
-
return "(#{slug})" unless slug.empty?
|
72
|
-
end
|
16
|
+
def find(params)
|
17
|
+
result = self.class.get("/#{@path}#{params[:slug]}", query: @options.merge(params[:query]))
|
18
|
+
code = result.code
|
19
|
+
raise RequestError, "#{code} Request Error: #{result.request.last_uri}" if code != 200
|
73
20
|
|
74
|
-
|
75
|
-
params = @criteria.slice(:limit, :page)
|
76
|
-
params[:show] = opts unless opts.empty?
|
77
|
-
@query.merge!(params) unless params.empty?
|
78
|
-
@query
|
21
|
+
Response.new(result, @path)
|
79
22
|
end
|
80
23
|
end
|
81
24
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module BestbuyApi
|
2
|
+
class Response
|
3
|
+
PAGE_VARS = %w[totalPages total currentPage].freeze
|
4
|
+
|
5
|
+
def initialize(result, path)
|
6
|
+
@result = result
|
7
|
+
@path = path
|
8
|
+
end
|
9
|
+
|
10
|
+
def items
|
11
|
+
@result[@path] if @result.key?(@path)
|
12
|
+
end
|
13
|
+
|
14
|
+
def pagination
|
15
|
+
@result.select { |key| PAGE_VARS.include?(key) }
|
16
|
+
end
|
17
|
+
|
18
|
+
def url
|
19
|
+
@result.request.last_uri.to_s
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/bestbuy_api/store.rb
CHANGED
@@ -1,20 +1,21 @@
|
|
1
1
|
require_relative 'model'
|
2
|
-
require_relative 'request'
|
3
2
|
|
4
3
|
module BestbuyApi
|
5
4
|
# Defines the attributes for the stores api. Documentation is
|
6
5
|
# located at https://bestbuyapis.github.io/api-documentation/#stores-api.
|
7
6
|
class Store < Model
|
8
|
-
|
7
|
+
path 'stores'
|
9
8
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
9
|
+
attribute :id, field: 'storeId', search: true
|
10
|
+
attribute :city, search: true
|
11
|
+
attribute :state, field: 'region', search: true
|
12
|
+
attribute :postal_code, field: 'fullPostalCode', search: true
|
13
|
+
attribute :store_type, field: 'storeType'
|
14
|
+
attribute :name
|
15
|
+
attribute :address
|
16
|
+
attribute :address2
|
17
|
+
attribute :country
|
18
|
+
attribute :hours
|
19
|
+
attribute :phone
|
19
20
|
end
|
20
21
|
end
|
data/lib/bestbuy_api/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bestbuy_api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael John Bayucot
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-01-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: httparty
|
@@ -128,6 +128,7 @@ extensions: []
|
|
128
128
|
extra_rdoc_files: []
|
129
129
|
files:
|
130
130
|
- ".gitignore"
|
131
|
+
- ".reek.yml"
|
131
132
|
- ".rspec"
|
132
133
|
- ".rubocop.yml"
|
133
134
|
- ".travis.yml"
|
@@ -141,8 +142,10 @@ files:
|
|
141
142
|
- lib/bestbuy_api/criteria.rb
|
142
143
|
- lib/bestbuy_api/exceptions.rb
|
143
144
|
- lib/bestbuy_api/model.rb
|
145
|
+
- lib/bestbuy_api/params.rb
|
144
146
|
- lib/bestbuy_api/product.rb
|
145
147
|
- lib/bestbuy_api/request.rb
|
148
|
+
- lib/bestbuy_api/response.rb
|
146
149
|
- lib/bestbuy_api/store.rb
|
147
150
|
- lib/bestbuy_api/version.rb
|
148
151
|
homepage: https://github.com/mbayucot/bestbuy-api
|