<commit_before># TODO improve naming. Attribute keys? Hash keys?
# Senior Men Pro 1/2 | Field size: 79 riders | Laps: 2 
class ResultsFile < GridFile

  attr_accessor :invalid_columns

  COLUMN_MAP = {
    "placing" => "place",
    "#" => "number",
    "wsba#" => "number",
    "rider_#" => "number",
    "bib #" => "number",
    "age_group" => "ages", #this is expected to be a range, like 10-18
    "age group" => "ages",
    "age" => "ages",
    "barcategory" => "parent",
    "bar_category" => "parent",
    "category.name" => "category_name",
    "categories" => "category_name",
    "category" => "category_name",
    "cat." => "category_name",
    "class" => "category_class",  #this is like A for Masters A
    "first" => "first_name",
    "firstname" => "first_name",
    "first name" => "first_name",
    "racer.first_name" => "first_name",
    "racer" => "name",
    "last" => "last_name",
    "lastname" => "last_name",
    "last name" => "last_name",
    "racer.last_name" => "last_name",
    "team" => "team_name",
    "team.name" => "team_name",
    "team name" => "team_name",
    "club/team" => "team_name",
    "obra_number" => "number",
    "oregoncup" => "oregon_cup",
    "membership #" => "license",
    "license #" => "license",
    "membership" => "license",
    "hometown" => 'city',
    "stage_time" => "time",
    "st" => "time",
    "stop time" => "time",
    "bonus" => "time_bonus_penalty",
    "penalty" => "time_bonus_penalty",
    "stage_+_penalty" => "time_total",
    "time" => "time",
    "time_total" => "time_total",
    "total_time" => "time_total",
    "down" => "time_gap_to_leader",
    "gap" => "time_gap_to_leader",
    "pts" => "points",
    "bonus points" => "points_bonus",
    "penalty points" => "points_penalty"
  }

  def initialize(source, event, *options)
    @invalid_columns = []
    @event = event
    
    if options.empty?
      options = Hash.new
    else
      options = options.first
    end
    
    options = {
      :header_row => true, 
      :column_map => COLUMN_MAP, 
      :row_class => Result
    }.merge(options)
    
    super(source, options)
    RACING_ON_RAILS_DEFAULT_LOGGER.debug("columns: #{@columns.inspect}") if RACING_ON_RAILS_DEFAULT_LOGGER.debug?
    delete_blank_rows
  end
  
  def after_columns_created
    if !columns.empty? and columns.first.name.blank?
      columns.first.name = 'place'
      columns.first.field = :place
    end
  end

  def import
    RACING_ON_RAILS_DEFAULT_LOGGER.info("import results")
    standings = nil
    
    begin
      @event.disable_notification!
      standings = Standings.create!(
        :event => @event,
        :name => (@event.full_name)
      )
      
      result_columns = columns.collect do |column|
        # Remove invalid columns
        column.field.to_s unless column.field.nil?
      end
      
      result_columns.delete_if do |column|
        column.blank?
      end
      
      category = nil
      race = nil
      previous_place = nil
      previous_time = nil
      
      rows.each_with_index do |row, index|
        continue if row.blank?
        RAILS_DEFAULT_LOGGER.debug(row.inspect) if RAILS_DEFAULT_LOGGER.debug?
        row_hash = row.to_hash
        RACING_ON_RAILS_DEFAULT_LOGGER.debug("import #{row_hash.inspect}") if RACING_ON_RAILS_DEFAULT_LOGGER.debug? 
        
        if new_race?(row_hash, index)
          category = new_category(row_hash)
          race = standings.races.create(:category => category, :notes => to_notes(row))
          race.result_columns = result_columns
          if race.result_columns.include?('name')
            name_index = race.result_columns.index('name')
            race.result_columns[name_index] = 'first_name'
            race.result_columns.insert(name_index + 1, 'last_name')
          end
          
          if race.result_columns.include?('place') and race.result_columns.first != 'place'
            race.result_columns.delete('place')
            race.result_columns.insert(0, 'place')
          end
          
          race.save!
          RACING_ON_RAILS_DEFAULT_LOGGER.info("ResultsFile import race #{category}")<commit_msg>Fix notes when creating new race in standing<commit_after># TODO improve naming. Attribute keys? Hash keys?
# Senior Men Pro 1/2 | Field size: 79 riders | Laps: 2 
class ResultsFile < GridFile

  attr_accessor :invalid_columns

  COLUMN_MAP = {
    "placing" => "place",
    "#" => "number",
    "wsba#" => "number",
    "rider_#" => "number",
    "bib #" => "number",
    "age_group" => "ages", #this is expected to be a range, like 10-18
    "age group" => "ages",
    "age" => "ages",
    "barcategory" => "parent",
    "bar_category" => "parent",
    "category.name" => "category_name",
    "categories" => "category_name",
    "category" => "category_name",
    "cat." => "category_name",
    "class" => "category_class",  #this is like A for Masters A
    "first" => "first_name",
    "firstname" => "first_name",
    "first name" => "first_name",
    "racer.first_name" => "first_name",
    "racer" => "name",
    "last" => "last_name",
    "lastname" => "last_name",
    "last name" => "last_name",
    "racer.last_name" => "last_name",
    "team" => "team_name",
    "team.name" => "team_name",
    "team name" => "team_name",
    "club/team" => "team_name",
    "obra_number" => "number",
    "oregoncup" => "oregon_cup",
    "membership #" => "license",
    "license #" => "license",
    "membership" => "license",
    "hometown" => 'city',
    "stage_time" => "time",
    "st" => "time",
    "stop time" => "time",
    "bonus" => "time_bonus_penalty",
    "penalty" => "time_bonus_penalty",
    "stage_+_penalty" => "time_total",
    "time" => "time",
    "time_total" => "time_total",
    "total_time" => "time_total",
    "down" => "time_gap_to_leader",
    "gap" => "time_gap_to_leader",
    "pts" => "points",
    "bonus points" => "points_bonus",
    "penalty points" => "points_penalty"
  }

  def initialize(source, event, *options)
    @invalid_columns = []
    @event = event
    
    if options.empty?
      options = Hash.new
    else
      options = options.first
    end
    
    options = {
      :header_row => true, 
      :column_map => COLUMN_MAP, 
      :row_class => Result
    }.merge(options)
    
    super(source, options)
    RACING_ON_RAILS_DEFAULT_LOGGER.debug("columns: #{@columns.inspect}") if RACING_ON_RAILS_DEFAULT_LOGGER.debug?
    delete_blank_rows
  end
  
  def after_columns_created
    if !columns.empty? and columns.first.name.blank?
      columns.first.name = 'place'
      columns.first.field = :place
    end
  end

  def import
    RACING_ON_RAILS_DEFAULT_LOGGER.info("import results")
    standings = nil
    
    begin
      @event.disable_notification!
      standings = Standings.create!(
        :event => @event,
        :name => (@event.full_name)
      )
      
      result_columns = columns.collect do |column|
        # Remove invalid columns
        column.field.to_s unless column.field.nil?
      end
      
      result_columns.delete_if do |column|
        column.blank?
      end
      
      category = nil
      race = nil
      previous_place = nil
      previous_time = nil
      
      rows.each_with_index do |row, index|
        continue if row.blank?
        RAILS_DEFAULT_LOGGER.debug(row.inspect) if RAILS_DEFAULT_LOGGER.debug?
        row_hash = row.to_hash
        RACING_ON_RAILS_DEFAULT_LOGGER.debug("import #{row_hash.inspect}") if RACING_ON_RAILS_DEFAULT_LOGGER.debug? 
        
        if new_race?(row_hash, index)
          category = new_category(row_hash)
          race = standings.races.create(:category => category)
          race.result_columns = result_columns
          if race.result_columns.include?('name')
            name_index = race.result_columns.index('name')
            race.result_columns[name_index] = 'first_name'
            race.result_columns.insert(name_index + 1, 'last_name')
          end
          
          if race.result_columns.include?('place') and race.result_columns.first != 'place'
            race.result_columns.delete('place')
            race.result_columns.insert(0, 'place')
          end
          
          race.save!
          RACING_ON_RAILS_DEFAULT_LOGGER.info("ResultsFile import race #{category}")
{'fraction_non_alphanumeric': 0.14258095698405027, 'fraction_numerical': 0.0026582890285161915, 'mean_word_length': 2.6446499339498017, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 112, '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': '6772012', 'n_tokens_mistral': 2825, 'n_tokens_neox': 2782, 'n_words': 554}