60 lines
2.2 KiB
Ruby
60 lines
2.2 KiB
Ruby
#
|
|
# Copyright (C) 2011 - present Instructure, Inc.
|
|
#
|
|
# This file is part of Canvas.
|
|
#
|
|
# Canvas 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, version 3 of the License.
|
|
#
|
|
# Canvas 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/>.
|
|
class CsvWithI18n < CSV
|
|
|
|
BYTE_ORDER_MARK = "\xEF\xBB\xBF".freeze
|
|
|
|
def initialize(data, **options)
|
|
@include_bom = options.delete(:include_bom)
|
|
super(data, options)
|
|
raise 'include_bom and write_headers cannot both be true' if self.write_headers? && @include_bom
|
|
end
|
|
|
|
def <<(row)
|
|
if @include_bom && !@bom_written
|
|
@io.write(BYTE_ORDER_MARK)
|
|
@bom_written = true
|
|
end
|
|
super(row)
|
|
end
|
|
|
|
def self.csv_i18n_settings(user, options = {})
|
|
options[:col_sep] ||= determine_column_separator(user)
|
|
options[:encoding] ||= I18n.t('csv.encoding', 'UTF-8')
|
|
|
|
# Wikipedia: Microsoft compilers and interpreters, and many pieces of software on Microsoft Windows such as
|
|
# Notepad treat the BOM as a required magic number rather than use heuristics. These tools add a BOM when saving
|
|
# text as UTF-8, and cannot interpret UTF-8 unless the BOM is present or the file contains only ASCII.
|
|
# https://en.wikipedia.org/wiki/Byte_order_mark#UTF-8
|
|
options[:include_bom] = include_bom?(user, options[:encoding])
|
|
|
|
options
|
|
end
|
|
|
|
def self.include_bom?(user, encoding)
|
|
encoding == 'UTF-8' && user.feature_enabled?(:include_byte_order_mark_in_gradebook_exports)
|
|
end
|
|
private_class_method :include_bom?
|
|
|
|
def self.determine_column_separator(user)
|
|
return ';' if user.feature_enabled?(:use_semi_colon_field_separators_in_gradebook_exports)
|
|
return ',' unless user.feature_enabled?(:autodetect_field_separators_for_gradebook_exports)
|
|
I18n.t('number.format.separator', '.') == ',' ? ';' : ','
|
|
end
|
|
private_class_method :determine_column_separator
|
|
end
|