invisiblehand 0.1.3 → 0.2
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.
- data/LICENSE +2 -2
 - data/README.md +16 -6
 - data/lib/invisiblehand/api.rb +40 -11
 - data/lib/invisiblehand/page.rb +38 -0
 - data/lib/invisiblehand/product.rb +44 -0
 - data/lib/invisiblehand/response.rb +28 -0
 - data/lib/invisiblehand/version.rb +1 -3
 - data/samples/live_price.rb +12 -0
 - data/samples/product.rb +20 -0
 - data/samples/products.rb +16 -0
 - data/spec/api_spec.rb +26 -10
 - metadata +10 -4
 
    
        data/LICENSE
    CHANGED
    
    | 
         @@ -1,4 +1,4 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            Copyright (c)  
     | 
| 
      
 1 
     | 
    
         
            +
            Copyright (c) 2013 InvisibleHand Software Limited
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            MIT License
         
     | 
| 
       4 
4 
     | 
    
         | 
| 
         @@ -19,4 +19,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
     | 
|
| 
       19 
19 
     | 
    
         
             
            NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
         
     | 
| 
       20 
20 
     | 
    
         
             
            LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
         
     | 
| 
       21 
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.
         
     | 
| 
      
 22 
     | 
    
         
            +
            WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
         
     | 
    
        data/README.md
    CHANGED
    
    | 
         @@ -51,8 +51,9 @@ api = InvisibleHand::API.new "path/to/invisiblehand.yml" 
     | 
|
| 
       51 
51 
     | 
    
         
             
            api.products({
         
     | 
| 
       52 
52 
     | 
    
         
             
              :query => "ipad"
         
     | 
| 
       53 
53 
     | 
    
         
             
            })
         
     | 
| 
       54 
     | 
    
         
            -
            #=>  
     | 
| 
       55 
     | 
    
         
            -
            # 
     | 
| 
      
 54 
     | 
    
         
            +
            #=> An InvisibleHand::Response object that contains the methods #results and
         
     | 
| 
      
 55 
     | 
    
         
            +
            #   #info. #results is an array of InvisibleHand::Product objects and #info is
         
     | 
| 
      
 56 
     | 
    
         
            +
            #   a Hash of meta information on the request (number of results, etc.)
         
     | 
| 
       56 
57 
     | 
    
         | 
| 
       57 
58 
     | 
    
         
             
            # Search for products with sorting and ordering and a specific size.
         
     | 
| 
       58 
59 
     | 
    
         
             
            api.products({
         
     | 
| 
         @@ -61,8 +62,6 @@ api.products({ 
     | 
|
| 
       61 
62 
     | 
    
         
             
              :order => "desc",      # Direction to order results by
         
     | 
| 
       62 
63 
     | 
    
         
             
              :size => "100"         # Number of results to return
         
     | 
| 
       63 
64 
     | 
    
         
             
            })
         
     | 
| 
       64 
     | 
    
         
            -
            #=> A massive hash that you can find details of at:
         
     | 
| 
       65 
     | 
    
         
            -
            #     https://developer.getinvisiblehand.com/documentation
         
     | 
| 
       66 
65 
     | 
    
         | 
| 
       67 
66 
     | 
    
         
             
            # Do a live price search on a product (price comes back as the currency in the
         
     | 
| 
       68 
67 
     | 
    
         
             
            # URL you specify. On amazon.com you get dollars, amazon.co.uk you get pounds.)
         
     | 
| 
         @@ -75,11 +74,22 @@ api.live_price "http://api.invisiblehand.co.uk/v1/pages/live_price?url=http%3A%2 
     | 
|
| 
       75 
74 
     | 
    
         | 
| 
       76 
75 
     | 
    
         
             
            # Search for a specific product by its Invisible Hand ID
         
     | 
| 
       77 
76 
     | 
    
         
             
            api.product "f619c3e117d50d1a2b10930e5b202336"
         
     | 
| 
       78 
     | 
    
         
            -
            #=>  
     | 
| 
       79 
     | 
    
         
            -
            #     https://developer.getinvisiblehand.com/documentation
         
     | 
| 
      
 77 
     | 
    
         
            +
            #=> An InvisibleHand::Product object.
         
     | 
| 
       80 
78 
     | 
    
         | 
| 
       81 
79 
     | 
    
         
             
            ```
         
     | 
| 
       82 
80 
     | 
    
         | 
| 
      
 81 
     | 
    
         
            +
            ### Region
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
            A little clarification surrounding what the `:region` parameter is for in the
         
     | 
| 
      
 84 
     | 
    
         
            +
            `invisiblehand.sample.yml` file.
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
            Because product data differs depending on where that product is being sold (for
         
     | 
| 
      
 87 
     | 
    
         
            +
            example, `amazon.com` and `amazon.co.uk` can differ in price and such), the API
         
     | 
| 
      
 88 
     | 
    
         
            +
            returns you only the data relevant to the region that you specify.
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
            A product that exists in our dataset and has only pages in the UK will not be
         
     | 
| 
      
 91 
     | 
    
         
            +
            returned for queries that are done on the US API endpoint.
         
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
       83 
93 
     | 
    
         
             
            ### Errors
         
     | 
| 
       84 
94 
     | 
    
         | 
| 
       85 
95 
     | 
    
         
             
            If the API returns any error information, an `InvisibleHand::Error::APIError` is
         
     | 
    
        data/lib/invisiblehand/api.rb
    CHANGED
    
    | 
         @@ -36,7 +36,7 @@ module InvisibleHand 
     | 
|
| 
       36 
36 
     | 
    
         | 
| 
       37 
37 
     | 
    
         
             
                  # The @config[:development] flag exists to bypass the app_id and app_key
         
     | 
| 
       38 
38 
     | 
    
         
             
                  # check in this gem (not on the server) for internal testing reasons.
         
     | 
| 
       39 
     | 
    
         
            -
                  if  
     | 
| 
      
 39 
     | 
    
         
            +
                  if invalid_config? and !@config[:development]
         
     | 
| 
       40 
40 
     | 
    
         
             
                    message = "Your config does not contain an app_id and app_key. " +
         
     | 
| 
       41 
41 
     | 
    
         
             
                      "Both are required to make API calls."
         
     | 
| 
       42 
42 
     | 
    
         | 
| 
         @@ -44,14 +44,37 @@ module InvisibleHand 
     | 
|
| 
       44 
44 
     | 
    
         
             
                  end
         
     | 
| 
       45 
45 
     | 
    
         | 
| 
       46 
46 
     | 
    
         
             
                  @config[:protocol] = @config[:use_ssl] == false ? "http://" : "https://"
         
     | 
| 
      
 47 
     | 
    
         
            +
                  @config[:version] ||= "1"
         
     | 
| 
       47 
48 
     | 
    
         
             
                end
         
     | 
| 
       48 
49 
     | 
    
         | 
| 
       49 
50 
     | 
    
         
             
                def products opts = {}
         
     | 
| 
       50 
     | 
    
         
            -
                  api_call :get, "/ 
     | 
| 
      
 51 
     | 
    
         
            +
                  response = api_call :get, "/products", opts
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                  if opts[:raw]
         
     | 
| 
      
 54 
     | 
    
         
            +
                    response
         
     | 
| 
      
 55 
     | 
    
         
            +
                  else
         
     | 
| 
      
 56 
     | 
    
         
            +
                    Response.new(response, self)
         
     | 
| 
      
 57 
     | 
    
         
            +
                  end
         
     | 
| 
       51 
58 
     | 
    
         
             
                end
         
     | 
| 
       52 
59 
     | 
    
         | 
| 
       53 
60 
     | 
    
         
             
                def product id, opts = {}
         
     | 
| 
       54 
     | 
    
         
            -
                  api_call :get, "/ 
     | 
| 
      
 61 
     | 
    
         
            +
                  response = api_call :get, "/products/#{CGI.escape(id)}", opts
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                  if opts[:raw]
         
     | 
| 
      
 64 
     | 
    
         
            +
                    response
         
     | 
| 
      
 65 
     | 
    
         
            +
                  else
         
     | 
| 
      
 66 
     | 
    
         
            +
                    Product.new(response, self)
         
     | 
| 
      
 67 
     | 
    
         
            +
                  end
         
     | 
| 
      
 68 
     | 
    
         
            +
                end
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                def page url, opts = {}
         
     | 
| 
      
 71 
     | 
    
         
            +
                  response = api_call :get, "/pages/?url=#{CGI.escape(url)}", opts
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
                  if opts[:raw]
         
     | 
| 
      
 74 
     | 
    
         
            +
                    response
         
     | 
| 
      
 75 
     | 
    
         
            +
                  else
         
     | 
| 
      
 76 
     | 
    
         
            +
                    Page.new(response, self)
         
     | 
| 
      
 77 
     | 
    
         
            +
                  end
         
     | 
| 
       55 
78 
     | 
    
         
             
                end
         
     | 
| 
       56 
79 
     | 
    
         | 
| 
       57 
80 
     | 
    
         
             
                def live_price url, opts = {}
         
     | 
| 
         @@ -61,14 +84,21 @@ module InvisibleHand 
     | 
|
| 
       61 
84 
     | 
    
         
             
                    json["price"]
         
     | 
| 
       62 
85 
     | 
    
         
             
                  else
         
     | 
| 
       63 
86 
     | 
    
         
             
                    opts[:url] = url
         
     | 
| 
       64 
     | 
    
         
            -
                    json = api_call :get, "/ 
     | 
| 
      
 87 
     | 
    
         
            +
                    json = api_call :get, "/pages/live_price", opts
         
     | 
| 
       65 
88 
     | 
    
         
             
                    json["price"]
         
     | 
| 
       66 
89 
     | 
    
         
             
                  end
         
     | 
| 
       67 
90 
     | 
    
         
             
                end
         
     | 
| 
       68 
91 
     | 
    
         | 
| 
       69 
92 
     | 
    
         
             
                def api_call method, path, opts = {}
         
     | 
| 
      
 93 
     | 
    
         
            +
                  if !@config[:development]
         
     | 
| 
      
 94 
     | 
    
         
            +
                    opts.merge!({
         
     | 
| 
      
 95 
     | 
    
         
            +
                      :app_id => @config[:app_id],
         
     | 
| 
      
 96 
     | 
    
         
            +
                      :app_key => @config[:app_key],
         
     | 
| 
      
 97 
     | 
    
         
            +
                    })
         
     | 
| 
      
 98 
     | 
    
         
            +
                  end
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
       70 
100 
     | 
    
         
             
                  query = url_params_from opts
         
     | 
| 
       71 
     | 
    
         
            -
                  url   = "#{@config[:protocol]}#{endpoint}#{path}?#{query}"
         
     | 
| 
      
 101 
     | 
    
         
            +
                  url   = "#{@config[:protocol]}#{endpoint}/v#{@config[:version]}#{path}?#{query}"
         
     | 
| 
       72 
102 
     | 
    
         | 
| 
       73 
103 
     | 
    
         
             
                  if opts[:debug]
         
     | 
| 
       74 
104 
     | 
    
         
             
                    debug { api_raw_request method, url }
         
     | 
| 
         @@ -96,8 +126,9 @@ module InvisibleHand 
     | 
|
| 
       96 
126 
     | 
    
         
             
                  old_log_level = logger.level
         
     | 
| 
       97 
127 
     | 
    
         
             
                  logger.level  = ::Logger::DEBUG
         
     | 
| 
       98 
128 
     | 
    
         
             
                  result        = block.call
         
     | 
| 
       99 
     | 
    
         
            -
                  logger.level  = old_log_level
         
     | 
| 
       100 
129 
     | 
    
         
             
                  result
         
     | 
| 
      
 130 
     | 
    
         
            +
                ensure
         
     | 
| 
      
 131 
     | 
    
         
            +
                  logger.level  = old_log_level
         
     | 
| 
       101 
132 
     | 
    
         
             
                end
         
     | 
| 
       102 
133 
     | 
    
         | 
| 
       103 
134 
     | 
    
         
             
                def api_raw_request method, url
         
     | 
| 
         @@ -124,7 +155,7 @@ module InvisibleHand 
     | 
|
| 
       124 
155 
     | 
    
         
             
                  params = hash.map do |key, value|
         
     | 
| 
       125 
156 
     | 
    
         
             
                    # There are some parameters that will be passed to an API call that we
         
     | 
| 
       126 
157 
     | 
    
         
             
                    # don't want to include in the query string. Filter them out here.
         
     | 
| 
       127 
     | 
    
         
            -
                    next if [:debug].include? key.to_sym
         
     | 
| 
      
 158 
     | 
    
         
            +
                    next if [:debug, :raw].include? key.to_sym
         
     | 
| 
       128 
159 
     | 
    
         | 
| 
       129 
160 
     | 
    
         
             
                    "#{CGI.escape(key.to_s)}=#{CGI.escape(value.to_s)}"
         
     | 
| 
       130 
161 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -132,10 +163,8 @@ module InvisibleHand 
     | 
|
| 
       132 
163 
     | 
    
         
             
                  params.compact.join('&')
         
     | 
| 
       133 
164 
     | 
    
         
             
                end
         
     | 
| 
       134 
165 
     | 
    
         | 
| 
       135 
     | 
    
         
            -
                def  
     | 
| 
       136 
     | 
    
         
            -
                  @config[:app_id].nil?  
     | 
| 
       137 
     | 
    
         
            -
                    @config[:app_key].nil? and
         
     | 
| 
       138 
     | 
    
         
            -
                    !@config[:development]
         
     | 
| 
      
 166 
     | 
    
         
            +
                def invalid_config?
         
     | 
| 
      
 167 
     | 
    
         
            +
                  (@config[:app_id].nil? or @config[:app_key].nil?)
         
     | 
| 
       139 
168 
     | 
    
         
             
                end
         
     | 
| 
       140 
169 
     | 
    
         
             
              end
         
     | 
| 
       141 
170 
     | 
    
         
             
            end
         
     | 
| 
         @@ -0,0 +1,38 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module InvisibleHand
         
     | 
| 
      
 2 
     | 
    
         
            +
              class Page
         
     | 
| 
      
 3 
     | 
    
         
            +
                # Array of fields that exist on a page returned from the InvisibleHand
         
     | 
| 
      
 4 
     | 
    
         
            +
                # API.
         
     | 
| 
      
 5 
     | 
    
         
            +
                FIELDS = [
         
     | 
| 
      
 6 
     | 
    
         
            +
                  :title,
         
     | 
| 
      
 7 
     | 
    
         
            +
                  :deeplink,
         
     | 
| 
      
 8 
     | 
    
         
            +
                  :original_url,
         
     | 
| 
      
 9 
     | 
    
         
            +
                  :price,
         
     | 
| 
      
 10 
     | 
    
         
            +
                  :currency,
         
     | 
| 
      
 11 
     | 
    
         
            +
                  :pnp,
         
     | 
| 
      
 12 
     | 
    
         
            +
                  :image_url,
         
     | 
| 
      
 13 
     | 
    
         
            +
                  :retailer_name,
         
     | 
| 
      
 14 
     | 
    
         
            +
                  :price_confidence,
         
     | 
| 
      
 15 
     | 
    
         
            +
                  :live_price_url,
         
     | 
| 
      
 16 
     | 
    
         
            +
                  :ean,
         
     | 
| 
      
 17 
     | 
    
         
            +
                  :upc,
         
     | 
| 
      
 18 
     | 
    
         
            +
                  :brand,
         
     | 
| 
      
 19 
     | 
    
         
            +
                  :model,
         
     | 
| 
      
 20 
     | 
    
         
            +
                  :mpn,
         
     | 
| 
      
 21 
     | 
    
         
            +
                  :isbn,
         
     | 
| 
      
 22 
     | 
    
         
            +
                  :asin,
         
     | 
| 
      
 23 
     | 
    
         
            +
                  :category,
         
     | 
| 
      
 24 
     | 
    
         
            +
                ]
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                attr_accessor(*FIELDS)
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                def initialize raw, api
         
     | 
| 
      
 29 
     | 
    
         
            +
                  @api = api
         
     | 
| 
      
 30 
     | 
    
         
            +
                  @raw = raw
         
     | 
| 
      
 31 
     | 
    
         
            +
                  FIELDS.each { |key| self.send("#{key}=", @raw[key.to_s]) }
         
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                def live_price opts = {}
         
     | 
| 
      
 35 
     | 
    
         
            +
                  @api.live_price(self.live_price_url, opts)
         
     | 
| 
      
 36 
     | 
    
         
            +
                end
         
     | 
| 
      
 37 
     | 
    
         
            +
              end
         
     | 
| 
      
 38 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,44 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module InvisibleHand
         
     | 
| 
      
 2 
     | 
    
         
            +
              class Product
         
     | 
| 
      
 3 
     | 
    
         
            +
                # Array of fields that exist on a product returned from the InvisibleHand
         
     | 
| 
      
 4 
     | 
    
         
            +
                # API.
         
     | 
| 
      
 5 
     | 
    
         
            +
                FIELDS = [
         
     | 
| 
      
 6 
     | 
    
         
            +
                  :pages,
         
     | 
| 
      
 7 
     | 
    
         
            +
                  :ebay_pages,
         
     | 
| 
      
 8 
     | 
    
         
            +
                  :best_page,
         
     | 
| 
      
 9 
     | 
    
         
            +
                  :id,
         
     | 
| 
      
 10 
     | 
    
         
            +
                  :title,
         
     | 
| 
      
 11 
     | 
    
         
            +
                  :resource,
         
     | 
| 
      
 12 
     | 
    
         
            +
                  :upcs,
         
     | 
| 
      
 13 
     | 
    
         
            +
                  :eans,
         
     | 
| 
      
 14 
     | 
    
         
            +
                  :mpns,
         
     | 
| 
      
 15 
     | 
    
         
            +
                  :isbns,
         
     | 
| 
      
 16 
     | 
    
         
            +
                  :asins,
         
     | 
| 
      
 17 
     | 
    
         
            +
                  :brands,
         
     | 
| 
      
 18 
     | 
    
         
            +
                  :models,
         
     | 
| 
      
 19 
     | 
    
         
            +
                  :categories,
         
     | 
| 
      
 20 
     | 
    
         
            +
                  :image_url,
         
     | 
| 
      
 21 
     | 
    
         
            +
                  :number_of_pages,
         
     | 
| 
      
 22 
     | 
    
         
            +
                ]
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                attr_accessor(*FIELDS)
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                def initialize raw, api
         
     | 
| 
      
 27 
     | 
    
         
            +
                  @api = api
         
     | 
| 
      
 28 
     | 
    
         
            +
                  @raw = raw
         
     | 
| 
      
 29 
     | 
    
         
            +
                  FIELDS.each { |key| self.send("#{key}=", @raw[key.to_s]) }
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                  if @raw["pages"]
         
     | 
| 
      
 32 
     | 
    
         
            +
                    self.pages = @raw["pages"].map { |json| Page.new(json, @api) }
         
     | 
| 
      
 33 
     | 
    
         
            +
                  end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                  if @raw["ebay_pages"]
         
     | 
| 
      
 36 
     | 
    
         
            +
                    self.ebay_pages = @raw["ebay_pages"].map { |json| Page.new(json, @api) }
         
     | 
| 
      
 37 
     | 
    
         
            +
                  end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                  if @raw["best_page"]
         
     | 
| 
      
 40 
     | 
    
         
            +
                    self.best_page = Page.new(@raw["best_page"], @api)
         
     | 
| 
      
 41 
     | 
    
         
            +
                  end
         
     | 
| 
      
 42 
     | 
    
         
            +
                end
         
     | 
| 
      
 43 
     | 
    
         
            +
              end
         
     | 
| 
      
 44 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,28 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module InvisibleHand
         
     | 
| 
      
 2 
     | 
    
         
            +
              class Response
         
     | 
| 
      
 3 
     | 
    
         
            +
                include Enumerable
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
                # Array of fields that exist on a response returned from the InvisibleHand
         
     | 
| 
      
 6 
     | 
    
         
            +
                # API.
         
     | 
| 
      
 7 
     | 
    
         
            +
                FIELDS = [
         
     | 
| 
      
 8 
     | 
    
         
            +
                  :info,
         
     | 
| 
      
 9 
     | 
    
         
            +
                  :results,
         
     | 
| 
      
 10 
     | 
    
         
            +
                ]
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                attr_accessor(*FIELDS)
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                def initialize raw, api
         
     | 
| 
      
 15 
     | 
    
         
            +
                  @api = api
         
     | 
| 
      
 16 
     | 
    
         
            +
                  @raw = raw
         
     | 
| 
      
 17 
     | 
    
         
            +
                  FIELDS.each { |key| self.send("#{key}=", @raw[key.to_s]) }
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                  if @raw["results"]
         
     | 
| 
      
 20 
     | 
    
         
            +
                    self.results = @raw["results"].map { |json| Product.new(json, @api) }
         
     | 
| 
      
 21 
     | 
    
         
            +
                  end
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                def each &block
         
     | 
| 
      
 25 
     | 
    
         
            +
                  self.results.each(&block)
         
     | 
| 
      
 26 
     | 
    
         
            +
                end
         
     | 
| 
      
 27 
     | 
    
         
            +
              end
         
     | 
| 
      
 28 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,12 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # encoding: utf-8
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'invisiblehand'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            api = InvisibleHand::API.new :app_id => "", :api_key => "", :region => "uk"
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            begin
         
     | 
| 
      
 7 
     | 
    
         
            +
              price = api.live_price "http://www.amazon.co.uk/Here-And-Now/dp/B0064Y9L9C"
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
              puts "£%.2f" % price
         
     | 
| 
      
 10 
     | 
    
         
            +
            rescue InvisibleHand::Error::APIError => e
         
     | 
| 
      
 11 
     | 
    
         
            +
              puts "Oh noes! There was an error: #{e.message}"
         
     | 
| 
      
 12 
     | 
    
         
            +
            end
         
     | 
    
        data/samples/product.rb
    ADDED
    
    | 
         @@ -0,0 +1,20 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # encoding: utf-8
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'invisiblehand'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            api = InvisibleHand::API.new :app_id => "", :api_key => "", :region => "uk"
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            begin
         
     | 
| 
      
 7 
     | 
    
         
            +
              # The "78b4fb8fa97b8bc746726a32d3393833" bit is a product ID in our database.
         
     | 
| 
      
 8 
     | 
    
         
            +
              # You aren't expected to know these beforehand, they will come from other API
         
     | 
| 
      
 9 
     | 
    
         
            +
              # calls.
         
     | 
| 
      
 10 
     | 
    
         
            +
              product = api.product "78b4fb8fa97b8bc746726a32d3393833"
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
              product["pages"].each do |page|
         
     | 
| 
      
 13 
     | 
    
         
            +
                puts "Retailer: %s" % page["retailer_name"]
         
     | 
| 
      
 14 
     | 
    
         
            +
                puts "Title: %s" % page["title"]
         
     | 
| 
      
 15 
     | 
    
         
            +
                puts "Price: £%.2f" % page["price"]
         
     | 
| 
      
 16 
     | 
    
         
            +
                puts
         
     | 
| 
      
 17 
     | 
    
         
            +
              end
         
     | 
| 
      
 18 
     | 
    
         
            +
            rescue InvisibleHand::Error::APIError => e
         
     | 
| 
      
 19 
     | 
    
         
            +
              puts "Oh noes! There was an error: #{e.message}"
         
     | 
| 
      
 20 
     | 
    
         
            +
            end
         
     | 
    
        data/samples/products.rb
    ADDED
    
    | 
         @@ -0,0 +1,16 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # encoding: utf-8
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'invisiblehand'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            api = InvisibleHand::API.new :app_id => "", :api_key => "", :region => "uk"
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            begin
         
     | 
| 
      
 7 
     | 
    
         
            +
              response = api.products(:query => "nickelback", :size => 5)
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
              response["results"].each do |product|
         
     | 
| 
      
 10 
     | 
    
         
            +
                puts "Title: %s" % product["best_page"]["title"]
         
     | 
| 
      
 11 
     | 
    
         
            +
                puts "Price: £%.2f" % product["best_page"]["price"]
         
     | 
| 
      
 12 
     | 
    
         
            +
                puts
         
     | 
| 
      
 13 
     | 
    
         
            +
              end
         
     | 
| 
      
 14 
     | 
    
         
            +
            rescue InvisibleHand::Error::APIError => e
         
     | 
| 
      
 15 
     | 
    
         
            +
              puts "Oh noes! There was an error: #{e.message}"
         
     | 
| 
      
 16 
     | 
    
         
            +
            end
         
     | 
    
        data/spec/api_spec.rb
    CHANGED
    
    | 
         @@ -5,6 +5,15 @@ describe InvisibleHand::API do 
     | 
|
| 
       5 
5 
     | 
    
         
             
              # yourself if you wish to run tests.
         
     | 
| 
       6 
6 
     | 
    
         
             
              let(:api_config) { File.join(File.dirname(__FILE__), 'invisiblehand.yml') }
         
     | 
| 
       7 
7 
     | 
    
         | 
| 
      
 8 
     | 
    
         
            +
              before do
         
     | 
| 
      
 9 
     | 
    
         
            +
                unless File.exist?(api_config)
         
     | 
| 
      
 10 
     | 
    
         
            +
                  puts "Your test config file does not exist. It should be at " +
         
     | 
| 
      
 11 
     | 
    
         
            +
                    "#{api_config}."
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                  exit 1
         
     | 
| 
      
 14 
     | 
    
         
            +
                end
         
     | 
| 
      
 15 
     | 
    
         
            +
              end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
       8 
17 
     | 
    
         
             
              ["uk", "us", "ca", "de"].each do |region|
         
     | 
| 
       9 
18 
     | 
    
         
             
                describe "Region: #{region}" do
         
     | 
| 
       10 
19 
     | 
    
         
             
                  let :api do
         
     | 
| 
         @@ -14,15 +23,22 @@ describe InvisibleHand::API do 
     | 
|
| 
       14 
23 
     | 
    
         
             
                    InvisibleHand::API.new(conf)
         
     | 
| 
       15 
24 
     | 
    
         
             
                  end
         
     | 
| 
       16 
25 
     | 
    
         | 
| 
       17 
     | 
    
         
            -
                  let(:product)    { api.products 
     | 
| 
       18 
     | 
    
         
            -
                  let(:product_id) { product 
     | 
| 
       19 
     | 
    
         
            -
                  let(:page)       { product 
     | 
| 
      
 26 
     | 
    
         
            +
                  let(:product)    { api.products.results.first }
         
     | 
| 
      
 27 
     | 
    
         
            +
                  let(:product_id) { product.id }
         
     | 
| 
      
 28 
     | 
    
         
            +
                  let(:page)       { product.best_page }
         
     | 
| 
       20 
29 
     | 
    
         | 
| 
       21 
30 
     | 
    
         
             
                  describe "#products" do
         
     | 
| 
       22 
     | 
    
         
            -
                    subject 
     | 
| 
       23 
     | 
    
         
            -
                    it 
     | 
| 
       24 
     | 
    
         
            -
                    its(: 
     | 
| 
       25 
     | 
    
         
            -
                    its(: 
     | 
| 
      
 31 
     | 
    
         
            +
                    subject       { api.products }
         
     | 
| 
      
 32 
     | 
    
         
            +
                    it            { should be_a InvisibleHand::Response }
         
     | 
| 
      
 33 
     | 
    
         
            +
                    its(:results) { should be_a Array }
         
     | 
| 
      
 34 
     | 
    
         
            +
                    its(:info)    { should be_a Hash }
         
     | 
| 
      
 35 
     | 
    
         
            +
                  end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                  describe "#products :raw => true" do
         
     | 
| 
      
 38 
     | 
    
         
            +
                    subject       { api.products :raw => true }
         
     | 
| 
      
 39 
     | 
    
         
            +
                    it            { should be_a Hash }
         
     | 
| 
      
 40 
     | 
    
         
            +
                    its(:keys)    { should include "results" }
         
     | 
| 
      
 41 
     | 
    
         
            +
                    its(:keys)    { should include "info" }
         
     | 
| 
       26 
42 
     | 
    
         
             
                  end
         
     | 
| 
       27 
43 
     | 
    
         | 
| 
       28 
44 
     | 
    
         
             
                  describe "#product" do
         
     | 
| 
         @@ -32,12 +48,12 @@ describe InvisibleHand::API do 
     | 
|
| 
       32 
48 
     | 
    
         | 
| 
       33 
49 
     | 
    
         
             
                  describe "#live_price" do
         
     | 
| 
       34 
50 
     | 
    
         
             
                    describe "with live price url" do
         
     | 
| 
       35 
     | 
    
         
            -
                      subject {  
     | 
| 
      
 51 
     | 
    
         
            +
                      subject { page.live_price }
         
     | 
| 
       36 
52 
     | 
    
         
             
                      it      { should be_a Float }
         
     | 
| 
       37 
53 
     | 
    
         
             
                    end
         
     | 
| 
       38 
54 
     | 
    
         | 
| 
       39 
55 
     | 
    
         
             
                    describe "with vanilla page url" do
         
     | 
| 
       40 
     | 
    
         
            -
                      subject { api.live_price(page 
     | 
| 
      
 56 
     | 
    
         
            +
                      subject { api.live_price(page.original_url) }
         
     | 
| 
       41 
57 
     | 
    
         
             
                      it      { should be_a Float }
         
     | 
| 
       42 
58 
     | 
    
         
             
                    end
         
     | 
| 
       43 
59 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -45,7 +61,7 @@ describe InvisibleHand::API do 
     | 
|
| 
       45 
61 
     | 
    
         
             
                  describe "ad-hoc debug flag" do
         
     | 
| 
       46 
62 
     | 
    
         
             
                    specify "the debug option to a single call should not break things" do
         
     | 
| 
       47 
63 
     | 
    
         
             
                      expect do
         
     | 
| 
       48 
     | 
    
         
            -
                        api.live_price(page 
     | 
| 
      
 64 
     | 
    
         
            +
                        api.live_price(page.original_url, :debug => true)
         
     | 
| 
       49 
65 
     | 
    
         
             
                      end.to_not raise_error
         
     | 
| 
       50 
66 
     | 
    
         
             
                    end
         
     | 
| 
       51 
67 
     | 
    
         
             
                  end
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: invisiblehand
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 0. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: '0.2'
         
     | 
| 
       5 
5 
     | 
    
         
             
              prerelease: 
         
     | 
| 
       6 
6 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       7 
7 
     | 
    
         
             
            authors:
         
     | 
| 
         @@ -9,7 +9,7 @@ authors: 
     | 
|
| 
       9 
9 
     | 
    
         
             
            autorequire: 
         
     | 
| 
       10 
10 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       11 
11 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       12 
     | 
    
         
            -
            date: 2013-02- 
     | 
| 
      
 12 
     | 
    
         
            +
            date: 2013-02-28 00:00:00.000000000 Z
         
     | 
| 
       13 
13 
     | 
    
         
             
            dependencies:
         
     | 
| 
       14 
14 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       15 
15 
     | 
    
         
             
              name: rest-client
         
     | 
| 
         @@ -93,7 +93,13 @@ files: 
     | 
|
| 
       93 
93 
     | 
    
         
             
            - lib/invisiblehand/api.rb
         
     | 
| 
       94 
94 
     | 
    
         
             
            - lib/invisiblehand/errors.rb
         
     | 
| 
       95 
95 
     | 
    
         
             
            - lib/invisiblehand/logger.rb
         
     | 
| 
      
 96 
     | 
    
         
            +
            - lib/invisiblehand/page.rb
         
     | 
| 
      
 97 
     | 
    
         
            +
            - lib/invisiblehand/product.rb
         
     | 
| 
      
 98 
     | 
    
         
            +
            - lib/invisiblehand/response.rb
         
     | 
| 
       96 
99 
     | 
    
         
             
            - lib/invisiblehand/version.rb
         
     | 
| 
      
 100 
     | 
    
         
            +
            - samples/live_price.rb
         
     | 
| 
      
 101 
     | 
    
         
            +
            - samples/product.rb
         
     | 
| 
      
 102 
     | 
    
         
            +
            - samples/products.rb
         
     | 
| 
       97 
103 
     | 
    
         
             
            - spec/api_spec.rb
         
     | 
| 
       98 
104 
     | 
    
         
             
            - spec/spec_helper.rb
         
     | 
| 
       99 
105 
     | 
    
         
             
            homepage: ''
         
     | 
| 
         @@ -110,7 +116,7 @@ required_ruby_version: !ruby/object:Gem::Requirement 
     | 
|
| 
       110 
116 
     | 
    
         
             
                  version: '0'
         
     | 
| 
       111 
117 
     | 
    
         
             
                  segments:
         
     | 
| 
       112 
118 
     | 
    
         
             
                  - 0
         
     | 
| 
       113 
     | 
    
         
            -
                  hash:  
     | 
| 
      
 119 
     | 
    
         
            +
                  hash: -4521448315867850484
         
     | 
| 
       114 
120 
     | 
    
         
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         
     | 
| 
       115 
121 
     | 
    
         
             
              none: false
         
     | 
| 
       116 
122 
     | 
    
         
             
              requirements:
         
     | 
| 
         @@ -119,7 +125,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement 
     | 
|
| 
       119 
125 
     | 
    
         
             
                  version: '0'
         
     | 
| 
       120 
126 
     | 
    
         
             
                  segments:
         
     | 
| 
       121 
127 
     | 
    
         
             
                  - 0
         
     | 
| 
       122 
     | 
    
         
            -
                  hash:  
     | 
| 
      
 128 
     | 
    
         
            +
                  hash: -4521448315867850484
         
     | 
| 
       123 
129 
     | 
    
         
             
            requirements: []
         
     | 
| 
       124 
130 
     | 
    
         
             
            rubyforge_project: 
         
     | 
| 
       125 
131 
     | 
    
         
             
            rubygems_version: 1.8.24
         
     |