<commit_before>require 'activerecord/uuid'
require 'money'
require './lib/poster_image'
require 'elasticsearch/model'

class Product < ActiveRecord::Base
  include ActiveRecord::UUID
  include Kaminari::ActiveRecordModelExtension
  include Elasticsearch::Model

  extend FriendlyId

  friendly_id :slug_candidates, use: :slugged

  belongs_to :user
  belongs_to :evaluator, class_name: 'User'
  belongs_to :main_thread, class_name: 'Discussion'

  has_many :activities
  has_many :assets
  has_many :auto_tip_contracts
  has_many :completed_missions
  has_many :contract_holders
  has_many :core_team_memberships
  has_many :core_team, -> { distinct }, :through => :core_team_memberships, :source => :user
  has_many :discussions
  has_many :event_activities, through: :events, source: :activities
  has_many :event_creators, -> { distinct }, :through => :events, :source => :user
  has_many :events, :through => :wips
  has_many :financial_accounts, class_name: 'Financial::Account'
  has_many :financial_transactions, class_name: 'Financial::Transaction'
  has_many :metrics
  has_many :milestones
  has_many :perks
  has_many :posts
  has_many :preorders, :through => :perks
  has_many :profit_reports
  has_many :rooms
  has_many :showcases
  has_many :status_messages
  has_many :stream_events
  has_many :subscribers, :through => :subscriptions, :source => :user
  has_many :subscriptions
  has_many :tasks
  has_many :team_memberships
  has_many :votes, :as => :voteable
  has_many :watchers, :through => :watchings, :source => :user
  has_many :watchings, :as => :watchable
  has_many :wip_activities, through: :wips, source: :activities
  has_many :wip_creators, -> { distinct }, :through => :wips, :source => :user
  has_many :wips
  has_many :work

  scope :featured,         -> {
    where.not(featured_on: nil).order(featured_on: :desc)
  }
  scope :approved,         -> { where(is_approved: true) }
  scope :created_in_month, ->(date) {
    where('date(products.created_at) >= ? and date(products.created_at) < ?',
      date.beginning_of_month, date.beginning_of_month + 1.month
    )
  }
  scope :created_in_week, ->(date) {
    where('date(products.created_at) >= ? and date(products.created_at) < ?',
      date.beginning_of_week, date.beginning_of_week + 1.week
    )
  }
  scope :declined,         -> { where(is_approved: false) }
  scope :greenlit,         -> { where('greenlit_at is not null') }
  scope :repos_gt,         ->(count) { where('array_length(repos,1) > ?', count) }
  scope :latest,           -> { where(flagged_at: nil).order(updated_at: :desc)}
  scope :public_products,  -> { where.not(slug: PRIVATE).where(flagged_at: nil) }
  scope :since,            ->(time) { where('created_at >= ?', time) }
  scope :tagged_with_any,  ->(tags) { where('tags && ARRAY[?]::varchar[]', tags) }
  scope :validating,       -> { where(greenlit_at: nil) }
  scope :waiting_approval, -> { where('submitted_at is not null and evaluated_at is null') }
  scope :with_repo,        ->(repo) { where('? = ANY(repos)', repo) }
  scope :with_logo,        ->{ where.not(poster: nil).where.not(poster: '') }


  validates :slug, uniqueness: { allow_nil: true }
  validates :name, presence: true,
                   length: { minimum: 2, maximum: 255 }
  validates :pitch, presence: true,
                    length: { maximum: 255 }

  # TODO This should be in a Form object (NewIdeaForm)
  validates :terms_of_service, acceptance: true

  before_validation :fill_in_generated_name, :if => :new_record?
  before_create :generate_authentication_token
  after_update -> { CreateIdeaWipWorker.perform_async self.id }, :if => :submitted_at_changed?

  after_commit -> { subscribe_owner_to_notifications }, on: :create
  after_commit -> { add_to_event_stream }, on: :create
  after_commit -> { create_auto_tips }, on: :create
  after_commit -> { Indexer.perform_async(:index, Product.to_s, self.id) }

  serialize :repos, Repo::Github

  PRIVATE = %w(asm coderwall asm-ideas)
  NON_PROFIT = %w(meta)

  class << self
    def find_by_id_or_slug!(id_or_slug)
      if id_or_slug.uuid?
        find_by!(id: id_or_slug)
      else
        find_by!(slug: id_or_slug)
      end
    end

    def unique_tags
      pluck('distinct unnest(tags)').sort_by{|t| t.downcase }
    end
  end

  def stage
    # TODO add shipping stage
    case
    when greenlit_at.nil?
      :validating
    else
      :building<commit_msg>move PRIVATE products into env var<commit_after>require 'activerecord/uuid'
require 'money'
require './lib/poster_image'
require 'elasticsearch/model'

class Product < ActiveRecord::Base
  include ActiveRecord::UUID
  include Kaminari::ActiveRecordModelExtension
  include Elasticsearch::Model

  extend FriendlyId

  friendly_id :slug_candidates, use: :slugged

  belongs_to :user
  belongs_to :evaluator, class_name: 'User'
  belongs_to :main_thread, class_name: 'Discussion'

  has_many :activities
  has_many :assets
  has_many :auto_tip_contracts
  has_many :completed_missions
  has_many :contract_holders
  has_many :core_team_memberships
  has_many :core_team, -> { distinct }, :through => :core_team_memberships, :source => :user
  has_many :discussions
  has_many :event_activities, through: :events, source: :activities
  has_many :event_creators, -> { distinct }, :through => :events, :source => :user
  has_many :events, :through => :wips
  has_many :financial_accounts, class_name: 'Financial::Account'
  has_many :financial_transactions, class_name: 'Financial::Transaction'
  has_many :metrics
  has_many :milestones
  has_many :perks
  has_many :posts
  has_many :preorders, :through => :perks
  has_many :profit_reports
  has_many :rooms
  has_many :showcases
  has_many :status_messages
  has_many :stream_events
  has_many :subscribers, :through => :subscriptions, :source => :user
  has_many :subscriptions
  has_many :tasks
  has_many :team_memberships
  has_many :votes, :as => :voteable
  has_many :watchers, :through => :watchings, :source => :user
  has_many :watchings, :as => :watchable
  has_many :wip_activities, through: :wips, source: :activities
  has_many :wip_creators, -> { distinct }, :through => :wips, :source => :user
  has_many :wips
  has_many :work

  scope :featured,         -> {
    where.not(featured_on: nil).order(featured_on: :desc)
  }
  scope :approved,         -> { where(is_approved: true) }
  scope :created_in_month, ->(date) {
    where('date(products.created_at) >= ? and date(products.created_at) < ?',
      date.beginning_of_month, date.beginning_of_month + 1.month
    )
  }
  scope :created_in_week, ->(date) {
    where('date(products.created_at) >= ? and date(products.created_at) < ?',
      date.beginning_of_week, date.beginning_of_week + 1.week
    )
  }
  scope :declined,         -> { where(is_approved: false) }
  scope :greenlit,         -> { where('greenlit_at is not null') }
  scope :repos_gt,         ->(count) { where('array_length(repos,1) > ?', count) }
  scope :latest,           -> { where(flagged_at: nil).order(updated_at: :desc)}
  scope :public_products,  -> { where.not(slug: PRIVATE).where(flagged_at: nil) }
  scope :since,            ->(time) { where('created_at >= ?', time) }
  scope :tagged_with_any,  ->(tags) { where('tags && ARRAY[?]::varchar[]', tags) }
  scope :validating,       -> { where(greenlit_at: nil) }
  scope :waiting_approval, -> { where('submitted_at is not null and evaluated_at is null') }
  scope :with_repo,        ->(repo) { where('? = ANY(repos)', repo) }
  scope :with_logo,        ->{ where.not(poster: nil).where.not(poster: '') }


  validates :slug, uniqueness: { allow_nil: true }
  validates :name, presence: true,
                   length: { minimum: 2, maximum: 255 }
  validates :pitch, presence: true,
                    length: { maximum: 255 }

  # TODO This should be in a Form object (NewIdeaForm)
  validates :terms_of_service, acceptance: true

  before_validation :fill_in_generated_name, :if => :new_record?
  before_create :generate_authentication_token
  after_update -> { CreateIdeaWipWorker.perform_async self.id }, :if => :submitted_at_changed?

  after_commit -> { subscribe_owner_to_notifications }, on: :create
  after_commit -> { add_to_event_stream }, on: :create
  after_commit -> { create_auto_tips }, on: :create
  after_commit -> { Indexer.perform_async(:index, Product.to_s, self.id) }

  serialize :repos, Repo::Github

  PRIVATE = ((ENV['PRIVATE_PRODUCTS'] || '').split(','))
  NON_PROFIT = %w(meta)

  class << self
    def find_by_id_or_slug!(id_or_slug)
      if id_or_slug.uuid?
        find_by!(id: id_or_slug)
      else
        find_by!(slug: id_or_slug)
      end
    end

    def unique_tags
      pluck('distinct unnest(tags)').sort_by{|t| t.downcase }
    end
  end

  def stage
    # TODO add shipping stage
    case
    when greenlit_at.nil?
      :validating
    else
      :building
{'fraction_non_alphanumeric': 0.12545126353790614, 'fraction_numerical': 0.002256317689530686, 'mean_word_length': 3.870879120879121, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 89, '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': '472600', 'n_tokens_mistral': 3112, 'n_tokens_neox': 3024, 'n_words': 669}