From b3f46a4232e244e19c9dc1345c37322ea4a091da Mon Sep 17 00:00:00 2001 From: Robin Houston Date: Wed, 4 Jul 2012 11:27:43 +0100 Subject: WIP new requests feed --- app/controllers/api_controller.rb | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'app/controllers') diff --git a/app/controllers/api_controller.rb b/app/controllers/api_controller.rb index 524aa44b7..b34386377 100644 --- a/app/controllers/api_controller.rb +++ b/app/controllers/api_controller.rb @@ -155,6 +155,20 @@ class ApiController < ApplicationController head :no_content end + def body_new_requests + feed_type = params[:feed_type] + raise PermissionDenied.new("#{@public_body.id} != #{params[:id]}") if @public_body.id != params[:id].to_i + + @requests = @public_body.info_requests + if feed_type == "atom" + render :template => "api/new_requests.atom" + elsif feed_type == "json" + render :json => @requests + else + raise ActiveRecord::RecordNotFound.new("Unrecognised feed type: " + feed_type) + end + end + protected def check_api_key raise "Missing required parameter 'k'" if params[:k].nil? -- cgit v1.2.3 From f03d71e493085c49e9c0a79c8608becd0b526c00 Mon Sep 17 00:00:00 2001 From: Robin Houston Date: Wed, 4 Jul 2012 11:39:27 +0100 Subject: Atom feed approximately working (?) --- app/controllers/api_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app/controllers') diff --git a/app/controllers/api_controller.rb b/app/controllers/api_controller.rb index b34386377..a8c9b5fef 100644 --- a/app/controllers/api_controller.rb +++ b/app/controllers/api_controller.rb @@ -161,7 +161,7 @@ class ApiController < ApplicationController @requests = @public_body.info_requests if feed_type == "atom" - render :template => "api/new_requests.atom" + render :template => "api/new_requests.atom", :layout => false elsif feed_type == "json" render :json => @requests else -- cgit v1.2.3 From d5a43f1aa76c1e0086f08bec9c575d2a41ae9a9b Mon Sep 17 00:00:00 2001 From: Robin Houston Date: Wed, 4 Jul 2012 13:45:29 +0100 Subject: Atom feed of request events We need not only new requests, but new outgoing correspondence of any sort. The idea is that this feed will contain any event that would have triggered an email to be sent to the public body, so can be used as an alternative, equivalent way to stay up-to-date with happenings on WDTK (or the Alaveteli installation of choice). --- app/controllers/api_controller.rb | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'app/controllers') diff --git a/app/controllers/api_controller.rb b/app/controllers/api_controller.rb index a8c9b5fef..3001ca3cb 100644 --- a/app/controllers/api_controller.rb +++ b/app/controllers/api_controller.rb @@ -155,17 +155,27 @@ class ApiController < ApplicationController head :no_content end - def body_new_requests + def body_request_events feed_type = params[:feed_type] raise PermissionDenied.new("#{@public_body.id} != #{params[:id]}") if @public_body.id != params[:id].to_i - @requests = @public_body.info_requests + @events = InfoRequestEvent.find_by_sql([ + %(select info_request_events.* + from info_requests + join info_request_events on info_requests.id = info_request_events.info_request_id + where info_requests.public_body_id = ? + and info_request_events.event_type in ( + 'sent', 'followup_sent', 'resent', 'followup_resent' + ) + order by info_request_events.created_at desc + ), @public_body.id + ]) if feed_type == "atom" - render :template => "api/new_requests.atom", :layout => false + render :template => "api/request_events.atom", :layout => false elsif feed_type == "json" - render :json => @requests + render :json => @events else - raise ActiveRecord::RecordNotFound.new("Unrecognised feed type: " + feed_type) + raise ActiveRecord::RecordNotFound.new("Unrecognised feed type: #{feed_type}") end end -- cgit v1.2.3 From d314c21449823f62afdb708b27ad327443162d8c Mon Sep 17 00:00:00 2001 From: Robin Houston Date: Wed, 4 Jul 2012 16:11:08 +0100 Subject: JSON new events feed --- app/controllers/api_controller.rb | 69 +++++++++++++++++++++++++++------------ 1 file changed, 48 insertions(+), 21 deletions(-) (limited to 'app/controllers') diff --git a/app/controllers/api_controller.rb b/app/controllers/api_controller.rb index 3001ca3cb..2ba88eb1a 100644 --- a/app/controllers/api_controller.rb +++ b/app/controllers/api_controller.rb @@ -156,27 +156,54 @@ class ApiController < ApplicationController end def body_request_events - feed_type = params[:feed_type] - raise PermissionDenied.new("#{@public_body.id} != #{params[:id]}") if @public_body.id != params[:id].to_i - - @events = InfoRequestEvent.find_by_sql([ - %(select info_request_events.* - from info_requests - join info_request_events on info_requests.id = info_request_events.info_request_id - where info_requests.public_body_id = ? - and info_request_events.event_type in ( - 'sent', 'followup_sent', 'resent', 'followup_resent' - ) - order by info_request_events.created_at desc - ), @public_body.id - ]) - if feed_type == "atom" - render :template => "api/request_events.atom", :layout => false - elsif feed_type == "json" - render :json => @events - else - raise ActiveRecord::RecordNotFound.new("Unrecognised feed type: #{feed_type}") - end + feed_type = params[:feed_type] + raise PermissionDenied.new("#{@public_body.id} != #{params[:id]}") if @public_body.id != params[:id].to_i + + @events = InfoRequestEvent.find_by_sql([ + %(select info_request_events.* + from info_requests + join info_request_events on info_requests.id = info_request_events.info_request_id + where info_requests.public_body_id = ? + and info_request_events.event_type in ( + 'sent', 'followup_sent', 'resent', 'followup_resent' + ) + order by info_request_events.created_at desc + ), @public_body.id + ]) + if feed_type == "atom" + render :template => "api/request_events.atom", :layout => false + elsif feed_type == "json" + # For the JSON feed, we take a "since" parameter that allows the client + # to restrict to events more recent than a certain other event + if params[:since_event_id] + @since_event_id = params[:since_event_id].to_i + end + @event_data = [] + @events.each do |event| + break if event.id == @since_event_id + + request = event.info_request + this_event = { + :event_id => event.id, + :created_at => event.created_at.iso8601, + :event_type => event.event_type, + :request_url => main_url(request_url(request)), + :request_email => request.incoming_email, + :title => request.title, + :body => event.outgoing_message.body, + + :user_name => request.user_name, + } + if request.user + this_event[:user_url] = main_url(user_url(request.user)) + end + + @event_data.push(this_event) + end + render :json => @event_data + else + raise ActiveRecord::RecordNotFound.new("Unrecognised feed type: #{feed_type}") + end end protected -- cgit v1.2.3 From d30312f2d13b561bc0f596a8a57b4a944401600e Mon Sep 17 00:00:00 2001 From: Robin Houston Date: Thu, 5 Jul 2012 12:06:02 +0100 Subject: Include request_id as well as event_id in the JSON --- app/controllers/api_controller.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'app/controllers') diff --git a/app/controllers/api_controller.rb b/app/controllers/api_controller.rb index 2ba88eb1a..4db07b4c9 100644 --- a/app/controllers/api_controller.rb +++ b/app/controllers/api_controller.rb @@ -184,6 +184,7 @@ class ApiController < ApplicationController request = event.info_request this_event = { + :request_id => request.id, :event_id => event.id, :created_at => event.created_at.iso8601, :event_type => event.event_type, -- cgit v1.2.3 From 049198b25c7033ad6d69ec0907679025a54f89db Mon Sep 17 00:00:00 2001 From: Seb Bacon Date: Mon, 9 Jul 2012 12:42:47 +0100 Subject: Ensure (at least in the most basic cases) that views support recent "external request" changes (mainly that InfoRequests no longer necessarily have a User). --- app/controllers/admin_request_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app/controllers') diff --git a/app/controllers/admin_request_controller.rb b/app/controllers/admin_request_controller.rb index fd1405319..ae4bb511a 100644 --- a/app/controllers/admin_request_controller.rb +++ b/app/controllers/admin_request_controller.rb @@ -28,7 +28,7 @@ class AdminRequestController < AdminController @info_request = InfoRequest.find(params[:id]) # XXX is this *really* the only way to render a template to a # variable, rather than to the response? - vars = OpenStruct.new(:name_to => @info_request.user.name, + vars = OpenStruct.new(:name_to => @info_request.user_name, :name_from => MySociety::Config.get("CONTACT_NAME", 'Alaveteli'), :info_request => @info_request, :reason => params[:reason], :info_request_url => 'http://' + MySociety::Config.get('DOMAIN') + request_url(@info_request), -- cgit v1.2.3 From 2547fc90a8630aec7f31af8be0bebf5e6c68dca1 Mon Sep 17 00:00:00 2001 From: Seb Bacon Date: Mon, 9 Jul 2012 12:43:55 +0100 Subject: Calls to API that are expected to return JSON are always expected to return something, even when there are no errors. --- app/controllers/api_controller.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'app/controllers') diff --git a/app/controllers/api_controller.rb b/app/controllers/api_controller.rb index 2ba88eb1a..6117435db 100644 --- a/app/controllers/api_controller.rb +++ b/app/controllers/api_controller.rb @@ -151,8 +151,9 @@ class ApiController < ApplicationController mail = RequestMailer.create_external_response(request, body, sent_at, attachment_hashes) request.receive(mail, mail.encoded, true) end - - head :no_content + render :json => { + 'url' => make_url("request", request.url_title), + } end def body_request_events -- cgit v1.2.3 From 4490482cedf362390b25efe453232ac1b7dfce99 Mon Sep 17 00:00:00 2001 From: Seb Bacon Date: Wed, 11 Jul 2012 08:38:08 +0100 Subject: In the API, when parsing posted responses, assume all multipart mail parts that are Tempfiles are attachments --- app/controllers/api_controller.rb | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'app/controllers') diff --git a/app/controllers/api_controller.rb b/app/controllers/api_controller.rb index 6117435db..3244a4c12 100644 --- a/app/controllers/api_controller.rb +++ b/app/controllers/api_controller.rb @@ -71,10 +71,18 @@ class ApiController < ApplicationController end + def _get_attachments_from_params(params) + attachments = [] + params.each_pair do |k, v| + attachments << v if v.is_a? Tempfile + end + return attachments + end + def add_correspondence request = InfoRequest.find(params[:id]) json = ActiveSupport::JSON.decode(params[:correspondence_json]) - attachments = params[:attachments] + attachments = _get_attachments_from_params(params) direction = json["direction"] body = json["body"] @@ -147,7 +155,6 @@ class ApiController < ApplicationController :filename => filename ) end - mail = RequestMailer.create_external_response(request, body, sent_at, attachment_hashes) request.receive(mail, mail.encoded, true) end -- cgit v1.2.3 From 088bc961328f4d876971994102cde52c1ad49246 Mon Sep 17 00:00:00 2001 From: Seb Bacon Date: Thu, 12 Jul 2012 13:04:27 +0100 Subject: Support regular expressions in CensorRules; also support 'global' CensorRules that aren't attached to a User or Request or Public Body (but don't expose this in the admin UI). Fixes #33 --- app/controllers/admin_censor_rule_controller.rb | 2 ++ 1 file changed, 2 insertions(+) (limited to 'app/controllers') diff --git a/app/controllers/admin_censor_rule_controller.rb b/app/controllers/admin_censor_rule_controller.rb index 52df8dfc1..ec86cdf8e 100644 --- a/app/controllers/admin_censor_rule_controller.rb +++ b/app/controllers/admin_censor_rule_controller.rb @@ -31,6 +31,8 @@ class AdminCensorRuleController < AdminController redirect_to admin_url('request/show/' + @censor_rule.info_request.id.to_s) elsif !@censor_rule.user.nil? redirect_to admin_url('user/show/' + @censor_rule.user.id.to_s) + elsif @censor_rule.regexp? + redirect_to admin_url('') else raise "internal error" end -- cgit v1.2.3 From 778979f8b9c3aa99880c8c844e6a5be6d5968f4a Mon Sep 17 00:00:00 2001 From: Seb Bacon Date: Thu, 12 Jul 2012 13:09:27 +0100 Subject: Factor popup banner out into own partial, for easier setting/unsetting (including from themes). Fixes #524 --- app/controllers/application_controller.rb | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'app/controllers') diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 41adf1848..11f21025c 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -27,6 +27,7 @@ class ApplicationController < ActionController::Base before_filter :check_in_post_redirect before_filter :session_remember_me before_filter :set_vary_header + before_filter :set_popup_banner # scrub sensitive parameters from the logs filter_parameter_logging :password @@ -553,6 +554,9 @@ class ApplicationController < ActionController::Base return country end + def set_popup_banner + @popup_banner = render_to_string(:partial => "general/popup_banner").strip + end # URL generating functions are needed by all controllers (for redirects), # views (for links) and mailers (for use in emails), so include them into # all of all. -- cgit v1.2.3 From d4a700da1760fc2ba09cf19613a995569e4965ea Mon Sep 17 00:00:00 2001 From: Robin Houston Date: Mon, 16 Jul 2012 18:05:39 +0100 Subject: Revert "In the API, when parsing posted responses, assume all multipart mail parts that are Tempfiles are attachments" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change makes the tests fail, I think, and doesn’t have (IMHO) a desperately strong rationale, so let’s try it without for now. This reverts commit 4490482cedf362390b25efe453232ac1b7dfce99. --- app/controllers/api_controller.rb | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) (limited to 'app/controllers') diff --git a/app/controllers/api_controller.rb b/app/controllers/api_controller.rb index 3244a4c12..6117435db 100644 --- a/app/controllers/api_controller.rb +++ b/app/controllers/api_controller.rb @@ -71,18 +71,10 @@ class ApiController < ApplicationController end - def _get_attachments_from_params(params) - attachments = [] - params.each_pair do |k, v| - attachments << v if v.is_a? Tempfile - end - return attachments - end - def add_correspondence request = InfoRequest.find(params[:id]) json = ActiveSupport::JSON.decode(params[:correspondence_json]) - attachments = _get_attachments_from_params(params) + attachments = params[:attachments] direction = json["direction"] body = json["body"] @@ -155,6 +147,7 @@ class ApiController < ApplicationController :filename => filename ) end + mail = RequestMailer.create_external_response(request, body, sent_at, attachment_hashes) request.receive(mail, mail.encoded, true) end -- cgit v1.2.3 From 49ff1a1c0304cd292d3eae80dc0b91b2f83727b9 Mon Sep 17 00:00:00 2001 From: Seb Bacon Date: Tue, 17 Jul 2012 10:02:26 +0100 Subject: Revert "Revert "In the API, when parsing posted responses, assume all multipart mail parts that are Tempfiles are attachments"" This reverts commit d4a700da1760fc2ba09cf19613a995569e4965ea. --- app/controllers/api_controller.rb | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'app/controllers') diff --git a/app/controllers/api_controller.rb b/app/controllers/api_controller.rb index 718c31e6f..a7853c787 100644 --- a/app/controllers/api_controller.rb +++ b/app/controllers/api_controller.rb @@ -71,10 +71,18 @@ class ApiController < ApplicationController end + def _get_attachments_from_params(params) + attachments = [] + params.each_pair do |k, v| + attachments << v if v.is_a? Tempfile + end + return attachments + end + def add_correspondence request = InfoRequest.find(params[:id]) json = ActiveSupport::JSON.decode(params[:correspondence_json]) - attachments = params[:attachments] + attachments = _get_attachments_from_params(params) direction = json["direction"] body = json["body"] @@ -147,7 +155,6 @@ class ApiController < ApplicationController :filename => filename ) end - mail = RequestMailer.create_external_response(request, body, sent_at, attachment_hashes) request.receive(mail, mail.encoded, true) end -- cgit v1.2.3 From 8e24786e42d28e47d413d1470628a719135d1dd2 Mon Sep 17 00:00:00 2001 From: Seb Bacon Date: Tue, 17 Jul 2012 10:28:53 +0100 Subject: Oh dear, a "revert revert revert" that reverts the "revert revert" that should never have been pushed in the first place. Sorry! Revert "Revert "Revert "In the API, when parsing posted responses, assume all multipart mail parts that are Tempfiles are attachments""" This reverts commit 49ff1a1c0304cd292d3eae80dc0b91b2f83727b9. --- app/controllers/api_controller.rb | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) (limited to 'app/controllers') diff --git a/app/controllers/api_controller.rb b/app/controllers/api_controller.rb index a7853c787..718c31e6f 100644 --- a/app/controllers/api_controller.rb +++ b/app/controllers/api_controller.rb @@ -71,18 +71,10 @@ class ApiController < ApplicationController end - def _get_attachments_from_params(params) - attachments = [] - params.each_pair do |k, v| - attachments << v if v.is_a? Tempfile - end - return attachments - end - def add_correspondence request = InfoRequest.find(params[:id]) json = ActiveSupport::JSON.decode(params[:correspondence_json]) - attachments = _get_attachments_from_params(params) + attachments = params[:attachments] direction = json["direction"] body = json["body"] @@ -155,6 +147,7 @@ class ApiController < ApplicationController :filename => filename ) end + mail = RequestMailer.create_external_response(request, body, sent_at, attachment_hashes) request.receive(mail, mail.encoded, true) end -- cgit v1.2.3 From 2a70db0eb8c14fa14c6ca5fe6a738cee4f3f66df Mon Sep 17 00:00:00 2001 From: Seb Bacon Date: Thu, 19 Jul 2012 13:05:34 +0100 Subject: Fix bug preventing CSV upload. Fixes #525 (needs tests!) --- app/controllers/admin_public_body_controller.rb | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'app/controllers') diff --git a/app/controllers/admin_public_body_controller.rb b/app/controllers/admin_public_body_controller.rb index 285523e11..25a8d1e08 100644 --- a/app/controllers/admin_public_body_controller.rb +++ b/app/controllers/admin_public_body_controller.rb @@ -139,14 +139,14 @@ class AdminPublicBodyController < AdminController end def import_csv - if params['commit'] == 'Dry run' - dry_run_only = true - elsif params['commit'] == 'Upload' - dry_run_only = false - else - raise "internal error, unknown button label" - end if params[:csv_file] + if params['commit'] == 'Dry run' + dry_run_only = true + elsif params['commit'] == 'Upload' + dry_run_only = false + else + raise "internal error, unknown button label" + end csv_contents = params[:csv_file].read else csv_contents = session.delete(:previous_csv) -- cgit v1.2.3 From 4900094bd5a116e0ca8f04b019a464ee0f07a969 Mon Sep 17 00:00:00 2001 From: Louise Crow Date: Tue, 14 Aug 2012 14:46:43 +0100 Subject: Whether a rule is a regex rule should not affect the redirect that happens after you create it. --- app/controllers/admin_censor_rule_controller.rb | 2 -- 1 file changed, 2 deletions(-) (limited to 'app/controllers') diff --git a/app/controllers/admin_censor_rule_controller.rb b/app/controllers/admin_censor_rule_controller.rb index ec86cdf8e..52df8dfc1 100644 --- a/app/controllers/admin_censor_rule_controller.rb +++ b/app/controllers/admin_censor_rule_controller.rb @@ -31,8 +31,6 @@ class AdminCensorRuleController < AdminController redirect_to admin_url('request/show/' + @censor_rule.info_request.id.to_s) elsif !@censor_rule.user.nil? redirect_to admin_url('user/show/' + @censor_rule.user.id.to_s) - elsif @censor_rule.regexp? - redirect_to admin_url('') else raise "internal error" end -- cgit v1.2.3 From 19d6e36039318cdb1f9aa9e0c4731b500b3b0aeb Mon Sep 17 00:00:00 2001 From: Louise Crow Date: Mon, 20 Aug 2012 16:27:26 +0100 Subject: Rework the temporary storing of a csv file of public body info between a dry run and real load. Use a temp file, not the session for the data. Also fixes #503. --- app/controllers/admin_public_body_controller.rb | 96 +++++++++++++++++-------- 1 file changed, 67 insertions(+), 29 deletions(-) (limited to 'app/controllers') diff --git a/app/controllers/admin_public_body_controller.rb b/app/controllers/admin_public_body_controller.rb index 25a8d1e08..7bd794d23 100644 --- a/app/controllers/admin_public_body_controller.rb +++ b/app/controllers/admin_public_body_controller.rb @@ -139,7 +139,9 @@ class AdminPublicBodyController < AdminController end def import_csv - if params[:csv_file] + @notes = "" + @errors = "" + if request.post? if params['commit'] == 'Dry run' dry_run_only = true elsif params['commit'] == 'Upload' @@ -147,40 +149,76 @@ class AdminPublicBodyController < AdminController else raise "internal error, unknown button label" end - csv_contents = params[:csv_file].read - else - csv_contents = session.delete(:previous_csv) - end - if !csv_contents.nil? - # Try with dry run first - en = PublicBody.import_csv(csv_contents, params[:tag], params[:tag_behaviour], true, admin_http_auth_user(), I18n.available_locales) - errors = en[0] - notes = en[1] - - if errors.size == 0 - if dry_run_only - notes.push("Dry run was successful, real run would do as above.") - session[:previous_csv] = csv_contents - else - # And if OK, with real run - en = PublicBody.import_csv(csv_contents, params[:tag], params[:tag_behaviour], false, admin_http_auth_user(), I18n.available_locales) - errors = en[0] - notes = en[1] - if errors.size != 0 - raise "dry run mismatched real run" + # Read file from params + if params[:csv_file] + csv_contents = params[:csv_file].read + @original_csv_file = params[:csv_file].original_filename + # or from previous dry-run temporary file + elsif params[:temporary_csv_file] && params[:original_csv_file] + csv_contents = retrieve_csv_data(params[:temporary_csv_file]) + @original_csv_file = params[:original_csv_file] + end + + if !csv_contents.nil? + # Try with dry run first + errors, notes = PublicBody.import_csv(csv_contents, + params[:tag], + params[:tag_behaviour], + true, + admin_http_auth_user(), + I18n.available_locales) + + if errors.size == 0 + if dry_run_only + notes.push("Dry run was successful, real run would do as above.") + # Store the csv file for ease of performing the real run + @temporary_csv_file = store_csv_data(csv_contents) + else + # And if OK, with real run + errors, notes = PublicBody.import_csv(csv_contents, + params[:tag], + params[:tag_behaviour], + false, + admin_http_auth_user(), + I18n.available_locales) + if errors.size != 0 + raise "dry run mismatched real run" + end + notes.push("Import was successful.") end - notes.push("Import was successful.") end + @errors = errors.join("\n") + @notes = notes.join("\n") end - @errors = errors.join("\n") - @notes = notes.join("\n") - else - @errors = "" - @notes = "" end - end private + # Save the contents to a temporary file - not using Tempfile as we need + # the file to persist between requests. Return the name of the file. + def store_csv_data(csv_contents) + tempfile_name = "csv_upload-#{Time.now.strftime("%Y%m%d")}-#{SecureRandom.random_number(10000)}" + tempfile = File.new(File.join(Dir::tmpdir, tempfile_name), 'w') + tempfile.write(csv_contents) + tempfile.close + return tempfile_name + end + + # Get csv contents from the file whose name is passed, as long as the + # name is of the expected form. + # Delete the file, return the contents. + def retrieve_csv_data(tempfile_name) + if not /csv_upload-\d{8}-\d{1,5}/.match(tempfile_name) + raise "Invalid filename in upload_csv: #{tempfile_name}" + end + tempfile_path = File.join(Dir::tmpdir, tempfile_name) + if ! File.exist?(tempfile_path) + raise "Missing file in upload_csv: #{tempfile_name}" + end + csv_contents = File.read(tempfile_path) + File.delete(tempfile_path) + return csv_contents + end + end -- cgit v1.2.3