shopify-api-limits 0.0.5 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -23,28 +23,23 @@ ActiveResource does not make it easy to read the HTTP response headers, since th
23
23
  end
24
24
 
25
25
  == Solution
26
- Hack ActiveResource::Connection to introduce a new attr_reader :response and saved the returned HTTPResponse instance to it.
26
+ Hack ActiveResource::Connection to introduce a new attr_reader :response and capture the returned HTTPResponse instance from the #handle_response method.
27
27
 
28
- class ActiveResource
28
+ module ActiveResource
29
29
  class Connection
30
- # HACK 1: Add an attr_reader for response
30
+ # HACK: Add an attr_reader for response
31
31
  attr_reader :response
32
32
 
33
- def request(method, path, *arguments)
34
- result = ActiveSupport::Notifications.instrument("request.active_resource") do |payload|
35
- payload[:method] = method
36
- payload[:request_uri] = "#{site.scheme}://#{site.host}:#{site.port}#{path}"
37
- payload[:result] = http.send(method, path, *arguments)
38
- end
39
- # HACK 2: Save response to instance var @response
40
- @response = handle_response(result)
41
- rescue Timeout::Error => e
42
- raise TimeoutError.new(e.message)
43
- rescue OpenSSL::SSL::SSLError => e
44
- raise SSLError.new(e.message)
45
- end
33
+ # capture the original #handle_response as an unbound method instead of using alias
34
+ handle_response = self.instance_method(:handle_response)
35
+
36
+ # re-implement #handle_response to capture the returned HTTPResponse to an instance var.
37
+ define_method(:handle_response) do |response|
38
+ @response = handle_response.bind(self).call(response)
39
+ end
46
40
  end
47
- end
41
+ end
42
+
48
43
 
49
44
  Now it's possible to access the HTTPResponse instance directly from ActiveResource, via:
50
45
  foo = ActiveResource::Base.connection.response['http-header-param-foo']
@@ -55,23 +50,23 @@ Now it's possible to access the HTTPResponse instance directly from ActiveResour
55
50
  gem "shopify-api-limits"
56
51
 
57
52
  == Usage
58
- count_shop = ShopifyAPI.call_count :shop
59
- limit_shop = ShopifyAPI.call_limit :shop
53
+ count_shop = ShopifyAPI.credit_used :shop
54
+ limit_shop = ShopifyAPI.credit_limit :shop
60
55
 
61
- count_global = ShopifyAPI.call_count :global
62
- limit_global = ShopifyAPI.call_limit :global
56
+ count_global = ShopifyAPI.credit_used :global
57
+ limit_global = ShopifyAPI.credit_limit :global
63
58
 
64
- Generally, you shouldn't need to use the methods above directly -- rather they're used under-the-hood by the following helpful methods which don't require a scope (:shop/:global): If the <b>:global</b> scope has fewer calls available than the <b>:local</b> scope, the methods will operate upon the <b>:global</b> scope; otherwise, values will be returned based upon the <b>:shop</b> scope.
59
+ Generally, you shouldn't need to use the methods above directly -- rather, they're used under-the-hood by the following helpful methods which don't require a scope (<b>:shop/:global</b>): If the <b>:global</b> scope has fewer calls available than the <b>:local</b> scope, the methods will operate upon the <b>:global</b> scope; otherwise, values will be returned based upon the <b>:shop</b> scope.
65
60
 
66
- unless ShopifyAPI.maxed?
67
- #make some ShopifyAPI calls
61
+ unless ShopifyAPI.credit_maxed?
62
+ #make a ShopifyAPI call
68
63
  end
69
64
 
70
- until ShopifyAPI.maxed?
65
+ until ShopifyAPI.credit_maxed? || stop_condition
71
66
  # make some ShopifyAPI calls
72
67
  end
73
68
 
74
- while ShopifyAPI.available_calls
69
+ while ShopifyAPI.credit_left || stop_condition
75
70
  # make some ShopifyAPI calls
76
71
  end
77
72
 
@@ -4,22 +4,16 @@ module ShopifyAPI
4
4
  module Limits
5
5
  # Connection hack
6
6
  require 'shopify-api-limits/active_resource/connection'
7
+ require 'shopify-api-limits/shopify_api/limits'
7
8
 
8
- require 'shopify-api-limits/shopify_api/shopify_api'
9
-
10
- class Error < StandardError
11
- def self.status_code(code = nil)
12
- return @code unless code
13
- @code = code
14
- end
15
-
16
- def status_code
17
- self.class.status_code
18
- end
9
+ def self.included(klass)
10
+ klass.send(:extend, ClassMethods)
19
11
  end
20
-
21
- class GlobalError < Error; status_code(1) ; end
22
- class ShopError < Error; status_code(2) ; end
12
+
13
+ class Error < StandardError; end
14
+ class GlobalError < Error; end
15
+ class ShopError < Error; end
16
+
23
17
  end
24
18
  end
25
19
 
@@ -0,0 +1,72 @@
1
+ module ShopifyAPI
2
+ module Limits
3
+ module ClassMethods
4
+
5
+ # Takes form num_requests_executed/max_requests
6
+ # Eg: 101/3000
7
+ CREDIT_LIMIT_HEADER_PARAM = {
8
+ :global => 'http_x_shopify_api_call_limit',
9
+ :shop => 'http_x_shopify_shop_api_call_limit'
10
+ }
11
+
12
+ ##
13
+ # How many more API calls can I make?
14
+ # @return {Integer}
15
+ #
16
+ def credit_left
17
+ shop = credit_limit(:shop) - credit_used(:shop)
18
+ global = credit_limit(:global) - credit_used(:global)
19
+ shop < global ? shop : global
20
+ end
21
+ alias_method :available_calls, :credit_left
22
+
23
+ ##
24
+ # Have I reached my API call limit?
25
+ # @return {Boolean}
26
+ #
27
+ def credit_maxed?
28
+ credit_left == 0
29
+ end
30
+ alias_method :maxed?, :credit_maxed?
31
+
32
+ ##
33
+ # How many total API calls can I make?
34
+ # NOTE: subtracting 1 from credit_limit because I think ShopifyAPI cuts off at 299/2999 or shop/global limits.
35
+ # @param {Symbol} scope [:shop|:global]
36
+ # @return {Integer}
37
+ #
38
+ def credit_limit(scope=:shop)
39
+ @api_credit_limit ||= {}
40
+ @api_credit_limit[scope] ||= api_credit_limit_param(scope).pop.to_i - 1
41
+ end
42
+ alias_method :call_limit, :credit_limit
43
+
44
+ ##
45
+ # How many API calls have I made?
46
+ # @param {Symbol} scope [:shop|:global]
47
+ # @return {Integer}
48
+ #
49
+ def credit_used(scope=:shop)
50
+ api_credit_limit_param(scope).shift.to_i
51
+ end
52
+ alias_method :call_count, :credit_used
53
+
54
+ ##
55
+ # @return {HTTPResonse}
56
+ #
57
+ def response
58
+ Shop.current unless ActiveResource::Base.connection.response
59
+ ActiveResource::Base.connection.response
60
+ end
61
+
62
+ private
63
+
64
+ ##
65
+ # @return {Array}
66
+ #
67
+ def api_credit_limit_param(scope)
68
+ response[CREDIT_LIMIT_HEADER_PARAM[scope]].split('/')
69
+ end
70
+ end
71
+ end
72
+ end
@@ -1,5 +1,5 @@
1
1
  module ShopifyAPI
2
2
  module Limits
3
- VERSION = "0.0.5"
3
+ VERSION = "0.0.7"
4
4
  end
5
5
  end
@@ -3,30 +3,32 @@ require './spec/boot'
3
3
 
4
4
  describe "Limits" do
5
5
  it "Can fetch local limits" do
6
- count = ShopifyAPI.call_count :shop
7
- limit = ShopifyAPI.call_limit :shop
6
+ count = ShopifyAPI.credit_used :shop
7
+ limit = ShopifyAPI.credit_limit :shop
8
8
 
9
- (count < 300 && count > 0).should be_true
10
9
  (count < limit).should be_true
11
- ShopifyAPI.maxed?.should be_false
12
- (ShopifyAPI.available_calls > 0).should be_true
10
+ (count > 0).should be_true
11
+ ShopifyAPI.credit_maxed?.should be_false
12
+ (ShopifyAPI.credit_left > 0).should be_true
13
13
  end
14
14
 
15
15
  it "Can fetch global limits" do
16
- count = ShopifyAPI.call_count :global
17
- limit = ShopifyAPI.call_limit :global
16
+ count = ShopifyAPI.credit_used :global
17
+ limit = ShopifyAPI.creidt_limit :global
18
18
 
19
19
  (count < 3000 && count > 0).should be_true
20
20
  (count < limit).should be_true
21
- ShopifyAPI.maxed?.should be_false
22
- (ShopifyAPI.available_calls > 0).should be_true
21
+ ShopifyAPI.credit_maxed?.should be_false
22
+ (ShopifyAPI.credit_left > 0).should be_true
23
23
  end
24
24
 
25
25
  it "Can execute up to local max" do
26
- until ShopifyAPI.maxed?
26
+ until ShopifyAPI.credit_maxed?
27
27
  ShopifyAPI::Shop.current
28
- puts "avail: #{ShopifyAPI.available_calls}, maxed: #{ShopifyAPI.maxed?}"
28
+ puts "avail: #{ShopifyAPI.credit_left}, maxed: #{ShopifyAPI.credit_maxed?}"
29
29
  end
30
+ ShopifyAPI.credit_maxed?.should be_true
31
+ (ShopifyAPI.credit_left == 0).should be_true
30
32
  end
31
33
 
32
34
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: shopify-api-limits
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.5
5
+ version: 0.0.7
6
6
  platform: ruby
7
7
  authors:
8
8
  - Chris Scott
@@ -62,7 +62,7 @@ files:
62
62
  - Rakefile
63
63
  - lib/shopify-api-limits.rb
64
64
  - lib/shopify-api-limits/active_resource/connection.rb
65
- - lib/shopify-api-limits/shopify_api/shopify_api.rb
65
+ - lib/shopify-api-limits/shopify_api/limits.rb
66
66
  - lib/shopify-api-limits/version.rb
67
67
  - shopify-api-limits.gemspec
68
68
  - spec/boot.rb
@@ -1,72 +0,0 @@
1
- module ShopifyAPI
2
- module Limits
3
- def self.included(klass)
4
- klass.send(:extend, ClassMethods)
5
- end
6
- end
7
-
8
- module ClassMethods
9
-
10
- # Takes form num_requests_executed/max_requests
11
- # Eg: 101/3000
12
- CALL_LIMIT_HEADER_PARAM = {
13
- :global => 'http_x_shopify_api_call_limit',
14
- :shop => 'http_x_shopify_shop_api_call_limit'
15
- }
16
-
17
- ##
18
- # How many more API calls can I make?
19
- # @return {Integer}
20
- #
21
- def available_calls
22
- shop = call_limit(:shop) - call_count(:shop)
23
- global = call_limit(:global) - call_count(:global)
24
- shop < global ? shop : global
25
- end
26
-
27
- ##
28
- # Have I reached my API call limit?
29
- # @return {Boolean}
30
- #
31
- def maxed?
32
- available_calls == 0
33
- end
34
-
35
- ##
36
- # How many total API calls can I make?
37
- # NOTE: subtracting 1 from call_limit because I think ShopifyAPI cuts off at 299/2999 or shop/global limits.
38
- # @param {Symbol} scope [:shop|:global]
39
- # @return {Integer}
40
- #
41
- def call_limit(scope=:shop)
42
- @api_call_limit ||= {}
43
- @api_call_limit[scope] ||= api_call_limit_param(scope).pop.to_i - 1
44
- end
45
-
46
- ##
47
- # How many API calls have I made?
48
- # @param {Symbol} scope [:shop|:global]
49
- # @return {Integer}
50
- #
51
- def call_count(scope=:shop)
52
- api_call_limit_param(scope).shift.to_i
53
- end
54
-
55
- ##
56
- # @return {HTTPResonse}
57
- #
58
- def response
59
- Shop.current unless ActiveResource::Base.connection.response
60
- ActiveResource::Base.connection.response
61
- end
62
-
63
- private
64
-
65
- ##
66
- # @return {Array}
67
- #
68
- def api_call_limit_param(scope)
69
- response[CALL_LIMIT_HEADER_PARAM[scope]].split('/')
70
- end
71
- end
72
- end