require 'mechanize' module Tap module Mechanize # A Configurable version of the WWW::Mechanize class. class Agent < ::WWW::Mechanize include Configurable DEFAULT_ATTRIBUTES = DEFAULT_ATTRIBUTES.dup DEFAULT_ATTRIBUTES[nil] = {:reader => false, :writer => false} config :ca_file, nil config :cert, nil config :conditional_requests, true, &c.switch config :follow_meta_refresh, false, &c.switch config :keep_alive, true, &c.switch config :keep_alive_time, 300, &c.integer_or_nil config :key, nil config :open_timeout, nil config :pass, nil config :read_timeout, nil config :redirect_ok, true, &c.switch config :redirection_limit, 20, &c.integer_or_nil config :user_agent, "WWW-Mechanize/0.9.2 (http://rubyforge.org/projects/mechanize/)" config :verify_callback, nil config :watch_for_set, nil def initialize(config={}) super() initialize_config(config) end # Fetches the specified request. Request must be a hash at least # specifying a url; these are the allowed keys and defaults: # # url:: nil, must be specified # request_method:: get # params:: {} # headers:: {} # def fetch(request) request = symbolize(request) # note get handles nil request methods (ie '') and has to # reassign uri to url to make mechanize happy case request[:request_method].to_s when /get/i, '' then get(request.merge(:url => request[:uri])) when /post/i then submit(prepare_form(request), nil) when /head/i then head(nil, nil, request) when /put/i then put(nil, nil, request) when /delete/i then delete(nil, nil, request) else raise "unsupported request method: #{request.inspect}" end end protected # taken from ActiveSupport def symbolize(hash) # :nodoc: hash.inject({}) do |options, (key, value)| options[(key.to_sym rescue key) || key] = value options end end # A subclass of Hash used exclusively as the node for a form. # Evidently a search method is necessary. class FormNode < Hash # :nodoc: def search(*args); []; end end # prepares a Mechanize::Form for the request. this method is patterned # after what happens in Mechanize#post and hopefully will not be # necessary in the future. def prepare_form(request) # :nodoc: node = FormNode.new node['method'] = request[:request_method] node['action'] = request[:uri] node['enctype'] = request[:headers] ? request[:headers]['Content-Type'] : nil form = Form.new(node) request[:params].each_pair do |key, value| case value when IO form.enctype = 'multipart/form-data' upload = Form::FileUpload.new(key.to_s, ::File.basename(value.path)) upload.file_data = value.read form.file_uploads << upload when Array fields = value.collect {|val| Form::Field.new(key.to_s, val)} form.fields.concat fields else form.fields << Form::Field.new(key.to_s, value) end end form end end end end