jnunemaker-httparty 0.1.8 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/History CHANGED
@@ -1,3 +1,7 @@
1
+ == 0.2.0 2008-12-07
2
+ * 1 major enhancement
3
+ * Removed ActiveSupport as a dependency. Now requires json gem for json deserialization and uses an included class to do the xml parsing.
4
+
1
5
  == 0.1.8 2008-11-30
2
6
  * 3 major enhancements
3
7
  * Moved base_uri normalization into request class and out of httparty module, fixing
data/Manifest CHANGED
@@ -6,15 +6,21 @@ examples/rubyurl.rb
6
6
  examples/twitter.rb
7
7
  examples/whoismyrep.rb
8
8
  History
9
- httparty.gemspec
9
+ lib/core_extensions.rb
10
+ lib/httparty/exceptions.rb
10
11
  lib/httparty/request.rb
11
12
  lib/httparty/version.rb
12
13
  lib/httparty.rb
14
+ lib/module_level_inheritable_attributes.rb
13
15
  Manifest
14
16
  MIT-LICENSE
15
17
  Rakefile
16
18
  README
17
19
  setup.rb
20
+ spec/fixtures/delicious.xml
21
+ spec/fixtures/google.html
22
+ spec/fixtures/twitter.json
23
+ spec/fixtures/twitter.xml
18
24
  spec/httparty/request_spec.rb
19
25
  spec/httparty_spec.rb
20
26
  spec/spec.opts
data/Rakefile CHANGED
@@ -13,7 +13,7 @@ Echoe.new(ProjectName, HTTParty::Version) do |p|
13
13
  p.url = "http://#{ProjectName}.rubyforge.org"
14
14
  p.author = "John Nunemaker"
15
15
  p.email = "nunemaker@gmail.com"
16
- p.extra_deps = [['activesupport', '>= 2.1']]
16
+ p.extra_deps = [['json', '~> 1.1']]
17
17
  p.need_tar_gz = false
18
18
  p.docs_host = WebsitePath
19
19
  end
data/examples/aaws.rb CHANGED
@@ -1,3 +1,6 @@
1
+ require 'rubygems'
2
+ require 'activesupport'
3
+
1
4
  dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
2
5
  require File.join(dir, 'httparty')
3
6
  require 'pp'
@@ -18,7 +18,6 @@ class Delicious
18
18
  # ie: posts(:query => {:tag => 'ruby'})
19
19
  def posts(options={})
20
20
  options.merge!({:basic_auth => @auth})
21
- # get posts and convert to structs so we can do .key instead of ['key'] with results
22
21
  self.class.get('/posts/get', options)
23
22
  end
24
23
 
@@ -33,4 +32,5 @@ end
33
32
 
34
33
  delicious = Delicious.new(config['username'], config['password'])
35
34
  pp delicious.posts(:query => {:tag => 'ruby'})
35
+ pp delicious.recent
36
36
 
data/examples/rubyurl.rb CHANGED
@@ -1,14 +1,14 @@
1
1
  dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
2
2
  require File.join(dir, 'httparty')
3
+ require 'pp'
3
4
 
4
5
  class Rubyurl
5
6
  include HTTParty
6
7
  base_uri 'rubyurl.com'
7
8
 
8
- def self.shorten(website_url)
9
- xml = post('/api/links.json', :query => {'link[website_url]' => website_url})
10
- xml['link'] && xml['link']['permalink']
9
+ def self.shorten( website_url )
10
+ post( '/api/links.json', :query => { :link => { :website_url => website_url } } )
11
11
  end
12
12
  end
13
13
 
14
- puts Rubyurl.shorten( 'http://istwitterdown.com/' ).inspect
14
+ pp Rubyurl.shorten( 'http://istwitterdown.com/' )
data/examples/twitter.rb CHANGED
@@ -28,4 +28,4 @@ twitter = Twitter.new(config['email'], config['password'])
28
28
  pp twitter.timeline
29
29
  # pp twitter.timeline(:friends, :query => {:since_id => 868482746})
30
30
  # pp twitter.timeline(:friends, :query => 'since_id=868482746')
31
- # pp twitter.post('this is a test')
31
+ # pp twitter.post('this is a test of 0.2.0')
@@ -6,4 +6,5 @@ class Rep
6
6
  include HTTParty
7
7
  end
8
8
 
9
- puts Rep.get('http://whoismyrepresentative.com/whoismyrep.php?zip=46544').inspect
9
+ pp Rep.get('http://whoismyrepresentative.com/whoismyrep.php?zip=46544')
10
+ pp Rep.get('http://whoismyrepresentative.com/whoismyrep.php', :query => {:zip => 46544})
data/httparty.gemspec CHANGED
@@ -2,15 +2,15 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{httparty}
5
- s.version = "0.1.8"
5
+ s.version = "0.2.0"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["John Nunemaker"]
9
- s.date = %q{2008-12-05}
9
+ s.date = %q{2008-12-07}
10
10
  s.description = %q{Makes http fun! Also, makes consuming restful web services dead easy.}
11
11
  s.email = %q{nunemaker@gmail.com}
12
- s.extra_rdoc_files = ["lib/httparty/request.rb", "lib/httparty/version.rb", "lib/httparty.rb", "README"]
13
- s.files = ["examples/aaws.rb", "examples/basic.rb", "examples/delicious.rb", "examples/google.rb", "examples/rubyurl.rb", "examples/twitter.rb", "examples/whoismyrep.rb", "History", "httparty.gemspec", "lib/httparty/request.rb", "lib/httparty/version.rb", "lib/httparty.rb", "Manifest", "MIT-LICENSE", "Rakefile", "README", "setup.rb", "spec/httparty/request_spec.rb", "spec/httparty_spec.rb", "spec/spec.opts", "spec/spec_helper.rb", "website/css/common.css", "website/index.html"]
12
+ s.extra_rdoc_files = ["lib/core_extensions.rb", "lib/httparty/exceptions.rb", "lib/httparty/request.rb", "lib/httparty/version.rb", "lib/httparty.rb", "lib/module_level_inheritable_attributes.rb", "README"]
13
+ s.files = ["examples/aaws.rb", "examples/basic.rb", "examples/delicious.rb", "examples/google.rb", "examples/rubyurl.rb", "examples/twitter.rb", "examples/whoismyrep.rb", "History", "httparty.gemspec", "lib/core_extensions.rb", "lib/httparty/exceptions.rb", "lib/httparty/request.rb", "lib/httparty/version.rb", "lib/httparty.rb", "lib/module_level_inheritable_attributes.rb", "Manifest", "MIT-LICENSE", "Rakefile", "README", "setup.rb", "spec/fixtures/delicious.xml", "spec/fixtures/google.html", "spec/fixtures/twitter.json", "spec/fixtures/twitter.xml", "spec/httparty/request_spec.rb", "spec/httparty_spec.rb", "spec/spec.opts", "spec/spec_helper.rb", "website/css/common.css", "website/index.html"]
14
14
  s.has_rdoc = true
15
15
  s.homepage = %q{http://httparty.rubyforge.org}
16
16
  s.post_install_message = %q{When you HTTParty, you must party hard!}
@@ -25,14 +25,14 @@ Gem::Specification.new do |s|
25
25
  s.specification_version = 2
26
26
 
27
27
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
28
- s.add_runtime_dependency(%q<activesupport>, [">= 2.1"])
28
+ s.add_runtime_dependency(%q<json>, ["~> 1.1"])
29
29
  s.add_development_dependency(%q<echoe>, [">= 0"])
30
30
  else
31
- s.add_dependency(%q<activesupport>, [">= 2.1"])
31
+ s.add_dependency(%q<json>, ["~> 1.1"])
32
32
  s.add_dependency(%q<echoe>, [">= 0"])
33
33
  end
34
34
  else
35
- s.add_dependency(%q<activesupport>, [">= 2.1"])
35
+ s.add_dependency(%q<json>, ["~> 1.1"])
36
36
  s.add_dependency(%q<echoe>, [">= 0"])
37
37
  end
38
38
  end
@@ -0,0 +1,340 @@
1
+ # Copyright (c) 2008 Sam Smoot.
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ class Object
23
+ # @return <TrueClass, FalseClass>
24
+ #
25
+ # @example [].blank? #=> true
26
+ # @example [1].blank? #=> false
27
+ # @example [nil].blank? #=> false
28
+ #
29
+ # Returns true if the object is nil or empty (if applicable)
30
+ def blank?
31
+ nil? || (respond_to?(:empty?) && empty?)
32
+ end
33
+ end # class Object
34
+
35
+ class Numeric
36
+ # @return <TrueClass, FalseClass>
37
+ #
38
+ # Numerics can't be blank
39
+ def blank?
40
+ false
41
+ end
42
+ end # class Numeric
43
+
44
+ class NilClass
45
+ # @return <TrueClass, FalseClass>
46
+ #
47
+ # Nils are always blank
48
+ def blank?
49
+ true
50
+ end
51
+ end # class NilClass
52
+
53
+ class TrueClass
54
+ # @return <TrueClass, FalseClass>
55
+ #
56
+ # True is not blank.
57
+ def blank?
58
+ false
59
+ end
60
+ end # class TrueClass
61
+
62
+ class FalseClass
63
+ # False is always blank.
64
+ def blank?
65
+ true
66
+ end
67
+ end # class FalseClass
68
+
69
+ class String
70
+ # @example "".blank? #=> true
71
+ # @example " ".blank? #=> true
72
+ # @example " hey ho ".blank? #=> false
73
+ #
74
+ # @return <TrueClass, FalseClass>
75
+ #
76
+ # Strips out whitespace then tests if the string is empty.
77
+ def blank?
78
+ strip.empty?
79
+ end
80
+ end # class String
81
+
82
+ require 'rexml/parsers/streamparser'
83
+ require 'rexml/parsers/baseparser'
84
+ require 'rexml/light/node'
85
+
86
+ # This is a slighly modified version of the XMLUtilityNode from
87
+ # http://merb.devjavu.com/projects/merb/ticket/95 (has.sox@gmail.com)
88
+ # It's mainly just adding vowels, as I ht cd wth n vwls :)
89
+ # This represents the hard part of the work, all I did was change the
90
+ # underlying parser.
91
+ class REXMLUtilityNode
92
+ attr_accessor :name, :attributes, :children, :type
93
+
94
+ def self.typecasts
95
+ @@typecasts
96
+ end
97
+
98
+ def self.typecasts=(obj)
99
+ @@typecasts = obj
100
+ end
101
+
102
+ def self.available_typecasts
103
+ @@typecasts
104
+ end
105
+
106
+ def self.available_typecasts=(obj)
107
+ @@typecasts = obj
108
+ end
109
+
110
+ self.typecasts = {}
111
+ self.typecasts["integer"] = lambda{|v| v.nil? ? nil : v.to_i}
112
+ self.typecasts["boolean"] = lambda{|v| v.nil? ? nil : (v.strip != "false")}
113
+ self.typecasts["datetime"] = lambda{|v| v.nil? ? nil : Time.parse(v).utc}
114
+ self.typecasts["date"] = lambda{|v| v.nil? ? nil : Date.parse(v)}
115
+ self.typecasts["dateTime"] = lambda{|v| v.nil? ? nil : Time.parse(v).utc}
116
+ self.typecasts["decimal"] = lambda{|v| BigDecimal(v)}
117
+ self.typecasts["double"] = lambda{|v| v.nil? ? nil : v.to_f}
118
+ self.typecasts["float"] = lambda{|v| v.nil? ? nil : v.to_f}
119
+ self.typecasts["symbol"] = lambda{|v| v.to_sym}
120
+ self.typecasts["string"] = lambda{|v| v.to_s}
121
+ self.typecasts["yaml"] = lambda{|v| v.nil? ? nil : YAML.load(v)}
122
+ self.typecasts["base64Binary"] = lambda{|v| v.unpack('m').first }
123
+
124
+ self.available_typecasts = self.typecasts.keys
125
+
126
+ def initialize(name, attributes = {})
127
+ @name = name.tr("-", "_")
128
+ # leave the type alone if we don't know what it is
129
+ @type = self.class.available_typecasts.include?(attributes["type"]) ? attributes.delete("type") : attributes["type"]
130
+
131
+ @nil_element = attributes.delete("nil") == "true"
132
+ @attributes = undasherize_keys(attributes)
133
+ @children = []
134
+ @text = false
135
+ end
136
+
137
+ def add_node(node)
138
+ @text = true if node.is_a? String
139
+ @children << node
140
+ end
141
+
142
+ def to_hash
143
+ if @type == "file"
144
+ f = StringIO.new((@children.first || '').unpack('m').first)
145
+ class << f
146
+ attr_accessor :original_filename, :content_type
147
+ end
148
+ f.original_filename = attributes['name'] || 'untitled'
149
+ f.content_type = attributes['content_type'] || 'application/octet-stream'
150
+ return {name => f}
151
+ end
152
+
153
+ if @text
154
+ return { name => typecast_value( translate_xml_entities( inner_html ) ) }
155
+ else
156
+ #change repeating groups into an array
157
+ groups = @children.inject({}) { |s,e| (s[e.name] ||= []) << e; s }
158
+
159
+ out = nil
160
+ if @type == "array"
161
+ out = []
162
+ groups.each do |k, v|
163
+ if v.size == 1
164
+ out << v.first.to_hash.entries.first.last
165
+ else
166
+ out << v.map{|e| e.to_hash[k]}
167
+ end
168
+ end
169
+ out = out.flatten
170
+
171
+ else # If Hash
172
+ out = {}
173
+ groups.each do |k,v|
174
+ if v.size == 1
175
+ out.merge!(v.first)
176
+ else
177
+ out.merge!( k => v.map{|e| e.to_hash[k]})
178
+ end
179
+ end
180
+ out.merge! attributes unless attributes.empty?
181
+ out = out.empty? ? nil : out
182
+ end
183
+
184
+ if @type && out.nil?
185
+ { name => typecast_value(out) }
186
+ else
187
+ { name => out }
188
+ end
189
+ end
190
+ end
191
+
192
+ # Typecasts a value based upon its type. For instance, if
193
+ # +node+ has #type == "integer",
194
+ # {{[node.typecast_value("12") #=> 12]}}
195
+ #
196
+ # @param value<String> The value that is being typecast.
197
+ #
198
+ # @details [:type options]
199
+ # "integer"::
200
+ # converts +value+ to an integer with #to_i
201
+ # "boolean"::
202
+ # checks whether +value+, after removing spaces, is the literal
203
+ # "true"
204
+ # "datetime"::
205
+ # Parses +value+ using Time.parse, and returns a UTC Time
206
+ # "date"::
207
+ # Parses +value+ using Date.parse
208
+ #
209
+ # @return <Integer, TrueClass, FalseClass, Time, Date, Object>
210
+ # The result of typecasting +value+.
211
+ #
212
+ # @note
213
+ # If +self+ does not have a "type" key, or if it's not one of the
214
+ # options specified above, the raw +value+ will be returned.
215
+ def typecast_value(value)
216
+ return value unless @type
217
+ proc = self.class.typecasts[@type]
218
+ proc.nil? ? value : proc.call(value)
219
+ end
220
+
221
+ # Convert basic XML entities into their literal values.
222
+ #
223
+ # @param value<#gsub> An XML fragment.
224
+ #
225
+ # @return <#gsub> The XML fragment after converting entities.
226
+ def translate_xml_entities(value)
227
+ value.gsub(/&lt;/, "<").
228
+ gsub(/&gt;/, ">").
229
+ gsub(/&quot;/, '"').
230
+ gsub(/&apos;/, "'").
231
+ gsub(/&amp;/, "&")
232
+ end
233
+
234
+ # Take keys of the form foo-bar and convert them to foo_bar
235
+ def undasherize_keys(params)
236
+ params.keys.each do |key, value|
237
+ params[key.tr("-", "_")] = params.delete(key)
238
+ end
239
+ params
240
+ end
241
+
242
+ # Get the inner_html of the REXML node.
243
+ def inner_html
244
+ @children.join
245
+ end
246
+
247
+ # Converts the node into a readable HTML node.
248
+ #
249
+ # @return <String> The HTML node in text form.
250
+ def to_html
251
+ attributes.merge!(:type => @type ) if @type
252
+ "<#{name}#{attributes.to_xml_attributes}>#{@nil_element ? '' : inner_html}</#{name}>"
253
+ end
254
+
255
+ # @alias #to_html #to_s
256
+ def to_s
257
+ to_html
258
+ end
259
+ end
260
+
261
+ class ToHashParser
262
+ def self.from_xml(xml)
263
+ stack = []
264
+ parser = REXML::Parsers::BaseParser.new(xml)
265
+
266
+ while true
267
+ event = parser.pull
268
+ case event[0]
269
+ when :end_document
270
+ break
271
+ when :end_doctype, :start_doctype
272
+ # do nothing
273
+ when :start_element
274
+ stack.push REXMLUtilityNode.new(event[1], event[2])
275
+ when :end_element
276
+ if stack.size > 1
277
+ temp = stack.pop
278
+ stack.last.add_node(temp)
279
+ end
280
+ when :text, :cdata
281
+ stack.last.add_node(event[1]) unless event[1].strip.length == 0
282
+ end
283
+ end
284
+ stack.pop.to_hash
285
+ end
286
+ end
287
+
288
+ class Hash
289
+ def self.from_xml(xml)
290
+ ToHashParser.from_xml(xml)
291
+ end
292
+
293
+ # @return <String> This hash as a query string
294
+ #
295
+ # @example
296
+ # { :name => "Bob",
297
+ # :address => {
298
+ # :street => '111 Ruby Ave.',
299
+ # :city => 'Ruby Central',
300
+ # :phones => ['111-111-1111', '222-222-2222']
301
+ # }
302
+ # }.to_params
303
+ # #=> "name=Bob&address[city]=Ruby Central&address[phones][]=111-111-1111&address[phones][]=222-222-2222&address[street]=111 Ruby Ave."
304
+ def to_params
305
+ params = self.map { |k,v| normalize_param(k,v) }.join
306
+ params.chop! # trailing &
307
+ params
308
+ end
309
+
310
+ # @param key<Object> The key for the param.
311
+ # @param value<Object> The value for the param.
312
+ #
313
+ # @return <String> This key value pair as a param
314
+ #
315
+ # @example normalize_param(:name, "Bob") #=> "name=Bob&"
316
+ def normalize_param(key, value)
317
+ param = ''
318
+ stack = []
319
+
320
+ if value.is_a?(Array)
321
+ param << value.map { |element| normalize_param("#{key}[]", element) }.join
322
+ elsif value.is_a?(Hash)
323
+ stack << [key,value]
324
+ else
325
+ param << "#{key}=#{URI.encode(value.to_s)}&"
326
+ end
327
+
328
+ stack.each do |parent, hash|
329
+ hash.each do |key, value|
330
+ if value.is_a?(Hash)
331
+ stack << ["#{parent}[#{key}]", value]
332
+ else
333
+ param << normalize_param("#{parent}[#{key}]", value)
334
+ end
335
+ end
336
+ end
337
+
338
+ param
339
+ end
340
+ end
@@ -0,0 +1,4 @@
1
+ module HTTParty
2
+ class UnsupportedFormat < StandardError; end
3
+ class RedirectionTooDeep < StandardError; end
4
+ end
@@ -1,24 +1,18 @@
1
+ require 'uri'
2
+
1
3
  module HTTParty
2
- class Request
3
- # Makes it so uri is sure to parse stuff like google.com without the http
4
- def self.normalize_base_uri(url) #:nodoc:
5
- use_ssl = (url =~ /^https/) || url.include?(':443')
6
- url.chop! if url.ends_with?('/')
7
- url.gsub!(/^https?:\/\//i, '')
8
- "http#{'s' if use_ssl}://#{url}"
9
- end
10
-
4
+ class Request
11
5
  SupportedHTTPMethods = [Net::HTTP::Get, Net::HTTP::Post, Net::HTTP::Put, Net::HTTP::Delete]
12
6
 
13
7
  attr_accessor :http_method, :path, :options
14
8
 
15
- def initialize(http_method, path, options={})
9
+ def initialize(http_method, path, o={})
16
10
  self.http_method = http_method
17
11
  self.path = path
18
12
  self.options = {
19
- :limit => options.delete(:no_follow) ? 0 : 5,
13
+ :limit => o.delete(:no_follow) ? 0 : 5,
20
14
  :default_params => {},
21
- }.merge(options.dup)
15
+ }.merge(o)
22
16
  end
23
17
 
24
18
  def path=(uri)
@@ -26,12 +20,15 @@ module HTTParty
26
20
  end
27
21
 
28
22
  def uri
29
- options[:base_uri] = self.class.normalize_base_uri(options[:base_uri]) unless options[:base_uri].nil?
30
23
  uri = path.relative? ? URI.parse("#{options[:base_uri]}#{path}") : path
31
24
  uri.query = query_string(uri)
32
25
  uri
33
26
  end
34
27
 
28
+ def format
29
+ options[:format]
30
+ end
31
+
35
32
  def perform
36
33
  validate!
37
34
  handle_response!(get_response(uri))
@@ -47,10 +44,18 @@ module HTTParty
47
44
 
48
45
  def get_response(uri) #:nodoc:
49
46
  request = http_method.new(uri.request_uri)
50
- request.set_form_data(options[:query]) if post? && options[:query]
51
- request.body = options[:body].is_a?(Hash) ? options[:body].to_query : options[:body] unless options[:body].blank?
47
+
48
+ if post? && options[:query]
49
+ request.set_form_data(options[:query])
50
+ end
51
+
52
+ request.body = options[:body].is_a?(Hash) ? options[:body].to_params : options[:body] unless options[:body].blank?
52
53
  request.initialize_http_header options[:headers]
53
- request.basic_auth(options[:basic_auth][:username], options[:basic_auth][:password]) if options[:basic_auth]
54
+
55
+ if options[:basic_auth]
56
+ request.basic_auth(options[:basic_auth][:username], options[:basic_auth][:password])
57
+ end
58
+
54
59
  response = http(uri).request(request)
55
60
  options[:format] ||= format_from_mimetype(response['content-type'])
56
61
  response
@@ -61,9 +66,9 @@ module HTTParty
61
66
  query_string_parts << uri.query unless uri.query.blank?
62
67
 
63
68
  if options[:query].is_a?(Hash)
64
- query_string_parts << options[:default_params].merge(options[:query]).to_query
69
+ query_string_parts << options[:default_params].merge(options[:query]).to_params
65
70
  else
66
- query_string_parts << options[:default_params].to_query unless options[:default_params].blank?
71
+ query_string_parts << options[:default_params].to_params unless options[:default_params].blank?
67
72
  query_string_parts << options[:query] unless options[:query].blank?
68
73
  end
69
74
 
@@ -88,11 +93,11 @@ module HTTParty
88
93
 
89
94
  def parse_response(body) #:nodoc:
90
95
  return nil if body.nil? or body.empty?
91
- case options[:format]
96
+ case format
92
97
  when :xml
93
98
  Hash.from_xml(body)
94
99
  when :json
95
- ActiveSupport::JSON.decode(body)
100
+ JSON.parse(body)
96
101
  else
97
102
  body
98
103
  end
@@ -1,3 +1,3 @@
1
1
  module HTTParty
2
- Version = '0.1.8'
2
+ Version = '0.2.0'
3
3
  end