<commit_before># This is a special kind of Agent (the relationship is mandatory; q.v.).  A ContentPartner is akin to a User, in that they can log
# in (see ContentPartnerController).  Of course, content partners are those people or organizations who add data to our database.
class ContentPartner < SpeciesSchemaModel

  belongs_to :agent

  unless defined? STEPS
    STEPS = [:partner, :contacts, :licensing, :attribution, :roles, :transfer_overview, :transfer_upload, :specialist_overview, :specialist_formatting] 
    STEPS.each { |s| define_method("#{s}_step?") { self.step.to_s == s.to_s }}
  end

  attr_reader :step

  # Alias some partner fields so we can use validation helpers
  alias_attribute :project_description, :description
  
  validate :validate_atleast_one_contact, :if => :contacts_step?
  # REMOVE VALIDATION FOR THESE STEPS TO ALLOW PEOPLE TO 'UNACCEPT', <NAME>, Sep 12, 2008
  #validate :validate_ipr_acceptance, :if => :licensing_step?  
  #validate :validate_attribution_acceptance, :if => :attribution_step?
  #validate :validate_roles_acceptance, :if => :roles_step?

  # Callbacks
  before_save :blank_not_null_fields
  
  def self.find_by_full_name(full_name)
    content_partners = ContentPartner.find_by_sql([%Q{
        SELECT cp.*
        FROM agents a
        JOIN content_partners cp ON (a.id=cp.agent_id)
        WHERE a.full_name=? }, full_name])
    
    return nil if content_partners.nil?
    content_partners[0]
  end
  
  def self.find_harvested_by_full_name(full_name)
    content_partners = ContentPartner.find_by_sql([%Q{
        SELECT cp.*
        FROM agents a
        JOIN content_partners cp ON (a.id=cp.agent_id)
        JOIN agents_resources ar ON (a.id=ar.agent_id)
        JOIN resources r ON (ar.resource_id=r.id)
        JOIN harvest_events he ON (r.id=he.resource_id)
        WHERE a.full_name=? }, full_name])
    
    return nil if content_partners.nil?
    content_partners[0]
  end
  
  def concepts_for_gallery(page, per_page)
    page = page - 1
    partner_resources = Resource.find_by_sql(%Q{
        SELECT
        r.*
        FROM agents_resources ar
        JOIN resources r ON (ar.resource_id=r.id)
        WHERE ar.agent_id=#{agent_id}
        AND ar.resource_agent_role_id=#{ResourceAgentRole.content_partner_upload_role.id}})
    
    return nil if partner_resources.nil?
    harvest_event_ids = partner_resources.collect{|r| r.latest_published_harvest_event.id || nil }
    return nil if harvest_event_ids.empty?
    
    count_result = SpeciesSchemaModel.connection.execute(%Q{
        SELECT count(distinct hierarchy_entry_id) count
        FROM data_objects_harvest_events dohevt
        JOIN data_objects_hierarchy_entries dohe ON (dohevt.data_object_id=dohe.data_object_id)
        JOIN hierarchy_entries he ON (dohe.hierarchy_entry_id=he.id)
        WHERE dohevt.harvest_event_id IN (#{harvest_event_ids.join(',')})}).all_hashes
    total_taxa_count = count_result[0]['count'].to_i
    
    sorted_hierarchy_entries = SpeciesSchemaModel.connection.execute("
        SELECT he.id hierarchy_entry_id, he.source_url, n.string scientific_name
        FROM data_objects_harvest_events dohevt
        JOIN data_objects_hierarchy_entries dohe ON (dohevt.data_object_id=dohe.data_object_id)
        JOIN hierarchy_entries he ON (dohe.hierarchy_entry_id=he.id)
        JOIN names n on (he.name_id=n.id)
        WHERE dohevt.harvest_event_id IN (#{harvest_event_ids.join(',')})
        GROUP BY he.id
        ORDER BY dohevt.data_object_id DESC
        LIMIT #{page*per_page}, #{per_page}").all_hashes
    
    start_index = page * per_page
    end_index = start_index + per_page
    
    all_concepts = []
    for i in 0...total_taxa_count
      all_concepts[i] = {}
      if i >= start_index && i < end_index 
        
        entry = sorted_hierarchy_entries[i-start_index]
        name_and_image = SpeciesSchemaModel.connection.execute("SELECT he.taxon_concept_id, n.string, do.object_cache_url
          FROM hierarchy_entries he<commit_msg>Improved speed of content partner galleries for #1639<commit_after># This is a special kind of Agent (the relationship is mandatory; q.v.).  A ContentPartner is akin to a User, in that they can log
# in (see ContentPartnerController).  Of course, content partners are those people or organizations who add data to our database.
class ContentPartner < SpeciesSchemaModel

  belongs_to :agent

  unless defined? STEPS
    STEPS = [:partner, :contacts, :licensing, :attribution, :roles, :transfer_overview, :transfer_upload, :specialist_overview, :specialist_formatting] 
    STEPS.each { |s| define_method("#{s}_step?") { self.step.to_s == s.to_s }}
  end

  attr_reader :step

  # Alias some partner fields so we can use validation helpers
  alias_attribute :project_description, :description
  
  validate :validate_atleast_one_contact, :if => :contacts_step?
  # REMOVE VALIDATION FOR THESE STEPS TO ALLOW PEOPLE TO 'UNACCEPT', <NAME>, Sep 12, 2008
  #validate :validate_ipr_acceptance, :if => :licensing_step?  
  #validate :validate_attribution_acceptance, :if => :attribution_step?
  #validate :validate_roles_acceptance, :if => :roles_step?

  # Callbacks
  before_save :blank_not_null_fields
  
  def self.find_by_full_name(full_name)
    content_partners = ContentPartner.find_by_sql([%Q{
        SELECT cp.*
        FROM agents a
        JOIN content_partners cp ON (a.id=cp.agent_id)
        WHERE a.full_name=? }, full_name])
    
    return nil if content_partners.nil?
    content_partners[0]
  end
  
  def self.find_harvested_by_full_name(full_name)
    content_partners = ContentPartner.find_by_sql([%Q{
        SELECT cp.*
        FROM agents a
        JOIN content_partners cp ON (a.id=cp.agent_id)
        JOIN agents_resources ar ON (a.id=ar.agent_id)
        JOIN resources r ON (ar.resource_id=r.id)
        JOIN harvest_events he ON (r.id=he.resource_id)
        WHERE a.full_name=? }, full_name])
    
    return nil if content_partners.nil?
    content_partners[0]
  end
  
  def concepts_for_gallery(page, per_page)
    page = page - 1
    partner_resources = Resource.find_by_sql(%Q{
        SELECT
        r.*
        FROM agents_resources ar
        JOIN resources r ON (ar.resource_id=r.id)
        WHERE ar.agent_id=#{agent_id}
        AND ar.resource_agent_role_id=#{ResourceAgentRole.content_partner_upload_role.id}})
    
    return nil if partner_resources.nil?
    harvest_event_ids = partner_resources.collect{|r| r.latest_published_harvest_event.id || nil }
    return nil if harvest_event_ids.empty?
    
    all_hierarchy_entry_ids = SpeciesSchemaModel.connection.select_values(%Q{
        SELECT hierarchy_entry_id
        FROM harvest_events_hierarchy_entries hehe
        WHERE hehe.harvest_event_id IN (#{harvest_event_ids.join(',')})}).uniq.reverse
    total_taxa_count = all_hierarchy_entry_ids.length
    
    start_index = page*per_page
    end_index = start_index + per_page
    sorted_hierarchy_entries = SpeciesSchemaModel.connection.execute("
        SELECT he.id hierarchy_entry_id, he.source_url, n.string scientific_name
        FROM hierarchy_entries he
        JOIN names n on (he.name_id=n.id)
        WHERE he.id IN (#{all_hierarchy_entry_ids[start_index...end_index].join(',')})").all_hashes
    
    start_index = page * per_page
    end_index = start_index + per_page
    
    all_concepts = []
    for i in 0...total_taxa_count
      all_concepts[i] = {}
      if i >= start_index && i < end_index 
        
        entry = sorted_hierarchy_entries[i-start_index]
        name_and_image = SpeciesSchemaModel.connection.execute("SELECT he.taxon_concept_id, n.string, do.object_cache_url
          FROM hierarchy_entries he
{'fraction_non_alphanumeric': 0.08612626656274357, 'fraction_numerical': 0.003247596778383996, 'mean_word_length': 3.5128956623681127, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 15, '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': '1527966', 'n_tokens_mistral': 2586, 'n_tokens_neox': 2514, 'n_words': 583}