scinote-web/lib/tasks/data.rake

233 lines
8.1 KiB
Ruby

# frozen_string_literal: true
# rubocop:disable Metrics/BlockLength
namespace :data do
Rails.logger = Logger.new(STDOUT)
desc "Remove expired temporary files"
task clean_temp_files: :environment do
Rails.logger.info "Cleaning temporary files older than 3 days"
TempFile.where("created_at < ?", 3.days.ago).each do |tmp_file|
TempFile.transaction do
begin
tmp_file.destroy!
rescue Exception => e
Rails.logger.error "Failed to destroy temporary file #{tmp_file.id}: #{e}"
raise ActiveRecord::Rollback
else
Rails.logger.info "Temporary file ##{tmp_file.id} removed"
end
end
end
end
def destroy_users(users)
users.each do |user|
User.transaction do
begin
# Destroy user team assignments, and possibly team
if user.teams.count > 0
oids = user.teams.pluck(:id)
oids.each do |oid|
team = Team.find(oid)
team_assignment = user.user_assignments.where(assignable: team).take
destroy_team = (team.users.count == 1 && team.created_by == user)
team_assignment.destroy!
team.destroy! if destroy_team
end
end
user.destroy!
rescue Exception => e
Rails.logger.error "Failed to destroy unconfirmed user #{user.id}: #{e}"
raise ActiveRecord::Rollback
else
Rails.logger.info "Unconfirmed user ##{user.id} removed"
end
end
end
end
desc "Remove unconfirmed user accounts"
task clean_unconfirmed_users: :environment do
Rails.logger.info "Cleaning unconfirmed users"
# First, remove the users who signed up by themselves
users = User
.where(confirmed_at: nil)
.where.not(confirmation_token: nil)
.where(invitation_token: nil)
.where("created_at < ?", Devise.confirm_within.ago)
destroy_users(users)
# Now, remove users who were invited
users = User
.where(confirmed_at: nil)
.where(invitation_accepted_at: nil)
.where(confirmation_token: nil)
.where.not(invitation_token: nil)
.where("created_at < ?", Devise.invite_for.ago)
destroy_users(users)
# Remove users who didn't finish signup with LinkedIn
users = User.joins(:user_identities)
.where(confirmed_at: nil)
.where('users.created_at < ?', Devise.confirm_within.ago)
destroy_users(users)
end
desc "Remove temporary and obsolete data"
task clean: [:environment, :clean_temp_files, :clean_unconfirmed_users]
desc 'Export team to directory'
task :team_export, [:team_id] => [:environment] do |_, args|
Rails.logger.info(
"Exporting team with ID:#{args[:team_id]} to directory in tmp"
)
te = ModelExporters::TeamExporter.new(args[:team_id])
te&.export_to_dir
end
desc 'Import team from directory'
task :team_import, [:dir_path] => [:environment] do |_, args|
Rails.logger.info(
"Importing team from directory #{args[:dir_path]}"
)
TeamImporter.new.import_from_dir(args[:dir_path])
end
desc 'Delete team and all data inside the team'
task :team_delete, [:team_id] => [:environment] do |_, args|
Rails.logger.info(
"Deleting team with ID:#{args[:team_id]} and all data inside the team"
)
team = Team.find_by_id(args[:team_id])
raise StandardError, 'Can not load team' unless team
UserDataDeletion.delete_team_data(team) if team
end
desc 'Export experiment to directory'
task :experiment_template_export,
[:experiment_id] => [:environment] do |_, args|
Rails.logger.info(
"Exporting experiment template with ID:#{args[:experiment_id]} "\
"to directory in tmp"
)
ee = ModelExporters::ExperimentExporter.new(args[:experiment_id])
ee&.export_template_to_dir
end
desc 'Import experiment from directory to given project'
task :experiment_template_import,
%i(dir_path project_id user_id) => [:environment] do |_, args|
Rails.logger.info(
"Importing experiment from directory #{args[:dir_path]}"
)
TeamImporter.new.import_experiment_template_from_dir(args[:dir_path],
args[:project_id],
args[:user_id])
end
desc 'Update all templates projects'
task :update_all_templates,
%i(slice_size) => [:environment] do |_, args|
args.with_defaults(slice_size: 800)
Rails.logger.info('Templates, syncing all templates projects')
Team.all.order(updated_at: :desc)
.each_slice(args[:slice_size].to_i).with_index do |teams, i|
Rails.logger.info("Processing slice with index #{i}. " \
"First team: #{teams.first.id}, " \
"Last team: #{teams.last.id}.")
teams.each do |team|
TemplatesService.new.delay(
run_at: i.hours.from_now,
queue: :templates,
priority: 5
).update_team(team)
end
end
end
desc 'Purge all experiment workflow images'
task purge_experiment_workflow_images: :environment do
ActiveStorage::Attachment.where(name: 'workflowimg').delete_all
end
desc 'Purge all experiment workflow images'
task cleanup_blobs: :environment do
ActiveStorage::Blob.unattached.find_each(&:purge_later)
end
desc 'Reset to defaults all predefined user roles'
task reset_predefined_user_roles: :environment do
ActiveRecord::Base.transaction do
%i(owner_role normal_user_role technician_role viewer_role).each do |predefined_role|
reference_role = UserRole.public_send(predefined_role)
existing_role = UserRole.find_by(name: reference_role.name)
if existing_role.present?
# rubocop:disable Rails/SkipsModelValidations
existing_role.update_attribute(:permissions, reference_role.permissions)
# rubocop:enable Rails/SkipsModelValidations
else
reference_role.save!
end
end
end
end
desc 'Reset repositories user assignments'
task reset_repositories_user_assignments: :environment do
ActiveRecord::Base.transaction do
Team.all.find_each do |team|
team.user_assignments.find_each do |team_user_assignment|
team.repositories.find_each do |repository|
new_user_assignment =
repository.automatic_user_assignments.find_or_initialize_by(user: team_user_assignment.user, team: team)
new_user_assignment.user_role = team_user_assignment.user_role
new_user_assignment.assigned_by = team_user_assignment.assigned_by
new_user_assignment.assigned = :automatically
new_user_assignment.save!
end
end
end
end
end
desc 'Reset protocols creator user assignments'
task reset_protocols_creator_user_assignments: :environment do
ActiveRecord::Base.transaction do
owner_role = UserRole.find_predefined_owner_role
protocols =
Protocol.where(protocol_type: Protocol::REPOSITORY_TYPES)
.joins('LEFT OUTER JOIN "user_assignments" ON "user_assignments"."assignable_type" = \'Protocol\' ' \
'AND "user_assignments"."assignable_id" = "protocols"."id" ' \
'AND "user_assignments"."assigned" = 1 ' \
'AND "user_assignments"."user_id" = "protocols"."added_by_id"')
.where('"user_assignments"."id" IS NULL')
.distinct
protocols.find_each do |protocol|
new_user_assignment = protocol.user_assignments
.find_or_initialize_by(user: protocol.added_by, team: protocol.team)
new_user_assignment.user_role = owner_role
new_user_assignment.assigned_by = protocol.added_by
new_user_assignment.assigned = :manually
new_user_assignment.save!
end
end
end
desc 'Extract missing asset texts'
task extract_missing_asset_texts: :environment do
Asset.joins(:file_blob)
.where.missing(:asset_text_datum)
.where(file_blob: { content_type: Constants::TEXT_EXTRACT_FILE_TYPES })
.find_each(&:extract_asset_text)
end
end
# rubocop:enable Metrics/BlockLength