class Ubcbooker::Scraper::Cs
Constants
- CS_BOOK_URL
- CS_ROOMS
- CS_ROOM_BASE_URL
Public Instance Methods
ampm_to_time(str)
click to toggle source
05:00pm -> 17:99
# File lib/ubcbooker/scrapers/cs.rb, line 170 def ampm_to_time(str) time = Time.parse(str) return time.strftime("%H:%M") end
batch_request(room_list, book_date)
click to toggle source
# File lib/ubcbooker/scrapers/cs.rb, line 73 def batch_request(room_list, book_date) cookie = @agent.cookies.join("; ") spinner = get_spinner("Checking room availabilities") hydra = Typhoeus::Hydra.new requests = room_list.map do |room_id| room_url = get_room_cal_url(book_date, room_id) request = Typhoeus::Request.new(room_url, headers: { Cookie: cookie }) hydra.queue(request) request end hydra.run # Start requests spinner.success("Done!") return typhoeus_to_mechanize(requests) end
book(options)
click to toggle source
# File lib/ubcbooker/scrapers/cs.rb, line 10 def book(options) login title = options[:name] book_date = Date.parse(options[:date]) book_slot = get_time_slot(options[:time]) room_pages = batch_request(CS_ROOMS, book_date) room_pages.select! { |r| is_available(r, book_date, book_slot) } if room_pages.any? # TODO: If -c CHOOSE option then run CLI-UI here room = room_pages.first # Choose the first available room submit_booking(room, title, book_date, book_slot) return get_room_page_id(room) else raise Ubcbooker::Error::NoAvailableRoom.new(options[:time]) end end
get_date_div_id(date)
click to toggle source
# File lib/ubcbooker/scrapers/cs.rb, line 148 def get_date_div_id(date) date_div_base = "calendar_space_entity_project_room-" date_div_base += "#{date.year}-#{date.strftime("%m")}-#{date.strftime("%d")}-0" return date_div_base end
get_room_cal_url(book_date, room_id)
click to toggle source
# File lib/ubcbooker/scrapers/cs.rb, line 89 def get_room_cal_url(book_date, room_id) if CS_ROOMS.include?(room_id) room_url = CS_ROOM_BASE_URL + "ICCS" + room_id if is_next_month(book_date) today = Date.today month_query = "?month=" + today.year + "-" + (today.month + 1) return room_url + month_query else return room_url end end end
get_room_page_id(page)
click to toggle source
# File lib/ubcbooker/scrapers/cs.rb, line 69 def get_room_page_id(page) return page.form.action.split("/").last end
get_slot_booked(room_page, book_date)
click to toggle source
# File lib/ubcbooker/scrapers/cs.rb, line 132 def get_slot_booked(room_page, book_date) day_div_id = get_date_div_id(book_date) day_div = room_page.search("td##{day_div_id}").first slot_num = day_div.search("div.item").size start_times = day_div.search("span.date-display-start") end_times = day_div.search("span.date-display-end") slot_booked = [] (0..slot_num-1).each do |i| slot_start = ampm_to_time(start_times[i].text) # 01:00 slot_end = ampm_to_time(end_times[i].text) # 05:00 slot_booked.push((slot_start..slot_end)) end return slot_booked end
get_spinner(text)
click to toggle source
# File lib/ubcbooker/scrapers/cs.rb, line 154 def get_spinner(text) spinner = ::TTY::Spinner.new("[:spinner] #{text} ... ", format: :dots) spinner.auto_spin # Automatic animation with default interval return spinner end
get_time_slot(time_str)
click to toggle source
Expect HH:MM-HH:MM
# File lib/ubcbooker/scrapers/cs.rb, line 164 def get_time_slot(time_str) times = time_str.split("-") return (times[0]..times[1]) end
is_available(room_page, book_date, book_slot)
click to toggle source
# File lib/ubcbooker/scrapers/cs.rb, line 115 def is_available(room_page, book_date, book_slot) slot_booked = get_slot_booked(room_page, book_date) return !is_slot_booked(slot_booked, book_slot) end
is_next_month(date)
click to toggle source
# File lib/ubcbooker/scrapers/cs.rb, line 111 def is_next_month(date) return date.month != Date.today.month end
is_slot_booked(slot_booked, book_slot)
click to toggle source
# File lib/ubcbooker/scrapers/cs.rb, line 120 def is_slot_booked(slot_booked, book_slot) booked = false slot_booked.each do |s| if (s.include?(book_slot.min) || s.include?(book_slot.max) || book_slot.include?(s)) booked = true end end return booked end
login()
click to toggle source
# File lib/ubcbooker/scrapers/cs.rb, line 29 def login spinner = get_spinner("Logging into CWL") booking_url = BOOKING_URL[:cs] @agent.get(booking_url) do |page| login_page = page.link_with(text: "CWL Login Redirect").click login_ubc_cwl(login_page) end spinner.success("Done!") # Stop animation end
select_room_option(booking_form, page)
click to toggle source
Select the form otpion with right room id
# File lib/ubcbooker/scrapers/cs.rb, line 59 def select_room_option(booking_form, page) room_id = get_room_page_id(page) select_options = booking_form.field_with(name: "field_space_project_room[und]").options select_options.each do |o| if o.text.include?(room_id) o.click end end end
submit_booking(room, title, book_date, book_slot)
click to toggle source
# File lib/ubcbooker/scrapers/cs.rb, line 39 def submit_booking(room, title, book_date, book_slot) spinner = get_spinner("Submitting booking request") booking_form = @agent.get(CS_BOOK_URL).forms[1] booking_form["title"] = title book_date_str = book_date.strftime("%Y/%m/%d") # ex 2018/03/08 select_room_option(booking_form, room) booking_form["field_date[und][0][value][date]"] = book_date_str booking_form["field_date[und][0][value][time]"] = time_to_ampm(book_slot.min) booking_form["field_date[und][0][value2][date]"] = book_date_str booking_form["field_date[und][0][value2][time]"] = time_to_ampm(book_slot.max) confirmation_page = booking_form.submit if confirmation_page.search("div.alert-error").empty? spinner.success("Done!") else spinner.fail("Booking rejected") raise Ubcbooker::Error::BookingFailed.new end end
time_to_ampm(str)
click to toggle source
17:00 -> 05:00pm
# File lib/ubcbooker/scrapers/cs.rb, line 176 def time_to_ampm(str) time = Time.parse(str) return time.strftime("%I:%M%P") end
typhoeus_to_mechanize(requests)
click to toggle source
Turn typhoneus obj to mechanize page obj
# File lib/ubcbooker/scrapers/cs.rb, line 103 def typhoeus_to_mechanize(requests) pages = requests.map do |request| html = request.response.body Mechanize::Page.new(nil, {"ontent-type" => "text/html"}, html, nil, @agent) end return pages end