sucker 1.3.0.pre.3 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -3,17 +3,9 @@ Sucker
3
3
 
4
4
  Sucker is a Nokogiri-based Ruby wrapper to the [Amazon Product Advertising API](https://affiliate-program.amazon.co.uk/gp/advertising/api/detail/main.html).
5
5
 
6
- It's minimalist and fast. It supports __the entire API__.
6
+ Sucker is fast and supports __the entire Amazon API__.
7
7
 
8
- ![Electrolux](https://github.com/papercavalier/sucker/raw/master/electrolux.jpg)
9
-
10
- Trim fat
11
- --------
12
- 1.3.0.pre has major changes under the hood.
13
-
14
- Active Support and Curb are no more.
15
-
16
- I edited out some nonessential methods. Check [here](http://rdoc.info/github/papercavalier/sucker/master/frames) to see what's left.
8
+ ![Hoover](https://github.com/papercavalier/sucker/raw/master/hoover.jpg)
17
9
 
18
10
  Usage
19
11
  -----
@@ -28,32 +20,29 @@ Set up.
28
20
  Build a request.
29
21
 
30
22
  worker << {
31
- "Operation" => 'ItemLookup',
32
- "IdType" => 'ASIN',
33
- "ItemId" => '0816614024',
34
- "ResponseGroup" => 'ItemAttributes' }
23
+ 'Operation' => 'ItemLookup',
24
+ 'IdType' => 'ASIN',
25
+ 'ItemId' => '0816614024',
26
+ 'ResponseGroup' => 'ItemAttributes' }
35
27
 
36
- Literally, get a response.
28
+ Get a response.
37
29
 
38
30
  response = worker.get
39
31
 
40
- Time for some business logic.
32
+ Do something with it.
41
33
 
42
- items = response['Item'] if response.valid?
34
+ items = response['Item'] if response.valid? # and so on
43
35
 
44
36
  Repeat ad infinitum.
45
37
 
46
- [Check the features](http://relishapp.com/papercavalier/sucker).
47
-
48
- [Read the API.](https://affiliate-program.amazon.co.uk/gp/advertising/api/detail/main.html)
38
+ Read further [here](http://rdoc.info/github/papercavalier/sucker/master/frames) and [here](http://relishapp.com/papercavalier/sucker).
49
39
 
50
-
51
- Monkey-patch that Net::HTTP
52
- ---------------------------
40
+ Multiple IPs
41
+ ------------
53
42
 
54
43
  Amazon limits calls to a venue to one per second per IP address.
55
44
 
56
- If your server has multiple local interfaces, do the following:
45
+ If your server has multiple local interfaces, use them simultaneously like so:
57
46
 
58
47
  your_ips.each do |ip|
59
48
  Thread.new do
@@ -62,36 +51,17 @@ If your server has multiple local interfaces, do the following:
62
51
  end
63
52
  end
64
53
 
65
- Throttle calls
66
- ----------------
67
-
68
- Use [Throttler](https://github.com/papercavalier/throttler) to throttle calls to one per second per IP address. Let me know if you figure out a more elegant solution.
69
-
70
- More concise syntax
71
- -------------------
72
-
73
- If you are on Ruby 1.9, do:
74
-
75
- worker << {
76
- operation: 'ItemLookup',
77
- id_type: 'ASIN',
78
- item_id: '0816614024' }
79
-
80
- Stub
81
- ----
54
+ Stubbing in Tests
55
+ -----------------
82
56
 
83
57
  Use [VCR](http://github.com/myronmarston/vcr).
84
58
 
85
- Check out [this](http://github.com/papercavalier/sucker/blob/master/spec/support/vcr.rb) and [this](https://github.com/papercavalier/sucker/blob/master/features/step_definitions/sucker_steps.rb).
86
-
87
59
  Compatibility
88
60
  -------------
89
61
 
90
62
  Specs pass against Ruby 1.8.7, Ruby 1.9.2, JRuby 1.5.6, and Rubinius 1.2.1.
91
63
 
92
- Morale(s) of the story
93
- -------------------
64
+ Moral of the story
65
+ ------------------
94
66
 
95
67
  Don't overabstract a spaghetti API.
96
-
97
- Fancy a DSL? Write your own on top of this.
@@ -0,0 +1,44 @@
1
+ module Sucker
2
+ class Hash < ::Hash
3
+ class << self
4
+
5
+ # Based on https://gist.github.com/335286
6
+ def from_xml(xml)
7
+ case xml
8
+ when Nokogiri::XML::Document
9
+ new[xml.root.name] = from_xml(xml.root)
10
+ when Nokogiri::XML::Element
11
+ result_hash = new
12
+
13
+ xml.attributes.each_pair do |key, attribute|
14
+ result_hash[key] = attribute.value
15
+ end
16
+
17
+ xml.children.each do |child|
18
+ result = from_xml(child)
19
+
20
+ if child.name == 'text'
21
+ if result_hash.empty?
22
+ return result
23
+ else
24
+ result_hash['__content__'] = result
25
+ end
26
+ elsif result_hash[child.name]
27
+ if result_hash[child.name].is_a? Array
28
+ result_hash[child.name] << result
29
+ else
30
+ result_hash[child.name] = [result_hash[child.name]] << result
31
+ end
32
+ else
33
+ result_hash[child.name] = result
34
+ end
35
+ end
36
+
37
+ result_hash
38
+ else
39
+ xml.content.to_s
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end