Class: Ubcbooker::Scraper::Cs
Constant Summary
collapse
- CS_ROOM_BASE_URL =
"https://my.cs.ubc.ca/space/"
- CS_BOOK_URL =
"https://my.cs.ubc.ca/node/add/pr-booking"
- CS_ROOMS =
["X139", "X141", "X151", "X153", "X237", "X239", "X241", "X337", "X339", "X341"]
Instance Method Summary
collapse
-
#ampm_to_time(str) ⇒ Object
-
#batch_request(room_list, book_date) ⇒ Object
-
#book(options) ⇒ Object
-
#get_date_div_id(date) ⇒ Object
-
#get_room_cal_url(book_date, room_id) ⇒ Object
-
#get_room_page_id(page) ⇒ Object
-
#get_slot_booked(room_page, book_date) ⇒ Object
-
#get_spinner(text) ⇒ Object
-
#get_time_slot(time_str) ⇒ Object
-
#is_available(room_page, book_date, book_slot) ⇒ Object
-
#is_next_month(date) ⇒ Object
-
#is_slot_booked(slot_booked, book_slot) ⇒ Object
-
#login ⇒ Object
-
#select_room_option(booking_form, page) ⇒ Object
Select the form otpion with right room id.
-
#submit_booking(room, title, book_date, book_slot) ⇒ Object
-
#time_to_ampm(str) ⇒ Object
-
#typhoeus_to_mechanize(requests) ⇒ Object
Turn typhoneus obj to mechanize page obj.
Methods inherited from BaseScraper
#initialize, #is_logged_in, #login_ubc_cwl, #populate_account_info
Instance Method Details
#ampm_to_time(str) ⇒ Object
170
171
172
173
|
# 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) ⇒ Object
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
# 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 spinner.success("Done!")
return typhoeus_to_mechanize(requests)
end
|
#book(options) ⇒ Object
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
# 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?
room = room_pages.first 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) ⇒ Object
148
149
150
151
152
|
# 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) ⇒ Object
89
90
91
92
93
94
95
96
97
98
99
100
|
# 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) ⇒ Object
69
70
71
|
# 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) ⇒ Object
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
|
# 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) slot_end = ampm_to_time(end_times[i].text) slot_booked.push((slot_start..slot_end))
end
return slot_booked
end
|
#get_spinner(text) ⇒ Object
154
155
156
157
158
|
# File 'lib/ubcbooker/scrapers/cs.rb', line 154
def get_spinner(text)
spinner = ::TTY::Spinner.new("[:spinner] #{text} ... ", format: :dots)
spinner.auto_spin return spinner
end
|
#get_time_slot(time_str) ⇒ Object
164
165
166
167
|
# 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) ⇒ Object
115
116
117
118
|
# 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) ⇒ Object
111
112
113
|
# 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) ⇒ Object
120
121
122
123
124
125
126
127
128
129
130
|
# 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 ⇒ Object
29
30
31
32
33
34
35
36
37
|
# 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!") end
|
#select_room_option(booking_form, page) ⇒ Object
Select the form otpion with right room id
59
60
61
62
63
64
65
66
67
|
# 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) ⇒ Object
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
# 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") 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) ⇒ Object
176
177
178
179
|
# 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) ⇒ Object
Turn typhoneus obj to mechanize page obj
103
104
105
106
107
108
109
|
# 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
|