* VRFS-1496 - export CSV

This commit is contained in:
Seth Call 2014-07-27 11:45:46 -05:00
parent 2dd6153ed8
commit 44ba9ef441
3 changed files with 83 additions and 25 deletions

View File

@ -11,46 +11,80 @@ ActiveAdmin.register_page "Score Exports" do
if start_time.blank?
start_time = '1900-01-01'
end
start_time = "DATE '#{start_time}'"
start_time = "#{start_time}"
if end_time.blank?
end_time = 'NOW()'
end_time = Time.now + 1.days
else
end_time = "DATE '#{end_time}'"
end_time = "#{end_time}"
end
@users = User.find(:all)
Fetching all user details and assigned on @users
puts "start_time #{start_time}, end_time #{end_time}"
scores = ScoreHistory
.select("from_city, from_regions.regionname as from_region_name, from_countries.countryname as from_country_name, from_isp,
to_city, to_regions.regionname as to_region_name, to_countries.countryname as to_country_name, to_isp,
min(score_histories.score) as min_latency, max(score_histories.score) as max_latency, avg(score_histories.score) as mean_latency, median(CAST(score_histories.score AS NUMERIC)) as median_latency, count(score_histories.score) as score_count")
.joins('LEFT JOIN countries AS from_countries ON from_countries.countrycode = from_country')
.joins('LEFT JOIN countries AS to_countries ON to_countries.countrycode = to_country')
.joins('LEFT JOIN regions AS from_regions ON from_regions.region = from_region')
.joins('LEFT JOIN regions AS to_regions ON to_regions.region = to_region')
.where("score_dt BETWEEN DATE '#{start_time}' AND DATE '#{end_time}'")
.order('from_city, from_regions.regionname, from_countries.countryname, from_isp, to_city, to_regions.regionname, to_countries.countryname, to_isp')
.group('from_city, from_regions.regionname, from_countries.countryname, from_isp, to_city, to_regions.regionname, to_countries.countryname, to_isp')
.limit(1_000_000)
csv_string = CSV.generate do |csv|
Using CSV class generate method to create csv file
csv << ["Id", "Name", "Email","Role"]
Creating header of CSV file
csv << ["From Country", "From Region", "From City", "From ISP", "To Country", "To Region", "To City", "To ISP", "Min Latency", "Max Latency", "Median Latency", "Mean Latency", 'Score Count']
@users.each do |user|
csv << [user.id, user.name, user.name, user.role]
scores.each do |score|
puts score.inspect
csv << [score.from_country_name, score.from_region_name, score.from_city, score.from_isp,
score.to_country_name, score.to_region_name, score.to_city, score.to_isp,
score[:min_latency], score[:max_latency], score[:median_latency], score[:mean_latency], score[:score_count]]
end
Retrieving each rows and assigning on csv_string variable.
end
send_data csv_string,
:type => 'text/csv; charset=iso-8859-1; header=present',
:disposition => "attachment;
filename=users.csv"
render 'hi'
# redirect_to admin_bootstrap_path, :notice => "Server created. If you start a job worker (bundle exec rake all_jobs in /web), it should update your icecast config."
send_data csv_string,
:type => 'text/csv; charset=iso-8859-1; header=present',
:disposition => "attachment; filename=score_export-#{start_time}-#{end_time}.csv"
end
content :title => "Score Exports" do
semantic_form_for :score_exports, :url => admin_score_exports_create_csv_path, :builder => ActiveAdmin::FormBuilder do |f|
f.inputs do
f.input :start, :as => :datepicker
f.input :end, :as => :datepicker
columns do
column do
semantic_form_for :score_exports, :url => admin_score_exports_create_csv_path, :builder => ActiveAdmin::FormBuilder do |f|
f.inputs do
f.input :start, :as => :datepicker
f.input :end, :as => :datepicker
end
f.actions do
f.action :submit, :label => 'Download CSV'
end
end
end
column do
panel "Usage" do
span "Select a start day, and end day to generate a CSV with a score summary."
end
panel "Limitation 1" do
div do
span do "The system limits the number of rows exported to 1,000,000" end
end
end
panel "Limitation 2" do
div do
span do "This report uses the score_histories table, which can lag up to 1 hour behind data. You can force a score_history sweep by going to" end
span do link_to "Resque", "#{Gon.global.prefix}resque/schedule" end
span do " and then running ScoreHistorySweeper. When the job count goes from 1 to 0, the score_histories table is now completely up-to-date, and you can make a 'fresh' CSV." end
end
end
end
f.buttons
end
#panel "Upaid Registrations" do
# table_for Registration.unpaid.limit(10).order('created_at desc') do
# column "Registration" do |registration|

View File

@ -195,4 +195,5 @@ max_mind_releases.sql
score_histories.sql
update_sms_index.sql
connection_allow_null_locidispid.sql
track_user_in_scores.sql
track_user_in_scores.sql
median_aggregate.sql

View File

@ -0,0 +1,23 @@
-- from here: https://wiki.postgresql.org/wiki/Aggregate_Median
CREATE OR REPLACE FUNCTION _final_median(numeric[])
RETURNS numeric
AS
$body$
SELECT AVG(val)
FROM (
SELECT val
FROM unnest($1) val
ORDER BY 1
LIMIT 2 - MOD(array_upper($1, 1), 2)
OFFSET CEIL(array_upper($1, 1) / 2.0) - 1
) sub;
$body$
LANGUAGE sql ;
-- IMMUTABLE not accepted by pg migrate
CREATE AGGREGATE median(numeric) (
SFUNC=array_append,
STYPE=numeric[],
FINALFUNC=_final_median,
INITCOND='{}'
);