# @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" 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 = 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:) if stage = target.stages.get_by_name(name) yield(stage) if block_given? end stage end private # Hook method to use before the target is switched def before_loading_new_target(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) logger.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 && 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) logger.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! logger.info("Successful update of #{object_reference(ooze)}") else logger.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)}" logger.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"] logger.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) unless options.dig(:feedback, :only_stats) if patch = (patch_doc(entry) || {})["page"] pp patch end end 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| logger.error(validation) if validation.is_a?(String) end display_patch(entry) backup_patch!(entry) if dirty?(entry) && dry_count > self.class::DRY_COUNT logger.info("Reached #{self.class::DRY_COUNT} dry-run samples.") exit(0) end false end def apiv2 @apiv2 ||= session.api(version: :oozes) end def exit_error(msg) logger.error(msg) exit(1) end end