jeff 0.2.4 → 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -1,2 +1,3 @@
1
1
  Gemfile.lock
2
+ amazon.yml
2
3
  pkg
data/Guardfile CHANGED
@@ -1,4 +1,5 @@
1
1
  guard 'rspec', :cli => '-fd' do
2
+ notification :off
2
3
  watch(%r{^spec/.+_spec\.rb$})
3
4
  watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
4
5
  watch('spec/spec_helper.rb') { 'spec' }
data/README.md CHANGED
@@ -76,32 +76,20 @@ Requests can be instrumented.
76
76
  ```ruby
77
77
  class Logger
78
78
  def self.instrument(name, params = {})
79
- if name =~ /request/
80
- $stderr.puts [
81
- params[:scheme],
82
- '://',
83
- params[:host],
84
- '/',
85
- params[:path],
86
- '?',
87
- params[:query]
88
- ].join
89
- yield if block_given?
90
- end
79
+ $stderr.puts name, params
80
+ yield if block_given?
91
81
  end
92
82
  end
93
83
 
94
- client.get query: {},
95
- instrumentor: Logger
84
+ client.get query: {}, instrumentor: Logger
96
85
  ```
97
86
 
98
87
  ### Miscellaneous
99
88
 
100
- HTTP connections are persistent.
89
+ * HTTP connections are persistent.
90
+ * By default, Jeff will retry failed requests 4 times.
101
91
 
102
- By default, Jeff will retry failed requests 4 times.
103
-
104
- For more detailed configuration options, check out [excon][excon].
92
+ For more detailed configuration options, read [excon][excon].
105
93
 
106
94
  ## Compatibility
107
95
 
@@ -0,0 +1,3 @@
1
+ key: foo
2
+ secret: bar
3
+ tag: baz
@@ -0,0 +1,41 @@
1
+ $:.unshift File.expand_path '../../lib', __FILE__
2
+
3
+ require 'yaml'
4
+
5
+ require 'jeff'
6
+ require 'pry'
7
+ require 'pry-doc'
8
+
9
+ class Client
10
+ include Jeff
11
+
12
+ params 'AssociateTag' => -> { tag },
13
+ 'Service' => 'AWSECommerceService',
14
+ 'Version' => '2011-08-01'
15
+
16
+ attr_accessor :tag
17
+
18
+ def initialize
19
+ self.key = config['key']
20
+ self.secret = config['secret']
21
+ self.tag = config['tag']
22
+ self.endpoint = 'http://ecs.amazonaws.com/onca/xml'
23
+ end
24
+
25
+ def find(asins)
26
+ params = {
27
+ 'Operation' => 'ItemLookup',
28
+ 'ItemId' => Array(asins).join(',')
29
+ }
30
+
31
+ get query: params
32
+ end
33
+
34
+ private
35
+
36
+ def config
37
+ @config ||= YAML.load_file File.expand_path '../amazon.yml', __FILE__
38
+ end
39
+ end
40
+
41
+ binding.pry
@@ -16,9 +16,8 @@ Gem::Specification.new do |gem|
16
16
  gem.require_paths = ['lib']
17
17
  gem.version = Jeff::VERSION
18
18
 
19
- gem.add_dependency 'excon', '~> 0.14.2'
19
+ gem.add_dependency 'excon', '~> 0.14.3'
20
20
  gem.add_development_dependency 'guard-rspec'
21
- gem.add_development_dependency 'pry'
22
21
  gem.add_development_dependency 'rake'
23
22
  gem.add_development_dependency 'rspec'
24
23
  end
@@ -1,8 +1,8 @@
1
- require 'base64'
2
1
  require 'time'
3
2
 
4
3
  require 'excon'
5
4
 
5
+ require 'jeff/secret'
6
6
  require 'jeff/version'
7
7
 
8
8
  module Jeff
@@ -10,32 +10,44 @@ module Jeff
10
10
  MissingKey = Class.new ArgumentError
11
11
  MissingSecret = Class.new ArgumentError
12
12
 
13
- SHA256 = OpenSSL::Digest::SHA256.new
14
13
  UNRESERVED = /([^\w.~-]+)/
15
14
 
16
15
  def self.included(base)
17
16
  base.extend ClassMethods
18
17
  end
19
18
 
20
- # Returns an Excon::Connection.
19
+ # Internal: Builds a sorted query.
20
+ #
21
+ # hsh - A hash of query parameters specific to the request.
22
+ #
23
+ # Returns a query String.
24
+ def build_query(hsh)
25
+ default_params
26
+ .merge(hsh)
27
+ .map { |k, v| "#{k}=#{ escape v }" }
28
+ .sort
29
+ .join '&'
30
+ end
31
+
32
+ # Internal: Returns an Excon::Connection.
21
33
  def connection
22
34
  @connection ||= Excon.new endpoint, headers: default_headers,
23
35
  idempotent: true
24
36
  end
25
37
 
26
- # Returns the Hash default request parameters.
38
+ # Internal: Returns the Hash default request parameters.
27
39
  def default_params
28
40
  self.class.params.reduce({}) do |a, (k, v)|
29
41
  a.update k => (v.is_a?(Proc) ? instance_exec(&v) : v)
30
42
  end
31
43
  end
32
44
 
33
- # Returns the Hash default headers.
45
+ # Internal: Returns the Hash default headers.
34
46
  def default_headers
35
47
  self.class.headers
36
48
  end
37
49
 
38
- # Gets the String AWS endpoint.
50
+ # Internal: Gets the String AWS endpoint.
39
51
  #
40
52
  # Raises a MissingEndpoint error if endpoint is missing.
41
53
  def endpoint
@@ -45,7 +57,7 @@ module Jeff
45
57
  # Sets the String AWS endpoint.
46
58
  attr_writer :endpoint
47
59
 
48
- # Gets the String AWS access key id.
60
+ # Internal: Gets the String AWS access key id.
49
61
  #
50
62
  # Raises a MissingKey error if key is missing.
51
63
  def key
@@ -55,15 +67,21 @@ module Jeff
55
67
  # Sets the String AWS access key id.
56
68
  attr_writer :key
57
69
 
58
- # Gets the String AWS secret key.
70
+ # Internal: Gets the Jeff::Secret.
59
71
  #
60
72
  # Raises a MissingSecret error if secret is missing.
61
73
  def secret
62
74
  @secret or raise MissingSecret
63
75
  end
64
76
 
65
- # Sets the String AWS secret key.
66
- attr_writer :secret
77
+ # Sets the AWS secret key.
78
+ #
79
+ # key - A String secret.
80
+ #
81
+ # Returns a Jeff::Secret.
82
+ def secret=(key)
83
+ @secret = Secret.new key
84
+ end
67
85
 
68
86
  # Generate HTTP request verb methods that sign queries and then delegate
69
87
  # request to Excon.
@@ -76,19 +94,6 @@ module Jeff
76
94
  DEF
77
95
  end
78
96
 
79
- # Internal: Builds a sorted query.
80
- #
81
- # hsh - A hash of query parameters specific to the request.
82
- #
83
- # Returns a query String.
84
- def build_query(hsh)
85
- default_params
86
- .merge(hsh)
87
- .map { |k, v| "#{k}=#{ escape v }" }
88
- .sort
89
- .join '&'
90
- end
91
-
92
97
  private
93
98
 
94
99
  def sign(opts)
@@ -96,13 +101,11 @@ module Jeff
96
101
 
97
102
  string_to_sign = [
98
103
  opts[:method].upcase,
99
- opts[:host] || connection.connection[:host],
100
- opts[:path] || connection.connection[:path],
104
+ connection_host,
105
+ opts[:path] || connection_path,
101
106
  query
102
107
  ].join "\n"
103
-
104
- digest = OpenSSL::HMAC.digest SHA256, secret, string_to_sign
105
- signature = Base64.encode64(digest).chomp
108
+ signature = secret.sign string_to_sign
106
109
 
107
110
  opts.update query: [
108
111
  query,
@@ -110,6 +113,14 @@ module Jeff
110
113
  ].join('&')
111
114
  end
112
115
 
116
+ def connection_host
117
+ [connection.connection[:host], connection.connection[:port]].join ':'
118
+ end
119
+
120
+ def connection_path
121
+ connection.connection[:path]
122
+ end
123
+
113
124
  def escape(val)
114
125
  val.to_s.gsub(UNRESERVED) do
115
126
  '%' + $1.unpack('H2' * $1.bytesize).join('%').upcase
@@ -0,0 +1,21 @@
1
+ require 'base64'
2
+
3
+ module Jeff
4
+ class Secret
5
+ SHA256 = OpenSSL::Digest::SHA256.new
6
+
7
+ def initialize(key)
8
+ @key = key
9
+ end
10
+
11
+ def sign(message)
12
+ Base64.encode64(digest(message)).chomp
13
+ end
14
+
15
+ private
16
+
17
+ def digest(message)
18
+ OpenSSL::HMAC.digest SHA256, @key, message
19
+ end
20
+ end
21
+ end
@@ -1,3 +1,3 @@
1
1
  module Jeff
2
- VERSION = '0.2.4'
2
+ VERSION = '0.2.5'
3
3
  end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ module Jeff
4
+ describe Secret do
5
+ let(:secret) { Secret.new 'key' }
6
+
7
+ describe '#sign' do
8
+ after { secret.sign 'message' }
9
+
10
+ it 'should digest' do
11
+ secret.should_receive(:digest)
12
+ .and_return double.as_null_object
13
+ end
14
+ it 'should Base64-encode' do
15
+ Base64.should_receive(:encode64)
16
+ .and_return double.as_null_object
17
+ end
18
+ end
19
+ end
20
+ end
@@ -128,6 +128,8 @@ describe Jeff do
128
128
  end
129
129
  end
130
130
 
131
+ after { Excon.stubs.clear }
132
+
131
133
  it "should make a #{method.upcase} request" do
132
134
  subject[:method].should eql method.to_sym
133
135
  end
@@ -151,6 +153,8 @@ describe Jeff do
151
153
  end
152
154
  end
153
155
 
156
+ after { Excon.stubs.clear }
157
+
154
158
  it 'should retry' do
155
159
  client.get(mock: true).status.should be 200
156
160
  end
@@ -1,4 +1,12 @@
1
- require 'pry'
1
+ begin
2
+ require 'pry'
3
+ require 'pry-doc'
4
+ rescue LoadError
5
+ end
2
6
  require 'rspec'
3
7
 
4
8
  require 'jeff'
9
+
10
+ RSpec.configure do |c|
11
+ c.order = :random
12
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jeff
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.2.5
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: 2012-07-05 00:00:00.000000000 Z
12
+ date: 2012-07-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: excon
@@ -18,7 +18,7 @@ dependencies:
18
18
  requirements:
19
19
  - - ~>
20
20
  - !ruby/object:Gem::Version
21
- version: 0.14.2
21
+ version: 0.14.3
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
@@ -26,7 +26,7 @@ dependencies:
26
26
  requirements:
27
27
  - - ~>
28
28
  - !ruby/object:Gem::Version
29
- version: 0.14.2
29
+ version: 0.14.3
30
30
  - !ruby/object:Gem::Dependency
31
31
  name: guard-rspec
32
32
  requirement: !ruby/object:Gem::Requirement
@@ -43,22 +43,6 @@ dependencies:
43
43
  - - ! '>='
44
44
  - !ruby/object:Gem::Version
45
45
  version: '0'
46
- - !ruby/object:Gem::Dependency
47
- name: pry
48
- requirement: !ruby/object:Gem::Requirement
49
- none: false
50
- requirements:
51
- - - ! '>='
52
- - !ruby/object:Gem::Version
53
- version: '0'
54
- type: :development
55
- prerelease: false
56
- version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
- requirements:
59
- - - ! '>='
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
46
  - !ruby/object:Gem::Dependency
63
47
  name: rake
64
48
  requirement: !ruby/object:Gem::Requirement
@@ -105,9 +89,13 @@ files:
105
89
  - LICENSE
106
90
  - README.md
107
91
  - Rakefile
92
+ - examples/amazon.yml.example
93
+ - examples/debug.rb
108
94
  - jeff.gemspec
109
95
  - lib/jeff.rb
96
+ - lib/jeff/secret.rb
110
97
  - lib/jeff/version.rb
98
+ - spec/jeff/secret_spec.rb
111
99
  - spec/jeff_spec.rb
112
100
  - spec/spec_helper.rb
113
101
  homepage: https://github.com/hakanensari/jeff
@@ -122,18 +110,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
122
110
  - - ! '>='
123
111
  - !ruby/object:Gem::Version
124
112
  version: '0'
125
- segments:
126
- - 0
127
- hash: 13761434509478082
128
113
  required_rubygems_version: !ruby/object:Gem::Requirement
129
114
  none: false
130
115
  requirements:
131
116
  - - ! '>='
132
117
  - !ruby/object:Gem::Version
133
118
  version: '0'
134
- segments:
135
- - 0
136
- hash: 13761434509478082
137
119
  requirements: []
138
120
  rubyforge_project:
139
121
  rubygems_version: 1.8.23
@@ -141,5 +123,7 @@ signing_key:
141
123
  specification_version: 3
142
124
  summary: AWS client
143
125
  test_files:
126
+ - spec/jeff/secret_spec.rb
144
127
  - spec/jeff_spec.rb
145
128
  - spec/spec_helper.rb
129
+ has_rdoc: