<commit_before>class SplitPDFJob < ActiveJob::Base
  include ActiveJob::Status

  queue_as MarkusConfigurator.markus_job_split_pdf_queue_name

  def self.on_complete_js
    "window.location.reload.bind(window.location)"
  end

  before_enqueue do |job|
    status.update(job_class: self.class)
  end

  def perform(exam_template, path, original_filename=nil, current_user=nil)
    m_logger = MarkusLogger.instance
    begin
      # Create directory for files whose QR code couldn't be parsed
      error_dir = File.join(exam_template.base_path, 'error')
      raw_dir = File.join(exam_template.base_path, 'raw')
      FileUtils.mkdir error_dir unless Dir.exists? error_dir
      FileUtils.mkdir raw_dir unless Dir.exists? raw_dir

      basename = File.basename path, '.pdf'
      filename = original_filename.nil? ? basename : File.basename(original_filename)
      pdf = CombinePDF.load path
      progress.total = pdf.pages.length
      partial_exams = Hash.new do |hash, key|
        hash[key] = []
      end
      num_pages_qr_scan_error = 0
      pdf.pages.each_index do |i|
        page = pdf.pages[i]
        new_page = CombinePDF.new
        new_page << page
        new_page.save File.join(raw_dir, "#{filename}-#{i}.pdf")

        # Snip out the part of the PDF that contains the QR code.
        img = Magick::Image::read(File.join(raw_dir, "#{filename}-#{i}.pdf")).first
        qr_img = img.crop 0, 10, img.columns, img.rows / 5
        qr_img.write File.join(raw_dir, "#{filename}-#{i}.png")

        # qrcode_string = ZXing.decode new_page.to_pdf
        qrcode_string = ZXing.decode qr_img.to_blob
        qrcode_regex = /(?<short_id>\w+)-(?<exam_num>\d+)-(?<page_num>\d+)/
        m = qrcode_regex.match qrcode_string
        if m.nil?
          new_page.save File.join(error_dir, "#{filename}-#{i}.pdf")
          num_pages_qr_scan_error += 1
        else
          if m[:short_id] == exam_template.name # if QR code contains corresponding exam template
            partial_exams[m[:exam_num]] << [m[:page_num].to_i, page]
            m_logger.log("#{m[:short_id]}: exam number #{m[:exam_num]}, page #{m[:page_num]}")
          else # if QR code doesn't contain corresponding exam template
            new_page.save File.join(error_dir, "#{filename}-#{i}.pdf")
            m_logger.log('QR code does not contain corresponding exam template.')
          end
        end
        progress.increment
      end
      save_pages(exam_template, partial_exams, filename)

      # creating an instance of split_pdf_log
      num_pages = pdf.pages.length
      complete_dir = File.join(exam_template.base_path, 'complete')
      incomplete_dir = File.join(exam_template.base_path, 'incomplete')
      num_groups_in_complete = get_num_groups_in_dir(complete_dir)
      num_groups_in_incomplete = get_num_groups_in_dir(incomplete_dir)
      split_pdf_log = SplitPdfLog.create(
        exam_template: exam_template,
        filename: filename,
        original_num_pages: num_pages,
        num_groups_in_complete: num_groups_in_complete,
        num_groups_in_incomplete: num_groups_in_incomplete,
        num_pages_qr_scan_error: num_pages_qr_scan_error,
        user: current_user
      )
      return split_pdf_log<commit_msg>fix error when exam template with different name is uploaded<commit_after>class SplitPDFJob < ActiveJob::Base
  include ActiveJob::Status

  queue_as MarkusConfigurator.markus_job_split_pdf_queue_name

  def self.on_complete_js
    "window.location.reload.bind(window.location)"
  end

  before_enqueue do |job|
    status.update(job_class: self.class)
  end

  def perform(exam_template, path, original_filename=nil, current_user=nil)
    m_logger = MarkusLogger.instance
    begin
      # Create directory for files whose QR code couldn't be parsed
      error_dir = File.join(exam_template.base_path, 'error')
      raw_dir = File.join(exam_template.base_path, 'raw')
      FileUtils.mkdir error_dir unless Dir.exists? error_dir
      FileUtils.mkdir raw_dir unless Dir.exists? raw_dir

      basename = File.basename path, '.pdf'
      filename = original_filename.nil? ? basename : File.basename(original_filename)
      pdf = CombinePDF.load path
      progress.total = pdf.pages.length
      partial_exams = Hash.new do |hash, key|
        hash[key] = []
      end
      num_pages_qr_scan_error = 0
      pdf.pages.each_index do |i|
        page = pdf.pages[i]
        new_page = CombinePDF.new
        new_page << page
        new_page.save File.join(raw_dir, "#{filename}-#{i}.pdf")

        # Snip out the part of the PDF that contains the QR code.
        img = Magick::Image::read(File.join(raw_dir, "#{filename}-#{i}.pdf")).first
        qr_img = img.crop 0, 10, img.columns, img.rows / 5
        qr_img.write File.join(raw_dir, "#{filename}-#{i}.png")

        # qrcode_string = ZXing.decode new_page.to_pdf
        qrcode_string = ZXing.decode qr_img.to_blob
        qrcode_regex = /(?<short_id>\w+)-(?<exam_num>\d+)-(?<page_num>\d+)/
        m = qrcode_regex.match qrcode_string
        if m.nil?
          new_page.save File.join(error_dir, "#{filename}-#{i}.pdf")
          num_pages_qr_scan_error += 1
        else
          if m[:short_id] == exam_template.assignment.short_identifier # if QR code contains corresponding exam template
            partial_exams[m[:exam_num]] << [m[:page_num].to_i, page]
            m_logger.log("#{m[:short_id]}: exam number #{m[:exam_num]}, page #{m[:page_num]}")
          else # if QR code doesn't contain corresponding exam template
            new_page.save File.join(error_dir, "#{filename}-#{i}.pdf")
            m_logger.log('QR code does not contain corresponding exam template.')
            num_pages_qr_scan_error += 1
          end
        end
        progress.increment
      end
      save_pages(exam_template, partial_exams, filename)

      # creating an instance of split_pdf_log
      num_pages = pdf.pages.length
      complete_dir = File.join(exam_template.base_path, 'complete')
      incomplete_dir = File.join(exam_template.base_path, 'incomplete')
      num_groups_in_complete = get_num_groups_in_dir(complete_dir)
      num_groups_in_incomplete = get_num_groups_in_dir(incomplete_dir)
      split_pdf_log = SplitPdfLog.create(
        exam_template: exam_template,
        filename: filename,
        original_num_pages: num_pages,
        num_groups_in_complete: num_groups_in_complete,
        num_groups_in_incomplete: num_groups_in_incomplete,
        num_pages_qr_scan_error: num_pages_qr_scan_error,
        user: current_user
      )
      return split_pdf_log
{'fraction_non_alphanumeric': 0.10192921160565092, 'fraction_numerical': 0.0019747835333434605, 'mean_word_length': 3.039263803680982, 'pattern_counts': {'":': 0, '<': 19, '<?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': '4300066', 'n_tokens_mistral': 2191, 'n_tokens_neox': 2123, 'n_words': 430}