talho/openphin

View on GitHub
lib/user_importer.rb

Summary

Maintainability
D
1 day
Test Coverage
=begin
    OpenPHIN is an opensource implementation of the CDC guidelines for 
    a public health information network.
    
    Copyright (C) 2009  Texas Association of Local Health Officials

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as
    published by the Free Software Foundation, either version 3 of the
    License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

=end
require 'csv'

class UserImporter
  FIELDS = [ :email, :first_name, :last_name, :display_name, :jurisdiction, :mobile, :fax, :phone ].freeze

  def self.import_users(filename, options={})
    options = {:col_sep => ",", :row_sep => :auto, :update => false, :create => true,
               :default_jurisdiction => nil, :default_password => self.generate_random_password}.merge(options)
    CSV.open(filename, :headers => true, :col_sep => options[:col_sep], :row_sep => options[:row_sep]) do |records|
      records.each do |rec|
        email, first_name, last_name, display_name, jurisdiction, mobile, fax, phone = FIELDS.collect { |f| rec[f.to_s] }
        if email.blank?
          $stderr.puts "CSV File did not contain an email address for the user: \n" + 
            rec.values_at.join(",")  + 
            "\n This user was NOT created.\n\n"       
          next
        end
        if options[:update] && options[:create]
          user=User.find_or_create_by_email(email)
          user.update_password(options[:default_password]) if user.new_record?          
        elsif options[:update]
          user=User.find_by_email(email)
          next if user.nil?
        elsif options[:create]
          user=User.find_by_email(email)
          next unless user.nil?
          user=User.create(:email => email)
          user.update_password(options[:default_password])
        else
          raise "At least one of :update or :create must be true"
        end
        user.update_attributes(:first_name => first_name,
                               :last_name => last_name,
                               :display_name => display_name) if user.new_record?
        unless user.save && user.valid?
          $stderr.puts "CSV format appears invalid for the user: \n" + 
            rec.values_at.join(",") + 
            user.errors.full_messages.join(", ") +
            "\n This user was NOT created.\n\n"
          next
        end

        userdevices = user.devices
        unless mobile.blank? || userdevices.detect{|u| u.type == "Device::PhoneDevice" && u.phone == mobile}
          mobile_device = create_device(Device::PhoneDevice, :phone, mobile)
          user.devices << mobile_device if mobile_device.valid?
        end

        unless phone.blank? || userdevices.detect{|u| u.type == "Device::PhoneDevice" && u.phone == phone}
          phone_device = create_device(Device::PhoneDevice, :phone, phone)
          user.devices << phone_device if phone_device.valid?
        end

        unless fax.blank?  || userdevices.detect{|u| u.type == "Device::FaxDevice" && u.fax == fax}
          fax_device = create_device(Device::FaxDevice, :fax, fax)
          user.devices << fax_device if fax_device.valid?
        end

        j=Jurisdiction.find_by_name(jurisdiction) unless jurisdiction.blank?
        j=options[:default_jurisdiction] if j.nil? && options[:default_jurisdiction]
        user.role_memberships.create(:jurisdiction => j, :role => Role.public) unless j.nil? || user.jurisdictions.include?(j)
        user.email_confirmed = true  # instead of user.confirm_email!() so the token is not cleared
        user.send(:generate_confirmation_token)
        user.save
        SignupMailer.signup_notification(user).deliver
      end
    end
  end

  def self.create_device(klass, method, value)
    dev=klass.new
    dev.send("#{method}=", value.strip)
    dev
  end

  def self.jurisdiction_transform(filename, options = {})
    options = {:col_sep => ",", :row_sep => :auto, :default_jurisdiction => "Texas"}.merge(options)
    CSV.open(filename, :headers => true, :col_sep => options[:col_sep], :row_sep => options[:row_sep]) do |records|
      puts records.first.headers.join(",")
      records.each do |rec|
        email, first_name, last_name, display_name, jurisdiction, mobile, fax, phone = FIELDS.collect { |f| rec[f.to_s] }
        puts rec.values_at.join(",") if jurisdiction == options[:default_jurisdiction]
      end
    end
  end

  def self.generate_random_password(length=16)
    chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
    (1..length).collect { |n| chars[rand(chars.length)] }.to_s + 'aZ9'
  end
end