app/models/setup/file_store_migration.rb
module Setup
class FileStoreMigration < Setup::Task
agent_field :data_type, :data_type_id
build_in_data_type
belongs_to :data_type, class_name: Setup::FileDataType.to_s, inverse_of: nil
def auto_description
if (file_type = agent_from_msg)
"Migrating file store of #{file_type.custom_title}"
else
super
end
end
def run(message)
if (data_type = agent_from_msg)
begin
config = data_type.file_store_config
total = data_type.all.count.to_f
processed = 0
if (file_store = message[:file_store])
file_store = file_store.to_s.constantize
unless file_store == data_type.file_store
data_type.all.each do |file|
if data_type.file_store.stored?(file)
file_store.save(file, file.data, public_read: false)
data_type.file_store.destroy(file)
end
processed += 1
update(progress: 89 * processed / total)
end
config.file_store = file_store
end
end
update(progress: 90)
processed = 0
if message.key?('public_read')
if (status = message[:public_read].to_s.to_b) || file_store.nil?
file_store ||= data_type.file_store
data_type.all.each do |file|
begin
file_store.set_public_read(file, status)
rescue ::Exception => ex
notify(message: "Error setting public read to #{status} on #{data_type.custom_title} ##{file.id} (#{file.filename}): #{ex.message}")
end
processed += 1
update(progress: 90 + 10 * processed / total)
end
end
config.public_read = status
end
config.save(skip_migration: true)
rescue ::Exception => ex
Setup::SystemNotification.create_from(ex)
fail "Error migrating data type #{data_type.custom_title} to file store #{message[:file_store]}: #{ex.message}"
end
else
fail "File Data Type with ID #{data_type_id} not found"
end
end
class << self
def migrating?(data_type)
Setup::FileStoreMigration.where(:status.in => Setup::Task::ALIVE_STATUS, data_type: data_type).present?
end
def enabled?
(user = ::User.current) &&
user.roles.any? { |role| ::Cenit.file_stores_roles.include?(role.name.to_s) }
end
def unable?
!enabled?
end
def cannot_migrate?(data_type)
unable? || migrating?(data_type)
end
end
end
end