sailthru-client 1.01 → 1.02

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.
Files changed (3) hide show
  1. data/README.md +2 -2
  2. data/lib/sailthru.rb +401 -346
  3. metadata +18 -4
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
1
  # A simple client library to remotely access the Sailthru REST API.
2
2
 
3
- ## Installing (Tested with Ruby 1.8.7)
4
- $ gem install sailthru
3
+ ## Installing from rubygems.org (Tested with Ruby 1.8.7)
4
+ $ gem install sailthru-client
data/lib/sailthru.rb CHANGED
@@ -1,38 +1,3 @@
1
- ################################################################################
2
- #
3
- # A simple client library to remotely access the Sailthru REST API.
4
- #
5
- ################################################################################
6
- #
7
- # Copyright (c) 2007 Sailthru, Inc.
8
- # All rights reserved.
9
- #
10
- # Special thanks to the iminlikewithyou.com team for the development
11
- # of this library.
12
- #
13
- # Redistribution and use in source and binary forms, with or without
14
- # modification, are permitted provided that the following conditions
15
- # are met:
16
- #
17
- # 1. Redistributions of source code must retain the above copyright
18
- # notice, this list of conditions and the following disclaimer.
19
- # 2. Redistributions in binary form must reproduce the above copyright
20
- # notice, this list of conditions and the following disclaimer in the
21
- # documentation and/or other materials provided with the distribution.
22
- #
23
- # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24
- # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25
- # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26
- # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27
- # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28
- # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29
- # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30
- # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31
- # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32
- # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
- #
34
- ################################################################################
35
-
36
1
  require 'net/http'
37
2
  require 'uri'
38
3
  require 'cgi'
@@ -40,335 +5,425 @@ require 'rubygems'
40
5
  require 'json'
41
6
  require 'md5'
42
7
 
43
- class SailthruClientException < Exception
44
- end
45
-
46
- class SailthruClient
47
- attr_accessor :api_uri, :api_key, :secret, :version, :last_request
48
-
49
- VERSION = '1.01'
50
-
51
- # params:
52
- # api_key, String
53
- # secret, String
54
- # api_uri, String
55
- #
56
- # Instantiate a new client; constructor optionally takes overrides for key/secret/uri.
57
- def initialize(api_key, secret, api_uri)
58
- @api_key = api_key
59
- @secret = secret
60
- @api_uri = api_uri
8
+ module Sailthru
9
+
10
+ Version = VERSION = '1.02'
11
+
12
+ class SailthruClientException < Exception
61
13
  end
62
-
63
- # params:
64
- # template_name, String
65
- # email, String
66
- # replacements, Hash
67
- # options, Hash
68
- # replyto: override Reply-To header
69
- # test: send as test email (subject line will be marked, will not count towards stats)
70
- # returns:
71
- # Hash, response data from server
72
- def send(template_name, email, vars, options = {}, schedule_time = nil)
73
- post = {}
74
- post[:template] = template_name
75
- post[:email] = email
76
- post[:vars] = vars
77
- post[:options] = options
78
- if schedule_time != nil
79
- post[:schedule_time] = schedule_time
14
+
15
+ module Helpers
16
+ # params:
17
+ # params, Hash
18
+ # returns:
19
+ # Array, values of each item in the Hash (and nested hashes)
20
+ #
21
+ # Extracts the values of a set of parameters, recursing into nested assoc arrays.
22
+ def extract_param_values(params)
23
+ values = []
24
+ params.each do |k, v|
25
+ if v.class == Hash
26
+ values.concat extract_param_values(v)
27
+ elsif v.class == Array
28
+ temp_hash = Hash.new()
29
+ v.each_with_index do |v_,i_|
30
+ temp_hash[i_.to_s] = v_
31
+ end
32
+ values.concat extract_param_values(temp_hash)
33
+ else
34
+ values.push v.to_s
35
+ end
36
+ end
37
+ return values
80
38
  end
81
- return self.api_post(:send, post)
82
- end
83
39
 
84
-
85
- # params:
86
- # send_id, Fixnum
87
- # returns:
88
- # Hash, response data from server
89
- #
90
- # Get the status of a send.
91
- def get_send(send_id)
92
- self.api_get(:send, {:send_id => send_id.to_s})
93
- end
94
-
95
- # params:
96
- # name, String
97
- # list, String
98
- # schedule_time, String
99
- # from_name, String
100
- # from_email, String
101
- # subject, String
102
- # content_html, String
103
- # content_text, String
104
- # options, Hash
105
- # returns:
106
- # Hash, response data from server
107
- #
108
- # Schedule a mass mail blast
109
- def schedule_blast(name, list, schedule_time, from_name, from_email, subject, content_html, content_text, options)
110
- post = options ? options : {}
111
- post[:name] = name
112
- post[:list] = list
113
- post[:schedule_time] = schedule_time
114
- post[:from_name] = from_name
115
- post[:from_email] = from_email
116
- post[:subject] = subject
117
- post[:content_html] = content_html
118
- post[:content_text] = content_text
119
- self.api_post(:blast, post)
120
- end
121
-
122
-
123
- # params:
124
- # blast_id, Fixnum
125
- # returns:
126
- # Hash, response data from server
127
- #
128
- # Get information on a previously scheduled email blast
129
- def get_blast(blast_id)
130
- self.api_get(:blast, {:blast_id => blast_id.to_s})
131
- end
132
-
133
- # params:
134
- # email, String
135
- # returns:
136
- # Hash, response data from server
137
- #
138
- # Return information about an email address, including replacement vars and lists.
139
- def get_email(email)
140
- self.api_get(:email, {:email => email})
141
- end
142
-
143
- # params:
144
- # email, String
145
- # vars, Hash
146
- # lists, Hash mapping list name => 1 for subscribed, 0 for unsubscribed
147
- # returns:
148
- # Hash, response data from server
149
- #
150
- # Set replacement vars and/or list subscriptions for an email address.
151
- def set_email(email, vars = {}, lists = {}, templates = {})
152
- data = {:email => email}
153
- data[:vars] = vars unless vars.empty?
154
- data[:lists] = lists unless lists.empty?
155
- data[:templates] = templates unless templates.empty?
156
- self.api_post(:email, data)
157
- end
158
-
159
- # params:
160
- # email, String
161
- # password, String
162
- # with_names, Boolean
163
- # returns:
164
- # Hash, response data from server
165
- #
166
- # Fetch email contacts from an address book at one of the major email providers (aol/gmail/hotmail/yahoo)
167
- # Use the with_names parameter if you want to fetch the contact names as well as emails
168
- def import_contacts(email, password, with_names = false)
169
- data = { :email => email, :password => password }
170
- data[:names] = 1 if with_names
171
- self.api_post(:contacts, data)
172
- end
173
-
174
-
175
- # params:
176
- # template_name, String
177
- # returns:
178
- # Hash of response data.
179
- #
180
- # Get a template.
181
- def get_template(template_name)
182
- self.api_get(:template, {:template => template_name})
183
- end
184
-
185
-
186
- # params:
187
- # template_name, String
188
- # template_fields, Hash
189
- # returns:
190
- # Hash containg response from the server.
191
- #
192
- # Save a template.
193
- def save_template(template_name, template_fields)
194
- data = template_fields
195
- data[:template] = template_name
196
- self.api_post(:template, data)
197
- end
198
-
199
-
200
- # params:
201
- # params, Hash
202
- # request, String
203
- # returns:
204
- # TrueClass or FalseClass, Returns true if the incoming request is an authenticated verify post.
205
- def receive_verify_post(params, request)
206
- if request.post?
207
- [:action, :email, :send_id, :sig].each { |key| return false unless params.has_key?(key) }
208
-
209
- return false unless params[:action] == :verify
210
-
211
- sig = params[:sig]
212
- params.delete(:sig)
213
- return false unless sig == SailthruClient.get_signature_hash(params, @secret)
214
-
215
- _send = self.get_send(params[:send_id])
216
- return false unless _send.has_key?(:email)
217
-
218
- return false unless _send[:email] == params[:email]
219
-
220
- return true
221
- else
40
+ # params:
41
+ # params, Hash
42
+ # secret, String
43
+ # returns:
44
+ # String
45
+ #
46
+ # Returns the unhashed signature string (secret + sorted list of param values) for an API call.
47
+ def get_signature_string(params, secret)
48
+ return secret + extract_param_values(params).sort.join("")
49
+ end
50
+
51
+
52
+ # params:
53
+ # params, Hash
54
+ # secret, String
55
+ # returns:
56
+ # String
57
+ #
58
+ # Returns an MD5 hash of the signature string for an API call.
59
+ def get_signature_hash(params, secret)
60
+ MD5.md5(get_signature_string(params, secret)).to_s # debuggin
61
+ end
62
+
63
+
64
+ # Flatten nested hash for GET / POST request.
65
+ def flatten_nested_hash(hash, brackets = true)
66
+ f = {}
67
+ hash.each do |key, value|
68
+ _key = brackets ? "[#{key}]" : key.to_s
69
+ if value.class == Hash
70
+ flatten_nested_hash(value).each do |k, v|
71
+ f["#{_key}#{k}"] = v
72
+ end
73
+ elsif value.class == Array
74
+ temp_hash = Hash.new()
75
+ value.each_with_index do |v, i|
76
+ temp_hash[i.to_s] = v
77
+ end
78
+ flatten_nested_hash(temp_hash).each do |k, v|
79
+ f["#{_key}#{k}"] = v
80
+ end
81
+
82
+ else
83
+ f[_key] = value
84
+ end
85
+ end
86
+ return f
87
+ end
88
+
89
+ def verify_purchase_items (items)
90
+ if items.class == Array and !items.empty?
91
+ required_item_fields = ['qty', 'title', 'price', 'id', 'url'].sort
92
+ items.each do |v|
93
+ keys = v.keys.sort
94
+ return false if keys != required_item_fields
95
+ end
96
+ return true
97
+ end
222
98
  return false
223
99
  end
224
100
  end
225
-
226
-
227
- # Perform API GET request
228
- def api_get(action, data)
229
- api_request(action, data, 'GET')
230
- end
231
-
232
- # Perform API POST request
233
- def api_post(action, data)
234
- api_request(action, data, 'POST')
235
- end
236
-
237
- # params:
238
- # action, String
239
- # data, Hash
240
- # request, String "GET" or "POST"
241
- # returns:
242
- # Hash
243
- #
244
- # Perform an API request, using the shared-secret auth hash.
245
- #
246
- def api_request(action, data, request_type)
247
- data[:api_key] = @api_key
248
- data[:format] ||= 'json'
249
- data[:sig] = SailthruClient.get_signature_hash(data, @secret)
250
- _result = self.http_request("#{@api_uri}/#{action}", data, request_type)
251
-
252
101
 
253
- # NOTE: don't do the unserialize here
254
- unserialized = JSON.parse(_result)
255
- return unserialized ? unserialized : _result
256
- end
257
-
258
-
259
- # params:
260
- # uri, String
261
- # data, Hash
262
- # method, String "GET" or "POST"
263
- # returns:
264
- # String, body of response
265
- def http_request(uri, data, method = 'POST')
266
- data = flatten_nested_hash(data, false)
267
- # puts data.inspect
268
- if method == 'POST'
269
- post_data = data
270
- else
271
- uri += "?" + data.map{ |key, value| "#{CGI::escape(key)}=#{CGI::escape(value)}" }.join("&")
102
+ class SailthruClient
103
+
104
+ include Helpers
105
+
106
+ # params:
107
+ # api_key, String
108
+ # secret, String
109
+ # api_uri, String
110
+ #
111
+ # Instantiate a new client; constructor optionally takes overrides for key/secret/uri.
112
+ def initialize(api_key, secret, api_uri)
113
+ @api_key = api_key
114
+ @secret = secret
115
+ @api_uri = api_uri
272
116
  end
273
- req = nil
274
- headers = {"User-Agent" => "Sailthru API Ruby Client #{VERSION}"}
275
-
276
- _uri = URI.parse(uri)
277
- if method == 'POST'
278
- req = Net::HTTP::Post.new(_uri.path, headers)
279
- req.set_form_data(data)
280
- else
281
- req = Net::HTTP::Get.new("#{_uri.path}?#{_uri.query}", headers)
117
+
118
+ # params:
119
+ # template_name, String
120
+ # email, String
121
+ # replacements, Hash
122
+ # options, Hash
123
+ # replyto: override Reply-To header
124
+ # test: send as test email (subject line will be marked, will not count towards stats)
125
+ # returns:
126
+ # Hash, response data from server
127
+ def send(template_name, email, vars={}, options = {}, schedule_time = nil)
128
+ post = {}
129
+ post[:template] = template_name
130
+ post[:email] = email
131
+ post[:options] = options
132
+
133
+ if vars.length > 0
134
+ post[:vars] = vars
135
+ end
136
+
137
+ if schedule_time != nil
138
+ post[:schedule_time] = schedule_time
139
+ end
140
+ return self.api_post(:send, post)
282
141
  end
283
-
284
- @last_request = req
285
- begin
286
- response = Net::HTTP.start(_uri.host, _uri.port) {|http|
287
- http.request(req)
288
- }
289
- rescue Exception => e
290
- raise SailthruClientException.new("Unable to open stream: #{_uri.to_s}");
142
+
143
+
144
+ def multi_send(template_name, emails, vars={}, options = {}, schedule_time = nil)
145
+ post = {}
146
+ post[:template] = template_name
147
+ post[:email] = emails
148
+ post[:options] = options
149
+
150
+ if schedule_time != nil
151
+ post[:schedule_time] = schedule_time
152
+ end
153
+
154
+ if vars.length > 0
155
+ post[:vars] = vars
156
+ end
157
+
158
+ return self.api_post(:send, post)
291
159
  end
292
-
293
- if response.body
294
- return response.body
295
- else
296
- raise SailthruClientException.new("No response received from stream: #{_uri.to_s}")
160
+
161
+
162
+ # params:
163
+ # send_id, Fixnum
164
+ # returns:
165
+ # Hash, response data from server
166
+ #
167
+ # Get the status of a send.
168
+ def get_send(send_id)
169
+ self.api_get(:send, {:send_id => send_id.to_s})
297
170
  end
171
+
298
172
 
299
- end
300
-
301
- # Flatten nested hash for GET / POST request.
302
- def flatten_nested_hash(hash, brackets = true)
303
- f = {}
304
- hash.each do |key, value|
305
- _key = brackets ? "[#{key}]" : key.to_s
306
- if value.class == Hash
307
- flatten_nested_hash(value).each do |k, v|
308
- f["#{_key}#{k}"] = v
309
- end
310
- elsif value.class == Array
311
- temp_hash = Hash.new()
312
- value.each_with_index do |v, i|
313
- temp_hash[i.to_s] = v
314
- end
315
- flatten_nested_hash(temp_hash).each do |k, v|
316
- f["#{_key}#{k}"] = v
317
- end
173
+ def cancel_send(send_id)
174
+ self.api_delete(:send, {:send_id => send_id.to_s})
175
+ end
176
+
177
+ # params:
178
+ # name, String
179
+ # list, String
180
+ # schedule_time, String
181
+ # from_name, String
182
+ # from_email, String
183
+ # subject, String
184
+ # content_html, String
185
+ # content_text, String
186
+ # options, Hash
187
+ # returns:
188
+ # Hash, response data from server
189
+ #
190
+ # Schedule a mass mail blast
191
+ def schedule_blast(name, list, schedule_time, from_name, from_email, subject, content_html, content_text, options = {})
192
+ post = options ? options : {}
193
+ post[:name] = name
194
+ post[:list] = list
195
+ post[:schedule_time] = schedule_time
196
+ post[:from_name] = from_name
197
+ post[:from_email] = from_email
198
+ post[:subject] = subject
199
+ post[:content_html] = content_html
200
+ post[:content_text] = content_text
201
+ self.api_post(:blast, post)
202
+ end
203
+
204
+
205
+ # params:
206
+ # blast_id, Fixnum
207
+ # returns:
208
+ # Hash, response data from server
209
+ #
210
+ # Get information on a previously scheduled email blast
211
+ def get_blast(blast_id)
212
+ self.api_get(:blast, {:blast_id => blast_id.to_s})
213
+ end
214
+
215
+ # params:
216
+ # email, String
217
+ # returns:
218
+ # Hash, response data from server
219
+ #
220
+ # Return information about an email address, including replacement vars and lists.
221
+ def get_email(email)
222
+ self.api_get(:email, {:email => email})
223
+ end
224
+
225
+ # params:
226
+ # email, String
227
+ # vars, Hash
228
+ # lists, Hash mapping list name => 1 for subscribed, 0 for unsubscribed
229
+ # returns:
230
+ # Hash, response data from server
231
+ #
232
+ # Set replacement vars and/or list subscriptions for an email address.
233
+ def set_email(email, vars = {}, lists = {}, templates = {})
234
+ data = {:email => email}
235
+ data[:vars] = vars unless vars.empty?
236
+ data[:lists] = lists unless lists.empty?
237
+ data[:templates] = templates unless templates.empty?
238
+ self.api_post(:email, data)
239
+ end
240
+
241
+ # params:
242
+ # email, String
243
+ # password, String
244
+ # with_names, Boolean
245
+ # returns:
246
+ # Hash, response data from server
247
+ #
248
+ # Fetch email contacts from an address book at one of the major email providers (aol/gmail/hotmail/yahoo)
249
+ # Use the with_names parameter if you want to fetch the contact names as well as emails
250
+ def import_contacts(email, password, with_names = false)
251
+ data = { :email => email, :password => password }
252
+ data[:names] = 1 if with_names
253
+ self.api_post(:contacts, data)
254
+ end
255
+
256
+
257
+ # params:
258
+ # template_name, String
259
+ # returns:
260
+ # Hash of response data.
261
+ #
262
+ # Get a template.
263
+ def get_template(template_name)
264
+ self.api_get(:template, {:template => template_name})
265
+ end
318
266
 
267
+
268
+ # params:
269
+ # template_name, String
270
+ # template_fields, Hash
271
+ # returns:
272
+ # Hash containg response from the server.
273
+ #
274
+ # Save a template.
275
+ def save_template(template_name, template_fields)
276
+ data = template_fields
277
+ data[:template] = template_name
278
+ self.api_post(:template, data)
279
+ end
280
+
281
+
282
+ # params:
283
+ # params, Hash
284
+ # request, String
285
+ # returns:
286
+ # TrueClass or FalseClass, Returns true if the incoming request is an authenticated verify post.
287
+ def receive_verify_post(params, request)
288
+ if request.post?
289
+ [:action, :email, :send_id, :sig].each { |key| return false unless params.has_key?(key) }
290
+
291
+ return false unless params[:action] == :verify
292
+
293
+ sig = params[:sig]
294
+ params.delete(:sig)
295
+ return false unless sig == get_signature_hash(params, @secret)
296
+
297
+ _send = self.get_send(params[:send_id])
298
+ return false unless _send.has_key?(:email)
299
+
300
+ return false unless _send[:email] == params[:email]
301
+
302
+ return true
319
303
  else
320
- f[_key] = value
304
+ return false
321
305
  end
322
306
  end
323
- return f
324
- end
325
307
 
326
- # params:
327
- # params, Hash
328
- # returns:
329
- # Array, values of each item in the Hash (and nested hashes)
330
- #
331
- # Extracts the values of a set of parameters, recursing into nested assoc arrays.
332
- def self.extract_param_values(params)
333
- values = []
334
- params.each do |k, v|
335
- # puts "k,v: #{k}, #{v}"
336
- if v.class == Hash
337
- values.concat SailthruClient.extract_param_values(v)
338
- elsif v.class == Array
339
- temp_hash = Hash.new()
340
- v.each_with_index do |v_,i_|
341
- temp_hash[i_.to_s] = v_
342
- end
343
- values.concat self.extract_param_values(temp_hash)
344
- else
345
- values.push v.to_s()
308
+ # params:
309
+ # email, String
310
+ # items, String
311
+ # incomplete, Integer
312
+ # message_id, String
313
+ # returns:
314
+ # hash, response from server
315
+ #
316
+ # Record that a user has made a purchase, or has added items to their purchase total.
317
+ def purchase(email, items, incomplete = nil, message_id = nil)
318
+ data = {}
319
+ data[:email] = email
320
+
321
+ if verify_purchase_items(items)
322
+ data[:items] = items
323
+ end
324
+
325
+ if incomplete != nil
326
+ data[:incomplete] = incomplete.to_i
346
327
  end
328
+
329
+ if message_id != nil
330
+ data[:message_id] = message_id
331
+ end
332
+ api_post(:purchase, data)
347
333
  end
348
- return values
349
- end
350
334
 
351
- # params:
352
- # params, Hash
353
- # secret, String
354
- # returns:
355
- # String
356
- #
357
- # Returns the unhashed signature string (secret + sorted list of param values) for an API call.
358
- def self.get_signature_string(params, secret)
359
- return secret + self.extract_param_values(params).sort.join("")
360
- end
361
-
362
-
363
- # params:
364
- # params, Hash
365
- # secret, String
366
- # returns:
367
- # String
368
- #
369
- # Returns an MD5 hash of the signature string for an API call.
370
- def self.get_signature_hash(params, secret)
371
- return MD5.md5(self.get_signature_string(params, secret)).to_s # debuggin
335
+ # params:
336
+ # stat, String
337
+ #
338
+ # returns:
339
+ # hash, response from server
340
+ # Request various stats from Sailthru.
341
+ def get_stats(stat)
342
+ api_get(:stats, {:stat => stat})
343
+ end
344
+
345
+
346
+ protected
347
+
348
+ # Perform API GET request
349
+ def api_get(action, data)
350
+ api_request(action, data, 'GET')
351
+ end
352
+
353
+ # Perform API POST request
354
+ def api_post(action, data)
355
+ api_request(action, data, 'POST')
356
+ end
357
+
358
+ #Perform API DELETE request
359
+ def api_delete(action, data)
360
+ api_request(action, data, 'DELETE')
361
+ end
362
+
363
+ # params:
364
+ # action, String
365
+ # data, Hash
366
+ # request, String "GET" or "POST"
367
+ # returns:
368
+ # Hash
369
+ #
370
+ # Perform an API request, using the shared-secret auth hash.
371
+ #
372
+ def api_request(action, data, request_type)
373
+ data[:api_key] = @api_key
374
+ data[:format] ||= 'json'
375
+ data[:sig] = get_signature_hash(data, @secret)
376
+ _result = self.http_request("#{@api_uri}/#{action}", data, request_type)
377
+
378
+
379
+ # NOTE: don't do the unserialize here
380
+ unserialized = JSON.parse(_result)
381
+ return unserialized ? unserialized : _result
382
+ end
383
+
384
+
385
+ # params:
386
+ # uri, String
387
+ # data, Hash
388
+ # method, String "GET" or "POST"
389
+ # returns:
390
+ # String, body of response
391
+ def http_request(uri, data, method = 'POST')
392
+ data = flatten_nested_hash(data, false)
393
+ if method == 'POST'
394
+ post_data = data
395
+ else
396
+ uri += "?" + data.map{ |key, value| "#{CGI::escape(key.to_s)}=#{CGI::escape(value.to_s)}" }.join("&")
397
+ end
398
+ req = nil
399
+ headers = {"User-Agent" => "Sailthru API Ruby Client #{VERSION}"}
400
+
401
+ _uri = URI.parse(uri)
402
+ if method == 'POST'
403
+ req = Net::HTTP::Post.new(_uri.path, headers)
404
+ req.set_form_data(data)
405
+ else
406
+ request_uri = "#{_uri.path}?#{_uri.query}"
407
+ if method == 'DELETE'
408
+ req = Net::HTTP::Delete.new(request_uri, headers)
409
+ else
410
+ req = Net::HTTP::Get.new(request_uri, headers)
411
+ end
412
+ end
413
+
414
+ begin
415
+ response = Net::HTTP.start(_uri.host, _uri.port) {|http|
416
+ http.request(req)
417
+ }
418
+ rescue Exception => e
419
+ raise SailthruClientException.new("Unable to open stream: #{_uri.to_s}");
420
+ end
421
+
422
+ if response.body
423
+ return response.body
424
+ else
425
+ raise SailthruClientException.new("No response received from stream: #{_uri.to_s}")
426
+ end
427
+ end
372
428
  end
373
-
374
- end
429
+ end
metadata CHANGED
@@ -1,12 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sailthru-client
3
3
  version: !ruby/object:Gem::Version
4
- hash: 13
4
+ hash: 11
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
- - 1
9
- version: "1.01"
8
+ - 2
9
+ version: "1.02"
10
10
  platform: ruby
11
11
  authors:
12
12
  - Prajwal Tuladhar
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2011-01-19 00:00:00 -05:00
17
+ date: 2011-01-25 00:00:00 -05:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -31,6 +31,20 @@ dependencies:
31
31
  version: "0"
32
32
  type: :runtime
33
33
  version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: fakeweb
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ hash: 3
43
+ segments:
44
+ - 0
45
+ version: "0"
46
+ type: :development
47
+ version_requirements: *id002
34
48
  description:
35
49
  email: praj@sailthru.com
36
50
  executables: []