# @attr_reader target [Ecoportal::API::V2::Page] current target ooze. class Eco::API::UseCases::OozeSamples::OozeBaseCase < Eco::API::Common::Loaders::UseCase name "ooze-base" type :other include Eco::API::UseCases::OozeSamples::Helpers include Eco::API::UseCases::OozeSamples::Helpers::Rescuable attr_reader :target SAVE_PATCH = "ooze_patch_update.json".freeze DRY_COUNT = 5 def main(_session, options, _usecase) options[:end_get] = false raise "You need to inherit from this class ('#{self.class}') and call super with a block" unless block_given? @target = nil yield end # Write here your script def process_ooze(ooz = target) ooz ||= ooze raise "You need to inherit from this class ('#{self.class}') and call super with a block" unless block_given? yield(ooz) update_ooze(ooz) end protected def new_page(template_id) apiv2.pages.get_new(template_id) end def create_page(page = nil, template_id: nil, retrieve: false) template_id = template_id.id if template_id.is_a?(Ecoportal::API::V2::Page) template_id ||= page.template_id if page.respond_to?(:template_id) template_id ||= page["template_id"] if page.is_a?(Hash) page = new_page(template_id) unless page || !template_id yield(page) if block_given? reference = apiv2.pages.create(page, from: template_id) ooze_id = reference.page_id stage_id = reference.active_stage_id return [ooze_id, stage_id] unless retrieve ooze(ooze_id, stage_id: stage_id) end def add_field_by_doc(doc, section, entry: target, after: nil, before: nil, side: :left) unless section.is_a?(Ecoportal::API::V2::Page::Section) raise "You need to specify a section for a new field. Given: #{section.class}" end entry.components.add(doc: doc) do |field| section.add_component(field, after: after, before: before, side: side) end.tap do |field| yield(field) if block_given? end end def add_field(name, type, section, entry: target, after: nil, before: nil, side: :left) unless section.is_a?(Ecoportal::API::V2::Page::Section) raise "You need to specify a section for a new field. Given: #{section.class}" end entry.components.add(label: name, type: type) do |field| section.add_component(field, after: after, before: before, side: side) end.tap do |field| yield(field) if block_given? end end def with_fields(entry = target, type: nil, label: nil) flds = entry.components if type if flds.respond_to?(:get_by_type) flds = flds.get_by_type(type) else flds = flds.select {|fld| fld.type == type} end end flds.select do |fld| value = label == :unnamed ? nil : label !label || same_string?(fld.label, value) end.each do |field| yield(field) if block_given? end end def with_sections(entry = target, type: nil, heading: nil) secs = entry.sections secs = secs.get_by_type(type) if type secs.select do |sec| value = heading == :unnamed ? nil : heading !heading || same_string?(sec.heading, value) end.each do |sec| yield(sec) if block_given? end end def with_stage(name:) return unless (stage = target.stages.get_by_name(name)) yield(stage) if block_given? stage end private # Hook method to use before the target is switched def before_loading_new_target(ooze_id) ooze_id end def ooze(ooze_id = nil, stage_id: nil) return target unless ooze_id before_loading_new_target(ooze_id) apiv2.pages.get(ooze_id, stage_id: stage_id).tap do |ooze| if ooze new_target(ooze) log(:info) { "Got #{object_reference(ooze)}" } else exit_error "Could not get ooze '#{ooze_id}'" end end end def stage(id_name = nil, ooze: target) if (ooze_id = ooze&.id) exit_error "#{object_reference(ooze)} does not have stages!" unless ooze.stages? else exit_error "There's no target ooze to retrieve stages from" end if (stg = ooze.stages[id_name] || ooze.stages.get_by_name(id_name)) return ooze if ooze.respond_to?(:current_stage_id) && (ooze.current_stage_id == stg.id) before_loading_new_target(ooze_id) return apiv2.pages.get(ooze_id, stage_id: stg.id).tap do |stage| if stage new_target(stage) log(:info) { "Got #{object_reference(stage)} from #{object_reference(ooze)}" } else exit_error "Could not get stage '#{id_name}' in ooze '#{ooze_id}'" end end end exit_error "Stage '#{id_name}' doesn't exist in ooze '#{ooze_id}'" end # It fill update the ooze only if it's dirty (it carries changes) # @return [Boolean, Response] `false` if there was not request against the server, `Response` otherwise def update_ooze(ooze = target) if dry_run? dry_run_feedback(ooze) false else return false unless dirty?(ooze) ooze.validate.tap do |validation| raise validation if validation.is_a?(String) end apiv2.pages.update(ooze).tap do |response| if response.success? ooze.consolidate! log(:info) { "Successful update of #{object_reference(ooze)}" } else log(:error) { "Could not update #{object_reference(ooze)} (created_at: #{ooze.created_at}: #{response.body}" } end end end end def new_target(object, warn_pending_changes: true) if dirty?(target) if warn_pending_changes msg = "You you are switching to a new target #{object_reference(object)}" msg += " after doing unsaved changes to #{object_reference(target)}" log(:warn) { msg } end yield(target) if block_given? end @target = object end def dirty?(object) object && patch_doc(object)["page"] end def backup_patch!(ooze = target) unless (patch = (patch_doc(ooze) || {})["page"]) log(:info) { "No changes to update for #{object_reference(ooze)}." } return end patch = patch_doc(ooze) # store the request File.open(SAVE_PATCH, "w") do |file| #file << (patch_doc || {}).to_json file << JSON.pretty_generate(patch || {}) end # TODO: ooze_requests folder with subfolders: for each run puts "Saved patch at: #{File.expand_path(SAVE_PATCH)}" end def display_patch(entry = target) return if options.dig(:feedback, :only_stats) return unless (patch = (patch_doc(entry) || {})["page"]) pp patch end def patch_doc(ooze = target) apiv2.pages.get_body(ooze) end def dry_count @dry_count ||= 0 @dry_count += 1 end def dry_run_feedback(entry = target) entry.validate.tap do |validation| log(:error) { validation } if validation.is_a?(String) end display_patch(entry) backup_patch!(entry) if dirty?(entry) && dry_count > self.class::DRY_COUNT log(:info) { "Reached #{self.class::DRY_COUNT} dry-run samples." } exit(0) end false end def apiv2 # rubocop:disable Naming/VariableNumber @apiv2 ||= session.api(version: :oozes) # rubocop:disable Naming/VariableNumber end def exit_error(msg) log(:error) { msg } exit(1) end end