Skip to content

Commit

Permalink
Download inputs as a csv with min, max, default, unit and user value
Browse files Browse the repository at this point in the history
  • Loading branch information
louispt1 committed Oct 25, 2024
1 parent 4d43973 commit db5029f
Show file tree
Hide file tree
Showing 3 changed files with 269 additions and 79 deletions.
69 changes: 60 additions & 9 deletions app/controllers/api/v3/inputs_controller.rb
Original file line number Diff line number Diff line change
@@ -1,27 +1,31 @@
# frozen_string_literal: true
require 'csv'

module Api
module V3
class InputsController < ::Api::V3::BaseController
before_action do
@scenario = Scenario.find(params[:scenario_id])
authorize!(:read, @scenario)
if user_signed_in? && current_user.can?(:read, @scenario)
authorize!(:read, @scenario)
end
end

# GET /api/v3/inputs
# GET /api/v3/scenarios/:scenario_id/inputs
# GET /api/v3/scenarios/:scenario_id/inputs.csv
#
# Returns the details for all available inputs. If the scenario_id isn't
# passed then the action will use the latest scenario.
#
# Returns input details in JSON or CSV format. Uses the latest scenario if
# scenario_id is not provided.

def index
extras = ActiveModel::Type::Boolean.new.cast(params[:include_extras])
inputs = serialized_inputs(extras)

render json: InputSerializer.collection(
Input.all,
@scenario,
**serializer_args(extra_attributes: extras)
)
respond_to do |format|
format.json { render json: inputs }
format.csv { send_csv_data(inputs) }
end
end

# GET /api/v3/inputs/:id
Expand Down Expand Up @@ -77,6 +81,53 @@ def serializer_args(extra_attributes:)
extra_attributes:
}
end

def serialized_inputs(extras)
InputSerializer.collection(
Input.all,
@scenario,
**serializer_args(extra_attributes: extras)
)
end

def send_csv_data(inputs)
csv_data = generate_csv(inputs)
send_data csv_data, filename: "inputs_#{@scenario.id}.csv"
end

def generate_csv(inputs)
CSV.generate(headers: true) do |csv|
csv << csv_headers
cached_values = Input.cache(@scenario.parent)
user_values = @scenario.user_values

inputs.each do |key, input|
add_csv_row(csv, key, input, cached_values, user_values)
end
end
end

def csv_headers
["Key", "Min", "Max", "Default", "User Value", "Unit", "Share Group"]
end

def add_csv_row(csv, key, input, cached_values, user_values)
input_data = input.instance_variable_get(:@input)
return if input_data.nil?

values = cached_values.read(@scenario.parent, input_data)
default_value = input.instance_variable_get(:@default_values_from).call(values)

csv << [
key,
input_data.min_value,
input_data.max_value,
default_value,
user_values[input_data.key] || "",
input_data.unit,
input_data.share_group
]
end
end
end
end
2 changes: 1 addition & 1 deletion config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@
get 'converters', to: redirect('/api/v3/scenarios/%{scenario_id}/nodes')
get 'converters/:id', to: redirect('/api/v3/scenarios/%{scenario_id}/nodes/%{id}')

resources :inputs, :only => [:index, :show]
resources :inputs, :only => [:index, :show], defaults: { format: :json}

resource :version, :only => [:create, :show, :update], controller: 'scenario_version_tags'

Expand Down
Loading

0 comments on commit db5029f

Please sign in to comment.