seeds.rb 4.16 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
  insert_hashes.each { |c| Course.find_or_create_by!(c) }
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
    all_sections.each { |s| CourseSection.find_or_create_by! s }
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
107
108
  # 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 }
  spring2019 = Semester.find_by(season: 'Spring', year: '2019')
  (11..17).each { |day| Closure.find_or_create_by! date: Date.new(2019, 3, day), semester: spring2019 }
109
110
111
end

def main
112
  # wipe_db
113
114

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

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

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

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

128
129
    puts "\tLoading courses..."
    load_courses(courses, db_semester)
130

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

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

138
  load_closures
Zac Wood's avatar
Zac Wood committed
139
end
Zac Wood's avatar
Zac Wood committed
140

141
main