aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ievkit/client.rb
diff options
context:
space:
mode:
authorLuc Donnet2015-03-23 21:12:56 +0100
committerLuc Donnet2015-03-23 21:12:56 +0100
commitfa7e745459aefd64086869882fcca73f948b46fa (patch)
treea5df17d4498b4ca612f6398156a667d2593cc76e /lib/ievkit/client.rb
parent0740decc6a2c5117d1dc89e3665774460626f86b (diff)
downloadchouette-core-fa7e745459aefd64086869882fcca73f948b46fa.tar.bz2
Change ruby client for iev server
Diffstat (limited to 'lib/ievkit/client.rb')
-rw-r--r--lib/ievkit/client.rb307
1 files changed, 307 insertions, 0 deletions
diff --git a/lib/ievkit/client.rb b/lib/ievkit/client.rb
new file mode 100644
index 000000000..53eb61074
--- /dev/null
+++ b/lib/ievkit/client.rb
@@ -0,0 +1,307 @@
+require 'sawyer'
+require 'ievkit/arguments'
+require 'ievkit/configurable'
+require 'ievkit/client/jobs'
+
+module Ievkit
+
+ # Client for the Iev API
+ class Client
+
+ include Ievkit::Configurable
+ include Ievkit::Authentication
+ include Ievkit::Client::Jobs
+
+ # Header keys that can be passed in options hash to {#get},{#head}
+ CONVENIENCE_HEADERS = Set.new([:accept, :content_type])
+
+ def initialize(options = {})
+ # Use options passed in, but fall back to module defaults
+ Ievkit::Configurable.keys.each do |key|
+ instance_variable_set(:"@#{key}", options[key] || Ievkit.instance_variable_get(:"@#{key}"))
+ end
+ end
+
+ # Compares client options to a Hash of requested options
+ #
+ # @param opts [Hash] Options to compare with current client options
+ # @return [Boolean]
+ def same_options?(opts)
+ opts.hash == options.hash
+ end
+
+ # Text representation of the client, masking tokens and passwords
+ #
+ # @return [String]
+ def inspect
+ inspected = super
+
+ # mask password
+ inspected = inspected.gsub! @password, "*******" if @password
+ # Only show last 4 of token, secret
+ if @access_token
+ inspected = inspected.gsub! @access_token, "#{'*'*36}#{@access_token[36..-1]}"
+ end
+ if @client_secret
+ inspected = inspected.gsub! @client_secret, "#{'*'*36}#{@client_secret[36..-1]}"
+ end
+
+ inspected
+ end
+
+ # Make a HTTP GET request
+ #
+ # @param url [String] The path, relative to {#api_endpoint}
+ # @param options [Hash] Query and header params for request
+ # @return [Sawyer::Resource]
+ def get(url, options = {})
+ request :get, url, parse_query_and_convenience_headers(options)
+ end
+
+ # Make a HTTP POST request
+ #
+ # @param url [String] The path, relative to {#api_endpoint}
+ # @param options [Hash] Body and header params for request
+ # @return [Sawyer::Resource]
+ def post(url, options = {})
+ request :post, url, options
+ end
+
+ # Make a HTTP PUT request
+ #
+ # @param url [String] The path, relative to {#api_endpoint}
+ # @param options [Hash] Body and header params for request
+ # @return [Sawyer::Resource]
+ def put(url, options = {})
+ request :put, url, options
+ end
+
+ # Make a HTTP PATCH request
+ #
+ # @param url [String] The path, relative to {#api_endpoint}
+ # @param options [Hash] Body and header params for request
+ # @return [Sawyer::Resource]
+ def patch(url, options = {})
+ request :patch, url, options
+ end
+
+ # Make a HTTP DELETE request
+ #
+ # @param url [String] The path, relative to {#api_endpoint}
+ # @param options [Hash] Query and header params for request
+ # @return [Sawyer::Resource]
+ def delete(url, options = {})
+ request :delete, url, options
+ end
+
+ # Make a HTTP HEAD request
+ #
+ # @param url [String] The path, relative to {#api_endpoint}
+ # @param options [Hash] Query and header params for request
+ # @return [Sawyer::Resource]
+ def head(url, options = {})
+ request :head, url, parse_query_and_convenience_headers(options)
+ end
+
+ # Make one or more HTTP GET requests, optionally fetching
+ # the next page of results from URL in Link response header based
+ # on value in {#auto_paginate}.
+ #
+ # @param url [String] The path, relative to {#api_endpoint}
+ # @param options [Hash] Query and header params for request
+ # @param block [Block] Block to perform the data concatination of the
+ # multiple requests. The block is called with two parameters, the first
+ # contains the contents of the requests so far and the second parameter
+ # contains the latest response.
+ # @return [Sawyer::Resource]
+ def paginate(url, options = {}, &block)
+ opts = parse_query_and_convenience_headers(options.dup)
+ if @auto_paginate || @per_page
+ opts[:query][:per_page] ||= @per_page || (@auto_paginate ? 100 : nil)
+ end
+
+ data = request(:get, url, opts)
+
+ if @auto_paginate
+ while @last_response.rels[:next] && rate_limit.remaining > 0
+ @last_response = @last_response.rels[:next].get
+ if block_given?
+ yield(data, @last_response)
+ else
+ data.concat(@last_response.data) if @last_response.data.is_a?(Array)
+ end
+ end
+
+ end
+
+ data
+ end
+
+ # Hypermedia agent for the Iev API
+ #
+ # @return [Sawyer::Agent]
+ def agent
+ @agent ||= Sawyer::Agent.new(api_endpoint, sawyer_options) do |http|
+ http.headers[:accept] = default_media_type
+ http.headers[:content_type] = "application/json"
+ http.headers[:user_agent] = user_agent
+
+ # Activate if authentication is needed
+ #
+ # if basic_authenticated?
+ # http.basic_auth(@login, @password)
+ # elsif token_authenticated?
+ # http.authorization 'token', @access_token
+ # elsif application_authenticated?
+ # http.params = http.params.merge application_authentication
+ # end
+ end
+ end
+
+ # Fetch the root resource for the API
+ #
+ # @return [Sawyer::Resource]
+ def root
+ get "/"
+ end
+
+ # Response for last HTTP request
+ #
+ # @return [Sawyer::Response]
+ def last_response
+ @last_response if defined? @last_response
+ end
+
+ # Duplicate client using client_id and client_secret as
+ # Basic Authentication credentials.
+ # @example
+ # Ievkit.client_id = "foo"
+ # Ievkit.client_secret = "bar"
+ #
+ # # GET https://api.github.com/?client_id=foo&client_secret=bar
+ # Ievkit.get "/"
+ #
+ # Ievkit.client.as_app do |client|
+ # # GET https://foo:bar@api.github.com/
+ # client.get "/"
+ # end
+ def as_app(key = client_id, secret = client_secret, &block)
+ if key.to_s.empty? || secret.to_s.empty?
+ raise ApplicationCredentialsRequired, "client_id and client_secret required"
+ end
+ app_client = self.dup
+ app_client.client_id = app_client.client_secret = nil
+ app_client.login = key
+ app_client.password = secret
+
+ yield app_client if block_given?
+ end
+
+ # Set username for authentication
+ #
+ # @param value [String] GitHub username
+ def login=(value)
+ reset_agent
+ @login = value
+ end
+
+ # Set password for authentication
+ #
+ # @param value [String] GitHub password
+ def password=(value)
+ reset_agent
+ @password = value
+ end
+
+ # Set OAuth access token for authentication
+ #
+ # @param value [String] 40 character GitHub OAuth access token
+ def access_token=(value)
+ reset_agent
+ @access_token = value
+ end
+
+ # Set OAuth app client_id
+ #
+ # @param value [String] 20 character GitHub OAuth app client_id
+ def client_id=(value)
+ reset_agent
+ @client_id = value
+ end
+
+ # Set OAuth app client_secret
+ #
+ # @param value [String] 40 character GitHub OAuth app client_secret
+ def client_secret=(value)
+ reset_agent
+ @client_secret = value
+ end
+
+ # Wrapper around Kernel#warn to print warnings unless
+ # IEVKIT_SILENT is set to true.
+ #
+ # @return [nil]
+ def ievkit_warn(*message)
+ unless ENV['IEVKIT_SILENT']
+ warn message
+ end
+ end
+
+ private
+
+ def reset_agent
+ @agent = nil
+ end
+
+ def request(method, path, data, options = {})
+ if data.is_a?(Hash)
+ options[:query] = data.delete(:query) || {}
+ options[:headers] = data.delete(:headers) || {}
+ if accept = data.delete(:accept)
+ options[:headers][:accept] = accept
+ end
+ end
+
+ @last_response = response = agent.call(method, URI::Parser.new.escape(path.to_s), data, options)
+ response.data
+ end
+
+ # Executes the request, checking if it was successful
+ #
+ # @return [Boolean] True on success, false otherwise
+ def boolean_from_response(method, path, options = {})
+ request(method, path, options)
+ @last_response.status == 204
+ rescue Ievkit::NotFound
+ false
+ end
+
+
+ def sawyer_options
+ opts = {
+ :links_parser => Sawyer::LinkParsers::Hal.new
+ }
+ conn_opts = @connection_options
+ conn_opts[:builder] = @middleware if @middleware
+ conn_opts[:proxy] = @proxy if @proxy
+ opts[:faraday] = Faraday.new(conn_opts)
+
+ opts
+ end
+
+ def parse_query_and_convenience_headers(options)
+ headers = options.fetch(:headers, {})
+ CONVENIENCE_HEADERS.each do |h|
+ if header = options.delete(h)
+ headers[h] = header
+ end
+ end
+ query = options.delete(:query)
+ opts = {:query => options}
+ opts[:query].merge!(query) if query && query.is_a?(Hash)
+ opts[:headers] = headers unless headers.empty?
+
+ opts
+ end
+ end
+end