<commit_before>require 'octokit'

class Api::ApiController < ApplicationController
  respond_to :json

  before_action :set_headers, only: %i[pept2taxa pept2lca pept2prot pept2funct pept2ec pept2go pept2interpro peptinfo taxa2lca taxonomy taxa2tree]
  before_action :set_params, only: %i[pept2taxa pept2lca pept2prot pept2funct pept2ec pept2go pept2interpro peptinfo taxa2lca taxonomy taxa2tree]
  before_action :set_query, only: %i[pept2taxa pept2lca peptinfo taxonomy]
  before_action :set_sequences, only: %i[pept2prot]

  before_action :log, only: %i[pept2taxa pept2lca pept2prot pept2funct pept2ec pept2go pept2interpro peptinfo taxa2lca taxonomy taxa2tree]

  # sends a message to the ruby cli
  def messages
    version = params[:version]
    gem_version = Rails.application.config.versions[:gem]
    if Gem::Version.new(gem_version) > Gem::Version.new(version)
      render plain: "Unipept gem #{gem_version} is released!. Run 'gem update unipept' to update."
    else
      render plain: ''
    end
  end

  # Returns a list of Uniprot entries containing a given tryptic peptide
  # params[:input]: Array, required, List of input peptides
  # params[:equate_il]: "true" or "false" (default), optional, Equate I and L?
  # params[:extra]: "true" or "false" (default), optional, Output extra info?
  def pept2prot
    lookup = Hash.new { |h, k| h[k] = Set.new }
    if @extra_info
      @result = {}
      # Perform joins and load objects (expensive)
      ids = []
      @sequences.pluck(:sequence, 'uniprot_entries.id').each do |sequence, uniprot_id|
        ids.append uniprot_id
        lookup[uniprot_id] << sequence
        @result[sequence] = Set.new
      end

      ids = ids.uniq.compact.sort
      UniprotEntry.includes(:taxon, :ec_cross_references, :go_cross_references, :refseq_cross_references, :embl_cross_references)
                  .where(id: ids).find_in_batches do |group|
        group.each do |uni|
          lookup[uni.id].each { |s| @result[s] << uni }
        end
      end
    else
      @result = Hash.new { |h, k| h[k] = Set.new }
      @sequences.pluck(:sequence, 'uniprot_entries.uniprot_accession_number', 'uniprot_entries.name', 'uniprot_entries.taxon_id').each do |sequence, uniprot_id, protein_name, taxon_id|
        @result[sequence] << [uniprot_id, protein_name, taxon_id]
      end
    end

    filter_input_order

    respond_with(@result)
  end

  # Returns a list of taxa retrieved from the Uniprot entries containing a given tryptic peptide
  # param[input]: Array, required, List of input peptides
  # param[equate_il]: "true" or "false", Indicate if you want to equate I and L
  # param[extra]: "true" or "false", Include lineage
  # param[names]: "true" or "false", Include the lineage names
  def pept2taxa
    @result = {}
    lookup = Hash.new { |h, k| h[k] = Set.new }
    ids = Set.new

    seqid2seq = Hash.new
    Sequence.where(sequence: @input).select(:id, :sequence).each do |seq|
      seqid2seq[seq[:id]] = seq[:sequence]
      @result[seq[:sequence]] = Set.new
    end

    rel_name = @equate_il ? :sequence_id : :original_sequence_id
    Peptide.where(rel_name => seqid2seq.keys).select(:id, rel_name, :uniprot_entry_id).find_in_batches do |items|
      uniprot2seqids = Hash.new { |h, k| h[k] = [] }
      items.each { |i| uniprot2seqids[i[:uniprot_entry_id]] << i[rel_name] }

      UniprotEntry.where(id: uniprot2seqids.keys).select(:id, :taxon_id).each do |entry|
        uniprot2seqids[entry[:id]].each do |seqid|
          sequence = seqid2seq[seqid]
          lookup[entry[:taxon_id]] << sequence<commit_msg>Fix linter errors<commit_after>require 'octokit'

class Api::ApiController < ApplicationController
  respond_to :json

  before_action :set_headers, only: %i[pept2taxa pept2lca pept2prot pept2funct pept2ec pept2go pept2interpro peptinfo taxa2lca taxonomy taxa2tree]
  before_action :set_params, only: %i[pept2taxa pept2lca pept2prot pept2funct pept2ec pept2go pept2interpro peptinfo taxa2lca taxonomy taxa2tree]
  before_action :set_query, only: %i[pept2taxa pept2lca peptinfo taxonomy]
  before_action :set_sequences, only: %i[pept2prot]

  before_action :log, only: %i[pept2taxa pept2lca pept2prot pept2funct pept2ec pept2go pept2interpro peptinfo taxa2lca taxonomy taxa2tree]

  # sends a message to the ruby cli
  def messages
    version = params[:version]
    gem_version = Rails.application.config.versions[:gem]
    if Gem::Version.new(gem_version) > Gem::Version.new(version)
      render plain: "Unipept gem #{gem_version} is released!. Run 'gem update unipept' to update."
    else
      render plain: ''
    end
  end

  # Returns a list of Uniprot entries containing a given tryptic peptide
  # params[:input]: Array, required, List of input peptides
  # params[:equate_il]: "true" or "false" (default), optional, Equate I and L?
  # params[:extra]: "true" or "false" (default), optional, Output extra info?
  def pept2prot
    lookup = Hash.new { |h, k| h[k] = Set.new }
    if @extra_info
      @result = {}
      # Perform joins and load objects (expensive)
      ids = []
      @sequences.pluck(:sequence, 'uniprot_entries.id').each do |sequence, uniprot_id|
        ids.append uniprot_id
        lookup[uniprot_id] << sequence
        @result[sequence] = Set.new
      end

      ids = ids.uniq.compact.sort
      UniprotEntry.includes(:taxon, :ec_cross_references, :go_cross_references, :refseq_cross_references, :embl_cross_references)
                  .where(id: ids).find_in_batches do |group|
        group.each do |uni|
          lookup[uni.id].each { |s| @result[s] << uni }
        end
      end
    else
      @result = Hash.new { |h, k| h[k] = Set.new }
      @sequences.pluck(:sequence, 'uniprot_entries.uniprot_accession_number', 'uniprot_entries.name', 'uniprot_entries.taxon_id').each do |sequence, uniprot_id, protein_name, taxon_id|
        @result[sequence] << [uniprot_id, protein_name, taxon_id]
      end
    end

    filter_input_order

    respond_with(@result)
  end

  # Returns a list of taxa retrieved from the Uniprot entries containing a given tryptic peptide
  # param[input]: Array, required, List of input peptides
  # param[equate_il]: "true" or "false", Indicate if you want to equate I and L
  # param[extra]: "true" or "false", Include lineage
  # param[names]: "true" or "false", Include the lineage names
  def pept2taxa
    @result = {}
    lookup = Hash.new { |h, k| h[k] = Set.new }
    ids = Set.new

    seqid2seq = {}
    Sequence.where(sequence: @input).select(:id, :sequence).each do |seq|
      seqid2seq[seq[:id]] = seq[:sequence]
      @result[seq[:sequence]] = Set.new
    end

    rel_name = @equate_il ? :sequence_id : :original_sequence_id
    Peptide.where(rel_name => seqid2seq.keys).select(:id, rel_name, :uniprot_entry_id).find_in_batches do |items|
      uniprot2seqids = Hash.new { |h, k| h[k] = [] }
      items.each { |i| uniprot2seqids[i[:uniprot_entry_id]] << i[rel_name] }

      UniprotEntry.where(id: uniprot2seqids.keys).select(:id, :taxon_id).each do |entry|
        uniprot2seqids[entry[:id]].each do |seqid|
          sequence = seqid2seq[seqid]
          lookup[entry[:taxon_id]] << sequence
{'fraction_non_alphanumeric': 0.11379502932141859, 'fraction_numerical': 0.01117006422786931, 'mean_word_length': 3.7187088274044795, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, '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': '7572668', 'n_tokens_mistral': 2570, 'n_tokens_neox': 2433, 'n_words': 618}