scinote-web/app/controllers/assets_controller.rb

335 lines
11 KiB
Ruby
Raw Normal View History

# frozen_string_literal: true
2016-02-12 23:52:43 +08:00
class AssetsController < ApplicationController
2016-09-29 21:30:55 +08:00
include WopiUtil
2019-06-19 21:19:47 +08:00
include AssetsActions
2017-03-13 20:20:49 +08:00
# include ActionView::Helpers
include ActionView::Helpers::AssetTagHelper
include ActionView::Helpers::TextHelper
2017-03-13 20:20:49 +08:00
include ActionView::Helpers::UrlHelper
include ActionView::Context
include ApplicationHelper
2017-03-13 20:20:49 +08:00
include InputSanitizeHelper
include FileIconsHelper
include MyModulesHelper
2016-09-29 21:30:55 +08:00
2019-03-16 03:59:15 +08:00
before_action :load_vars, except: :create_wopi_file
2016-12-08 22:24:14 +08:00
before_action :check_read_permission, except: :file_present
2019-06-20 15:43:23 +08:00
before_action :check_edit_permission, only: %i(edit create_start_edit_image_activity)
2016-02-12 23:52:43 +08:00
2016-07-21 19:11:15 +08:00
def file_present
return render_403 unless @asset.team == current_team
2016-07-21 19:11:15 +08:00
respond_to do |format|
format.json do
if @asset.file.processing?
render json: { processing: true }
else
# Only if file is ready, check_read_permission
2016-07-21 19:11:15 +08:00
check_read_permission
# If check_read_permission already rendered error, stop execution
return if performed?
2016-07-21 19:11:15 +08:00
placeholder_html =
if @assoc.class == Step
render_to_string(partial: 'steps/attachments/placeholder.html.erb',
locals: { asset: @asset, edit_page: false })
else
render_to_string(partial: 'shared/asset_link_placeholder.html.erb',
locals: { asset: @asset, display_image_tag: true })
end
2016-07-21 19:11:15 +08:00
render json: { placeholder_html: placeholder_html, processing: false }
end
end
end
end
2018-03-30 17:50:28 +08:00
def file_preview
response_json = {
2018-10-19 16:00:58 +08:00
'id' => @asset.id,
2018-03-30 17:50:28 +08:00
'type' => (@asset.is_image? ? 'image' : 'file'),
'filename' => truncate(escape_input(@asset.file_file_name),
length: Constants::FILENAME_TRUNCATION_LENGTH),
2019-07-24 13:06:05 +08:00
'download-url' => asset_file_url_path(@asset)
2018-03-30 17:50:28 +08:00
}
2018-04-26 23:00:51 +08:00
can_edit = if @assoc.class == Step
can_manage_protocol_in_module?(@protocol) || can_manage_protocol_in_repository?(@protocol)
elsif @assoc.class == Result
can_manage_module?(@my_module)
elsif @assoc.class == RepositoryCell
2019-07-12 22:43:54 +08:00
can_manage_repository_rows?(@repository)
end
if @asset.is_image?
if ['image/jpeg', 'image/pjpeg'].include? @asset.file.content_type
response_json['quality'] = @asset.file_image_quality || 90
end
response_json.merge!(
'editable' => @asset.editable_image? && can_edit,
'mime-type' => @asset.file.content_type,
'processing' => @asset.file.processing?,
'large-preview-url' => @asset.url(:large),
'processing-img' => image_tag('medium/processing.gif')
)
2018-03-30 17:50:28 +08:00
else
response_json['processing'] = @asset.file.processing?
response_json['large-preview-url'] = @asset.url(:large)
response_json['preview-icon'] = render_to_string(
partial: 'shared/file_preview_icon.html.erb',
locals: { asset: @asset }
2018-03-30 17:50:28 +08:00
)
end
if wopi_enabled? && wopi_file?(@asset)
edit_supported, title = wopi_file_edit_button_status
2018-03-30 17:50:28 +08:00
response_json['wopi-controls'] = render_to_string(
partial: 'assets/wopi/file_wopi_controls.html.erb',
locals: {
asset: @asset,
can_edit: can_edit,
edit_supported: edit_supported,
title: title
}
2018-03-30 17:50:28 +08:00
)
end
respond_to do |format|
format.json do
2018-03-30 17:50:28 +08:00
render json: response_json
end
2016-02-12 23:52:43 +08:00
end
end
# Check whether the wopi file can be edited and return appropriate response
def wopi_file_edit_button_status
file_ext = @asset.file_file_name.split('.').last
if Constants::WOPI_EDITABLE_FORMATS.include?(file_ext)
edit_supported = true
title = ''
else
edit_supported = false
title = if Constants::FILE_TEXT_FORMATS.include?(file_ext)
I18n.t('assets.wopi_supported_text_formats_title')
elsif Constants::FILE_TABLE_FORMATS.include?(file_ext)
I18n.t('assets.wopi_supported_table_formats_title')
else
I18n.t('assets.wopi_supported_presentation_formats_title')
end
end
return edit_supported, title
end
2016-02-12 23:52:43 +08:00
def download
2016-07-21 19:11:15 +08:00
if !@asset.file_present
render_404 and return
elsif @asset.file.is_stored_on_s3?
redirect_to @asset.presigned_url(download: true), status: 307
2016-02-12 23:52:43 +08:00
else
send_file @asset.file.path, filename: URI.unescape(@asset.file_file_name),
2016-02-12 23:52:43 +08:00
type: @asset.file_content_type
end
end
2019-07-24 13:06:05 +08:00
def file_url
render_404 and return unless @asset.file_present
url = if @asset.file.is_stored_on_s3?
@asset.presigned_url(download: true)
else
@asset.file.url
end
render plain: url
end
def edit
action = @asset.file_file_size.zero? && !@asset.locked? ? 'editnew' : 'edit'
2016-10-05 00:00:08 +08:00
@action_url = append_wd_params(@asset
.get_action_url(current_user, action, false))
2016-09-29 18:19:29 +08:00
@favicon_url = @asset.favicon_url('edit')
tkn = current_user.get_wopi_token
@token = tkn.token
@ttl = (tkn.ttl * 1000).to_s
@asset.step&.protocol&.update(updated_at: Time.now)
2016-09-29 21:30:55 +08:00
create_wopi_file_activity(current_user, true)
2016-10-04 02:02:13 +08:00
render layout: false
end
def view
2016-10-05 00:00:08 +08:00
@action_url = append_wd_params(@asset
.get_action_url(current_user, 'view', false))
2016-09-29 18:19:29 +08:00
@favicon_url = @asset.favicon_url('view')
tkn = current_user.get_wopi_token
@token = tkn.token
@ttl = (tkn.ttl * 1000).to_s
2016-10-04 02:02:13 +08:00
render layout: false
end
2019-06-19 21:19:47 +08:00
def create_start_edit_image_activity
create_edit_image_activity(@asset, current_user, :start_editing)
end
2018-10-19 16:00:58 +08:00
def update_image
@asset = Asset.find(params[:id])
orig_file_size = @asset.file_file_size
orig_file_name = @asset.file_file_name
2018-10-19 16:00:58 +08:00
return render_403 unless can_read_team?(@asset.team)
@asset.file = params[:image]
@asset.file_file_name = orig_file_name
2018-10-19 16:00:58 +08:00
@asset.save!
2019-06-19 21:19:47 +08:00
create_edit_image_activity(@asset, current_user, :finish_editing)
# release previous image space
@asset.team.release_space(orig_file_size)
2018-10-19 16:00:58 +08:00
# Post process file here
@asset.post_process_file(@asset.team)
@asset.step&.protocol&.update(updated_at: Time.now)
render_html = if @asset.step
assets = @asset.step.assets
order_atoz = az_ordered_assets_index(assets, @asset.id)
order_ztoa = assets.length - az_ordered_assets_index(assets, @asset.id)
asset_position = @asset.step.asset_position(@asset)
render_to_string(
partial: 'steps/attachments/item.html.erb',
locals: {
asset: @asset,
i: asset_position[:pos],
assets_count: asset_position[:count],
step: @asset.step,
order_atoz: order_atoz,
order_ztoa: order_ztoa
},
formats: :html
)
else
render_to_string(
partial: 'shared/asset_link',
locals: { asset: @asset, display_image_tag: true },
formats: :html
)
end
respond_to do |format|
format.json do
render json: { html: render_html }
end
end
2018-10-19 16:00:58 +08:00
end
2019-03-18 02:23:17 +08:00
# POST: create_wopi_file_path
2019-03-16 03:59:15 +08:00
def create_wopi_file
2019-03-18 02:23:17 +08:00
# Presence validation
2019-03-21 15:47:52 +08:00
params.require(%i(element_type element_id file_type))
2019-03-19 17:19:27 +08:00
2019-03-18 02:23:17 +08:00
# File type validation
2019-03-19 17:19:27 +08:00
render_403 && return unless %w(docx xlsx pptx).include?(params[:file_type])
2019-03-18 02:23:17 +08:00
# Asset validation
2019-03-19 17:19:27 +08:00
file = Paperclip.io_adapters.for(StringIO.new)
file.original_filename = "#{params[:file_name]}.#{params[:file_type]}"
2019-03-18 02:23:17 +08:00
file.content_type = wopi_content_type(params[:file_type])
asset = Asset.new(file: file, created_by: current_user, file_present: true)
2019-03-21 15:47:52 +08:00
unless asset.valid?(:wopi_file_creation)
render json: {
message: asset.errors
}, status: 400 and return
2019-03-19 17:19:27 +08:00
end
2019-03-18 02:23:17 +08:00
2019-03-19 17:19:27 +08:00
# Create file depending on the type
2019-03-18 02:23:17 +08:00
if params[:element_type] == 'Step'
step = Step.find(params[:element_id].to_i)
render_403 && return unless can_manage_protocol_in_module?(step.protocol) ||
2019-03-19 17:19:27 +08:00
can_manage_protocol_in_repository?(step.protocol)
2019-03-18 02:23:17 +08:00
step_asset = StepAsset.create!(step: step, asset: asset)
step.protocol&.update(updated_at: Time.now)
2019-03-18 02:23:17 +08:00
edit_url = edit_asset_url(step_asset.asset_id)
elsif params[:element_type] == 'Result'
my_module = MyModule.find(params[:element_id].to_i)
render_403 and return unless can_manage_module?(my_module)
2019-03-19 17:19:27 +08:00
# First create result and then the asset
2019-03-18 02:23:17 +08:00
result = Result.create(name: file.original_filename,
my_module: my_module,
user: current_user)
result_asset = ResultAsset.create!(result: result, asset: asset)
edit_url = edit_asset_url(result_asset.asset_id)
else
2019-03-21 15:47:52 +08:00
render_404 and return
end
2019-03-18 02:23:17 +08:00
2019-03-19 17:19:27 +08:00
# Return edit url
2019-03-21 15:47:52 +08:00
render json: {
success: true,
edit_url: edit_url
}, status: :ok
2018-10-19 16:00:58 +08:00
end
2016-02-12 23:52:43 +08:00
private
def load_vars
@asset = Asset.find_by_id(params[:id])
return render_404 unless @asset
2016-02-12 23:52:43 +08:00
@assoc ||= @asset.step
@assoc ||= @asset.result
@assoc ||= @asset.repository_cell
2016-02-12 23:52:43 +08:00
2016-07-21 19:11:15 +08:00
if @assoc.class == Step
@protocol = @asset.step.protocol
2018-03-10 00:04:54 +08:00
elsif @assoc.class == Result
2016-07-21 19:11:15 +08:00
@my_module = @assoc.my_module
elsif @assoc.class == RepositoryCell
@repository = @assoc.repository_column.repository
2016-07-21 19:11:15 +08:00
end
2016-02-12 23:52:43 +08:00
end
def check_read_permission
if @assoc.class == Step
render_403 && return unless can_read_protocol_in_module?(@protocol) ||
can_read_protocol_in_repository?(@protocol)
2016-02-12 23:52:43 +08:00
elsif @assoc.class == Result
render_403 and return unless can_read_experiment?(@my_module.experiment)
2018-03-10 00:04:54 +08:00
elsif @assoc.class == RepositoryCell
render_403 and return unless can_read_repository?(@repository)
2016-02-12 23:52:43 +08:00
end
end
def check_edit_permission
if @assoc.class == Step
render_403 && return unless can_manage_protocol_in_module?(@protocol) ||
can_manage_protocol_in_repository?(@protocol)
elsif @assoc.class == Result
render_403 and return unless can_manage_module?(@my_module)
2018-03-10 00:04:54 +08:00
elsif @assoc.class == RepositoryCell
2019-07-12 22:43:54 +08:00
render_403 and return unless can_manage_repository_rows?(@repository)
end
end
2016-10-05 00:00:08 +08:00
def append_wd_params(url)
exclude_params = %w(wdPreviousSession wdPreviousCorrelation)
wd_params = params.as_json.select { |key, _value| key[/^wd.*/] && !(exclude_params.include? key) }.to_query
url + '&' + wd_params
2016-10-05 00:00:08 +08:00
end
def asset_params
params.permit(
:file
)
end
2017-03-13 20:20:49 +08:00
def asset_data_type(asset)
return 'wopi' if wopi_file?(asset)
return 'image' if asset.is_image?
2017-03-13 20:20:49 +08:00
'file'
end
2016-07-21 19:11:15 +08:00
end