retailigence_ruby 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|