<commit_before>require 'forwardable'
require 'bio'
require 'fileutils'

module GeneValidatorApp

  module GeneValidator
    # To signal error in query sequence or options.
    #
    # ArgumentError is raised when BLAST+'s exit status is 1; see [1].
    class ArgumentError < ArgumentError
    end

    # To signal internal errors.
    #
    # RuntimeError is raised when there is a problem in writing the input file,
    # in running BLAST, get_raw_sequence or genevalidator. These are rare,
    # infrastructure errors, used internally, and of concern only to the
    # admins/developers.
    class RuntimeError  < RuntimeError
    end

    class << self
      extend Forwardable

      def_delegators GeneValidatorApp, :config, :logger
      
      attr_reader :gv_dir, :tmp_gv_dir, :input_file, :xml_file, :raw_seq,
                  :unique_id, :params

      # Setting the scene
      def init(url, params)
        create_unique_id
        create_subdir_in_main_tmpdir
        create_soft_link_from_tmpdir_to_GV_dir
        @params = params
        validate_params
        obtain_db_path
        @url = produce_result_url_link(url)
      end

      # Run BLAST(X/P), get_raw_sequence and genevalidator
      #  Returns html for just the table or a link to the page produced by GV 
      def run
        write_seq_to_file
        run_blast
        run_get_raw_sequence
        run_genevalidator
        (@params[:result_link]) ? @url : produce_table_html
      end

      private

      # Creates a unique run ID (based on time),
      def create_unique_id
        @unique_id = Time.new.strftime('%Y-%m-%d_%H-%M-%S_%L-%N')
        @gv_tmpdir = GeneValidatorApp.tempdir + unique_id
        ensure_unique_id
      end

      # Ensures that the Unique id is unique (if a sub dir is present in the  
      #  temp dir with the unique id, it simply creates a new one)
      def ensure_unique_id
        while File.exist?(@gv_tmpdir)
          @unique_id = GeneValidator.create_unique_id
          @gv_tmpdir = GeneValidatorApp.tempdir + @unique_id
        end
        logger.debug("Unique ID = #{@unique_id}")
      end

      # Create a sub_dir in the Tempdir (name is based on unique id)
      def create_subdir_in_main_tmpdir
        logger.debug("GV Tempdir = #{@gv_tmpdir}")
        FileUtils.mkdir_p(@gv_tmpdir)
      end

      # Create the Tmp Dir and the create a soft link to it.
      def create_soft_link_from_tmpdir_to_GV_dir
        @gv_dir = GeneValidatorApp.public_dir + 'GeneValidator' + @unique_id
        logger.debug("Local GV dir = #{@gv_dir}")
        FileUtils.ln_s "#{@gv_tmpdir}", "#{@gv_dir}"
      end

      # Validates the paramaters provided via the app.
      #  Only important if POST request is sent via API - Web APP, validates 
      #  all params via Javascript.
      def validate_params
        assert_seq_param_present
        # TODO: validate the seq length is smaller than max Characters.
        assert_validations_param_present
        assert_database_params_present
      end

      # Simply asserts whether that the seq param is present
      def assert_seq_param_present
        unless @params[:seq]
          fail ArgumentError, 'No input sequence provided.'
        end
        logger.debug("seq param = #{@params[:seq]}")
      end

      # Asserts whether the validations param are specified
      def assert_validations_param_present
        unless @params[:validations]
          fail ArgumentError, 'No validations specified'
        end
        logger.debug("validations param = #{@params[:validations]}")
      end

      # Asserts whether the database parameter is present
      def assert_database_params_present
        unless @params[:database]
          fail ArgumentError, 'No database specified'
        end
        logger.debug("database param = #{@params[:database]}")
      end

      def obtain_db_path
        Database.obtain_original_structure(@params[:database]).each do |db|
          @db = db.name
        end
      end
<commit_msg>validate whether the input sequence is smaller than max_characters value<commit_after>require 'forwardable'
require 'bio'
require 'fileutils'

module GeneValidatorApp

  module GeneValidator
    # To signal error in query sequence or options.
    #
    # ArgumentError is raised when BLAST+'s exit status is 1; see [1].
    class ArgumentError < ArgumentError
    end

    # To signal internal errors.
    #
    # RuntimeError is raised when there is a problem in writing the input file,
    # in running BLAST, get_raw_sequence or genevalidator. These are rare,
    # infrastructure errors, used internally, and of concern only to the
    # admins/developers.
    class RuntimeError  < RuntimeError
    end

    class << self
      extend Forwardable

      def_delegators GeneValidatorApp, :config, :logger
      
      attr_reader :gv_dir, :tmp_gv_dir, :input_file, :xml_file, :raw_seq,
                  :unique_id, :params

      # Setting the scene
      def init(url, params)
        create_unique_id
        create_subdir_in_main_tmpdir
        create_soft_link_from_tmpdir_to_GV_dir
        @params = params
        validate_params
        obtain_db_path
        @url = produce_result_url_link(url)
      end

      # Run BLAST(X/P), get_raw_sequence and genevalidator
      #  Returns html for just the table or a link to the page produced by GV 
      def run
        write_seq_to_file
        run_blast
        run_get_raw_sequence
        run_genevalidator
        (@params[:result_link]) ? @url : produce_table_html
      end

      private

      # Creates a unique run ID (based on time),
      def create_unique_id
        @unique_id = Time.new.strftime('%Y-%m-%d_%H-%M-%S_%L-%N')
        @gv_tmpdir = GeneValidatorApp.tempdir + unique_id
        ensure_unique_id
      end

      # Ensures that the Unique id is unique (if a sub dir is present in the  
      #  temp dir with the unique id, it simply creates a new one)
      def ensure_unique_id
        while File.exist?(@gv_tmpdir)
          @unique_id = GeneValidator.create_unique_id
          @gv_tmpdir = GeneValidatorApp.tempdir + @unique_id
        end
        logger.debug("Unique ID = #{@unique_id}")
      end

      # Create a sub_dir in the Tempdir (name is based on unique id)
      def create_subdir_in_main_tmpdir
        logger.debug("GV Tempdir = #{@gv_tmpdir}")
        FileUtils.mkdir_p(@gv_tmpdir)
      end

      # Create the Tmp Dir and the create a soft link to it.
      def create_soft_link_from_tmpdir_to_GV_dir
        @gv_dir = GeneValidatorApp.public_dir + 'GeneValidator' + @unique_id
        logger.debug("Local GV dir = #{@gv_dir}")
        FileUtils.ln_s "#{@gv_tmpdir}", "#{@gv_dir}"
      end

      # Validates the paramaters provided via the app.
      #  Only important if POST request is sent via API - Web APP, validates 
      #  all params via Javascript.
      def validate_params
        assert_seq_param_present
        assert_seq_length if config[:max_characters]
        assert_validations_param_present
        assert_database_params_present
      end

      # Simply asserts whether that the seq param is present
      def assert_seq_param_present
        unless @params[:seq]
          fail ArgumentError, 'No input sequence provided.'
        end
        logger.debug("seq param = #{@params[:seq]}")
      end

      def assert_seq_length
        unless @params[:seq].length < config[:max_characters]
          fail ArgumentError, 'The input sequence is too long.'
        end
        logger.debug("seq length = #{@params[:seq].length}")
      end

      # Asserts whether the validations param are specified
      def assert_validations_param_present
        unless @params[:validations]
          fail ArgumentError, 'No validations specified'
        end
        logger.debug("validations param = #{@params[:validations]}")
      end

      # Asserts whether the database parameter is present
      def assert_database_params_present
        unless @params[:database]
          fail ArgumentError, 'No database specified'
        end
        logger.debug("database param = #{@params[:database]}")
      end

      def obtain_db_path
        Database.obtain_original_structure(@params[:database]).each do |db|
          @db = db.name
        end
      end

{'fraction_non_alphanumeric': 0.06966916203815504, 'fraction_numerical': 0.0004829751267809708, 'mean_word_length': 2.4890480202190397, 'pattern_counts': {'":': 0, '<': 12, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2122148', 'n_tokens_mistral': 2421, 'n_tokens_neox': 2350, 'n_words': 728}