scinote-web/app/controllers/gene_sequence_assets_controller.rb
2024-03-21 10:38:27 +01:00

241 lines
5.9 KiB
Ruby

# frozen_string_literal: true
class GeneSequenceAssetsController < ApplicationController
include ActiveStorage::SetCurrent
skip_before_action :verify_authenticity_token
before_action :check_open_vector_service_enabled, except: %i(new edit)
before_action :load_vars, except: %i(new create)
before_action :load_create_vars, only: %i(new create)
before_action :check_read_permission
before_action :check_manage_permission, only: %i(new update create)
def new
render :edit, layout: false
end
def edit
@file_url = rails_representation_url(@asset.file)
@file_name = @asset.render_file_name
log_activity('sequence_asset_edit_started')
render :edit, layout: false
end
def create
save_asset!
case @parent
when Step
log_activity('sequence_asset_added')
when Result
log_result_activity(
:sequence_on_result_added,
@parent,
file: @asset.file_name,
user: current_user.id
)
end
head :ok
end
def update
save_asset!
case @parent
when Step
log_activity('sequence_asset_edit_finished')
when Result
log_result_activity(
:sequence_on_result_edited,
@parent,
file: @asset.file_name,
user: current_user.id
)
end
head :ok
end
def destroy
log_activity('sequence_asset_deleted')
head :ok
end
def rename
new_name = params.require(:asset).permit(:name)[:name]
if new_name.empty?
render json: { error: 'File name must be at least 1 character long.' }, status: :unprocessable_entity
return
elsif new_name.length > Constants::NAME_MAX_LENGTH
render json: { error: 'File name is too long (maximum number is 255 characters).' }, status: :unprocessable_entity
return
end
asset = current_team.assets.find_by(id: params[:id])
return render_404 unless asset
ActiveRecord::Base.transaction do
asset.last_modified_by = current_user
asset.rename_file(new_name)
asset.save!
# log_activity(TODO)
end
render json: asset, serializer: AssetSerializer, user: current_user
rescue StandardError => e
Rails.logger.error(e.message)
Rails.logger.error(e.backtrace.join("\n"))
render json: { error: I18n.t('errors.general') }, status: :unprocessable_entity
end
private
def save_asset!
ActiveRecord::Base.transaction do
view_mode = @asset.view_mode if @asset
ensure_asset!
@asset.file.purge
@asset.preview_image.purge
@asset.file.attach(
io: StringIO.new(params[:sequence_data].to_json),
filename: "#{params[:sequence_name]}.json"
)
@asset.preview_image.attach(
io: StringIO.new(Base64.decode64(params[:base64_image].split(',').last)),
filename: "#{params[:sequence_name]}.png"
)
file = @asset.file
file.blob.metadata['asset_type'] = 'gene_sequence'
file.blob.metadata['name'] = params[:sequence_name]
file.save!
@asset.view_mode = view_mode || @parent.assets_view_mode
@asset.last_modified_by = current_user
@asset.save!
end
end
def ensure_asset!
return if @asset
return unless @parent
@asset = @parent.assets.create!(last_modified_by: current_user, team: current_team)
end
def load_vars
@ove_enabled = OpenVectorEditorService.enabled?
@asset = current_team.assets.find_by(id: params[:id])
return render_404 unless @asset
@parent ||= @asset.step
@parent ||= @asset.result
case @parent
when Step
@protocol = @parent.protocol
when Result
@my_module = @parent.my_module
end
end
def load_create_vars
@ove_enabled = OpenVectorEditorService.enabled?
@parent = case params[:parent_type]
when 'Step'
Step.find_by(id: params[:parent_id])
when 'Result'
Result.find_by(id: params[:parent_id])
end
case @parent
when Step
@protocol = @parent.protocol
when Result
@result = @parent
end
end
def check_read_permission
case @parent
when Step
return render_403 unless can_read_protocol_in_module?(@protocol) ||
can_read_protocol_in_repository?(@protocol)
when Result
return render_403 unless can_read_result?(@parent)
else
render_403
end
end
def check_manage_permission
render_403 unless asset_managable?
end
def check_open_vector_service_enabled
render_403 unless OpenVectorEditorService.enabled?
end
helper_method :asset_managable?
def asset_managable?
case @parent
when Step
can_manage_step?(@parent)
when Result
can_manage_result?(@parent)
else
false
end
end
def log_activity(type_of, project = nil, message_items = {})
return unless @parent.is_a?(Step)
my_module = @parent.my_module
default_items = {
protocol: @parent.protocol.id,
step: @parent.id,
asset_name: { id: @asset.id, value_for: 'file_name' },
step_position: { id: @parent.id, value_for: 'position_plus_one' }
}
if my_module
project = my_module.project
default_items[:my_module] = my_module.id
type_of = "task_#{type_of}".to_sym
else
type_of = "protocol_#{type_of}".to_sym
end
message_items = default_items.merge(message_items)
Activities::CreateActivityService.call(
activity_type: type_of,
owner: current_user,
team: @parent.protocol.team,
subject: @parent.protocol,
message_items: message_items,
project: project
)
end
def log_result_activity(type_of, result, message_items)
Activities::CreateActivityService
.call(activity_type: type_of,
owner: current_user,
subject: result,
team: result.my_module.team,
project: result.my_module.project,
message_items: {
result: result.id
}.merge(message_items))
end
end