lib/ecoportal/api/v1/people.rb in ecoportal-api-0.9.7 vs lib/ecoportal/api/v1/people.rb in ecoportal-api-0.10.0
- old
+ new
@@ -1,15 +1,16 @@
module Ecoportal
module API
class V1
- # @attr_reader client [Common::Client] a `Common::Client` object that holds the configuration of the api connection.
+ # @attr_reader client [Common::Client] a `Common::Client` object that
+ # holds the configuration of the api connection.
class People
extend Common::BaseClass
- include Enumerable
include Common::DocHelpers
+ include Enumerable
- JOB_TIMEOUT = 240
+ JOB_TIMEOUT = 240
DELAY_STATUS_CHECK = 5
class_resolver :person_class, "Ecoportal::API::V1::Person"
attr_reader :client
@@ -28,39 +29,53 @@
# @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]
- def each(params: {}, silent: false, &block)
- return to_enum(:each, params: params, silent: silent) unless block
- cursor_id = nil; results = 0
+ def each(params: {}, silent: false) # rubocop:disable Metrics/AbcSize
+ return to_enum(:each, params: params, silent: silent) unless block_given?
+
+ cursor_id = nil
+ results = 0
+
puts "\n" unless silent
+
loop do
params.update(cursor_id: cursor_id) if cursor_id
- body = nil; response = nil; count = 5
+
+ body = nil
+ response = nil
+ count = 5
+
loop do
response = client.get("/people", params: params)
body = response && body_data(response.body)
break if response.success? || count <= 0
+
puts "Request failed - Status #{response.status}: #{body}"
count -= 1
+
sleep(0.5)
end
+
raise "Request failed - Status #{response.status}: #{body}" unless response.success?
- unless silent || (total = body["total_results"]) == 0
+ unless silent || (total = body["total_results"])&.zero?
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"
+ msg << " (search=#{params[:q]})" if params.key?(:q)
+
+ print "#{msg}: #{percent.round}% (of #{total}): #{results}\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
@@ -79,23 +94,24 @@
# @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`.
def get(doc)
id = get_id(doc)
- response = client.get("/people/"+CGI.escape(id))
+ 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 #{response.status}: #{body}"
end
# 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.
def update(doc)
body = get_body(doc)
id = get_id(doc)
- client.patch("/people/"+CGI.escape(id), data: body)
+ client.patch("/people/#{CGI.escape(id)}", data: body)
end
# 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.
@@ -108,48 +124,64 @@
# @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.
def upsert(doc)
body = get_body(doc)
id = get_id(doc)
- client.post("/people/"+CGI.escape(id), data: body)
+ client.post("/people/#{CGI.escape(id)}", data: body)
end
# 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.
def delete(doc)
id = get_id(doc)
- client.delete("/people/"+CGI.escape(id))
+ client.delete("/people/#{CGI.escape(id)}")
end
# 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]
# @param job_mode [Boolean] whether or not it should use batch jobs
# @return [Ecoportal::API::Common::Response] the results of the batch
def batch(job_mode: true, &block)
return job(&block) if job_mode
- operation = Common::BatchOperation.new("/people", person_class, logger: client.logger)
+
+ operation = Common::BatchOperation.new(
+ "/people",
+ person_class,
+ logger: client.logger
+ )
+
yield operation
+
# The batch operation is responsible for logging the output
client.post("/people/batch", data: operation.as_json).tap do |response|
operation.process_response(response)
end
end
# @return [Ecoportal::API::Common::Response] the results of the batch job
def job
- operation = Common::BatchOperation.new("/people", person_class, logger: client.logger)
+ operation = Common::BatchOperation.new(
+ "/people",
+ person_class,
+ logger: client.logger
+ )
+
yield operation
+
job_id = create_job(operation)
status = wait_for_job_completion(job_id)
if status&.complete?
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
+ msg = "Job `#{job_id}` not complete. "
+ msg << "Probably timeout after #{JOB_TIMEOUT} seconds. "
+ msg << "Current status: #{status}"
+
+ raise API::Errors::TimeOut, msg
end
end
# Creates a new `Person` object.
# @return [Person] new empty person object of the current version.
@@ -158,14 +190,19 @@
end
private
JobStatus = Struct.new(:id, :complete?, :errored?, :progress)
+
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?
+
+ msg = "Status error (#{response.status}) - "
+ msg << "Errors: #{body}"
+ raise msg unless response.success?
+
JobStatus.new(
body["id"],
body["complete"],
body["errored"],
body["progress"]
@@ -181,14 +218,16 @@
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
+
+ loop do
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
@@ -205,10 +244,9 @@
# Hook for other api versions to obtain the raw data of a response
# @note this was introduced to allow `v2` to reuse this class
def body_data(body)
body
end
-
end
end
end
end