<commit_before># frozen_string_literal: true

class AssetsController < ApplicationController
  include WopiUtil
  include AssetsActions
  # include ActionView::Helpers
  include ActionView::Helpers::AssetTagHelper
  include ActionView::Helpers::TextHelper
  include ActionView::Helpers::UrlHelper
  include ActionView::Context
  include ApplicationHelper
  include InputSanitizeHelper
  include FileIconsHelper

  before_action :load_vars, except: :create_wopi_file
  before_action :check_read_permission, except: :file_present
  before_action :check_edit_permission, only: %i(edit create_start_edit_image_activity)

  def file_present
    return render_403 unless @asset.team == current_team

    respond_to do |format|
      format.json do
        if @asset.file.processing?
          render json: { processing: true }
        else
          # Only if file is ready, check_read_permission
          check_read_permission
          # If check_read_permission already rendered error, stop execution
          return if performed?

          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

          render json: { placeholder_html: placeholder_html, processing: false }
        end
      end
    end
  end

  def file_preview
    response_json = {
      'id' => @asset.id,
      'type' => (@asset.is_image? ? 'image' : 'file'),

      'filename' => truncate(escape_input(@asset.file_file_name),
                             length: Constants::FILENAME_TRUNCATION_LENGTH),
      'download-url' => download_asset_path(@asset, timestamp: Time.now.to_i)
    }

    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
                 can_manage_repository_rows?(@repository.team)
               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')
      )
    else
      response_json['processing'] = @asset.file.processing?
      response_json['preview-icon'] = render_to_string(
        partial: 'shared/file_preview_icon.html.erb',
        locals: { asset: @asset }
      )
    end

    if wopi_enabled? && wopi_file?(@asset)
      edit_supported, title = wopi_file_edit_button_status
      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
        }
      )
    end
    respond_to do |format|
      format.json do
        render json: response_json
      end
    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

  def download
    if !@asset.file_present
      render_404 and return
    elsif @asset.file.is_stored_on_s3?
      redirect_to @asset.presigned_url(download: true), status: 307
    else
      send_file @asset.file.path, filename: URI.unescape(@asset.file_file_name),
        type: @asset.file_content_type
    end
  end

  def edit
    action = @asset.file_file_size.zero? && !@asset.locked? ? 'editnew' : 'edit'
    @action_url = append_wd_params(@asset
                                  .get_action_url(current_user, action, false))
    @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)

    create_wopi_file_activity(current_user, true)

    render layout: false
  end

  def view
    @action_url = append_wd_params(@asset
                                   .get_action_url(current_user, 'view', false))
    @favicon_url = @asset.favicon_url('view')
    tkn = current_user.get_wopi_token
    @token = tkn.token
    @ttl = (tkn.ttl * 1000).to_s

    render layout: false
  end

  def create_start_edit_image_activity
    create_edit_image_activity(@asset, current_user, :start_editing)
  end

  def update_image
    @asset = Asset.find(params[:id])
    orig_file_size = @asset.file_file_size
    orig_file_name = @asset.file_file_name
    return render_403 unless can_read_team?(@asset.team)

    @asset.file = params[:image]
    @asset.file_file_name = orig_file_name
    @asset.save!
    create_edit_image_activity(@asset, current_user, :finish_editing)
    # release previous image space
    @asset.team.release_space(orig_file_size)
    # Post process file here
    @asset.post_process_file(@asset.team)
    @asset.step&.protocol&.update(updated_at: Time.now)

    render_html = if @asset.step
                    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
                      },
                      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<commit_msg>Fix infinite update for image annotation (#1889)<commit_after># frozen_string_literal: true

class AssetsController < ApplicationController
  include WopiUtil
  include AssetsActions
  # include ActionView::Helpers
  include ActionView::Helpers::AssetTagHelper
  include ActionView::Helpers::TextHelper
  include ActionView::Helpers::UrlHelper
  include ActionView::Context
  include ApplicationHelper
  include InputSanitizeHelper
  include FileIconsHelper
  include MyModulesHelper

  before_action :load_vars, except: :create_wopi_file
  before_action :check_read_permission, except: :file_present
  before_action :check_edit_permission, only: %i(edit create_start_edit_image_activity)

  def file_present
    return render_403 unless @asset.team == current_team

    respond_to do |format|
      format.json do
        if @asset.file.processing?
          render json: { processing: true }
        else
          # Only if file is ready, check_read_permission
          check_read_permission
          # If check_read_permission already rendered error, stop execution
          return if performed?

          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

          render json: { placeholder_html: placeholder_html, processing: false }
        end
      end
    end
  end

  def file_preview
    response_json = {
      'id' => @asset.id,
      'type' => (@asset.is_image? ? 'image' : 'file'),

      'filename' => truncate(escape_input(@asset.file_file_name),
                             length: Constants::FILENAME_TRUNCATION_LENGTH),
      'download-url' => download_asset_path(@asset, timestamp: Time.now.to_i)
    }

    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
                 can_manage_repository_rows?(@repository.team)
               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')
      )
    else
      response_json['processing'] = @asset.file.processing?
      response_json['preview-icon'] = render_to_string(
        partial: 'shared/file_preview_icon.html.erb',
        locals: { asset: @asset }
      )
    end

    if wopi_enabled? && wopi_file?(@asset)
      edit_supported, title = wopi_file_edit_button_status
      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
        }
      )
    end
    respond_to do |format|
      format.json do
        render json: response_json
      end
    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

  def download
    if !@asset.file_present
      render_404 and return
    elsif @asset.file.is_stored_on_s3?
      redirect_to @asset.presigned_url(download: true), status: 307
    else
      send_file @asset.file.path, filename: URI.unescape(@asset.file_file_name),
        type: @asset.file_content_type
    end
  end

  def edit
    action = @asset.file_file_size.zero? && !@asset.locked? ? 'editnew' : 'edit'
    @action_url = append_wd_params(@asset
                                  .get_action_url(current_user, action, false))
    @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)

    create_wopi_file_activity(current_user, true)

    render layout: false
  end

  def view
    @action_url = append_wd_params(@asset
                                   .get_action_url(current_user, 'view', false))
    @favicon_url = @asset.favicon_url('view')
    tkn = current_user.get_wopi_token
    @token = tkn.token
    @ttl = (tkn.ttl * 1000).to_s

    render layout: false
  end

  def create_start_edit_image_activity
    create_edit_image_activity(@asset, current_user, :start_editing)
  end

  def update_image
    @asset = Asset.find(params[:id])
    orig_file_size = @asset.file_file_size
    orig_file_name = @asset.file_file_name
    return render_403 unless can_read_team?(@asset.team)

    @asset.file = params[:image]
    @asset.file_file_name = orig_file_name
    @asset.save!
    create_edit_image_activity(@asset, current_user, :finish_editing)
    # release previous image space
    @asset.team.release_space(orig_file_size)
    # 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
{'fraction_non_alphanumeric': 0.09199187276676242, 'fraction_numerical': 0.004343866040776291, 'mean_word_length': 2.2843994477680627, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7469387', 'n_tokens_mistral': 4340, 'n_tokens_neox': 4204, 'n_words': 804}