module Eco module API class Session class Batch # @attr_reader job [Eco::API::Session::Batch::Job] `batch job` the feedback is associated with class Feedback class << self def person_ref(entry) row_str = (row = get_row(entry)) ? "(row: #{row}) " : nil "#{row_str}(id: '#{get_attr(entry, :id)}') '#{get_attr(entry, :name)}' ('#{get_attr(entry, :external_id)}': '#{get_attr(entry, :email)}')" end def get_attr(entry, attr) if entry.respond_to?(attr.to_sym) entry.public_send(attr.to_sym) elsif entry.is_a?(Hash) entry["#{attr}"] end end def get_row(value) case value when Eco::API::Common::People::PersonEntry value.idx when Ecoportal::API::V1::Person get_row(value.entry) end end end attr_reader :job # @param job [Eco::API::Session::Batch::Job] `batch job` the feedback is associated with def initialize(job:) raise "A Eco::API::Session::Batch::Job object is required. Given: #{job}" unless job.is_a?(Eco::API::Session::Batch::Job) @job = job end # @!group Job shortcut methods # @see Eco::API::Session::Batch::Job#name # @return [String] name of the `batch job` def name job.name end # @see Eco::API::Session::Batch::Job#type def type job.type end # @see Eco::API::Session::Batch::Job#sets def sets job.sets end # @see Eco::API::Session::Batch::Job#options def options job.options end # @see Eco::API::Session::Batch::Job#requests def job_requests job.requests end # @!endgroup # @!group Pure feedback methods # Slightly modifies the behaviour of `Ecoportal::API::Common::BaseModel#as_update`, so schema details fields show the `alt_id` # It also fixes possible patch updates that are incomplete or unnecessary. # @note for better feedback # @param entry [Hash, Ecoportal::API::V1::Person, Ecoportal::API::Internal::Person] # @param add_feedback [Boolean] if `true` it tweak the hash update with additional data. def as_update(entry, add_feedback: true) case when entry.is_a?(Hash) hash = entry else #entry.is_a?(Ecoportal::API::V1::Person) if only_ids? hash = entry.as_json.slice("id", "external_id", "email") else hash = entry.as_update if add_feedback && details = hash["details"] if hfields = details["fields"] hfields.each do |fld| fld.merge!("alt_id" => entry.details.get_field(fld["id"]).alt_id) end end end if account = hash["account"] if account.keys == ["send_invites"] && !account["send_invites"] hash.delete("account") hash.delete("id") if hash.keys == ["id"] end end end end hash || {} end # @note if `requests` is not provided, it uses the last requests of the parent `Batch::Job` `job` # @param requests [Enumerable] raw requests as they would be sent to the _Server_ # @return [Eco::API::Session::Batch::RequestStats] the stats object of the current requests def request_stats(requests = nil) requests ||= job.requests return @request_stats if @request_stats && requests == job.requests @request_stats ||= Eco::API::Session::Batch::RequestStats.new(type: type, requests: requests) end # Generates the lines of feedback of the current requests # @note if `requests` is not provided, it uses the last requests of the parent `Batch::Job` `job` # @param requests [Enumerable] raw requests as they would be sent to the _Server_ # @param max_chars [Integer] the max number of characters for the current feedback message # @param only_stats [Boolean] whether or not should only include a brief summary of stats # @return [String] the feedback message def generate(requests = nil, max_chars: 800, only_stats: false) requests ||= job.requests [].tap do |msg| if !requests || !requests.is_a?(Enumerable) || requests.empty? msg << "#{"*" * 10} Nothing for #{signature} so far :) #{"*" * 10}" else header = "#{"*"*10} #{signature} - Feedback Sample #{"*"*10}" msg << header unless only_stats unless only_stats sample_length = 1 sample = requests.slice(0, 20).map do |request| max_chars -= request.pretty_inspect.length sample_length += 1 if max_chars > 0 request end msg << "#{sample.slice(0, sample_length).pretty_inspect}" end stats_str = "#{"+"*3} #{type.to_s.upcase} length: #{requests.length} #{"+"*3} STATS (job '#{name}') #{"+"*3}" msg << "#{"-"*stats_str.length}" if only_stats msg << stats_str msg << "#{request_stats(requests).message}" msg << "#{"-"*stats_str.length}" if only_stats msg << "*" * header.length unless only_stats end end.join("\n") end # @!endgroup private def only_ids? [:delete, :get].include?(type) end def signature "Batch job \"#{name}\" ['#{type.to_s.upcase}': #{sets_title}]" end def sets_title "#{sets.map {|s| s.to_s}.join(", ")}" end end end end end end