class Ecoportal::API::V1::People

@attr_reader client [Common::Client] a `Common::Client` object that holds the configuration of the api connection.

Constants

DELAY_STATUS_CHECK
JOB_TIMEOUT
JobStatus

Attributes

client[R]

Public Class Methods

new(client) click to toggle source

@param client [Common::Client] a `Common::Client` object that holds the configuration of the api connection. @return [People] an instance object ready to make people api requests.

# File lib/ecoportal/api/v1/people.rb, line 19
def initialize(client)
  @client = client
end

Public Instance Methods

batch(job_mode: true) { |operation| ... } click to toggle source

Creates a `BatchOperation` and yields it to the given bock. @yield [batch_op] adds multiple api requests for the current batch. @yieldparam batch_op [BatchOperation]

# File lib/ecoportal/api/v1/people.rb, line 120
def batch(job_mode: true, &block)
  return job(&block) if job_mode
  operation = Common::BatchOperation.new("/people", person_class, logger: client.logger)
  yield operation
  # The batch operation is responsible for logging the output
  client.without_response_logging do
    client.post("/people/batch", data: operation.as_json).tap do |response|
      operation.process_response(response)
    end
  end
end
create(doc) click to toggle source

Requests to create a person via api. @param doc [Person, Hash] data that at least contains an `id` (internal or external) of the target person. @return [Response] an object with the api response.

# File lib/ecoportal/api/v1/people.rb, line 95
def create(doc)
  body = get_body(doc)
  client.post("/people", data: body)
end
delete(doc) click to toggle source

Requests to completelly remove from an organization an existing person via api. @param doc [Person, Hash] data that at least contains an `id` (internal or external) of the target person. @return [Response] an object with the api response.

# File lib/ecoportal/api/v1/people.rb, line 112
def delete(doc)
  id = get_id(doc)
  client.delete("/people/"+CGI.escape(id))
end
each(params: {}, silent: false) { |person_class| ... } click to toggle source

Iterates all the people of the organization. @note

- it ignores the key `cursor_id:` of `params:`.
- `each` is called by `to_a`

@param params [Hash] @option params [String] :per_page the number of people you get per request. @option params [String] :q some text to search. Omit this parameter to target all the people. @param silent [Boolean] `false` to show percentage of progress. @yield [person] does some stuff with the person. @yieldparam person [Person]

# File lib/ecoportal/api/v1/people.rb, line 33
def each(params: {}, silent: false, &block)
  return to_enum(:each, params: params, silent: silent) unless block
  cursor_id = nil; results = 0
  puts "\n" unless silent
  loop do
    params.update(cursor_id: cursor_id) if cursor_id
    response = client.get("/people", params: params)
    body     = response && body_data(response.body)
    raise "Request failed - Status #{response.status}: #{body}" unless response.success?

    unless silent || (total = body["total_results"]) == 0
      results += body["results"].length
      percent  = results * 100 / total
      msg      = "People GET"
      msg     += " (search=#{params[:q]})" if params.key?(:q)
      print "#{msg}: #{percent.round}% (of #{total})\r"
      $stdout.flush
    end

    body["results"].each do |person|
      yield person_class.new(person)
    end
    break unless (cursor_id = body["cursor_id"])
  end
  self
end
get(doc) click to toggle source

Gets a person via api. @note if the request has `success?` the returned `object.result` gives an object with that `Person`. @param doc [String, Hash, Person] data containing an `id` (internal or external) of the target person. @return [Person] the person with `id` (internal or external) contained in `doc`.

# File lib/ecoportal/api/v1/people.rb, line 75
def get(doc)
  id       = get_id(doc)
  response = client.get("/people/"+CGI.escape(id))
  body     = body_data(response.body)
  return person_class.new(body) if response.success?
  raise "Could not get person #{id} - Error #{reponse.status}: #{body}"
end
get_all(params: {}, silent: false) click to toggle source

Gets all the people via api requests. @note it ignores the key `:cursor_id` in `params:`. @param params [Hash] @option params [Integer] :per_page the number of people you get per request. @option params [String] :q some text to search. @param silent [Boolean] `false` to show percentage of progress. @return [Array<Person>] the array of people got via api.

# File lib/ecoportal/api/v1/people.rb, line 67
def get_all(params: {}, silent: false)
  each(params: params, silent: silent).to_a
end
job() { |operation| ... } click to toggle source
# File lib/ecoportal/api/v1/people.rb, line 132
def job
  operation = Common::BatchOperation.new("/people", person_class, logger: client.logger)
  yield operation
  # The batch operation is responsible for logging the output
  job_id = create_job(operation)
  status = wait_for_job_completion(job_id)

  if status&.complete?
    operation.process_response job_result(job_id, operation)
  else
    msg = "Job `#{job_id}` not complete. Probably timeout after #{JOB_TIMEOUT} seconds. Current status: #{status}"
    raise API::Errors::TimeOut.new msg
  end
end
new() click to toggle source

Creates a new `Person` object. @return [Person] new empty person object of the current version.

# File lib/ecoportal/api/v1/people.rb, line 149
def new
  person_class.new
end
update(doc) click to toggle source

Requests an update of a person via api. @param doc [Person, Hash] data that at least contains an `id` (internal or external) of the target person. @return [Response] an object with the api response.

# File lib/ecoportal/api/v1/people.rb, line 86
def update(doc)
  body = get_body(doc)
  id   = get_id(doc)
  client.patch("/people/"+CGI.escape(id), data: body)
end
upsert(doc) click to toggle source

Requests to update an existing person or if it does not exist, to create it, via api. @param doc [Person, Hash] data that at least contains an `id` (internal or external) of the target person. @return [Response] an object with the api response.

# File lib/ecoportal/api/v1/people.rb, line 103
def upsert(doc)
  body = get_body(doc)
  id   = get_id(doc)
  client.post("/people/"+CGI.escape(id), data: body)
end

Private Instance Methods

body_data(body) click to toggle source

Hook for other api versions to obtain the raw data of a response @note this was introduced to allow `v2` to reuse this class

# File lib/ecoportal/api/v1/people.rb, line 203
def body_data(body)
  body
end
create_job(operation) click to toggle source
# File lib/ecoportal/api/v1/people.rb, line 190
def create_job(operation)
  job_id = nil
  client.without_response_logging do
    client.post("/people/job", data: operation.as_json).tap do |response|
      job_id = body_data(response.body)["id"] if response.success?
    end
    raise "Could not create job - Error (#{response.status}): #{body_data(response.body)}" unless job_id
  end
  job_id
end
job_result(job_id, operation) click to toggle source
# File lib/ecoportal/api/v1/people.rb, line 168
def job_result(job_id, operation)
  # The batch operation is responsible for logging the output
  client.without_response_logging do
    client.get("/people/job/#{CGI.escape(job_id)}").tap do |response|
      operation.process_response(response)
    end
  end
end
job_status(job_id) click to toggle source
# File lib/ecoportal/api/v1/people.rb, line 156
def job_status(job_id)
  response = client.get("/people/job/#{CGI.escape(job_id)}/status")
  body     = response && body_data(response.body)
  raise "Status error (#{response.status}) - Errors: #{body}" unless response.success?
  JobStatus.new(
    body["id"],
    body["complete"],
    body["errored"],
    body["progress"]
  )
end
wait_for_job_completion(job_id) click to toggle source
# File lib/ecoportal/api/v1/people.rb, line 177
def wait_for_job_completion(job_id)
  # timeout library is evil. So we make poor-man timeout.
  # https://jvns.ca/blog/2015/11/27/why-rubys-timeout-is-dangerous-and-thread-dot-raise-is-terrifying/
  before = Time.now
  while true
    status = job_status(job_id)
    break status if status.complete?
    break status if Time.now >= before + JOB_TIMEOUT
    sleep(DELAY_STATUS_CHECK)
    status
  end
end