discourse/app/jobs/regular/bulk_invite.rb
Guo Xiang Tan 142571bba0 Remove use of rescue nil.
* `rescue nil` is a really bad pattern to use in our code base.
  We should rescue errors that we expect the code to throw and
  not rescue everything because we're unsure of what errors the
  code would throw. This would reduce the amount of pain we face
  when debugging why something isn't working as expexted. I've
  been bitten countless of times by errors being swallowed as a
  result during debugging sessions.
2018-04-02 13:52:51 +08:00

118 lines
3.1 KiB
Ruby

require 'csv'
require_dependency 'system_message'
module Jobs
class BulkInvite < Jobs::Base
sidekiq_options retry: false
attr_accessor :current_user
def initialize
@logs = []
@sent = 0
@failed = 0
end
def execute(args)
filename = args[:filename]
@current_user = User.find_by(id: args[:current_user_id])
raise Discourse::InvalidParameters.new(:filename) if filename.blank?
csv_path = "#{Invite.base_directory}/#{filename}"
# read csv file, and send out invitations
read_csv_file(csv_path)
ensure
# send notification to user regarding progress
notify_user
FileUtils.rm_rf(csv_path) if csv_path
end
def read_csv_file(csv_path)
file = File.open(csv_path, encoding: 'bom|utf-8')
CSV.new(file).each do |csv_info|
if csv_info[0]
if (EmailValidator.email_regex =~ csv_info[0])
# email is valid
send_invite(csv_info, $INPUT_LINE_NUMBER)
@sent += 1
else
# invalid email
log "Invalid Email '#{csv_info[0]}' at line number '#{$INPUT_LINE_NUMBER}'"
@failed += 1
end
end
end
rescue Exception => e
log "Bulk Invite Process Failed -- '#{e.message}'"
@failed += 1
ensure
file.close
end
def get_group_ids(group_names, csv_line_number)
group_ids = []
if group_names
group_names = group_names.split(';')
group_names.each { |group_name|
group_detail = Group.find_by_name(group_name)
if group_detail
# valid group
group_ids.push(group_detail.id)
else
# invalid group
log "Invalid Group '#{group_name}' at line number '#{csv_line_number}'"
@failed += 1
end
}
end
return group_ids
end
def get_topic(topic_id, csv_line_number)
topic = nil
if topic_id
topic = Topic.find_by_id(topic_id)
if topic.nil?
log "Invalid Topic ID '#{topic_id}' at line number '#{csv_line_number}'"
@failed += 1
end
end
return topic
end
def send_invite(csv_info, csv_line_number)
email = csv_info[0]
group_ids = get_group_ids(csv_info[1], csv_line_number)
topic = get_topic(csv_info[2], csv_line_number)
begin
Invite.invite_by_email(email, @current_user, topic, group_ids)
rescue => e
log "Error inviting '#{email}' -- #{Rails::Html::FullSanitizer.new.sanitize(e.message)}"
@sent -= 1
@failed += 1
end
end
def log(message)
save_log(message)
end
def save_log(message)
@logs << "[#{Time.now}] #{message}"
end
def notify_user
if @current_user
if (@sent > 0 && @failed == 0)
SystemMessage.create_from_system_user(@current_user, :bulk_invite_succeeded, sent: @sent)
else
SystemMessage.create_from_system_user(@current_user, :bulk_invite_failed, sent: @sent, failed: @failed, logs: @logs.join("\n"))
end
end
end
end
end