Skip to content

Instantly share code, notes, and snippets.

@phlipper
Last active August 29, 2015 14:07
Show Gist options
  • Save phlipper/812ae393fe8db8bf42db to your computer and use it in GitHub Desktop.
Save phlipper/812ae393fe8db8bf42db to your computer and use it in GitHub Desktop.
TECH 601-00 Course Database Project
require "csv"
require "yaml"
require "./report_functions"
courses = YAML.load_file("./courses.yaml")
puts "Find Courses by Title or Instructor?" \
"\n * Enter '1' for Title" \
"\n * Enter '2' for Instructor"
sort_key = gets.chomp.to_i
if sort_key == 1
puts "Enter a Title to search for:"
title = gets.chomp
selected_courses = find_courses_by_title(courses, title)
elsif sort_key == 2
puts "Enter an Instructor to search for:"
instructor = gets.chomp
selected_courses = find_courses_by_instructor(courses, instructor)
else
puts "Unknown option '#{sort_key}'. Exiting..."
exit 1
end
csv_headers = ["Title", "Code", "Instructors", "Sections"]
CSV.open("./courses.csv", "wb") do |csv|
csv << csv_headers
selected_courses.each do |course|
csv << [
course["title"],
course_title_code(course),
formatted_course_instructor_names(course),
formatted_course_section_descriptions(course)
]
end
end
puts "Report saved to './courses.csv'"
require "yaml"
require "./report_functions"
courses = YAML.load_file("./courses.yaml")
puts "Find Courses by Title or Instructor?" \
"\n * Enter '1' for Title" \
"\n * Enter '2' for Instructor"
sort_key = gets.chomp.to_i
if sort_key == 1
puts "Enter a Title to search for:"
title = gets.chomp
selected_courses = find_courses_by_title(courses, title)
elsif sort_key == 2
puts "Enter an Instructor to search for:"
instructor = gets.chomp
selected_courses = find_courses_by_instructor(courses, instructor)
else
puts "Unknown option '#{sort_key}'. Exiting..."
exit 1
end
puts "-" * 30, "Displaying #{selected_courses.size} results:", "-" * 30, ""
selected_courses.sort_by { |c| c["course_number"].to_i }.each do |course|
output =[
"Title: #{course["title"]}",
"Code: #{course_title_code(course)}",
"Instructors: #{formatted_course_instructor_names(course)}",
"Sections: #{formatted_course_section_descriptions(course)}"
]
puts output, "-" * 30, ""
end
require "open-uri"
require "yaml"
require "bundler"
Bundler.setup
require "nokogiri"
text_divider = "-" * 40
#
def fix_encoding(text)
text.to_s
.force_encoding("UTF-8")
.encode("UTF-8", "binary", :undef => :replace)
end
#
def normalize_key(key)
key.to_s.downcase.gsub(" ", "_").gsub("(s)", "s")
end
#
def split_instructors(line)
line.split(",").map do |instructor|
instructor.strip
end
end
#
course_url_prefix = "https://www.cisweb1.unr.edu/cxs/"
#
upcoming_url = "#{course_url_prefix}/Upcoming.asp"
#
upcoming_html = open(upcoming_url).read
#
html_doc = Nokogiri::HTML(upcoming_html)
#
css_path = "li > a"
#
course_links = html_doc.css(css_path)
#
courses = []
puts "Processing #{course_links.size} records ...", text_divider
#
course_links.each_with_index do |link, index|
#
course_title = link["title"].strip
course_url = course_url_prefix + link["href"]
puts "Processing ##{index + 1} - #{course_title}"
#
url_params = course_url[/\?(.*)/, 1].split("&")
#
params_hash = url_params.reduce({}) do |params, param|
key, value = param.split("=")
params.update(key => value)
end
#
course = params_hash.merge(
"url" => course_url,
"title" => course_title
)
#
course_html = open(course_url).read
#
course_doc = Nokogiri::HTML(course_html)
#
course_section_path = "table > tr:only-child"
#
course_sections = course_doc.css(course_section_path)
#
sections = Array(course_sections).delete_if { |sel|
sel["class"] == "nav" ||
#
fix_encoding(sel.text) =~ /Extended Studies at the University of Nevada/
}
#
course["sections"] = sections.map do |section|
fix_encoding(section.text)
.strip
.gsub(/[\t\r]/, "")
.split("\n")
.map(&:strip)
.delete_if do |line|
line.empty? ||
line == "Course Section" ||
line == "Add To Shopping Cart"
end
.join("\n")
.gsub(":\n", ":")
.split("\n")
.reduce({}) do |sections, line|
if line.match(":")
key, value = line.split(":")
key = normalize_key(key)
if key == "instructors"
value = split_instructors(value)
end
sections[key] = value
end
sections
end
end
courses << course
end
#
puts text_divider, "Preparing to save Course Database ..."
#
File.open("courses.yaml", "wb") do |file|
file.write YAML.dump(courses)
end
#
puts text_divider, "Database save Complete!"
source "https://rubygems.org"
gem "nokogiri"
def course_title_code(course)
course["course_area"] + " " +
course["course_number"] + "-" +
course["course_subtitle"]
end
def formatted_course_section_descriptions(course)
course["sections"].map { |c| c["description"] }.join("\n")
end
def formatted_course_instructor_names(course)
course["sections"].map do |c|
c["instructors"]
end.uniq.join(", ")
end
def find_courses_by_title(courses, title)
courses.select do |course|
course["title"].downcase.match title.downcase
end
end
def find_courses_by_instructor(courses, name)
courses.select do |course|
course["sections"].any? do |section|
section["instructors"].any? do |instructor|
instructor.downcase.match name.downcase
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment