Skip to content

Instantly share code, notes, and snippets.

@paulgrammer
Created November 21, 2023 09:10
Show Gist options
  • Save paulgrammer/c09ee39cfaf1e8262348c938f5c89578 to your computer and use it in GitHub Desktop.
Save paulgrammer/c09ee39cfaf1e8262348c938f5c89578 to your computer and use it in GitHub Desktop.
require 'net/http'
require 'json'
require 'openssl'
require 'time'
require 'csv'
module Foundant
module GrantManagement
module DataSets
KEY = ENV['FOUNDANT_KEY']
SECRET = ENV['FOUNDANT_SECRET']
API_URL = ENV.fetch('FOUNDANT_URL', "https://www.grantinterface.com/API/DataSet/GetData")
DEFAULT_OPTIONS = [
{ label: "Community Fund", id: "community_fund", value: 0 },
{ label: "Education Fund", id: "education_fund", value: 0 },
{ label: "Employment Fund", id: "employment_fund", value: 0 },
{ label: "Housing & Neighborhoods Fund", id: "housing_&_neighborhoods_fund", value: 0 },
{ label: "Education & Employment Fund", id: "education_&_employment_fund", value: 0 }
]
class << self
def datasets
response = request
process_response(response.body) if response.code.to_i == 200
rescue StandardError => e
puts "Error: #{e.message}"
nil
end
private
def request
uri = URI(API_URL)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri.path, headers)
request.body = body
http.request(request)
end
def headers
{
'Content-Type' => 'application/json',
'GLM-API-Key' => KEY,
'GLM-API-Signature' => signature
}
end
def signature
secret_bytes = [SECRET].pack('H*')
body_bytes = body.encode('utf-8')
OpenSSL::HMAC.hexdigest('sha256', secret_bytes, body_bytes)
end
def body
'{"timestamp":' + Time.now.to_i.to_s + '}'
end
def process_response(csv_data)
csv_data.force_encoding('UTF-8')
csv_data.gsub!("\xEF\xBB\xBF".force_encoding('UTF-8'), '')
parsed_data = parse_csv_data(csv_data)
formatted_data = normalize_data(parsed_data)
replace_default_options(formatted_data)
end
def parse_csv_data(csv_data)
parsed_data = []
CSV.parse(csv_data, headers: :first_row) { |row| parsed_data << row.to_h }
parsed_data.map!(&:compact)
end
def normalize_data(parsed_data)
parsed_data.map do |row|
process_name_parts = row["Process Name"].split(' - ')
label = process_name_parts[1]
{
label: label,
key: label.downcase.gsub(/ /, "_"),
value: row["Amount Awarded"].gsub(/[$,]/, '').to_f,
year: process_name_parts[0].split(" ")[0]
}
end
end
def replace_default_options(formatted_data)
formated_api_data = formatted_data
.group_by { |item| item[:key] }
.transform_values { |items| items.sum { |item| item[:value] } }
datasets = DEFAULT_OPTIONS.map do |option|
option[:value] = formated_api_data.dig(option[:id]) || option[:value]
option
end
{datasets:, total: formated_api_data.values.sum }
end
end
end
end
end
result = Foundant::GrantManagement::DataSets.datasets
puts result
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment