73 lines
2.8 KiB
Ruby
73 lines
2.8 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'google/apis/sheets_v4'
|
|
module SpreadsheetBackends
|
|
class GoogleSheets
|
|
# Hash to translate an index to a A1 notation. e.g. 1 => 'B', 27 => 'AA'
|
|
COLUMN_INDEX_TO_LETTER = Hash.new { |hash, key| hash[key] = hash[key - 1].next }.merge({ 0 => 'A' })
|
|
|
|
attr_accessor :form, :user
|
|
|
|
def initialize(form)
|
|
@form = form
|
|
@user = form.user
|
|
end
|
|
|
|
def url
|
|
"https://docs.google.com/spreadsheets/d/#{form.google_spreadsheet_id}/edit" if form.google_spreadsheet_id.present?
|
|
end
|
|
|
|
def append(data)
|
|
data = data.with_indifferent_access
|
|
check_spreadsheed_headers!(data)
|
|
|
|
values = headers.map { |key| data[key] }
|
|
range = "A1:A#{COLUMN_INDEX_TO_LETTER[values.length]}1"
|
|
value_range = Google::Apis::SheetsV4::ValueRange.new(values: [values], major_dimension: 'ROWS')
|
|
|
|
result = spreadsheet_service.append_spreadsheet_value(form.google_spreadsheet_id, range, value_range, value_input_option: 'USER_ENTERED')
|
|
result.updates.updated_rows > 0
|
|
end
|
|
|
|
def create
|
|
sheets = Google::Apis::SheetsV4::SheetsService.new
|
|
sheets.authorization = user.google_authorization
|
|
create_object = Google::Apis::SheetsV4::Spreadsheet.new(properties: { title: form.title })
|
|
spreadsheet = sheets.create_spreadsheet(create_object)
|
|
form.update(google_spreadsheet_id: spreadsheet.spreadsheet_id)
|
|
end
|
|
|
|
def headers
|
|
@headers ||= begin
|
|
values = spreadsheet_service.get_spreadsheet_values(form.google_spreadsheet_id, 'A1:An').values
|
|
# if there are no headers yet, return an empty array
|
|
if values
|
|
values[0].map(&:strip)
|
|
else
|
|
[]
|
|
end
|
|
end
|
|
end
|
|
|
|
def spreadsheet_service
|
|
@spreadsheet_service ||= Google::Apis::SheetsV4::SheetsService.new.tap do |s|
|
|
s.authorization = user.google_authorization
|
|
end
|
|
end
|
|
|
|
def check_spreadsheed_headers!(data)
|
|
missing_headers = data.keys.map { |k| k.to_s.strip } - headers
|
|
append_missing_headers(missing_headers) unless missing_headers.empty?
|
|
end
|
|
|
|
def append_missing_headers(missing_headers)
|
|
start_column = COLUMN_INDEX_TO_LETTER[headers.length]
|
|
end_column = COLUMN_INDEX_TO_LETTER[headers.length + missing_headers.length]
|
|
range = "#{start_column}1:#{end_column}1"
|
|
value_range = Google::Apis::SheetsV4::ValueRange.new(values: [missing_headers], major_dimension: 'ROWS')
|
|
spreadsheet_service.update_spreadsheet_value(form.google_spreadsheet_id, range, value_range, value_input_option: 'USER_ENTERED')
|
|
@headers = nil # reset header values to refresh memoization on next access
|
|
end
|
|
end
|
|
end
|