hyperpublic 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/Gemfile ADDED
@@ -0,0 +1,25 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ # Add dependencies to develop your gem here.
7
+ # Include everything needed to run rake, tests, features, etc.
8
+
9
+ gem "jeweler", "~> 1.5.1"
10
+ gem "hashie", "~>1.1.0"
11
+ gem "httparty", "~>0.7.8"
12
+ gem "rest-client", "~>1.5.1"
13
+ gem "multi_json", "~>1.0.3"
14
+ gem "json"
15
+ gem "fakeweb", "~>1.3.0"
16
+ gem "yajl-ruby"
17
+ gem 'addressable'
18
+
19
+ group :development do
20
+ gem 'ruby-debug'
21
+ gem "rspec-rails", ">= 2.2.1"
22
+ gem 'autotest-growl'
23
+ gem 'ZenTest'
24
+ #gem "rcov", ">= 0"
25
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,110 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ ZenTest (4.6.2)
5
+ actionpack (3.1.0)
6
+ activemodel (= 3.1.0)
7
+ activesupport (= 3.1.0)
8
+ builder (~> 3.0.0)
9
+ erubis (~> 2.7.0)
10
+ i18n (~> 0.6)
11
+ rack (~> 1.3.2)
12
+ rack-cache (~> 1.0.3)
13
+ rack-mount (~> 0.8.2)
14
+ rack-test (~> 0.6.1)
15
+ sprockets (~> 2.0.0)
16
+ activemodel (3.1.0)
17
+ activesupport (= 3.1.0)
18
+ bcrypt-ruby (~> 3.0.0)
19
+ builder (~> 3.0.0)
20
+ i18n (~> 0.6)
21
+ activesupport (3.1.0)
22
+ multi_json (~> 1.0)
23
+ addressable (2.2.6)
24
+ autotest-growl (0.2.11)
25
+ bcrypt-ruby (3.0.1)
26
+ builder (3.0.0)
27
+ columnize (0.3.4)
28
+ crack (0.1.8)
29
+ diff-lcs (1.1.3)
30
+ erubis (2.7.0)
31
+ fakeweb (1.3.0)
32
+ git (1.2.5)
33
+ hashie (1.1.0)
34
+ hike (1.2.1)
35
+ httparty (0.7.8)
36
+ crack (= 0.1.8)
37
+ i18n (0.6.0)
38
+ jeweler (1.5.2)
39
+ bundler (~> 1.0.0)
40
+ git (>= 1.2.5)
41
+ rake
42
+ json (1.6.0)
43
+ linecache (0.46)
44
+ rbx-require-relative (> 0.0.4)
45
+ mime-types (1.16)
46
+ multi_json (1.0.3)
47
+ rack (1.3.3)
48
+ rack-cache (1.0.3)
49
+ rack (>= 0.4)
50
+ rack-mount (0.8.3)
51
+ rack (>= 1.0.0)
52
+ rack-ssl (1.3.2)
53
+ rack
54
+ rack-test (0.6.1)
55
+ rack (>= 1.0)
56
+ railties (3.1.0)
57
+ actionpack (= 3.1.0)
58
+ activesupport (= 3.1.0)
59
+ rack-ssl (~> 1.3.2)
60
+ rake (>= 0.8.7)
61
+ rdoc (~> 3.4)
62
+ thor (~> 0.14.6)
63
+ rake (0.9.2)
64
+ rbx-require-relative (0.0.5)
65
+ rdoc (3.9.4)
66
+ rest-client (1.5.1)
67
+ mime-types (>= 1.16)
68
+ rspec (2.6.0)
69
+ rspec-core (~> 2.6.0)
70
+ rspec-expectations (~> 2.6.0)
71
+ rspec-mocks (~> 2.6.0)
72
+ rspec-core (2.6.4)
73
+ rspec-expectations (2.6.0)
74
+ diff-lcs (~> 1.1.2)
75
+ rspec-mocks (2.6.0)
76
+ rspec-rails (2.6.1)
77
+ actionpack (~> 3.0)
78
+ activesupport (~> 3.0)
79
+ railties (~> 3.0)
80
+ rspec (~> 2.6.0)
81
+ ruby-debug (0.10.4)
82
+ columnize (>= 0.1)
83
+ ruby-debug-base (~> 0.10.4.0)
84
+ ruby-debug-base (0.10.4)
85
+ linecache (>= 0.3)
86
+ sprockets (2.0.0)
87
+ hike (~> 1.2)
88
+ rack (~> 1.0)
89
+ tilt (!= 1.3.0, ~> 1.1)
90
+ thor (0.14.6)
91
+ tilt (1.3.3)
92
+ yajl-ruby (1.0.0)
93
+
94
+ PLATFORMS
95
+ ruby
96
+
97
+ DEPENDENCIES
98
+ ZenTest
99
+ addressable
100
+ autotest-growl
101
+ fakeweb (~> 1.3.0)
102
+ hashie (~> 1.1.0)
103
+ httparty (~> 0.7.8)
104
+ jeweler (~> 1.5.1)
105
+ json
106
+ multi_json (~> 1.0.3)
107
+ rest-client (~> 1.5.1)
108
+ rspec-rails (>= 2.2.1)
109
+ ruby-debug
110
+ yajl-ruby
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 etang
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.
data/README.md ADDED
@@ -0,0 +1,71 @@
1
+ #The Hyperpublic Ruby Gem
2
+ =========================
3
+
4
+ A Ruby wrapper for the Hyperpublic REST API
5
+
6
+
7
+ Installation
8
+ -------------
9
+ gem install hyperpublic_ruby
10
+
11
+
12
+ Sample Usage
13
+ -------------
14
+ require 'hyperpublic'
15
+
16
+ auth = Hyperpublic::OAuth.new("your_key", "your_secret")
17
+
18
+
19
+ ###Working with Places
20
+ places_client = Hyperpublic::Places.new(auth)
21
+
22
+ # find a single place by ID
23
+ place = places_client.find("4dd53bffe2f2d70816000001")
24
+
25
+ # find places by a query
26
+ places = places_client.find(:q => "chicken")
27
+
28
+ # find places by a location
29
+ places = places_client.find(:location => "416 w 13th st, New York")
30
+
31
+ # find places by multiple criteria
32
+ places = places_client.find(:category => "food", "postal_code" => 10012)
33
+
34
+ # create a place
35
+ places_client.create({:display_name => "Hyperpublic HQ",
36
+ :tags => ["place_tag1", "place_tag2"].join(","),
37
+ :image_url => "http://s3.amazonaws.com/prestigedevelopment/beta/image_photos/4dd535cab47dfd026c000002/square.png?1296938636",
38
+ :phone_number => "2124857375",
39
+ :website => "www.hyperpublic.com.com",
40
+ :category_id => "4e274d89bd0286830f000170",
41
+ :address => "416 w 13th st, New York, NY 10012",
42
+ :lat => 40.7405,
43
+ :lon => -74.007})
44
+
45
+
46
+ ###Working with Geodeals & Events
47
+ offers_client = Hyperpublic::Offers.new(auth)
48
+
49
+ # find a single offer by ID
50
+ offer = offers_client.show("4e5e66f9a7ecee0001027a7b")
51
+
52
+ # find offers by a query
53
+ offers = offers_client.find(:q => "bowling")
54
+
55
+ # find offers by a location
56
+ offers = offers_client.find(:lat => 40.7, :lon => 74.0)
57
+
58
+ # find offers by multiple criteria
59
+ offers = offers_client.find(:source => "buywithme", :price_min => 10, :limit => 5)
60
+
61
+
62
+ ###Working with Categories
63
+ categories_client = Hyperpublic::Categories.new(auth)
64
+
65
+ # get a list of categories
66
+ categories = categories_client.find
67
+
68
+
69
+ Documentation
70
+ -------------
71
+ Visit our [developer site](http://developer.hyperpublic.com) for full documentation.
data/Rakefile ADDED
@@ -0,0 +1,54 @@
1
+ require 'lib/hyperpublic/version.rb'
2
+ require 'rubygems'
3
+ require 'bundler'
4
+
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.version = Hyperpublic::VERSION
18
+ gem.files = FileList['lib/**/*.rb', '[A-Z]*', 'spec/**/*'].to_a
19
+ gem.name = "hyperpublic_ruby"
20
+ gem.homepage = "http://github.com/jumppost/hyperpublic_api_ruby"
21
+ gem.license = "MIT"
22
+ gem.summary = %Q{Client library for the hyperpublic api}
23
+ gem.description = %Q{Provides easy access to the hyperpublic api}
24
+ gem.email = "etang@hyperpublic.com"
25
+ gem.authors = ["etang"]
26
+ # Include your dependencies below. Runtime dependencies are required when using your gem,
27
+ # and development dependencies are only needed for development (ie running rake tasks, tests, etc)
28
+ # gem.add_runtime_dependency 'jabber4r', '> 0.1'
29
+ # gem.add_development_dependency 'rspec', '> 1.2.3'
30
+ end
31
+ Jeweler::RubygemsDotOrgTasks.new
32
+
33
+ require 'rspec/core'
34
+ require 'rspec/core/rake_task'
35
+ RSpec::Core::RakeTask.new(:spec) do |spec|
36
+ spec.pattern = FileList['spec/**/*_spec.rb']
37
+ end
38
+
39
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
40
+ spec.pattern = 'spec/**/*_spec.rb'
41
+ spec.rcov = true
42
+ end
43
+
44
+ task :default => :spec
45
+
46
+ require 'rake/rdoctask'
47
+ Rake::RDocTask.new do |rdoc|
48
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
49
+
50
+ rdoc.rdoc_dir = 'rdoc'
51
+ rdoc.title = "hyperpublic #{version}"
52
+ rdoc.rdoc_files.include('README*')
53
+ rdoc.rdoc_files.include('lib/**/*.rb')
54
+ end
@@ -0,0 +1,18 @@
1
+ module Hyperpublic
2
+ class All < Base
3
+ extend Forwardable
4
+ def_delegators :client, :get, :post, :post_multi, :put, :delete
5
+
6
+ attr_reader :client
7
+
8
+ def initialize(client)
9
+ @client = client
10
+ end
11
+
12
+ def find(params)
13
+ q = Addressable::URI.new
14
+ q.query_values = stringify(params)
15
+ perform_get("/all?#{q.query}")
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,117 @@
1
+ require 'cgi'
2
+
3
+ module Hyperpublic
4
+ class Base
5
+ extend Forwardable
6
+
7
+ def_delegators :client, :get, :post, :post_multi, :put, :delete
8
+
9
+ attr_reader :client
10
+
11
+ def initialize(client)
12
+ @client = client
13
+ end
14
+
15
+ def search_neighborhoods(search_string, limit)
16
+ perform_get("/locations/search_neighborhoods", {:search_string => search_string, :limit => limit})
17
+ end
18
+
19
+ def search_tags(search_string, limit)
20
+ perform_get("/tags/search", {:search_string => search_string, :limit => limit})
21
+ end
22
+
23
+ def photos(params)
24
+ query = {}
25
+ case
26
+ when params[:ids] then query[:ids] = params[:ids]
27
+ when params[:object_id] && params[:object_type] then
28
+ begin
29
+ query[:object_id] = params[:object_id]
30
+ query[:object_type] = params[:object_type]
31
+ end
32
+ end
33
+
34
+ perform_get("/photos", query)
35
+ end
36
+
37
+ protected
38
+
39
+ def self.mime_type(file)
40
+ case
41
+ when file =~ /\.jpg/ then 'image/jpg'
42
+ when file =~ /\.gif$/ then 'image/gif'
43
+ when file =~ /\.png$/ then 'image/png'
44
+ else 'application/octet-stream'
45
+ end
46
+ end
47
+
48
+ def mime_type(f) self.class.mime_type(f) end
49
+
50
+ CRLF = "\r\n"
51
+
52
+ def self.build_multipart_bodies(parts)
53
+ boundary = Time.now.to_i.to_s(16)
54
+ body = ""
55
+ parts.each do |key, value|
56
+ esc_key = CGI.escape(key.to_s)
57
+ body << "--#{boundary}#{CRLF}"
58
+ if value.respond_to?(:read)
59
+ body << "Content-Disposition: form-data; name=\"#{esc_key}\"; filename=\"#{File.basename(value.path)}\"#{CRLF}"
60
+ body << "Content-Type: #{mime_type(value.path)}#{CRLF*2}"
61
+ body << value.read
62
+ else
63
+ body << "Content-Disposition: form-data; name=\"#{esc_key}\"#{CRLF*2}#{value}"
64
+ end
65
+ body << CRLF
66
+ end
67
+ body << "--#{boundary}--#{CRLF*2}"
68
+ {
69
+ :body => body,
70
+ :headers => {"Content-Type" => "multipart/form-data; boundary=#{boundary}"}
71
+ }
72
+ end
73
+
74
+ def build_multipart_bodies(parts) self.class.build_multipart_bodies(parts) end
75
+
76
+
77
+ private
78
+
79
+ def stringify(obj)
80
+ if obj.is_a? Hash
81
+ obj.each do |key, value|
82
+ obj.delete(key)
83
+ obj[key.to_s] = stringify(value)
84
+ end
85
+ elsif obj.is_a? Array
86
+ obj.collect {|e| stringify(e)}
87
+ else
88
+ obj.to_s if obj
89
+ end
90
+ end
91
+
92
+ def arr_str(tags)
93
+ arr_str = (tags.is_a? Array) ? tags.join(",") : tags
94
+ arr_str
95
+ end
96
+
97
+ def perform_get(path, options={})
98
+ Hyperpublic::Request.get(self, path, options)
99
+ end
100
+
101
+ def perform_post(path, options={})
102
+ Hyperpublic::Request.post(self, path, options)
103
+ end
104
+
105
+ def perform_post_multi(path, options={})
106
+ Hyperpublic::Request.post_multi(self, path, options)
107
+ end
108
+
109
+ def perform_put(path, options={})
110
+ Hyperpublic::Request.put(self, path, options)
111
+ end
112
+
113
+ def perform_delete(path, options={})
114
+ Hyperpublic::Request.delete(self, path, options)
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,19 @@
1
+ module Hyperpublic
2
+ class Categories< Base
3
+ extend Forwardable
4
+ def_delegators :client, :get, :post, :post_multi, :put, :delete
5
+
6
+ attr_reader :client
7
+
8
+ def initialize(client)
9
+ @client = client
10
+ end
11
+
12
+ def find(params={})
13
+ q = Addressable::URI.new
14
+ q.query_values = stringify(params)
15
+ perform_get("/categories#{("?" + q.query) unless q.query.empty?}")
16
+ end
17
+ end
18
+ end
19
+
@@ -0,0 +1,63 @@
1
+ require 'addressable/uri'
2
+ require 'oauth'
3
+ require 'oauth/consumer'
4
+ require 'json'
5
+
6
+ module Hyperpublic
7
+ class OAuth
8
+ extend Forwardable
9
+
10
+ attr_reader :ctoken, :csecret
11
+
12
+ def initialize(ctoken, csecret, options={})
13
+ @ctoken, @csecret, @consumer_options = ctoken, csecret, {}
14
+ @api_endpoint = options[:api_endpoint] || 'https://api.hyperpublic.com/api/v1'
15
+ @consumer = ::OAuth::Consumer.new(ctoken, csecret, :site => @api_endpiont)
16
+ @token = ::OAuth::AccessToken.new(@consumer)
17
+ @signing_endpoint = options[:signing_endpoint] || 'https://api.hyperpublic.com/api/v1'
18
+ if options[:sign_in]
19
+ @consumer_options[:authorize_path] = '/oauth/authenticate'
20
+ end
21
+ @auth_params = "client_id=#{@ctoken}&client_secret=#{@csecret}" + (@token.token.empty? ? "" : "&access_token=#{@token.token}")
22
+ @auth_params_hash = {"client_id" => @ctoken, "client_secret" => @csecret}
23
+ @auth_params_hash["access_token"] = @token.token unless @token.token.empty?
24
+ end
25
+
26
+ def get(uri, options={})
27
+ path = @api_endpoint + uri
28
+ sep = (path =~ /\/.*\?/) ? "&" : "?"
29
+ @token.get(path + sep + @auth_params)
30
+ end
31
+
32
+ def post(uri, body, options={})
33
+ body.merge!("client_id" => @ctoken, "client_secret" => @csecret)
34
+ @token.post(@api_endpoint + uri, body.to_json, {"Content-Type" => 'application/json'})
35
+ end
36
+
37
+ def put(uri, body, options={})
38
+ @token.put(@api_endpoint + uri, body.merge(@auth_params_hash).to_json, {'Content-Type' => 'application/json'})
39
+ end
40
+
41
+ def delete(uri, options={})
42
+ path = @api_endpoint + uri
43
+ sep = (path =~ /\/.*\?/) ? "&" : "?"
44
+ @token.delete(path + sep + @auth_params)
45
+ end
46
+
47
+ def access_token
48
+ @access_token ||= ::OAuth::AccessToken.new(signing_consumer, @atoken, @asecret)
49
+ end
50
+
51
+ def authorize_from_access(atoken, asecret)
52
+ @atoken, @asecret = atoken, asecret
53
+ end
54
+
55
+ private
56
+
57
+ def clear_request_token
58
+ @request_token = nil
59
+ end
60
+
61
+ end
62
+ end
63
+
@@ -0,0 +1,27 @@
1
+ module Hyperpublic
2
+ class Offers < Base
3
+ extend Forwardable
4
+
5
+ def_delegators :client, :get, :post, :post_multi, :put, :delete
6
+
7
+ attr_reader :client
8
+
9
+ def initialize(client)
10
+ @client = client
11
+ end
12
+
13
+ def find(params={})
14
+ if params.is_a? String
15
+ perform_get("/offers/#{params}")
16
+ else
17
+ q = Addressable::URI.new
18
+ q.query_values = stringify(params)
19
+ perform_get("/offers?#{q.query}")
20
+ end
21
+ end
22
+
23
+ def show(id)
24
+ perform_get("/offers/#{id}")
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,32 @@
1
+ module Hyperpublic
2
+ class People < Base
3
+ extend Forwardable
4
+ def_delegators :client, :get, :post, :post_multi, :put, :delete
5
+
6
+ attr_reader :client
7
+
8
+ def initialize(client)
9
+ @client = client
10
+ end
11
+
12
+ #param can be
13
+ # id
14
+ # {:ids => [1, 2, 3]},
15
+ # {:tags => [tag1, tags]}, or
16
+ # {:location => {:lat=>35,:lon=>-70}}
17
+ # etc
18
+ def find(params)
19
+ if params.is_a? String
20
+ perform_get("/people/#{params}")
21
+ else
22
+ q = Addressable::URI.new
23
+ q.query_values = stringify(params)
24
+ perform_get("/people?#{q.query}")
25
+ end
26
+ end
27
+
28
+ def create(options={})
29
+ perform_post("/people", :body => options)
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,27 @@
1
+ module Hyperpublic
2
+ class Places < Base
3
+ extend Forwardable
4
+ def_delegators :client, :get, :post, :post_multi, :put, :delete
5
+
6
+ attr_reader :client
7
+
8
+ def initialize(client)
9
+ @client = client
10
+ end
11
+
12
+ def find(params)
13
+ if params.is_a? String
14
+ perform_get("/places/#{params}")
15
+ else
16
+ q = Addressable::URI.new
17
+ q.query_values = stringify(params)
18
+ perform_get("/places?#{q.query}")
19
+ end
20
+ end
21
+
22
+ def create(options={})
23
+ perform_post("/places", :body => options)
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,105 @@
1
+ module Hyperpublic
2
+ class Request
3
+ extend Forwardable
4
+
5
+ def self.get(client, path, options={})
6
+ new(client, :get, path, options).perform
7
+ end
8
+
9
+ def self.post(client, path, options={})
10
+ new(client, :post, path, options).perform
11
+ end
12
+
13
+ def self.post_multi(client, path, options={})
14
+ new(client, :post_multi, path, options).perform
15
+ end
16
+
17
+ def self.put(client, path, options={})
18
+ new(client, :put, path, options).perform
19
+ end
20
+
21
+ def self.delete(client, path, options={})
22
+ new(client, :delete, path, options).perform
23
+ end
24
+
25
+ attr_reader :client, :method, :path, :options
26
+
27
+ def_delegators :client, :get, :post, :post_multi, :put, :delete
28
+
29
+ def initialize(client, method, path, options={})
30
+ @client, @method, @path, @options = client, method, path, options
31
+ end
32
+
33
+ def uri
34
+ @uri ||= begin
35
+ uri = URI.parse(path)
36
+
37
+ if options[:query] && options[:query] != {}
38
+ uri.query = to_query(options[:query])
39
+ end
40
+
41
+ uri.to_s
42
+ end
43
+ end
44
+
45
+ def perform
46
+ Hyperpublic.make_friendly(send("perform_#{method}"))
47
+ end
48
+
49
+ private
50
+ def perform_get
51
+ get(uri, options[:headers])
52
+ end
53
+
54
+ def perform_post
55
+ post(uri, options[:body], options[:headers])
56
+ end
57
+
58
+ def perform_put
59
+ put(uri, options[:body], options[:headers])
60
+ end
61
+
62
+ def perform_delete
63
+ delete(uri, options[:headers])
64
+ end
65
+
66
+ def to_query(options)
67
+ options.inject([]) do |collection, opt|
68
+ collection << "#{opt[0]}=#{opt[1]}"
69
+ collection
70
+ end * '&'
71
+ end
72
+
73
+ =begin
74
+ def perform_get
75
+ #get(uri, options || {})
76
+ get(uri)
77
+ end
78
+
79
+ def perform_post
80
+ #post(uri, options[:body], options[:headers] || {})
81
+ post(uri, options[:body])
82
+ end
83
+
84
+ def perform_post_multi
85
+ post_multi(uri, options[:body], options[:headers] || {})
86
+ end
87
+
88
+ def perform_put
89
+ put(uri, options[:body], options[:headers] || {})
90
+ end
91
+
92
+ def perform_delete
93
+ delete(uri, options[:headers] || {})
94
+ end
95
+
96
+ def to_query(options)
97
+ options.inject([]) do |collection, opt|
98
+ collection << "#{opt[0]}=#{opt[1]}"
99
+ collection
100
+ end * '&'
101
+ end
102
+ =end
103
+ end
104
+ end
105
+