<commit_before>class Version < ActiveRecord::Base
  belongs_to :rubygem
  has_many :dependencies, :dependent => :destroy

  scope :owned_by, lambda { |user|
    where(:rubygem_id => user.rubygem_ids)
  }

  scope :subscribed_to_by, lambda { |user|
    where(:rubygem_id => user.subscribed_gem_ids).
    order('created_at desc')
  }

  scope :with_associated,
    where("versions.rubygem_id IN (SELECT versions.rubygem_id FROM versions GROUP BY versions.rubygem_id HAVING COUNT(versions.id) > 1)").
    includes(:rubygem).
    order("versions.built_at desc")

  scope :by_position, order('position')
  scope :with_deps,   includes(:dependencies)
  scope :latest,      where(:latest       => true     )
  scope :prerelease,  where(:prerelease   => true     )
  scope :release,     where(:prerelease   => false    )
  scope :indexed,     where(:indexed      => true     )

  before_save      :update_prerelease
  after_validation :join_authors
  after_create     :full_nameify!
  after_save       :reorder_versions

  validates_format_of :number, :with => /\A#{Gem::Version::VERSION_PATTERN}\z/
  validate :platform_and_number_are_unique, :on => :create
  validate :authors_format, :on => :create

  def platform_and_number_are_unique
    if Version.exists?(:rubygem_id => rubygem_id,
                       :number     => number,
                       :platform   => platform)
      errors[:base] << "A version already exists with this number or platform."
    end
  end

  def authors_format
    if !authors.is_a?(Array) || authors.any? { |a| !a.is_a?(String) }
      errors.add :authors, "must be an Array of Strings"
    end
  end

  def join_authors
    self.authors = self.authors.join(', ') if self.authors.is_a?(Array)
  end

  def self.with_indexed(reverse = false)
    order_str =  "rubygems.name asc"
    order_str << ", position desc" if reverse

    where(:indexed => true).includes(:rubygem).order(order_str)
  end

  def self.most_recent
    recent = where(:latest => true)
    recent.find_by_platform('ruby') || recent.first || first
  end

  def self.updated(limit=5)
    where("built_at <= ?", DateTime.now.utc).with_associated.limit(limit)
  end

  def self.published(limit=5)
    where("built_at <= ?", DateTime.now.utc).order("built_at desc").limit(limit)
  end

  def self.find_from_slug!(rubygem_id, slug)
    rubygem = Rubygem.find(rubygem_id)
    find_by_full_name!("#{rubygem.name}-#{slug}")
  end

  def self.platforms
    select('platform').map(&:platform).uniq
  end

  def self.rubygem_name_for(full_name)
    $redis.hget(info_key(full_name), :name)
  end

  def self.info_key(full_name)
    "v:#{full_name}"
  end

  def platformed?
    platform != "ruby"
  end

  def update_prerelease
    self[:prerelease] = to_gem_version.prerelease?
    true
  end

  def reorder_versions
    rubygem.reorder_versions
  end

  def yank!
    update_attributes!(:indexed => false)
    $redis.lrem(Rubygem.versions_key(rubygem.name), 1, full_name)
  end

  def unyank!<commit_msg>Gem::Version#prerelease? in 1.4 likes returning nil, double bang it back to true/false<commit_after>class Version < ActiveRecord::Base
  belongs_to :rubygem
  has_many :dependencies, :dependent => :destroy

  scope :owned_by, lambda { |user|
    where(:rubygem_id => user.rubygem_ids)
  }

  scope :subscribed_to_by, lambda { |user|
    where(:rubygem_id => user.subscribed_gem_ids).
    order('created_at desc')
  }

  scope :with_associated,
    where("versions.rubygem_id IN (SELECT versions.rubygem_id FROM versions GROUP BY versions.rubygem_id HAVING COUNT(versions.id) > 1)").
    includes(:rubygem).
    order("versions.built_at desc")

  scope :by_position, order('position')
  scope :with_deps,   includes(:dependencies)
  scope :latest,      where(:latest       => true     )
  scope :prerelease,  where(:prerelease   => true     )
  scope :release,     where(:prerelease   => false    )
  scope :indexed,     where(:indexed      => true     )

  before_save      :update_prerelease
  after_validation :join_authors
  after_create     :full_nameify!
  after_save       :reorder_versions

  validates_format_of :number, :with => /\A#{Gem::Version::VERSION_PATTERN}\z/
  validate :platform_and_number_are_unique, :on => :create
  validate :authors_format, :on => :create

  def platform_and_number_are_unique
    if Version.exists?(:rubygem_id => rubygem_id,
                       :number     => number,
                       :platform   => platform)
      errors[:base] << "A version already exists with this number or platform."
    end
  end

  def authors_format
    if !authors.is_a?(Array) || authors.any? { |a| !a.is_a?(String) }
      errors.add :authors, "must be an Array of Strings"
    end
  end

  def join_authors
    self.authors = self.authors.join(', ') if self.authors.is_a?(Array)
  end

  def self.with_indexed(reverse = false)
    order_str =  "rubygems.name asc"
    order_str << ", position desc" if reverse

    where(:indexed => true).includes(:rubygem).order(order_str)
  end

  def self.most_recent
    recent = where(:latest => true)
    recent.find_by_platform('ruby') || recent.first || first
  end

  def self.updated(limit=5)
    where("built_at <= ?", DateTime.now.utc).with_associated.limit(limit)
  end

  def self.published(limit=5)
    where("built_at <= ?", DateTime.now.utc).order("built_at desc").limit(limit)
  end

  def self.find_from_slug!(rubygem_id, slug)
    rubygem = Rubygem.find(rubygem_id)
    find_by_full_name!("#{rubygem.name}-#{slug}")
  end

  def self.platforms
    select('platform').map(&:platform).uniq
  end

  def self.rubygem_name_for(full_name)
    $redis.hget(info_key(full_name), :name)
  end

  def self.info_key(full_name)
    "v:#{full_name}"
  end

  def platformed?
    platform != "ruby"
  end

  def update_prerelease
    self[:prerelease] = !!to_gem_version.prerelease?
    true
  end

  def reorder_versions
    rubygem.reorder_versions
  end

  def yank!
    update_attributes!(:indexed => false)
    $redis.lrem(Rubygem.versions_key(rubygem.name), 1, full_name)
  end

  def unyank!
{'fraction_non_alphanumeric': 0.12155698499092858, 'fraction_numerical': 0.0016493485073396008, 'mean_word_length': 3.4457478005865103, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 37, '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': '5408992', 'n_tokens_mistral': 2158, 'n_tokens_neox': 2060, 'n_words': 422}