<commit_before>class SpellingAnalysisWorker
  attr_reader :resource

  LANG = I18n.locale.to_s # es
  SUGGESTIONS = 3

  def initialize(resource)
    @resource = resource
  end

  def run!
    attributes_to_analyse.each do |attribute|
      text = resource.send(attribute)
      if text.present?
        resource.spellcheck_analyses.create!(
          attr_name: attribute,
          words: formatted_mispelled_words_for(text)
        )
      end
    end
  end

  private

  ##
  # we'll only analyse attributes that
  # have changed
  def attributes_to_analyse
    resource.send(:spellcheck_attributes) - resource.spellcheck_analyses.pluck(:attr_name)
  end

  ##
  # store a limited ammount of suggestions
  # and discard :correct property
  def formatted_mispelled_words_for(text)
    mispelled_words_for(text).map do |word|
      {
        original: word[:original],
        suggestions: word[:suggestions].sample(SUGGESTIONS) # or .first(3)
      }
    end
  end

  ##
  # call spellchecker and reject correct
  # words
  def mispelled_words_for(text)
    Spellchecker.check(text, LANG).reject do |word|
      word[:correct]
    end
  end

  class << self
    def perform!(id)
      new(Content.find(id)).run!
    end
  end
end<commit_msg>rescue from schedule analysis when spellcheck is not present<commit_after>class SpellingAnalysisWorker
  attr_reader :resource

  LANG = I18n.locale.to_s # es
  SUGGESTIONS = 3

  def initialize(resource)
    @resource = resource
  end

  def run!
    attributes_to_analyse.each do |attribute|
      text = resource.send(attribute)
      create_analysis!(attribute, text) if text.present?
    end
  end

  private

  ##
  # creates spellcheck analysis only if
  # there's mispelled words
  def create_analysis!(attribute, text)
    words = formatted_mispelled_words_for(text)
    resource.spellcheck_analyses.create!(
      attr_name: attribute,
      words: words
    ) if words.any?
  end

  ##
  # we'll only analyse attributes that
  # have changed
  def attributes_to_analyse
    resource.send(:spellcheck_attributes) - resource.spellcheck_analyses.pluck(:attr_name)
  end

  ##
  # store a limited ammount of suggestions
  # and discard :correct property
  def formatted_mispelled_words_for(text)
    mispelled_words_for(text).map do |word|
      {
        original: word[:original],
        suggestions: word[:suggestions].sample(SUGGESTIONS) # or .first(3)
      }
    end
  end

  ##
  # call spellchecker and reject correct
  # words
  def mispelled_words_for(text)
    Spellchecker.check(text, LANG).reject do |word|
      word[:correct]
    end
  rescue RuntimeError => e
    if e.message == "Aspell command not found"
      # aspell is not present. gracefully fallback
      []
    else
      raise e
    end
  end

  class << self
    def perform!(id)
      new(Content.find(id)).run!
    end
  end
end
{'fraction_non_alphanumeric': 0.08356643356643356, 'fraction_numerical': 0.002797202797202797, 'mean_word_length': 2.9791376912378302, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 4, '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': '3817836', 'n_tokens_mistral': 938, 'n_tokens_neox': 894, 'n_words': 223}