agent_cooper 0.0.7.pre → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
data/.rvmrc CHANGED
@@ -1 +1 @@
1
- rvm use --create 1.9.2@agent_cooper
1
+ rvm use --create 1.9.3@agent_cooper
data/README.md CHANGED
@@ -3,9 +3,14 @@ Agent Cooper
3
3
 
4
4
  [![travis](https://secure.travis-ci.org/rclosner/agent_cooper.png)](http://travis-ci.org/rclosner/agent_cooper)
5
5
 
6
+
7
+ <img src="https://github.com/rclosner/agent_cooper/raw/master/agent_cooper.jpg" width="200px">
8
+
9
+
6
10
  Agent Cooper is a minimalist, Nokogiri-based Ruby wrapper to the [eBay Web Services API](http://developer.ebay.com/).
7
11
 
8
- It supports the following eBay APIs are supported:
12
+
13
+ It supports the following eBay APIs:
9
14
  - [Finding API](http://developer.ebay.com/products/finding/)
10
15
  - [Shopping API](http://developer.ebay.com/products/shopping/)
11
16
  - [Merchandising API](http://developer.ebay.com/products/merchandising/)
@@ -50,6 +55,14 @@ Return a hash:
50
55
  returns: {'getSearchKeywordsRecommendationResponse' => {'xmnls' => 'http://www.ebay.com/marketplace/search/v1/services', 'ack' => 'Success', 'version' => '1.9.0', 'keywords' => 'harry potter'}}
51
56
  ```
52
57
 
58
+ If you need to preserve XML attributes
59
+
60
+ ```ruby
61
+ response.to_hash(:preserve_attributes => true)
62
+
63
+ returns: {'CurrentPrice' => {'__content__' => '154.99', 'CurrencyID' => 'EUR' }}
64
+ ```
65
+
53
66
  Or parse a response with Nokogiri:
54
67
 
55
68
  ```ruby
@@ -59,6 +72,3 @@ Or parse a response with Nokogiri:
59
72
 
60
73
  response.xml.xpath("//Item")
61
74
  ```
62
- ----
63
-
64
- Based on hakanensari's [amazon_product](http://github.com/hakanensari/amazon_product).
data/agent_cooper.gemspec CHANGED
@@ -16,8 +16,8 @@ Gem::Specification.new do |s|
16
16
 
17
17
  runtime_dependencies = {
18
18
  "httpclient" => "~> 2.2.3",
19
- "nokogiri" => "~> 1.5.0",
20
- "virtus" => "~> 0.0.9"
19
+ "nokogiri" => "~> 1.5.5",
20
+ "virtus" => "~> 0.5.1"
21
21
  }
22
22
 
23
23
  runtime_dependencies.each {|lib, version| s.add_runtime_dependency(lib, version) }
data/agent_cooper.jpg ADDED
Binary file
@@ -1,9 +1,9 @@
1
1
  module AgentCooper
2
2
  class Response
3
3
 
4
- include Virtus
5
-
6
- attribute :response, Object, :accessor => :protected
4
+ def initialize(attributes)
5
+ @response = attributes.fetch(:response)
6
+ end
7
7
 
8
8
  # @api public
9
9
  def body
@@ -11,8 +11,8 @@ module AgentCooper
11
11
  end
12
12
 
13
13
  # @api public
14
- def to_hash
15
- AgentCooper::Builder.from_xml(xml)
14
+ def to_hash(options = {})
15
+ AgentCooper::Utils::Hash.from_xml(xml, options)
16
16
  end
17
17
 
18
18
  # @api public
@@ -30,5 +30,9 @@ module AgentCooper
30
30
  @xml ||= Nokogiri::XML(body)
31
31
  end
32
32
 
33
+ protected
34
+
35
+ attr_reader :response
36
+
33
37
  end
34
38
  end
@@ -0,0 +1,94 @@
1
+ module AgentCooper
2
+ module Utils
3
+ class Hash
4
+ def self.from_xml(xml, options)
5
+ unless xml.is_a?(Nokogiri::XML::Node)
6
+ raise ArgumentError, "`xml` must be an instance of Nokogiri::XML::Node"
7
+ end
8
+
9
+ doc = XMLDocumentDecorator.new(xml, options)
10
+
11
+ doc.to_hash
12
+ end
13
+
14
+ class XMLDocumentDecorator
15
+ def initialize(document, options)
16
+ @document, @options = document, options
17
+ end
18
+
19
+ def to_hash
20
+ root.to_hash
21
+ end
22
+
23
+ def root
24
+ XMLNodeDecorator.new(document.root, options)
25
+ end
26
+
27
+ def method_missing(m, *args)
28
+ document.send(m, *args)
29
+ end
30
+
31
+ private
32
+
33
+ attr_reader :document, :options
34
+ end
35
+
36
+ class XMLNodeDecorator
37
+ CONTENT_ROOT = '__content__'.freeze
38
+
39
+ def initialize(node, options)
40
+ @node, @options = node, options
41
+ end
42
+
43
+ def to_hash(hash = {})
44
+ node_hash = {}
45
+
46
+ # Insert node hash into parent hash correctly
47
+ case hash[name]
48
+ when Array then hash[name] << node_hash
49
+ when Hash then hash[name] = [hash[name], node_hash]
50
+ when nil then hash[name] = node_hash
51
+ end
52
+
53
+ # Handle child elements
54
+ children.each do |c|
55
+ child = XMLNodeDecorator.new(c, options)
56
+
57
+ if child.element?
58
+ child.to_hash(node_hash)
59
+ elsif child.text? || child.cdata?
60
+ unless preserve_attributes?
61
+ hash[name] = child.content
62
+ else
63
+ node_hash[CONTENT_ROOT] ||= ''
64
+ node_hash[CONTENT_ROOT] << child.content
65
+ end
66
+ end
67
+ end
68
+
69
+ # Remove content node if it is blank and there are child tags
70
+ if node_hash.length > 1 && node_hash[CONTENT_ROOT].empty?
71
+ node_hash.delete(CONTENT_ROOT)
72
+ end
73
+
74
+ # Handle attributes
75
+ attribute_nodes.each {|a| node_hash[a.node_name] = a.value }
76
+
77
+ hash
78
+ end
79
+
80
+ def method_missing(m, *args)
81
+ node.send(m, *args)
82
+ end
83
+
84
+ private
85
+
86
+ def preserve_attributes?
87
+ options.fetch(:preserve_attributes) { false }
88
+ end
89
+
90
+ attr_reader :node, :options
91
+ end
92
+ end
93
+ end
94
+ end
@@ -1,3 +1,3 @@
1
1
  module AgentCooper
2
- VERSION = "0.0.7.pre"
2
+ VERSION = "0.0.7"
3
3
  end
data/lib/agent_cooper.rb CHANGED
@@ -11,7 +11,7 @@ end
11
11
 
12
12
  require 'agent_cooper/config'
13
13
  require 'agent_cooper/response'
14
- require 'agent_cooper/builder'
14
+ require 'agent_cooper/utils/hash'
15
15
 
16
16
  require 'agent_cooper/request'
17
17
  require 'agent_cooper/requests/finder'
@@ -12,7 +12,13 @@ describe AgentCooper::Response do
12
12
  its(:body) { should eql(body) }
13
13
  its(:code) { should eql(code) }
14
14
 
15
- its(:to_hash) { should eql({"foo" => "bar"}) }
15
+ its(:to_hash) { should eql({"root" => {"foo" => "bar"}}) }
16
+
17
+ context "when options are passed" do
18
+ specify "preserve_attributes" do
19
+ subject.to_hash(:preserve_attributes => true).should eql({"root" => {"foo" => {"__content__" => "bar"}}})
20
+ end
21
+ end
16
22
 
17
23
  its(:xml) { should be_a(Nokogiri::XML::Document) }
18
24
  its(:valid?) { should be_true }
@@ -22,4 +28,4 @@ describe AgentCooper::Response do
22
28
  its(:valid?) { should be_false }
23
29
  end
24
30
 
25
- end
31
+ end
metadata CHANGED
@@ -1,19 +1,19 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: agent_cooper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7.pre
5
- prerelease: 6
4
+ version: 0.0.7
5
+ prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Ryan Closner
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-11-12 00:00:00.000000000Z
12
+ date: 2012-07-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: httpclient
16
- requirement: &70240722674260 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,32 +21,47 @@ dependencies:
21
21
  version: 2.2.3
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70240722674260
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 2.2.3
25
30
  - !ruby/object:Gem::Dependency
26
31
  name: nokogiri
27
- requirement: &70240722673780 !ruby/object:Gem::Requirement
32
+ requirement: !ruby/object:Gem::Requirement
28
33
  none: false
29
34
  requirements:
30
35
  - - ~>
31
36
  - !ruby/object:Gem::Version
32
- version: 1.5.0
37
+ version: 1.5.5
33
38
  type: :runtime
34
39
  prerelease: false
35
- version_requirements: *70240722673780
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 1.5.5
36
46
  - !ruby/object:Gem::Dependency
37
47
  name: virtus
38
- requirement: &70240722673340 !ruby/object:Gem::Requirement
48
+ requirement: !ruby/object:Gem::Requirement
39
49
  none: false
40
50
  requirements:
41
51
  - - ~>
42
52
  - !ruby/object:Gem::Version
43
- version: 0.0.9
53
+ version: 0.5.1
44
54
  type: :runtime
45
55
  prerelease: false
46
- version_requirements: *70240722673340
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 0.5.1
47
62
  - !ruby/object:Gem::Dependency
48
63
  name: cucumber
49
- requirement: &70240722672580 !ruby/object:Gem::Requirement
64
+ requirement: !ruby/object:Gem::Requirement
50
65
  none: false
51
66
  requirements:
52
67
  - - ~>
@@ -54,10 +69,15 @@ dependencies:
54
69
  version: 1.1.2
55
70
  type: :development
56
71
  prerelease: false
57
- version_requirements: *70240722672580
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 1.1.2
58
78
  - !ruby/object:Gem::Dependency
59
79
  name: rake
60
- requirement: &70240722672140 !ruby/object:Gem::Requirement
80
+ requirement: !ruby/object:Gem::Requirement
61
81
  none: false
62
82
  requirements:
63
83
  - - ~>
@@ -65,10 +85,15 @@ dependencies:
65
85
  version: 0.9.2
66
86
  type: :development
67
87
  prerelease: false
68
- version_requirements: *70240722672140
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: 0.9.2
69
94
  - !ruby/object:Gem::Dependency
70
95
  name: rspec
71
- requirement: &70240722671700 !ruby/object:Gem::Requirement
96
+ requirement: !ruby/object:Gem::Requirement
72
97
  none: false
73
98
  requirements:
74
99
  - - ~>
@@ -76,10 +101,15 @@ dependencies:
76
101
  version: 2.7.0
77
102
  type: :development
78
103
  prerelease: false
79
- version_requirements: *70240722671700
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ~>
108
+ - !ruby/object:Gem::Version
109
+ version: 2.7.0
80
110
  - !ruby/object:Gem::Dependency
81
111
  name: vcr
82
- requirement: &70240722668700 !ruby/object:Gem::Requirement
112
+ requirement: !ruby/object:Gem::Requirement
83
113
  none: false
84
114
  requirements:
85
115
  - - ~>
@@ -87,10 +117,15 @@ dependencies:
87
117
  version: 1.11.3
88
118
  type: :development
89
119
  prerelease: false
90
- version_requirements: *70240722668700
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ~>
124
+ - !ruby/object:Gem::Version
125
+ version: 1.11.3
91
126
  - !ruby/object:Gem::Dependency
92
127
  name: webmock
93
- requirement: &70240722668060 !ruby/object:Gem::Requirement
128
+ requirement: !ruby/object:Gem::Requirement
94
129
  none: false
95
130
  requirements:
96
131
  - - ~>
@@ -98,7 +133,12 @@ dependencies:
98
133
  version: 1.7.7
99
134
  type: :development
100
135
  prerelease: false
101
- version_requirements: *70240722668060
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ~>
140
+ - !ruby/object:Gem::Version
141
+ version: 1.7.7
102
142
  description: A Ruby wrapper to the eBay Web Services API
103
143
  email:
104
144
  - ryan@ryanclosner.com
@@ -113,6 +153,7 @@ files:
113
153
  - README.md
114
154
  - Rakefile
115
155
  - agent_cooper.gemspec
156
+ - agent_cooper.jpg
116
157
  - features/finder.feature
117
158
  - features/merchandiser.feature
118
159
  - features/shopper.feature
@@ -123,7 +164,6 @@ files:
123
164
  - features/support/env.rb
124
165
  - features/support/vcr.rb
125
166
  - lib/agent_cooper.rb
126
- - lib/agent_cooper/builder.rb
127
167
  - lib/agent_cooper/config.rb
128
168
  - lib/agent_cooper/request.rb
129
169
  - lib/agent_cooper/requests/finder.rb
@@ -131,6 +171,7 @@ files:
131
171
  - lib/agent_cooper/requests/shopper.rb
132
172
  - lib/agent_cooper/response.rb
133
173
  - lib/agent_cooper/synchrony.rb
174
+ - lib/agent_cooper/utils/hash.rb
134
175
  - lib/agent_cooper/version.rb
135
176
  - spec/agent_cooper/config_spec.rb
136
177
  - spec/agent_cooper/request_spec.rb
@@ -177,52 +218,13 @@ required_ruby_version: !ruby/object:Gem::Requirement
177
218
  required_rubygems_version: !ruby/object:Gem::Requirement
178
219
  none: false
179
220
  requirements:
180
- - - ! '>'
221
+ - - ! '>='
181
222
  - !ruby/object:Gem::Version
182
- version: 1.3.1
223
+ version: '0'
183
224
  requirements: []
184
225
  rubyforge_project: agent_cooper
185
- rubygems_version: 1.8.10
226
+ rubygems_version: 1.8.21
186
227
  signing_key:
187
228
  specification_version: 3
188
229
  summary: A Ruby wrapper to the eBay Web Services API
189
- test_files:
190
- - features/finder.feature
191
- - features/merchandiser.feature
192
- - features/shopper.feature
193
- - features/step_definitions/agent_cooper_steps.rb
194
- - features/step_definitions/finder_steps.rb
195
- - features/step_definitions/merchandiser_steps.rb
196
- - features/step_definitions/shopper_steps.rb
197
- - features/support/env.rb
198
- - features/support/vcr.rb
199
- - spec/agent_cooper/config_spec.rb
200
- - spec/agent_cooper/request_spec.rb
201
- - spec/agent_cooper/requests/finder_spec.rb
202
- - spec/agent_cooper/requests/merchandiser_spec.rb
203
- - spec/agent_cooper/requests/shopper_spec.rb
204
- - spec/agent_cooper/response_spec.rb
205
- - spec/agent_cooper_spec.rb
206
- - spec/fixtures/cassettes/finder/find_items_advanced/0612b88aa6d3bcece0d88b587267b6de.yml
207
- - spec/fixtures/cassettes/finder/find_items_by_category/e782300f74c9c6669d5c0d9719d03853.yml
208
- - spec/fixtures/cassettes/finder/find_items_by_keywords/a6e74b4aff9c701b73db82def8b31bc8.yml
209
- - spec/fixtures/cassettes/finder/find_items_by_product/9dd9b3128cbf3cda22e027207825c4c0.yml
210
- - spec/fixtures/cassettes/finder/find_items_in_ebay_stores/6514aa6b1db3f9fbddcfbb32b58fb67e.yml
211
- - spec/fixtures/cassettes/finder/get_histograms/1cc52302ce2de278051c3b6be90ccd36.yml
212
- - spec/fixtures/cassettes/finder/get_search_keywords_recommendation/85a972f0b32d1e011b2c8b74fff19261.yml
213
- - spec/fixtures/cassettes/merchandiser/get_most_watched_items/66600b7c4cb52b32e517f3e5563463e1.yml
214
- - spec/fixtures/cassettes/merchandiser/get_related_category_items/c74a3e3dff9ffb3e5a84c057d1a88bf3.yml
215
- - spec/fixtures/cassettes/merchandiser/get_similar_items/943af1f951bf437e72a0d6325bc167af.yml
216
- - spec/fixtures/cassettes/merchandiser/get_top_selling_products/323d900971616df3712c8bc7737a70f1.yml
217
- - spec/fixtures/cassettes/shopper/find_half_products/7bf13f5c5fad44a19d46d68168dc05a3.yml
218
- - spec/fixtures/cassettes/shopper/find_popular_items/67c26e00c0be5bfa5994b1ae408517f7.yml
219
- - spec/fixtures/cassettes/shopper/find_popular_searches/bcf07f2cb90cae7cb40f2252dde126a6.yml
220
- - spec/fixtures/cassettes/shopper/find_products/b1001bc7a19381f533b36d7b40daedd7.yml
221
- - spec/fixtures/cassettes/shopper/find_reviews_and_guides/ceb14bd40e2371d3e58e9c4645e857f2.yml
222
- - spec/fixtures/cassettes/shopper/get_item_status/83876f24642637642979b09a6475b475.yml
223
- - spec/fixtures/cassettes/shopper/get_multiple_items/1f42d0c0fe105f8c0ad79d08f1900738.yml
224
- - spec/fixtures/cassettes/shopper/get_shipping_costs/9ca24c61a943a3f6647e45b0ae30261f.yml
225
- - spec/fixtures/cassettes/shopper/get_single_item/d50997fefbf6099325c3c01ef2a4cb51.yml
226
- - spec/fixtures/cassettes/shopper/get_user_profile/a5a8fd7e8aeaea9a16dc09c6cb8f3092.yml
227
- - spec/spec_helper.rb
228
- - spec/support/shared/request.rb
230
+ test_files: []
@@ -1,46 +0,0 @@
1
- module AgentCooper
2
- class Builder
3
-
4
- # Based on https://gist.github.com/335286
5
-
6
- # @api public
7
- def self.from_xml(xml)
8
- case xml
9
- when Nokogiri::XML::Document
10
- from_xml(xml.root)
11
- when Nokogiri::XML::Element
12
- hsh = {}
13
-
14
- xml.attributes.each_pair do |key, attr|
15
- hsh[key] = attr.value
16
- end
17
-
18
- xml.children.each do |child|
19
- result = from_xml(child)
20
-
21
- if child.name == 'text'
22
- if hsh.empty?
23
- return result
24
- else
25
- hsh['__content__'] = result
26
- end
27
- elsif hsh[child.name]
28
- case hsh[child.name]
29
- when Array
30
- hsh[child.name] << result
31
- else
32
- hsh[child.name] = [hsh[child.name]] << result
33
- end
34
- else
35
- hsh[child.name] = result
36
- end
37
- end
38
-
39
- hsh
40
- else
41
- xml.content.to_s
42
- end
43
- end
44
-
45
- end
46
- end