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 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
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in retailigence_ruby.gemspec
4
+ gemspec
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
@@ -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,5 @@
1
+ module Retailigence #:nodoc:
2
+ # Raised when Retailigence has not yet be configured.
3
+ # See Retailigence::configure.
4
+ class NotConfigured < StandardError; end
5
+ 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