require "rails" require 'chronic_duration' module CanvasSync class Engine < ::Rails::Engine isolate_namespace CanvasSync initializer "canvas_sync.safe_yaml_classes" do |app| app.config.active_record.yaml_column_permitted_classes ||= [] app.config.active_record.yaml_column_permitted_classes |= [Symbol, ActiveSupport::HashWithIndifferentAccess] ActiveRecord::Base.yaml_column_permitted_classes |= app.config.active_record.yaml_column_permitted_classes rescue end initializer :append_migrations do |app| config.paths["db/migrate"].expanded.each do |expanded_path| app.config.paths["db/migrate"] << expanded_path end # Apartment will modify this, but it doesn't fully support engine migrations, so we'll reset it here ActiveRecord::Migrator.migrations_paths = Rails.application.paths["db/migrate"].to_a end RETENTION_TYPE = { type: 'string', validate: ->(value, *args, errors:, **kwargs) { origExc = ChronicDuration.raise_exceptions ChronicDuration.raise_exceptions = true begin ChronicDuration.parse(value) unless value == nil nil rescue ChronicDuration.DurationParseError errors << " must be nil or a parseable duration" ensure ChronicDuration.raise_exceptions = origExc end } } initializer 'canvas_sync.global_methods' do next if defined?(canvas_sync_client) require 'panda_pal' class ::Object def canvas_sync_client(account_id = nil) org = PandaPal::Organization.current org = org.platform_api(PandaPal::Platform::Canvas) if (PandaPal::Organization.instance_method(:platform_api) rescue nil) Bearcat::Client.new( prefix: org.canvas_url, token: org.canvas_api_token, master_rate_limit: (Rails.env.production? && !!defined?(Redis) && ENV['REDIS_URL'].present?), ) end end rescue LoadError end initializer :integrate_pandapal do require 'panda_pal' Rails.application.reloader.to_prepare do if PandaPal::Organization.respond_to?(:scheduled_task) if PandaPal::Organization.respond_to?(:define_setting) PandaPal::Organization.define_setting(:canvas_sync, { type: 'Hash', required: false, properties: { job_log_retention: { **RETENTION_TYPE }, sync_batch_retention: { **RETENTION_TYPE }, } }) end unless PandaPal::Organization.task_scheduled?(:clean_canvas_sync_logs) PandaPal::Organization.scheduled_task '0 0 3 * * *', :clean_canvas_sync_logs do job_log_retention = ChronicDuration.parse(settings.dig(:canvas_sync, :job_log_retention) || '3 months', keep_zero: true).seconds.ago JobLog.where('updated_at < ?', job_log_retention).delete_all sync_batch_retention = ChronicDuration.parse(settings.dig(:canvas_sync, :sync_batch_retention) || '6 months', keep_zero: true).seconds.ago SyncBatch.where('updated_at < ?', sync_batch_retention).delete_all end end end end rescue LoadError end end end