best_buy_ruby 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +21 -0
- data/.reek.yml +127 -0
- data/.rspec +3 -0
- data/.rubocop.yml +74 -0
- data/.travis.yml +33 -0
- data/CHANGELOG.md +10 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/CONTRIBUTING.md +42 -0
- data/Gemfile +5 -0
- data/LICENSE.txt +21 -0
- data/README.md +83 -0
- data/Rakefile +6 -0
- data/best_buy_ruby.gemspec +42 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/docs/categories_api.md +25 -0
- data/docs/general_overview.md +67 -0
- data/docs/products_api.md +85 -0
- data/docs/stores_api.md +68 -0
- data/lib/best_buy.rb +34 -0
- data/lib/best_buy/base.rb +13 -0
- data/lib/best_buy/base/version.rb +7 -0
- data/lib/best_buy/base_api.rb +46 -0
- data/lib/best_buy/categories.rb +23 -0
- data/lib/best_buy/config.rb +17 -0
- data/lib/best_buy/helpers/api_helper.rb +13 -0
- data/lib/best_buy/helpers/conditions/category_condition.rb +19 -0
- data/lib/best_buy/helpers/conditions/max_price_condition.rb +19 -0
- data/lib/best_buy/helpers/conditions/min_price_condition.rb +19 -0
- data/lib/best_buy/helpers/conditions/new_condition.rb +19 -0
- data/lib/best_buy/helpers/conditions/pre_owned_condition.rb +19 -0
- data/lib/best_buy/helpers/conditions/refurbished_condition.rb +19 -0
- data/lib/best_buy/models/address.rb +23 -0
- data/lib/best_buy/models/base_category.rb +12 -0
- data/lib/best_buy/models/category.rb +20 -0
- data/lib/best_buy/models/collection_header.rb +20 -0
- data/lib/best_buy/models/collections_response.rb +19 -0
- data/lib/best_buy/models/image.rb +16 -0
- data/lib/best_buy/models/offer.rb +18 -0
- data/lib/best_buy/models/product.rb +39 -0
- data/lib/best_buy/models/shipping_level_of_service.rb +13 -0
- data/lib/best_buy/models/store.rb +26 -0
- data/lib/best_buy/products.rb +53 -0
- data/lib/best_buy/search_query_builder.rb +21 -0
- data/lib/best_buy/stores.rb +30 -0
- data/lib/generators/best_buy/config/config_generator.rb +13 -0
- data/lib/generators/best_buy/config/templates/config.rb +5 -0
- metadata +234 -0
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BestBuy
|
4
|
+
module Conditions
|
5
|
+
class CategoryCondition
|
6
|
+
def initialize(condition_hash)
|
7
|
+
@category_id = condition_hash[:category_id]
|
8
|
+
end
|
9
|
+
|
10
|
+
def valid?
|
11
|
+
@category_id.present?
|
12
|
+
end
|
13
|
+
|
14
|
+
def search_query
|
15
|
+
"categoryPath.id=#{@category_id}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BestBuy
|
4
|
+
module Conditions
|
5
|
+
class MaxPriceCondition
|
6
|
+
def initialize(condition_hash)
|
7
|
+
@max_price = condition_hash[:max_price]
|
8
|
+
end
|
9
|
+
|
10
|
+
def valid?
|
11
|
+
@max_price.present?
|
12
|
+
end
|
13
|
+
|
14
|
+
def search_query
|
15
|
+
"((regularPrice<=#{@max_price}&onSale=false)|(salePrice<=#{@max_price}&onSale=true))"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BestBuy
|
4
|
+
module Conditions
|
5
|
+
class MinPriceCondition
|
6
|
+
def initialize(condition_hash)
|
7
|
+
@min_price = condition_hash[:min_price]
|
8
|
+
end
|
9
|
+
|
10
|
+
def valid?
|
11
|
+
@min_price.present?
|
12
|
+
end
|
13
|
+
|
14
|
+
def search_query
|
15
|
+
"((regularPrice>=#{@min_price}&onSale=false)|(salePrice>=#{@min_price}&onSale=true))"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BestBuy
|
4
|
+
module Conditions
|
5
|
+
class NewCondition
|
6
|
+
def initialize(condition_hash)
|
7
|
+
@item_condition = condition_hash[:item_condition]&.downcase
|
8
|
+
end
|
9
|
+
|
10
|
+
def valid?
|
11
|
+
@item_condition.present? && @item_condition == 'new'
|
12
|
+
end
|
13
|
+
|
14
|
+
def search_query
|
15
|
+
'(condition=new|new=true)'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BestBuy
|
4
|
+
module Conditions
|
5
|
+
class PreOwnedCondition
|
6
|
+
def initialize(condition_hash)
|
7
|
+
@item_condition = condition_hash[:item_condition]&.downcase
|
8
|
+
end
|
9
|
+
|
10
|
+
def valid?
|
11
|
+
@item_condition.present? && @item_condition == 'pre-owned'
|
12
|
+
end
|
13
|
+
|
14
|
+
def search_query
|
15
|
+
'(condition=pre-owned|preowned=true)'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BestBuy
|
4
|
+
module Conditions
|
5
|
+
class RefurbishedCondition
|
6
|
+
def initialize(condition_hash)
|
7
|
+
@item_condition = condition_hash[:item_condition]&.downcase
|
8
|
+
end
|
9
|
+
|
10
|
+
def valid?
|
11
|
+
@item_condition.present? && @item_condition == 'refurbished'
|
12
|
+
end
|
13
|
+
|
14
|
+
def search_query
|
15
|
+
'condition=refurbished'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BestBuy
|
4
|
+
# :reek:TooManyInstanceVariables
|
5
|
+
# :reek:UncommunicativeVariableName
|
6
|
+
class Address
|
7
|
+
attr_reader :address, :address2, :city, :country, :full_postal_code, :gmt_offset,
|
8
|
+
:lat, :lng, :postal_code, :region
|
9
|
+
|
10
|
+
def initialize(init_params)
|
11
|
+
@address = init_params[:address]
|
12
|
+
@address2 = init_params[:address2]
|
13
|
+
@city = init_params[:city]
|
14
|
+
@country = init_params[:country]
|
15
|
+
@full_postal_code = init_params[:full_postal_code]
|
16
|
+
@gmt_offset = init_params[:gmt_offset]
|
17
|
+
@lat = init_params[:lat]
|
18
|
+
@lng = init_params[:lng]
|
19
|
+
@postal_code = init_params[:postal_code]
|
20
|
+
@region = init_params[:region]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'best_buy'
|
4
|
+
|
5
|
+
module BestBuy
|
6
|
+
class Category < BaseCategory
|
7
|
+
attr_reader :url, :active, :path, :sub_categories
|
8
|
+
|
9
|
+
def initialize(init_params)
|
10
|
+
@url = init_params[:url]
|
11
|
+
@active = init_params[:active]
|
12
|
+
@path = init_params[:path]
|
13
|
+
@sub_categories = init_params[:sub_categories].map do |sub_category|
|
14
|
+
BaseCategory.new(sub_category)
|
15
|
+
end
|
16
|
+
|
17
|
+
super(init_params)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BestBuy
|
4
|
+
class CollectionHeader
|
5
|
+
attr_reader :canonical_url, :current_page, :from, :partial,
|
6
|
+
:query_time, :to, :total, :total_pages, :total_time
|
7
|
+
|
8
|
+
def initialize(init_params)
|
9
|
+
@canonical_url = init_params[:canonical_url]
|
10
|
+
@current_page = init_params[:current_page]
|
11
|
+
@from = init_params[:from]
|
12
|
+
@partial = init_params[:partial]
|
13
|
+
@query_time = init_params[:query_time]
|
14
|
+
@to = init_params[:to]
|
15
|
+
@total = init_params[:total]
|
16
|
+
@total_pages = init_params[:total_pages]
|
17
|
+
@total_time = init_params[:total_time]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'best_buy'
|
4
|
+
|
5
|
+
module BestBuy
|
6
|
+
class CollectionsResponse
|
7
|
+
attr_reader :header, :collection
|
8
|
+
|
9
|
+
def initialize(response:, collection_name:, collection_type:)
|
10
|
+
header_hash = response.except(collection_name)
|
11
|
+
collection_hash = response[collection_name]
|
12
|
+
|
13
|
+
@header = CollectionHeader.new(header_hash)
|
14
|
+
@collection = collection_hash.map do |collection_item|
|
15
|
+
collection_type.new(collection_item)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BestBuy
|
4
|
+
class Image
|
5
|
+
attr_reader :height, :href, :primary, :rel, :unit_of_measure, :width
|
6
|
+
|
7
|
+
def initialize(init_params)
|
8
|
+
@height = init_params[:height]
|
9
|
+
@href = init_params[:href]
|
10
|
+
@primary = init_params[:primary]
|
11
|
+
@rel = init_params[:rel]
|
12
|
+
@unit_of_measure = init_params[:unit_of_measure]
|
13
|
+
@width = init_params[:width]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BestBuy
|
4
|
+
class Offer
|
5
|
+
attr_reader :content_notes, :end_date, :id, :offer_name, :start_date, :text, :type, :url
|
6
|
+
|
7
|
+
def initialize(init_params)
|
8
|
+
@content_notes = init_params[:content_notes]
|
9
|
+
@end_date = init_params[:end_date]
|
10
|
+
@id = init_params[:id]
|
11
|
+
@offer_name = init_params[:offer_name]
|
12
|
+
@start_date = init_params[:start_date]
|
13
|
+
@text = init_params[:text]
|
14
|
+
@type = init_params[:type]
|
15
|
+
@url = init_params[:url]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'best_buy'
|
4
|
+
|
5
|
+
module BestBuy
|
6
|
+
# :reek:TooManyInstanceVariables
|
7
|
+
class Product
|
8
|
+
attr_reader :active, :alternate_categories, :category_path, :images, :name, :offers,
|
9
|
+
:raw_attributes, :regular_price, :sale_price, :shipping_cost,
|
10
|
+
:shipping_levels_of_service, :sku, :type, :upc, :url
|
11
|
+
|
12
|
+
# rubocop:disable Metrics/AbcSize
|
13
|
+
def initialize(init_params)
|
14
|
+
@active = init_params[:active]
|
15
|
+
@alternate_categories = init_params[:alternate_categories]
|
16
|
+
@category_path = init_params[:category_path]
|
17
|
+
@images = init_params[:images]&.map do |image_params|
|
18
|
+
Image.new(image_params)
|
19
|
+
end
|
20
|
+
@name = init_params[:name]
|
21
|
+
@offers = init_params[:offers]&.map do |offer_params|
|
22
|
+
Offer.new(offer_params)
|
23
|
+
end
|
24
|
+
@regular_price = init_params[:regular_price]
|
25
|
+
@sale_price = init_params[:sale_price]
|
26
|
+
@shipping_cost = init_params[:shipping_cost]
|
27
|
+
@shipping_levels_of_service = init_params[:shipping_levels_of_service]&.map do |slos_params|
|
28
|
+
ShippingLevelOfService.new(slos_params)
|
29
|
+
end
|
30
|
+
@sku = init_params[:sku]
|
31
|
+
@type = init_params[:type]
|
32
|
+
@upc = init_params[:upc]
|
33
|
+
@url = init_params[:url]
|
34
|
+
|
35
|
+
@raw_attributes = init_params
|
36
|
+
end
|
37
|
+
# rubocop:enable Metrics/AbcSize
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BestBuy
|
4
|
+
class ShippingLevelOfService
|
5
|
+
attr_reader :service_level_id, :service_level_name, :unit_shipping_price
|
6
|
+
|
7
|
+
def initialize(init_params)
|
8
|
+
@service_level_id = init_params[:service_level_id]
|
9
|
+
@service_level_name = init_params[:service_level_name]
|
10
|
+
@unit_shipping_price = init_params[:unit_shipping_price]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'best_buy'
|
4
|
+
|
5
|
+
module BestBuy
|
6
|
+
class Store
|
7
|
+
attr_reader :location_type, :long_name, :name, :opening_time, :phone,
|
8
|
+
:services, :store_id, :store_type, :store_address
|
9
|
+
|
10
|
+
delegate :address, :address2, :city, :country, :full_postal_code, :gmt_offset,
|
11
|
+
:lat, :lng, :postal_code, :region, to: :store_address
|
12
|
+
|
13
|
+
def initialize(init_params)
|
14
|
+
@location_type = init_params[:location_type]
|
15
|
+
@long_name = init_params[:long_name]
|
16
|
+
@name = init_params[:name]
|
17
|
+
@opening_time = init_params[:detailed_hours]
|
18
|
+
@phone = init_params[:phone]
|
19
|
+
@services = init_params[:services]&.map { |service_hash| service_hash[:service] }
|
20
|
+
@store_id = init_params[:store_id]
|
21
|
+
@store_type = init_params[:store_type]
|
22
|
+
|
23
|
+
@store_address = Address.new(init_params)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BestBuy
|
4
|
+
class Products < BaseAPI
|
5
|
+
include Conditions
|
6
|
+
|
7
|
+
PRODUCTS_API = '/v1/products'
|
8
|
+
CONDITIONS = [
|
9
|
+
CategoryCondition,
|
10
|
+
MinPriceCondition,
|
11
|
+
MaxPriceCondition,
|
12
|
+
NewCondition,
|
13
|
+
PreOwnedCondition,
|
14
|
+
RefurbishedCondition
|
15
|
+
].freeze
|
16
|
+
|
17
|
+
def get_by(conditions)
|
18
|
+
add_search_conditions_to_query(conditions.except(:pagination))
|
19
|
+
|
20
|
+
pagination = conditions[:pagination] || {}
|
21
|
+
|
22
|
+
get_all(search_query: search_query_builder.build, pagination: pagination)
|
23
|
+
end
|
24
|
+
|
25
|
+
protected
|
26
|
+
|
27
|
+
def model_class
|
28
|
+
Product
|
29
|
+
end
|
30
|
+
|
31
|
+
def collection_name
|
32
|
+
:products
|
33
|
+
end
|
34
|
+
|
35
|
+
def api_url
|
36
|
+
PRODUCTS_API
|
37
|
+
end
|
38
|
+
|
39
|
+
def search_query_builder
|
40
|
+
@search_query_builder ||= SearchQueryBuilder.new
|
41
|
+
end
|
42
|
+
|
43
|
+
def add_search_conditions_to_query(conditions)
|
44
|
+
applying_conditions = CONDITIONS.map do |condition|
|
45
|
+
condition.new(conditions)
|
46
|
+
end.select(&:valid?)
|
47
|
+
|
48
|
+
applying_conditions.each do |applying_condition|
|
49
|
+
search_query_builder.add(applying_condition.search_query)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BestBuy
|
4
|
+
class SearchQueryBuilder
|
5
|
+
def add(condition)
|
6
|
+
conditions << condition
|
7
|
+
end
|
8
|
+
|
9
|
+
def build
|
10
|
+
return '' unless conditions.any?
|
11
|
+
|
12
|
+
"(#{conditions.join('&')})"
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def conditions
|
18
|
+
@conditions ||= []
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|