module PandaPal module OrganizationConcerns module OrganizationBuilder extend ActiveSupport::Concern include OrganizationConcerns::SettingsValidation class InteractiveSessionError < StandardError attr_reader :source_code def initialize(message, source_code) super(message) @source_code = source_code end def print puts cause&.message, cause&.backtrace puts "" puts message puts "Code is below for tweaking and/or using it in a Rails console" puts "" puts source_code puts "" end end class_methods do def _interactive_save!(org) code = org.generate_orgbuilder_ruby tries = 0 result = nil loop do begin code = ConsoleHelpers.open_string_editor(code, name: "organization.rb", require_save: tries == 0) rescue => ex raise InteractiveSessionError.new("Failed to open interactive editor", code) end if code == :aborted puts "Aborted" return end begin result = eval(code, TOPLEVEL_BINDING) break rescue => ex puts "Failed to save Organization: #{ex}" if !ConsoleHelpers.prompt_yes_no("Retry?") raise InteractiveSessionError.new("Failed to save Organization", code) end tries += 1 end end result end def interactive_create!(org = PandaPal::Organization.new) result = _interactive_save!(org) if result&.persisted? && ConsoleHelpers.prompt_yes_no("Organization created. Install in Canvas?", default: false) result.interactive_install! end result end if Rails.env.development? def development_create! if PandaPal::Organization.count > 0 return unless ConsoleHelpers.prompt_yes_no("An Organization is already set up. Continue?") end org = PandaPal::Organization.new( name: "local", canvas_account_id: "1", key: "#{_panda_pal_console_app_name}-local", secret: "#{_panda_pal_console_app_name}-local", salesforce_id: "1", ) rcsettings = ConsoleHelpers.pandapalrc["settings"] || {} cleaned_settings = PandaPal::Organization.remove_undeclared_settings(rcsettings) org.settings = cleaned_settings result = interactive_create!(org) return unless result puts "Created Development Organization: #{result.name}" result.switch_tenant end end end def interactive_update! saved = self.class._interactive_save!(self) puts "Organization Updated" if saved saved end def interactive_install!(host: nil, exists: :error) first = true loop do # If a host is explicitly passed, don't prompt for it on the first try unless first && host.present? if Rails.env.development? host ||= ConsoleHelpers.pandapalrc["lti_host"].presence || "http://localhost:5000" end host = ConsoleHelpers.prompt("Specify LTI host:", default: host) end begin install_lti(host: host, exists: exists) break rescue => ex puts "Failed to install in Canvas: #{ex}" raise ex unless ConsoleHelpers.prompt_pry_retry first = false end end end def generate_orgbuilder_ruby code = ConsoleHelpers::CodeBuilder.new columns = %w[ canvas_account_id key secret salesforce_id ] if self.persisted? code << "PandaPal::Organization.find_by(name: \"#{self.name}\").update!(" else code << "PandaPal::Organization.create!(" columns.unshift("name") end code << "\n" code.block do columns.each do |col| code << "#{col}: \"#{self.send(col)}\"," code << "\n" end code << "settings: " code << PandaPal::Organization.generate_settings_ruby(value: settings) code << ",\n" end code << ")" code.to_s end end end end