agent_cooper 0.0.5 → 0.0.6
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/.gitignore +1 -1
- data/README.md +13 -4
- data/Rakefile +0 -3
- data/agent_cooper.gemspec +12 -13
- data/features/finder.feature +4 -6
- data/features/merchandiser.feature +1 -2
- data/features/shopper.feature +2 -2
- data/features/support/env.rb +5 -5
- data/features/support/vcr.rb +10 -0
- data/lib/agent_cooper.rb +17 -4
- data/lib/agent_cooper/config.rb +3 -9
- data/lib/agent_cooper/nokogiri_decorator.rb +47 -0
- data/lib/agent_cooper/request.rb +36 -13
- data/lib/agent_cooper/requests/finder.rb +25 -0
- data/lib/agent_cooper/requests/merchandiser.rb +25 -0
- data/lib/agent_cooper/requests/shopper.rb +23 -0
- data/lib/agent_cooper/response.rb +3 -4
- data/lib/agent_cooper/synchrony.rb +34 -0
- data/lib/agent_cooper/version.rb +1 -1
- data/spec/agent_cooper/request_spec.rb +91 -6
- data/spec/agent_cooper/requests/finder_spec.rb +13 -0
- data/spec/agent_cooper/requests/merchandiser_spec.rb +13 -0
- data/spec/agent_cooper/requests/shopper_spec.rb +13 -0
- data/spec/agent_cooper/response_spec.rb +51 -1
- data/spec/agent_cooper_spec.rb +12 -0
- data/spec/fixtures/cassettes/finder/find_items_advanced/d49218a9522a4a055e31fc6b88c3a2b5.yml +528 -0
- data/spec/fixtures/cassettes/finder/find_items_by_category/85e07de9993e68d09e895f1b01234c5a.yml +463 -0
- data/spec/fixtures/cassettes/finder/find_items_by_keywords/91d7d9b4b62b82877604465a20f9ffa9.yml +668 -0
- data/spec/fixtures/cassettes/finder/find_items_by_product/59ee1391b6dfc2a93e30c8911942fc71.yml +744 -0
- data/spec/fixtures/cassettes/finder/find_items_in_ebay_stores/c7d658804b6353fda03809c21b183af2.yml +472 -0
- data/spec/fixtures/cassettes/finder/get_histograms/80bd04d96cd529af4148866a2d28f079.yml +46 -0
- data/spec/fixtures/cassettes/finder/get_search_keywords_recommendation/ec96bf3af091373de08550ff46f86c87.yml +41 -0
- data/spec/fixtures/cassettes/merchandiser/get_most_watched_items/3c0cb6fb7bb94b384cae15be175e9640.yml +51 -0
- data/spec/fixtures/cassettes/merchandiser/get_related_category_items/c949e90fb2bd975020df657a4348328d.yml +41 -0
- data/spec/fixtures/cassettes/merchandiser/get_similar_items/56c2c41a60135db83d359053778a065f.yml +41 -0
- data/spec/fixtures/cassettes/merchandiser/get_top_selling_products/a82dcb1f094754e54f2a5de191818c3f.yml +53 -0
- data/spec/fixtures/cassettes/shopper/find_half_products/77ad8a2ade8e4efadef07346677e43a9.yml +55 -0
- data/spec/fixtures/cassettes/shopper/find_popular_items/532fcb32fee187bdc6cc5fb7e4336992.yml +258 -0
- data/spec/fixtures/cassettes/shopper/find_popular_searches/6db9b375ea610e870e7a4ca4e20974ec.yml +45 -0
- data/spec/fixtures/cassettes/shopper/find_products/3fd6d6000037cd409ab1ef18a6075257.yml +52 -0
- data/spec/fixtures/cassettes/shopper/find_reviews_and_guides/8586a984e122cb84136d3cc0bb8bec77.yml +174 -0
- data/spec/fixtures/cassettes/shopper/get_item_status/f34cf10c602f9fec7a388297888b4299.yml +45 -0
- data/spec/fixtures/cassettes/shopper/get_multiple_items/c1183c23add6cad9afbb73f986c2692e.yml +46 -0
- data/spec/fixtures/cassettes/shopper/get_shipping_costs/e7de18031f266637414155639797c097.yml +45 -0
- data/spec/fixtures/cassettes/shopper/get_single_item/d4a895de6b214907c47a0b32ab630b9a.yml +44 -0
- data/spec/fixtures/cassettes/shopper/get_user_profile/dccabbf426bfeba4d898ca546e17dd4b.yml +47 -0
- data/spec/{support → fixtures}/ebay.yml.sample +0 -0
- data/spec/spec_helper.rb +4 -0
- metadata +141 -177
- data/lib/agent_cooper/finder.rb +0 -21
- data/lib/agent_cooper/merchandiser.rb +0 -24
- data/lib/agent_cooper/shopper.rb +0 -22
- data/spec/agent_cooper/config_spec.rb +0 -21
- data/spec/agent_cooper/finder_spec.rb +0 -19
- data/spec/agent_cooper/merchandiser_spec.rb +0 -18
- data/spec/agent_cooper/shopper_spec.rb +0 -18
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -12,42 +12,51 @@ Usage
|
|
12
12
|
-----
|
13
13
|
Set up.
|
14
14
|
|
15
|
-
|
15
|
+
```ruby
|
16
|
+
AgentCooper.configure do |config|
|
16
17
|
config.app_id = "SOME_OBSCURE_APP_ID"
|
17
18
|
end
|
19
|
+
```
|
18
20
|
|
19
21
|
Initialize a request
|
20
22
|
|
23
|
+
```ruby
|
21
24
|
request = AgentCooper::Finder.new
|
22
25
|
request = AgentCooper::Shopper.new
|
23
26
|
request = AgentCooper::Merchandiser.new
|
24
|
-
|
27
|
+
```
|
25
28
|
Build request params.
|
26
29
|
|
30
|
+
```ruby
|
27
31
|
request << {
|
28
32
|
'OPERATION-NAME' => 'getSearchKeywordsRecommendation',
|
29
33
|
'KEYWORDS' => 'arry potter'
|
30
34
|
}
|
35
|
+
```
|
31
36
|
|
32
37
|
Get a response.
|
33
38
|
|
39
|
+
```ruby
|
34
40
|
response = request.get
|
41
|
+
```
|
35
42
|
|
36
43
|
Return a hash:
|
37
44
|
|
45
|
+
```ruby
|
38
46
|
response.to_hash
|
39
47
|
|
40
48
|
returns: {'getSearchKeywordsRecommendationResponse' => {'xmnls' => 'http://www.ebay.com/marketplace/search/v1/services', 'ack' => 'Success', 'version' => '1.9.0', 'keywords' => 'harry potter'}}
|
41
|
-
|
49
|
+
```
|
42
50
|
|
43
51
|
Or parse a response with Nokogiri:
|
44
52
|
|
53
|
+
```ruby
|
45
54
|
response.xml.css("Item > Title").each do |title|
|
46
55
|
some business value
|
47
56
|
end
|
48
57
|
|
49
58
|
response.xml.xpath("//Item")
|
50
|
-
|
59
|
+
```
|
51
60
|
----
|
52
61
|
|
53
62
|
Based on papercavalier's [sucker](http://github.com/papercavalier/sucker).
|
data/Rakefile
CHANGED
data/agent_cooper.gemspec
CHANGED
@@ -15,22 +15,21 @@ Gem::Specification.new do |s|
|
|
15
15
|
s.rubyforge_project = "agent_cooper"
|
16
16
|
|
17
17
|
{
|
18
|
-
'
|
19
|
-
'nokogiri' => '~> 1.4
|
18
|
+
'httpclient' => '~> 2.2',
|
19
|
+
'nokogiri' => '~> 1.4'
|
20
20
|
}.each {|lib, version| s.add_runtime_dependency lib, version }
|
21
|
-
|
22
|
-
|
21
|
+
|
22
|
+
|
23
23
|
{
|
24
|
-
'
|
25
|
-
'
|
26
|
-
'
|
27
|
-
'rake' => '~> 0.
|
28
|
-
'
|
29
|
-
'
|
30
|
-
'
|
31
|
-
'webmock' => '~> 1.6.0'
|
24
|
+
'cucumber' => '~> 1.0',
|
25
|
+
'em-http-request' => '~> 1.0.0.beta.4',
|
26
|
+
'em-synchrony' => '~> 0.3.0.beta.1',
|
27
|
+
'rake' => '~> 0.9',
|
28
|
+
'rspec' => '~> 2.6',
|
29
|
+
'vcr' => '~> 1.10',
|
30
|
+
'webmock' => '~> 1.6'
|
32
31
|
}.each {|lib, version| s.add_development_dependency lib, version }
|
33
|
-
|
32
|
+
|
34
33
|
s.files = `git ls-files`.split("\n")
|
35
34
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
36
35
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
data/features/finder.feature
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
Feature: Ebay Finder
|
2
2
|
As an API consumer
|
3
3
|
|
4
|
-
Background:
|
4
|
+
Background:
|
5
5
|
Given a new finder request
|
6
|
-
|
6
|
+
|
7
7
|
Scenario: getSearchKeywordsRecommendation
|
8
8
|
Given the following parameters:
|
9
9
|
| OPERATION-NAME | keywords |
|
@@ -11,7 +11,7 @@ Feature: Ebay Finder
|
|
11
11
|
When I tape the "finder" request as: "get_search_keywords_recommendation"
|
12
12
|
Then the response code should be "200"
|
13
13
|
And the response should have 1 "keywords" nodes
|
14
|
-
|
14
|
+
|
15
15
|
Scenario: findItemsByKeywords
|
16
16
|
Given the following parameters:
|
17
17
|
| OPERATION-NAME | keywords |
|
@@ -27,7 +27,7 @@ Feature: Ebay Finder
|
|
27
27
|
When I tape the "finder" request as: "find_items_by_category"
|
28
28
|
Then the response code should be "200"
|
29
29
|
And the response should have 100 "item" nodes
|
30
|
-
|
30
|
+
|
31
31
|
Scenario: findItemsAdvanced
|
32
32
|
Given the following parameters:
|
33
33
|
| OPERATION-NAME | keywords |
|
@@ -60,5 +60,3 @@ Feature: Ebay Finder
|
|
60
60
|
When I tape the "finder" request as: "get_histograms"
|
61
61
|
Then the response code should be "200"
|
62
62
|
And the response should have 6 "childCategoryHistogram" nodes
|
63
|
-
|
64
|
-
|
@@ -1,7 +1,7 @@
|
|
1
1
|
Feature: Ebay Merchandiser
|
2
2
|
As an API consumer
|
3
3
|
|
4
|
-
Background:
|
4
|
+
Background:
|
5
5
|
Given a new merchandiser request
|
6
6
|
|
7
7
|
Scenario: getMostWatchedItems
|
@@ -31,4 +31,3 @@ Feature: Ebay Merchandiser
|
|
31
31
|
| getTopSellingProducts | 3 |
|
32
32
|
When I tape the "merchandiser" request as: "get_top_selling_products"
|
33
33
|
Then the response code should be "200"
|
34
|
-
|
data/features/shopper.feature
CHANGED
data/features/support/env.rb
CHANGED
@@ -4,9 +4,9 @@ require 'digest/md5'
|
|
4
4
|
require 'agent_cooper'
|
5
5
|
|
6
6
|
|
7
|
-
module AgentCooperMethods
|
7
|
+
module AgentCooperMethods
|
8
8
|
def ebay
|
9
|
-
@ebay ||= YAML::load_file(File.dirname(__FILE__) + "/../../spec/
|
9
|
+
@ebay ||= YAML::load_file(File.dirname(__FILE__) + "/../../spec/fixtures/ebay.yml")
|
10
10
|
end
|
11
11
|
|
12
12
|
def ebay_app_id
|
@@ -14,14 +14,14 @@ module AgentCooperMethods
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def cassette_name
|
17
|
-
Digest::MD5.hexdigest(@request.
|
17
|
+
Digest::MD5.hexdigest(@request.parameters.to_json)
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
21
|
World(AgentCooperMethods)
|
22
22
|
|
23
23
|
Before do
|
24
|
-
AgentCooper
|
25
|
-
config.app_id =
|
24
|
+
AgentCooper.configure do |config|
|
25
|
+
config.app_id = ebay_app_id
|
26
26
|
end
|
27
27
|
end
|
data/features/support/vcr.rb
CHANGED
@@ -1,9 +1,19 @@
|
|
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
|
+
def ebay_app_id
|
8
|
+
ebay['app_id']
|
9
|
+
end
|
10
|
+
|
11
|
+
|
3
12
|
VCR.config do |c|
|
4
13
|
c.cassette_library_dir = File.dirname(__FILE__) + '/../../spec/fixtures/cassettes'
|
5
14
|
c.default_cassette_options = {
|
6
15
|
:record => :none,
|
7
16
|
:match_requests_on => [:host] }
|
8
17
|
c.stub_with :webmock
|
18
|
+
c.filter_sensitive_data('YOUR-APP-ID') { ebay_app_id }
|
9
19
|
end
|
data/lib/agent_cooper.rb
CHANGED
@@ -1,9 +1,22 @@
|
|
1
|
+
# Utilities
|
1
2
|
require 'agent_cooper/config'
|
2
|
-
require 'agent_cooper/request'
|
3
3
|
require 'agent_cooper/response'
|
4
|
-
require 'agent_cooper/
|
5
|
-
|
6
|
-
require 'agent_cooper/
|
4
|
+
require 'agent_cooper/request'
|
5
|
+
|
6
|
+
require 'agent_cooper/nokogiri_decorator'
|
7
|
+
|
8
|
+
# Requests
|
9
|
+
require 'agent_cooper/requests/finder'
|
10
|
+
require 'agent_cooper/requests/shopper'
|
11
|
+
require 'agent_cooper/requests/merchandiser'
|
12
|
+
|
13
|
+
#Version
|
14
|
+
require "agent_cooper/version"
|
7
15
|
|
8
16
|
module AgentCooper
|
17
|
+
class << self
|
18
|
+
def configure(&block)
|
19
|
+
Config.configure(&block)
|
20
|
+
end
|
21
|
+
end
|
9
22
|
end
|
data/lib/agent_cooper/config.rb
CHANGED
@@ -1,16 +1,10 @@
|
|
1
1
|
module AgentCooper
|
2
2
|
class Config
|
3
3
|
class << self
|
4
|
-
|
5
|
-
yield self
|
6
|
-
end
|
4
|
+
attr_accessor :app_id
|
7
5
|
|
8
|
-
def
|
9
|
-
|
10
|
-
end
|
11
|
-
|
12
|
-
def app_id
|
13
|
-
@@app_id ||= nil
|
6
|
+
def configure(&block)
|
7
|
+
yield self
|
14
8
|
end
|
15
9
|
end
|
16
10
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module AgentCooper
|
2
|
+
|
3
|
+
# Based on https://gist.github.com/335286
|
4
|
+
|
5
|
+
class Nokogiri::XML::Document
|
6
|
+
def to_hash
|
7
|
+
root.to_hash
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class Nokogiri::XML::Element
|
12
|
+
def to_hash
|
13
|
+
({}).tap do |hash|
|
14
|
+
|
15
|
+
attributes.each_pair do |key, attribute|
|
16
|
+
hash[key] = attribute.value
|
17
|
+
end
|
18
|
+
|
19
|
+
children.each do |child|
|
20
|
+
result = child.to_hash
|
21
|
+
|
22
|
+
if child.name == 'text'
|
23
|
+
if hash.empty?
|
24
|
+
return result
|
25
|
+
else
|
26
|
+
hash['__content__'] = result
|
27
|
+
end
|
28
|
+
elsif hash[child.name]
|
29
|
+
if hash[child.name].is_a?(Array)
|
30
|
+
hash[child.name] << result
|
31
|
+
else
|
32
|
+
hash[child.name] = [hash[child.name]] << result
|
33
|
+
end
|
34
|
+
else
|
35
|
+
hash[child.name] = result
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class Nokogiri::XML::Text
|
43
|
+
def to_hash
|
44
|
+
content.to_s
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/lib/agent_cooper/request.rb
CHANGED
@@ -1,30 +1,53 @@
|
|
1
|
-
require '
|
1
|
+
require 'forwardable'
|
2
|
+
require 'httpclient'
|
3
|
+
require 'cgi'
|
2
4
|
|
3
5
|
module AgentCooper
|
4
6
|
class Request
|
5
7
|
|
8
|
+
extend Forwardable
|
9
|
+
|
10
|
+
def_delegators :@config, :app_id
|
11
|
+
|
6
12
|
ENCODING = 'XML'
|
7
13
|
|
8
|
-
|
9
|
-
|
14
|
+
def initialize
|
15
|
+
@config = Config
|
16
|
+
end
|
10
17
|
|
11
|
-
|
18
|
+
def adapter
|
19
|
+
@adapter ||= HTTPClient.new
|
20
|
+
end
|
12
21
|
|
13
|
-
def
|
14
|
-
|
22
|
+
def get
|
23
|
+
response = adapter.get(url)
|
24
|
+
Response.new(response)
|
15
25
|
end
|
16
26
|
|
17
|
-
def
|
18
|
-
|
27
|
+
def url
|
28
|
+
URI::HTTP.build(
|
29
|
+
:host => host,
|
30
|
+
:path => path,
|
31
|
+
:query => query
|
32
|
+
)
|
19
33
|
end
|
20
34
|
|
21
|
-
def
|
22
|
-
|
35
|
+
def query
|
36
|
+
query = default_parameters.merge(parameters)
|
37
|
+
|
38
|
+
query.collect {|k,v| "#{CGI.escape(k.to_s)}=#{CGI.escape(v.to_s)}"} * '&'
|
23
39
|
end
|
24
40
|
|
25
|
-
def
|
26
|
-
|
27
|
-
|
41
|
+
def parameters
|
42
|
+
@parameters ||= {}
|
43
|
+
end
|
44
|
+
|
45
|
+
def <<(hash)
|
46
|
+
parameters.merge!(hash)
|
47
|
+
end
|
48
|
+
|
49
|
+
def reset!
|
50
|
+
@parameters = {}
|
28
51
|
end
|
29
52
|
end
|
30
53
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module AgentCooper
|
2
|
+
class Finder < Request
|
3
|
+
|
4
|
+
VERSION = '1.9.0'
|
5
|
+
|
6
|
+
def host
|
7
|
+
'svcs.ebay.com'
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
def path
|
12
|
+
'/services/search/FindingService/v1'
|
13
|
+
end
|
14
|
+
|
15
|
+
def default_parameters
|
16
|
+
{
|
17
|
+
'SECURITY-APPNAME' => app_id,
|
18
|
+
'SECURITY-VERSION' => VERSION,
|
19
|
+
'RESPONSE-DATA-FORMAT' => ENCODING,
|
20
|
+
'REST-PAYLOAD' => ''
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module AgentCooper
|
2
|
+
class Merchandiser < Request
|
3
|
+
|
4
|
+
SERVICE_NAME = 'MerchandisingService'
|
5
|
+
VERSION = '1.4.0'
|
6
|
+
|
7
|
+
def host
|
8
|
+
'svcs.ebay.com'
|
9
|
+
end
|
10
|
+
|
11
|
+
def path
|
12
|
+
'/MerchandisingService'
|
13
|
+
end
|
14
|
+
|
15
|
+
def default_parameters
|
16
|
+
{
|
17
|
+
'CONSUMER-ID' => app_id,
|
18
|
+
'SERVICE-NAME' => SERVICE_NAME,
|
19
|
+
'SERVICE-VERSION' => VERSION,
|
20
|
+
'RESPONSE-DATA-FORMAT' => ENCODING,
|
21
|
+
'REST-PAYLOAD' => ''
|
22
|
+
}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module AgentCooper
|
2
|
+
class Shopper < Request
|
3
|
+
|
4
|
+
VERSION = '717'
|
5
|
+
|
6
|
+
def host
|
7
|
+
'open.api.ebay.com'
|
8
|
+
end
|
9
|
+
|
10
|
+
def path
|
11
|
+
'/shopping'
|
12
|
+
end
|
13
|
+
|
14
|
+
def default_parameters
|
15
|
+
{
|
16
|
+
'APPID' => app_id,
|
17
|
+
'RESPONSEENCODING' => ENCODING,
|
18
|
+
'VERSION' => VERSION,
|
19
|
+
'SITEID' => 0
|
20
|
+
}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|