seeds.rb 3.9 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 33 34
  insert_hashes = courses.map do |course|
    {
      subject: course[:subject],
      title: course[:title],
      course_number: course[:course_number],
      credits: course[:credits],
      description: course[:description],
      semester: semester
    }
35
  end
36 37

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

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

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

50
  ThreadsWait.all_waits(*threads)
51

52 53
  sections_in
end
54

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
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)
85
    end
Zac Wood's avatar
Zac Wood committed
86

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

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

98
def load_closures
99 100
  # create closures for the days there will be no classes
  # see: https://registrar.gmu.edu/calendars/fall-2018/
101 102 103 104 105
  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 }
106 107 108 109 110 111
end

def main
  wipe_db

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

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

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

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

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

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

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

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

138
main