agent_cooper 0.0.6 → 0.0.7.pre
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +0 -1
- data/.rvmrc +1 -0
- data/.travis.yml +2 -0
- data/README.md +6 -4
- data/Rakefile +2 -0
- data/agent_cooper.gemspec +16 -14
- data/features/finder.feature +1 -1
- data/features/support/env.rb +1 -5
- data/features/support/vcr.rb +2 -6
- data/lib/agent_cooper.rb +13 -15
- data/lib/agent_cooper/builder.rb +46 -0
- data/lib/agent_cooper/config.rb +6 -1
- data/lib/agent_cooper/request.rb +54 -30
- data/lib/agent_cooper/requests/finder.rb +12 -15
- data/lib/agent_cooper/requests/merchandiser.rb +15 -16
- data/lib/agent_cooper/requests/shopper.rb +14 -14
- data/lib/agent_cooper/response.rb +9 -10
- data/lib/agent_cooper/synchrony.rb +22 -9
- data/lib/agent_cooper/version.rb +1 -1
- data/spec/agent_cooper/config_spec.rb +36 -0
- data/spec/agent_cooper/request_spec.rb +17 -106
- data/spec/agent_cooper/requests/finder_spec.rb +11 -8
- data/spec/agent_cooper/requests/merchandiser_spec.rb +13 -7
- data/spec/agent_cooper/requests/shopper_spec.rb +12 -7
- data/spec/agent_cooper/response_spec.rb +21 -53
- data/spec/agent_cooper_spec.rb +5 -2
- data/spec/fixtures/cassettes/finder/find_items_advanced/0612b88aa6d3bcece0d88b587267b6de.yml +590 -0
- data/spec/fixtures/cassettes/finder/find_items_by_category/e782300f74c9c6669d5c0d9719d03853.yml +420 -0
- data/spec/fixtures/cassettes/finder/find_items_by_keywords/a6e74b4aff9c701b73db82def8b31bc8.yml +632 -0
- data/spec/fixtures/cassettes/finder/find_items_by_product/9dd9b3128cbf3cda22e027207825c4c0.yml +684 -0
- data/spec/fixtures/cassettes/finder/find_items_in_ebay_stores/6514aa6b1db3f9fbddcfbb32b58fb67e.yml +464 -0
- data/spec/fixtures/cassettes/finder/get_histograms/{80bd04d96cd529af4148866a2d28f079.yml → 1cc52302ce2de278051c3b6be90ccd36.yml} +11 -11
- data/spec/fixtures/cassettes/finder/get_search_keywords_recommendation/{ec96bf3af091373de08550ff46f86c87.yml → 85a972f0b32d1e011b2c8b74fff19261.yml} +6 -6
- data/spec/fixtures/cassettes/merchandiser/get_most_watched_items/66600b7c4cb52b32e517f3e5563463e1.yml +51 -0
- data/spec/fixtures/cassettes/merchandiser/get_related_category_items/{c949e90fb2bd975020df657a4348328d.yml → c74a3e3dff9ffb3e5a84c057d1a88bf3.yml} +6 -6
- data/spec/fixtures/cassettes/merchandiser/get_similar_items/{56c2c41a60135db83d359053778a065f.yml → 943af1f951bf437e72a0d6325bc167af.yml} +6 -6
- data/spec/fixtures/cassettes/merchandiser/get_top_selling_products/323d900971616df3712c8bc7737a70f1.yml +51 -0
- data/spec/fixtures/cassettes/shopper/find_half_products/{77ad8a2ade8e4efadef07346677e43a9.yml → 7bf13f5c5fad44a19d46d68168dc05a3.yml} +15 -15
- data/spec/fixtures/cassettes/shopper/find_popular_items/67c26e00c0be5bfa5994b1ae408517f7.yml +258 -0
- data/spec/fixtures/cassettes/shopper/find_popular_searches/{6db9b375ea610e870e7a4ca4e20974ec.yml → bcf07f2cb90cae7cb40f2252dde126a6.yml} +8 -8
- data/spec/fixtures/cassettes/shopper/find_products/{3fd6d6000037cd409ab1ef18a6075257.yml → b1001bc7a19381f533b36d7b40daedd7.yml} +16 -16
- data/spec/fixtures/cassettes/shopper/find_reviews_and_guides/{8586a984e122cb84136d3cc0bb8bec77.yml → ceb14bd40e2371d3e58e9c4645e857f2.yml} +16 -16
- data/spec/fixtures/cassettes/shopper/get_item_status/{f34cf10c602f9fec7a388297888b4299.yml → 83876f24642637642979b09a6475b475.yml} +8 -8
- data/spec/fixtures/cassettes/shopper/get_multiple_items/{c1183c23add6cad9afbb73f986c2692e.yml → 1f42d0c0fe105f8c0ad79d08f1900738.yml} +8 -8
- data/spec/fixtures/cassettes/shopper/get_shipping_costs/{e7de18031f266637414155639797c097.yml → 9ca24c61a943a3f6647e45b0ae30261f.yml} +8 -8
- data/spec/fixtures/cassettes/shopper/get_single_item/{d4a895de6b214907c47a0b32ab630b9a.yml → d50997fefbf6099325c3c01ef2a4cb51.yml} +8 -8
- data/spec/fixtures/cassettes/shopper/get_user_profile/{dccabbf426bfeba4d898ca546e17dd4b.yml → a5a8fd7e8aeaea9a16dc09c6cb8f3092.yml} +8 -8
- data/spec/spec_helper.rb +2 -1
- data/spec/support/shared/request.rb +67 -0
- metadata +83 -92
- data/lib/agent_cooper/nokogiri_decorator.rb +0 -47
- data/spec/fixtures/cassettes/finder/find_items_advanced/d49218a9522a4a055e31fc6b88c3a2b5.yml +0 -528
- data/spec/fixtures/cassettes/finder/find_items_by_category/85e07de9993e68d09e895f1b01234c5a.yml +0 -463
- data/spec/fixtures/cassettes/finder/find_items_by_keywords/91d7d9b4b62b82877604465a20f9ffa9.yml +0 -668
- data/spec/fixtures/cassettes/finder/find_items_by_product/59ee1391b6dfc2a93e30c8911942fc71.yml +0 -744
- data/spec/fixtures/cassettes/finder/find_items_in_ebay_stores/c7d658804b6353fda03809c21b183af2.yml +0 -472
- data/spec/fixtures/cassettes/merchandiser/get_most_watched_items/3c0cb6fb7bb94b384cae15be175e9640.yml +0 -51
- data/spec/fixtures/cassettes/merchandiser/get_top_selling_products/a82dcb1f094754e54f2a5de191818c3f.yml +0 -53
- data/spec/fixtures/cassettes/shopper/find_popular_items/532fcb32fee187bdc6cc5fb7e4336992.yml +0 -258
- data/spec/fixtures/ebay.yml.sample +0 -1
data/.gitignore
CHANGED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm use --create 1.9.2@agent_cooper
|
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
Agent Cooper
|
2
2
|
======
|
3
3
|
|
4
|
-
|
4
|
+
[![travis](https://secure.travis-ci.org/rclosner/agent_cooper.png)](http://travis-ci.org/rclosner/agent_cooper)
|
5
5
|
|
6
|
-
|
6
|
+
Agent Cooper is a minimalist, Nokogiri-based Ruby wrapper to the [eBay Web Services API](http://developer.ebay.com/).
|
7
|
+
|
8
|
+
It supports the following eBay APIs are supported:
|
7
9
|
- [Finding API](http://developer.ebay.com/products/finding/)
|
8
10
|
- [Shopping API](http://developer.ebay.com/products/shopping/)
|
9
11
|
- [Merchandising API](http://developer.ebay.com/products/merchandising/)
|
@@ -14,7 +16,7 @@ Set up.
|
|
14
16
|
|
15
17
|
```ruby
|
16
18
|
AgentCooper.configure do |config|
|
17
|
-
config.app_id = "
|
19
|
+
config.app_id = "YOUR_EBAY_APP_ID"
|
18
20
|
end
|
19
21
|
```
|
20
22
|
|
@@ -59,4 +61,4 @@ Or parse a response with Nokogiri:
|
|
59
61
|
```
|
60
62
|
----
|
61
63
|
|
62
|
-
Based on
|
64
|
+
Based on hakanensari's [amazon_product](http://github.com/hakanensari/amazon_product).
|
data/Rakefile
CHANGED
data/agent_cooper.gemspec
CHANGED
@@ -7,28 +7,30 @@ Gem::Specification.new do |s|
|
|
7
7
|
s.version = AgentCooper::VERSION
|
8
8
|
s.platform = Gem::Platform::RUBY
|
9
9
|
s.authors = ["Ryan Closner"]
|
10
|
-
s.email = ["ryan
|
10
|
+
s.email = ["ryan@ryanclosner.com"]
|
11
11
|
s.homepage = "https://rubygems.org/gems/agent_cooper"
|
12
12
|
s.summary = %q{A Ruby wrapper to the eBay Web Services API}
|
13
13
|
s.description = %q{A Ruby wrapper to the eBay Web Services API}
|
14
14
|
|
15
15
|
s.rubyforge_project = "agent_cooper"
|
16
16
|
|
17
|
-
{
|
18
|
-
|
19
|
-
|
20
|
-
|
17
|
+
runtime_dependencies = {
|
18
|
+
"httpclient" => "~> 2.2.3",
|
19
|
+
"nokogiri" => "~> 1.5.0",
|
20
|
+
"virtus" => "~> 0.0.9"
|
21
|
+
}
|
21
22
|
|
23
|
+
runtime_dependencies.each {|lib, version| s.add_runtime_dependency(lib, version) }
|
22
24
|
|
23
|
-
{
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
25
|
+
development_dependencies = {
|
26
|
+
"cucumber" => "~> 1.1.2",
|
27
|
+
"rake" => "~> 0.9.2",
|
28
|
+
"rspec" => "~> 2.7.0",
|
29
|
+
"vcr" => "~> 1.11.3",
|
30
|
+
"webmock" => "~> 1.7.7"
|
31
|
+
}
|
32
|
+
|
33
|
+
development_dependencies.each {|lib, version| s.add_development_dependency(lib, version) }
|
32
34
|
|
33
35
|
s.files = `git ls-files`.split("\n")
|
34
36
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
data/features/finder.feature
CHANGED
@@ -18,7 +18,7 @@ Feature: Ebay Finder
|
|
18
18
|
| findItemsByKeywords | harry potter phoenix |
|
19
19
|
When I tape the "finder" request as: "find_items_by_keywords"
|
20
20
|
Then the response code should be "200"
|
21
|
-
And the response should have
|
21
|
+
And the response should have 99 "item" nodes
|
22
22
|
|
23
23
|
Scenario: findItemsByCategory
|
24
24
|
Given the following parameters:
|
data/features/support/env.rb
CHANGED
@@ -5,12 +5,8 @@ require 'agent_cooper'
|
|
5
5
|
|
6
6
|
|
7
7
|
module AgentCooperMethods
|
8
|
-
def ebay
|
9
|
-
@ebay ||= YAML::load_file(File.dirname(__FILE__) + "/../../spec/fixtures/ebay.yml")
|
10
|
-
end
|
11
|
-
|
12
8
|
def ebay_app_id
|
13
|
-
|
9
|
+
ENV['EBAY_APP_ID'] || "APP_ID"
|
14
10
|
end
|
15
11
|
|
16
12
|
def cassette_name
|
data/features/support/vcr.rb
CHANGED
@@ -1,11 +1,7 @@
|
|
1
1
|
require 'vcr'
|
2
2
|
|
3
|
-
def ebay
|
4
|
-
@ebay ||= YAML::load_file(File.dirname(__FILE__) + "/../../spec/fixtures/ebay.yml")
|
5
|
-
end
|
6
|
-
|
7
3
|
def ebay_app_id
|
8
|
-
|
4
|
+
ENV['EBAY_APP_ID'] || "APP_ID"
|
9
5
|
end
|
10
6
|
|
11
7
|
|
@@ -15,5 +11,5 @@ VCR.config do |c|
|
|
15
11
|
:record => :none,
|
16
12
|
:match_requests_on => [:host] }
|
17
13
|
c.stub_with :webmock
|
18
|
-
c.filter_sensitive_data('
|
14
|
+
c.filter_sensitive_data('APP_ID') { ebay_app_id }
|
19
15
|
end
|
data/lib/agent_cooper.rb
CHANGED
@@ -1,22 +1,20 @@
|
|
1
|
-
|
1
|
+
require 'nokogiri'
|
2
|
+
require 'httpclient'
|
3
|
+
require 'virtus'
|
4
|
+
require 'cgi'
|
5
|
+
|
6
|
+
module AgentCooper
|
7
|
+
def self.configure(&block)
|
8
|
+
Config.configure(&block)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
2
12
|
require 'agent_cooper/config'
|
3
13
|
require 'agent_cooper/response'
|
4
|
-
require 'agent_cooper/
|
5
|
-
|
6
|
-
require 'agent_cooper/nokogiri_decorator'
|
14
|
+
require 'agent_cooper/builder'
|
7
15
|
|
8
|
-
|
16
|
+
require 'agent_cooper/request'
|
9
17
|
require 'agent_cooper/requests/finder'
|
10
18
|
require 'agent_cooper/requests/shopper'
|
11
19
|
require 'agent_cooper/requests/merchandiser'
|
12
|
-
|
13
|
-
#Version
|
14
20
|
require "agent_cooper/version"
|
15
|
-
|
16
|
-
module AgentCooper
|
17
|
-
class << self
|
18
|
-
def configure(&block)
|
19
|
-
Config.configure(&block)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
@@ -0,0 +1,46 @@
|
|
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
|
data/lib/agent_cooper/config.rb
CHANGED
data/lib/agent_cooper/request.rb
CHANGED
@@ -1,53 +1,77 @@
|
|
1
|
-
require 'forwardable'
|
2
|
-
require 'httpclient'
|
3
|
-
require 'cgi'
|
4
|
-
|
5
1
|
module AgentCooper
|
6
2
|
class Request
|
7
3
|
|
8
|
-
|
4
|
+
include Virtus
|
9
5
|
|
10
|
-
|
6
|
+
# config attributes
|
7
|
+
attribute :app_id, String,
|
8
|
+
:default => Proc.new { AgentCooper::Config.app_id },
|
9
|
+
:writer => :protected
|
11
10
|
|
12
|
-
|
11
|
+
# request attributes
|
12
|
+
attribute :request_adapter, Object,
|
13
|
+
:default => Proc.new { HTTPClient.new },
|
14
|
+
:accessor => :protected
|
13
15
|
|
14
|
-
|
15
|
-
|
16
|
-
|
16
|
+
attribute :query_parameters, Hash,
|
17
|
+
:default => Proc.new { {} },
|
18
|
+
:accessor => :protected
|
17
19
|
|
18
|
-
|
19
|
-
|
20
|
-
end
|
20
|
+
attribute :default_parameters, Hash,
|
21
|
+
:accessor => :protected
|
21
22
|
|
23
|
+
attribute :host, String,
|
24
|
+
:accessor => :protected
|
25
|
+
|
26
|
+
attribute :path, String,
|
27
|
+
:accessor => :protected
|
28
|
+
|
29
|
+
# @api public
|
22
30
|
def get
|
23
|
-
response
|
24
|
-
Response.new(response)
|
31
|
+
Response.new(:response => request_adapter.get(url))
|
25
32
|
end
|
26
33
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
)
|
33
|
-
end
|
34
|
+
# @api public
|
35
|
+
def <<(parameters)
|
36
|
+
unless parameters.is_a?(Hash)
|
37
|
+
raise ArgumentError, "+parameters+ must be an instance of Hash"
|
38
|
+
end
|
34
39
|
|
35
|
-
|
36
|
-
|
40
|
+
query_parameters.merge!(parameters)
|
41
|
+
end
|
37
42
|
|
38
|
-
|
43
|
+
# @api public
|
44
|
+
def reset!
|
45
|
+
self.query_parameters = {}
|
39
46
|
end
|
40
47
|
|
48
|
+
# @api public
|
41
49
|
def parameters
|
42
|
-
|
50
|
+
default_parameters.merge(query_parameters)
|
51
|
+
end
|
52
|
+
|
53
|
+
protected
|
54
|
+
|
55
|
+
# @api private
|
56
|
+
def query
|
57
|
+
parameters.collect { |k,v| "#{escape(k)}=#{escape(v)}" }.sort * '&'
|
43
58
|
end
|
44
59
|
|
45
|
-
|
46
|
-
|
60
|
+
# @api private
|
61
|
+
def escape(value)
|
62
|
+
CGI.escape("#{value}")
|
47
63
|
end
|
48
64
|
|
49
|
-
|
50
|
-
|
65
|
+
# @api private
|
66
|
+
def url
|
67
|
+
options = {
|
68
|
+
:host => host,
|
69
|
+
:path => path,
|
70
|
+
:query => query
|
71
|
+
}
|
72
|
+
|
73
|
+
URI::HTTP.build(options)
|
51
74
|
end
|
75
|
+
|
52
76
|
end
|
53
77
|
end
|
@@ -1,23 +1,20 @@
|
|
1
1
|
module AgentCooper
|
2
2
|
class Finder < Request
|
3
3
|
|
4
|
-
VERSION
|
4
|
+
VERSION = "1.11.0".freeze
|
5
|
+
HOST = "svcs.ebay.com".freeze
|
6
|
+
PATH = "/services/search/FindingService/v1".freeze
|
7
|
+
ENCODING = "XML".freeze
|
5
8
|
|
6
|
-
def
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
def path
|
12
|
-
'/services/search/FindingService/v1'
|
13
|
-
end
|
9
|
+
def initialize
|
10
|
+
self.host = HOST
|
11
|
+
self.path = PATH
|
14
12
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
'REST-PAYLOAD' => ''
|
13
|
+
self.default_parameters = {
|
14
|
+
"SECURITY-APPNAME" => app_id,
|
15
|
+
"SECURITY-VERSION" => VERSION,
|
16
|
+
"RESPONSE-DATA-FORMAT" => ENCODING,
|
17
|
+
"REST-PAYLOAD" => ""
|
21
18
|
}
|
22
19
|
end
|
23
20
|
|
@@ -1,25 +1,24 @@
|
|
1
1
|
module AgentCooper
|
2
2
|
class Merchandiser < Request
|
3
3
|
|
4
|
-
|
5
|
-
|
4
|
+
VERSION = "1.5.0".freeze
|
5
|
+
HOST = "svcs.ebay.com".freeze
|
6
|
+
SERVICE_NAME = "MerchandisingService".freeze
|
7
|
+
PATH = "/MerchandisingService".freeze
|
8
|
+
ENCODING = "XML".freeze
|
6
9
|
|
7
|
-
def
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
def path
|
12
|
-
'/MerchandisingService'
|
13
|
-
end
|
10
|
+
def initialize
|
11
|
+
self.host = HOST
|
12
|
+
self.path = PATH
|
14
13
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
'REST-PAYLOAD' => ''
|
14
|
+
self.default_parameters = {
|
15
|
+
"CONSUMER-ID" => app_id,
|
16
|
+
"SERVICE-NAME" => SERVICE_NAME,
|
17
|
+
"SERVICE-VERSION" => VERSION,
|
18
|
+
"RESPONSE-DATA-FORMAT" => ENCODING,
|
19
|
+
"REST-PAYLOAD" => ""
|
22
20
|
}
|
23
21
|
end
|
22
|
+
|
24
23
|
end
|
25
24
|
end
|
@@ -1,23 +1,23 @@
|
|
1
1
|
module AgentCooper
|
2
2
|
class Shopper < Request
|
3
3
|
|
4
|
-
VERSION
|
4
|
+
VERSION = "745".freeze
|
5
|
+
HOST = "open.api.ebay.com".freeze
|
6
|
+
PATH = "/shopping".freeze
|
7
|
+
SITE_ID = 0.freeze
|
8
|
+
ENCODING = "XML".freeze
|
5
9
|
|
6
|
-
def
|
7
|
-
|
8
|
-
|
10
|
+
def initialize
|
11
|
+
self.host = HOST
|
12
|
+
self.path = PATH
|
9
13
|
|
10
|
-
|
11
|
-
|
14
|
+
self.default_parameters = {
|
15
|
+
"APPID" => app_id,
|
16
|
+
"RESPONSEENCODING" => ENCODING,
|
17
|
+
"VERSION" => VERSION,
|
18
|
+
"SITEID" => SITE_ID
|
19
|
+
}
|
12
20
|
end
|
13
21
|
|
14
|
-
def default_parameters
|
15
|
-
{
|
16
|
-
'APPID' => app_id,
|
17
|
-
'RESPONSEENCODING' => ENCODING,
|
18
|
-
'VERSION' => VERSION,
|
19
|
-
'SITEID' => 0
|
20
|
-
}
|
21
|
-
end
|
22
22
|
end
|
23
23
|
end
|