amazonian 0.0.2 → 0.1.0
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/lib/amazonian/version.rb +1 -1
- data/lib/amazonian.rb +37 -13
- metadata +3 -3
data/lib/amazonian/version.rb
CHANGED
data/lib/amazonian.rb
CHANGED
@@ -48,20 +48,33 @@ module Amazonian
|
|
48
48
|
def self.asin(asin, params={})
|
49
49
|
params = params.merge :Operation => :ItemLookup, :ItemId => asin
|
50
50
|
xml = self.call params
|
51
|
-
Item.new xml
|
51
|
+
Item.new xml['ItemLookupResponse']['Items']['Item']
|
52
52
|
end
|
53
53
|
|
54
|
-
|
54
|
+
def self.search(query, params={})
|
55
|
+
params = params.merge :Operation => :ItemSearch,
|
56
|
+
:Keywords => query
|
57
|
+
|
58
|
+
params[:SearchIndex] = :Music if params[:SearchIndex].nil?
|
59
|
+
|
60
|
+
xml = self.call params
|
61
|
+
Search.new xml['ItemSearchResponse']
|
62
|
+
end
|
63
|
+
|
64
|
+
#private
|
55
65
|
|
56
66
|
def self.call(params)
|
57
67
|
raise "Cannot call the Amazon API without key and secret key." if @@key.blank? || @@secret.blank?
|
58
68
|
|
59
69
|
#get the signed query, and assemble the querystring
|
60
|
-
log :debug, "
|
70
|
+
log :debug, "Started Amazonian request for params: #{params.map {|p| "#{p[0]}=>#{p[1]}" }.join ','}" if @@debug
|
61
71
|
|
62
72
|
#memoize the last request for faster API querying...
|
63
73
|
query = assemble_querystring params
|
64
|
-
|
74
|
+
if query == @@query
|
75
|
+
log :debug, "MEMO'D! Shortcutting API call for dup request."
|
76
|
+
return Crack::XML.parse @@response.body
|
77
|
+
end
|
65
78
|
@@query = query
|
66
79
|
|
67
80
|
#sign the query
|
@@ -76,7 +89,9 @@ module Amazonian
|
|
76
89
|
|
77
90
|
log :debug, "Response Code: #{@@response.status}" if @@debug
|
78
91
|
|
79
|
-
|
92
|
+
#todo, this memo logic is broken....an error code is not always without a body
|
93
|
+
log :error, "Amazon API Error: #{@@response.status}" if @@response.status >= 400
|
94
|
+
|
80
95
|
#parse the response and return it
|
81
96
|
Crack::XML.parse @@response.body
|
82
97
|
end
|
@@ -88,25 +103,28 @@ module Amazonian
|
|
88
103
|
|
89
104
|
# CGI escape each param
|
90
105
|
# signing needs to order the query alphabetically
|
91
|
-
params.map{|key, value| "#{key}=#{CGI.escape(value.to_s)}" }.sort.join('&')
|
106
|
+
params.map{|key, value| "#{key}=#{CGI.escape(value.to_s)}" }.sort.join('&').gsub('+','%20')
|
92
107
|
end
|
93
108
|
|
94
109
|
def self.sign_query(query)
|
110
|
+
#make a copy... fixme fixme I'm awkward
|
95
111
|
q = query.clone
|
96
112
|
# UTC timestamp needed for signing
|
97
113
|
q <<= '&Timestamp=' << CGI.escape(Time.now.utc.strftime '%Y-%m-%dT%H:%M:%SZ')
|
98
114
|
|
99
115
|
# Sign the entire get-request (not just the querystring)
|
100
116
|
# possible gotcha if Patron starts using more/different headers.
|
101
|
-
request_to_sign =
|
117
|
+
request_to_sign = "GET\n#{@@host}\n#{@@path}\n#{q}"
|
118
|
+
|
119
|
+
"#{q}&Signature=#{sign_request request_to_sign}"
|
120
|
+
end
|
102
121
|
|
122
|
+
def self.sign_request(request_to_sign)
|
103
123
|
# Sign it.
|
104
124
|
hmac = OpenSSL::HMAC.digest(@@digest, @@secret, request_to_sign)
|
105
125
|
|
106
126
|
# Don't forget to remove the newline from base64
|
107
|
-
|
108
|
-
|
109
|
-
"#{q}&Signature=#{signature}"
|
127
|
+
CGI.escape(Base64.encode64(hmac).chomp)
|
110
128
|
end
|
111
129
|
|
112
130
|
def self.log(severity, message)
|
@@ -121,17 +139,23 @@ module Amazonian
|
|
121
139
|
# A Hashie::Mash is used for the internal data representation and can be accessed over the +raw+ attribute.
|
122
140
|
#
|
123
141
|
class Item
|
124
|
-
|
125
142
|
attr_reader :raw
|
126
|
-
|
127
143
|
def initialize(hash)
|
128
|
-
@raw = Hashie::Mash.new(hash)
|
144
|
+
@raw = Hashie::Mash.new(hash)
|
129
145
|
end
|
130
146
|
|
131
147
|
def title
|
132
148
|
@raw.ItemAttributes.Title
|
133
149
|
end
|
150
|
+
end
|
134
151
|
|
152
|
+
class Search
|
153
|
+
attr_reader :items
|
154
|
+
def initialize(hash)
|
155
|
+
@raw = Hashie::Mash.new(hash)
|
156
|
+
@items = []
|
157
|
+
@raw.Items.Item.each {|i| @items.push Amazonian::Item.new(i) }
|
158
|
+
end
|
135
159
|
end
|
136
160
|
|
137
161
|
end
|
metadata
CHANGED
@@ -5,9 +5,9 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
+
- 1
|
8
9
|
- 0
|
9
|
-
|
10
|
-
version: 0.0.2
|
10
|
+
version: 0.1.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Robert L. Carpenter
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-11-
|
18
|
+
date: 2010-11-29 00:00:00 -07:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|