class Travis::Client::Session

Constants

PRIMITIVE
SSL_OPTIONS

Attributes

access_token[R]
agent_info[R]
connection[R]
debug_http[RW]
faraday_adapter[R]
headers[R]
instruments[R]
ssl[R]

Public Class Methods

new(options = Travis::Client::ORG_URI) click to toggle source
# File lib/travis/client/session.rb, line 26
def initialize(options = Travis::Client::ORG_URI)
  @headers         = {}
  @cache           = {}
  @instruments     = []
  @agent_info      = []
  @config          = nil
  @faraday_adapter = defined?(Typhoeus) ? :typhoeus : :net_http
  @ssl             = SSL_OPTIONS

  options = { :uri => options } unless options.respond_to? :each_pair
  options.each_pair { |key, value| public_send("#{key}=", value) }

  raise ArgumentError, "neither :uri nor :connection specified" unless connection
  headers['Accept'] = 'application/vnd.travis-ci.2+json'
  set_user_agent
  check_ssl
end

Public Instance Methods

access_token=(token) click to toggle source
# File lib/travis/client/session.rb, line 73
def access_token=(token)
  clear_cache!
  @access_token = token
  headers['Authorization'] = "token #{token}"
  headers.delete('Authorization') unless token
end
agent_info=(info) click to toggle source
# File lib/travis/client/session.rb, line 48
def agent_info=(info)
  @agent_info = [info].flatten.freeze
  set_user_agent
end
clear_cache() click to toggle source
# File lib/travis/client/session.rb, line 234
def clear_cache
  reset_entities
  clear_find_cache
  self
end
clear_cache!() click to toggle source
# File lib/travis/client/session.rb, line 240
def clear_cache!
  reset_entities
  @cache.clear
  self
end
config() click to toggle source
# File lib/travis/client/session.rb, line 133
def config
  @config ||= get_raw('/config')['config'] || {}
end
connection=(connection) click to toggle source
# File lib/travis/client/session.rb, line 80
def connection=(connection)
  clear_cache!
  connection.headers.merge! headers
  @config     = nil
  @connection = connection
  @headers    = connection.headers
end
delete(*args) click to toggle source
# File lib/travis/client/session.rb, line 169
def delete(*args)
  load delete_raw(*args)
end
delete_raw(*args) click to toggle source
# File lib/travis/client/session.rb, line 201
def delete_raw(*args)
  raw(:delete, *args)
end
faraday_adapter=(adapter) click to toggle source
# File lib/travis/client/session.rb, line 67
def faraday_adapter=(adapter)
  @faraday_adapter = adapter
  self.uri &&= uri
  set_user_agent
end
find_many(entity, args = {}) click to toggle source
# File lib/travis/client/session.rb, line 100
def find_many(entity, args = {})
  raise Travis::Client::Error, "cannot fetch #{entity}" unless entity.respond_to?(:many) and entity.many
  cached(entity, :many, args) { fetch_many(entity, args) }
end
find_one(entity, id = nil) click to toggle source
# File lib/travis/client/session.rb, line 94
def find_one(entity, id = nil)
  raise Travis::Client::Error, "cannot fetch #{entity}" unless entity.respond_to?(:many) and entity.many
  return create_entity(entity, entity.id_field => id) if entity.id? id
  cached(entity, :by, id) { fetch_one(entity, id) }
end
find_one_or_many(entity, args = nil) click to toggle source
# File lib/travis/client/session.rb, line 105
def find_one_or_many(entity, args = nil)
  raise Travis::Client::Error, "cannot fetch #{entity}" unless entity.respond_to?(:many) and entity.many
  cached(entity, :one_or_many, args) do
    path       = "/#{entity.many}"
    path, args = "#{path}/#{args}", {} unless args.is_a? Hash
    result     = get(path, args)
    one        = result[entity.one]

    if result.include? entity.many
      Array(one) + Array(result[entity.many])
    else
      one
    end
  end
end
get(*args) click to toggle source
# File lib/travis/client/session.rb, line 165
def get(*args)
  load get_raw(*args)
end
get_raw(*args) click to toggle source
# File lib/travis/client/session.rb, line 185
def get_raw(*args)
  raw(:get, *args)
end
headers=(headers) click to toggle source
# File lib/travis/client/session.rb, line 88
def headers=(headers)
  clear_cache!
  connection.headers = headers if connection
  @headers = headers
end
inspect() click to toggle source
# File lib/travis/client/session.rb, line 230
def inspect
  "#<#{self.class}: #{uri}>"
end
instrument(&block) click to toggle source
# File lib/travis/client/session.rb, line 250
def instrument(&block)
  instruments << block
end
load(data) click to toggle source
# File lib/travis/client/session.rb, line 137
def load(data)
  result = {}
  (data || {}).each_pair do |key, value|
    entity      = load_entity(key, value)
    result[key] = entity if entity
  end
  result
end
load_entity(key, value) click to toggle source
# File lib/travis/client/session.rb, line 146
def load_entity(key, value)
  type = Entity.subclass_for(key)
  if value.respond_to? :to_ary
    value.to_ary.map { |e| create_entity(type, e) }
  else
    create_entity(type, value)
  end
rescue IndexError
end
patch(*args) click to toggle source
# File lib/travis/client/session.rb, line 173
def patch(*args)
  load patch_raw(*args)
end
patch_raw(*args) click to toggle source
# File lib/travis/client/session.rb, line 197
def patch_raw(*args)
  raw(:patch, *args)
end
post(*args) click to toggle source
# File lib/travis/client/session.rb, line 177
def post(*args)
  load post_raw(*args)
end
post_raw(*args) click to toggle source
# File lib/travis/client/session.rb, line 189
def post_raw(*args)
  raw(:post, *args)
end
preload(list) click to toggle source
# File lib/travis/client/session.rb, line 156
def preload(list)
  list.group_by(&:class).each do |type, instances|
    next unless type.preloadable?
    ids = instances.map { |e| e.id unless e.complete? }.compact
    find_many(type, :ids => ids) if ids.any?
  end
  list
end
private_channels?() click to toggle source
# File lib/travis/client/session.rb, line 254
def private_channels?
  !!config['pusher']['private']
end
put(*args) click to toggle source
# File lib/travis/client/session.rb, line 181
def put(*args)
  load put_raw(*args)
end
put_raw(*args) click to toggle source
# File lib/travis/client/session.rb, line 193
def put_raw(*args)
  raw(:put, *args)
end
raw(verb, url, *args) click to toggle source
# File lib/travis/client/session.rb, line 205
def raw(verb, url, *args)
  url     = url.sub(/^\//, '')
  result  = instrumented(verb.to_s.upcase, url, *args) do
    if url !~ /^https?:/ or url.start_with? api_endpoint
      connection.public_send(verb, url, *args)
    else
      Faraday.public_send(verb, url, *args) { |r| r.headers.delete("Authorization") }
    end
  end

  case result.status
  when 0             then raise Travis::Client::SSLError, 'SSL error: could not verify peer'
  when 200..299      then JSON.parse(result.body) rescue result.body
  when 301, 303      then raw(:get, result.headers['Location'])
  when 302, 307, 308 then raw(verb, result.headers['Location'])
  when 401           then raise Travis::Client::NotLoggedIn,      'not logged in'
  when 403           then raise Travis::Client::NotLoggedIn,      'invalid access token'
  when 404           then raise Travis::Client::NotFound,         result.body
  when 422           then raise Travis::Client::ValidationFailed, result.body
  when 400..499      then raise Travis::Client::Error,            "%s: %p" % [result.status, result.body]
  when 500..599      then raise Travis::Client::Error,            "server error (%s: %p)" % [result.status, result.body]
  else raise Travis::Client::Error, "unhandled status code #{result.status}"
  end
end
reload(entity) click to toggle source
# File lib/travis/client/session.rb, line 126
def reload(entity)
  reset(entity)
  result = fetch_one(entity.class, entity.id)
  entity.update_attributes(result.attributes) if result.attributes != entity.attributes
  result
end
reset(entity) click to toggle source
# File lib/travis/client/session.rb, line 121
def reset(entity)
  entity.attributes.clear
  entity
end
session() click to toggle source
# File lib/travis/client/session.rb, line 246
def session
  self
end
ssl=(options) click to toggle source
# File lib/travis/client/session.rb, line 53
def ssl=(options)
  @ssl     = options.dup.freeze
  self.uri = uri if uri
end
uri() click to toggle source
# File lib/travis/client/session.rb, line 44
def uri
  connection.url_prefix.to_s if connection
end
uri=(uri) click to toggle source
# File lib/travis/client/session.rb, line 58
def uri=(uri)
  clear_cache!
  self.connection = Faraday.new(:url => uri, :ssl => ssl) do |faraday|
    faraday.request  :url_encoded
    faraday.response :logger if debug_http
    faraday.adapter(*faraday_adapter)
  end
end

Private Instance Methods

adapter_version(adapter) click to toggle source
# File lib/travis/client/session.rb, line 266
def adapter_version(adapter)
  version = Object.const_get(adapter).const_get("VERSION")
  [*version].join('.')
rescue Exception
  "unknown"
end
cached(*keys) { || ... } click to toggle source
# File lib/travis/client/session.rb, line 326
def cached(*keys)
  last  = keys.pop
  cache = keys.inject(@cache) { |store, key| store[key] ||= {} }
  cache[last] ||= yield
end
check_ssl() click to toggle source
# File lib/travis/client/session.rb, line 332
def check_ssl
  raw(:head, '/') if ssl == SSL_OPTIONS
rescue SSLError => error
  self.ssl = {}
end
clear_find_cache() click to toggle source
# File lib/travis/client/session.rb, line 306
def clear_find_cache
  subcaches do |subcache|
    subcache.delete_if { |k, v| k != :id }
  end
end
create_entity(type, data) click to toggle source
# File lib/travis/client/session.rb, line 282
def create_entity(type, data)
  return data if primitive?(data)
  data   = { type.id_field => data } if type.id? data
  id     = type.cast_id(data.fetch(type.id_field)) unless type.weak?
  entity = id ? cached(type, :id, id) { type.new(self, id) } : type.new(self, nil)
  entity.update_attributes(data)
  entity
end
error_message(e) click to toggle source
# File lib/travis/client/session.rb, line 295
def error_message(e)
  message = e.response[:body].to_str rescue e.message
  JSON.parse(message).fetch('error').fetch('message') rescue message
end
fetch_many(entity, params = {}) click to toggle source
# File lib/travis/client/session.rb, line 322
def fetch_many(entity, params = {})
  get("/#{entity.base_path}/", params)[entity.many]
end
fetch_one(entity, id = nil) click to toggle source
# File lib/travis/client/session.rb, line 318
def fetch_one(entity, id = nil)
  get("/#{entity.base_path}/#{id}")[entity.one]
end
instrumented(name, *args) { || ... } click to toggle source
# File lib/travis/client/session.rb, line 273
def instrumented(name, *args)
  name   = [name, *args.map(&:inspect)].join(" ") if args.any?
  result = nil
  chain  = instruments + [proc { |n,l| result = yield }]
  lift   = proc { chain.shift.call(name, lift) }
  lift.call
  result
end
primitive?(data) click to toggle source
# File lib/travis/client/session.rb, line 291
def primitive?(data)
  PRIMITIVE.include? data
end
reset_entities() click to toggle source
# File lib/travis/client/session.rb, line 300
def reset_entities
  subcaches do |subcache|
    subcache[:id].each_value { |e| e.attributes.clear } if subcache.include? :id
  end
end
set_user_agent() click to toggle source
# File lib/travis/client/session.rb, line 260
def set_user_agent
  adapter = Array === faraday_adapter ? faraday_adapter.first : faraday_adapter
  adapter = adapter.to_s.capitalize.gsub(/_http_(.)/) { "::HTTP::#{$1.upcase}" }.gsub(/_http/, '::HTTP')
  headers['User-Agent'] = "Travis/#{Travis::VERSION} (#{Travis::Tools::System.description(agent_info)}) Faraday/#{Faraday::VERSION} #{adapter}/#{adapter_version(adapter)}"
end
subcaches() { |subcache| ... } click to toggle source
# File lib/travis/client/session.rb, line 312
def subcaches
  @cache.each_value do |subcache|
    yield subcache if subcache.is_a? Hash
  end
end