From dbac38209409578d289ae4c60dd28a7a4aabbfbe Mon Sep 17 00:00:00 2001 From: Thomas Davis Date: Sat, 12 Dec 2009 10:29:06 -0500 Subject: [PATCH] unpacked the httparty gem --- config/environment.rb | 2 +- vendor/gems/httparty-0.4.3/.specification | 137 ++ vendor/gems/httparty-0.4.3/History | 125 ++ vendor/gems/httparty-0.4.3/MIT-LICENSE | 20 + vendor/gems/httparty-0.4.3/Manifest | 50 + vendor/gems/httparty-0.4.3/README | 36 + vendor/gems/httparty-0.4.3/Rakefile | 48 + vendor/gems/httparty-0.4.3/bin/httparty | 98 + vendor/gems/httparty-0.4.3/cucumber.yml | 1 + vendor/gems/httparty-0.4.3/examples/aaws.rb | 32 + vendor/gems/httparty-0.4.3/examples/basic.rb | 11 + .../gems/httparty-0.4.3/examples/delicious.rb | 37 + vendor/gems/httparty-0.4.3/examples/google.rb | 16 + .../gems/httparty-0.4.3/examples/rubyurl.rb | 14 + .../gems/httparty-0.4.3/examples/twitter.rb | 31 + .../httparty-0.4.3/examples/whoismyrep.rb | 10 + .../features/basic_authentication.feature | 20 + .../features/command_line.feature | 7 + .../deals_with_http_error_codes.feature | 26 + .../features/handles_multiple_formats.feature | 34 + .../gems/httparty-0.4.3/features/steps/env.rb | 15 + .../features/steps/httparty_response_steps.rb | 26 + .../features/steps/httparty_steps.rb | 15 + .../features/steps/mongrel_helper.rb | 55 + .../features/steps/remote_service_steps.rb | 47 + .../features/supports_redirection.feature | 22 + vendor/gems/httparty-0.4.3/httparty.gemspec | 40 + vendor/gems/httparty-0.4.3/lib/httparty.rb | 205 +++ .../lib/httparty/cookie_hash.rb | 9 + .../lib/httparty/core_extensions.rb | 25 + .../httparty-0.4.3/lib/httparty/exceptions.rb | 7 + .../httparty/module_inheritable_attributes.rb | 25 + .../httparty-0.4.3/lib/httparty/request.rb | 139 ++ .../httparty-0.4.3/lib/httparty/response.rb | 18 + .../httparty-0.4.3/lib/httparty/version.rb | 3 + vendor/gems/httparty-0.4.3/setup.rb | 1585 +++++++++++++++++ .../spec/fixtures/delicious.xml | 23 + .../httparty-0.4.3/spec/fixtures/empty.xml | 0 .../httparty-0.4.3/spec/fixtures/google.html | 3 + .../httparty-0.4.3/spec/fixtures/twitter.json | 1 + .../httparty-0.4.3/spec/fixtures/twitter.xml | 403 +++++ .../undefined_method_add_node_for_nil.xml | 2 + vendor/gems/httparty-0.4.3/spec/hash_spec.rb | 49 + .../spec/httparty/cookie_hash_spec.rb | 38 + .../spec/httparty/request_spec.rb | 196 ++ .../spec/httparty/response_spec.rb | 62 + .../gems/httparty-0.4.3/spec/httparty_spec.rb | 283 +++ vendor/gems/httparty-0.4.3/spec/spec.opts | 3 + .../gems/httparty-0.4.3/spec/spec_helper.rb | 21 + .../gems/httparty-0.4.3/spec/string_spec.rb | 27 + .../httparty-0.4.3/website/css/common.css | 47 + vendor/gems/httparty-0.4.3/website/index.html | 74 + 52 files changed, 4222 insertions(+), 1 deletion(-) create mode 100644 vendor/gems/httparty-0.4.3/.specification create mode 100644 vendor/gems/httparty-0.4.3/History create mode 100644 vendor/gems/httparty-0.4.3/MIT-LICENSE create mode 100644 vendor/gems/httparty-0.4.3/Manifest create mode 100644 vendor/gems/httparty-0.4.3/README create mode 100644 vendor/gems/httparty-0.4.3/Rakefile create mode 100755 vendor/gems/httparty-0.4.3/bin/httparty create mode 100644 vendor/gems/httparty-0.4.3/cucumber.yml create mode 100644 vendor/gems/httparty-0.4.3/examples/aaws.rb create mode 100644 vendor/gems/httparty-0.4.3/examples/basic.rb create mode 100644 vendor/gems/httparty-0.4.3/examples/delicious.rb create mode 100644 vendor/gems/httparty-0.4.3/examples/google.rb create mode 100644 vendor/gems/httparty-0.4.3/examples/rubyurl.rb create mode 100644 vendor/gems/httparty-0.4.3/examples/twitter.rb create mode 100644 vendor/gems/httparty-0.4.3/examples/whoismyrep.rb create mode 100644 vendor/gems/httparty-0.4.3/features/basic_authentication.feature create mode 100644 vendor/gems/httparty-0.4.3/features/command_line.feature create mode 100644 vendor/gems/httparty-0.4.3/features/deals_with_http_error_codes.feature create mode 100644 vendor/gems/httparty-0.4.3/features/handles_multiple_formats.feature create mode 100644 vendor/gems/httparty-0.4.3/features/steps/env.rb create mode 100644 vendor/gems/httparty-0.4.3/features/steps/httparty_response_steps.rb create mode 100644 vendor/gems/httparty-0.4.3/features/steps/httparty_steps.rb create mode 100644 vendor/gems/httparty-0.4.3/features/steps/mongrel_helper.rb create mode 100644 vendor/gems/httparty-0.4.3/features/steps/remote_service_steps.rb create mode 100644 vendor/gems/httparty-0.4.3/features/supports_redirection.feature create mode 100644 vendor/gems/httparty-0.4.3/httparty.gemspec create mode 100644 vendor/gems/httparty-0.4.3/lib/httparty.rb create mode 100644 vendor/gems/httparty-0.4.3/lib/httparty/cookie_hash.rb create mode 100644 vendor/gems/httparty-0.4.3/lib/httparty/core_extensions.rb create mode 100644 vendor/gems/httparty-0.4.3/lib/httparty/exceptions.rb create mode 100644 vendor/gems/httparty-0.4.3/lib/httparty/module_inheritable_attributes.rb create mode 100644 vendor/gems/httparty-0.4.3/lib/httparty/request.rb create mode 100644 vendor/gems/httparty-0.4.3/lib/httparty/response.rb create mode 100644 vendor/gems/httparty-0.4.3/lib/httparty/version.rb create mode 100644 vendor/gems/httparty-0.4.3/setup.rb create mode 100644 vendor/gems/httparty-0.4.3/spec/fixtures/delicious.xml create mode 100644 vendor/gems/httparty-0.4.3/spec/fixtures/empty.xml create mode 100644 vendor/gems/httparty-0.4.3/spec/fixtures/google.html create mode 100644 vendor/gems/httparty-0.4.3/spec/fixtures/twitter.json create mode 100644 vendor/gems/httparty-0.4.3/spec/fixtures/twitter.xml create mode 100644 vendor/gems/httparty-0.4.3/spec/fixtures/undefined_method_add_node_for_nil.xml create mode 100644 vendor/gems/httparty-0.4.3/spec/hash_spec.rb create mode 100644 vendor/gems/httparty-0.4.3/spec/httparty/cookie_hash_spec.rb create mode 100644 vendor/gems/httparty-0.4.3/spec/httparty/request_spec.rb create mode 100644 vendor/gems/httparty-0.4.3/spec/httparty/response_spec.rb create mode 100644 vendor/gems/httparty-0.4.3/spec/httparty_spec.rb create mode 100644 vendor/gems/httparty-0.4.3/spec/spec.opts create mode 100644 vendor/gems/httparty-0.4.3/spec/spec_helper.rb create mode 100644 vendor/gems/httparty-0.4.3/spec/string_spec.rb create mode 100644 vendor/gems/httparty-0.4.3/website/css/common.css create mode 100644 vendor/gems/httparty-0.4.3/website/index.html diff --git a/config/environment.rb b/config/environment.rb index 1efa926..25d86bb 100644 --- a/config/environment.rb +++ b/config/environment.rb @@ -28,7 +28,7 @@ # config.gem "sqlite3-ruby", :lib => "sqlite3" # config.gem "aws-s3", :lib => "aws/s3" # config.gem 'crack', :version => '0.1.4' - # config.gem 'httparty', :version => '0.4.4' + config.gem 'httparty', :version => '0.4.3' config.gem 'hashie', :version => '0.1.5' config.gem 'ruby-hmac', :lib => 'hmac', :version => '0.3.2' config.gem 'oauth', :version => '0.3.6' diff --git a/vendor/gems/httparty-0.4.3/.specification b/vendor/gems/httparty-0.4.3/.specification new file mode 100644 index 0000000..163d7ec --- /dev/null +++ b/vendor/gems/httparty-0.4.3/.specification @@ -0,0 +1,137 @@ +--- !ruby/object:Gem::Specification +name: httparty +version: !ruby/object:Gem::Version + version: 0.4.3 +platform: ruby +authors: +- John Nunemaker +autorequire: +bindir: bin +cert_chain: [] + +date: 2009-04-23 00:00:00 -04:00 +default_executable: httparty +dependencies: +- !ruby/object:Gem::Dependency + name: crack + type: :runtime + version_requirement: + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - ">=" + - !ruby/object:Gem::Version + version: 0.1.1 + version: +- !ruby/object:Gem::Dependency + name: echoe + type: :development + version_requirement: + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - ">=" + - !ruby/object:Gem::Version + version: "0" + version: +description: Makes http fun! Also, makes consuming restful web services dead easy. +email: nunemaker@gmail.com +executables: +- httparty +extensions: [] + +extra_rdoc_files: +- bin/httparty +- lib/httparty/cookie_hash.rb +- lib/httparty/core_extensions.rb +- lib/httparty/exceptions.rb +- lib/httparty/module_inheritable_attributes.rb +- lib/httparty/request.rb +- lib/httparty/response.rb +- lib/httparty/version.rb +- lib/httparty.rb +- README +files: +- bin/httparty +- cucumber.yml +- examples/aaws.rb +- examples/basic.rb +- examples/delicious.rb +- examples/google.rb +- examples/rubyurl.rb +- examples/twitter.rb +- examples/whoismyrep.rb +- features/basic_authentication.feature +- features/command_line.feature +- features/deals_with_http_error_codes.feature +- features/handles_multiple_formats.feature +- features/steps/env.rb +- features/steps/httparty_response_steps.rb +- features/steps/httparty_steps.rb +- features/steps/mongrel_helper.rb +- features/steps/remote_service_steps.rb +- features/supports_redirection.feature +- History +- httparty.gemspec +- lib/httparty/cookie_hash.rb +- lib/httparty/core_extensions.rb +- lib/httparty/exceptions.rb +- lib/httparty/module_inheritable_attributes.rb +- lib/httparty/request.rb +- lib/httparty/response.rb +- lib/httparty/version.rb +- lib/httparty.rb +- Manifest +- MIT-LICENSE +- Rakefile +- README +- setup.rb +- spec/fixtures/delicious.xml +- spec/fixtures/empty.xml +- spec/fixtures/google.html +- spec/fixtures/twitter.json +- spec/fixtures/twitter.xml +- spec/fixtures/undefined_method_add_node_for_nil.xml +- spec/hash_spec.rb +- spec/httparty/cookie_hash_spec.rb +- spec/httparty/request_spec.rb +- spec/httparty/response_spec.rb +- spec/httparty_spec.rb +- spec/spec.opts +- spec/spec_helper.rb +- spec/string_spec.rb +- website/css/common.css +- website/index.html +has_rdoc: true +homepage: http://httparty.rubyforge.org +licenses: [] + +post_install_message: When you HTTParty, you must party hard! +rdoc_options: +- --line-numbers +- --inline-source +- --title +- Httparty +- --main +- README +require_paths: +- lib +required_ruby_version: !ruby/object:Gem::Requirement + requirements: + - - ">=" + - !ruby/object:Gem::Version + version: "0" + version: +required_rubygems_version: !ruby/object:Gem::Requirement + requirements: + - - ">=" + - !ruby/object:Gem::Version + version: "1.2" + version: +requirements: [] + +rubyforge_project: httparty +rubygems_version: 1.3.5 +signing_key: +specification_version: 2 +summary: Makes http fun! Also, makes consuming restful web services dead easy. +test_files: [] + diff --git a/vendor/gems/httparty-0.4.3/History b/vendor/gems/httparty-0.4.3/History new file mode 100644 index 0000000..ddf987e --- /dev/null +++ b/vendor/gems/httparty-0.4.3/History @@ -0,0 +1,125 @@ +== 0.4.5 2009-04-23 +* 1 minor update + * added message to the response object + +== 0.4.2 2009-03-30 +* 2 minor changes + * response code now returns an integer instead of a string (jqr) + * rubyforge project setup for crack so i'm now depending on that instead of jnunemaker-crack + +== 0.4.1 2009-03-29 +* 1 minor fix + * gem 'jnunemaker-crack' instead of gem 'crack' + +== 0.4.0 2009-03-29 +* 1 minor change + * Switched xml and json parsing to crack (same code as before just moved to gem for easier reuse in other projects) + +== 0.3.1 2009-02-10 +* 1 minor fix, 1 minor enhancement + * Fixed unescaping umlauts (siebertm) + * Added yaml response parsing (Miha Filej) + +== 0.3.0 2009-01-31 +* 1 major enhancement, 1 bug fix + * JSON gem no longer a requirement. It was conflicting with rails json stuff so I just stole ActiveSupport's json decoding and bundled it with HTTParty. + * Fixed bug where query strings were being duplicated on redirects + * Added a bunch of specs and moved some code around. + +== 0.2.10 2009-01-29 +* 1 minor enhancement + * Made encoding on query parameters treat everything except URI::PATTERN::UNRESERVED as UNSAFE to force encoding of '+' character (Julian Russell) + +== 0.2.9 2009-01-29 +* 3 minor enhancements + * Added a 'headers' accessor to the response with a hash of any HTTP headers. (Don Peterson) + * Add support for a ":cookies" option to be used at the class level, or as an option on any individual call. It should be passed a hash, which will be converted to the proper format and added to the request headers when the call is made. (Don Peterson) + * Refactored several specs and added a full suite of cucumber features (Don Peterson) + +== 0.2.8 2009-01-28 +* 1 major fix + * fixed major bug with response where it wouldn't iterate or really work at all with parsed responses + +== 0.2.7 2009-01-28 +* 2 minor fixes, 2 minor enhancements, 2 major enhancements + * fixed undefined method add_node for nil class error that occasionally happened (juliocesar) + * Handle nil or unexpected values better when typecasting. (Brian Landau) + * More robust handling of mime types (Alex Vollmer) + * Fixed support for specifying headers and added support for basic auth to CLI. (Alex Vollmer) + * Added first class response object that includes original body and status code (Alex Vollmer) + * Now parsing all response types as some non-200 responses provide important information, this means no more exception raising (Alex Vollmer) + +== 0.2.6 2009-01-05 +* 1 minor bug fix + * added explicit require of time as Time#parse failed outside of rails (willcodeforfoo) + +== 0.2.5 2009-01-05 +* 1 major enhancement + * Add command line interface to HTTParty (Alex Vollmer) + +== 0.2.4 2008-12-23 +* 1 bug fix + * Fixed that mimetype detection was failing if no mimetype was returned from service (skippy) +== 0.2.3 2008-12-23 +* 1 bug fix + * Fixed typecasting class variable naming issue + +== 0.2.2 2008-12-08 +* 1 bug fix + * Added the missing core extension hash method to_xml_attributes + +== 0.2.1 2008-12-08 +* 1 bug fix + * Fixed that HTTParty was borking ActiveSupport and as such Rails (thanks to Rob Sanheim) + +== 0.2.0 2008-12-07 +* 1 major enhancement + * Removed ActiveSupport as a dependency. Now requires json gem for json deserialization and uses an included class to do the xml parsing. + +== 0.1.8 2008-11-30 +* 3 major enhancements + * Moved base_uri normalization into request class and out of httparty module, fixing + the problem where base_uri was not always being normalized. + * Stupid simple support for HTTParty.get/post/put/delete. (jqr) + * Switched gem management to Echoe from newgem. + +== 0.1.7 2008-11-30 +* 1 major enhancement + * fixed multiple class definitions overriding each others options + +== 0.1.6 2008-11-26 +* 1 major enhancement + * now passing :query to set_form_data if post request to avoid content length errors + +== 0.1.5 2008-11-14 +* 2 major enhancements + * Refactored send request method out into its own object. + * Added :html format if you just want to do that. + +== 0.1.4 2008-11-08 +* 3 major enhancements: + * Removed some cruft + * Added ability to follow redirects automatically and turn that off (Alex Vollmer) + +== 0.1.3 2008-08-22 + +* 3 major enhancements: + * Added http_proxy key for setting proxy server and port (francxk@gmail.com) + * Now raises exception when http error occurs (francxk@gmail.com) + * Changed auto format detection from file extension to response content type (Jay Pignata) + +== 0.1.2 2008-08-09 + +* 1 major enhancement: + * default_params were not being appended to query string if option[:query] was blank + +== 0.1.1 2008-07-30 + +* 2 major enhancement: + * Added :basic_auth key for options when making a request + * :query and :body both now work with query string or hash + +== 0.1.0 2008-07-27 + +* 1 major enhancement: + * Initial release diff --git a/vendor/gems/httparty-0.4.3/MIT-LICENSE b/vendor/gems/httparty-0.4.3/MIT-LICENSE new file mode 100644 index 0000000..ea4d340 --- /dev/null +++ b/vendor/gems/httparty-0.4.3/MIT-LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2008 John Nunemaker + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/vendor/gems/httparty-0.4.3/Manifest b/vendor/gems/httparty-0.4.3/Manifest new file mode 100644 index 0000000..deaccbf --- /dev/null +++ b/vendor/gems/httparty-0.4.3/Manifest @@ -0,0 +1,50 @@ +bin/httparty +cucumber.yml +examples/aaws.rb +examples/basic.rb +examples/delicious.rb +examples/google.rb +examples/rubyurl.rb +examples/twitter.rb +examples/whoismyrep.rb +features/basic_authentication.feature +features/command_line.feature +features/deals_with_http_error_codes.feature +features/handles_multiple_formats.feature +features/steps/env.rb +features/steps/httparty_response_steps.rb +features/steps/httparty_steps.rb +features/steps/mongrel_helper.rb +features/steps/remote_service_steps.rb +features/supports_redirection.feature +History +httparty.gemspec +lib/httparty/cookie_hash.rb +lib/httparty/core_extensions.rb +lib/httparty/exceptions.rb +lib/httparty/module_inheritable_attributes.rb +lib/httparty/request.rb +lib/httparty/response.rb +lib/httparty/version.rb +lib/httparty.rb +Manifest +MIT-LICENSE +Rakefile +README +setup.rb +spec/fixtures/delicious.xml +spec/fixtures/empty.xml +spec/fixtures/google.html +spec/fixtures/twitter.json +spec/fixtures/twitter.xml +spec/fixtures/undefined_method_add_node_for_nil.xml +spec/hash_spec.rb +spec/httparty/cookie_hash_spec.rb +spec/httparty/request_spec.rb +spec/httparty/response_spec.rb +spec/httparty_spec.rb +spec/spec.opts +spec/spec_helper.rb +spec/string_spec.rb +website/css/common.css +website/index.html diff --git a/vendor/gems/httparty-0.4.3/README b/vendor/gems/httparty-0.4.3/README new file mode 100644 index 0000000..2ec6d8e --- /dev/null +++ b/vendor/gems/httparty-0.4.3/README @@ -0,0 +1,36 @@ += httparty + +== DESCRIPTION: + +Makes http fun again! + +== FEATURES: + +* Easy get, post requests +* Basic http authentication +* Default request query string parameters (ie: for api keys that are needed on each request) +* Automatic parsing of JSON and XML into ruby hashes based on response content-type + +== EXAMPLES: + +See http://github.com/jnunemaker/httparty/tree/master/examples + +== COMMAND LINE INTERFACE + +httparty also includes the executable httparty which can be +used to query web services and examine the resulting output. By default +it will output the response as a pretty-printed Ruby object (useful for +grokking the structure of output). This can also be overridden to output +formatted XML or JSON. Execute httparty --help for all the +options. Below is an example of how easy it is. + + httparty "http://twitter.com/statuses/public_timeline.json" + +== REQUIREMENTS: + +* Crack http://github.com/jnunemaker/crack/ - For XML and JSON parsing. +* You like to party! + +== INSTALL: + +* sudo gem install httparty \ No newline at end of file diff --git a/vendor/gems/httparty-0.4.3/Rakefile b/vendor/gems/httparty-0.4.3/Rakefile new file mode 100644 index 0000000..6580830 --- /dev/null +++ b/vendor/gems/httparty-0.4.3/Rakefile @@ -0,0 +1,48 @@ +ProjectName = 'httparty' +WebsitePath = "jnunemaker@rubyforge.org:/var/www/gforge-projects/#{ProjectName}" + +require 'rubygems' +require 'rake' +require 'echoe' +require 'spec/rake/spectask' +require "lib/#{ProjectName}/version" +require 'cucumber/rake/task' + +Echoe.new(ProjectName, HTTParty::Version) do |p| + p.description = "Makes http fun! Also, makes consuming restful web services dead easy." + p.install_message = "When you HTTParty, you must party hard!" + p.url = "http://#{ProjectName}.rubyforge.org" + p.author = "John Nunemaker" + p.email = "nunemaker@gmail.com" + p.extra_deps = [['crack', '>= 0.1.1']] + p.need_tar_gz = false + p.docs_host = WebsitePath +end + +desc 'Upload website files to rubyforge' +task :website do + sh %{rsync -av website/ #{WebsitePath}} + Rake::Task['website_docs'].invoke +end + +task :website_docs do + Rake::Task['redocs'].invoke + sh %{rsync -av doc/ #{WebsitePath}/docs} +end + +desc 'Preps the gem for a new release' +task :prepare do + %w[manifest build_gemspec].each do |task| + Rake::Task[task].invoke + end +end + +Rake::Task[:default].prerequisites.clear +task :default => :spec +Spec::Rake::SpecTask.new do |t| + t.spec_files = FileList["spec/**/*_spec.rb"] +end + +Cucumber::Rake::Task.new(:features) do |t| + t.cucumber_opts = "--format pretty" +end diff --git a/vendor/gems/httparty-0.4.3/bin/httparty b/vendor/gems/httparty-0.4.3/bin/httparty new file mode 100755 index 0000000..729cc8a --- /dev/null +++ b/vendor/gems/httparty-0.4.3/bin/httparty @@ -0,0 +1,98 @@ +#!/usr/bin/env ruby + +require "optparse" +require "pp" + +$:.unshift(File.join(File.dirname(__FILE__), "/../lib")) +require "httparty" + +opts = { + :action => :get, + :headers => {}, + :verbose => false +} + +def die(msg) + STDERR.puts(msg) + exit 1 +end + +OptionParser.new do |o| + o.banner = "USAGE: #{$0} [options] [url]" + + o.on("-f", + "--format [FORMAT]", + "Output format to use instead of pretty-print ruby: " + + "plain, json or xml") do |f| + opts[:output_format] = f.downcase.to_sym + end + + o.on("-a", + "--action [ACTION]", + "HTTP action: get (default), post, put or delete") do |a| + opts[:action] = a.downcase.to_sym + end + + o.on("-d", + "--data [BODY]", + "Data to put in request body (prefix with '@' for file)") do |d| + if d =~ /^@/ + opts[:data] = open(d).read + else + opts[:data] = d + end + end + + o.on("-H", "--header [NAME=VALUE]", "Additional HTTP headers in NAME=VALUE form") do |h| + die "Invalid header specification, should be Name:Value" unless h =~ /.+:.+/ + name, value = h.split(':') + opts[:headers][name.strip] = value.strip + end + + o.on("-v", "--verbose", "If set, print verbose output") do |v| + opts[:verbose] = true + end + + o.on("-u", "--user [CREDS]", "Use basic authentication. Value should be user:password") do |u| + die "Invalid credentials format. Must be user:password" unless u =~ /.+:.+/ + user, password = u.split(':') + opts[:basic_auth] = { :username => user, :password => password } + end + + o.on("-h", "--help", "Show help documentation") do |h| + puts o + exit + end +end.parse! + +puts "Querying #{ARGV.first} with options: #{opts.inspect}" if opts[:verbose] + +if ARGV.empty? + STDERR.puts "You need to provide a URL" + STDERR.puts "USAGE: #{$0} [options] [url]" +end + +if opts[:output_format].nil? + response = HTTParty.send(opts[:action], ARGV.first, opts) + puts "Status: #{response.code}" + pp response +else + print_format = opts[:output_format] + response = HTTParty.send(opts[:action], ARGV.first, opts) + puts "Status: #{response.code}" + case opts[:output_format] + when :json + begin + require 'rubygems' + require 'json' + puts JSON.pretty_generate(response.delegate) + rescue LoadError + puts YAML.dump(response.delegate) + end + when :xml + REXML::Document.new(response.body).write(STDOUT, 2) + puts + else + puts response + end +end \ No newline at end of file diff --git a/vendor/gems/httparty-0.4.3/cucumber.yml b/vendor/gems/httparty-0.4.3/cucumber.yml new file mode 100644 index 0000000..c1869b5 --- /dev/null +++ b/vendor/gems/httparty-0.4.3/cucumber.yml @@ -0,0 +1 @@ +default: features diff --git a/vendor/gems/httparty-0.4.3/examples/aaws.rb b/vendor/gems/httparty-0.4.3/examples/aaws.rb new file mode 100644 index 0000000..3389d11 --- /dev/null +++ b/vendor/gems/httparty-0.4.3/examples/aaws.rb @@ -0,0 +1,32 @@ +require 'rubygems' +require 'activesupport' + +dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')) +require File.join(dir, 'httparty') +require 'pp' +config = YAML::load(File.read(File.join(ENV['HOME'], '.aaws'))) + +module AAWS + class Book + include HTTParty + base_uri 'http://ecs.amazonaws.com' + default_params :Service => 'AWSECommerceService', :Operation => 'ItemSearch', :SearchIndex => 'Books' + + def initialize(key) + self.class.default_params :AWSAccessKeyId => key + end + + def search(options={}) + raise ArgumentError, 'You must search for something' if options[:query].blank? + + # amazon uses nasty camelized query params + options[:query] = options[:query].inject({}) { |h, q| h[q[0].to_s.camelize] = q[1]; h } + + # make a request and return the items (NOTE: this doesn't handle errors at this point) + self.class.get('/onca/xml', options)['ItemSearchResponse']['Items'] + end + end +end + +aaws = AAWS::Book.new(config[:access_key]) +pp aaws.search(:query => {:title => 'Ruby On Rails'}) \ No newline at end of file diff --git a/vendor/gems/httparty-0.4.3/examples/basic.rb b/vendor/gems/httparty-0.4.3/examples/basic.rb new file mode 100644 index 0000000..767589b --- /dev/null +++ b/vendor/gems/httparty-0.4.3/examples/basic.rb @@ -0,0 +1,11 @@ +dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')) +require File.join(dir, 'httparty') +require 'pp' + +# You can also use post, put, delete in the same fashion +response = HTTParty.get('http://twitter.com/statuses/public_timeline.json') +puts response.body, response.code, response.message, response.headers.inspect + +response.each do |item| + puts item['user']['screen_name'] +end diff --git a/vendor/gems/httparty-0.4.3/examples/delicious.rb b/vendor/gems/httparty-0.4.3/examples/delicious.rb new file mode 100644 index 0000000..e6d6243 --- /dev/null +++ b/vendor/gems/httparty-0.4.3/examples/delicious.rb @@ -0,0 +1,37 @@ +dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')) +require File.join(dir, 'httparty') +require 'pp' +config = YAML::load(File.read(File.join(ENV['HOME'], '.delicious'))) + +class Delicious + include HTTParty + base_uri 'https://api.del.icio.us/v1' + + def initialize(u, p) + @auth = {:username => u, :password => p} + end + + # query params that filter the posts are: + # tag (optional). Filter by this tag. + # dt (optional). Filter by this date (CCYY-MM-DDThh:mm:ssZ). + # url (optional). Filter by this url. + # ie: posts(:query => {:tag => 'ruby'}) + def posts(options={}) + options.merge!({:basic_auth => @auth}) + self.class.get('/posts/get', options) + end + + # query params that filter the posts are: + # tag (optional). Filter by this tag. + # count (optional). Number of items to retrieve (Default:15, Maximum:100). + def recent(options={}) + options.merge!({:basic_auth => @auth}) + self.class.get('/posts/recent', options) + end +end + +delicious = Delicious.new(config['username'], config['password']) +pp delicious.posts(:query => {:tag => 'ruby'}) +pp delicious.recent + +delicious.recent['posts']['post'].each { |post| puts post['href'] } \ No newline at end of file diff --git a/vendor/gems/httparty-0.4.3/examples/google.rb b/vendor/gems/httparty-0.4.3/examples/google.rb new file mode 100644 index 0000000..f629b4d --- /dev/null +++ b/vendor/gems/httparty-0.4.3/examples/google.rb @@ -0,0 +1,16 @@ +dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')) +require File.join(dir, 'httparty') +require 'pp' + +class Google + include HTTParty + format :html +end + +# google.com redirects to www.google.com so this is live test for redirection +pp Google.get('http://google.com') + +puts '', '*'*70, '' + +# check that ssl is requesting right +pp Google.get('https://www.google.com') \ No newline at end of file diff --git a/vendor/gems/httparty-0.4.3/examples/rubyurl.rb b/vendor/gems/httparty-0.4.3/examples/rubyurl.rb new file mode 100644 index 0000000..65808fb --- /dev/null +++ b/vendor/gems/httparty-0.4.3/examples/rubyurl.rb @@ -0,0 +1,14 @@ +dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')) +require File.join(dir, 'httparty') +require 'pp' + +class Rubyurl + include HTTParty + base_uri 'rubyurl.com' + + def self.shorten( website_url ) + post( '/api/links.json', :query => { :link => { :website_url => website_url } } ) + end +end + +pp Rubyurl.shorten( 'http://istwitterdown.com/') \ No newline at end of file diff --git a/vendor/gems/httparty-0.4.3/examples/twitter.rb b/vendor/gems/httparty-0.4.3/examples/twitter.rb new file mode 100644 index 0000000..c7794fa --- /dev/null +++ b/vendor/gems/httparty-0.4.3/examples/twitter.rb @@ -0,0 +1,31 @@ +dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')) +require File.join(dir, 'httparty') +require 'pp' +config = YAML::load(File.read(File.join(ENV['HOME'], '.twitter'))) + +class Twitter + include HTTParty + base_uri 'twitter.com' + + def initialize(u, p) + @auth = {:username => u, :password => p} + end + + # which can be :friends, :user or :public + # options[:query] can be things like since, since_id, count, etc. + def timeline(which=:friends, options={}) + options.merge!({:basic_auth => @auth}) + self.class.get("/statuses/#{which}_timeline.json", options) + end + + def post(text) + options = { :query => {:status => text}, :basic_auth => @auth } + self.class.post('/statuses/update.json', options) + end +end + +twitter = Twitter.new(config['email'], config['password']) +pp twitter.timeline +# pp twitter.timeline(:friends, :query => {:since_id => 868482746}) +# pp twitter.timeline(:friends, :query => 'since_id=868482746') +# pp twitter.post('this is a test of 0.2.0') \ No newline at end of file diff --git a/vendor/gems/httparty-0.4.3/examples/whoismyrep.rb b/vendor/gems/httparty-0.4.3/examples/whoismyrep.rb new file mode 100644 index 0000000..b59473c --- /dev/null +++ b/vendor/gems/httparty-0.4.3/examples/whoismyrep.rb @@ -0,0 +1,10 @@ +dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')) +require File.join(dir, 'httparty') +require 'pp' + +class Rep + include HTTParty +end + +pp Rep.get('http://whoismyrepresentative.com/whoismyrep.php?zip=46544') +pp Rep.get('http://whoismyrepresentative.com/whoismyrep.php', :query => {:zip => 46544}) \ No newline at end of file diff --git a/vendor/gems/httparty-0.4.3/features/basic_authentication.feature b/vendor/gems/httparty-0.4.3/features/basic_authentication.feature new file mode 100644 index 0000000..ee27650 --- /dev/null +++ b/vendor/gems/httparty-0.4.3/features/basic_authentication.feature @@ -0,0 +1,20 @@ +Feature: Basic Authentication + + As a developer + I want to be able to use a service that requires Basic Authentication + Because that is not an uncommon requirement + + Scenario: Passing no credentials to a page requiring Basic Authentication + Given a restricted page at '/protected.html' + When I call HTTParty#get with '/protected.html' + Then it should return a response with a 401 response code + + Scenario: Passing proper credentials to a page requiring Basic Authentication + Given a remote service that returns 'Authenticated Page' + And that service is accessed at the path '/protected.html' + And that service is protected by Basic Authentication + And that service requires the username 'jcash' with the password 'maninblack' + When I call HTTParty#get with '/protected.html' and a basic_auth hash: + | username | password | + | jcash | maninblack | + Then the return value should match 'Authenticated Page' diff --git a/vendor/gems/httparty-0.4.3/features/command_line.feature b/vendor/gems/httparty-0.4.3/features/command_line.feature new file mode 100644 index 0000000..951e236 --- /dev/null +++ b/vendor/gems/httparty-0.4.3/features/command_line.feature @@ -0,0 +1,7 @@ +Feature: Command Line + + As a developer + I want to be able to harness the power of HTTParty from the command line + Because that would make quick testing and debugging easy + And 'easy' is my middle name + And I'm kidding it's actually 'Danger'! diff --git a/vendor/gems/httparty-0.4.3/features/deals_with_http_error_codes.feature b/vendor/gems/httparty-0.4.3/features/deals_with_http_error_codes.feature new file mode 100644 index 0000000..ccb9912 --- /dev/null +++ b/vendor/gems/httparty-0.4.3/features/deals_with_http_error_codes.feature @@ -0,0 +1,26 @@ +Feature: Deals with HTTP error codes + + As a developer + I want to be informed of non-successful responses + Because sometimes thing explode + And I should probably know what happened + + Scenario: A response of '404 - Not Found' + Given a remote service that returns a 404 status code + And that service is accessed at the path '/service.html' + When I call HTTParty#get with '/service.html' + Then it should return a response with a 404 response code + + Scenario: A response of '500 - Internal Server Error' + Given a remote service that returns a 500 status code + And that service is accessed at the path '/service.html' + When I call HTTParty#get with '/service.html' + Then it should return a response with a 500 response code + + Scenario: A non-successful response where I need the body + Given a remote service that returns a 400 status code + And the response from the service has a body of 'Bad response' + And that service is accessed at the path '/service.html' + When I call HTTParty#get with '/service.html' + Then it should return a response with a 400 response code + And the return value should match 'Bad response' diff --git a/vendor/gems/httparty-0.4.3/features/handles_multiple_formats.feature b/vendor/gems/httparty-0.4.3/features/handles_multiple_formats.feature new file mode 100644 index 0000000..24c91fa --- /dev/null +++ b/vendor/gems/httparty-0.4.3/features/handles_multiple_formats.feature @@ -0,0 +1,34 @@ +Feature: Handles Multiple Formats + + As a developer + I want to be able to consume remote services of many different formats + And I want those formats to be automatically detected and handled + Because web services take many forms + And I don't want to have to do any extra work + + Scenario: An HTML service + Given a remote service that returns '

Some HTML

' + And that service is accessed at the path '/service.html' + And the response from the service has a Content-Type of 'text/html' + When I call HTTParty#get with '/service.html' + Then it should return a String + And the return value should match '

Some HTML

' + + Scenario: A JSON service + Given a remote service that returns '{ "jennings": "waylon", "cash": "johnny" }' + And that service is accessed at the path '/service.json' + And the response from the service has a Content-Type of 'application/json' + When I call HTTParty#get with '/service.json' + Then it should return a Hash equaling: + | key | value | + | jennings | waylon | + | cash | johnny | + + Scenario: An XML Service + Given a remote service that returns 'waylon jennings' + And that service is accessed at the path '/service.xml' + And the response from the service has a Content-Type of 'text/xml' + When I call HTTParty#get with '/service.xml' + Then it should return a Hash equaling: + | key | value | + | singer | waylon jennings | diff --git a/vendor/gems/httparty-0.4.3/features/steps/env.rb b/vendor/gems/httparty-0.4.3/features/steps/env.rb new file mode 100644 index 0000000..b85c79a --- /dev/null +++ b/vendor/gems/httparty-0.4.3/features/steps/env.rb @@ -0,0 +1,15 @@ +require 'mongrel' +require 'activesupport' +require 'lib/httparty' +require 'spec/expectations' + +Before do + port = ENV["HTTPARTY_PORT"] || 31981 + @host_and_port = "0.0.0.0:#{port}" + @server = Mongrel::HttpServer.new("0.0.0.0", port) + @server.run +end + +After do + @server.stop +end diff --git a/vendor/gems/httparty-0.4.3/features/steps/httparty_response_steps.rb b/vendor/gems/httparty-0.4.3/features/steps/httparty_response_steps.rb new file mode 100644 index 0000000..f210cc6 --- /dev/null +++ b/vendor/gems/httparty-0.4.3/features/steps/httparty_response_steps.rb @@ -0,0 +1,26 @@ +Then /it should return an? (\w+)$/ do |class_string| + @response_from_httparty.should be_an_instance_of(class_string.constantize) +end + +Then /the return value should match '(.*)'/ do |expected_text| + @response_from_httparty.should eql(expected_text) +end + +Then /it should return a Hash equaling:/ do |hash_table| + @response_from_httparty.should be_an_instance_of(Hash) + @response_from_httparty.keys.length.should eql(hash_table.rows.length) + hash_table.hashes.each do |pair| + key, value = pair["key"], pair["value"] + @response_from_httparty.keys.should include(key) + @response_from_httparty[key].should eql(value) + end +end + +Then /it should return a response with a (\d+) response code/ do |code| + @response_from_httparty.code.should eql(code.to_i) +end + +Then /it should raise an HTTParty::RedirectionTooDeep exception/ do + @exception_from_httparty.should_not be_nil + @exception_from_httparty.class.should eql(HTTParty::RedirectionTooDeep) +end diff --git a/vendor/gems/httparty-0.4.3/features/steps/httparty_steps.rb b/vendor/gems/httparty-0.4.3/features/steps/httparty_steps.rb new file mode 100644 index 0000000..17c63dd --- /dev/null +++ b/vendor/gems/httparty-0.4.3/features/steps/httparty_steps.rb @@ -0,0 +1,15 @@ +When /I call HTTParty#get with '(.*)'$/ do |url| + begin + @response_from_httparty = HTTParty.get("http://#{@host_and_port}#{url}") + rescue HTTParty::RedirectionTooDeep => e + @exception_from_httparty = e + end +end + +When /I call HTTParty#get with '(.*)' and a basic_auth hash:/ do |url, auth_table| + h = auth_table.hashes.first + @response_from_httparty = HTTParty.get( + "http://#{@host_and_port}#{url}", + :basic_auth => { :username => h["username"], :password => h["password"] } + ) +end diff --git a/vendor/gems/httparty-0.4.3/features/steps/mongrel_helper.rb b/vendor/gems/httparty-0.4.3/features/steps/mongrel_helper.rb new file mode 100644 index 0000000..3b78248 --- /dev/null +++ b/vendor/gems/httparty-0.4.3/features/steps/mongrel_helper.rb @@ -0,0 +1,55 @@ +def basic_mongrel_handler + Class.new(Mongrel::HttpHandler) do + attr_writer :content_type, :response_body, :response_code + + def initialize + @content_type = "text/html" + @response_body = "" + @response_code = 200 + @custom_headers = {} + end + + def process(request, response) + reply_with(response, @response_code, @response_body) + end + + def reply_with(response, code, response_body) + response.start(code) do |head, body| + head["Content-Type"] = @content_type + @custom_headers.each { |k,v| head[k] = v } + body.write(response_body) + end + end + end +end + +def new_mongrel_handler + basic_mongrel_handler.new +end + +def add_basic_authentication_to(handler) + m = Module.new do + attr_writer :username, :password + + def self.extended(base) + base.instance_eval { @custom_headers["WWW-Authenticate"] = 'Basic Realm="Super Secret Page"' } + base.class_eval { alias_method_chain :process, :basic_authentication } + end + + def process_with_basic_authentication(request, response) + if authorized?(request) then process_without_basic_authentication(request, response) + else reply_with(response, 401, "Incorrect. You have 20 seconds to comply.") + end + end + + def authorized?(request) + request.params["HTTP_AUTHORIZATION"] == "Basic " + Base64.encode64("#{@username}:#{@password}").strip + end + end + handler.extend(m) +end + +def new_mongrel_redirector(target_url, relative_path = false) + target_url = "http://#{@host_and_port}#{target_url}" unless relative_path + Mongrel::RedirectHandler.new(target_url) +end diff --git a/vendor/gems/httparty-0.4.3/features/steps/remote_service_steps.rb b/vendor/gems/httparty-0.4.3/features/steps/remote_service_steps.rb new file mode 100644 index 0000000..08e205c --- /dev/null +++ b/vendor/gems/httparty-0.4.3/features/steps/remote_service_steps.rb @@ -0,0 +1,47 @@ +Given /a remote service that returns '(.*)'/ do |response_body| + @handler = new_mongrel_handler + Given "the response from the service has a body of '#{response_body}'" +end + +Given /a remote service that returns a (\d+) status code/ do |code| + @handler = new_mongrel_handler + @handler.response_code = code +end + +Given /that service is accessed at the path '(.*)'/ do |path| + @server.register(path, @handler) +end + +Given /the response from the service has a Content-Type of '(.*)'/ do |content_type| + @handler.content_type = content_type +end + +Given /the response from the service has a body of '(.*)'/ do |response_body| + @handler.response_body = response_body +end + +Given /the url '(.*)' redirects to '(.*)'/ do |redirection_url, target_url| + @server.register redirection_url, new_mongrel_redirector(target_url) +end + +Given /that service is protected by Basic Authentication/ do + add_basic_authentication_to @handler +end + +Given /that service requires the username '(.*)' with the password '(.*)'/ do |username, password| + @handler.username = username + @handler.password = password +end + +Given /a restricted page at '(.*)'/ do |url| + Given "a remote service that returns 'A response I will never see'" + And "that service is accessed at the path '#{url}'" + And "that service is protected by Basic Authentication" + And "that service requires the username 'something' with the password 'secret'" +end + +# This joins the server thread, and halts cucumber, so you can actually hit the +# server with a browser. Runs until you kill it with Ctrl-c +Given /I want to hit this in a browser/ do + @server.acceptor.join +end diff --git a/vendor/gems/httparty-0.4.3/features/supports_redirection.feature b/vendor/gems/httparty-0.4.3/features/supports_redirection.feature new file mode 100644 index 0000000..1c1deef --- /dev/null +++ b/vendor/gems/httparty-0.4.3/features/supports_redirection.feature @@ -0,0 +1,22 @@ +Feature: Supports Redirection + + As a developer + I want to work with services that may redirect me + And I want it to follow a reasonable number of redirects + Because sometimes web services do that + + Scenario: A service that redirects once + Given a remote service that returns 'Service Response' + And that service is accessed at the path '/service.html' + And the url '/redirector.html' redirects to '/service.html' + When I call HTTParty#get with '/redirector.html' + Then the return value should match 'Service Response' + + # TODO: Look in to why this actually fails... + Scenario: A service that redirects to a relative URL + + Scenario: A service that redirects infinitely + Given the url '/first.html' redirects to '/second.html' + And the url '/second.html' redirects to '/first.html' + When I call HTTParty#get with '/first.html' + Then it should raise an HTTParty::RedirectionTooDeep exception diff --git a/vendor/gems/httparty-0.4.3/httparty.gemspec b/vendor/gems/httparty-0.4.3/httparty.gemspec new file mode 100644 index 0000000..d45a8f9 --- /dev/null +++ b/vendor/gems/httparty-0.4.3/httparty.gemspec @@ -0,0 +1,40 @@ +# -*- encoding: utf-8 -*- + +Gem::Specification.new do |s| + s.name = %q{httparty} + s.version = "0.4.3" + + s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version= + s.authors = ["John Nunemaker"] + s.date = %q{2009-04-23} + s.default_executable = %q{httparty} + s.description = %q{Makes http fun! Also, makes consuming restful web services dead easy.} + s.email = %q{nunemaker@gmail.com} + s.executables = ["httparty"] + s.extra_rdoc_files = ["bin/httparty", "lib/httparty/cookie_hash.rb", "lib/httparty/core_extensions.rb", "lib/httparty/exceptions.rb", "lib/httparty/module_inheritable_attributes.rb", "lib/httparty/request.rb", "lib/httparty/response.rb", "lib/httparty/version.rb", "lib/httparty.rb", "README"] + s.files = ["bin/httparty", "cucumber.yml", "examples/aaws.rb", "examples/basic.rb", "examples/delicious.rb", "examples/google.rb", "examples/rubyurl.rb", "examples/twitter.rb", "examples/whoismyrep.rb", "features/basic_authentication.feature", "features/command_line.feature", "features/deals_with_http_error_codes.feature", "features/handles_multiple_formats.feature", "features/steps/env.rb", "features/steps/httparty_response_steps.rb", "features/steps/httparty_steps.rb", "features/steps/mongrel_helper.rb", "features/steps/remote_service_steps.rb", "features/supports_redirection.feature", "History", "httparty.gemspec", "lib/httparty/cookie_hash.rb", "lib/httparty/core_extensions.rb", "lib/httparty/exceptions.rb", "lib/httparty/module_inheritable_attributes.rb", "lib/httparty/request.rb", "lib/httparty/response.rb", "lib/httparty/version.rb", "lib/httparty.rb", "Manifest", "MIT-LICENSE", "Rakefile", "README", "setup.rb", "spec/fixtures/delicious.xml", "spec/fixtures/empty.xml", "spec/fixtures/google.html", "spec/fixtures/twitter.json", "spec/fixtures/twitter.xml", "spec/fixtures/undefined_method_add_node_for_nil.xml", "spec/hash_spec.rb", "spec/httparty/cookie_hash_spec.rb", "spec/httparty/request_spec.rb", "spec/httparty/response_spec.rb", "spec/httparty_spec.rb", "spec/spec.opts", "spec/spec_helper.rb", "spec/string_spec.rb", "website/css/common.css", "website/index.html"] + s.has_rdoc = true + s.homepage = %q{http://httparty.rubyforge.org} + s.post_install_message = %q{When you HTTParty, you must party hard!} + s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Httparty", "--main", "README"] + s.require_paths = ["lib"] + s.rubyforge_project = %q{httparty} + s.rubygems_version = %q{1.3.1} + s.summary = %q{Makes http fun! Also, makes consuming restful web services dead easy.} + + if s.respond_to? :specification_version then + current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION + s.specification_version = 2 + + if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then + s.add_runtime_dependency(%q, [">= 0.1.1"]) + s.add_development_dependency(%q, [">= 0"]) + else + s.add_dependency(%q, [">= 0.1.1"]) + s.add_dependency(%q, [">= 0"]) + end + else + s.add_dependency(%q, [">= 0.1.1"]) + s.add_dependency(%q, [">= 0"]) + end +end diff --git a/vendor/gems/httparty-0.4.3/lib/httparty.rb b/vendor/gems/httparty-0.4.3/lib/httparty.rb new file mode 100644 index 0000000..362df86 --- /dev/null +++ b/vendor/gems/httparty-0.4.3/lib/httparty.rb @@ -0,0 +1,205 @@ +$:.unshift(File.dirname(__FILE__)) + +require 'net/http' +require 'net/https' +require 'httparty/module_inheritable_attributes' +require 'rubygems' +gem 'crack' +require 'crack' + +module HTTParty + + AllowedFormats = { + 'text/xml' => :xml, + 'application/xml' => :xml, + 'application/json' => :json, + 'text/json' => :json, + 'application/javascript' => :json, + 'text/javascript' => :json, + 'text/html' => :html, + 'application/x-yaml' => :yaml, + 'text/yaml' => :yaml, + 'text/plain' => :plain + } unless defined?(AllowedFormats) + + def self.included(base) + base.extend ClassMethods + base.send :include, HTTParty::ModuleInheritableAttributes + base.send(:mattr_inheritable, :default_options) + base.instance_variable_set("@default_options", {}) + end + + module ClassMethods + # Allows setting http proxy information to be used + # + # class Foo + # include HTTParty + # http_proxy 'http://foo.com', 80 + # end + def http_proxy(addr=nil, port = nil) + default_options[:http_proxyaddr] = addr + default_options[:http_proxyport] = port + end + + # Allows setting a base uri to be used for each request. + # Will normalize uri to include http, etc. + # + # class Foo + # include HTTParty + # base_uri 'twitter.com' + # end + def base_uri(uri=nil) + return default_options[:base_uri] unless uri + default_options[:base_uri] = HTTParty.normalize_base_uri(uri) + end + + # Allows setting basic authentication username and password. + # + # class Foo + # include HTTParty + # basic_auth 'username', 'password' + # end + def basic_auth(u, p) + default_options[:basic_auth] = {:username => u, :password => p} + end + + # Allows setting default parameters to be appended to each request. + # Great for api keys and such. + # + # class Foo + # include HTTParty + # default_params :api_key => 'secret', :another => 'foo' + # end + def default_params(h={}) + raise ArgumentError, 'Default params must be a hash' unless h.is_a?(Hash) + default_options[:default_params] ||= {} + default_options[:default_params].merge!(h) + end + + # Allows setting a base uri to be used for each request. + # + # class Foo + # include HTTParty + # headers 'Accept' => 'text/html' + # end + def headers(h={}) + raise ArgumentError, 'Headers must be a hash' unless h.is_a?(Hash) + default_options[:headers] ||= {} + default_options[:headers].merge!(h) + end + + def cookies(h={}) + raise ArgumentError, 'Cookies must be a hash' unless h.is_a?(Hash) + default_options[:cookies] ||= CookieHash.new + default_options[:cookies].add_cookies(h) + end + + # Allows setting the format with which to parse. + # Must be one of the allowed formats ie: json, xml + # + # class Foo + # include HTTParty + # format :json + # end + def format(f) + raise UnsupportedFormat, "Must be one of: #{AllowedFormats.values.uniq.join(', ')}" unless AllowedFormats.value?(f) + default_options[:format] = f + end + + # Allows making a get request to a url. + # + # class Foo + # include HTTParty + # end + # + # # Simple get with full url + # Foo.get('http://foo.com/resource.json') + # + # # Simple get with full url and query parameters + # # ie: http://foo.com/resource.json?limit=10 + # Foo.get('http://foo.com/resource.json', :query => {:limit => 10}) + def get(path, options={}) + perform_request Net::HTTP::Get, path, options + end + + # Allows making a post request to a url. + # + # class Foo + # include HTTParty + # end + # + # # Simple post with full url and setting the body + # Foo.post('http://foo.com/resources', :body => {:bar => 'baz'}) + # + # # Simple post with full url using :query option, + # # which gets set as form data on the request. + # Foo.post('http://foo.com/resources', :query => {:bar => 'baz'}) + def post(path, options={}) + perform_request Net::HTTP::Post, path, options + end + + def put(path, options={}) + perform_request Net::HTTP::Put, path, options + end + + def delete(path, options={}) + perform_request Net::HTTP::Delete, path, options + end + + def default_options #:nodoc: + @default_options + end + + private + def perform_request(http_method, path, options) #:nodoc: + process_cookies(options) + Request.new(http_method, path, default_options.dup.merge(options)).perform + end + + def process_cookies(options) #:nodoc: + return unless options[:cookies] || default_options[:cookies] + options[:headers] ||= {} + options[:headers]["cookie"] = cookies(options[:cookies] || {}).to_cookie_string + + default_options.delete(:cookies) + options.delete(:cookies) + end + end + + def self.normalize_base_uri(url) #:nodoc: + normalized_url = url.dup + use_ssl = (normalized_url =~ /^https/) || normalized_url.include?(':443') + ends_with_slash = normalized_url =~ /\/$/ + + normalized_url.chop! if ends_with_slash + normalized_url.gsub!(/^https?:\/\//i, '') + + "http#{'s' if use_ssl}://#{normalized_url}" + end + + class Basement #:nodoc: + include HTTParty + end + + def self.get(*args) + Basement.get(*args) + end + + def self.post(*args) + Basement.post(*args) + end + + def self.put(*args) + Basement.put(*args) + end + + def self.delete(*args) + Basement.delete(*args) + end +end + +require 'httparty/cookie_hash' +require 'httparty/core_extensions' +require 'httparty/exceptions' +require 'httparty/request' +require 'httparty/response' diff --git a/vendor/gems/httparty-0.4.3/lib/httparty/cookie_hash.rb b/vendor/gems/httparty-0.4.3/lib/httparty/cookie_hash.rb new file mode 100644 index 0000000..cf18bd7 --- /dev/null +++ b/vendor/gems/httparty-0.4.3/lib/httparty/cookie_hash.rb @@ -0,0 +1,9 @@ +class HTTParty::CookieHash < Hash #:nodoc: + def add_cookies(hash) + merge!(hash) + end + + def to_cookie_string + collect { |k, v| "#{k}=#{v}" }.join("; ") + end +end diff --git a/vendor/gems/httparty-0.4.3/lib/httparty/core_extensions.rb b/vendor/gems/httparty-0.4.3/lib/httparty/core_extensions.rb new file mode 100644 index 0000000..ad10497 --- /dev/null +++ b/vendor/gems/httparty-0.4.3/lib/httparty/core_extensions.rb @@ -0,0 +1,25 @@ +class BlankSlate #:nodoc: + instance_methods.each { |m| undef_method m unless m =~ /^__/ } +end + +# 1.8.6 has mistyping of transitive in if statement +require "rexml/document" +module REXML #:nodoc: + class Document < Element #:nodoc: + def write( output=$stdout, indent=-1, transitive=false, ie_hack=false ) + if xml_decl.encoding != "UTF-8" && !output.kind_of?(Output) + output = Output.new( output, xml_decl.encoding ) + end + formatter = if indent > -1 + if transitive + REXML::Formatters::Transitive.new( indent, ie_hack ) + else + REXML::Formatters::Pretty.new( indent, ie_hack ) + end + else + REXML::Formatters::Default.new( ie_hack ) + end + formatter.write( self, output ) + end + end +end diff --git a/vendor/gems/httparty-0.4.3/lib/httparty/exceptions.rb b/vendor/gems/httparty-0.4.3/lib/httparty/exceptions.rb new file mode 100644 index 0000000..423f989 --- /dev/null +++ b/vendor/gems/httparty-0.4.3/lib/httparty/exceptions.rb @@ -0,0 +1,7 @@ +module HTTParty + # Exception raised when you attempt to set a non-existant format + class UnsupportedFormat < StandardError; end + + # Exception that is raised when request has redirected too many times + class RedirectionTooDeep < StandardError; end +end \ No newline at end of file diff --git a/vendor/gems/httparty-0.4.3/lib/httparty/module_inheritable_attributes.rb b/vendor/gems/httparty-0.4.3/lib/httparty/module_inheritable_attributes.rb new file mode 100644 index 0000000..0afe608 --- /dev/null +++ b/vendor/gems/httparty-0.4.3/lib/httparty/module_inheritable_attributes.rb @@ -0,0 +1,25 @@ +module HTTParty + module ModuleInheritableAttributes #:nodoc: + def self.included(base) + base.extend(ClassMethods) + end + + module ClassMethods #:nodoc: + def mattr_inheritable(*args) + @mattr_inheritable_attrs ||= [:mattr_inheritable_attrs] + @mattr_inheritable_attrs += args + args.each do |arg| + module_eval %(class << self; attr_accessor :#{arg} end) + end + @mattr_inheritable_attrs + end + + def inherited(subclass) + @mattr_inheritable_attrs.each do |inheritable_attribute| + instance_var = "@#{inheritable_attribute}" + subclass.instance_variable_set(instance_var, instance_variable_get(instance_var)) + end + end + end + end +end \ No newline at end of file diff --git a/vendor/gems/httparty-0.4.3/lib/httparty/request.rb b/vendor/gems/httparty-0.4.3/lib/httparty/request.rb new file mode 100644 index 0000000..7370f7b --- /dev/null +++ b/vendor/gems/httparty-0.4.3/lib/httparty/request.rb @@ -0,0 +1,139 @@ +require 'uri' + +module HTTParty + class Request #:nodoc: + SupportedHTTPMethods = [Net::HTTP::Get, Net::HTTP::Post, Net::HTTP::Put, Net::HTTP::Delete] + + attr_accessor :http_method, :path, :options + + def initialize(http_method, path, o={}) + self.http_method = http_method + self.path = path + self.options = { + :limit => o.delete(:no_follow) ? 0 : 5, + :default_params => {}, + }.merge(o) + end + + def path=(uri) + @path = URI.parse(uri) + end + + def uri + new_uri = path.relative? ? URI.parse("#{options[:base_uri]}#{path}") : path + + # avoid double query string on redirects [#12] + unless @redirect + new_uri.query = query_string(new_uri) + end + + new_uri + end + + def format + options[:format] + end + + def perform + validate + setup_raw_request + handle_response(get_response) + end + + private + def http + http = Net::HTTP.new(uri.host, uri.port, options[:http_proxyaddr], options[:http_proxyport]) + http.use_ssl = (uri.port == 443) + http.verify_mode = OpenSSL::SSL::VERIFY_NONE + http + end + + def configure_basic_auth + @raw_request.basic_auth(options[:basic_auth][:username], options[:basic_auth][:password]) + end + + def setup_raw_request + @raw_request = http_method.new(uri.request_uri) + + if post? && options[:query] + @raw_request.set_form_data(options[:query]) + end + + @raw_request.body = options[:body].is_a?(Hash) ? options[:body].to_params : options[:body] unless options[:body].blank? + @raw_request.initialize_http_header options[:headers] + + configure_basic_auth if options[:basic_auth] + end + + def perform_actual_request + http.request(@raw_request) + end + + def get_response + response = perform_actual_request + options[:format] ||= format_from_mimetype(response['content-type']) + response + end + + def query_string(uri) + query_string_parts = [] + query_string_parts << uri.query unless uri.query.blank? + + if options[:query].is_a?(Hash) + query_string_parts << options[:default_params].merge(options[:query]).to_params + else + query_string_parts << options[:default_params].to_params unless options[:default_params].blank? + query_string_parts << options[:query] unless options[:query].blank? + end + + query_string_parts.size > 0 ? query_string_parts.join('&') : nil + end + + # Raises exception Net::XXX (http error code) if an http error occured + def handle_response(response) + case response + when Net::HTTPRedirection + options[:limit] -= 1 + self.path = response['location'] + @redirect = true + perform + else + parsed_response = parse_response(response.body) + Response.new(parsed_response, response.body, response.code, response.message, response.to_hash) + end + end + + def parse_response(body) + return nil if body.nil? or body.empty? + case format + when :xml + Crack::XML.parse(body) + when :json + Crack::JSON.parse(body) + when :yaml + YAML::load(body) + else + body + end + end + + # Uses the HTTP Content-Type header to determine the format of the response + # It compares the MIME type returned to the types stored in the AllowedFormats hash + def format_from_mimetype(mimetype) + return nil if mimetype.nil? + AllowedFormats.each { |k, v| return v if mimetype.include?(k) } + end + + def validate + raise HTTParty::RedirectionTooDeep, 'HTTP redirects too deep' if options[:limit].to_i <= 0 + raise ArgumentError, 'only get, post, put and delete methods are supported' unless SupportedHTTPMethods.include?(http_method) + raise ArgumentError, ':headers must be a hash' if options[:headers] && !options[:headers].is_a?(Hash) + raise ArgumentError, ':basic_auth must be a hash' if options[:basic_auth] && !options[:basic_auth].is_a?(Hash) + raise ArgumentError, ':query must be hash if using HTTP Post' if post? && !options[:query].nil? && !options[:query].is_a?(Hash) + end + + def post? + Net::HTTP::Post == http_method + end + end +end diff --git a/vendor/gems/httparty-0.4.3/lib/httparty/response.rb b/vendor/gems/httparty-0.4.3/lib/httparty/response.rb new file mode 100644 index 0000000..2670b51 --- /dev/null +++ b/vendor/gems/httparty-0.4.3/lib/httparty/response.rb @@ -0,0 +1,18 @@ +module HTTParty + class Response < BlankSlate #:nodoc: + attr_accessor :body, :code, :message, :headers + attr_reader :delegate + + def initialize(delegate, body, code, message, headers={}) + @delegate = delegate + @body = body + @code = code.to_i + @message = message + @headers = headers + end + + def method_missing(name, *args, &block) + @delegate.send(name, *args, &block) + end + end +end diff --git a/vendor/gems/httparty-0.4.3/lib/httparty/version.rb b/vendor/gems/httparty-0.4.3/lib/httparty/version.rb new file mode 100644 index 0000000..fefa37a --- /dev/null +++ b/vendor/gems/httparty-0.4.3/lib/httparty/version.rb @@ -0,0 +1,3 @@ +module HTTParty #:nodoc: + Version = '0.4.3' +end diff --git a/vendor/gems/httparty-0.4.3/setup.rb b/vendor/gems/httparty-0.4.3/setup.rb new file mode 100644 index 0000000..424a5f3 --- /dev/null +++ b/vendor/gems/httparty-0.4.3/setup.rb @@ -0,0 +1,1585 @@ +# +# setup.rb +# +# Copyright (c) 2000-2005 Minero Aoki +# +# This program is free software. +# You can distribute/modify this program under the terms of +# the GNU LGPL, Lesser General Public License version 2.1. +# + +unless Enumerable.method_defined?(:map) # Ruby 1.4.6 + module Enumerable + alias map collect + end +end + +unless File.respond_to?(:read) # Ruby 1.6 + def File.read(fname) + open(fname) {|f| + return f.read + } + end +end + +unless Errno.const_defined?(:ENOTEMPTY) # Windows? + module Errno + class ENOTEMPTY + # We do not raise this exception, implementation is not needed. + end + end +end + +def File.binread(fname) + open(fname, 'rb') {|f| + return f.read + } +end + +# for corrupted Windows' stat(2) +def File.dir?(path) + File.directory?((path[-1,1] == '/') ? path : path + '/') +end + + +class ConfigTable + + include Enumerable + + def initialize(rbconfig) + @rbconfig = rbconfig + @items = [] + @table = {} + # options + @install_prefix = nil + @config_opt = nil + @verbose = true + @no_harm = false + end + + attr_accessor :install_prefix + attr_accessor :config_opt + + attr_writer :verbose + + def verbose? + @verbose + end + + attr_writer :no_harm + + def no_harm? + @no_harm + end + + def [](key) + lookup(key).resolve(self) + end + + def []=(key, val) + lookup(key).set val + end + + def names + @items.map {|i| i.name } + end + + def each(&block) + @items.each(&block) + end + + def key?(name) + @table.key?(name) + end + + def lookup(name) + @table[name] or setup_rb_error "no such config item: #{name}" + end + + def add(item) + @items.push item + @table[item.name] = item + end + + def remove(name) + item = lookup(name) + @items.delete_if {|i| i.name == name } + @table.delete_if {|name, i| i.name == name } + item + end + + def load_script(path, inst = nil) + if File.file?(path) + MetaConfigEnvironment.new(self, inst).instance_eval File.read(path), path + end + end + + def savefile + '.config' + end + + def load_savefile + begin + File.foreach(savefile()) do |line| + k, v = *line.split(/=/, 2) + self[k] = v.strip + end + rescue Errno::ENOENT + setup_rb_error $!.message + "\n#{File.basename($0)} config first" + end + end + + def save + @items.each {|i| i.value } + File.open(savefile(), 'w') {|f| + @items.each do |i| + f.printf "%s=%s\n", i.name, i.value if i.value? and i.value + end + } + end + + def load_standard_entries + standard_entries(@rbconfig).each do |ent| + add ent + end + end + + def standard_entries(rbconfig) + c = rbconfig + + rubypath = File.join(c['bindir'], c['ruby_install_name'] + c['EXEEXT']) + + major = c['MAJOR'].to_i + minor = c['MINOR'].to_i + teeny = c['TEENY'].to_i + version = "#{major}.#{minor}" + + # ruby ver. >= 1.4.4? + newpath_p = ((major >= 2) or + ((major == 1) and + ((minor >= 5) or + ((minor == 4) and (teeny >= 4))))) + + if c['rubylibdir'] + # V > 1.6.3 + libruby = "#{c['prefix']}/lib/ruby" + librubyver = c['rubylibdir'] + librubyverarch = c['archdir'] + siteruby = c['sitedir'] + siterubyver = c['sitelibdir'] + siterubyverarch = c['sitearchdir'] + elsif newpath_p + # 1.4.4 <= V <= 1.6.3 + libruby = "#{c['prefix']}/lib/ruby" + librubyver = "#{c['prefix']}/lib/ruby/#{version}" + librubyverarch = "#{c['prefix']}/lib/ruby/#{version}/#{c['arch']}" + siteruby = c['sitedir'] + siterubyver = "$siteruby/#{version}" + siterubyverarch = "$siterubyver/#{c['arch']}" + else + # V < 1.4.4 + libruby = "#{c['prefix']}/lib/ruby" + librubyver = "#{c['prefix']}/lib/ruby/#{version}" + librubyverarch = "#{c['prefix']}/lib/ruby/#{version}/#{c['arch']}" + siteruby = "#{c['prefix']}/lib/ruby/#{version}/site_ruby" + siterubyver = siteruby + siterubyverarch = "$siterubyver/#{c['arch']}" + end + parameterize = lambda {|path| + path.sub(/\A#{Regexp.quote(c['prefix'])}/, '$prefix') + } + + if arg = c['configure_args'].split.detect {|arg| /--with-make-prog=/ =~ arg } + makeprog = arg.sub(/'/, '').split(/=/, 2)[1] + else + makeprog = 'make' + end + + [ + ExecItem.new('installdirs', 'std/site/home', + 'std: install under libruby; site: install under site_ruby; home: install under $HOME')\ + {|val, table| + case val + when 'std' + table['rbdir'] = '$librubyver' + table['sodir'] = '$librubyverarch' + when 'site' + table['rbdir'] = '$siterubyver' + table['sodir'] = '$siterubyverarch' + when 'home' + setup_rb_error '$HOME was not set' unless ENV['HOME'] + table['prefix'] = ENV['HOME'] + table['rbdir'] = '$libdir/ruby' + table['sodir'] = '$libdir/ruby' + end + }, + PathItem.new('prefix', 'path', c['prefix'], + 'path prefix of target environment'), + PathItem.new('bindir', 'path', parameterize.call(c['bindir']), + 'the directory for commands'), + PathItem.new('libdir', 'path', parameterize.call(c['libdir']), + 'the directory for libraries'), + PathItem.new('datadir', 'path', parameterize.call(c['datadir']), + 'the directory for shared data'), + PathItem.new('mandir', 'path', parameterize.call(c['mandir']), + 'the directory for man pages'), + PathItem.new('sysconfdir', 'path', parameterize.call(c['sysconfdir']), + 'the directory for system configuration files'), + PathItem.new('localstatedir', 'path', parameterize.call(c['localstatedir']), + 'the directory for local state data'), + PathItem.new('libruby', 'path', libruby, + 'the directory for ruby libraries'), + PathItem.new('librubyver', 'path', librubyver, + 'the directory for standard ruby libraries'), + PathItem.new('librubyverarch', 'path', librubyverarch, + 'the directory for standard ruby extensions'), + PathItem.new('siteruby', 'path', siteruby, + 'the directory for version-independent aux ruby libraries'), + PathItem.new('siterubyver', 'path', siterubyver, + 'the directory for aux ruby libraries'), + PathItem.new('siterubyverarch', 'path', siterubyverarch, + 'the directory for aux ruby binaries'), + PathItem.new('rbdir', 'path', '$siterubyver', + 'the directory for ruby scripts'), + PathItem.new('sodir', 'path', '$siterubyverarch', + 'the directory for ruby extentions'), + PathItem.new('rubypath', 'path', rubypath, + 'the path to set to #! line'), + ProgramItem.new('rubyprog', 'name', rubypath, + 'the ruby program using for installation'), + ProgramItem.new('makeprog', 'name', makeprog, + 'the make program to compile ruby extentions'), + SelectItem.new('shebang', 'all/ruby/never', 'ruby', + 'shebang line (#!) editing mode'), + BoolItem.new('without-ext', 'yes/no', 'no', + 'does not compile/install ruby extentions') + ] + end + private :standard_entries + + def load_multipackage_entries + multipackage_entries().each do |ent| + add ent + end + end + + def multipackage_entries + [ + PackageSelectionItem.new('with', 'name,name...', '', 'ALL', + 'package names that you want to install'), + PackageSelectionItem.new('without', 'name,name...', '', 'NONE', + 'package names that you do not want to install') + ] + end + private :multipackage_entries + + ALIASES = { + 'std-ruby' => 'librubyver', + 'stdruby' => 'librubyver', + 'rubylibdir' => 'librubyver', + 'archdir' => 'librubyverarch', + 'site-ruby-common' => 'siteruby', # For backward compatibility + 'site-ruby' => 'siterubyver', # For backward compatibility + 'bin-dir' => 'bindir', + 'bin-dir' => 'bindir', + 'rb-dir' => 'rbdir', + 'so-dir' => 'sodir', + 'data-dir' => 'datadir', + 'ruby-path' => 'rubypath', + 'ruby-prog' => 'rubyprog', + 'ruby' => 'rubyprog', + 'make-prog' => 'makeprog', + 'make' => 'makeprog' + } + + def fixup + ALIASES.each do |ali, name| + @table[ali] = @table[name] + end + @items.freeze + @table.freeze + @options_re = /\A--(#{@table.keys.join('|')})(?:=(.*))?\z/ + end + + def parse_opt(opt) + m = @options_re.match(opt) or setup_rb_error "config: unknown option #{opt}" + m.to_a[1,2] + end + + def dllext + @rbconfig['DLEXT'] + end + + def value_config?(name) + lookup(name).value? + end + + class Item + def initialize(name, template, default, desc) + @name = name.freeze + @template = template + @value = default + @default = default + @description = desc + end + + attr_reader :name + attr_reader :description + + attr_accessor :default + alias help_default default + + def help_opt + "--#{@name}=#{@template}" + end + + def value? + true + end + + def value + @value + end + + def resolve(table) + @value.gsub(%r<\$([^/]+)>) { table[$1] } + end + + def set(val) + @value = check(val) + end + + private + + def check(val) + setup_rb_error "config: --#{name} requires argument" unless val + val + end + end + + class BoolItem < Item + def config_type + 'bool' + end + + def help_opt + "--#{@name}" + end + + private + + def check(val) + return 'yes' unless val + case val + when /\Ay(es)?\z/i, /\At(rue)?\z/i then 'yes' + when /\An(o)?\z/i, /\Af(alse)\z/i then 'no' + else + setup_rb_error "config: --#{@name} accepts only yes/no for argument" + end + end + end + + class PathItem < Item + def config_type + 'path' + end + + private + + def check(path) + setup_rb_error "config: --#{@name} requires argument" unless path + path[0,1] == '$' ? path : File.expand_path(path) + end + end + + class ProgramItem < Item + def config_type + 'program' + end + end + + class SelectItem < Item + def initialize(name, selection, default, desc) + super + @ok = selection.split('/') + end + + def config_type + 'select' + end + + private + + def check(val) + unless @ok.include?(val.strip) + setup_rb_error "config: use --#{@name}=#{@template} (#{val})" + end + val.strip + end + end + + class ExecItem < Item + def initialize(name, selection, desc, &block) + super name, selection, nil, desc + @ok = selection.split('/') + @action = block + end + + def config_type + 'exec' + end + + def value? + false + end + + def resolve(table) + setup_rb_error "$#{name()} wrongly used as option value" + end + + undef set + + def evaluate(val, table) + v = val.strip.downcase + unless @ok.include?(v) + setup_rb_error "invalid option --#{@name}=#{val} (use #{@template})" + end + @action.call v, table + end + end + + class PackageSelectionItem < Item + def initialize(name, template, default, help_default, desc) + super name, template, default, desc + @help_default = help_default + end + + attr_reader :help_default + + def config_type + 'package' + end + + private + + def check(val) + unless File.dir?("packages/#{val}") + setup_rb_error "config: no such package: #{val}" + end + val + end + end + + class MetaConfigEnvironment + def initialize(config, installer) + @config = config + @installer = installer + end + + def config_names + @config.names + end + + def config?(name) + @config.key?(name) + end + + def bool_config?(name) + @config.lookup(name).config_type == 'bool' + end + + def path_config?(name) + @config.lookup(name).config_type == 'path' + end + + def value_config?(name) + @config.lookup(name).config_type != 'exec' + end + + def add_config(item) + @config.add item + end + + def add_bool_config(name, default, desc) + @config.add BoolItem.new(name, 'yes/no', default ? 'yes' : 'no', desc) + end + + def add_path_config(name, default, desc) + @config.add PathItem.new(name, 'path', default, desc) + end + + def set_config_default(name, default) + @config.lookup(name).default = default + end + + def remove_config(name) + @config.remove(name) + end + + # For only multipackage + def packages + raise '[setup.rb fatal] multi-package metaconfig API packages() called for single-package; contact application package vendor' unless @installer + @installer.packages + end + + # For only multipackage + def declare_packages(list) + raise '[setup.rb fatal] multi-package metaconfig API declare_packages() called for single-package; contact application package vendor' unless @installer + @installer.packages = list + end + end + +end # class ConfigTable + + +# This module requires: #verbose?, #no_harm? +module FileOperations + + def mkdir_p(dirname, prefix = nil) + dirname = prefix + File.expand_path(dirname) if prefix + $stderr.puts "mkdir -p #{dirname}" if verbose? + return if no_harm? + + # Does not check '/', it's too abnormal. + dirs = File.expand_path(dirname).split(%r<(?=/)>) + if /\A[a-z]:\z/i =~ dirs[0] + disk = dirs.shift + dirs[0] = disk + dirs[0] + end + dirs.each_index do |idx| + path = dirs[0..idx].join('') + Dir.mkdir path unless File.dir?(path) + end + end + + def rm_f(path) + $stderr.puts "rm -f #{path}" if verbose? + return if no_harm? + force_remove_file path + end + + def rm_rf(path) + $stderr.puts "rm -rf #{path}" if verbose? + return if no_harm? + remove_tree path + end + + def remove_tree(path) + if File.symlink?(path) + remove_file path + elsif File.dir?(path) + remove_tree0 path + else + force_remove_file path + end + end + + def remove_tree0(path) + Dir.foreach(path) do |ent| + next if ent == '.' + next if ent == '..' + entpath = "#{path}/#{ent}" + if File.symlink?(entpath) + remove_file entpath + elsif File.dir?(entpath) + remove_tree0 entpath + else + force_remove_file entpath + end + end + begin + Dir.rmdir path + rescue Errno::ENOTEMPTY + # directory may not be empty + end + end + + def move_file(src, dest) + force_remove_file dest + begin + File.rename src, dest + rescue + File.open(dest, 'wb') {|f| + f.write File.binread(src) + } + File.chmod File.stat(src).mode, dest + File.unlink src + end + end + + def force_remove_file(path) + begin + remove_file path + rescue + end + end + + def remove_file(path) + File.chmod 0777, path + File.unlink path + end + + def install(from, dest, mode, prefix = nil) + $stderr.puts "install #{from} #{dest}" if verbose? + return if no_harm? + + realdest = prefix ? prefix + File.expand_path(dest) : dest + realdest = File.join(realdest, File.basename(from)) if File.dir?(realdest) + str = File.binread(from) + if diff?(str, realdest) + verbose_off { + rm_f realdest if File.exist?(realdest) + } + File.open(realdest, 'wb') {|f| + f.write str + } + File.chmod mode, realdest + + File.open("#{objdir_root()}/InstalledFiles", 'a') {|f| + if prefix + f.puts realdest.sub(prefix, '') + else + f.puts realdest + end + } + end + end + + def diff?(new_content, path) + return true unless File.exist?(path) + new_content != File.binread(path) + end + + def command(*args) + $stderr.puts args.join(' ') if verbose? + system(*args) or raise RuntimeError, + "system(#{args.map{|a| a.inspect }.join(' ')}) failed" + end + + def ruby(*args) + command config('rubyprog'), *args + end + + def make(task = nil) + command(*[config('makeprog'), task].compact) + end + + def extdir?(dir) + File.exist?("#{dir}/MANIFEST") or File.exist?("#{dir}/extconf.rb") + end + + def files_of(dir) + Dir.open(dir) {|d| + return d.select {|ent| File.file?("#{dir}/#{ent}") } + } + end + + DIR_REJECT = %w( . .. CVS SCCS RCS CVS.adm .svn ) + + def directories_of(dir) + Dir.open(dir) {|d| + return d.select {|ent| File.dir?("#{dir}/#{ent}") } - DIR_REJECT + } + end + +end + + +# This module requires: #srcdir_root, #objdir_root, #relpath +module HookScriptAPI + + def get_config(key) + @config[key] + end + + alias config get_config + + # obsolete: use metaconfig to change configuration + def set_config(key, val) + @config[key] = val + end + + # + # srcdir/objdir (works only in the package directory) + # + + def curr_srcdir + "#{srcdir_root()}/#{relpath()}" + end + + def curr_objdir + "#{objdir_root()}/#{relpath()}" + end + + def srcfile(path) + "#{curr_srcdir()}/#{path}" + end + + def srcexist?(path) + File.exist?(srcfile(path)) + end + + def srcdirectory?(path) + File.dir?(srcfile(path)) + end + + def srcfile?(path) + File.file?(srcfile(path)) + end + + def srcentries(path = '.') + Dir.open("#{curr_srcdir()}/#{path}") {|d| + return d.to_a - %w(. ..) + } + end + + def srcfiles(path = '.') + srcentries(path).select {|fname| + File.file?(File.join(curr_srcdir(), path, fname)) + } + end + + def srcdirectories(path = '.') + srcentries(path).select {|fname| + File.dir?(File.join(curr_srcdir(), path, fname)) + } + end + +end + + +class ToplevelInstaller + + Version = '3.4.1' + Copyright = 'Copyright (c) 2000-2005 Minero Aoki' + + TASKS = [ + [ 'all', 'do config, setup, then install' ], + [ 'config', 'saves your configurations' ], + [ 'show', 'shows current configuration' ], + [ 'setup', 'compiles ruby extentions and others' ], + [ 'install', 'installs files' ], + [ 'test', 'run all tests in test/' ], + [ 'clean', "does `make clean' for each extention" ], + [ 'distclean',"does `make distclean' for each extention" ] + ] + + def ToplevelInstaller.invoke + config = ConfigTable.new(load_rbconfig()) + config.load_standard_entries + config.load_multipackage_entries if multipackage? + config.fixup + klass = (multipackage?() ? ToplevelInstallerMulti : ToplevelInstaller) + klass.new(File.dirname($0), config).invoke + end + + def ToplevelInstaller.multipackage? + File.dir?(File.dirname($0) + '/packages') + end + + def ToplevelInstaller.load_rbconfig + if arg = ARGV.detect {|arg| /\A--rbconfig=/ =~ arg } + ARGV.delete(arg) + load File.expand_path(arg.split(/=/, 2)[1]) + $".push 'rbconfig.rb' + else + require 'rbconfig' + end + ::Config::CONFIG + end + + def initialize(ardir_root, config) + @ardir = File.expand_path(ardir_root) + @config = config + # cache + @valid_task_re = nil + end + + def config(key) + @config[key] + end + + def inspect + "#<#{self.class} #{__id__()}>" + end + + def invoke + run_metaconfigs + case task = parsearg_global() + when nil, 'all' + parsearg_config + init_installers + exec_config + exec_setup + exec_install + else + case task + when 'config', 'test' + ; + when 'clean', 'distclean' + @config.load_savefile if File.exist?(@config.savefile) + else + @config.load_savefile + end + __send__ "parsearg_#{task}" + init_installers + __send__ "exec_#{task}" + end + end + + def run_metaconfigs + @config.load_script "#{@ardir}/metaconfig" + end + + def init_installers + @installer = Installer.new(@config, @ardir, File.expand_path('.')) + end + + # + # Hook Script API bases + # + + def srcdir_root + @ardir + end + + def objdir_root + '.' + end + + def relpath + '.' + end + + # + # Option Parsing + # + + def parsearg_global + while arg = ARGV.shift + case arg + when /\A\w+\z/ + setup_rb_error "invalid task: #{arg}" unless valid_task?(arg) + return arg + when '-q', '--quiet' + @config.verbose = false + when '--verbose' + @config.verbose = true + when '--help' + print_usage $stdout + exit 0 + when '--version' + puts "#{File.basename($0)} version #{Version}" + exit 0 + when '--copyright' + puts Copyright + exit 0 + else + setup_rb_error "unknown global option '#{arg}'" + end + end + nil + end + + def valid_task?(t) + valid_task_re() =~ t + end + + def valid_task_re + @valid_task_re ||= /\A(?:#{TASKS.map {|task,desc| task }.join('|')})\z/ + end + + def parsearg_no_options + unless ARGV.empty? + task = caller(0).first.slice(%r<`parsearg_(\w+)'>, 1) + setup_rb_error "#{task}: unknown options: #{ARGV.join(' ')}" + end + end + + alias parsearg_show parsearg_no_options + alias parsearg_setup parsearg_no_options + alias parsearg_test parsearg_no_options + alias parsearg_clean parsearg_no_options + alias parsearg_distclean parsearg_no_options + + def parsearg_config + evalopt = [] + set = [] + @config.config_opt = [] + while i = ARGV.shift + if /\A--?\z/ =~ i + @config.config_opt = ARGV.dup + break + end + name, value = *@config.parse_opt(i) + if @config.value_config?(name) + @config[name] = value + else + evalopt.push [name, value] + end + set.push name + end + evalopt.each do |name, value| + @config.lookup(name).evaluate value, @config + end + # Check if configuration is valid + set.each do |n| + @config[n] if @config.value_config?(n) + end + end + + def parsearg_install + @config.no_harm = false + @config.install_prefix = '' + while a = ARGV.shift + case a + when '--no-harm' + @config.no_harm = true + when /\A--prefix=/ + path = a.split(/=/, 2)[1] + path = File.expand_path(path) unless path[0,1] == '/' + @config.install_prefix = path + else + setup_rb_error "install: unknown option #{a}" + end + end + end + + def print_usage(out) + out.puts 'Typical Installation Procedure:' + out.puts " $ ruby #{File.basename $0} config" + out.puts " $ ruby #{File.basename $0} setup" + out.puts " # ruby #{File.basename $0} install (may require root privilege)" + out.puts + out.puts 'Detailed Usage:' + out.puts " ruby #{File.basename $0} " + out.puts " ruby #{File.basename $0} [] []" + + fmt = " %-24s %s\n" + out.puts + out.puts 'Global options:' + out.printf fmt, '-q,--quiet', 'suppress message outputs' + out.printf fmt, ' --verbose', 'output messages verbosely' + out.printf fmt, ' --help', 'print this message' + out.printf fmt, ' --version', 'print version and quit' + out.printf fmt, ' --copyright', 'print copyright and quit' + out.puts + out.puts 'Tasks:' + TASKS.each do |name, desc| + out.printf fmt, name, desc + end + + fmt = " %-24s %s [%s]\n" + out.puts + out.puts 'Options for CONFIG or ALL:' + @config.each do |item| + out.printf fmt, item.help_opt, item.description, item.help_default + end + out.printf fmt, '--rbconfig=path', 'rbconfig.rb to load',"running ruby's" + out.puts + out.puts 'Options for INSTALL:' + out.printf fmt, '--no-harm', 'only display what to do if given', 'off' + out.printf fmt, '--prefix=path', 'install path prefix', '' + out.puts + end + + # + # Task Handlers + # + + def exec_config + @installer.exec_config + @config.save # must be final + end + + def exec_setup + @installer.exec_setup + end + + def exec_install + @installer.exec_install + end + + def exec_test + @installer.exec_test + end + + def exec_show + @config.each do |i| + printf "%-20s %s\n", i.name, i.value if i.value? + end + end + + def exec_clean + @installer.exec_clean + end + + def exec_distclean + @installer.exec_distclean + end + +end # class ToplevelInstaller + + +class ToplevelInstallerMulti < ToplevelInstaller + + include FileOperations + + def initialize(ardir_root, config) + super + @packages = directories_of("#{@ardir}/packages") + raise 'no package exists' if @packages.empty? + @root_installer = Installer.new(@config, @ardir, File.expand_path('.')) + end + + def run_metaconfigs + @config.load_script "#{@ardir}/metaconfig", self + @packages.each do |name| + @config.load_script "#{@ardir}/packages/#{name}/metaconfig" + end + end + + attr_reader :packages + + def packages=(list) + raise 'package list is empty' if list.empty? + list.each do |name| + raise "directory packages/#{name} does not exist"\ + unless File.dir?("#{@ardir}/packages/#{name}") + end + @packages = list + end + + def init_installers + @installers = {} + @packages.each do |pack| + @installers[pack] = Installer.new(@config, + "#{@ardir}/packages/#{pack}", + "packages/#{pack}") + end + with = extract_selection(config('with')) + without = extract_selection(config('without')) + @selected = @installers.keys.select {|name| + (with.empty? or with.include?(name)) \ + and not without.include?(name) + } + end + + def extract_selection(list) + a = list.split(/,/) + a.each do |name| + setup_rb_error "no such package: #{name}" unless @installers.key?(name) + end + a + end + + def print_usage(f) + super + f.puts 'Inluded packages:' + f.puts ' ' + @packages.sort.join(' ') + f.puts + end + + # + # Task Handlers + # + + def exec_config + run_hook 'pre-config' + each_selected_installers {|inst| inst.exec_config } + run_hook 'post-config' + @config.save # must be final + end + + def exec_setup + run_hook 'pre-setup' + each_selected_installers {|inst| inst.exec_setup } + run_hook 'post-setup' + end + + def exec_install + run_hook 'pre-install' + each_selected_installers {|inst| inst.exec_install } + run_hook 'post-install' + end + + def exec_test + run_hook 'pre-test' + each_selected_installers {|inst| inst.exec_test } + run_hook 'post-test' + end + + def exec_clean + rm_f @config.savefile + run_hook 'pre-clean' + each_selected_installers {|inst| inst.exec_clean } + run_hook 'post-clean' + end + + def exec_distclean + rm_f @config.savefile + run_hook 'pre-distclean' + each_selected_installers {|inst| inst.exec_distclean } + run_hook 'post-distclean' + end + + # + # lib + # + + def each_selected_installers + Dir.mkdir 'packages' unless File.dir?('packages') + @selected.each do |pack| + $stderr.puts "Processing the package `#{pack}' ..." if verbose? + Dir.mkdir "packages/#{pack}" unless File.dir?("packages/#{pack}") + Dir.chdir "packages/#{pack}" + yield @installers[pack] + Dir.chdir '../..' + end + end + + def run_hook(id) + @root_installer.run_hook id + end + + # module FileOperations requires this + def verbose? + @config.verbose? + end + + # module FileOperations requires this + def no_harm? + @config.no_harm? + end + +end # class ToplevelInstallerMulti + + +class Installer + + FILETYPES = %w( bin lib ext data conf man ) + + include FileOperations + include HookScriptAPI + + def initialize(config, srcroot, objroot) + @config = config + @srcdir = File.expand_path(srcroot) + @objdir = File.expand_path(objroot) + @currdir = '.' + end + + def inspect + "#<#{self.class} #{File.basename(@srcdir)}>" + end + + def noop(rel) + end + + # + # Hook Script API base methods + # + + def srcdir_root + @srcdir + end + + def objdir_root + @objdir + end + + def relpath + @currdir + end + + # + # Config Access + # + + # module FileOperations requires this + def verbose? + @config.verbose? + end + + # module FileOperations requires this + def no_harm? + @config.no_harm? + end + + def verbose_off + begin + save, @config.verbose = @config.verbose?, false + yield + ensure + @config.verbose = save + end + end + + # + # TASK config + # + + def exec_config + exec_task_traverse 'config' + end + + alias config_dir_bin noop + alias config_dir_lib noop + + def config_dir_ext(rel) + extconf if extdir?(curr_srcdir()) + end + + alias config_dir_data noop + alias config_dir_conf noop + alias config_dir_man noop + + def extconf + ruby "#{curr_srcdir()}/extconf.rb", *@config.config_opt + end + + # + # TASK setup + # + + def exec_setup + exec_task_traverse 'setup' + end + + def setup_dir_bin(rel) + files_of(curr_srcdir()).each do |fname| + update_shebang_line "#{curr_srcdir()}/#{fname}" + end + end + + alias setup_dir_lib noop + + def setup_dir_ext(rel) + make if extdir?(curr_srcdir()) + end + + alias setup_dir_data noop + alias setup_dir_conf noop + alias setup_dir_man noop + + def update_shebang_line(path) + return if no_harm? + return if config('shebang') == 'never' + old = Shebang.load(path) + if old + $stderr.puts "warning: #{path}: Shebang line includes too many args. It is not portable and your program may not work." if old.args.size > 1 + new = new_shebang(old) + return if new.to_s == old.to_s + else + return unless config('shebang') == 'all' + new = Shebang.new(config('rubypath')) + end + $stderr.puts "updating shebang: #{File.basename(path)}" if verbose? + open_atomic_writer(path) {|output| + File.open(path, 'rb') {|f| + f.gets if old # discard + output.puts new.to_s + output.print f.read + } + } + end + + def new_shebang(old) + if /\Aruby/ =~ File.basename(old.cmd) + Shebang.new(config('rubypath'), old.args) + elsif File.basename(old.cmd) == 'env' and old.args.first == 'ruby' + Shebang.new(config('rubypath'), old.args[1..-1]) + else + return old unless config('shebang') == 'all' + Shebang.new(config('rubypath')) + end + end + + def open_atomic_writer(path, &block) + tmpfile = File.basename(path) + '.tmp' + begin + File.open(tmpfile, 'wb', &block) + File.rename tmpfile, File.basename(path) + ensure + File.unlink tmpfile if File.exist?(tmpfile) + end + end + + class Shebang + def Shebang.load(path) + line = nil + File.open(path) {|f| + line = f.gets + } + return nil unless /\A#!/ =~ line + parse(line) + end + + def Shebang.parse(line) + cmd, *args = *line.strip.sub(/\A\#!/, '').split(' ') + new(cmd, args) + end + + def initialize(cmd, args = []) + @cmd = cmd + @args = args + end + + attr_reader :cmd + attr_reader :args + + def to_s + "#! #{@cmd}" + (@args.empty? ? '' : " #{@args.join(' ')}") + end + end + + # + # TASK install + # + + def exec_install + rm_f 'InstalledFiles' + exec_task_traverse 'install' + end + + def install_dir_bin(rel) + install_files targetfiles(), "#{config('bindir')}/#{rel}", 0755 + end + + def install_dir_lib(rel) + install_files libfiles(), "#{config('rbdir')}/#{rel}", 0644 + end + + def install_dir_ext(rel) + return unless extdir?(curr_srcdir()) + install_files rubyextentions('.'), + "#{config('sodir')}/#{File.dirname(rel)}", + 0555 + end + + def install_dir_data(rel) + install_files targetfiles(), "#{config('datadir')}/#{rel}", 0644 + end + + def install_dir_conf(rel) + # FIXME: should not remove current config files + # (rename previous file to .old/.org) + install_files targetfiles(), "#{config('sysconfdir')}/#{rel}", 0644 + end + + def install_dir_man(rel) + install_files targetfiles(), "#{config('mandir')}/#{rel}", 0644 + end + + def install_files(list, dest, mode) + mkdir_p dest, @config.install_prefix + list.each do |fname| + install fname, dest, mode, @config.install_prefix + end + end + + def libfiles + glob_reject(%w(*.y *.output), targetfiles()) + end + + def rubyextentions(dir) + ents = glob_select("*.#{@config.dllext}", targetfiles()) + if ents.empty? + setup_rb_error "no ruby extention exists: 'ruby #{$0} setup' first" + end + ents + end + + def targetfiles + mapdir(existfiles() - hookfiles()) + end + + def mapdir(ents) + ents.map {|ent| + if File.exist?(ent) + then ent # objdir + else "#{curr_srcdir()}/#{ent}" # srcdir + end + } + end + + # picked up many entries from cvs-1.11.1/src/ignore.c + JUNK_FILES = %w( + core RCSLOG tags TAGS .make.state + .nse_depinfo #* .#* cvslog.* ,* .del-* *.olb + *~ *.old *.bak *.BAK *.orig *.rej _$* *$ + + *.org *.in .* + ) + + def existfiles + glob_reject(JUNK_FILES, (files_of(curr_srcdir()) | files_of('.'))) + end + + def hookfiles + %w( pre-%s post-%s pre-%s.rb post-%s.rb ).map {|fmt| + %w( config setup install clean ).map {|t| sprintf(fmt, t) } + }.flatten + end + + def glob_select(pat, ents) + re = globs2re([pat]) + ents.select {|ent| re =~ ent } + end + + def glob_reject(pats, ents) + re = globs2re(pats) + ents.reject {|ent| re =~ ent } + end + + GLOB2REGEX = { + '.' => '\.', + '$' => '\$', + '#' => '\#', + '*' => '.*' + } + + def globs2re(pats) + /\A(?:#{ + pats.map {|pat| pat.gsub(/[\.\$\#\*]/) {|ch| GLOB2REGEX[ch] } }.join('|') + })\z/ + end + + # + # TASK test + # + + TESTDIR = 'test' + + def exec_test + unless File.directory?('test') + $stderr.puts 'no test in this package' if verbose? + return + end + $stderr.puts 'Running tests...' if verbose? + begin + require 'test/unit' + rescue LoadError + setup_rb_error 'test/unit cannot loaded. You need Ruby 1.8 or later to invoke this task.' + end + runner = Test::Unit::AutoRunner.new(true) + runner.to_run << TESTDIR + runner.run + end + + # + # TASK clean + # + + def exec_clean + exec_task_traverse 'clean' + rm_f @config.savefile + rm_f 'InstalledFiles' + end + + alias clean_dir_bin noop + alias clean_dir_lib noop + alias clean_dir_data noop + alias clean_dir_conf noop + alias clean_dir_man noop + + def clean_dir_ext(rel) + return unless extdir?(curr_srcdir()) + make 'clean' if File.file?('Makefile') + end + + # + # TASK distclean + # + + def exec_distclean + exec_task_traverse 'distclean' + rm_f @config.savefile + rm_f 'InstalledFiles' + end + + alias distclean_dir_bin noop + alias distclean_dir_lib noop + + def distclean_dir_ext(rel) + return unless extdir?(curr_srcdir()) + make 'distclean' if File.file?('Makefile') + end + + alias distclean_dir_data noop + alias distclean_dir_conf noop + alias distclean_dir_man noop + + # + # Traversing + # + + def exec_task_traverse(task) + run_hook "pre-#{task}" + FILETYPES.each do |type| + if type == 'ext' and config('without-ext') == 'yes' + $stderr.puts 'skipping ext/* by user option' if verbose? + next + end + traverse task, type, "#{task}_dir_#{type}" + end + run_hook "post-#{task}" + end + + def traverse(task, rel, mid) + dive_into(rel) { + run_hook "pre-#{task}" + __send__ mid, rel.sub(%r[\A.*?(?:/|\z)], '') + directories_of(curr_srcdir()).each do |d| + traverse task, "#{rel}/#{d}", mid + end + run_hook "post-#{task}" + } + end + + def dive_into(rel) + return unless File.dir?("#{@srcdir}/#{rel}") + + dir = File.basename(rel) + Dir.mkdir dir unless File.dir?(dir) + prevdir = Dir.pwd + Dir.chdir dir + $stderr.puts '---> ' + rel if verbose? + @currdir = rel + yield + Dir.chdir prevdir + $stderr.puts '<--- ' + rel if verbose? + @currdir = File.dirname(rel) + end + + def run_hook(id) + path = [ "#{curr_srcdir()}/#{id}", + "#{curr_srcdir()}/#{id}.rb" ].detect {|cand| File.file?(cand) } + return unless path + begin + instance_eval File.read(path), path, 1 + rescue + raise if $DEBUG + setup_rb_error "hook #{path} failed:\n" + $!.message + end + end + +end # class Installer + + +class SetupError < StandardError; end + +def setup_rb_error(msg) + raise SetupError, msg +end + +if $0 == __FILE__ + begin + ToplevelInstaller.invoke + rescue SetupError + raise if $DEBUG + $stderr.puts $!.message + $stderr.puts "Try 'ruby #{$0} --help' for detailed usage." + exit 1 + end +end diff --git a/vendor/gems/httparty-0.4.3/spec/fixtures/delicious.xml b/vendor/gems/httparty-0.4.3/spec/fixtures/delicious.xml new file mode 100644 index 0000000..f93a1ee --- /dev/null +++ b/vendor/gems/httparty-0.4.3/spec/fixtures/delicious.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/vendor/gems/httparty-0.4.3/spec/fixtures/empty.xml b/vendor/gems/httparty-0.4.3/spec/fixtures/empty.xml new file mode 100644 index 0000000..e69de29 diff --git a/vendor/gems/httparty-0.4.3/spec/fixtures/google.html b/vendor/gems/httparty-0.4.3/spec/fixtures/google.html new file mode 100644 index 0000000..1c4221d --- /dev/null +++ b/vendor/gems/httparty-0.4.3/spec/fixtures/google.html @@ -0,0 +1,3 @@ +Google

Google

 
  Advanced Search
  Preferences
  Language Tools


Advertising Programs - Business Solutions - About Google

©2008 - Privacy

\ No newline at end of file diff --git a/vendor/gems/httparty-0.4.3/spec/fixtures/twitter.json b/vendor/gems/httparty-0.4.3/spec/fixtures/twitter.json new file mode 100644 index 0000000..642dd01 --- /dev/null +++ b/vendor/gems/httparty-0.4.3/spec/fixtures/twitter.json @@ -0,0 +1 @@ +[{"user":{"followers_count":1,"description":null,"url":null,"profile_image_url":"http:\/\/static.twitter.com\/images\/default_profile_normal.png","protected":false,"location":"Opera Plaza, California","screen_name":"Pyk","name":"Pyk","id":"7694602"},"text":"@lapilofu If you need a faster transfer, target disk mode should work too :)","truncated":false,"favorited":false,"in_reply_to_user_id":6128642,"created_at":"Sat Dec 06 21:29:14 +0000 2008","source":"twitterrific","in_reply_to_status_id":1042497164,"id":"1042500587"},{"user":{"followers_count":278,"description":"しがないプログラマ\/とりあえず宮子は俺の嫁\u2026いや、娘だ!\/Delphi&Pythonプログラマ修行中\/bot製作にハマりつつある。三つほど製作&構想中\/[eof]","url":"http:\/\/logiq.orz.hm\/","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/59588711\/l_ワ_l↑_normal.png","protected":false,"location":"ひだまり荘202号室","screen_name":"feiz","name":"azkn3","id":"14310520"},"text":"@y_benjo ちょー遅レスですがただのはだいろすぎる・・・ ( ll ワ ll )","truncated":false,"favorited":false,"in_reply_to_user_id":8428752,"created_at":"Sat Dec 06 21:29:14 +0000 2008","source":"twit","in_reply_to_status_id":1042479758,"id":"1042500586"},{"user":{"followers_count":1233,"description":""to understand one life you must swallow the world." I run refine+focus: a marketing agency working w\/ brands, media and VCs. http:\/\/tinyurl.com\/63mrn","url":"http:\/\/www.quiverandquill.com","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/53684650\/539059005_2a3b462d20_normal.jpg","protected":false,"location":"Cambridge, MA ","screen_name":"quiverandquill","name":"zach Braiker","id":"6845872"},"text":"@18percentgrey I didn't see Damon on Palin. i'll look on youtube. thx .Z","truncated":false,"favorited":false,"in_reply_to_user_id":10529932,"created_at":"Sat Dec 06 21:29:12 +0000 2008","source":"web","in_reply_to_status_id":1042499331,"id":"1042500584"},{"user":{"followers_count":780,"description":"Mein Blog ist unter http:\/\/blog.helmschrott.de zu finden. Unter http:\/\/blogalm.de kannst Du Deinen Blog eintragen!","url":"http:\/\/helmschrott.de\/blog","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/60997686\/avatar-250_normal.jpg","protected":false,"location":"Münchner Straße","screen_name":"helmi","name":"Frank Helmschrott","id":"867641"},"text":"@gigold auch mist oder?ich glaub ich fangs jetzt dann einfach mal an - wird schon vernünftige update-prozesse geben.","truncated":false,"favorited":false,"in_reply_to_user_id":959931,"created_at":"Sat Dec 06 21:29:11 +0000 2008","source":"twhirl","in_reply_to_status_id":1042500095,"id":"1042500583"},{"user":{"followers_count":63,"description":"Liberation from Misconceptions","url":"http:\/\/sexorcism.blogspot.com","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/63897302\/having-sex-on-bed_normal.jpg","protected":false,"location":"USA","screen_name":"Sexorcism","name":"Sexorcism","id":"16929435"},"text":"@thursdays_child someecards might.","truncated":false,"favorited":false,"in_reply_to_user_id":14484963,"created_at":"Sat Dec 06 21:29:13 +0000 2008","source":"twittergadget","in_reply_to_status_id":1042499777,"id":"1042500581"},{"user":{"followers_count":106,"description":"Researcher. Maître de Conférences - Sémiologue - Spécialiste des médias audiovisuels. Analyste des médias, de la télévision et de la presse people (gossip). ","url":"http:\/\/semioblog.over-blog.org\/","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/57988482\/Thomas_et_Vic_pour_promo_2_058_normal.JPG","protected":false,"location":"France","screen_name":"semioblog","name":"Virginie Spies","id":"10078802"},"text":"@richardvonstern on reparle de tout cela bientôt, si vous voulez vraiment m'aider","truncated":false,"favorited":false,"in_reply_to_user_id":15835317,"created_at":"Sat Dec 06 21:29:13 +0000 2008","source":"twitterrific","in_reply_to_status_id":1042357537,"id":"1042500580"},{"user":{"followers_count":26,"description":"","url":"","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/63461084\/November2ndpics_125_normal.jpg","protected":false,"location":"Louisville, Ky","screen_name":"scrapaunt","name":"scrapaunt","id":"16660671"},"text":"@NKOTB4LIFE Hope your neck feels better after your nap.","truncated":false,"favorited":false,"in_reply_to_user_id":16041403,"created_at":"Sat Dec 06 21:29:10 +0000 2008","source":"web","in_reply_to_status_id":1042450159,"id":"1042500579"},{"user":{"followers_count":245,"description":"Maui HI Real Estate Salesperson specializing in off the grid lifestyle","url":"http:\/\/www.eastmaui.com","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/59558480\/face2_normal.jpg","protected":false,"location":"north shore maui hawaii","screen_name":"mauihunter","name":"Georgina M. Hunter ","id":"16161708"},"text":"@BeeRealty http:\/\/twitpic.com\/qpog - It's a good safe place to lay - no dogs up there.","truncated":false,"favorited":false,"in_reply_to_user_id":15781063,"created_at":"Sat Dec 06 21:29:13 +0000 2008","source":"twitpic","in_reply_to_status_id":1042497815,"id":"1042500578"},{"user":{"followers_count":95,"description":"","url":"","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/66581657\/nose-pick_normal.jpg","protected":false,"location":"zoetermeer","screen_name":"GsKlukkluk","name":"Klukkluk","id":"14218588"},"text":"twit \/off zalige nacht!","truncated":false,"favorited":false,"in_reply_to_user_id":null,"created_at":"Sat Dec 06 21:29:14 +0000 2008","source":"web","in_reply_to_status_id":null,"id":"1042500577"},{"user":{"followers_count":33,"description":"Living in denial that I live in a podunk town, I spend my time in search of good music in LA. Pure city-dweller and puma. That's about it.","url":"","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/56024131\/Photo_145_normal.jpg","protected":false,"location":"Santa Barbara, CA","screen_name":"pumainthemvmt","name":"Valerie","id":"15266837"},"text":"I love my parents with all my heart, but sometimes they make me want to scratch my eyes out.","truncated":false,"favorited":false,"in_reply_to_user_id":null,"created_at":"Sat Dec 06 21:29:10 +0000 2008","source":"sms","in_reply_to_status_id":null,"id":"1042500576"},{"user":{"followers_count":99,"description":"大学生ですよ。Ad[es]er。趣味で辭書とか編輯してゐます。JavaScriptでゲーム書きたいけど時間ねえ。","url":"http:\/\/greengablez.net\/diary\/","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/60269370\/zonu_1_normal.gif","protected":false,"location":"Sapporo, Hokkaido, Japan","screen_name":"tadsan","name":"船越次男","id":"11637282"},"text":"リトル・プリンセスとだけ書かれたら小公女を連想するだろ、常識的に考へて。","truncated":false,"favorited":false,"in_reply_to_user_id":null,"created_at":"Sat Dec 06 21:29:11 +0000 2008","source":"tiitan","in_reply_to_status_id":null,"id":"1042500575"},{"user":{"followers_count":68,"description":"I love all things beer. What goes better with beer than Porn, nothig I tell ya nothing.","url":"","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/66479069\/Picture_9_normal.jpg","protected":false,"location":"Durant","screen_name":"Jeffporn","name":"Jeffporn","id":"14065262"},"text":"At Lefthand having milk stout on cask - Photo: http:\/\/bkite.com\/02PeH","truncated":false,"favorited":false,"in_reply_to_user_id":null,"created_at":"Sat Dec 06 21:29:10 +0000 2008","source":"brightkite","in_reply_to_status_id":null,"id":"1042500574"},{"user":{"followers_count":7,"description":"","url":"http:\/\/www.PeteKinser.com","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/65572489\/PeteKinser-close_normal.jpg","protected":false,"location":"Denver, CO","screen_name":"pkinser","name":"pkinser","id":"15570525"},"text":"Snooze is where it's at for brunch if you're ever in Denver. Yum.","truncated":false,"favorited":false,"in_reply_to_user_id":null,"created_at":"Sat Dec 06 21:29:11 +0000 2008","source":"fring","in_reply_to_status_id":null,"id":"1042500572"},{"user":{"followers_count":75,"description":"I am a gamer and this is my gaming account, check out my other Twitter account for non-gaming tweets.","url":"http:\/\/twitter.com\/Nailhead","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/56881055\/nailhead_184x184_normal.jpg","protected":false,"location":"Huntsville, AL","screen_name":"Nailhead_Gamer","name":"Eric Fullerton","id":"15487663"},"text":"Completed the epic quest line for the Death Knight. Now what? Outlands? I wish to skip Outlands please, thanks.","truncated":false,"favorited":false,"in_reply_to_user_id":null,"created_at":"Sat Dec 06 21:29:13 +0000 2008","source":"twitterfox","in_reply_to_status_id":null,"id":"1042500571"},{"user":{"followers_count":111,"description":"","url":"http:\/\/www.ns-tech.com\/blog\/geldred.nsf","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/63865052\/brak2_normal.JPG","protected":false,"location":"Cleveland OH","screen_name":"geldred","name":"geldred","id":"14093394"},"text":"I'm at Target Store - Avon OH (35830 Detroit Rd, Avon, OH 44011, USA) - http:\/\/bkite.com\/02PeI","truncated":false,"favorited":false,"in_reply_to_user_id":null,"created_at":"Sat Dec 06 21:29:13 +0000 2008","source":"brightkite","in_reply_to_status_id":null,"id":"1042500570"},{"user":{"followers_count":16,"description":"Soundtrack Composer\/Musician\/Producer","url":"http:\/\/www.reverbnation\/musicbystratos","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/63311865\/logo-stratos_normal.png","protected":false,"location":"Grove City, Ohio 43123","screen_name":"Stratos","name":"Bryan K Borgman","id":"756062"},"text":"is reminded how beautiful the world can be when it's blanketed by clean white snow.","truncated":false,"favorited":false,"in_reply_to_user_id":null,"created_at":"Sat Dec 06 21:29:13 +0000 2008","source":"web","in_reply_to_status_id":null,"id":"1042500569"},{"user":{"followers_count":7,"description":null,"url":null,"profile_image_url":"http:\/\/static.twitter.com\/images\/default_profile_normal.png","protected":false,"location":null,"screen_name":"garrettromine","name":"garrettromine","id":"16120885"},"text":"Go Julio","truncated":false,"favorited":false,"in_reply_to_user_id":null,"created_at":"Sat Dec 06 21:29:10 +0000 2008","source":"sms","in_reply_to_status_id":null,"id":"1042500568"},{"user":{"followers_count":111,"description":"WHAT IS HAPPNING IN THE WORLD??? SEE DIFFERENT NEWS STORIES FROM MANY SOURCES.","url":"http:\/\/henrynews.wetpaint.com","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/65118112\/2008-election-map-nytimes_normal.png","protected":false,"location":"","screen_name":"HenryNews","name":"HenryNews","id":"17398510"},"text":"Svindal completes double at Beaver Creek: Read full story for latest details. http:\/\/tinyurl.com\/6qugub","truncated":false,"favorited":false,"in_reply_to_user_id":null,"created_at":"Sat Dec 06 21:29:13 +0000 2008","source":"twitterfeed","in_reply_to_status_id":null,"id":"1042500567"},{"user":{"followers_count":34,"description":"I am a man of many bio's, scott bio's!","url":"http:\/\/flickr.com\/photos\/giantcandy","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/25680382\/Icon_for_Twitter_normal.jpg","protected":false,"location":"Loves Park, IL, USA","screen_name":"Pychobj2001","name":"William Boehm Jr","id":"809103"},"text":"I have a 3rd break light and the license plate lights are out...just replacing 1 plate light...abide by law just enough","truncated":false,"favorited":false,"in_reply_to_user_id":null,"created_at":"Sat Dec 06 21:29:10 +0000 2008","source":"twidroid","in_reply_to_status_id":null,"id":"1042500566"},{"user":{"followers_count":61,"description":"Wife. Designer. Green Enthusiast. New Homeowner. Pet Owner. Internet Addict.","url":"http:\/\/confessionsofadesignjunkie.blogspot.com\/","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/66044439\/n27310459_33432814_6743-1_normal.jpg","protected":false,"location":"Indiana","screen_name":"smquaseb","name":"Stacy","id":"15530992"},"text":"@Indygardener We still had a few people shoveling in our neighborhood - I didn't think it was enough to shovel, but keeps the kids busy.","truncated":false,"favorited":false,"in_reply_to_user_id":12811482,"created_at":"Sat Dec 06 21:29:13 +0000 2008","source":"web","in_reply_to_status_id":1042488558,"id":"1042500565"}] \ No newline at end of file diff --git a/vendor/gems/httparty-0.4.3/spec/fixtures/twitter.xml b/vendor/gems/httparty-0.4.3/spec/fixtures/twitter.xml new file mode 100644 index 0000000..24abaa8 --- /dev/null +++ b/vendor/gems/httparty-0.4.3/spec/fixtures/twitter.xml @@ -0,0 +1,403 @@ + + + Sun Dec 07 00:36:16 +0000 2008 + 1042729116 + @sebbo Outlook not so good + web + false + 1042716367 + 2989541 + false + + 17656026 + Magic 8 Bot + magic8bot + ask me a question + + http://s3.amazonaws.com/twitter_production/profile_images/65565851/8ball_large_normal.jpg + + false + 90 + + + Sun Dec 07 00:36:14 +0000 2008 + 1042729115 + Azdel Slade :friends from midian city http://bloghud.com/id/27312 + web + false + + + false + + 801094 + BlogHUD + bloghud + + + http://s3.amazonaws.com/twitter_production/profile_images/25235272/bloghud_twitter_normal.jpg + + false + 313 + + + Sun Dec 07 00:36:14 +0000 2008 + 1042729114 + Reading: "The Reckoning - Debt Watchdogs - Tamed or Caught Napping? - Series - NYTimes.com" ( http://tinyurl.com/5754s6 ) + twitthat + false + + + false + + 3512101 + bill + niubi + in beijing learning socialism 2 prepare 4 return 2 us + beijing + http://s3.amazonaws.com/twitter_production/profile_images/53292616/realtwitterers_normal.jpg + + false + 710 + + + Sun Dec 07 00:36:14 +0000 2008 + 1042729113 + Fianlly done and headed home! + sms + false + + + false + + 13186842 + Okthirddayfan + Okthirddayfan + + Oklahoma! + http://s3.amazonaws.com/twitter_production/profile_images/61414367/mecropped_normal.jpg + http://thirddaypix.blogspot.com/ + false + 68 + + + Sun Dec 07 00:36:16 +0000 2008 + 1042729112 + Adobe Flashplayer 10 and Debug versions: http://www.adobe.com/support/flashplayer/downloads.html + toro + false + + + false + + 15243380 + cbrueggenolte + cbrueggenolte + 27, Male, Mac Geek, Developer Java &amp; Flex &amp; Air + Aachen + http://s3.amazonaws.com/twitter_production/profile_images/55929263/214508011845f026bfd407c_normal.jpg + http://my.opera.com/carstenbrueggenolte + false + 16 + + + Sun Dec 07 00:36:14 +0000 2008 + 1042729111 + Done and done. + twitterrific + false + + + false + + 10978752 + Sergey Safonov + iron_Lung + I have my fingers in many pies. + Moscow + http://s3.amazonaws.com/twitter_production/profile_images/57841057/eat38_normal.gif + http://www.flickr.com/photos/iron_Lung + false + 11 + + + Sun Dec 07 00:36:14 +0000 2008 + 1042729110 + Veja a tabela de preços do Acquaplay da Tecnisa aqui:http://tinyurl.com/acquaplaypreco + web + false + + + false + + 13735402 + Tecnisa S.A + Tecnisa + Mais construtora por m2 + Faria Lima, 3144 - SP + http://s3.amazonaws.com/twitter_production/profile_images/56572222/logo_normal.jpg + http://www.tecnisa.com.br + false + 77 + + + Sun Dec 07 00:36:16 +0000 2008 + 1042729108 + devin harris has the flu. always have the memory of jordan scoring 50 on the knicks at the garden with the flu + web + false + + + false + + 17930773 + 24 Seconds to Shoot + NBA24sts + NBA handicapping insight and analysis. + las vegas + http://s3.amazonaws.com/twitter_production/profile_images/66593862/fresno_normal.jpg + + false + 1 + + + Sun Dec 07 00:36:16 +0000 2008 + 1042729105 + At Brandon and Shannon's holiday party.. + twitterberry + false + + + false + + 5388602 + Mike J. (Telligent) + mjamrst + Video Game Account Manager + Palo Alto, CA + http://s3.amazonaws.com/twitter_production/profile_images/66375174/Thanksgiving_11272008-048_normal.jpg + http://www.telligent.com + false + 225 + + + Sun Dec 07 00:36:13 +0000 2008 + 1042729104 + Xinhua: Forty percent of Australian PM office' staff quit : CANBERRA, Dec. 7 (Xinhua) -- Only.. http://tinyurl.com/5gwotd + twitterfeed + false + + + false + + 11566502 + Headline News + headlinenews + + + http://s3.amazonaws.com/twitter_production/profile_images/41784602/1890_wires_normal.jpg + + false + 575 + + + Sun Dec 07 00:36:13 +0000 2008 + 1042729101 + @hilarycassman soo funnny + sms + false + 1042725825 + 17644455 + false + + 17887548 + katieballss + katieballss + + + http://s3.amazonaws.com/twitter_production/profile_images/66523737/th_Photo87_normal.jpg + http://www.myspace.com/xxpeachxx101 + false + 23 + + + Sun Dec 07 00:36:13 +0000 2008 + 1042729100 + d'ora in poi, oltre al ferragosto, odiera' anche il natale e tutto il mese che ci gira intorno.. =.='' + mobile + false + + + false + + 9719482 + trotto + trotto + sociologo di formazione... uno dei tanti attivisti! :) + Fano - Italy + http://s3.amazonaws.com/twitter_production/profile_images/55603933/mybob-calimetux-1526_normal.png + http://trotto1308.netsons.org/wordpress/ + false + 98 + + + Sun Dec 07 00:36:13 +0000 2008 + 1042729099 + Came across an ad on another site with a redneck looking santa... said "Bust Santa's zit and win a free ipod." Umm... disturbing much? + web + false + + + false + + 9937182 + froggybluesock + froggybluesock + + Indiana + http://s3.amazonaws.com/twitter_production/profile_images/35393032/about_me_normal.jpg + http://www.footprintsonthemoon.com + false + 82 + + + Sun Dec 07 00:36:17 +0000 2008 + 1042729098 + nothing + web + false + + + false + + 17932339 + treblehook + treblehook + + + http://static.twitter.com/images/default_profile_normal.png + + false + 0 + + + Sun Dec 07 00:36:13 +0000 2008 + 1042729095 + Setting up my new Windows Live profile + web + false + + + false + + 17906075 + Mark_Layton + Mark_Layton + + + http://static.twitter.com/images/default_profile_normal.png + + false + 2 + + + Sun Dec 07 00:36:13 +0000 2008 + 1042729092 + me voy a sobar, a ver si mañana estoy mejor, wenas noches a tod@s + web + false + + + false + + 14062655 + tmaniak + tmaniak + + + http://s3.amazonaws.com/twitter_production/profile_images/51680481/BF-109_normal.jpg + http://dhost.info/tmaniak + false + 10 + + + Sun Dec 07 00:36:14 +0000 2008 + 1042729090 + バイト延長戦入りましたー 店長が遅刻ってどうなんだ。しかも何回も + natsuliphone + false + + + false + + 15618846 + kabayaki + kabayaki + FPS(L4D、TF2、CS:S、BF)、TPS、RCG、マンガ、アニメ、デジモノが好きなとある学生 + tokyo + http://s3.amazonaws.com/twitter_production/profile_images/57305902/184_normal.jpg + http://kabayakiya.blog43.fc2.com/ + false + 20 + + + Sun Dec 07 00:36:13 +0000 2008 + 1042729089 + just drove to southern california and joy of children hugging grandparents made it all worthwhile. heading to imedia in la quinta tomorrow. + web + false + + + false + + 1630261 + mark silva + marksilva + digital media http://realbranding.com Principal, Managing Director + often san francisco + http://s3.amazonaws.com/twitter_production/profile_images/29807902/silvasimpson3th_normal.jpg + http://marksilva.com + false + 497 + + + Sun Dec 07 00:36:14 +0000 2008 + 1042729088 + @wholefoods would love to have a juicebar in one of your cambridge or boston locations + web + false + 1041125103 + 15131310 + false + + 15856582 + Maura McGovern + mmcgovern + photographer with a day job in venture capital; obsessed with design blogs, long walks, yoga, social networking, people watching. tea and music are essential! + Boston + http://s3.amazonaws.com/twitter_production/profile_images/66110383/DSCN1740_normal.JPG + http://lefteyephotography.blogspot.com + false + 244 + + + Sun Dec 07 00:36:15 +0000 2008 + 1042729087 + Going over the Advent lists. + web + false + + + false + + 17122107 + gsusan + gsusan + US American writer/sister/daughter/aunt/woman from New England living in SoCal. + San Diego, CA USA + http://s3.amazonaws.com/twitter_production/profile_images/63951854/susan_ocracoke_normal.jpg + + false + 6 + + + \ No newline at end of file diff --git a/vendor/gems/httparty-0.4.3/spec/fixtures/undefined_method_add_node_for_nil.xml b/vendor/gems/httparty-0.4.3/spec/fixtures/undefined_method_add_node_for_nil.xml new file mode 100644 index 0000000..43d96a7 --- /dev/null +++ b/vendor/gems/httparty-0.4.3/spec/fixtures/undefined_method_add_node_for_nil.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/vendor/gems/httparty-0.4.3/spec/hash_spec.rb b/vendor/gems/httparty-0.4.3/spec/hash_spec.rb new file mode 100644 index 0000000..4ad0e8d --- /dev/null +++ b/vendor/gems/httparty-0.4.3/spec/hash_spec.rb @@ -0,0 +1,49 @@ +require File.dirname(__FILE__) + '/spec_helper' + +describe Hash, "to_xml_attributes" do + before do + @hash = { :one => "ONE", "two" => "TWO" } + end + + it "should turn the hash into xml attributes" do + attrs = @hash.to_xml_attributes + attrs.should match(/one="ONE"/m) + attrs.should match(/two="TWO"/m) + end + + it 'should preserve _ in hash keys' do + attrs = { + :some_long_attribute => "with short value", + :crash => :burn, + :merb => "uses extlib" + }.to_xml_attributes + + attrs.should =~ /some_long_attribute="with short value"/ + attrs.should =~ /merb="uses extlib"/ + attrs.should =~ /crash="burn"/ + end +end + + +describe Hash, 'to_params' do + { + { "foo" => "bar", "baz" => "bat" } => "foo=bar&baz=bat", + { "foo" => [ "bar", "baz" ] } => "foo[]=bar&foo[]=baz", + { "foo" => [ {"bar" => "1"}, {"bar" => 2} ] } => "foo[][bar]=1&foo[][bar]=2", + { "foo" => { "bar" => [ {"baz" => 1}, {"baz" => "2"} ] } } => "foo[bar][][baz]=1&foo[bar][][baz]=2", + { "foo" => {"1" => "bar", "2" => "baz"} } => "foo[1]=bar&foo[2]=baz" + }.each do |hash, params| + it "should covert hash: #{hash.inspect} to params: #{params.inspect}" do + hash.to_params.split('&').sort.should == params.split('&').sort + end + end + + it 'should not leave a trailing &' do + { :name => 'Bob', :address => { :street => '111 Ruby Ave.', :city => 'Ruby Central', :phones => ['111-111-1111', '222-222-2222'] } }.to_params.should_not match(/&$/) + end + + it 'should URL encode unsafe characters' do + {:q => "?&\" +"}.to_params.should == "q=%3F%26%22%20%2B" + end + +end \ No newline at end of file diff --git a/vendor/gems/httparty-0.4.3/spec/httparty/cookie_hash_spec.rb b/vendor/gems/httparty-0.4.3/spec/httparty/cookie_hash_spec.rb new file mode 100644 index 0000000..f142217 --- /dev/null +++ b/vendor/gems/httparty-0.4.3/spec/httparty/cookie_hash_spec.rb @@ -0,0 +1,38 @@ +require File.join(File.dirname(__FILE__), '../spec_helper') + +describe HTTParty::CookieHash do + before(:each) do + @cookie_hash = HTTParty::CookieHash.new + end + + describe "#add_cookies" do + it "should add new key/value pairs to the hash" do + @cookie_hash.add_cookies(:foo => "bar") + @cookie_hash.add_cookies(:rofl => "copter") + @cookie_hash.length.should eql(2) + end + + it "should overwrite any existing key" do + @cookie_hash.add_cookies(:foo => "bar") + @cookie_hash.add_cookies(:foo => "copter") + @cookie_hash.length.should eql(1) + @cookie_hash[:foo].should eql("copter") + end + end + + # The regexen are required because Hashes aren't ordered, so a test against + # a hardcoded string was randomly failing. + describe "#to_cookie_string" do + before(:each) do + @cookie_hash.add_cookies(:foo => "bar") + @cookie_hash.add_cookies(:rofl => "copter") + @s = @cookie_hash.to_cookie_string + end + + it "should format the key/value pairs, delimited by semi-colons" do + @s.should match(/foo=bar/) + @s.should match(/rofl=copter/) + @s.should match(/^\w+=\w+; \w+=\w+$/) + end + end +end diff --git a/vendor/gems/httparty-0.4.3/spec/httparty/request_spec.rb b/vendor/gems/httparty-0.4.3/spec/httparty/request_spec.rb new file mode 100644 index 0000000..02cab3f --- /dev/null +++ b/vendor/gems/httparty-0.4.3/spec/httparty/request_spec.rb @@ -0,0 +1,196 @@ +require File.join(File.dirname(__FILE__), '..', 'spec_helper') + +describe HTTParty::Request do + def stub_response(body, code = 200) + unless @http + @http = Net::HTTP.new('localhost', 80) + @request.stub!(:http).and_return(@http) + @request.stub!(:uri).and_return(URI.parse("http://foo.com/foobar")) + end + + response = Net::HTTPResponse::CODE_TO_OBJ[code.to_s].new("1.1", code, body) + response.stub!(:body).and_return(body) + + @http.stub!(:request).and_return(response) + response + end + + before do + @request = HTTParty::Request.new(Net::HTTP::Get, 'http://api.foo.com/v1', :format => :xml) + end + + describe "#format" do + it "should return the correct parsing format" do + @request.format.should == :xml + end + end + + describe 'http' do + it "should use ssl for port 443" do + request = HTTParty::Request.new(Net::HTTP::Get, 'https://api.foo.com/v1:443') + request.send(:http).use_ssl?.should == true + end + + it 'should not use ssl for port 80' do + request = HTTParty::Request.new(Net::HTTP::Get, 'http://foobar.com') + @request.send(:http).use_ssl?.should == false + end + + it "should use basic auth when configured" do + @request.options[:basic_auth] = {:username => 'foobar', :password => 'secret'} + @request.send(:setup_raw_request) + @request.instance_variable_get(:@raw_request)['authorization'].should_not be_nil + end + end + + describe '#format_from_mimetype' do + it 'should handle text/xml' do + ["text/xml", "text/xml; charset=iso8859-1"].each do |ct| + @request.send(:format_from_mimetype, ct).should == :xml + end + end + + it 'should handle application/xml' do + ["application/xml", "application/xml; charset=iso8859-1"].each do |ct| + @request.send(:format_from_mimetype, ct).should == :xml + end + end + + it 'should handle text/json' do + ["text/json", "text/json; charset=iso8859-1"].each do |ct| + @request.send(:format_from_mimetype, ct).should == :json + end + end + + it 'should handle application/json' do + ["application/json", "application/json; charset=iso8859-1"].each do |ct| + @request.send(:format_from_mimetype, ct).should == :json + end + end + + it 'should handle text/javascript' do + ["text/javascript", "text/javascript; charset=iso8859-1"].each do |ct| + @request.send(:format_from_mimetype, ct).should == :json + end + end + + it 'should handle application/javascript' do + ["application/javascript", "application/javascript; charset=iso8859-1"].each do |ct| + @request.send(:format_from_mimetype, ct).should == :json + end + end + end + + describe 'parsing responses' do + it 'should handle xml automatically' do + xml = %q[1234Foo Bar!] + @request.options[:format] = :xml + @request.send(:parse_response, xml).should == {'books' => {'book' => {'id' => '1234', 'name' => 'Foo Bar!'}}} + end + + it 'should handle json automatically' do + json = %q[{"books": {"book": {"name": "Foo Bar!", "id": "1234"}}}] + @request.options[:format] = :json + @request.send(:parse_response, json).should == {'books' => {'book' => {'id' => '1234', 'name' => 'Foo Bar!'}}} + end + + it 'should handle yaml automatically' do + yaml = "books: \n book: \n name: Foo Bar!\n id: \"1234\"\n" + @request.options[:format] = :yaml + @request.send(:parse_response, yaml).should == {'books' => {'book' => {'id' => '1234', 'name' => 'Foo Bar!'}}} + end + + it "should include any HTTP headers in the returned response" do + @request.options[:format] = :html + response = stub_response "Content" + response.initialize_http_header("key" => "value") + + @request.perform.headers.should == { "key" => ["value"] } + end + + describe 'with non-200 responses' do + + it 'should return a valid object for 4xx response' do + stub_response 'yes', 401 + resp = @request.perform + resp.code.should == 401 + resp.body.should == "yes" + resp['foo']['bar'].should == "yes" + end + + it 'should return a valid object for 5xx response' do + stub_response 'error', 500 + resp = @request.perform + resp.code.should == 500 + resp.body.should == "error" + resp['foo']['bar'].should == "error" + end + + end + end + + it "should not attempt to parse empty responses" do + stub_response "", 204 + + @request.options[:format] = :xml + @request.perform.should be_nil + end + + it "should not fail for missing mime type" do + stub_response "Content for you" + @request.options[:format] = :html + @request.perform.should == 'Content for you' + end + + describe "a request that redirects" do + before(:each) do + @redirect = stub_response("", 302) + @redirect['location'] = '/foo' + + @ok = stub_response('bar', 200) + end + + describe "once" do + before(:each) do + @http.stub!(:request).and_return(@redirect, @ok) + end + + it "should be handled by GET transparently" do + @request.perform.should == {"hash" => {"foo" => "bar"}} + end + + it "should be handled by POST transparently" do + @request.http_method = Net::HTTP::Post + @request.perform.should == {"hash" => {"foo" => "bar"}} + end + + it "should be handled by DELETE transparently" do + @request.http_method = Net::HTTP::Delete + @request.perform.should == {"hash" => {"foo" => "bar"}} + end + + it "should be handled by PUT transparently" do + @request.http_method = Net::HTTP::Put + @request.perform.should == {"hash" => {"foo" => "bar"}} + end + end + + describe "infinitely" do + before(:each) do + @http.stub!(:request).and_return(@redirect) + end + + it "should raise an exception" do + lambda { @request.perform }.should raise_error(HTTParty::RedirectionTooDeep) + end + end + end +end + +describe HTTParty::Request, "with POST http method" do + it "should raise argument error if query is not a hash" do + lambda { + HTTParty::Request.new(Net::HTTP::Post, 'http://api.foo.com/v1', :format => :xml, :query => 'astring').perform + }.should raise_error(ArgumentError) + end +end diff --git a/vendor/gems/httparty-0.4.3/spec/httparty/response_spec.rb b/vendor/gems/httparty-0.4.3/spec/httparty/response_spec.rb new file mode 100644 index 0000000..e3ede68 --- /dev/null +++ b/vendor/gems/httparty-0.4.3/spec/httparty/response_spec.rb @@ -0,0 +1,62 @@ +require File.join(File.dirname(__FILE__), '..', 'spec_helper') + +describe HTTParty::Response do + describe "initialization" do + before do + @response_object = {'foo' => 'bar'} + @body = "{foo:'bar'}" + @code = '200' + @message = 'OK' + @response = HTTParty::Response.new(@response_object, @body, @code, @message) + end + + it "should set delegate" do + @response.delegate.should == @response_object + end + + it "should set body" do + @response.body.should == @body + end + + it "should set code" do + @response.code.should.to_s == @code + end + + it "should set code as a Fixnum" do + @response.code.should be_an_instance_of(Fixnum) + end + + it "should set body" do + @response.body.should == @body + end + end + + it "should be able to set headers during initialization" do + response = HTTParty::Response.new({'foo' => 'bar'}, "{foo:'bar'}", 200, 'OK', {'foo' => 'bar'}) + response.headers.should == {'foo' => 'bar'} + end + + it "should send missing methods to delegate" do + response = HTTParty::Response.new({'foo' => 'bar'}, "{foo:'bar'}", 200, 'OK') + response['foo'].should == 'bar' + end + + it "should be able to iterate delegate if it is array" do + response = HTTParty::Response.new([{'foo' => 'bar'}, {'foo' => 'baz'}], "[{foo:'bar'}, {foo:'baz'}]", 200, 'OK') + response.size.should == 2 + lambda { + response.each { |item| } + }.should_not raise_error + end + + xit "should allow hashes to be accessed with dot notation" do + response = HTTParty::Response.new({'foo' => 'bar'}, "{foo:'bar'}", 200, 'OK') + response.foo.should == 'bar' + end + + xit "should allow nested hashes to be accessed with dot notation" do + response = HTTParty::Response.new({'foo' => {'bar' => 'baz'}}, "{foo: {bar:'baz'}}", 200, 'OK') + response.foo.should == {'bar' => 'baz'} + response.foo.bar.should == 'baz' + end +end \ No newline at end of file diff --git a/vendor/gems/httparty-0.4.3/spec/httparty_spec.rb b/vendor/gems/httparty-0.4.3/spec/httparty_spec.rb new file mode 100644 index 0000000..07c042d --- /dev/null +++ b/vendor/gems/httparty-0.4.3/spec/httparty_spec.rb @@ -0,0 +1,283 @@ +require File.join(File.dirname(__FILE__), 'spec_helper') + +describe HTTParty do + before(:each) do + @klass = Class.new + @klass.instance_eval { include HTTParty } + end + + describe "base uri" do + before(:each) do + @klass.base_uri('api.foo.com/v1') + end + + it "should have reader" do + @klass.base_uri.should == 'http://api.foo.com/v1' + end + + it 'should have writer' do + @klass.base_uri('http://api.foobar.com') + @klass.base_uri.should == 'http://api.foobar.com' + end + + it 'should not modify the parameter during assignment' do + uri = 'http://api.foobar.com' + @klass.base_uri(uri) + uri.should == 'http://api.foobar.com' + end + end + + describe "#normalize_base_uri" do + it "should add http if not present for non ssl requests" do + uri = HTTParty.normalize_base_uri('api.foobar.com') + uri.should == 'http://api.foobar.com' + end + + it "should add https if not present for ssl requests" do + uri = HTTParty.normalize_base_uri('api.foo.com/v1:443') + uri.should == 'https://api.foo.com/v1:443' + end + + it "should not remove https for ssl requests" do + uri = HTTParty.normalize_base_uri('https://api.foo.com/v1:443') + uri.should == 'https://api.foo.com/v1:443' + end + + it 'should not modify the parameter' do + uri = 'http://api.foobar.com' + HTTParty.normalize_base_uri(uri) + uri.should == 'http://api.foobar.com' + end + end + + describe "headers" do + it "should default to empty hash" do + @klass.headers.should == {} + end + + it "should be able to be updated" do + init_headers = {:foo => 'bar', :baz => 'spax'} + @klass.headers init_headers + @klass.headers.should == init_headers + end + end + + describe "cookies" do + def expect_cookie_header(s) + HTTParty::Request.should_receive(:new) \ + .with(anything, anything, hash_including({ :headers => { "cookie" => s } })) \ + .and_return(mock("mock response", :perform => nil)) + end + + it "should not be in the headers by default" do + HTTParty::Request.stub!(:new).and_return(stub(nil, :perform => nil)) + @klass.get("") + @klass.headers.keys.should_not include("cookie") + end + + it "should raise an ArgumentError if passed a non-Hash" do + lambda do + @klass.cookies("nonsense") + end.should raise_error(ArgumentError) + end + + it "should allow a cookie to be specified with a one-off request" do + expect_cookie_header "type=snickerdoodle" + @klass.get("", :cookies => { :type => "snickerdoodle" }) + end + + describe "when a cookie is set at the class level" do + before(:each) do + @klass.cookies({ :type => "snickerdoodle" }) + end + + it "should include that cookie in the request" do + expect_cookie_header "type=snickerdoodle" + @klass.get("") + end + + it "should allow the class defaults to be overridden" do + expect_cookie_header "type=chocolate_chip" + + @klass.get("", :cookies => { :type => "chocolate_chip" }) + end + end + + describe "in a class with multiple methods that use different cookies" do + before(:each) do + @klass.instance_eval do + def first_method + get("first_method", :cookies => { :first_method_cookie => "foo" }) + end + + def second_method + get("second_method", :cookies => { :second_method_cookie => "foo" }) + end + end + end + + it "should not allow cookies used in one method to carry over into other methods" do + expect_cookie_header "first_method_cookie=foo" + @klass.first_method + + expect_cookie_header "second_method_cookie=foo" + @klass.second_method + end + end + end + + describe "default params" do + it "should default to empty hash" do + @klass.default_params.should == {} + end + + it "should be able to be updated" do + new_defaults = {:foo => 'bar', :baz => 'spax'} + @klass.default_params new_defaults + @klass.default_params.should == new_defaults + end + end + + describe "basic http authentication" do + it "should work" do + @klass.basic_auth 'foobar', 'secret' + @klass.default_options[:basic_auth].should == {:username => 'foobar', :password => 'secret'} + end + end + + describe "format" do + it "should allow xml" do + @klass.format :xml + @klass.default_options[:format].should == :xml + end + + it "should allow json" do + @klass.format :json + @klass.default_options[:format].should == :json + end + + it "should allow yaml" do + @klass.format :yaml + @klass.default_options[:format].should == :yaml + end + + it "should allow plain" do + @klass.format :plain + @klass.default_options[:format].should == :plain + end + + it 'should not allow funky format' do + lambda do + @klass.format :foobar + end.should raise_error(HTTParty::UnsupportedFormat) + end + + it 'should only print each format once with an exception' do + lambda do + @klass.format :foobar + end.should raise_error(HTTParty::UnsupportedFormat, "Must be one of: json, plain, html, yaml, xml") + end + + end + + describe "with explicit override of automatic redirect handling" do + + it "should fail with redirected GET" do + lambda do + @klass.get('/foo', :no_follow => true) + end.should raise_error(HTTParty::RedirectionTooDeep) + end + + it "should fail with redirected POST" do + lambda do + @klass.post('/foo', :no_follow => true) + end.should raise_error(HTTParty::RedirectionTooDeep) + end + + it "should fail with redirected DELETE" do + lambda do + @klass.delete('/foo', :no_follow => true) + end.should raise_error(HTTParty::RedirectionTooDeep) + end + + it "should fail with redirected PUT" do + lambda do + @klass.put('/foo', :no_follow => true) + end.should raise_error(HTTParty::RedirectionTooDeep) + end + end + + describe "with multiple class definitions" do + before(:each) do + @klass.instance_eval do + base_uri "http://first.com" + default_params :one => 1 + end + + @additional_klass = Class.new + @additional_klass.instance_eval do + include HTTParty + base_uri "http://second.com" + default_params :two => 2 + end + end + + it "should not run over each others options" do + @klass.default_options.should == { :base_uri => 'http://first.com', :default_params => { :one => 1 } } + @additional_klass.default_options.should == { :base_uri => 'http://second.com', :default_params => { :two => 2 } } + end + end + + describe "#get" do + it "should be able to get html" do + stub_http_response_with('google.html') + HTTParty.get('http://www.google.com').should == file_fixture('google.html') + end + + it "should be able parse response type json automatically" do + stub_http_response_with('twitter.json') + tweets = HTTParty.get('http://twitter.com/statuses/public_timeline.json') + tweets.size.should == 20 + tweets.first['user'].should == { + "name" => "Pyk", + "url" => nil, + "id" => "7694602", + "description" => nil, + "protected" => false, + "screen_name" => "Pyk", + "followers_count" => 1, + "location" => "Opera Plaza, California", + "profile_image_url" => "http://static.twitter.com/images/default_profile_normal.png" + } + end + + it "should be able parse response type xml automatically" do + stub_http_response_with('twitter.xml') + tweets = HTTParty.get('http://twitter.com/statuses/public_timeline.xml') + tweets['statuses'].size.should == 20 + tweets['statuses'].first['user'].should == { + "name" => "Magic 8 Bot", + "url" => nil, + "id" => "17656026", + "description" => "ask me a question", + "protected" => "false", + "screen_name" => "magic8bot", + "followers_count" => "90", + "profile_image_url" => "http://s3.amazonaws.com/twitter_production/profile_images/65565851/8ball_large_normal.jpg", + "location" => nil + } + end + + it "should not get undefined method add_node for nil class for the following xml" do + stub_http_response_with('undefined_method_add_node_for_nil.xml') + result = HTTParty.get('http://foobar.com') + result.should == {"Entities"=>{"href"=>"https://s3-sandbox.parature.com/api/v1/5578/5633/Account", "results"=>"0", "total"=>"0", "page_size"=>"25", "page"=>"1"}} + end + + it "should parse empty response fine" do + stub_http_response_with('empty.xml') + result = HTTParty.get('http://foobar.com') + result.should == nil + end + end +end diff --git a/vendor/gems/httparty-0.4.3/spec/spec.opts b/vendor/gems/httparty-0.4.3/spec/spec.opts new file mode 100644 index 0000000..7113a85 --- /dev/null +++ b/vendor/gems/httparty-0.4.3/spec/spec.opts @@ -0,0 +1,3 @@ +--format + progress +--colour diff --git a/vendor/gems/httparty-0.4.3/spec/spec_helper.rb b/vendor/gems/httparty-0.4.3/spec/spec_helper.rb new file mode 100644 index 0000000..358b484 --- /dev/null +++ b/vendor/gems/httparty-0.4.3/spec/spec_helper.rb @@ -0,0 +1,21 @@ +require 'rubygems' +gem 'rspec' +require 'spec' +require File.join(File.dirname(__FILE__), '..', 'lib', 'httparty') + +def file_fixture(filename) + open(File.join(File.dirname(__FILE__), 'fixtures', "#{filename.to_s}")).read +end + +def stub_http_response_with(filename) + format = filename.split('.').last.intern + data = file_fixture(filename) + + response = Net::HTTPOK.new("1.1", 200, "Content for you") + response.stub!(:body).and_return(data) + + http_request = HTTParty::Request.new(Net::HTTP::Get, 'http://localhost', :format => format) + http_request.stub!(:perform_actual_request).and_return(response) + + HTTParty::Request.should_receive(:new).and_return(http_request) +end \ No newline at end of file diff --git a/vendor/gems/httparty-0.4.3/spec/string_spec.rb b/vendor/gems/httparty-0.4.3/spec/string_spec.rb new file mode 100644 index 0000000..54867a2 --- /dev/null +++ b/vendor/gems/httparty-0.4.3/spec/string_spec.rb @@ -0,0 +1,27 @@ +describe String, "#snake_case" do + it "lowercases one word CamelCase" do + "Merb".snake_case.should == "merb" + end + + it "makes one underscore snake_case two word CamelCase" do + "MerbCore".snake_case.should == "merb_core" + end + + it "handles CamelCase with more than 2 words" do + "SoYouWantContributeToMerbCore".snake_case.should == "so_you_want_contribute_to_merb_core" + end + + it "handles CamelCase with more than 2 capital letter in a row" do + "CNN".snake_case.should == "cnn" + "CNNNews".snake_case.should == "cnn_news" + "HeadlineCNNNews".snake_case.should == "headline_cnn_news" + end + + it "does NOT change one word lowercase" do + "merb".snake_case.should == "merb" + end + + it "leaves snake_case as is" do + "merb_core".snake_case.should == "merb_core" + end +end \ No newline at end of file diff --git a/vendor/gems/httparty-0.4.3/website/css/common.css b/vendor/gems/httparty-0.4.3/website/css/common.css new file mode 100644 index 0000000..61f38ac --- /dev/null +++ b/vendor/gems/httparty-0.4.3/website/css/common.css @@ -0,0 +1,47 @@ +@media screen, projection { + /* + Copyright (c) 2007, Yahoo! Inc. All rights reserved. + Code licensed under the BSD License: + http://developer.yahoo.net/yui/license.txt + version: 2.2.0 + */ + body {font:13px arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small;}table {font-size:inherit;font:100%;}select, input, textarea {font:99% arial,helvetica,clean,sans-serif;}pre, code {font:115% monospace;*font-size:100%;}body * {line-height:1.22em;} + body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;}/*ol,ul {list-style:none;}*/caption,th {text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}q:before,q:after{content:'';}abbr,acronym {border:0;} + /* end of yahoo reset and fonts */ + + body {color:#333; background:#4b1a1a; line-height:1.3;} + p {margin:0 0 20px;} + a {color:#4b1a1a;} + a:hover {text-decoration:none;} + strong {font-weight:bold;} + em {font-style:italics;} + h1,h2,h3,h4,h5,h6 {font-weight:bold;} + h1 {font-size:197%; margin:30px 0; color:#4b1a1a;} + h2 {font-size:174%; margin:20px 0; color:#b8111a;} + h3 {font-size:152%; margin:10px 0;} + h4 {font-size:129%; margin:10px 0;} + pre {background:#eee; margin:0 0 20px; padding:20px; border:1px solid #ccc; font-size:100%; overflow:auto;} + code {font-size:100%; margin:0; padding:0;} + ul, ol {margin:10px 0 10px 25px;} + ol li {margin:0 0 10px;} + + + + + + div#wrapper {background:#fff; width:560px; margin:0 auto; padding:20px; border:10px solid #bc8c46; border-width:0 10px;} + div#header {position:relative; border-bottom:1px dotted; margin:0 0 10px; padding:0 0 10px;} + div#header p {margin:0; padding:0;} + div#header h1 {margin:0; padding:0;} + ul#nav {position:absolute; top:0; right:0; list-style:none; margin:0; padding:0;} + ul#nav li {display:inline; padding:0 0 0 5px;} + ul#nav li a {} + div#content {} + div#footer {margin:40px 0 0; border-top:1px dotted; padding:10px 0 0;} + + + + + + +} \ No newline at end of file diff --git a/vendor/gems/httparty-0.4.3/website/index.html b/vendor/gems/httparty-0.4.3/website/index.html new file mode 100644 index 0000000..79ce7b7 --- /dev/null +++ b/vendor/gems/httparty-0.4.3/website/index.html @@ -0,0 +1,74 @@ + + + + + HTTParty by John Nunemaker + + + + +
+ + +
+

Install

+
$ sudo gem install httparty
+ +

Some Quick Examples

+ +

The following is a simple example of wrapping Twitter's API for posting updates.

+ +
class Twitter
+  include HTTParty
+  base_uri 'twitter.com'
+  basic_auth 'username', 'password'
+end
+
+Twitter.post('/statuses/update.json', :query => {:status => "It's an HTTParty and everyone is invited!"})
+ +

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).

+ +

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:

+ +
class Twitter
+  include HTTParty
+  base_uri 'twitter.com'
+
+  def initialize(u, p)
+    @auth = {:username => u, :password => p}
+  end
+
+  def post(text)
+    options = { :query => {:status => text}, :basic_auth => @auth }
+    self.class.post('/statuses/update.json', options)
+  end
+end
+
+Twitter.new('username', 'password').post("It's an HTTParty and everyone is invited!")
+ +

More Examples: There are several examples in the gem itself.

+ +

Support

+

Conversations welcome in the google group and bugs/features over at Lightouse.

+ + +
+ + +
+ + + \ No newline at end of file