def sign_request(method, uri, form_args)
      # Convert non-string keys to strings so the sort works
      args = {}
      if form_args
        form_args.each do |key, value|
          next unless value and value != ""

          key = key.to_s unless key.is_a?(String)
          args[key] = value
        end
      end

      # Add the necessary OAuth args
      args["oauth_version"] = "1.0"
      args["oauth_consumer_key"] = @config[:api_key]
      args["oauth_nonce"] = Digest::MD5.hexdigest("#{Time.now.to_f}#{rand(10 ** 30)}")
      args["oauth_signature_method"] = "HMAC-SHA1"
      args["oauth_timestamp"] = Time.now.utc.to_i
      args["oauth_token"] = @config[:user][:token]

      # RFC 1738 (http://www.ietf.org/rfc/rfc1738.txt) says:
      #
      #     Thus, only alphanumerics, the special characters "$-_.+!*'(),", and
      #     reserved characters used for their reserved purposes may be used
      #     unencoded within a URL.
      #
      # However, if we don't escape apostrophes and parentheses the SmugMug API fails
      # with an invalid signature error:
      #
      #     Error #35, invalid signature (SmugMug::OAuthError)
      #
      # To overcome this, define a new unreserved character list and use this in URI::escape
      unreserved = "\\-_.!~*a-zA-Z\\d"
      unsafe = Regexp.new("[^#{unreserved}]", false, 'N')

      # Sort the params
      sorted_args = []
      args.sort.each do |key, value|
        sorted_args.push("#{key.to_s}=#{URI::escape(value.to_s, unsafe)}")
      end

      postdata = sorted_args.join("&")

      # Final string to hash
      sig_base = "#{method}&#{URI::escape("#{uri.scheme}://#{uri.host}#{uri.path}", unsafe)}&#{URI::escape(postdata, unsafe)}"

      signature = OpenSSL::HMAC.digest(@digest, "#{@config[:oauth_secret]}&#{@config[:user][:secret]}", sig_base)
      signature = URI::escape(Base64.encode64(signature).chomp, unsafe)

      if uri == API_URI
        "#{postdata}&oauth_signature=#{signature}"
      else
        args["oauth_signature"] = signature
        args
      end
    end
def sign_request(method, uri, form_args)
      # Convert non-string keys to strings so the sort works
      args = {}
      if form_args
        form_args.each do |key, value|
          next unless value and value != ""

          key = key.to_s unless key.is_a?(String)
          args[key] = value
        end
      end

      # Add the necessary OAuth args
      args["oauth_version"] = "1.0"
      args["oauth_consumer_key"] = @config[:api_key]
      args["oauth_nonce"] = Digest::MD5.hexdigest("#{Time.now.to_f}#{rand(10 ** 30)}")
      args["oauth_signature_method"] = "HMAC-SHA1"
      args["oauth_timestamp"] = Time.now.utc.to_i
      args["oauth_token"] = @config[:user][:token]

      # RFC 1738 (http://www.ietf.org/rfc/rfc1738.txt) says:
      #
      #     Thus, only alphanumerics, the special characters "$-_.+!*'(),", and
      #     reserved characters used for their reserved purposes may be used
      #     unencoded within a URL.
      #
      # However, if we don't escape apostrophes and parentheses the SmugMug API fails
      # with an invalid signature error:
      #
      #     Error #35, invalid signature (SmugMug::OAuthError)
      #
      # To overcome this, define a new unreserved character list and use this in URI::escape
      unreserved = "\\-_.!~*a-zA-Z\\d"
      unsafe = Regexp.new("[^#{unreserved}]", false, 'N')

      # Sort the params
      sorted_args = []
      args.sort.each do |key, value|
        sorted_args.push("#{key.to_s}=#{URI::escape(value.to_s, unsafe)}")
      end

      postdata = sorted_args.join("&")

      # Final string to hash
      sig_base = "#{method}&#{URI::escape("#{uri.scheme}://#{uri.host}#{uri.path}", unsafe)}&#{URI::escape(postdata, unsafe)}"

      signature = OpenSSL::HMAC.digest(@digest, "#{@config[:oauth_secret]}&#{@config[:user][:secret]}", sig_base)
      signature = URI::escape(Base64.encode64(signature).chomp, unsafe)

      if uri == API_URI
        "#{postdata}&oauth_signature=#{signature}"
      else
        args["oauth_signature"] = signature
        args
      end
    end
Generates an OAuth signature and updates the args with the required fields
 @param [String] method HTTP method that the request is sent as
 @param [String] uri Full URL of the request
 @param [Hash] form_args Args to be passed to the server