Skip to content
This repository has been archived by the owner on Nov 21, 2022. It is now read-only.

Spring Cleaning #20

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions .github/workflows/rails.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: Rails Test

on: [push]

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Clone Schedules
uses: actions/checkout@v2

- name: Set up Ruby 2.6
uses: actions/setup-ruby@v1
with:
ruby-version: 2.6.x

- name: Build and test
run: |
cd schedules
gem install bundler
sudo apt-get install -y mysql-client libmysqlclient-dev
bundle install
bundle exec rails help
1 change: 1 addition & 0 deletions schedules/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
TODO: Add information about different folders

for now, ping @zacwood on slack if you have questions!

10 changes: 10 additions & 0 deletions schedules/app/assets/stylesheets/application.scss
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,16 @@ nav {
text-overflow: ellipsis;
}

.prereqs {
display: block;
margin-top: 1em;
line-height: 1.7em;
font-family: 'Roboto', sans-serif;
color: $gray;
font-size: 0.9em;
max-height: 200px;
}

.see-more {
display: block;
text-align: center;
Expand Down
5 changes: 5 additions & 0 deletions schedules/app/controllers/about_controller.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
class AboutController < ApplicationController

# Suprise -- this page is left in from Schedules v3.
# No way to get to it expect manually navigating to /about.
# Leaving it in in case we ever want to add one again.
def index; end

end
6 changes: 4 additions & 2 deletions schedules/app/controllers/api/schedules_controller.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
class API::SchedulesController < ApplicationController
include BySemester

# Render an iCal file containing the schedules of all the
# course sections with the given CRNs.
def index
crns = params["crns"].split ','
@schedule = Schedule.new(crns, @semester.season)
render plain: @schedule.to_ical # render a plaintext iCal file
schedule = Schedule.new(crns, @semester.season)
render plain: schedule.to_ical # render a plaintext iCal file
end
end
2 changes: 1 addition & 1 deletion schedules/app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Configures the application.
class ApplicationController < ActionController::Base
include BySemester
include ApplicationHelper
end
21 changes: 19 additions & 2 deletions schedules/app/controllers/concerns/by_semester.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,32 @@ module BySemester
end

# This page needs to know what semester it should load data from.
# set_semester checks both the semester_id query parameter and the current session
# set_semester checks the semester_id query parameter
# to look for a semester id and loads whatever it finds into @semester.
#
# By default, load the most recent semester.
def set_semester
@semester = if params.key?(:semester_id)
Semester.find_by_id(params[:semester_id])
Semester.find(params[:semester_id])
else
Semester.sorted_by_date.first
end
end

# Get a sorted list of semesters from a given list of sections
def semesters_from(sections)
# "pluck" each semester_id from every section in the list of sections
semester_ids = sections.pluck(:semester_id).uniq
semesters = Semester.where(id: semester_ids)
semesters = Semester.sorted_by_date(semesters)

# If this course is not being taught this semester, the current semester will not
# be in @semesters. However, users expect the default semester to be the current semester,
# so add the current semester as the first semester to ensure that will be the case.
unless semesters.include?(Semester.sorted_by_date.first)
semesters = [Semester.sorted_by_date.first, *semesters]
end

semesters
end
end
32 changes: 1 addition & 31 deletions schedules/app/controllers/course_sections_controller.rb
Original file line number Diff line number Diff line change
@@ -1,35 +1,5 @@
class CourseSectionsController < ApplicationController
def index
crns = params[:crns].split(',')
@sections = crns.map { |crn| CourseSection.latest_by_crn(crn) }
@days = {
"M" => [], "T" => [], "W" => [],
"R" => [], "F" => [], "Online" => []
}

@sections.each do |s|
days = s.days.gsub(/[^a-zA-Z]/, "") # get rid of weird &nbsp; character
@days["Online"] << s if days.empty?
days.split('').each do |day|
@days[day] << s unless s.start_time == "TBA"
end
end

@days_map = {
"M" => "Monday", "T" => "Tuesday", "W" => "Wednesday",
"R" => "Thursday", "F" => "Friday", "Online" => "Online"
}

@days.each do |day, sections|
sections.sort! do |a,b|
Time.new(a.start_time) <=> Time.new(b.start_time)
end
end

render(layout: false)
end

def show
@section = CourseSection.find_by_id(params[:id])
@section = CourseSection.find(params[:id])
end
end
43 changes: 13 additions & 30 deletions schedules/app/controllers/courses_controller.rb
Original file line number Diff line number Diff line change
@@ -1,42 +1,25 @@
class CoursesController < ApplicationController
include BySemester

def show
# Load the course with the id passed in the URL.
@course = Course.find_by_id(params[:id])
@course = Course.find(params[:id])
@rating = @course.rating

semester_ids = Set.new(@course.course_sections.map(&:semester_id)).to_a
@semesters = Semester.where(id: semester_ids)
@semesters = Semester.sorted_by_date(@semesters)
@semesters = semesters_from(@course.course_sections)

@taught_in = Set.new(@semesters.map(&:season))
@taught_in = if @taught_in.empty?
"Has not been offered since #{Semester.sorted_by_date.last.to_s}"
# To get a list of the seasons this course was taught in,
# put them in a Set to get rid of duplicates, then sort them chronologically
seasons_taught = sort_seasons(@semesters.pluck(:season).uniq)
@taught_in = if seasons_taught.empty?
"Has not been offered since #{Semester.sorted_by_date.last}"
else
"Has been offered in #{(@taught_in.to_a).join(", ")}"
"Has been offered in #{seasons_taught.join(", ")}"
end


if @semesters.first != Semester.sorted_by_date.first
@semesters = [Semester.sorted_by_date.first, *@semesters]
end

@sections = @course.course_sections.where(semester: @semester).group_by { |s| s.section_type }
# Get all the sections in the current semester and group them by their section type.
@sections = @course.course_sections.where(semester: @semester).group_by(&:section_type)
end

private

def sort_seasons(seasons)
seasons.sort do |s1, s2|
case
when s1 == "Fall"
-1
when s1 == "Summer" && s2 == "Fall"
1
when s1 == "Spring"
1
else
0
end
end
end
end
end
4 changes: 4 additions & 0 deletions schedules/app/controllers/home_controller.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
# HomeController renders the homepage. It currently requires no logic.
class HomeController < ApplicationController

# Nothing to do here.
# Rails will just render the view in app/views/home/index.html.erb
def index; end

end
17 changes: 6 additions & 11 deletions schedules/app/controllers/instructors_controller.rb
Original file line number Diff line number Diff line change
@@ -1,20 +1,15 @@
class InstructorsController < ApplicationController
include BySemester

def show
@instructor = Instructor.find_by_id(params[:id])
@instructor = Instructor.find(params[:id])

# find the courses being taught this semester
sections = CourseSection.where(instructor: @instructor)
semester_ids = Set.new(sections.pluck(:semester_id))

@semesters = Semester.where(id: semester_ids)
@semesters = Semester.sorted_by_date(@semesters)

@sections = sections.where(semester: @semester).group_by { |s| s.section_type }
@semesters = semesters_from(sections)

if @semesters.first != Semester.sorted_by_date.first
@semesters = [Semester.sorted_by_date.first, *@semesters]
end
@sections = sections.where(semester: @semester).group_by(&:section_type)

@rating = { teaching: @instructor.rating, respect: @instructor.rating(6) }
@rating = @instructor.rating(:teaching)
end
end
37 changes: 35 additions & 2 deletions schedules/app/controllers/schedules_controller.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,36 @@
class SchedulesController < ApplicationController
def index; end
end
# index renders the /schedule page, which then asynchronously
# requests #sections to get the list of sections currently in the cart.
def index; end

def sections
crns = params[:crns].split(',')
@sections = crns.map { |crn| CourseSection.latest_by_crn(crn) }
@days = {
"M" => [], "T" => [], "W" => [],
"R" => [], "F" => [], "Online" => []
}

@sections.each do |s|
days = s.days.gsub(/[^a-zA-Z]/, "") # get rid of weird &nbsp; character
@days["Online"] << s if days.empty?
days.split('').each do |day|
@days[day] << s unless s.start_time == "TBA"
end
end

@days_map = {
"M" => "Monday", "T" => "Tuesday", "W" => "Wednesday",
"R" => "Thursday", "F" => "Friday", "Online" => "Online"
}

@days.each do |day, sections|
sections.sort! do |a,b|
Time.new(a.start_time) <=> Time.new(b.start_time)
end
end

# Don't render the normal HTML head, just render what's in the view file
render(layout: false)
end
end
19 changes: 9 additions & 10 deletions schedules/app/controllers/search_controller.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
class SearchController < ApplicationController

# Searching is hard. This code isn't very good, but it works for the most part.
# It trys to match the search query to different regular expressions
# and attempts to take you to the correct place based on which one matches.
#
# - CRNs get sent to the course page that contains the CRN
# - Queries of the form "Subject CourseNum", like "CS 112", get sent to that course
# - Otherwise search every course's title and description, along with instutor names and display whatever matches
def index
params[:query].strip!
redirect_to(home_url) unless params[:query].length > 1

if params[:query].casecmp('god').zero?
bell = Instructor.find_by_name('Jonathan Bell')
redirect_to(instructor_url(bell))
end

@instructors = nil
@courses = nil

Expand All @@ -25,18 +28,14 @@ def index
@courses = Course.where("(courses.title LIKE ?) OR (courses.description LIKE ?)", query, query).uniq
@instructors = Instructor.named(params[:query])
end

@courses.map! do |c|
c.serializable_hash.merge(url: course_url(c))
end
end

/[0-9]{5}/.match(params[:query]) do |m|
redirect_to(course_url(CourseSection.latest_by_crn(m[0]).course))
end

if @courses&.count == 1 && @instructors&.count&.zero?
redirect_to(course_url(@courses.first["id"]))
redirect_to(course_url(@courses.first))
elsif @courses&.count&.zero? && @instructors&.count == 1
redirect_to(instructor_url(@instructors.first))
end
Expand Down
15 changes: 15 additions & 0 deletions schedules/app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
@@ -1,2 +1,17 @@
module ApplicationHelper
def sort_seasons(seasons)
# Sort by Spring < Summer < Fall
seasons.sort do |s1, s2|
case
when s1 == "Fall"
-1
when s1 == "Summer" && s2 == "Fall"
1
when s1 == "Spring"
1
else
0
end
end
end
end
27 changes: 0 additions & 27 deletions schedules/app/helpers/schedules_helper.rb
Original file line number Diff line number Diff line change
@@ -1,29 +1,2 @@
module SchedulesHelper
DAYS = {
"M": Date.new(2019, 1, 14),
"T": Date.new(2019, 1, 15),
"W": Date.new(2019, 1, 16),
"R": Date.new(2019, 1, 17),
"F": Date.new(2019, 1, 18),
"S": Date.new(2019, 1, 19),
"U": Date.new(2019, 1, 20)
}.freeze

def generate_fullcalender_events(sections)
sections.map do |s|
s.days.split('').map do |day|
formatted_date = DAYS[day.to_sym].to_s.tr('-', '')
time = Time.parse(s.start_time).strftime("%H%M%S")
endtime = Time.parse(s.end_time).strftime("%H%M%S")

{
title: s.name,
start: "#{formatted_date}T#{time}",
end: "#{formatted_date}T#{endtime}",
crn: s.crn,
active: true
}
end
end.flatten
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export default class extends Controller {
this.loaderTarget.classList.remove('hidden')
this.scheduleTarget.innerHTML = ''

fetch(`/course_sections?crns=${getCart().join(',')}`)
fetch(`/schedule/sections?crns=${getCart().join(',')}`)
.then(resp => resp.text())
.then(text => {
this.scheduleTarget.innerHTML = text
Expand Down
6 changes: 3 additions & 3 deletions schedules/app/models/course.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ class Course < ApplicationRecord
has_many :course_sections

# Ensure all necessary are fields present.
validates :course_number, presence: true
validates :subject, presence: true
validates :course_number, format: { with: /[0-9]{3}/ }
validates :subject, format: { with: /[A-Z]{2,4}/ }

def full_name
"#{subject} #{course_number}"
Expand All @@ -19,6 +19,6 @@ def rating(question = 1, sections = course_sections)
total += s.rating_questions[question]["instr_mean"].to_f * s.rating_questions[0]["resp"].to_i
end

[(total / resp).round(2), resp] unless resp.zero?
Rating.new((total / resp).round(2), resp) unless resp.zero?
end
end
Loading