agent_cooper 0.0.7.pre → 0.0.7

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/.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