Retrospring/lib/exporter.rb

79 lines
2.3 KiB
Ruby
Raw Normal View History

# frozen_string_literal: true
2022-12-07 23:20:45 -08:00
require "fileutils"
require "securerandom"
require "zip/filesystem"
require "use_case/data_export/answers"
require "use_case/data_export/appendables"
require "use_case/data_export/comments"
require "use_case/data_export/inbox_entries"
require "use_case/data_export/mute_rules"
require "use_case/data_export/questions"
require "use_case/data_export/relationships"
require "use_case/data_export/theme"
require "use_case/data_export/user"
# the justask data exporter, now with 200% less shelling out to system tools!
#
# the data export can be easily extended by subclassing `UseCase::DataExport::Base`
# and `require`ing it above
2016-01-05 10:44:20 -08:00
class Exporter
def initialize(user)
@user = user
2022-12-07 23:20:45 -08:00
@export_name = "export-#{@user.id}-#{SecureRandom.base36(32)}"
FileUtils.mkdir_p(Rails.public_path.join("export")) # ensure the public export path exists
export_zipfile_path = Rails.public_path.join("export", "#{@export_name}.zip")
@zipfile = Zip::File.open(export_zipfile_path, Zip::File::CREATE)
2016-01-05 10:44:20 -08:00
end
def export
@user.export_processing = true
@user.save validate: false
2022-12-07 23:20:45 -08:00
prepare_zipfile
write_files
2016-01-05 10:44:20 -08:00
publish
2017-03-31 14:17:36 -07:00
rescue => e
2021-12-28 09:32:03 -08:00
Sentry.capture_exception(e)
2016-01-05 10:44:20 -08:00
@user.export_processing = false
@user.save validate: false
2022-12-07 23:20:45 -08:00
raise # so that e.g. the sidekiq job fails
ensure
2022-12-07 23:20:45 -08:00
@zipfile.close
2016-01-05 10:44:20 -08:00
end
private
2022-12-07 23:20:45 -08:00
# creates some directories we want to exist and sets a nice comment
def prepare_zipfile
@zipfile.mkdir(@export_name)
@zipfile.mkdir("#{@export_name}/pictures")
2016-01-05 10:44:20 -08:00
2022-12-07 23:20:45 -08:00
@zipfile.comment = <<~COMMENT
#{APP_CONFIG.fetch(:site_name)} export done for #{@user.screen_name} on #{Time.now.utc.iso8601}
COMMENT
2016-01-05 10:44:20 -08:00
end
2022-12-07 23:20:45 -08:00
# writes the files to the zip file
def write_files
UseCase::DataExport::Base.descendants.each do |export_klass|
export_klass.call(user: @user).each do |file_name, contents|
@zipfile.file.open("#{@export_name}/#{file_name}", "wb".dup) do |file| # .dup because of %(can't modify frozen String: "wb")
file.write contents
2016-01-05 10:44:20 -08:00
end
end
end
end
def publish
2022-12-07 23:20:45 -08:00
url = "#{APP_CONFIG['https'] ? 'https' : 'http'}://#{APP_CONFIG['hostname']}/export/#{@export_name}.zip"
2016-01-05 10:44:20 -08:00
@user.export_processing = false
@user.export_url = url
2022-07-10 11:11:48 -07:00
@user.export_created_at = Time.now.utc
2016-01-05 10:44:20 -08:00
@user.save validate: false
url
end
end