Move calendar scraping to a model method
This commit is contained in:
parent
ef3642678d
commit
0e0d26d06d
@ -1,71 +0,0 @@
|
||||
class ScrapeCalendarJob < ApplicationJob
|
||||
queue_as :default
|
||||
|
||||
def clean_up_lecture_title(unit_code, short_lecture_title) end
|
||||
|
||||
def perform(*args)
|
||||
ics_file = HTTParty.get("https://mytimetable.bath.ac.uk/ical?6519757b&group=false&timetable=!MjAyMyFzdHVkZW50c2V0ITRDRjQ5MjlGRTg1M0Q4N0MyMDZENTVDNUQ3QTJFNzk0&eu=amMzMDkxQGJhdGguYWMudWs=&h=MiuDbRiudE_Yf7B25v2SfEuFCtmYGkFb5sAUI3yGmtY=")
|
||||
calendars = Icalendar::Calendar.parse(ics_file)
|
||||
calendar = calendars.first
|
||||
|
||||
unit_codes = Course.all.map(&:unit_code)
|
||||
|
||||
events = calendar.events.map do |event|
|
||||
summary = event.summary
|
||||
match = summary.split('-')
|
||||
|
||||
# Handle odd events we don't care about
|
||||
next if match.length != 2
|
||||
|
||||
unit_code = match[0]
|
||||
short_lecture_title = match[1]
|
||||
start_time = event.dtstart.to_time
|
||||
event_uuid = event.uid.to_s
|
||||
|
||||
next if unit_code.nil? ||
|
||||
short_lecture_title.nil? ||
|
||||
event_uuid.nil? ||
|
||||
start_time.nil? ||
|
||||
!unit_code.in?(unit_codes)
|
||||
|
||||
{
|
||||
unit_code:,
|
||||
short_lecture_title:,
|
||||
start_time:,
|
||||
event_uuid:,
|
||||
}
|
||||
end
|
||||
|
||||
events
|
||||
.compact
|
||||
.filter { |attrs| attrs[:unit_code].in? unit_codes }
|
||||
.group_by { |attrs| attrs[:unit_code] }
|
||||
.map do |unit_code, course_events|
|
||||
course = Course.find_by(unit_code: unit_code)
|
||||
|
||||
lecture_counter = 0
|
||||
|
||||
course_events.each do |event|
|
||||
# Naive check to see if we've already created this lecture
|
||||
if course.lectures.find_by(event_uuid: event[:event_uuid]).present? || course.lectures.find_by(
|
||||
start_time: (event[:start_time].beginning_of_hour + 5.minutes)..(event[:start_time].beginning_of_hour + 1.hour + 5.minutes)
|
||||
).present?
|
||||
next
|
||||
end
|
||||
|
||||
if event[:short_lecture_title].starts_with? "Lec"
|
||||
lecture_counter += 1
|
||||
title = "Lecture #{lecture_counter}"
|
||||
else
|
||||
title = event[:short_lecture_title]
|
||||
end
|
||||
|
||||
course.lectures.create!(
|
||||
title: title,
|
||||
start_time: event[:start_time],
|
||||
event_uuid: event[:event_uuid],
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -4,4 +4,68 @@ class Course < ApplicationRecord
|
||||
# A course has a standalone connection to its recordings. To be shown they must be associated with a lecture but we
|
||||
# track those not associated with a lecture to avoid duplication.
|
||||
has_many :recordings, dependent: :destroy
|
||||
|
||||
def import_from_calendar!
|
||||
ics_file = HTTParty.get("https://mytimetable.bath.ac.uk/ical?6519757b&group=false&timetable=!MjAyMyFzdHVkZW50c2V0ITRDRjQ5MjlGRTg1M0Q4N0MyMDZENTVDNUQ3QTJFNzk0&eu=amMzMDkxQGJhdGguYWMudWs=&h=MiuDbRiudE_Yf7B25v2SfEuFCtmYGkFb5sAUI3yGmtY=")
|
||||
calendars = Icalendar::Calendar.parse(ics_file)
|
||||
calendar = calendars.first
|
||||
|
||||
events = calendar.events.map do |event|
|
||||
summary = event.summary
|
||||
match = summary.split('-')
|
||||
|
||||
# Handle odd events we don't care about
|
||||
next if match.length != 2
|
||||
|
||||
unit_code = match[0]
|
||||
short_lecture_title = match[1]
|
||||
start_time = event.dtstart.to_time
|
||||
event_uuid = event.uid.to_s
|
||||
|
||||
next if unit_code.nil? ||
|
||||
short_lecture_title.nil? ||
|
||||
event_uuid.nil? ||
|
||||
start_time.nil? ||
|
||||
unit_code != self.unit_code
|
||||
|
||||
{
|
||||
unit_code:,
|
||||
short_lecture_title:,
|
||||
start_time:,
|
||||
event_uuid:,
|
||||
}
|
||||
end
|
||||
|
||||
lecture_counter = 0
|
||||
|
||||
events.compact.each do |event|
|
||||
# Naive check to see if we've already created this lecture
|
||||
if lectures.find_by(event_uuid: event[:event_uuid]).present? || lectures.find_by(
|
||||
start_time: (event[:start_time].beginning_of_hour + 5.minutes)..(event[:start_time].beginning_of_hour + 1.hour + 5.minutes)
|
||||
).present?
|
||||
next
|
||||
end
|
||||
|
||||
if event[:short_lecture_title].starts_with? "Lec"
|
||||
lecture_counter += 1
|
||||
title = "Lecture #{lecture_counter}"
|
||||
else
|
||||
title = event[:short_lecture_title]
|
||||
end
|
||||
|
||||
lectures.create!(
|
||||
title: title,
|
||||
start_time: event[:start_time],
|
||||
event_uuid: event[:event_uuid],
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def renumber_lectures!
|
||||
lectures.group_by(&:kind).each do |kind, lectures|
|
||||
lectures.sort_by(&:start_time).each_with_index do |lecture, index|
|
||||
lecture.update!(title: "#{kind.to_s.humanize} #{index + 1}")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
class Lecture < ApplicationRecord
|
||||
belongs_to :course
|
||||
has_one :attendance
|
||||
has_one :recording
|
||||
has_one :attendance, dependent: :destroy
|
||||
has_one :recording, dependent: :nullify
|
||||
|
||||
enum :kind, [
|
||||
:lecture,
|
||||
|
||||
@ -24,10 +24,9 @@
|
||||
<th colspan="4" scope="colgroup" class="bg-gray-50 py-2 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">Week <%= week_number %></th>
|
||||
</tr>
|
||||
|
||||
<% lectures.each do |lecture| %>
|
||||
<% lectures.reject(&:cancelled).each do |lecture| %>
|
||||
<tr class="<%= class_names({
|
||||
'lecture-future': lecture.start_time.future?,
|
||||
'bg-slate-200': lecture.cancelled,
|
||||
'bg-green-100': lecture.attendance.present?,
|
||||
}) %>">
|
||||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-6">
|
||||
|
||||
@ -1,7 +0,0 @@
|
||||
require "test_helper"
|
||||
|
||||
class ScrapeCalendarJobTest < ActiveJob::TestCase
|
||||
# test "the truth" do
|
||||
# assert true
|
||||
# end
|
||||
end
|
||||
Loading…
Reference in New Issue
Block a user