alexvollmer-httparty 0.1.5

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/History.txt ADDED
@@ -0,0 +1,32 @@
1
+ == 0.1.5 2008-11-14
2
+ * 2 major enhancements
3
+ * Refactored send request method out into its own object.
4
+ * Added :html format if you just want to do that.
5
+
6
+ == 0.1.4 2008-11-08
7
+ * 3 major enhancements:
8
+ * Removed some cruft
9
+ * Added ability to follow redirects automatically and turn that off (Alex Vollmer)
10
+
11
+ == 0.1.3 2008-08-22
12
+
13
+ * 3 major enhancements:
14
+ * Added http_proxy key for setting proxy server and port (francxk@gmail.com)
15
+ * Now raises exception when http error occurs (francxk@gmail.com)
16
+ * Changed auto format detection from file extension to response content type (Jay Pignata)
17
+
18
+ == 0.1.2 2008-08-09
19
+
20
+ * 1 major enhancement:
21
+ * default_params were not being appended to query string if option[:query] was blank
22
+
23
+ == 0.1.1 2008-07-30
24
+
25
+ * 2 major enhancement:
26
+ * Added :basic_auth key for options when making a request
27
+ * :query and :body both now work with query string or hash
28
+
29
+ == 0.1.0 2008-07-27
30
+
31
+ * 1 major enhancement:
32
+ * Initial release
data/License.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 John Nunemaker
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/Manifest.txt ADDED
@@ -0,0 +1,31 @@
1
+ History.txt
2
+ License.txt
3
+ Manifest.txt
4
+ PostInstall.txt
5
+ README.txt
6
+ Rakefile
7
+ config/hoe.rb
8
+ config/requirements.rb
9
+ examples/aaws.rb
10
+ examples/delicious.rb
11
+ examples/google.rb
12
+ examples/twitter.rb
13
+ examples/whoismyrep.rb
14
+ httparty.gemspec
15
+ lib/httparty.rb
16
+ lib/httparty/request.rb
17
+ lib/httparty/version.rb
18
+ script/console
19
+ script/destroy
20
+ script/generate
21
+ script/txt2html
22
+ setup.rb
23
+ spec/httparty/request_spec.rb
24
+ spec/httparty_spec.rb
25
+ spec/spec.opts
26
+ spec/spec_helper.rb
27
+ tasks/deployment.rake
28
+ tasks/environment.rake
29
+ tasks/website.rake
30
+ website/css/common.css
31
+ website/index.html
data/PostInstall.txt ADDED
@@ -0,0 +1 @@
1
+ When you HTTParty, you must party hard!
data/README.txt ADDED
@@ -0,0 +1,66 @@
1
+ = httparty
2
+
3
+ == DESCRIPTION:
4
+
5
+ Makes http fun again!
6
+
7
+ == FEATURES/PROBLEMS:
8
+
9
+ * Easy get, post, put, delete requests
10
+ * Basic http authentication
11
+ * Default request query string parameters (ie: for api keys that are needed on each request)
12
+ * Automatic parsing of JSON and XML into ruby hashes based on response content-type
13
+
14
+ == SYNOPSIS:
15
+
16
+ The following is a simple example of wrapping Twitter's API for posting updates.
17
+
18
+ class Twitter
19
+ include HTTParty
20
+ base_uri 'twitter.com'
21
+ basic_auth 'username', 'password'
22
+ end
23
+
24
+ Twitter.post('/statuses/update.json', :query => {:status => "It's an HTTParty and everyone is invited!"})
25
+
26
+ That is really it! The object returned is a ruby hash that is decoded from Twitter's json response. JSON parsing is used because of the .json extension in the path of the request. You can also explicitly set a format (see the examples).
27
+
28
+ That works and all but what if you don't want to embed your username and password in the class? Below is an example to fix that:
29
+
30
+ class Twitter
31
+ include HTTParty
32
+ base_uri 'twitter.com'
33
+
34
+ def initialize(u, p)
35
+ @auth = {:username => u, :password => p}
36
+ end
37
+
38
+ def post(text)
39
+ options = { :query => {:status => text}, :basic_auth => @auth }
40
+ self.class.post('/statuses/update.json', options)
41
+ end
42
+ end
43
+
44
+ Twitter.new('username', 'password').post("It's an HTTParty and everyone is invited!")
45
+
46
+ === REQUEST OPTIONS
47
+
48
+ Each of the HTTP method (get, post, put and delete) each take a hash of options.
49
+ The following keys can be specified in the options:
50
+
51
+ headers:: A <tt>Hash</tt> of header key/value pairs
52
+ query:: A <tt>Hash</tt> of query key/value pairs
53
+ body:: The body of the request. If it's a <tt>Hash</tt>, it is
54
+ converted into query-string format, otherwise it is sent
55
+ as-is.
56
+ basic_auth:: A <tt>Hash</tt> containing keys for <tt>:username</tt> and
57
+ <tt>:password</tt>.
58
+ no_follow:: Turns off automatic redirect following
59
+
60
+ == REQUIREMENTS:
61
+
62
+ * Active Support >= 2.1
63
+
64
+ == INSTALL:
65
+
66
+ * sudo gem install httparty
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ require 'config/requirements'
2
+ require 'config/hoe' # setup Hoe + all gem configuration
3
+ require "spec/rake/spectask"
4
+
5
+ Dir['tasks/**/*.rake'].each { |rake| load rake }
6
+
7
+ task :default => :spec
8
+
9
+ Spec::Rake::SpecTask.new do |t|
10
+ t.spec_files = FileList["spec/**/*_spec.rb"]
11
+ end
data/config/hoe.rb ADDED
@@ -0,0 +1,73 @@
1
+ require 'httparty/version'
2
+
3
+ AUTHOR = 'John Nunemaker' # can also be an array of Authors
4
+ EMAIL = "nunemaker@gmail.com"
5
+ DESCRIPTION = "Makes http fun! Also, makes consuming restful web services dead easy."
6
+ GEM_NAME = 'httparty' # what ppl will type to install your gem
7
+ RUBYFORGE_PROJECT = 'httparty' # The unix name for your project
8
+ HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
9
+ DOWNLOAD_PATH = "http://rubyforge.org/projects/#{RUBYFORGE_PROJECT}"
10
+ EXTRA_DEPENDENCIES = [
11
+ ['activesupport', '>= 2.1']
12
+ ] # An array of rubygem dependencies [name, version]
13
+
14
+ @config_file = "~/.rubyforge/user-config.yml"
15
+ @config = nil
16
+ RUBYFORGE_USERNAME = "unknown"
17
+ def rubyforge_username
18
+ unless @config
19
+ begin
20
+ @config = YAML.load(File.read(File.expand_path(@config_file)))
21
+ rescue
22
+ puts <<-EOS
23
+ ERROR: No rubyforge config file found: #{@config_file}
24
+ Run 'rubyforge setup' to prepare your env for access to Rubyforge
25
+ - See http://newgem.rubyforge.org/rubyforge.html for more details
26
+ EOS
27
+ exit
28
+ end
29
+ end
30
+ RUBYFORGE_USERNAME.replace @config["username"]
31
+ end
32
+
33
+
34
+ REV = nil
35
+ # UNCOMMENT IF REQUIRED:
36
+ # REV = YAML.load(`svn info`)['Revision']
37
+ VERS = HTTParty::VERSION::STRING + (REV ? ".#{REV}" : "")
38
+ RDOC_OPTS = ['--quiet', '--title', 'httparty documentation',
39
+ "--opname", "index.html",
40
+ "--line-numbers",
41
+ "--main", "README",
42
+ "--inline-source"]
43
+
44
+ class Hoe
45
+ def extra_deps
46
+ @extra_deps.reject! { |x| Array(x).first == 'hoe' }
47
+ @extra_deps
48
+ end
49
+ end
50
+
51
+ # Generate all the Rake tasks
52
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
53
+ $hoe = Hoe.new(GEM_NAME, VERS) do |p|
54
+ p.developer(AUTHOR, EMAIL)
55
+ p.description = DESCRIPTION
56
+ p.summary = DESCRIPTION
57
+ p.url = HOMEPATH
58
+ p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
59
+ p.test_globs = ["test/**/test_*.rb"]
60
+ p.clean_globs |= ['**/.*.sw?', '*.gem', '.config', '**/.DS_Store'] #An array of file patterns to delete on clean.
61
+
62
+ # == Optional
63
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
64
+ p.extra_deps = EXTRA_DEPENDENCIES
65
+
66
+ #p.spec_extras = {} # A hash of extra values to set in the gemspec.
67
+ end
68
+
69
+ CHANGES = $hoe.paragraphs_of('History.txt', 0..1).join("\\n\\n")
70
+ PATH = (RUBYFORGE_PROJECT == GEM_NAME) ? RUBYFORGE_PROJECT : "#{RUBYFORGE_PROJECT}/#{GEM_NAME}"
71
+ $hoe.remote_rdoc_dir = File.join(PATH.gsub(/^#{RUBYFORGE_PROJECT}\/?/,''), 'rdoc')
72
+ $hoe.rsync_args = '-av --delete --ignore-errors'
73
+ $hoe.spec.post_install_message = File.open(File.dirname(__FILE__) + "/../PostInstall.txt").read rescue ""
@@ -0,0 +1,15 @@
1
+ require 'fileutils'
2
+ include FileUtils
3
+
4
+ require 'rubygems'
5
+ %w[rake hoe newgem rubigen].each do |req_gem|
6
+ begin
7
+ require req_gem
8
+ rescue LoadError
9
+ puts "This Rakefile requires the '#{req_gem}' RubyGem."
10
+ puts "Installation: gem install #{req_gem} -y"
11
+ exit
12
+ end
13
+ end
14
+
15
+ $:.unshift(File.join(File.dirname(__FILE__), %w[.. lib]))
data/examples/aaws.rb ADDED
@@ -0,0 +1,29 @@
1
+ dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ require File.join(dir, 'httparty')
3
+ require 'pp'
4
+ config = YAML::load(File.read(File.join(ENV['HOME'], '.aaws')))
5
+
6
+ module AAWS
7
+ class Book
8
+ include HTTParty
9
+ base_uri 'http://ecs.amazonaws.com'
10
+ default_params :Service => 'AWSECommerceService', :Operation => 'ItemSearch', :SearchIndex => 'Books'
11
+
12
+ def initialize(key)
13
+ self.class.default_params :AWSAccessKeyId => key
14
+ end
15
+
16
+ def search(options={})
17
+ raise ArgumentError, 'You must search for something' if options[:query].blank?
18
+
19
+ # amazon uses nasty camelized query params
20
+ options[:query] = options[:query].inject({}) { |h, q| h[q[0].to_s.camelize] = q[1]; h }
21
+
22
+ # make a request and return the items (NOTE: this doesn't handle errors at this point)
23
+ self.class.get('/onca/xml', options)['ItemSearchResponse']['Items']
24
+ end
25
+ end
26
+ end
27
+
28
+ aaws = AAWS::Book.new(config[:access_key])
29
+ pp aaws.search(:query => {:title => 'Ruby On Rails'})
@@ -0,0 +1,37 @@
1
+ dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ require File.join(dir, 'httparty')
3
+ require 'pp'
4
+ config = YAML::load(File.read(File.join(ENV['HOME'], '.delicious')))
5
+
6
+ class Delicious
7
+ include HTTParty
8
+ base_uri 'https://api.del.icio.us/v1'
9
+
10
+ def initialize(u, p)
11
+ @auth = {:username => u, :password => p}
12
+ end
13
+
14
+ # query params that filter the posts are:
15
+ # tag (optional). Filter by this tag.
16
+ # dt (optional). Filter by this date (CCYY-MM-DDThh:mm:ssZ).
17
+ # url (optional). Filter by this url.
18
+ # ie: posts(:query => {:tag => 'ruby'})
19
+ def posts(options={})
20
+ options.merge!({:basic_auth => @auth})
21
+ # get posts and convert to structs so we can do .key instead of ['key'] with results
22
+ self.class.get('/posts/get', options)
23
+ end
24
+
25
+ # query params that filter the posts are:
26
+ # tag (optional). Filter by this tag.
27
+ # count (optional). Number of items to retrieve (Default:15, Maximum:100).
28
+ def recent(options={})
29
+ options.merge!({:basic_auth => @auth})
30
+ self.class.get('/posts/recent', options)
31
+ end
32
+ end
33
+
34
+ delicious = Delicious.new(config['username'], config['password'])
35
+ pp delicious.posts(:query => {:tag => 'ruby'})
36
+ pp delicious.recent
37
+
@@ -0,0 +1,16 @@
1
+ dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ require File.join(dir, 'httparty')
3
+ require 'pp'
4
+
5
+ class Google
6
+ include HTTParty
7
+ format :html
8
+ end
9
+
10
+ # google.com redirects to www.google.com so this is live test for redirection
11
+ pp Google.get('http://google.com')
12
+
13
+ puts '', '*'*70, ''
14
+
15
+ # check that ssl is requesting right
16
+ pp Google.get('https://www.google.com')
@@ -0,0 +1,31 @@
1
+ dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ require File.join(dir, 'httparty')
3
+ require 'pp'
4
+ config = YAML::load(File.read(File.join(ENV['HOME'], '.twitter')))
5
+
6
+ class Twitter
7
+ include HTTParty
8
+ base_uri 'twitter.com'
9
+
10
+ def initialize(u, p)
11
+ @auth = {:username => u, :password => p}
12
+ end
13
+
14
+ # which can be :friends, :user or :public
15
+ # options[:query] can be things like since, since_id, count, etc.
16
+ def timeline(which=:friends, options={})
17
+ options.merge!({:basic_auth => @auth})
18
+ self.class.get("/statuses/#{which}_timeline.json", options)
19
+ end
20
+
21
+ def post(text)
22
+ options = { :query => {:status => text}, :basic_auth => @auth }
23
+ self.class.post('/statuses/update.json', options)
24
+ end
25
+ end
26
+
27
+ twitter = Twitter.new(config['email'], config['password'])
28
+ pp twitter.timeline
29
+ # pp twitter.timeline(:friends, :query => {:since_id => 868482746})
30
+ # pp twitter.timeline(:friends, :query => 'since_id=868482746')
31
+ # pp twitter.post('this is a test')
@@ -0,0 +1,9 @@
1
+ dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ require File.join(dir, 'httparty')
3
+ require 'pp'
4
+
5
+ class Rep
6
+ include HTTParty
7
+ end
8
+
9
+ puts Rep.get('http://whoismyrepresentative.com/whoismyrep.php?zip=46544').inspect
data/httparty.gemspec ADDED
@@ -0,0 +1,38 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{httparty}
5
+ s.version = "0.1.5"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["John Nunemaker"]
9
+ s.date = %q{2008-11-14}
10
+ s.description = %q{Makes http fun! Also, makes consuming restful web services dead easy.}
11
+ s.email = ["nunemaker@gmail.com"]
12
+ s.extra_rdoc_files = ["History.txt", "License.txt", "Manifest.txt", "PostInstall.txt", "README.txt"]
13
+ s.files = ["History.txt", "License.txt", "Manifest.txt", "PostInstall.txt", "README.txt", "Rakefile", "config/hoe.rb", "config/requirements.rb", "examples/aaws.rb", "examples/delicious.rb", "examples/google.rb", "examples/twitter.rb", "examples/whoismyrep.rb", "httparty.gemspec", "lib/httparty.rb", "lib/httparty/request.rb", "lib/httparty/version.rb", "script/console", "script/destroy", "script/generate", "script/txt2html", "setup.rb", "spec/httparty/request_spec.rb", "spec/httparty_spec.rb", "spec/spec.opts", "spec/spec_helper.rb", "tasks/deployment.rake", "tasks/environment.rake", "tasks/website.rake", "website/css/common.css", "website/index.html"]
14
+ s.has_rdoc = true
15
+ s.homepage = %q{http://httparty.rubyforge.org}
16
+ s.post_install_message = %q{When you HTTParty, you must party hard!}
17
+ s.rdoc_options = ["--main", "README.txt"]
18
+ s.require_paths = ["lib"]
19
+ s.rubyforge_project = %q{httparty}
20
+ s.rubygems_version = %q{1.3.1}
21
+ s.summary = %q{Makes http fun! Also, makes consuming restful web services dead easy.}
22
+
23
+ if s.respond_to? :specification_version then
24
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
25
+ s.specification_version = 2
26
+
27
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
28
+ s.add_runtime_dependency(%q<activesupport>, [">= 2.1"])
29
+ s.add_development_dependency(%q<hoe>, [">= 1.8.0"])
30
+ else
31
+ s.add_dependency(%q<activesupport>, [">= 2.1"])
32
+ s.add_dependency(%q<hoe>, [">= 1.8.0"])
33
+ end
34
+ else
35
+ s.add_dependency(%q<activesupport>, [">= 2.1"])
36
+ s.add_dependency(%q<hoe>, [">= 1.8.0"])
37
+ end
38
+ end
@@ -0,0 +1,104 @@
1
+ module HTTParty
2
+ class Request
3
+ SupportedHTTPMethods = [Net::HTTP::Get, Net::HTTP::Post, Net::HTTP::Put, Net::HTTP::Delete]
4
+
5
+ attr_accessor :http_method, :path, :options
6
+
7
+ def initialize(http_method, path, options={})
8
+ self.http_method = http_method
9
+ self.path = path
10
+ self.options = {
11
+ :limit => options.delete(:no_follow) ? 0 : 5,
12
+ :default_params => {},
13
+ }.merge(options.dup)
14
+ end
15
+
16
+ def path=(uri)
17
+ @path = URI.parse(uri)
18
+ end
19
+
20
+ def uri
21
+ uri = path.relative? ? URI.parse("#{options[:base_uri]}#{path}") : path
22
+ uri.query = query_string(uri)
23
+ uri
24
+ end
25
+
26
+ def perform
27
+ validate!
28
+ handle_response!(get_response(uri))
29
+ end
30
+
31
+ private
32
+ def http(uri) #:nodoc:
33
+ http = Net::HTTP.new(uri.host, uri.port, options[:http_proxyaddr], options[:http_proxyport])
34
+ http.use_ssl = (uri.port == 443)
35
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
36
+ http
37
+ end
38
+
39
+ def get_response(uri) #:nodoc:
40
+ request = http_method.new(uri.request_uri)
41
+ request.body = options[:body].is_a?(Hash) ? options[:body].to_query : options[:body] unless options[:body].blank?
42
+ request.initialize_http_header options[:headers]
43
+ request.basic_auth(options[:basic_auth][:username], options[:basic_auth][:password]) if options[:basic_auth]
44
+ response = http(uri).request(request)
45
+ options[:format] ||= format_from_mimetype(response['content-type'])
46
+ response
47
+ end
48
+
49
+ def query_string(uri) #:nodoc:
50
+ query_string_parts = []
51
+ query_string_parts << uri.query unless uri.query.blank?
52
+
53
+ if options[:query].is_a?(Hash)
54
+ query_string_parts << options[:default_params].merge(options[:query]).to_query
55
+ else
56
+ query_string_parts << options[:default_params].to_query unless options[:default_params].blank?
57
+ query_string_parts << options[:query] unless options[:query].blank?
58
+ end
59
+
60
+ query_string_parts.size > 0 ? query_string_parts.join('&') : nil
61
+ end
62
+
63
+ # Raises exception Net::XXX (http error code) if an http error occured
64
+ def handle_response!(response) #:nodoc:
65
+ case response
66
+ when Net::HTTPSuccess
67
+ parse_response(response.body)
68
+ when Net::HTTPRedirection
69
+ options[:limit] -= 1
70
+ self.path = response['location']
71
+ perform
72
+ else
73
+ response.instance_eval { class << self; attr_accessor :body_parsed; end }
74
+ begin; response.body_parsed = parse_response(response.body); rescue; end
75
+ response.error! # raises exception corresponding to http error Net::XXX
76
+ end
77
+ end
78
+
79
+ def parse_response(body) #:nodoc:
80
+ return nil if body.nil? or body.empty?
81
+ case options[:format]
82
+ when :xml
83
+ Hash.from_xml(body)
84
+ when :json
85
+ ActiveSupport::JSON.decode(body)
86
+ else
87
+ body
88
+ end
89
+ end
90
+
91
+ # Uses the HTTP Content-Type header to determine the format of the response
92
+ # It compares the MIME type returned to the types stored in the AllowedFormats hash
93
+ def format_from_mimetype(mimetype) #:nodoc:
94
+ AllowedFormats.each { |k, v| return k if mimetype.include?(v) }
95
+ end
96
+
97
+ def validate! #:nodoc:
98
+ raise HTTParty::RedirectionTooDeep, 'HTTP redirects too deep' if options[:limit].to_i <= 0
99
+ raise ArgumentError, 'only get, post, put and delete methods are supported' unless SupportedHTTPMethods.include?(http_method)
100
+ raise ArgumentError, ':headers must be a hash' if options[:headers] && !options[:headers].is_a?(Hash)
101
+ raise ArgumentError, ':basic_auth must be a hash' if options[:basic_auth] && !options[:basic_auth].is_a?(Hash)
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,9 @@
1
+ module HTTParty
2
+ module VERSION #:nodoc:
3
+ MAJOR = 0
4
+ MINOR = 1
5
+ TINY = 5
6
+
7
+ STRING = [MAJOR, MINOR, TINY].join('.')
8
+ end
9
+ end
data/lib/httparty.rb ADDED
@@ -0,0 +1,107 @@
1
+ require 'net/http'
2
+ require 'net/https'
3
+ require 'uri'
4
+ require 'ostruct'
5
+ require 'rubygems'
6
+ require 'active_support'
7
+
8
+ directory = File.dirname(__FILE__)
9
+ $:.unshift(directory) unless $:.include?(directory) || $:.include?(File.expand_path(directory))
10
+
11
+ require 'httparty/request'
12
+
13
+ module HTTParty
14
+ class UnsupportedFormat < StandardError; end
15
+ class RedirectionTooDeep < StandardError; end
16
+
17
+ AllowedFormats = {:xml => 'text/xml', :json => 'application/json', :html => 'text/html'}
18
+
19
+ def self.included(base)
20
+ base.extend ClassMethods
21
+ end
22
+
23
+ module ClassMethods
24
+ def default_options
25
+ @@default_options ||= {}
26
+ end
27
+
28
+ #
29
+ # Set an http proxy
30
+ #
31
+ # class Twitter
32
+ # include HTTParty
33
+ # http_proxy 'http://myProxy', 1080
34
+ # ....
35
+ def http_proxy(addr=nil, port = nil)
36
+ default_options[:http_proxyaddr] = addr
37
+ default_options[:http_proxyport] = port
38
+ end
39
+
40
+ def base_uri(uri=nil)
41
+ return default_options[:base_uri] unless uri
42
+ default_options[:base_uri] = normalize_base_uri(uri)
43
+ end
44
+
45
+ def basic_auth(u, p)
46
+ default_options[:basic_auth] = {:username => u, :password => p}
47
+ end
48
+
49
+ def default_params(h={})
50
+ raise ArgumentError, 'Default params must be a hash' unless h.is_a?(Hash)
51
+ default_options[:default_params] ||= {}
52
+ default_options[:default_params].merge!(h)
53
+ end
54
+
55
+ def headers(h={})
56
+ raise ArgumentError, 'Headers must be a hash' unless h.is_a?(Hash)
57
+ default_options[:headers] ||= {}
58
+ default_options[:headers].merge!(h)
59
+ end
60
+
61
+ def format(f)
62
+ raise UnsupportedFormat, "Must be one of: #{AllowedFormats.keys.join(', ')}" unless AllowedFormats.key?(f)
63
+ default_options[:format] = f
64
+ end
65
+
66
+ def get(path, options={})
67
+ perform_request Net::HTTP::Get, path, options
68
+ end
69
+
70
+ def post(path, options={})
71
+ perform_request Net::HTTP::Post, path, options
72
+ end
73
+
74
+ def put(path, options={})
75
+ perform_request Net::HTTP::Put, path, options
76
+ end
77
+
78
+ def delete(path, options={})
79
+ perform_request Net::HTTP::Delete, path, options
80
+ end
81
+
82
+ private
83
+ def perform_request(http_method, path, options) #:nodoc:
84
+ Request.new(http_method, path, default_options.merge(options)).perform
85
+ end
86
+
87
+ # Makes it so uri is sure to parse stuff like google.com without the http
88
+ def normalize_base_uri(url) #:nodoc:
89
+ use_ssl = (url =~ /^https/) || url.include?(':443')
90
+ url.chop! if url.ends_with?('/')
91
+ url.gsub!(/^https?:\/\//i, '')
92
+ "http#{'s' if use_ssl}://#{url}"
93
+ end
94
+
95
+ # Figure out the Content-Type from the path extension
96
+ def format_from_path(path) #:nodoc:
97
+ case path
98
+ when /\.xml$/
99
+ 'xml'
100
+ when /\.json$/
101
+ 'json'
102
+ else
103
+ nil
104
+ end
105
+ end
106
+ end
107
+ end
data/script/console ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # File: script/console
3
+ irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
4
+
5
+ libs = " -r irb/completion"
6
+ # Perhaps use a console_lib to store any extra methods I may want available in the cosole
7
+ # libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
8
+ libs << " -r #{File.dirname(__FILE__) + '/../lib/httparty.rb'}"
9
+ puts "Loading httparty gem"
10
+ exec "#{irb} #{libs} --simple-prompt"
data/script/destroy ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/destroy'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Destroy.new.run(ARGV)