app/jobs/split_pdf_job.rb
# Save the pages into groups for this assignment
Save the pages into groups for this assignment
Save the pages into groups for this assignment
def save_pages(exam_template, partial_exams, filename = nil, split_pdf_log = nil)
    return unless exam_template.course.instructors.exists?
    complete_dir = File.join(exam_template.base_path, 'complete')
    incomplete_dir = File.join(exam_template.base_path, 'incomplete')
    error_dir = File.join(exam_template.base_path, 'error')
    raw_dir = File.join(exam_template.base_path, 'raw')
    groupings = []
    num_complete = 0
    partial_exams.each do |exam_num, pages|
      next if pages.empty?
      pages.sort_by! { |page_num, _| page_num }
      group = Group.find_by(
        group_name: group_name_for(exam_template, exam_num),
        repo_name: group_name_for(exam_template, exam_num),
        course: exam_template.course
      )
      grouping = Grouping.find_or_create_by(
        group: group,
        assignment: exam_template.assignment
      )
      groupings << grouping
      if pages.length == exam_template.num_pages
        destination = File.join complete_dir, exam_num.to_s
        num_complete += 1
      else
        destination = File.join incomplete_dir, exam_num.to_s
      end
      FileUtils.mkdir_p destination
      pages.each do |page_num, page, raw_page_num|
        new_pdf = CombinePDF.new
        new_pdf << page
        split_page = SplitPage.find_by(
          filename: filename,
          exam_page_number: page_num.to_i,
          raw_page_number: raw_page_num,
          group: group,
          split_pdf_log: split_pdf_log
        )
        if File.exist?(File.join(destination, "#{page_num}.pdf"))
          new_pdf.save File.join(error_dir, "#{split_page.id}.pdf")
          status = "ERROR: #{exam_template.name}: exam number #{exam_num}, page #{page_num} already exists"
        else
          new_pdf.save File.join(destination, "#{page_num}.pdf")
          if File.dirname(destination) == complete_dir
            status = 'Saved to complete directory'
          else
            status = 'Saved to incomplete directory'
          end
        end
        split_page.update(status: status)
      end
      grouping.access_repo do |repo|
        assignment_folder = exam_template.assignment.repository_folder
        txn = repo.get_transaction(exam_template.course.instructors.first.user_name)
        exam_template.template_divisions.each do |division|
          new_pdf = CombinePDF.new
          pages.each do |page_num, page|
            if division.start <= page_num && page_num <= division.end
              new_pdf << page
            end
          end
          if File.exist? File.join(assignment_folder, "#{division.label}.pdf")
            txn.replace(File.join(assignment_folder,
                                  "#{division.label}.pdf"),
                        new_pdf.to_pdf,
                        'application/pdf')
          else
            txn.add(File.join(assignment_folder,
                              "#{division.label}.pdf"),
                    new_pdf.to_pdf,
                    'application/pdf')
          end
        end
        extra_pages = pages.reject do |page_num, _|
          exam_template.template_divisions.any? do |division|
            division.start <= page_num && page_num <= division.end
          end
        end
        extra_pages.sort_by! { |page_num, _| page_num }
        extra_pdf = CombinePDF.new
        cover_pdf = CombinePDF.new
        start_page = 0
        if !extra_pages.empty? && extra_pages[0][0] == 1
          cover_pdf << extra_pages[0][1]
          start_page = 1
        end
        extra_pdf << extra_pages[start_page..extra_pages.size].collect { |_, page| page }
        if File.exist? File.join(assignment_folder, 'EXTRA.pdf')
          txn.replace(File.join(assignment_folder,
                                'EXTRA.pdf'),
                      extra_pdf.to_pdf,
                      'application/pdf')
        else
          txn.add(File.join(assignment_folder,
                            'EXTRA.pdf'),
                  extra_pdf.to_pdf,
                  'application/pdf')
        end
        if File.exist? File.join(assignment_folder, 'COVER.pdf')
          txn.replace(File.join(assignment_folder,
                                'COVER.pdf'),
                      cover_pdf.to_pdf,
                      'application/pdf')
        else
          txn.add(File.join(assignment_folder,
                            'COVER.pdf'),
                  cover_pdf.to_pdf,
                  'application/pdf')
        end
        repo.commit(txn)
        next unless exam_template.automatic_parsing
        begin
          imglist = Magick::Image.from_blob(cover_pdf.to_pdf) do
            self.quality = 100
            self.density = '300'
          end
        rescue StandardError
          next
        end
        img = imglist.first
        student_info = img.crop exam_template.crop_x * img.columns, exam_template.crop_y * img.rows,
                                exam_template.crop_width * img.columns, exam_template.crop_height * img.rows
        student_info_file = File.join(raw_dir, "#{grouping.id}_info.jpg")
        student_info.write(student_info_file)
        python_exe = File.join(Settings.python.bin, 'python')
        read_chars_py_file = File.join(::Rails.root, 'lib', 'scanner', 'read_chars.py')
        stdout, status = Open3.capture2(python_exe, read_chars_py_file, student_info_file)
        next unless status.success?
        student = match_student(stdout.strip.split("\n"), exam_template)
        unless student.nil?
          StudentMembership.find_or_create_by(role: student,
                                              grouping: grouping,
                                              membership_status: StudentMembership::STATUSES[:inviter])
        end
      end
    end
    num_complete
  end
def save_pages ( exam_template , partial_exams , filename = nil , split_pdf_log = nil ) return unless exam_template . course . instructors . exists? complete_dir = File . join ( exam_template . base_path , 'complete' ) incomplete_dir = File . join ( exam_template . base_path , 'incomplete' ) error_dir = File . join ( exam_template . base_path , 'error' ) raw_dir = File . join ( exam_template . base_path , 'raw' ) groupings = [ ] num_complete = 0 partial_exams . each do | exam_num , pages | next if pages . empty? pages . sort_by! { | page_num , _ | page_num } group = Group . find_by ( group_name : group_name_for ( exam_template , exam_num ) , repo_name : group_name_for ( exam_template , exam_num ) , course : exam_template . course ) grouping = Grouping . find_or_create_by ( group : group , assignment : exam_template . assignment ) groupings << grouping if pages . length == exam_template . num_pages destination = File . join complete_dir , exam_num . to_s num_complete += 1 else destination = File . join incomplete_dir , exam_num . to_s end FileUtils . mkdir_p destination pages . each do | page_num , page , raw_page_num | new_pdf = CombinePDF . new new_pdf << page split_page = SplitPage . find_by ( filename : filename , exam_page_number : page_num . to_i , raw_page_number : raw_page_num , group : group , split_pdf_log : split_pdf_log ) if File . exist? ( File . join ( destination , "#{page_num}.pdf" ) ) new_pdf . save File . join ( error_dir , "#{split_page.id}.pdf" ) status = "ERROR: #{exam_template.name}: exam number #{exam_num}, page #{page_num} already exists" else new_pdf . save File . join ( destination , "#{page_num}.pdf" ) if File . dirname ( destination ) == complete_dir status = 'Saved to complete directory' else status = 'Saved to incomplete directory' end end split_page . update ( status : status ) end grouping . access_repo do | repo | assignment_folder = exam_template . assignment . repository_folder txn = repo . get_transaction ( exam_template . course . instructors . first . user_name ) exam_template . template_divisions . each do | division | new_pdf = CombinePDF . new pages . each do | page_num , page | if division . start <= page_num && page_num <= division . end new_pdf << page end end if File . exist? File . join ( assignment_folder , "#{division.label}.pdf" ) txn . replace ( File . join ( assignment_folder , "#{division.label}.pdf" ) , new_pdf . to_pdf , 'application/pdf' ) else txn . add ( File . join ( assignment_folder , "#{division.label}.pdf" ) , new_pdf . to_pdf , 'application/pdf' ) end end extra_pages = pages . reject do | page_num , _ | exam_template . template_divisions . any? do | division | division . start <= page_num && page_num <= division . end end end extra_pages . sort_by! { | page_num , _ | page_num } extra_pdf = CombinePDF . new cover_pdf = CombinePDF . new start_page = 0 if ! extra_pages . empty? && extra_pages [ 0 ] [ 0 ] == 1 cover_pdf << extra_pages [ 0 ] [ 1 ] start_page = 1 end extra_pdf << extra_pages [ start_page .. extra_pages . size ] . collect { | _ , page | page } if File . exist? File . join ( assignment_folder , 'EXTRA.pdf' ) txn . replace ( File . join ( assignment_folder , 'EXTRA.pdf' ) , extra_pdf . to_pdf , 'application/pdf' ) else txn . add ( File . join ( assignment_folder , 'EXTRA.pdf' ) , extra_pdf . to_pdf , 'application/pdf' ) end if File . exist? File . join ( assignment_folder , 'COVER.pdf' ) txn . replace ( File . join ( assignment_folder , 'COVER.pdf' ) , cover_pdf . to_pdf , 'application/pdf' ) else txn . add ( File . join ( assignment_folder , 'COVER.pdf' ) , cover_pdf . to_pdf , 'application/pdf' ) end repo . commit ( txn ) next unless exam_template . automatic_parsing begin imglist = Magick :: Image . from_blob ( cover_pdf . to_pdf ) do self . quality = 100 self . density = '300' end rescue StandardError next end img = imglist . first student_info = img . crop exam_template . crop_x * img . columns , exam_template . crop_y * img . rows , exam_template . crop_width * img . columns , exam_template . crop_height * img . rows student_info_file = File . join ( raw_dir , "#{grouping.id}_info.jpg" ) student_info . write ( student_info_file ) python_exe = File . join ( Settings . python . bin , 'python' ) read_chars_py_file = File . join ( :: Rails . root , 'lib' , 'scanner' , 'read_chars.py' ) stdout , status = Open3 . capture2 ( python_exe , read_chars_py_file , student_info_file ) next unless status . success? student = match_student ( stdout . strip . split ( "\n" ) , exam_template ) unless student . nil? StudentMembership . find_or_create_by ( role : student , grouping : grouping , membership_status : StudentMembership :: STATUSES [ :inviter ] ) end end end num_complete end
Save the pages into groups for this assignment
Save the pages into groups for this assignment
# Save raw pages # if a page already exists, move the page to error directory instead of overwriting it # set status depending on whether parent directory of destination is complete or incomplete # update status of page # Pages that belong to a division # Pages that don't belong to any division # convert PDF to an image # Snip out the middle of PDF that contains the student information
exam_template
<not_specific>
partial_exams
<not_specific>
filename
<not_specific>
split_pdf_log
<not_specific>