<commit_before>class AssignmentExportPerformer < ResqueJob::Performer
  include ModelAddons::ImprovedLogging # log errors with attributes

  def setup
    fetch_assets
  end

  # perform() attributes assigned to @attrs in the ResqueJob::Base class
  def do_the_work
    if work_resources_present?
      require_success(generate_csv_messages, max_result_size: 250) do
        generate_export_csv
      end

      require_success(csv_export_messages) do
        export_csv_successful?
      end
    else
      if logger
        log_error_with_attributes "@assignment.present? or @students.present? failed and both should have been present, could not do_the_work"
      end
    end
  end

  # add this for logging_with_attributes
  def attributes
    { 
      assignment_id: @assignment.try(:id),
      course_id: @course.try(:id),
      professor_id: @professor.try(:id),
      student_ids: @students.collect(&:id),
      team_id: @team.try(:id)
    }
  end

  protected

  def work_resources_present?
    @assignment.present? and @students.present?
  end

  def fetch_assets
    @assignment = fetch_assignment # this should pull in submissions as well
    @course = fetch_course
    @professor = fetch_professor
    @students = fetch_students
    @team = fetch_team if team_present?
    @submissions = fetch_submissions
  end

  def team_present?
    @attrs[:team_id].present?
  end

  def tmp_dir
    @tmp_dir ||= Dir.mktmpdir
  end

  def csv_file_path
    @csv_file_path ||= File.expand_path("_grade_import_template.csv", tmp_dir)
  end

  def archive_basename
    if team_present?
      "#{formatted_assignment_name}_#{formatted_team_name}"
    else
      formatted_assignment_name
    end
  end

  # @mz todo: add specs
  def fileized_assignment_name
    @assignment.name
      .downcase
      .gsub(/[^\w\s_-]+/, '') # strip out characters besides letters and digits
      .gsub(/(^|\b\s)\s+($|\s?\b)/, '\\1\\2') # remove extra spaces
      .gsub(/\s+/, '_') # replace spaces with underscores
  end

  # @mz todo: add specs
  def sorted_student_directory_keys
    submissions_grouped_by_student.keys.sort
  end

  # @mz todo: add specs
  def export_file_basename
    @export_file_basename ||= "#{fileized_assignment_name}_export_#{Time.now.strftime("%Y-%m-%d")}"
  end

  # @mz todo: add specs
  def submissions_grouped_by_student
    @submissions_grouped_by_student ||= submissions.group_by do |submission|
      student = submission.student
      "#{student.last_name}_#{student.first_name}-#{student.id}".downcase
    end
  end

  def formatted_assignment_name
    formatted_archive_fragment(@assignment.name)
  end

  def formatted_team_name
    formatted_archive_fragment(@team.name)
  end

  def formatted_archive_fragment(fragment)
    "#{fragment.gsub(/\W+/, "_").downcase[0..19]}"
  end

  def fetch_course
    @course = @assignment.course
  end<commit_msg>fix @submissions ivar bug<commit_after>class AssignmentExportPerformer < ResqueJob::Performer
  include ModelAddons::ImprovedLogging # log errors with attributes

  def setup
    fetch_assets
  end

  # perform() attributes assigned to @attrs in the ResqueJob::Base class
  def do_the_work
    if work_resources_present?
      require_success(generate_csv_messages, max_result_size: 250) do
        generate_export_csv
      end

      require_success(csv_export_messages) do
        export_csv_successful?
      end
    else
      if logger
        log_error_with_attributes "@assignment.present? or @students.present? failed and both should have been present, could not do_the_work"
      end
    end
  end

  # add this for logging_with_attributes
  def attributes
    { 
      assignment_id: @assignment.try(:id),
      course_id: @course.try(:id),
      professor_id: @professor.try(:id),
      student_ids: @students.collect(&:id),
      team_id: @team.try(:id)
    }
  end

  protected

  def work_resources_present?
    @assignment.present? and @students.present?
  end

  def fetch_assets
    @assignment = fetch_assignment # this should pull in submissions as well
    @course = fetch_course
    @professor = fetch_professor
    @students = fetch_students
    @team = fetch_team if team_present?
    @submissions = fetch_submissions
  end

  def team_present?
    @attrs[:team_id].present?
  end

  def tmp_dir
    @tmp_dir ||= Dir.mktmpdir
  end

  def csv_file_path
    @csv_file_path ||= File.expand_path("_grade_import_template.csv", tmp_dir)
  end

  def archive_basename
    if team_present?
      "#{formatted_assignment_name}_#{formatted_team_name}"
    else
      formatted_assignment_name
    end
  end

  # @mz todo: add specs
  def fileized_assignment_name
    @assignment.name
      .downcase
      .gsub(/[^\w\s_-]+/, '') # strip out characters besides letters and digits
      .gsub(/(^|\b\s)\s+($|\s?\b)/, '\\1\\2') # remove extra spaces
      .gsub(/\s+/, '_') # replace spaces with underscores
  end

  # @mz todo: add specs
  def sorted_student_directory_keys
    submissions_grouped_by_student.keys.sort
  end

  # @mz todo: add specs
  def export_file_basename
    @export_file_basename ||= "#{fileized_assignment_name}_export_#{Time.now.strftime("%Y-%m-%d")}"
  end

  # @mz todo: add specs
  def submissions_grouped_by_student
    @submissions_grouped_by_student ||= @submissions.group_by do |submission|
      student = submission.student
      "#{student.last_name}_#{student.first_name}-#{student.id}".downcase
    end
  end

  def formatted_assignment_name
    formatted_archive_fragment(@assignment.name)
  end

  def formatted_team_name
    formatted_archive_fragment(@team.name)
  end

  def formatted_archive_fragment(fragment)
    "#{fragment.gsub(/\W+/, "_").downcase[0..19]}"
  end

  def fetch_course
    @course = @assignment.course
  end
{'fraction_non_alphanumeric': 0.09661164205039097, 'fraction_numerical': 0.002780191138140747, 'mean_word_length': 3.441358024691358, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, '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': '2358023', 'n_tokens_mistral': 1952, 'n_tokens_neox': 1880, 'n_words': 412}