agent_cooper 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|