<commit_before>class Submission < ActiveRecord::Base
  include Named

  belongs_to :user
  belongs_to :user_exercise
  has_many :comments, ->{ order 'created_at ASC' }, dependent: :destroy

  # I don't really want the notifications method,
  # just the dependent destroy
  has_many :notifications, ->{ where(item_type: 'Submission') }, dependent: :destroy, foreign_key: 'item_id', class_name: 'Notification'

  has_many :submission_viewers, dependent: :destroy
  has_many :viewers, through: :submission_viewers

  has_many :muted_submissions, dependent: :destroy
  has_many :muted_by, through: :muted_submissions, source: :user

  has_many :likes, dependent: :destroy
  has_many :liked_by, through: :likes, source: :user

  validates_presence_of :user

  before_create do
    self.state          ||= "pending"
    self.nit_count      ||= 0
    self.version        ||= 0
    self.is_liked       ||= false
    self.key            ||= generate_key
    true
  end


  scope :done, ->{ where(state: 'done') }
  scope :pending, ->{ where(state: %w(needs_input pending)) }
  scope :hibernating, ->{ where(state: 'hibernating') }
  scope :needs_input, ->{ where(state: 'needs_input') }
  scope :aging, lambda {
    three_weeks_ago = Time.now - (60*60*24*7*3)
    cutoff = three_weeks_ago.strftime('%Y-%m-%d %H:%M:%S')
    pending.where('nit_count > 0').where('created_at < ?', cutoff)
  }
  scope :chronologically, -> { order('created_at ASC') }
  scope :reversed, -> { order('created_at DESC') }
  scope :not_commented_on_by, ->(user) {
    joins("LEFT JOIN (SELECT submission_id FROM comments WHERE user_id=#{user.id}) AS already_commented ON submissions.id=already_commented.submission_id").
    where('already_commented.submission_id IS NULL')
  }
  scope :not_liked_by, ->(user) {
    joins("LEFT JOIN (SELECT submission_id FROM likes WHERE user_id=#{user.id}) AS already_liked ON submissions.id=already_liked.submission_id").
    where('already_liked.submission_id IS NULL')
  }

  scope :between, ->(upper_bound, lower_bound) {
    where('created_at < ? AND created_at > ?', upper_bound, lower_bound)
  }

  scope :older_than, ->(timestamp) {
    where('created_at < ?', timestamp)
  }

  scope :since, ->(timestamp) {
    where('created_at > ?', timestamp)
  }

  def self.completed_for(problem)
    done.where(language: problem.track_id, slug: problem.slug)
  end

  def self.random_completed_for(problem)
    where(
      state: 'done',
      language: problem.track_id,<commit_msg>Add a scope for filtering submissions by language<commit_after>class Submission < ActiveRecord::Base
  include Named

  belongs_to :user
  belongs_to :user_exercise
  has_many :comments, ->{ order 'created_at ASC' }, dependent: :destroy

  # I don't really want the notifications method,
  # just the dependent destroy
  has_many :notifications, ->{ where(item_type: 'Submission') }, dependent: :destroy, foreign_key: 'item_id', class_name: 'Notification'

  has_many :submission_viewers, dependent: :destroy
  has_many :viewers, through: :submission_viewers

  has_many :muted_submissions, dependent: :destroy
  has_many :muted_by, through: :muted_submissions, source: :user

  has_many :likes, dependent: :destroy
  has_many :liked_by, through: :likes, source: :user

  validates_presence_of :user

  before_create do
    self.state          ||= "pending"
    self.nit_count      ||= 0
    self.version        ||= 0
    self.is_liked       ||= false
    self.key            ||= generate_key
    true
  end


  scope :done, ->{ where(state: 'done') }
  scope :pending, ->{ where(state: %w(needs_input pending)) }
  scope :hibernating, ->{ where(state: 'hibernating') }
  scope :needs_input, ->{ where(state: 'needs_input') }
  scope :aging, lambda {
    three_weeks_ago = Time.now - (60*60*24*7*3)
    cutoff = three_weeks_ago.strftime('%Y-%m-%d %H:%M:%S')
    pending.where('nit_count > 0').where('created_at < ?', cutoff)
  }
  scope :chronologically, -> { order('created_at ASC') }
  scope :reversed, -> { order('created_at DESC') }
  scope :not_commented_on_by, ->(user) {
    joins("LEFT JOIN (SELECT submission_id FROM comments WHERE user_id=#{user.id}) AS already_commented ON submissions.id=already_commented.submission_id").
    where('already_commented.submission_id IS NULL')
  }
  scope :not_liked_by, ->(user) {
    joins("LEFT JOIN (SELECT submission_id FROM likes WHERE user_id=#{user.id}) AS already_liked ON submissions.id=already_liked.submission_id").
    where('already_liked.submission_id IS NULL')
  }

  scope :between, ->(upper_bound, lower_bound) {
    where('created_at < ? AND created_at > ?', upper_bound, lower_bound)
  }

  scope :older_than, ->(timestamp) {
    where('created_at < ?', timestamp)
  }

  scope :since, ->(timestamp) {
    where('created_at > ?', timestamp)
  }

  scope :for_language, ->(language) {
    where(language: language)
  }

  def self.completed_for(problem)
    done.where(language: problem.track_id, slug: problem.slug)
  end

  def self.random_completed_for(problem)
    where(
      state: 'done',
      language: problem.track_id,
{'fraction_non_alphanumeric': 0.13334646444750836, 'fraction_numerical': 0.004333267677762458, 'mean_word_length': 4.062811565304088, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 36, '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': '2820500', 'n_tokens_mistral': 1787, 'n_tokens_neox': 1677, 'n_words': 385}