2014-08-09 18:28:57 +08:00
|
|
|
require 'csv'
|
|
|
|
require_dependency 'system_message'
|
|
|
|
|
|
|
|
module Jobs
|
|
|
|
|
|
|
|
class ExportCsvFile < Jobs::Base
|
2014-11-12 16:42:50 +08:00
|
|
|
CSV_USER_ATTRS = ['id','name','username','email','title','created_at','trust_level','active','admin','moderator','ip_address']
|
|
|
|
CSV_USER_STATS = ['topics_entered','posts_read_count','time_read','topic_count','post_count','likes_given','likes_received']
|
2014-11-26 06:43:17 +08:00
|
|
|
CSV_USER_SSO_ATTRS = ['external_id','external_email', 'external_username', 'external_name', 'external_avatar_url']
|
2014-11-21 23:25:04 +08:00
|
|
|
SCREENED_IP_ATTRS = ['ip_address','action_type','match_count','last_match_at','created_at']
|
2014-11-20 01:09:23 +08:00
|
|
|
|
2014-08-09 18:28:57 +08:00
|
|
|
sidekiq_options retry: false
|
|
|
|
attr_accessor :current_user
|
|
|
|
|
|
|
|
def initialize
|
|
|
|
@file_name = ""
|
|
|
|
end
|
|
|
|
|
|
|
|
def execute(args)
|
|
|
|
entity = args[:entity]
|
|
|
|
@current_user = User.find_by(id: args[:user_id])
|
|
|
|
|
|
|
|
|
2014-11-26 06:43:17 +08:00
|
|
|
data =
|
|
|
|
if entity == 'user'
|
|
|
|
user_export
|
|
|
|
elsif entity == 'screened_ips'
|
|
|
|
screened_ips_export
|
|
|
|
else
|
|
|
|
raise Discourse::InvalidParameters.new(:entity) if entity.blank?
|
|
|
|
end
|
2014-08-09 18:28:57 +08:00
|
|
|
|
|
|
|
if data && data.length > 0
|
|
|
|
set_file_path
|
2014-11-21 23:25:04 +08:00
|
|
|
header = get_header(entity)
|
|
|
|
write_csv_file(data, header)
|
2014-08-09 18:28:57 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
notify_user
|
|
|
|
end
|
|
|
|
|
2014-11-26 06:43:17 +08:00
|
|
|
def user_export
|
|
|
|
query = ::AdminUserIndexQuery.new
|
|
|
|
user_data = query.find_users_query.to_a
|
|
|
|
user_data.map do |user|
|
|
|
|
group_names = get_group_names(user).join(';')
|
|
|
|
user_array = get_user_fields(user)
|
|
|
|
user_array.push(group_names) if group_names != ''
|
|
|
|
user_array
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
def screened_ips_export
|
|
|
|
screened_ips_data = ScreenedIpAddress.order('id desc').to_a
|
|
|
|
screened_ips_data.map do |screened_ip|
|
|
|
|
get_screened_ip_fields(screened_ip)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def get_header(entity)
|
|
|
|
|
|
|
|
case entity
|
|
|
|
when 'user'
|
|
|
|
header_array = CSV_USER_ATTRS + CSV_USER_STATS
|
|
|
|
if SiteSetting.enable_sso
|
|
|
|
header_array.concat(CSV_USER_SSO_ATTRS)
|
|
|
|
end
|
|
|
|
user_custom_fields = UserField.all
|
|
|
|
if user_custom_fields.present?
|
|
|
|
user_custom_fields.each do |custom_field|
|
|
|
|
header_array.push("#{custom_field.name} (custom user field)")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
header_array.push("group_names")
|
|
|
|
when 'screened_ips'
|
|
|
|
header_array = SCREENED_IP_ATTRS
|
|
|
|
end
|
|
|
|
|
|
|
|
header_array
|
|
|
|
end
|
|
|
|
|
2014-08-09 18:28:57 +08:00
|
|
|
private
|
|
|
|
|
2014-09-06 23:41:05 +08:00
|
|
|
def get_group_names(user)
|
2014-11-21 23:25:04 +08:00
|
|
|
group_names = []
|
2014-10-24 03:06:45 +08:00
|
|
|
groups = user.groups
|
2014-09-06 23:41:05 +08:00
|
|
|
groups.each do |group|
|
|
|
|
group_names.push(group.name)
|
|
|
|
end
|
|
|
|
return group_names
|
|
|
|
end
|
|
|
|
|
2014-11-03 23:04:51 +08:00
|
|
|
def get_user_fields(user)
|
2014-11-21 23:25:04 +08:00
|
|
|
user_array = []
|
2014-11-03 23:04:51 +08:00
|
|
|
|
2014-11-12 16:42:50 +08:00
|
|
|
CSV_USER_ATTRS.each do |attr|
|
2014-11-08 22:07:21 +08:00
|
|
|
user_array.push(user.attributes[attr])
|
2014-11-03 23:04:51 +08:00
|
|
|
end
|
|
|
|
|
2014-11-12 16:42:50 +08:00
|
|
|
CSV_USER_STATS.each do |stat|
|
2014-11-08 22:07:21 +08:00
|
|
|
user_array.push(user.user_stat.attributes[stat])
|
2014-11-03 23:04:51 +08:00
|
|
|
end
|
|
|
|
|
2014-11-26 06:43:17 +08:00
|
|
|
if SiteSetting.enable_sso
|
|
|
|
sso = user.single_sign_on_record
|
|
|
|
CSV_USER_SSO_ATTRS.each do |stat|
|
|
|
|
field = sso.attributes[stat] if sso
|
|
|
|
user_array.push(field)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-11-12 16:42:50 +08:00
|
|
|
if user.user_fields.present?
|
|
|
|
user.user_fields.each do |custom_field|
|
|
|
|
user_array.push(custom_field[1])
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-11-26 06:43:17 +08:00
|
|
|
user_array
|
2014-11-03 23:04:51 +08:00
|
|
|
end
|
|
|
|
|
2014-11-21 23:25:04 +08:00
|
|
|
def get_screened_ip_fields(screened_ip)
|
|
|
|
screened_ip_array = []
|
2014-11-12 16:42:50 +08:00
|
|
|
|
2014-11-21 23:25:04 +08:00
|
|
|
SCREENED_IP_ATTRS.each do |attr|
|
|
|
|
screened_ip_array.push(screened_ip.attributes[attr])
|
|
|
|
end
|
|
|
|
|
2014-11-26 06:43:17 +08:00
|
|
|
screened_ip_array
|
2014-11-21 23:25:04 +08:00
|
|
|
end
|
|
|
|
|
2014-11-12 16:42:50 +08:00
|
|
|
|
2014-08-09 18:28:57 +08:00
|
|
|
def set_file_path
|
|
|
|
@file_name = "export_#{SecureRandom.hex(4)}.csv"
|
|
|
|
# ensure directory exists
|
|
|
|
dir = File.dirname("#{ExportCsv.base_directory}/#{@file_name}")
|
|
|
|
FileUtils.mkdir_p(dir) unless Dir.exists?(dir)
|
|
|
|
end
|
|
|
|
|
2014-11-21 23:25:04 +08:00
|
|
|
def write_csv_file(data, header)
|
2014-08-09 18:28:57 +08:00
|
|
|
# write to CSV file
|
|
|
|
CSV.open(File.expand_path("#{ExportCsv.base_directory}/#{@file_name}", __FILE__), "w") do |csv|
|
2014-11-21 23:25:04 +08:00
|
|
|
csv << header
|
2014-08-09 18:28:57 +08:00
|
|
|
data.each do |value|
|
2014-08-16 01:53:17 +08:00
|
|
|
csv << value
|
2014-08-09 18:28:57 +08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def notify_user
|
|
|
|
if @current_user
|
|
|
|
if @file_name != "" && File.exists?("#{ExportCsv.base_directory}/#{@file_name}")
|
2014-11-20 01:09:23 +08:00
|
|
|
SystemMessage.create_from_system_user(@current_user, :csv_export_succeeded, download_link: "#{Discourse.base_url}/admin/export_csv/#{@file_name}", file_name: @file_name)
|
2014-08-09 18:28:57 +08:00
|
|
|
else
|
|
|
|
SystemMessage.create_from_system_user(@current_user, :csv_export_failed)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|