2018-09-13 16:37:21 +08:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
module Api
|
|
|
|
module V1
|
|
|
|
class ResultsController < BaseController
|
2019-09-24 18:41:45 +08:00
|
|
|
before_action :load_team, :load_project, :load_experiment, :load_task
|
|
|
|
before_action :load_result, only: %i(show update)
|
|
|
|
before_action :check_manage_permissions, only: %i(create update)
|
2018-09-13 16:37:21 +08:00
|
|
|
|
|
|
|
def index
|
2023-07-31 18:21:40 +08:00
|
|
|
results = timestamps_filter(@task.results).page(params.dig(:page, :number))
|
|
|
|
.per(params.dig(:page, :size))
|
2018-09-13 16:37:21 +08:00
|
|
|
render jsonapi: results, each_serializer: ResultSerializer,
|
2021-08-18 16:00:01 +08:00
|
|
|
include: (%i(text table file) << include_params).flatten.compact
|
2018-09-13 16:37:21 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
def create
|
|
|
|
create_text_result if result_text_params.present?
|
2019-09-24 18:41:45 +08:00
|
|
|
create_file_result if !@result && result_file_params.present?
|
|
|
|
|
2018-09-13 16:37:21 +08:00
|
|
|
render jsonapi: @result,
|
|
|
|
serializer: ResultSerializer,
|
2018-10-07 18:36:58 +08:00
|
|
|
include: %i(text table file),
|
2018-09-13 16:37:21 +08:00
|
|
|
status: :created
|
|
|
|
end
|
|
|
|
|
2019-09-24 18:41:45 +08:00
|
|
|
def update
|
|
|
|
@result.attributes = result_params
|
|
|
|
|
2023-08-16 16:37:44 +08:00
|
|
|
update_file_result if result_file_params.present? && @result.assets.any?
|
|
|
|
update_text_result if result_text_params.present? && @result.result_texts.any?
|
2020-07-25 17:41:26 +08:00
|
|
|
|
2019-09-24 18:41:45 +08:00
|
|
|
if (@result.changed? && @result.save!) || @asset_result_updated
|
|
|
|
render jsonapi: @result,
|
|
|
|
serializer: ResultSerializer,
|
|
|
|
include: %i(text table file),
|
|
|
|
status: :ok
|
|
|
|
else
|
|
|
|
render body: nil, status: :no_content
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-09-13 16:37:21 +08:00
|
|
|
def show
|
|
|
|
render jsonapi: @result, serializer: ResultSerializer,
|
2021-08-18 16:00:01 +08:00
|
|
|
include: (%i(text table file) << include_params).flatten.compact
|
2018-09-13 16:37:21 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
def load_result
|
|
|
|
@result = @task.results.find(params.require(:id))
|
|
|
|
end
|
|
|
|
|
|
|
|
def check_manage_permissions
|
2021-09-14 17:08:35 +08:00
|
|
|
raise PermissionError.new(MyModule, :manage) unless can_manage_my_module?(@task)
|
2018-09-13 16:37:21 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
def create_text_result
|
2019-09-24 18:41:45 +08:00
|
|
|
# rubocop:disable Metrics/BlockLength:
|
2019-09-04 19:41:06 +08:00
|
|
|
Result.transaction do
|
|
|
|
@result = Result.create!(
|
|
|
|
user: current_user,
|
|
|
|
my_module: @task,
|
|
|
|
name: result_params[:name],
|
|
|
|
last_modified_by: current_user
|
|
|
|
)
|
|
|
|
|
|
|
|
result_text = ResultText.create!(
|
|
|
|
result: @result,
|
|
|
|
text: convert_old_tiny_mce_format(result_text_params[:text])
|
|
|
|
)
|
|
|
|
|
2023-08-16 16:37:44 +08:00
|
|
|
@result.result_orderable_elements.create!(
|
|
|
|
position: 0,
|
|
|
|
orderable: result_text
|
|
|
|
)
|
|
|
|
|
2018-09-13 16:37:21 +08:00
|
|
|
if tiny_mce_asset_params.present?
|
|
|
|
tiny_mce_asset_params.each do |t|
|
|
|
|
image_params = t[:attributes]
|
|
|
|
token = image_params[:file_token]
|
2019-04-02 19:41:32 +08:00
|
|
|
unless result_text.text["data-mce-token=\"#{token}\""]
|
2018-11-07 23:39:00 +08:00
|
|
|
raise ActiveRecord::RecordInvalid,
|
|
|
|
I18n.t('api.core.errors.result_wrong_tinymce.detail')
|
2018-09-13 16:37:21 +08:00
|
|
|
end
|
2019-04-19 20:44:16 +08:00
|
|
|
tiny_image = TinyMceAsset.create!(
|
2019-03-11 20:43:50 +08:00
|
|
|
team: @team,
|
|
|
|
object: result_text,
|
|
|
|
saved: true
|
|
|
|
)
|
2019-08-21 19:26:11 +08:00
|
|
|
tiny_image.image.attach(
|
|
|
|
io: StringIO.new(Base64.decode64(image_params[:file_data].split(',')[1])),
|
|
|
|
filename: image_params[:file_name]
|
|
|
|
)
|
2019-04-19 20:44:16 +08:00
|
|
|
result_text.text.sub!("data-mce-token=\"#{token}\"", "data-mce-token=\"#{Base62.encode(tiny_image.id)}\"")
|
2018-09-13 16:37:21 +08:00
|
|
|
end
|
2019-09-04 19:41:06 +08:00
|
|
|
result_text.save!
|
2018-09-13 16:37:21 +08:00
|
|
|
end
|
|
|
|
end
|
2019-09-24 18:41:45 +08:00
|
|
|
# rubocop:enable Metrics/BlockLength:
|
|
|
|
end
|
|
|
|
|
|
|
|
def update_text_result
|
|
|
|
raise NotImplementedError, 'update_text_result should be implemented!'
|
|
|
|
end
|
|
|
|
|
|
|
|
def create_file_result
|
|
|
|
Result.transaction do
|
|
|
|
@result = @task.results.create!(result_params.merge(user_id: current_user.id))
|
2020-07-25 17:41:26 +08:00
|
|
|
if @form_multipart_upload
|
2020-09-25 14:38:38 +08:00
|
|
|
asset = Asset.create!(result_file_params.merge({ team_id: @team.id }))
|
2020-07-25 17:41:26 +08:00
|
|
|
else
|
|
|
|
blob = create_blob_from_params
|
2020-09-25 14:38:38 +08:00
|
|
|
asset = Asset.create!(file: blob, team: @team)
|
2020-07-24 20:56:42 +08:00
|
|
|
end
|
2024-02-05 23:24:06 +08:00
|
|
|
asset.post_process_file
|
2019-09-24 18:41:45 +08:00
|
|
|
ResultAsset.create!(asset: asset, result: @result)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def update_file_result
|
|
|
|
old_checksum, new_checksum = nil
|
2023-08-16 16:37:44 +08:00
|
|
|
asset = @result.assets.order(created_at: :asc).first
|
2019-09-24 18:41:45 +08:00
|
|
|
Result.transaction do
|
2023-08-16 16:37:44 +08:00
|
|
|
old_checksum = asset.file.blob.checksum
|
2020-07-25 17:41:26 +08:00
|
|
|
if @form_multipart_upload
|
2023-08-16 16:37:44 +08:00
|
|
|
asset.file.attach(result_file_params[:file])
|
2020-07-25 17:41:26 +08:00
|
|
|
else
|
|
|
|
blob = create_blob_from_params
|
2023-08-16 16:37:44 +08:00
|
|
|
asset.update!(file: blob)
|
2020-07-25 17:41:26 +08:00
|
|
|
end
|
2024-02-05 23:24:06 +08:00
|
|
|
asset.post_process_file
|
2023-08-16 16:37:44 +08:00
|
|
|
new_checksum = asset.file.blob.checksum
|
2019-09-24 18:41:45 +08:00
|
|
|
end
|
|
|
|
@asset_result_updated = old_checksum != new_checksum
|
2018-09-13 16:37:21 +08:00
|
|
|
end
|
|
|
|
|
2020-07-25 17:41:26 +08:00
|
|
|
def create_blob_from_params
|
2021-01-28 21:43:45 +08:00
|
|
|
blob = ActiveStorage::Blob.create_and_upload!(
|
2020-07-25 17:41:26 +08:00
|
|
|
io: StringIO.new(Base64.decode64(result_file_params[:file_data])),
|
|
|
|
filename: result_file_params[:file_name],
|
|
|
|
content_type: result_file_params[:file_type]
|
|
|
|
)
|
|
|
|
blob
|
|
|
|
end
|
|
|
|
|
2018-09-13 16:37:21 +08:00
|
|
|
def result_params
|
2018-10-23 23:52:48 +08:00
|
|
|
raise TypeError unless params.require(:data).require(:type) == 'results'
|
2019-03-11 20:43:50 +08:00
|
|
|
|
2018-09-13 16:37:21 +08:00
|
|
|
params.require(:data).require(:attributes).require(:name)
|
2018-09-25 00:10:37 +08:00
|
|
|
params.permit(data: { attributes: :name })[:data][:attributes]
|
2018-09-13 16:37:21 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
# Partially implement sideposting draft
|
|
|
|
# https://github.com/json-api/json-api/pull/1197
|
|
|
|
def result_text_params
|
2019-09-24 18:41:45 +08:00
|
|
|
prms = params[:included]&.select { |el| el[:type] == 'result_texts' }&.first
|
2019-10-18 17:16:27 +08:00
|
|
|
return nil unless prms
|
|
|
|
|
|
|
|
prms.require(:attributes).require(:text)
|
|
|
|
prms.dig(:attributes).permit(:text)
|
2019-09-24 18:41:45 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
def result_file_params
|
|
|
|
prms = params[:included]&.select { |el| el[:type] == 'result_files' }&.first
|
2019-10-18 17:16:27 +08:00
|
|
|
return nil unless prms
|
|
|
|
|
2020-07-25 17:41:26 +08:00
|
|
|
if prms.require(:attributes)[:file]
|
|
|
|
@form_multipart_upload = true
|
|
|
|
return prms.dig(:attributes).permit(:file)
|
|
|
|
end
|
|
|
|
attr_list = %i(file_data file_type file_name)
|
2020-07-24 20:56:42 +08:00
|
|
|
|
2020-07-25 17:41:26 +08:00
|
|
|
prms.require(:attributes).require(attr_list)
|
|
|
|
prms.dig(:attributes).permit(attr_list)
|
2018-09-13 16:37:21 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
def tiny_mce_asset_params
|
|
|
|
prms = params[:included]&.select { |el| el[:type] == 'tiny_mce_assets' }
|
|
|
|
prms.each do |p|
|
|
|
|
p.require(:attributes).require(%i(file_data file_name file_token))
|
|
|
|
end
|
2018-09-25 00:10:37 +08:00
|
|
|
file_tokens = prms.map { |p| p[:attributes][:file_token] }
|
|
|
|
result_text_params[:text].scan(
|
2019-04-02 22:04:50 +08:00
|
|
|
/data-mce-token="(\w+)"/
|
2018-09-25 00:10:37 +08:00
|
|
|
).flatten.each do |token|
|
|
|
|
unless file_tokens.include?(token)
|
2018-11-07 23:39:00 +08:00
|
|
|
raise ActiveRecord::RecordInvalid,
|
|
|
|
I18n.t('api.core.errors.result_missing_tinymce.detail')
|
2018-09-25 00:10:37 +08:00
|
|
|
end
|
|
|
|
end
|
2018-09-13 16:37:21 +08:00
|
|
|
prms
|
|
|
|
end
|
2019-04-19 20:44:16 +08:00
|
|
|
|
2021-08-18 16:00:01 +08:00
|
|
|
def permitted_includes
|
|
|
|
%w(comments)
|
|
|
|
end
|
|
|
|
|
2019-04-19 20:44:16 +08:00
|
|
|
def convert_old_tiny_mce_format(text)
|
|
|
|
text.scan(/\[~tiny_mce_id:(\w+)\]/).flatten.each do |token|
|
|
|
|
old_format = /\[~tiny_mce_id:#{token}\]/
|
|
|
|
new_format = "<img src=\"\" class=\"img-responsive\" data-mce-token=\"#{token}\"/>"
|
|
|
|
text.sub!(old_format, new_format)
|
|
|
|
end
|
|
|
|
text
|
|
|
|
end
|
2018-09-13 16:37:21 +08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|