module Weary class Base @@resources = {} attr_accessor :defaults # Assign credentials to be used when authenticating to a Resource. # Can be a username/password combo, or an OAuth::AccessToken def credentials(username,password='') if username.is_a?(OAuth::AccessToken) @credentials = username else @credentials = {:username => username, :password => password} end end # Each Weary::Base object has its own set of Resources def resources @resources ||= Marshal.load(Marshal.dump(@@resources)) end # Make changes to a Resource given and rebuild the Request method for this object def modify_resource(name) yield resources[name] if block_given? rebuild_method(resources[name]) end # Rebuild the Request Method for a given Resource. This only affects the current instance. def rebuild_method(resource) instance_eval %Q{ def #{resource.name}(params={}) resources[:#{resource.name}].build!(params, @defaults, @credentials) end } end class << self # Getter for class-level resources def resources @@resources end # Declare a resource. Use it with a block to setup the resource # # Methods that are understood are: # [via] Get, Post, etc. Defaults to a GET request # [with] An array of parameters that will be passed to the body or query of the request. If you pass a hash, it will define default values for params keys # [requires] Array of members of :with that are required by the resource. # [authenticates] Boolean value; does the resource require authentication? # [url] The url of the resource. You can use the same flags as #construct_url # [follows] Boolean; Does this follow redirects? Defaults to true # [headers] Set headers for the HTTP Request def get(name,&block) build_resource(name, :get, block) end alias declare get # Declares a Resource to be requested via POST def post(name,&block) build_resource(name, :post, block) end # Declares a Resource to be requested via PUT def put(name,&block) build_resource(name, :put, block) end # Declares a Resource to be requested via DELETE def delete(name,&block) build_resource(name, :delete, block) end # Set custom default Headers for your Request def headers(headers) @headers = headers end # Sets the domain to be used to build default url's def domain(dom) domain = URI.extract(dom) raise ArgumentError, 'The domain must be a URL.' if domain.blank? @domain = URI.parse(domain[0]).normalize.to_s end # Sets a default format, used to build default Resource url's def format(format) @format = format end # Prepare and store the Resource def build_resource(name,verb,block=nil) resource = prepare_resource(name,verb) block.call(resource) if block store_resource(resource) build_method(resource) resource end # Prepare a Resource with set defaults def prepare_resource(name,via = :get) preparation = Weary::Resource.new(name) preparation.via = via preparation.headers = @headers unless @headers.blank? preparation.url = "#{@domain}#{preparation.name}." + (@format || :json).to_s if @domain preparation end # Store the resource for future use def store_resource(resource) @@resources[resource.name.to_sym] = resource resource end # Build a method to form a Request for the given Resource def build_method(resource) define_method resource.name.to_sym do |*args| args.blank? ? params = {} : params = args[0] resource.build!(params, @defaults, @credentials) end end end end end