lib/weary/resource.rb in weary-0.5.1 vs lib/weary/resource.rb in weary-0.6.0

- old
+ new

@@ -1,135 +1,139 @@ module Weary class Resource - attr_accessor :name, :domain, :with, :requires, :via, :format, :url, :authenticates, :follows, :headers, :oauth, :access_token + attr_reader :name, :via, :with, :requires, :url + attr_accessor :headers def initialize(name) self.name = name self.via = :get self.authenticates = false self.follows = true - self.with = [] - self.requires = [] - self.oauth = false end + # The name of the Resource. Will be a lowercase string, whitespace replaced with underscores. def name=(resource_name) - resource_name = resource_name.to_s unless resource_name.is_a?(String) - @name = resource_name.downcase.strip.gsub(/\s/,'_') + @name = resource_name.to_s.downcase.strip.gsub(/\s/,'_') end + # The HTTP Method used to fetch the Resource def via=(http_verb) verb = HTTPVerb.new(http_verb).normalize @via = if Methods.include?(verb) verb else :get end end - def format=(type) - type = type.downcase if type.is_a?(String) - @format = case type - when *ContentTypes[:json] - :json - when *ContentTypes[:xml] - :xml - when *ContentTypes[:html] - :html - when *ContentTypes[:yaml] - :yaml - when *ContentTypes[:plain] - :plain - else - raise ArgumentError, "#{type} is not a recognized format." - end - end - + # Optional params. Should be an array. Merges with requires if that is set. def with=(params) - if params.is_a?(Hash) - @requires.each { |key| params[key] = nil unless params.has_key?(key) } - @with = params - else - if @requires.nil? - @with = params.collect {|x| x.to_sym} - else - @with = params.collect {|x| x.to_sym} | @requires - end - end + @with = [params].flatten.collect {|x| x.to_sym} + @with = (requires | @with) if requires end + # Required params. Should be an array. Merges with `with` or sets `with`. def requires=(params) - if @with.is_a?(Hash) - params.each { |key| @with[key] = nil unless @with.has_key?(key) } - @requires = params.collect {|x| x.to_sym} - else - @with = @with | params.collect {|x| x.to_sym} - @requires = params.collect {|x| x.to_sym} - end + @requires = [params].flatten.collect {|x| x.to_sym} + with ? @with = (with | @requires) : (@with = @requires) end - def url=(pattern) - if pattern.index("<domain>") - raise StandardError, "Domain flag found but the domain is not defined" if @domain.nil? - pattern = pattern.gsub("<domain>", @domain) - end - pattern = pattern.gsub("<resource>", @name) - pattern = pattern.gsub("<format>", @format.to_s) - @url = pattern + # Sets whether the Resource requires authentication. Always sets to a boolean value. + def authenticates=(bool) + @authenticates = bool ? true : false end - def oauth=(bool) - @authenticates = false if bool - @oauth = if bool - true - else - false - end + # Does the Resource require authentication? + def authenticates? + @authenticates end - def authenticates=(bool) - @oauth = false if bool - @authenticates = if bool - true - else - false - end + # Sets whether the Resource should follow redirection. Always sets to a boolean value. + def follows=(bool) + @follows = (bool ? true : false) end - def authenticates? - @authenticates + # Should the resource follow redirection? + def follows? + @follows end - def oauth? - @oauth + # Set the Resource's URL as a URI + def url=(uri) + @url = URI.parse(uri) end - def access_token=(token) - raise ArgumentError, "Token needs to be an OAuth::AccessToken object" unless token.is_a?(OAuth::AccessToken) - @oauth = true - @access_token = token + # A hash representation of the Resource + def to_hash + {@name.to_sym => { :via => via, + :with => with, + :requires => requires, + :follows => follows?, + :authenticates => authenticates?, + :url => url, + :headers => headers}} end - def follows_redirects? - if @follows - true + # Take parameters, default params, and credentials and build a Request object for this Resource + def build!(params={}, defaults=nil, credentials=nil) + uri = @url + parameters = setup_parameters(params, defaults) + request_opts = setup_options(parameters, credentials) + uri.query = request_opts[:query].to_params if request_opts[:query] + Weary::Request.new(uri.normalize.to_s, @via, request_opts) + end + + # Setup the parameters to make the Request with + def setup_parameters(params={}, defaults=nil) + params = defaults ? defaults.merge(params) : params + find_missing_requirements(params) + remove_unnecessary_params(params) + end + + # Search the given parameters to see if they are missing any required params + def find_missing_requirements(params) + if (@requires && !@requires.empty?) + missing_requirements = @requires - params.keys + raise ArgumentError, "This resource is missing required parameters: '#{missing_requirements.inspect}'" unless missing_requirements.empty? + end + end + + # Remove params that have not been specified with #with + def remove_unnecessary_params(params) + params.delete_if {|k,v| !@with.include?(k) } if (@with && !@with.empty?) + end + + # Setup the options to be passed into the Request + def setup_options(params={}, credentials=nil) + options = {} + prepare_request_body(params, options) + setup_authentication(options, credentials) + options[:no_follow] = true if !follows? + options[:headers] = @headers if !@headers.blank? + options + end + + # Prepare the Request query or body depending on the HTTP method + def prepare_request_body(params, options={}) + if (@via == :post || @via == :put) + options[:body] = params unless params.blank? else - false + options[:query] = params unless params.blank? end + options end - - def to_hash - {@name.to_sym => { :via => @via, - :with => @with, - :requires => @requires, - :follows => follows_redirects?, - :authenticates => authenticates?, - :format => @format, - :url => @url, - :domain => @domain, - :headers => @headers, - :oauth => oauth?, - :access_token => @access_token}} + + # Prepare authentication credentials for the Request + def setup_authentication(options, credentials=nil) + if authenticates? + raise ArgumentError, "This resource requires authentication and no credentials were given." if credentials.blank? + if credentials.is_a?(OAuth::AccessToken) + options[:oauth] = credentials + else + options[:basic_auth] = credentials + end + end + options end end end \ No newline at end of file