debian-mirror-gitlab/app/services/issuable/import_csv/base_service.rb

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

99 lines
2.6 KiB
Ruby
Raw Normal View History

2021-01-29 00:20:46 +05:30
# frozen_string_literal: true
module Issuable
module ImportCsv
class BaseService
def initialize(user, project, csv_io)
@user = user
@project = project
@csv_io = csv_io
@results = { success: 0, error_lines: [], parse_error: false }
end
def execute
process_csv
email_results_to_user
@results
end
private
def process_csv
with_csv_lines.each do |row, line_no|
2022-08-27 11:52:29 +05:30
attributes = issuable_attributes_for(row)
2021-01-29 00:20:46 +05:30
2022-11-25 23:54:43 +05:30
if create_issuable(attributes)&.persisted?
2021-01-29 00:20:46 +05:30
@results[:success] += 1
else
@results[:error_lines].push(line_no)
end
end
rescue ArgumentError, CSV::MalformedCSVError
@results[:parse_error] = true
end
2022-08-27 11:52:29 +05:30
def issuable_attributes_for(row)
{
title: row[:title],
description: row[:description],
due_date: row[:due_date]
}
end
2021-01-29 00:20:46 +05:30
def with_csv_lines
csv_data = @csv_io.open(&:read).force_encoding(Encoding::UTF_8)
2021-02-22 17:27:13 +05:30
validate_headers_presence!(csv_data.lines.first)
2021-01-29 00:20:46 +05:30
2021-02-22 17:27:13 +05:30
CSV.new(
csv_data,
2021-01-29 00:20:46 +05:30
col_sep: detect_col_sep(csv_data.lines.first),
headers: true,
header_converters: :symbol
2021-02-22 17:27:13 +05:30
).each.with_index(2)
2021-01-29 00:20:46 +05:30
end
2021-02-22 17:27:13 +05:30
def validate_headers_presence!(headers)
headers.downcase! if headers
return if headers && headers.include?('title') && headers.include?('description')
2021-01-29 00:20:46 +05:30
raise CSV::MalformedCSVError
end
def detect_col_sep(header)
if header.include?(",")
","
elsif header.include?(";")
";"
elsif header.include?("\t")
"\t"
else
raise CSV::MalformedCSVError
end
end
def create_issuable(attributes)
2021-09-30 23:02:18 +05:30
# NOTE: CSV imports are performed by workers, so we do not have a request context in order
# to create a SpamParams object to pass to the issuable create service.
spam_params = nil
2021-11-18 22:05:49 +05:30
create_service = create_issuable_class.new(project: @project, current_user: @user, params: attributes, spam_params: spam_params)
# For now, if create_issuable_class prepends RateLimitedService let's bypass rate limiting
if create_issuable_class < RateLimitedService
create_service.execute_without_rate_limiting
else
create_service.execute
end
2021-01-29 00:20:46 +05:30
end
def email_results_to_user
# defined in ImportCsvService
end
def create_issuable_class
# defined in ImportCsvService
end
end
end
end