seeds.rb 3.93 KB
Newer Older
Zac Wood's avatar
Zac Wood committed
1 2
# This file should contain all the record creation needed to seed the database with its default values.
# The data can then be loaded with the rails db:seed command (or created alongside the database with db:setup).
3

Zac Wood's avatar
Zac Wood committed
4
require_relative 'patriot_web_parser'
5
require_relative 'courses_loader'
Zac Wood's avatar
Zac Wood committed
6 7 8 9 10
require 'thwait'
require 'httparty'
require 'nokogiri'
require 'json'

11 12
def parse_courses(subjects)
  courses = []
Zac Wood's avatar
Zac Wood committed
13

14 15 16 17 18 19 20
  threads = subjects.map do |subject|
    Thread.new do
      courses.push(*get_courses(subject.downcase))
    end
  end

  ThreadsWait.all_waits(*threads)
Zac Wood's avatar
Zac Wood committed
21

22 23
  courses
end
Zac Wood's avatar
Zac Wood committed
24

25
def load_courses(courses, semester)
26 27 28 29 30 31 32
  insert_hashes = courses.map do |course|
    {
      subject: course[:subject],
      title: course[:title],
      course_number: course[:course_number],
      credits: course[:credits],
      description: course[:description],
33
      prereqs: course[:prereqs],
34 35
      semester: semester
    }
36
  end
37 38

  Course.create!(insert_hashes)
Zac Wood's avatar
Zac Wood committed
39 40
end

41
def parse_sections(semester, subjects)
42 43 44 45 46
  parser = PatriotWeb::Parser.new
  sections_in = {}

  threads = subjects.map do |subject|
    Thread.new do
47
      sections_in[subject] = parser.parse_courses_in_subject(semester, subject)
48 49 50
    end
  end

51
  ThreadsWait.all_waits(*threads)
52

53 54
  sections_in
end
55

56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
def load_sections(sections_in, semester)
  sections_in.each do |subject, sections|
    all_sections = []

    sections.each do |section|
      if section.nil? || !section.key?(:subj) || !section.key?(:course_number)
        puts "#{subject} failed section: #{section.class}"
        next
      end

      course = Course.find_or_create_by!(subject: section[:subj],
                                         course_number: section[:course_number],
                                         semester: semester)

      instructor = Instructor.find_or_create_by!(name: section[:instructor])

      section_name = "#{section[:subj]} #{section[:course_number]} #{section[:section]}"

      all_sections.push(name: section_name,
                        crn: section[:crn],
                        section_type: section[:type],
                        title: section[:title],
                        start_date: section[:start_date],
                        end_date: section[:end_date],
                        days: section[:days],
                        start_time: section[:start_time],
                        end_time: section[:end_time],
                        location: section[:location],
                        course: course,
                        instructor: instructor)
86
    end
Zac Wood's avatar
Zac Wood committed
87

88
    CourseSection.create!(all_sections)
Zac Wood's avatar
Zac Wood committed
89
  end
90 91 92 93 94 95 96 97 98
end

def wipe_db
  Closure.delete_all
  CourseSection.delete_all
  Course.delete_all
  Semester.delete_all
end

99
def load_closures
100 101
  # create closures for the days there will be no classes
  # see: https://registrar.gmu.edu/calendars/fall-2018/
102 103 104 105 106
  fall2018 = Semester.find_by(season: 'Fall', year: '2018')
  Closure.create! date: Date.new(2018, 9, 3), semester: fall2018
  Closure.create! date: Date.new(2018, 10, 8), semester: fall2018
  (21..25).each { |n| Closure.create! date: Date.new(2018, 11, n), semester: fall2018 }
  (10..19).each { |n| Closure.create! date: Date.new(2018, 12, n), semester: fall2018 }
107 108 109 110 111 112
end

def main
  wipe_db

  parser = PatriotWeb::Parser.new
113 114
  semesters = [parser.parse_semesters.first] # expand to include however many semesters you want
  courses = nil
Zac Wood's avatar
oops  
Zac Wood committed
115

116 117 118
  semesters.each do |semester|
    puts "#{semester[:season]} #{semester[:year]}"
    db_semester = Semester.create!(season: semester[:season], year: semester[:year])
119

120 121
    puts "\tParsing subjects..."
    subjects = parser.parse_subjects(semester[:value])
122

123 124
    puts "\tParsing courses from catalog.gmu.edu..."
    courses = parse_courses(subjects) if courses.nil?
125

126 127
    puts "\tLoading courses..."
    load_courses(courses, db_semester)
128

129 130
    puts "\tParsing sections from Patriot Web..."
    sections_in = parse_sections(semester[:value], subjects)
131

132 133 134
    puts "\tLoading sections..."
    load_sections(sections_in, db_semester)
  end
Zac Wood's avatar
Zac Wood committed
135

136
  load_closures
Zac Wood's avatar
Zac Wood committed
137
end
Zac Wood's avatar
Zac Wood committed
138

139
main