require "csv" require "activerecord-import" require "zip" require_relative "./report_processor" module CanvasSync module Processors class ProvisioningReportProcessor < ReportProcessor # Processes a provisioning report using the bulk importer. # # options must contain a models key. If there is only one model # Canvas downloads the single report directly as a CSV. If it's # more than one model Canvas downloads a ZIP file, so we have to # extract that and iterate through it for processing. # # @param report_file_path [String] # @param options [Hash] def self.process(report_file_path, options) new(report_file_path, options) end def initialize(report_file_path, options) # rubocop:disable Metrics/AbcSize @options = options if options[:models].length == 1 run_import(options[:models][0], report_file_path) else unzipped_file_path = extract(report_file_path) Dir[unzipped_file_path + "/*.csv"].sort.each do |file_path| model_name = file_path.split("/").last.split(".").first run_import(model_name, file_path) end end end private def extract(file_path) unzipped_file_path = "#{file_path}_unzipped" Zip::File.open(file_path) do |zip_file| zip_file.each do |f| f_path = File.join(unzipped_file_path, f.name) FileUtils.mkdir_p(File.dirname(f_path)) zip_file.extract(f, f_path) unless File.exist?(f_path) end end unzipped_file_path end def run_import(model_name, report_file_path) if @options[:legacy_support] CanvasSync::Importers::LegacyImporter.import( report_file_path, model_name.singularize.capitalize.constantize, @options[:account_id], ) else send("bulk_process_#{model_name}", report_file_path) end end def bulk_process_users(report_file_path) CanvasSync::Importers::BulkImporter.import( report_file_path, mapping[:users][:report_columns], User, mapping[:users][:conflict_target].to_sym, ) end def bulk_process_accounts(report_file_path) CanvasSync::Importers::BulkImporter.import( report_file_path, mapping[:accounts][:report_columns], Account, mapping[:accounts][:conflict_target].to_sym ) end def bulk_process_courses(report_file_path) CanvasSync::Importers::BulkImporter.import( report_file_path, mapping[:courses][:report_columns], Course, mapping[:courses][:conflict_target].to_sym, ) end def bulk_process_enrollments(report_file_path) CanvasSync::Importers::BulkImporter.import( report_file_path, mapping[:enrollments][:report_columns], Enrollment, mapping[:enrollments][:conflict_target].to_sym, ) end def bulk_process_sections(report_file_path) CanvasSync::Importers::BulkImporter.import( report_file_path, mapping[:sections][:report_columns], Section, mapping[:sections][:conflict_target].to_sym, ) end def bulk_process_xlist(report_file_path) CanvasSync::Importers::BulkImporter.import( report_file_path, mapping[:xlist][:report_columns], Section, mapping[:xlist][:conflict_target].to_sym, ) end end end end