Skip to content

Commit

Permalink
Use ActiveResource and Kaminari
Browse files Browse the repository at this point in the history
  • Loading branch information
stephencdaly committed Dec 24, 2024
1 parent 54dd2ee commit 63a9e8f
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 85 deletions.
5 changes: 3 additions & 2 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ ruby file: ".ruby-version"
gem "rails", "8.0.1"

gem "activeresource", "~> 6.1"
gem "activeresource-response"

# Use postgresql as the database for Active Record
gem "pg", "~> 1.5"
Expand Down Expand Up @@ -78,8 +79,8 @@ gem "aws-sdk-codepipeline", "~> 1.92"
# For Mailchimp audience integration
gem "MailchimpMarketing", "~> 3.0"

# For making API requests for reports
gem "http"
# For pagination
gem "kaminari"

# For generating CSV reports
gem "csv"
Expand Down
37 changes: 16 additions & 21 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ GEM
activemodel (>= 6.0)
activemodel-serializers-xml (~> 1.0)
activesupport (>= 6.0)
activeresource-response (1.0.1)
activeresource (>= 4.0.0)
activestorage (8.0.1)
actionpack (= 8.0.1)
activejob (= 8.0.1)
Expand Down Expand Up @@ -175,7 +177,6 @@ GEM
thread_safe (~> 0.3, >= 0.3.1)
diff-lcs (1.5.1)
docile (1.4.0)
domain_name (0.6.20240107)
drb (2.2.1)
dry-cli (1.2.0)
dumb_delegator (1.0.0)
Expand All @@ -192,13 +193,6 @@ GEM
faraday-net_http (>= 2.0, < 3.2)
faraday-net_http (3.1.0)
net-http
ffi (1.17.0-aarch64-linux-gnu)
ffi (1.17.0-arm64-darwin)
ffi (1.17.0-x86_64-darwin)
ffi (1.17.0-x86_64-linux-gnu)
ffi-compiler (1.3.2)
ffi (>= 1.15.5)
rake
gds-sso (19.1.0)
oauth2 (~> 2.0)
omniauth (~> 2.1)
Expand Down Expand Up @@ -226,15 +220,6 @@ GEM
highline (3.0.1)
html-attributes-utils (1.0.2)
activesupport (>= 6.1.4.4)
http (5.2.0)
addressable (~> 2.8)
base64 (~> 0.1)
http-cookie (~> 1.0)
http-form_data (~> 2.2)
llhttp-ffi (~> 0.5.0)
http-cookie (1.0.8)
domain_name (~> 0.5)
http-form_data (2.3.0)
i18n (1.14.6)
concurrent-ruby (~> 1.0)
i18n-tasks (1.0.14)
Expand All @@ -256,10 +241,19 @@ GEM
json (2.9.0)
jwt (2.8.2)
base64
kaminari (1.2.2)
activesupport (>= 4.1.0)
kaminari-actionview (= 1.2.2)
kaminari-activerecord (= 1.2.2)
kaminari-core (= 1.2.2)
kaminari-actionview (1.2.2)
actionview
kaminari-core (= 1.2.2)
kaminari-activerecord (1.2.2)
activerecord
kaminari-core (= 1.2.2)
kaminari-core (1.2.2)
language_server-protocol (3.17.0.3)
llhttp-ffi (0.5.0)
ffi-compiler (~> 1.0)
rake (~> 13.0)
logger (1.6.3)
lograge (0.14.0)
actionpack (>= 4)
Expand Down Expand Up @@ -543,6 +537,7 @@ PLATFORMS
DEPENDENCIES
MailchimpMarketing (~> 3.0)
activeresource (~> 6.1)
activeresource-response
aws-sdk-cloudwatch (~> 1.108)
aws-sdk-codepipeline (~> 1.92)
axe-core-rspec
Expand All @@ -561,8 +556,8 @@ DEPENDENCIES
govuk-forms-markdown!
govuk_design_system_formbuilder
govuk_notify_rails
http
i18n-tasks (~> 1.0.14)
kaminari
lograge
omniauth-auth0
omniauth-rails_csrf_protection
Expand Down
7 changes: 7 additions & 0 deletions app/models/form_document.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class FormDocument < ActiveResource::Base
self.site = "#{Settings.forms_api.base_url}/api/v2"
self.element_name = "form-document"
self.include_format_in_path = false
headers["X-API-Token"] = Settings.forms_api.auth_key
add_response_method :http_response
end
132 changes: 70 additions & 62 deletions app/services/reports_service.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
require "http"
require "csv"

class ReportsService
Expand All @@ -10,19 +9,14 @@ def live_forms_csv
CSV.generate do |csv|
csv << ["ID", "Tag", "Name", "Slug", "Organisation name", "Organisation ID", "Group name", "Group ID", "Number of questions", "Has routes", "Live at", "Created at", "Updated at", "Payment URL", "Support URL", "Support URL text", "Support email", "Support phone", "Privacy policy URL", "What happens next markdown", "Submission type"]

page = 1
loop do
live_forms_response = get_live_forms(page)
forms = JSON.parse(live_forms_response.body)
forms.each do |form|
csv << form_row(form)
end
forms = get_paginated_form_documents(1)
write_forms_to_csv(csv, forms)

unless live_forms_response.headers["link"]&.include?("rel=\"next\"")
break
if forms.next_page.present?
(2...forms.total_pages).each do |i|
forms_batch = get_paginated_form_documents(i)
write_forms_to_csv(csv, forms_batch)
end

page += 1
end
end
end
Expand All @@ -31,84 +25,98 @@ def live_questions_csv
CSV.generate do |csv|
csv << ["Form ID", "Form name", "Form tag", "Organisation name", "Organisation ID", "Group name", "Group ID", "Question text", "Answer type", "Is optional?", "Is repeatable?", "Hint text", "Page heading", "Guidance markdown", "Has routes?", "Answer settings - Input type", "Selection settings - Only one option?", "Selection settings - Number of options", "Name settings - Title needed?", "Raw answer settings"]

page = 1
loop do
live_forms_response = get_live_forms(page)
forms = JSON.parse(live_forms_response.body)
forms.each do |form|
question_rows(form).each do |question|
csv << question
end
end
forms = get_paginated_form_documents(1)
write_form_questions_to_csv(csv, forms)

unless live_forms_response.headers["link"]&.include?("rel=\"next\"")
break
if forms.next_page.present?
(2...forms.total_pages).each do |i|
forms_batch = get_paginated_form_documents(i)
write_form_questions_to_csv(csv, forms_batch)
end

page += 1
end
end
end

def get_live_forms(page)
HTTP.headers(HEADERS)
.get("#{BASE_URL}/live-forms", params: { page: })
private

def get_paginated_form_documents(page)
documents = FormDocument.all(params: { tag: "live", page:, per_page: 500 })
Kaminari::PaginatableArray.new(
documents,
limit: documents.http_response["X-limit"].to_i,
offset: documents.http_response["X-offset"].to_i,
total_count: documents.http_response["X-total"].to_i,
)
end

def write_forms_to_csv(csv, forms)
forms.each do |form|
csv << form_row(form)
end
end

def write_form_questions_to_csv(csv, forms)
forms.each do |form|
question_rows(form).each do |question|
csv << question
end
end
end

def form_row(form)
form_id = form["form_id"]
form_id = form.form_id
group = GroupForm.find_by_form_id(form_id)&.group
[
form_id,
form["tag"],
form["content"]["name"],
form["content"]["form_slug"],
form.tag,
form.content.name,
form.content.form_slug,
group&.organisation&.name,
group&.organisation&.id,
group&.name,
group&.external_id,
form["content"]["steps"].length,
form["content"]["steps"].any? { |step| step["routing_conditions"].present? },
form["content"]["live_at"],
form["content"]["created_at"],
form["content"]["updated_at"],
form["content"]["payment_url"],
form["content"]["support_url"],
form["content"]["support_url_text"],
form["content"]["support_email"],
form["content"]["support_phone"],
form["content"]["privacy_policy_url"],
form["content"]["what_happens_next_markdown"],
form["content"]["submission_type"],
form.content.steps.length,
form.content.steps.any? { |step| step.routing_conditions.present? },
form.content.live_at,
form.content.created_at,
form.content.updated_at,
form.content.payment_url,
form.content.support_url,
form.content.support_url_text,
form.content.support_email,
form.content.support_phone,
form.content.privacy_policy_url,
form.content.what_happens_next_markdown,
form.content.submission_type,
]
end

def question_rows(form)
form_id = form["form_id"]
form_id = form.form_id
group = GroupForm.find_by_form_id(form_id)&.group

form["content"]["steps"].map do |step|
form.content.steps.map do |step|
[
form_id,
form["content"]["name"],
form["tag"],
form.content.name,
form.tag,
group&.organisation&.name,
group&.organisation&.id,
group&.name,
group&.external_id,
step["data"]["question_text"],
step["data"]["answer_type"],
step["data"]["is_optional"],
step["data"]["is_repeatable"],
step["data"]["hint_text"],
step["data"]["page_heading"],
step["data"]["guidance_markdown"],
step["data"]["routing_conditions"].present?,
step.dig("data", "answer_settings", "input_type"),
step.dig("data", "answer_settings", "only_one_option"),
step.dig("data", "answer_settings", "selection_options")&.length,
step.dig("data", "answer_settings", "title_needed"),
step["data"]["answer_settings"],
step.data.question_text,
step.data.answer_type,
step.data.is_optional,
step.data.is_repeatable,
step.data.hint_text,
step.data.page_heading,
step.data.guidance_markdown,
step.routing_conditions.present?,
step.data.answer_settings.respond_to?(:input_type) ? step.data.answer_settings.input_type.as_json : nil,
step.data.answer_settings.respond_to?(:only_one_option) ? step.data.answer_settings.only_one_option : nil,
step.data.answer_settings.respond_to?(:selection_options) ? step.data.answer_settings.selection_options&.length : nil,
step.data.answer_settings.respond_to?(:title_needed) ? step.data.answer_settings.title_needed : nil,
step.data.answer_settings.as_json,
]
end
end
Expand Down

0 comments on commit 63a9e8f

Please sign in to comment.