retailigence_ruby 0.0.1
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 +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +81 -0
- data/Rakefile +25 -0
- data/lib/retailigence.rb +33 -0
- data/lib/retailigence/address.rb +14 -0
- data/lib/retailigence/configuration.rb +26 -0
- data/lib/retailigence/distance.rb +11 -0
- data/lib/retailigence/exceptions.rb +5 -0
- data/lib/retailigence/image.rb +10 -0
- data/lib/retailigence/inventory.rb +33 -0
- data/lib/retailigence/location.rb +61 -0
- data/lib/retailigence/model.rb +84 -0
- data/lib/retailigence/product.rb +108 -0
- data/lib/retailigence/retailer.rb +18 -0
- data/lib/retailigence/search_result.rb +40 -0
- data/lib/retailigence/version.rb +3 -0
- data/lib/retailigence_ruby.rb +1 -0
- data/retailigence_ruby.gemspec +27 -0
- data/test/cassettes/inventory.yml +39 -0
- data/test/cassettes/location_search.yml +72 -0
- data/test/cassettes/product_inventory.yml +39 -0
- data/test/cassettes/product_search.yml +699 -0
- data/test/helper.rb +10 -0
- data/test/test_inventory.rb +22 -0
- data/test/test_location.rb +48 -0
- data/test/test_product.rb +30 -0
- data/test/vcr_setup.rb +7 -0
- metadata +166 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c402bae87c9588519c02a8854a8fda6c3d1cc539
|
4
|
+
data.tar.gz: db26dab02b2f714a992e690fefd75caf6613426a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f9217ceddba1ff48fde254d1d8adaf4855ad1189ea1c1a390ef1dc5d6ea6f26f09d2230dfc5cb86da0d71e4f0393c7c8df0daa09af5858b4ee5491ec8d5fc26a
|
7
|
+
data.tar.gz: 048892f901ad61f3155cfe7c864b0cb7db1d3bd22e5b25590b99193f90fc67cd3e3b504f0dac669edc8c1639587b646ed509fea45da0d68fcb43f49bb5417fb5
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Drew Tempelmeyer
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
# Retailigence
|
2
|
+
|
3
|
+
Ruby library for interacting with [Retailigence](http://retailigence.com) API v2.1.
|
4
|
+
|
5
|
+
**NOTE:** You'll need an API key from Retailigence. You can [request one from here](http://www.retailigence.com/developers/request-key/).
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
gem 'retailigence_ruby'
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install retailigence_ruby
|
20
|
+
|
21
|
+
## Configuring
|
22
|
+
|
23
|
+
Configuration only needs to be defined once.
|
24
|
+
|
25
|
+
```
|
26
|
+
Retailigence.configure do |config|
|
27
|
+
config.api_key = 'your-api-key'
|
28
|
+
# config.production = false # Uncomment this line if you want to use the test environment
|
29
|
+
end
|
30
|
+
```
|
31
|
+
|
32
|
+
If you're using Rails, it's recommended you place the above code in an initializer such as `config/initializers/retailigence.rb`.
|
33
|
+
|
34
|
+
## Searching Products
|
35
|
+
|
36
|
+
Searching products will return a `SearchResult` with a collection of `Retailigence::Product` for the results. See the `Product` model for available attributes and methods.
|
37
|
+
|
38
|
+
```
|
39
|
+
search_results = Retailigence::Product.search(
|
40
|
+
userlocation: '37.3323,-122.0312',
|
41
|
+
requestorid: 'test',
|
42
|
+
name: 'Xbox One'
|
43
|
+
)
|
44
|
+
|
45
|
+
search_results.each do |product|
|
46
|
+
puts product.name
|
47
|
+
end
|
48
|
+
|
49
|
+
# => "Xbox One - Console"
|
50
|
+
# => "FIFA 2014 (Xbox One)"
|
51
|
+
```
|
52
|
+
|
53
|
+
## Searching Locations
|
54
|
+
|
55
|
+
Searching locations will return a `SearchResult` with a collection of `Retailigence::Retailer` for the results. Locations are embedded within the retailer and can be accessed by calling `retailer.locations`. See the `Retailer` and `Location` models available attributes and methods.
|
56
|
+
|
57
|
+
```
|
58
|
+
search_results = Retailigence::Location.search(
|
59
|
+
userlocation: '37.3323,-122.0312',
|
60
|
+
requestorid: 'test',
|
61
|
+
keywords: 'Best Buy'
|
62
|
+
)
|
63
|
+
|
64
|
+
search_results.each do |retailer|
|
65
|
+
puts retailer.name
|
66
|
+
puts retailer.locations
|
67
|
+
end
|
68
|
+
|
69
|
+
# => "Best Buy"
|
70
|
+
# => #<Retailigence::Location>
|
71
|
+
# => #<Retailigence::Location>
|
72
|
+
```
|
73
|
+
|
74
|
+
|
75
|
+
## Contributing
|
76
|
+
|
77
|
+
1. Fork it ( https://github.com/drewtempelmeyer/retailigence_ruby/fork )
|
78
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
79
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
80
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
81
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rdoc/task'
|
3
|
+
require 'rake/testtask'
|
4
|
+
require 'rubocop/rake_task'
|
5
|
+
|
6
|
+
Rubocop::RakeTask.new(:rubocop)
|
7
|
+
|
8
|
+
Rake::TestTask.new(:test) do |test|
|
9
|
+
test.libs << 'lib' << 'test'
|
10
|
+
test.pattern = 'test/test_*.rb'
|
11
|
+
test.verbose = false
|
12
|
+
end
|
13
|
+
|
14
|
+
task :console do
|
15
|
+
require 'irb'
|
16
|
+
require 'irb/completion'
|
17
|
+
require 'retailigence_ruby' # You know what to do.
|
18
|
+
ARGV.clear
|
19
|
+
IRB.start
|
20
|
+
end
|
21
|
+
|
22
|
+
RDoc::Task.new do |rdoc|
|
23
|
+
rdoc.main = 'README.md'
|
24
|
+
rdoc.rdoc_files.include('README.md', 'lib/**/*.rb')
|
25
|
+
end
|
data/lib/retailigence.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'retailigence/version'
|
2
|
+
require 'retailigence/configuration'
|
3
|
+
require 'retailigence/exceptions'
|
4
|
+
require 'retailigence/model'
|
5
|
+
require 'retailigence/search_result'
|
6
|
+
require 'retailigence/product'
|
7
|
+
require 'retailigence/distance'
|
8
|
+
require 'retailigence/location'
|
9
|
+
require 'retailigence/retailer'
|
10
|
+
require 'retailigence/address'
|
11
|
+
require 'retailigence/image'
|
12
|
+
require 'retailigence/inventory'
|
13
|
+
|
14
|
+
module Retailigence
|
15
|
+
# Retailigence's API Version
|
16
|
+
API_VERSION = '2.1'
|
17
|
+
|
18
|
+
class << self
|
19
|
+
# Stores the current Retailigence Configuration
|
20
|
+
attr_accessor :configuration
|
21
|
+
|
22
|
+
# Configure Retailigence. See Configuration for available configuration options
|
23
|
+
#
|
24
|
+
# === Example
|
25
|
+
# Retailigence.configure do |config|
|
26
|
+
# config.api_key = 'your-retailigence-api-key'
|
27
|
+
# end
|
28
|
+
def configure
|
29
|
+
@configuration ||= Configuration.new
|
30
|
+
yield @configuration
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Retailigence #:nodoc:
|
2
|
+
# Represents an address returned from Retailigence. The address is normally
|
3
|
+
# embedded within a Location object.
|
4
|
+
#
|
5
|
+
# === Attributes
|
6
|
+
# * <tt>address1</tt> - The street address of the Location
|
7
|
+
# * <tt>city</tt> - The city of the Location
|
8
|
+
# * <tt>state</tt> - The state of the Location
|
9
|
+
# * <tt>postal</tt> - The postal code (ZIP code) of the Location
|
10
|
+
# * <tt>country</tt> - The country of the Location
|
11
|
+
class Address < Model
|
12
|
+
attributes :address1, :city, :state, :postal, :country
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Retailigence #:nodoc:
|
2
|
+
# Configure Retailigence with your credentials.
|
3
|
+
#
|
4
|
+
# === Example
|
5
|
+
# Retailigence.configure do |config|
|
6
|
+
# config.api_key = 'yourapikeyhere'
|
7
|
+
# config.production = false # Use the test route
|
8
|
+
# end
|
9
|
+
class Configuration
|
10
|
+
# The API key issued to you by Retailigence
|
11
|
+
attr_accessor :api_key
|
12
|
+
|
13
|
+
# Wether or not to use the production Retailigence API
|
14
|
+
attr_writer :production
|
15
|
+
|
16
|
+
# Returns true if using the production API
|
17
|
+
def production?
|
18
|
+
@production == true
|
19
|
+
end
|
20
|
+
|
21
|
+
# Returns true if using the test API
|
22
|
+
def test?
|
23
|
+
!production?
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Retailigence #:nodoc:
|
2
|
+
# Representation of the distance from the <tt>userlocation</tt> and the
|
3
|
+
# respective Product or Location
|
4
|
+
#
|
5
|
+
# === Attributes
|
6
|
+
# * <tt>distance</tt> - A float value based on the distance <tt>units</tt>
|
7
|
+
# * <tt>units</tt> - String of distance measurement. Example: "miles", "meters", etc.
|
8
|
+
class Distance < Model
|
9
|
+
attributes :distance, :units
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module Retailigence #:nodoc:
|
2
|
+
# A product image returned by the API
|
3
|
+
#
|
4
|
+
# === Attributes
|
5
|
+
# * <tt>image_name</tt> - The image name. Normally either "IMAGESMALL" or "IMAGELARGE"
|
6
|
+
# * <tt>link</tt> - The URL of the image
|
7
|
+
class Image < Model
|
8
|
+
attributes :imageName, :link
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Retailigence #:nodoc:
|
2
|
+
# Retrieve the inventory for a product at a specific location.
|
3
|
+
#
|
4
|
+
# === Attributes
|
5
|
+
# * <tt>product_id</tt> - The Product#id
|
6
|
+
# * <tt>retailer_id</tt> - The Retailer#id
|
7
|
+
# * <tt>location_id</tt> - The Location#id
|
8
|
+
# * <tt>price</tt> - The price
|
9
|
+
# * <tt>currency</tt> - The price's respective currency
|
10
|
+
# * <tt>quantity</tt> - Number of items in stock
|
11
|
+
# * <tt>quantity_text</tt> - Detail about the current stock
|
12
|
+
# * <tt>product_name</tt> - The Product#name
|
13
|
+
class Inventory < Model
|
14
|
+
attributes :product_id, :retailer_id, :location_id, :price, :currency,
|
15
|
+
:quantity, :quantityText, :productName
|
16
|
+
|
17
|
+
# Retrieve the inventory information for the provided <tt>product_id</tt>
|
18
|
+
# and <tt>location_id</tt>
|
19
|
+
#
|
20
|
+
# === Returns
|
21
|
+
# Inventory
|
22
|
+
def self.fetch(product_id = nil, location_id = nil)
|
23
|
+
params = {
|
24
|
+
productId: product_id,
|
25
|
+
locationId: location_id
|
26
|
+
}
|
27
|
+
|
28
|
+
results = get('inventory', params)['RetailigenceAPIResult']['results']
|
29
|
+
|
30
|
+
Inventory.new(results.first['ProductLocation'])
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Retailigence #:nodoc:
|
2
|
+
# A location result from the Retailigence API
|
3
|
+
#
|
4
|
+
# === Attributes
|
5
|
+
# * <tt>id</tt> - Unique identifier for the location
|
6
|
+
# * <tt>timezone</tt> - Timezone of the location
|
7
|
+
# * <tt>distance</tt> - Distance object calculated based off the <tt>userlocation</tt> param
|
8
|
+
# * <tt>phone</tt> - Location's phone number
|
9
|
+
# * <tt>t_nav_link</tt> - URL to get directions from your current position to the location's position
|
10
|
+
# * <tt>location</tt> - Contains the latitude and longitude for the location. Using the <tt>latitude</tt> and <tt>longitude</tt> attributes are preferred
|
11
|
+
# * <tt>address</tt> - An Address object containing the physical postal address
|
12
|
+
# * <tt>hours</tt> - Colon separated operating hours
|
13
|
+
# * <tt>map_link</tt> - Google Maps URL for the location's address
|
14
|
+
# * <tt>name</tt> - Name of the location
|
15
|
+
# * <tt>retailer</tt> - Retailer
|
16
|
+
# * <tt>retlocationid</tt> - External location ID provided by the Retailer
|
17
|
+
# * <tt>latitude</tt> - The location's latitude
|
18
|
+
# * <tt>longitide</tt> - The location's longitude
|
19
|
+
class Location < Model
|
20
|
+
attributes :id, :timezone, :distance, :phone, :tNavLink, :location,
|
21
|
+
:address, :hours, :mapLink, :name, :retailer, :retlocationid, :latitude,
|
22
|
+
:longitude
|
23
|
+
|
24
|
+
# Search locations and retailers based on the <tt>params</tt> passed.
|
25
|
+
#
|
26
|
+
# === Params
|
27
|
+
# See the documentation from Retailigence for all possible parameters
|
28
|
+
#
|
29
|
+
# === Returns
|
30
|
+
# SearchResult with <tt>results</tt> being an array of Retailer
|
31
|
+
def self.search(params = {})
|
32
|
+
results = get('locations', params)
|
33
|
+
|
34
|
+
retailers = results['RetailigenceAPIResult']['results'].map do |result|
|
35
|
+
Retailer.new(result['Retailer'])
|
36
|
+
end
|
37
|
+
|
38
|
+
SearchResult.new(retailers)
|
39
|
+
end
|
40
|
+
|
41
|
+
def retailer=(retailer) #:nodoc:
|
42
|
+
@retailer = Retailer.new(retailer)
|
43
|
+
end
|
44
|
+
|
45
|
+
def distance=(distance) #:nodoc:
|
46
|
+
@distance = Distance.new(distance)
|
47
|
+
end
|
48
|
+
|
49
|
+
def address=(address) #:nodoc:
|
50
|
+
@address = Address.new(address)
|
51
|
+
end
|
52
|
+
|
53
|
+
# Convert the locations hash to latitude and longitude
|
54
|
+
def location=(location) #:nodoc:
|
55
|
+
@latitude = location['latitude']
|
56
|
+
@longitude = location['longitude']
|
57
|
+
@location = location
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'typhoeus'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module Retailigence #:nodoc:
|
5
|
+
# The base for all API requests and models throughout the Retailigence library.
|
6
|
+
class Model
|
7
|
+
# Initialize an object with the provided <tt>params</tt>. For the available
|
8
|
+
# <tt>params</tt>, see the model's <tt>Attributes</tt>.
|
9
|
+
def initialize(params = {})
|
10
|
+
params.each do |key, value|
|
11
|
+
mapped_key = underscore(key)
|
12
|
+
send("#{mapped_key}=".to_sym, value) if safe_attribute?(mapped_key)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class << self
|
17
|
+
# Attributes safe for initialization
|
18
|
+
attr_accessor :safe_attributes
|
19
|
+
|
20
|
+
# Creates a list of safe attributes for assign using #initialize.
|
21
|
+
def attributes(*attrs)
|
22
|
+
@safe_attributes ||= []
|
23
|
+
|
24
|
+
attrs.each do |attr_name|
|
25
|
+
name = underscore(attr_name.to_s).to_sym
|
26
|
+
|
27
|
+
attr_accessor name
|
28
|
+
@safe_attributes << name
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Perform a request using Typhoeus.
|
33
|
+
#
|
34
|
+
# === Arguments
|
35
|
+
# * <tt>method</tt> - Symbol for the request method.
|
36
|
+
# * <tt>action</tt> - The path to request
|
37
|
+
# * <tt>params</tt> - Hash of params to send with the request
|
38
|
+
def request(method = :get, action = nil, params = {})
|
39
|
+
params[:apikey] = Retailigence.configuration.api_key
|
40
|
+
params[:format] = 'JSON'
|
41
|
+
|
42
|
+
url = "http://#{host}/v#{Retailigence::API_VERSION}/#{action}"
|
43
|
+
|
44
|
+
response = Typhoeus.send(method, url, params: params)
|
45
|
+
JSON.parse response.body
|
46
|
+
end
|
47
|
+
|
48
|
+
# Convenience method for performing a GET request. See #request
|
49
|
+
def get(action = nil, params = {})
|
50
|
+
request(:get, action, params)
|
51
|
+
end
|
52
|
+
|
53
|
+
# Convert the camelCase to its underscore/snake_case equivalent.
|
54
|
+
def underscore(word)
|
55
|
+
word.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
56
|
+
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
57
|
+
.tr('-', '_').downcase
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def host
|
63
|
+
host =
|
64
|
+
if Retailigence.configuration.production?
|
65
|
+
'api'
|
66
|
+
else
|
67
|
+
'apitest'
|
68
|
+
end
|
69
|
+
|
70
|
+
"#{host}.retailigence.com"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def underscore(word)
|
77
|
+
self.class.underscore(word.to_s).to_sym
|
78
|
+
end
|
79
|
+
|
80
|
+
def safe_attribute?(key)
|
81
|
+
self.class.safe_attributes.include?(key)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|