module Typhoeus class RemoteMethod attr_accessor :http_method, :options, :base_uri, :path, :on_success, :on_failure, :cache_ttl def initialize(options = {}) @http_method = options.delete(:method) || :get @options = options @base_uri = options.delete(:base_uri) @path = options.delete(:path) @on_success = options[:on_success] @on_failure = options[:on_failure] @cache_responses = options.delete(:cache_responses) @memoize_responses = options.delete(:memoize_responses) || @cache_responses @cache_ttl = @cache_responses == true ? 0 : @cache_responses @keys = nil clear_cache end def cache_responses? @cache_responses end def memoize_responses? @memoize_responses end def args_options_key(args, options) "#{args.to_s}+#{options.to_s}" end def calling(args, options) @called_methods[args_options_key(args, options)] = true end def already_called?(args, options) @called_methods.has_key? args_options_key(args, options) end def add_response_block(block, args, options) @response_blocks[args_options_key(args, options)] << block end def call_response_blocks(result, args, options) key = args_options_key(args, options) @response_blocks[key].each {|block| block.call(result)} @response_blocks.delete(key) @called_methods.delete(key) end def clear_cache @response_blocks = Hash.new {|h, k| h[k] = []} @called_methods = {} end def merge_options(new_options) merged = options.merge(new_options) if options.has_key?(:params) && new_options.has_key?(:params) merged[:params] = options[:params].merge(new_options[:params]) end argument_names.each {|a| merged.delete(a)} merged.delete(:on_success) if merged[:on_success].nil? merged.delete(:on_failure) if merged[:on_failure].nil? merged end def interpolate_path_with_arguments(args) interpolated_path = @path argument_names.each do |arg| interpolated_path = interpolated_path.gsub(":#{arg}", args[arg].to_s) end interpolated_path end def argument_names return @keys if @keys pattern, keys = compile(@path) @keys = keys.collect {|k| k.to_sym} end # rippped from Sinatra. clean up stuff we don't need later def compile(path) path ||= "" keys = [] if path.respond_to? :to_str special_chars = %w{. + ( )} pattern = path.gsub(/((:\w+)|[\*#{special_chars.join}])/) do |match| case match when "*" keys << 'splat' "(.*?)" when *special_chars Regexp.escape(match) else keys << $2[1..-1] "([^/?&#]+)" end end [/^#{pattern}$/, keys] elsif path.respond_to? :match [path, keys] else raise TypeError, path end end end end