<commit_before>class Batch < ActiveRecord::Base
  belongs_to :batch_type
  belongs_to :server
  belongs_to :status
  has_many :packages, dependent: :destroy
  attr_accessible :batch_type_id, :dark_archive, :discussion_link, :name, :oral_history, :reprocessing, :server_id, :status_id
  before_create :mark_as_started
  after_create :create_packages
  before_update :check_status
  has_paper_trail

  has_many :tasks, through: :packages

  def failures
    self.tasks.where(status_id: Status.failed.id).count
  end

  def done?
    self.packages.select {|p|
      p.done?
    }.count == self.packages.count
  end

  def notify message
    if message
      method = "when_#{message.to_s.gsub(/\s+/, '_')}".to_sym
      if respond_to? method
        logger.debug "\nDEBUG batch #{self.id}: dispatching to #{method}"
        send(method)
      else
        logger.debug "\nDEBUG batch #{self.id}: can't dispatch to #{method}"
      end
    end
  end

  def mark_reviewed
    if self.status == Status.awaiting_approval
      self.update_attributes(:status_id => Status.under_review.id)
    end

    if enough_packages_approved?
      self.update_attributes(:status_id => Status.approved.id)
    end
  end

  private

  def mark_as_started
    self.status ||= Status.started
  end

  def create_packages
    # find the right place for this
    base = '/opt/pdp/services/staging/processing'
    path = File.join(
      base,
      self.name,
      'sips'
    )
    limit = 100
    sip_paths = Dir.glob("#{path}/*")
    tickets = (1..sip_paths.count).to_a.shuffle
    sip_paths.each_with_index do |sip_path, i|
      Package.create(
        batch_id: self.id,
        sip_path: sip_path,
        oral_history: self.oral_history,
        dark_archive: self.dark_archive,
        reprocessing: self.reprocessing,
        approved: false,
        requires_approval: tickets[i] <= limit
      )
    end
  end

  def check_status
    if self.status_id_changed?
      if self.status == Status.approved
        approve_packages
      end
    end
    
    if enough_packages_approved?
      self.status = Status.approved
      approve_packages
    end
  end

  def enough_packages_approved?
    self.packages.where(
      :requires_approval => true
    ).reject { |package|
      package.status == Status.approved
    }.empty?
  end

  def approve_packages<commit_msg>require approval for all package submissions<commit_after>class Batch < ActiveRecord::Base
  belongs_to :batch_type
  belongs_to :server
  belongs_to :status
  has_many :packages, dependent: :destroy
  attr_accessible :batch_type_id, :dark_archive, :discussion_link, :name, :oral_history, :reprocessing, :server_id, :status_id
  before_create :mark_as_started
  after_create :create_packages
  before_update :check_status
  has_paper_trail

  has_many :tasks, through: :packages

  def failures
    self.tasks.where(status_id: Status.failed.id).count
  end

  def done?
    self.packages.select {|p|
      p.done?
    }.count == self.packages.count
  end

  def notify message
    if message
      method = "when_#{message.to_s.gsub(/\s+/, '_')}".to_sym
      if respond_to? method
        logger.debug "\nDEBUG batch #{self.id}: dispatching to #{method}"
        send(method)
      else
        logger.debug "\nDEBUG batch #{self.id}: can't dispatch to #{method}"
      end
    end
  end

  def mark_reviewed
    if self.status == Status.awaiting_approval
      self.update_attributes(:status_id => Status.under_review.id)
    end

    if enough_packages_approved?
      self.update_attributes(:status_id => Status.approved.id)
    end
  end

  private

  def mark_as_started
    self.status ||= Status.started
  end

  def create_packages
    # find the right place for this
    base = '/opt/pdp/services/staging/processing'
    path = File.join(
      base,
      self.name,
      'sips'
    )
    sip_paths = Dir.glob("#{path}/*")
    sip_paths.each_with_index do |sip_path, i|
      Package.create(
        batch_id: self.id,
        sip_path: sip_path,
        oral_history: self.oral_history,
        dark_archive: self.dark_archive,
        reprocessing: self.reprocessing,
        approved: false,
        requires_approval: true
      )
    end
  end

  def check_status
    if self.status_id_changed?
      if self.status == Status.approved
        approve_packages
      end
    end
    
    if enough_packages_approved?
      self.status = Status.approved
      approve_packages
    end
  end

  def enough_packages_approved?
    self.packages.where(
      :requires_approval => true
    ).reject { |package|
      package.status == Status.approved
    }.empty?
  end

  def approve_packages
{'fraction_non_alphanumeric': 0.09342783505154639, 'fraction_numerical': 0.000859106529209622, 'mean_word_length': 2.758676351896691, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 9, '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': '3666095', 'n_tokens_mistral': 1526, 'n_tokens_neox': 1476, 'n_words': 339}