mirror of
https://github.com/codeninjasllc/discourse.git
synced 2024-11-27 09:36:19 -05:00
create a new table to maintain csv export log
This commit is contained in:
parent
bb152a5b3f
commit
7c7474aa10
9 changed files with 86 additions and 63 deletions
|
@ -15,14 +15,14 @@ class ExportCsvController < ApplicationController
|
||||||
|
|
||||||
# download
|
# download
|
||||||
def show
|
def show
|
||||||
params.require(:entity)
|
params.require(:id)
|
||||||
params.require(:file_id)
|
filename = params.fetch(:id)
|
||||||
if params[:entity] == "system"
|
export_id = filename.split('_')[1].split('.')[0]
|
||||||
guardian.ensure_can_export_admin_entity!(current_user)
|
export_initiated_by_user_id = 0
|
||||||
end
|
export_initiated_by_user_id = CsvExportLog.where(id: export_id)[0].user_id unless CsvExportLog.where(id: export_id).empty?
|
||||||
|
export_csv_path = CsvExportLog.get_download_path(filename)
|
||||||
|
|
||||||
filename = params.fetch(:file_id)
|
if export_csv_path && export_initiated_by_user_id == current_user.id
|
||||||
if export_csv_path = ExportCsv.get_download_path(filename)
|
|
||||||
send_file export_csv_path
|
send_file export_csv_path
|
||||||
else
|
else
|
||||||
render nothing: true, status: 404
|
render nothing: true, status: 404
|
||||||
|
|
|
@ -239,15 +239,17 @@ module Jobs
|
||||||
|
|
||||||
|
|
||||||
def set_file_path
|
def set_file_path
|
||||||
@file_name = "export_#{SecureRandom.hex(4)}.csv"
|
@file = CsvExportLog.create(export_type: @entity_type, user_id: @current_user.id)
|
||||||
|
@file_name = "export_#{@file.id}.csv"
|
||||||
|
|
||||||
# ensure directory exists
|
# ensure directory exists
|
||||||
dir = File.dirname("#{ExportCsv.base_directory}/#{@file_name}")
|
dir = File.dirname("#{CsvExportLog.base_directory}/#{@file_name}")
|
||||||
FileUtils.mkdir_p(dir) unless Dir.exists?(dir)
|
FileUtils.mkdir_p(dir) unless Dir.exists?(dir)
|
||||||
end
|
end
|
||||||
|
|
||||||
def write_csv_file(data, header)
|
def write_csv_file(data, header)
|
||||||
# write to CSV file
|
# write to CSV file
|
||||||
CSV.open(File.expand_path("#{ExportCsv.base_directory}/#{@file_name}", __FILE__), "w") do |csv|
|
CSV.open(File.expand_path("#{CsvExportLog.base_directory}/#{@file_name}", __FILE__), "w") do |csv|
|
||||||
csv << header
|
csv << header
|
||||||
data.each do |value|
|
data.each do |value|
|
||||||
csv << value
|
csv << value
|
||||||
|
@ -257,12 +259,8 @@ module Jobs
|
||||||
|
|
||||||
def notify_user
|
def notify_user
|
||||||
if @current_user
|
if @current_user
|
||||||
if @file_name != "" && File.exists?("#{ExportCsv.base_directory}/#{@file_name}")
|
if @file_name != "" && File.exists?("#{CsvExportLog.base_directory}/#{@file_name}")
|
||||||
if @entity_type == "admin"
|
SystemMessage.create_from_system_user(@current_user, :csv_export_succeeded, download_link: "#{Discourse.base_url}/export_csv/#{@file_name}", file_name: @file_name)
|
||||||
SystemMessage.create_from_system_user(@current_user, :csv_export_succeeded, download_link: "#{Discourse.base_url}/export_csv/system/#{@file_name}", file_name: @file_name)
|
|
||||||
else
|
|
||||||
SystemMessage.create_from_system_user(@current_user, :csv_export_succeeded, download_link: "#{Discourse.base_url}/export_csv/#{@current_user.username}/#{@file_name}", file_name: @file_name)
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
SystemMessage.create_from_system_user(@current_user, :csv_export_failed)
|
SystemMessage.create_from_system_user(@current_user, :csv_export_failed)
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,7 +3,7 @@ module Jobs
|
||||||
every 2.day
|
every 2.day
|
||||||
|
|
||||||
def execute(args)
|
def execute(args)
|
||||||
ExportCsv.remove_old_exports # delete exported CSV files older than 2 days
|
CsvExportLog.remove_old_exports # delete exported CSV files older than 2 days
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -31,6 +31,7 @@ end
|
||||||
# created_at :datetime not null
|
# created_at :datetime not null
|
||||||
# updated_at :datetime not null
|
# updated_at :datetime not null
|
||||||
# allowed_ips :inet is an Array
|
# allowed_ips :inet is an Array
|
||||||
|
# hidden :boolean default(FALSE), not null
|
||||||
#
|
#
|
||||||
# Indexes
|
# Indexes
|
||||||
#
|
#
|
||||||
|
|
40
app/models/csv_export_log.rb
Normal file
40
app/models/csv_export_log.rb
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
class CsvExportLog < ActiveRecord::Base
|
||||||
|
|
||||||
|
def self.get_download_path(filename)
|
||||||
|
path = File.join(CsvExportLog.base_directory, filename)
|
||||||
|
if File.exists?(path)
|
||||||
|
return path
|
||||||
|
else
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.remove_old_exports
|
||||||
|
expired_exports = CsvExportLog.where('created_at < ?', 2.days.ago).to_a
|
||||||
|
expired_exports.map do |expired_export|
|
||||||
|
file_name = "export_#{expired_export.id}.csv"
|
||||||
|
file_path = "#{CsvExportLog.base_directory}/#{file_name}"
|
||||||
|
|
||||||
|
if File.exist?(file_path)
|
||||||
|
File.delete(file_path)
|
||||||
|
end
|
||||||
|
CsvExportLog.find(expired_export.id).destroy
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.base_directory
|
||||||
|
File.join(Rails.root, "public", "uploads", "csv_exports", RailsMultisite::ConnectionManagement.current_db)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: csv_export_logs
|
||||||
|
#
|
||||||
|
# id :integer not null, primary key
|
||||||
|
# export_type :string(255) not null
|
||||||
|
# user_id :integer not null
|
||||||
|
# created_at :datetime
|
||||||
|
# updated_at :datetime
|
||||||
|
#
|
|
@ -1,29 +0,0 @@
|
||||||
class ExportCsv
|
|
||||||
|
|
||||||
def self.get_download_path(filename)
|
|
||||||
path = File.join(ExportCsv.base_directory, filename)
|
|
||||||
if File.exists?(path)
|
|
||||||
return path
|
|
||||||
else
|
|
||||||
nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.remove_old_exports
|
|
||||||
if Dir.exists?(ExportCsv.base_directory)
|
|
||||||
Dir.foreach(ExportCsv.base_directory) do |file|
|
|
||||||
path = File.join(ExportCsv.base_directory, file)
|
|
||||||
next if File.directory? path
|
|
||||||
|
|
||||||
if (File.mtime(path) < 2.days.ago)
|
|
||||||
File.delete(path)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.base_directory
|
|
||||||
File.join(Rails.root, "public", "uploads", "csv_exports", RailsMultisite::ConnectionManagement.current_db)
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
|
@ -436,8 +436,10 @@ Discourse::Application.routes.draw do
|
||||||
collection do
|
collection do
|
||||||
get "export_entity" => "export_csv#export_entity"
|
get "export_entity" => "export_csv#export_entity"
|
||||||
end
|
end
|
||||||
|
member do
|
||||||
|
get "" => "export_csv#show", constraints: { id: /[^\/]+/ }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
get "export_csv/:entity/:file_id" => "export_csv#show", constraints: {entity: USERNAME_ROUTE_FORMAT, file_id: /[^\/]+/}
|
|
||||||
|
|
||||||
get "onebox" => "onebox#show"
|
get "onebox" => "onebox#show"
|
||||||
|
|
||||||
|
|
9
db/migrate/20141223145058_create_csv_export_logs.rb
Normal file
9
db/migrate/20141223145058_create_csv_export_logs.rb
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
class CreateCsvExportLogs < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
create_table :csv_export_logs do |t|
|
||||||
|
t.string :export_type, null: false
|
||||||
|
t.integer :user_id, null: false
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,8 +1,7 @@
|
||||||
require "spec_helper"
|
require "spec_helper"
|
||||||
|
|
||||||
describe ExportCsvController do
|
describe ExportCsvController do
|
||||||
|
let(:export_filename) { "export_999.csv" }
|
||||||
let(:export_filename) { "export_b6a2bc87.csv" }
|
|
||||||
|
|
||||||
|
|
||||||
context "while logged in as normal user" do
|
context "while logged in as normal user" do
|
||||||
|
@ -23,23 +22,24 @@ describe ExportCsvController do
|
||||||
|
|
||||||
describe ".download" do
|
describe ".download" do
|
||||||
it "uses send_file to transmit the export file" do
|
it "uses send_file to transmit the export file" do
|
||||||
|
file = CsvExportLog.create(export_type: "user", user_id: @user.id)
|
||||||
|
file_name = "export_#{file.id}.csv"
|
||||||
controller.stubs(:render)
|
controller.stubs(:render)
|
||||||
export = ExportCsv.new()
|
export = CsvExportLog.new()
|
||||||
ExportCsv.expects(:get_download_path).with(export_filename).returns(export)
|
CsvExportLog.expects(:get_download_path).with(file_name).returns(export)
|
||||||
subject.expects(:send_file).with(export)
|
subject.expects(:send_file).with(export)
|
||||||
get :show, entity: "username", file_id: export_filename
|
get :show, id: file_name
|
||||||
response.should be_success
|
response.should be_success
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns 404 when the normal user tries to access admin export file" do
|
it "returns 404 when the user tries to export another user's csv file" do
|
||||||
controller.stubs(:render)
|
get :show, id: export_filename
|
||||||
get :show, entity: "system", file_id: export_filename
|
response.should be_not_found
|
||||||
response.should_not be_success
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns 404 when the export file does not exist" do
|
it "returns 404 when the export file does not exist" do
|
||||||
ExportCsv.expects(:get_download_path).returns(nil)
|
CsvExportLog.expects(:get_download_path).returns(nil)
|
||||||
get :show, entity: "username", file_id: export_filename
|
get :show, id: export_filename
|
||||||
response.should be_not_found
|
response.should be_not_found
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -59,17 +59,19 @@ describe ExportCsvController do
|
||||||
|
|
||||||
describe ".download" do
|
describe ".download" do
|
||||||
it "uses send_file to transmit the export file" do
|
it "uses send_file to transmit the export file" do
|
||||||
|
file = CsvExportLog.create(export_type: "admin", user_id: @admin.id)
|
||||||
|
file_name = "export_#{file.id}.csv"
|
||||||
controller.stubs(:render)
|
controller.stubs(:render)
|
||||||
export = ExportCsv.new()
|
export = CsvExportLog.new()
|
||||||
ExportCsv.expects(:get_download_path).with(export_filename).returns(export)
|
CsvExportLog.expects(:get_download_path).with(file_name).returns(export)
|
||||||
subject.expects(:send_file).with(export)
|
subject.expects(:send_file).with(export)
|
||||||
get :show, entity: "system", file_id: export_filename
|
get :show, id: file_name
|
||||||
response.should be_success
|
response.should be_success
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns 404 when the export file does not exist" do
|
it "returns 404 when the export file does not exist" do
|
||||||
ExportCsv.expects(:get_download_path).returns(nil)
|
CsvExportLog.expects(:get_download_path).returns(nil)
|
||||||
get :show, entity: "system", file_id: export_filename
|
get :show, id: export_filename
|
||||||
response.should be_not_found
|
response.should be_not_found
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue