Commit ef6460e9 authored by Zac Wood's avatar Zac Wood

Start work on course ratings

parent 485c9d4d
......@@ -10,6 +10,21 @@ class Course < ApplicationRecord
"#{subject} #{course_number}"
end
def rating
i = 0
total = 0
course_sections.each do |s|
next if s.course_rating.nil?
total += s.course_rating.to_f
i += 1
end
if i == 0
"N/A"
else
total / i
end
end
def self.from_subject(base_query, subject)
base_query.where("courses.subject = ?", subject.upcase)
end
......
......@@ -14,6 +14,24 @@ class CourseSection < ApplicationRecord
validates :course_id, presence: true
validates :semester_id, presence: true
serialize :rating_questions, Array
def teaching_rating
if rating_questions.empty?
nil
else
rating_questions[0]["instr_mean"]
end
end
def course_rating
if rating_questions.empty?
nil
else
rating_questions[1]["instr_mean"]
end
end
def overlaps?(other)
t1_start, t1_end = Time.parse(start_time), Time.parse(end_time)
t2_start, t2_end = Time.parse(other.start_time), Time.parse(other.end_time)
......
......@@ -40,6 +40,10 @@
<% prereqs, note = rest.split('.') %>
<p><strong><%= first %>:</strong> <%= prereqs %> <sub><%= note %></sub></p>
<% end %>
<% unless course.rating.nil? %>
<p>This course has a <%= course.rating %> / 5 rating.</p>
<% end %>
<% if expanded %>
<div class="d-block" style="text-align: center">
......@@ -52,6 +56,8 @@
<i id="course-chevron" class="fas fa-chevron-down"></i>
</div>
<% end %>
<!-- List of Course Sections -->
<div class="list-group list-group-flush sections" style="display: <%= expanded ? "flex" : "none" %>">
......
......@@ -23,7 +23,9 @@
<% if section.instructor.name == "TBA" %>
TBA
<% else %>
<%= link_to section.instructor.name, section.instructor %><% end %> <br/>
<%= link_to section.instructor.name, section.instructor %> was rated <%= section.teaching_rating %> / 5 for this section.
<% end %>
<br/>
<i class="fas fa-map-marker-alt"></i> <%= section.location %> <br/>
<i class="fas fa-clock"></i> <%= "#{section.days}, #{section.start_time}-#{section.end_time}" %> <br/>
......
require 'httparty'
require 'nokogiri'
headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:65.0) Gecko/20100101 Firefox/65.0',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Encoding': 'gzip, deflate, br',
'Referer': 'https://crserating.gmu.edu/ReportPaper/',
'Content-Type': 'application/x-www-form-urlencoded',
'Connection': 'keep-alive',
'Cookie': 'ga=GA1.2.1878572417.1543773996; __unam=74bec77-167701a5090-6fe3a784-10; __insp_slim=1549744302281; CFID=1938650; CFTOKEN=b1990d0cd24bb3f4-19FA09EB-5056-9470-35EEF241BAFA23D5; CFGLOBALS=urltoken%3DCFID%23%3D1938650%26CFTOKEN%23%3Db1990d0cd24bb3f4%2D19FA09EB%2D5056%2D9470%2D35EEF241BAFA23D5%23lastvisit%3D%7Bts%20%272019%2D01%2D29%2019%3A40%3A10%27%7D%23timecreated%3D%7Bts%20%272019%2D01%2D29%2019%3A39%3A51%27%7D%23hitcount%3D7%23cftoken%3Db1990d0cd24bb3f4%2D19FA09EB%2D5056%2D9470%2D35EEF241BAFA23D5%23cfid%3D1938650%23; __insp_wid=1435896333; __insp_nv=true; __insp_ref=aHR0cHM6Ly9pcnIyLmdtdS5lZHUvTmV3L05fRW5yb2xsT2ZmL0VucmxTdHMuY2Zt; __insp_targlpu=https%3A%2F%2Firr2.gmu.edu%2FNew%2FN_EnrollOff%2FEnrlSts.cfm; __insp_targlpt=Office%20of%20Institutional%20Research%20and%20Effectiveness; BIGipServer~web.gmu.edu~goose.gmu.edu_p80=1242087434.20480.0000',
'Upgrade-Insecure-Requests': '1',
'Cache-Control': 'max-age=0'
}
resp = HTTParty.post('https://crserating.gmu.edu/ReportPaper/InstructorList.cfm',
body: "SearchType=instructor&semester=f17&ctitle=&iname=&divsname=&deptname=&disc=&ckey=&orig=off&SearchTypeHid=instructor",
headers: headers).body
document = Nokogiri::HTML(resp)
values = document.css('select option').map { |e| e['value'] }
i = values.index('--Select an Instructor--')
values = values[i+1..-1]
all = {}
c = values.count
counter = 1
values.each do |v|
puts "#{counter}/#{c} getting data for #{v}..."
counter += 1
resp = HTTParty.post('https://crserating.gmu.edu/ReportPaper/InstructorList.cfm',
body: "SearchType=instructor&semester=f17&ctitle=&iname=#{v}&divsname=&deptname=&disc=&ckey=&orig=off&SearchTypeHid=instructor",
headers: headers)
document = Nokogiri::HTML(resp)
rows = document.css('tr')
i = rows.index { |r| r.css('td').first&.text == 'Course' }
rows[i+1..-3].each do |s_tr|
tds = s_tr.css('td')
id = tds.first.css('font a').first['href'].match(/[0-9]+/)[0]
section, instr = tds.first&.text, tds[2]&.text
resp = HTTParty.post("https://crserating.gmu.edu/ReportPaper/MeansSummary16.cfm?rat_num=#{id}&caller=InstructorList",
body: "semester=f17&formseq=62&orig=off&iname=#{instr}",
headers: headers)
document = Nokogiri::HTML(resp)
rows = document.css('tr')
qs = [9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39].map do |i|
datas = rows[i].css('td')
{ q: datas[0].text.match(/[A-Z].*/)[0], resp: datas[1].text.strip, instr_mean: datas[2].text.strip, dept_mean: datas[3].text.strip }
end
all[section] = qs
end
puts '------------------------------'
end
File.write('f17.json', all.to_json)
require 'json'
ratings = JSON.parse(File.read('db/data/sm18.json'))
semester = Semester.find_by!(season: 'Summer', year: "2018")
ratings.each do |section, qs|
section = section.split(',').first
subj = section.match(/[A-Z]+/)[0]
course = section.match(/[0-9]{3} /)[0].strip
sect_num = section.match(/ [A-Z0-9]+/)[0].strip
name = "#{subj} #{course} #{sect_num}"
s = CourseSection.find_by(name: name, semester: semester)
next if s.nil?
s.rating_questions = qs
s.save!
end
class AddRatingsToCourseSection < ActiveRecord::Migration[5.1]
def change
add_column :course_sections, :rating_questions, :string
end
end
......@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20190210152552) do
ActiveRecord::Schema.define(version: 20190307042304) do
create_table "closures", force: :cascade do |t|
t.date "date"
......@@ -40,6 +40,7 @@ ActiveRecord::Schema.define(version: 20190210152552) do
t.datetime "updated_at", null: false
t.integer "instructor_id"
t.integer "semester_id"
t.string "rating_questions"
t.index ["course_id"], name: "index_course_sections_on_course_id"
t.index ["instructor_id"], name: "index_course_sections_on_instructor_id"
t.index ["semester_id"], name: "index_course_sections_on_semester_id"
......
......@@ -114,10 +114,10 @@ def main
parser = PatriotWeb::Parser.new
semesters = if ARGV.first == "update"
[parser.parse_semesters.first]
[parser.parse_semesters[3]]
else
# expand to include however many semesters you want
parser.parse_semesters[0..6]
parser.parse_semesters[0..1]
end
puts "\tParsing subjects..."
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment