Update lecture properties and various migration changes
Modified code to remove 'status' field from lecture's table and added 'event_uuid' field. Also refined the 'start_time' field in recordings' table to handle datetime instead of strings. Further, made minor changes in scraping jobs and seeding logic. Implemented these changes to allow lectures to be associated with calendar events and streamlined various fields.
This commit is contained in:
parent
070816f0a2
commit
d9d182bc94
1
Gemfile
1
Gemfile
@ -77,3 +77,4 @@ gem "httparty"
|
||||
|
||||
gem "sidekiq"
|
||||
gem "icalendar"
|
||||
gem "administrate"
|
||||
|
||||
33
Gemfile.lock
33
Gemfile.lock
@ -68,6 +68,14 @@ GEM
|
||||
tzinfo (~> 2.0)
|
||||
addressable (2.8.5)
|
||||
public_suffix (>= 2.0.2, < 6.0)
|
||||
administrate (0.19.0)
|
||||
actionpack (>= 5.0)
|
||||
actionview (>= 5.0)
|
||||
activerecord (>= 5.0)
|
||||
jquery-rails (>= 4.0)
|
||||
kaminari (>= 1.0)
|
||||
sassc-rails (~> 2.1)
|
||||
selectize-rails (~> 0.6)
|
||||
bindex (0.8.1)
|
||||
bootsnap (1.16.0)
|
||||
msgpack (~> 1.2)
|
||||
@ -112,6 +120,22 @@ GEM
|
||||
jbuilder (2.11.5)
|
||||
actionview (>= 5.0.0)
|
||||
activesupport (>= 5.0.0)
|
||||
jquery-rails (4.6.0)
|
||||
rails-dom-testing (>= 1, < 3)
|
||||
railties (>= 4.2.0)
|
||||
thor (>= 0.14, < 2.0)
|
||||
kaminari (1.2.2)
|
||||
activesupport (>= 4.1.0)
|
||||
kaminari-actionview (= 1.2.2)
|
||||
kaminari-activerecord (= 1.2.2)
|
||||
kaminari-core (= 1.2.2)
|
||||
kaminari-actionview (1.2.2)
|
||||
actionview
|
||||
kaminari-core (= 1.2.2)
|
||||
kaminari-activerecord (1.2.2)
|
||||
activerecord
|
||||
kaminari-core (= 1.2.2)
|
||||
kaminari-core (1.2.2)
|
||||
loofah (2.21.3)
|
||||
crass (~> 1.0.2)
|
||||
nokogiri (>= 1.12.0)
|
||||
@ -190,6 +214,13 @@ GEM
|
||||
rubyzip (2.3.2)
|
||||
sassc (2.4.0)
|
||||
ffi (~> 1.9)
|
||||
sassc-rails (2.1.2)
|
||||
railties (>= 4.0.0)
|
||||
sassc (>= 2.0)
|
||||
sprockets (> 3.0)
|
||||
sprockets-rails
|
||||
tilt
|
||||
selectize-rails (0.12.6)
|
||||
selenium-webdriver (4.10.0)
|
||||
rexml (~> 3.2, >= 3.2.5)
|
||||
rubyzip (>= 1.2.2, < 3.0)
|
||||
@ -212,6 +243,7 @@ GEM
|
||||
tailwindcss-rails (2.0.30-arm64-darwin)
|
||||
railties (>= 6.0.0)
|
||||
thor (1.2.2)
|
||||
tilt (2.3.0)
|
||||
timeout (0.4.0)
|
||||
turbo-rails (1.4.0)
|
||||
actionpack (>= 6.0.0)
|
||||
@ -240,6 +272,7 @@ PLATFORMS
|
||||
arm64-darwin-22
|
||||
|
||||
DEPENDENCIES
|
||||
administrate
|
||||
bootsnap
|
||||
capybara
|
||||
debug
|
||||
|
||||
@ -11,6 +11,7 @@ class CourseDashboard < Administrate::BaseDashboard
|
||||
id: Field::Number,
|
||||
lectures: Field::HasMany,
|
||||
panopto_folders: Field::String.with_options(searchable: false),
|
||||
semester_start_date: Field::Date,
|
||||
title: Field::String,
|
||||
toggl_project: Field::Number,
|
||||
unit_code: Field::String,
|
||||
@ -27,7 +28,7 @@ class CourseDashboard < Administrate::BaseDashboard
|
||||
id
|
||||
lectures
|
||||
panopto_folders
|
||||
title
|
||||
semester_start_date
|
||||
].freeze
|
||||
|
||||
# SHOW_PAGE_ATTRIBUTES
|
||||
@ -36,6 +37,7 @@ class CourseDashboard < Administrate::BaseDashboard
|
||||
id
|
||||
lectures
|
||||
panopto_folders
|
||||
semester_start_date
|
||||
title
|
||||
toggl_project
|
||||
unit_code
|
||||
@ -49,6 +51,7 @@ class CourseDashboard < Administrate::BaseDashboard
|
||||
FORM_ATTRIBUTES = %i[
|
||||
lectures
|
||||
panopto_folders
|
||||
semester_start_date
|
||||
title
|
||||
toggl_project
|
||||
unit_code
|
||||
|
||||
@ -11,9 +11,9 @@ class LectureDashboard < Administrate::BaseDashboard
|
||||
id: Field::Number,
|
||||
attendance: Field::HasOne,
|
||||
course: Field::BelongsTo,
|
||||
recording_id: Field::String,
|
||||
event_uuid: Field::String,
|
||||
recording: Field::BelongsTo,
|
||||
start_time: Field::DateTime,
|
||||
status: Field::Select.with_options(searchable: false, collection: ->(field) { field.resource.class.send(field.attribute.to_s.pluralize).keys }),
|
||||
title: Field::String,
|
||||
created_at: Field::DateTime,
|
||||
updated_at: Field::DateTime,
|
||||
@ -28,7 +28,7 @@ class LectureDashboard < Administrate::BaseDashboard
|
||||
id
|
||||
attendance
|
||||
course
|
||||
recording_id
|
||||
event_uuid
|
||||
].freeze
|
||||
|
||||
# SHOW_PAGE_ATTRIBUTES
|
||||
@ -37,9 +37,9 @@ class LectureDashboard < Administrate::BaseDashboard
|
||||
id
|
||||
attendance
|
||||
course
|
||||
recording_id
|
||||
event_uuid
|
||||
recording
|
||||
start_time
|
||||
status
|
||||
title
|
||||
created_at
|
||||
updated_at
|
||||
@ -51,9 +51,9 @@ class LectureDashboard < Administrate::BaseDashboard
|
||||
FORM_ATTRIBUTES = %i[
|
||||
attendance
|
||||
course
|
||||
recording_id
|
||||
event_uuid
|
||||
recording
|
||||
start_time
|
||||
status
|
||||
title
|
||||
].freeze
|
||||
|
||||
|
||||
@ -1,21 +1,71 @@
|
||||
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
|
||||
|
||||
calendar.events.each do |event|
|
||||
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
|
||||
return if match.length != 2
|
||||
next if match.length != 2
|
||||
|
||||
unit_code = match[0]
|
||||
short_lecture_title = match[1]
|
||||
start_time = event.dtstart
|
||||
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
|
||||
|
||||
@ -27,13 +27,22 @@ class ScrapePanoptoJob < ApplicationJob
|
||||
|
||||
created.each do |new_recording_attrs|
|
||||
new_recording = Recording.new(new_recording_attrs)
|
||||
Lecture.create!(
|
||||
title: new_recording.nice_title,
|
||||
start_time: new_recording.start_time,
|
||||
course_id: new_recording.course_id,
|
||||
status: :undetermined,
|
||||
recording_id: new_recording.id
|
||||
)
|
||||
|
||||
# Find existing lecture to associate with this recording
|
||||
if (lecture = course.lectures.find_by(
|
||||
start_time: new_recording.start_time.beginning_of_hour + 15.minutes,
|
||||
recording_id: nil,
|
||||
))
|
||||
lecture.update!(recording_id: new_recording.id)
|
||||
else
|
||||
# Else create a new lecture
|
||||
Lecture.create!(
|
||||
title: new_recording.nice_title,
|
||||
start_time: new_recording.start_time,
|
||||
course_id: new_recording.course_id,
|
||||
recording_id: new_recording.id
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -3,15 +3,6 @@ class Lecture < ApplicationRecord
|
||||
has_one :attendance
|
||||
belongs_to :recording, optional: true
|
||||
|
||||
enum :status, [
|
||||
:undetermined,
|
||||
:future,
|
||||
:happening_now,
|
||||
:attended_in_person,
|
||||
:watched_recording,
|
||||
:missed,
|
||||
], default: :undetermined
|
||||
|
||||
def week_number
|
||||
((start_time.beginning_of_week - course.semester_start_date.to_time) / 1.week).floor + 1
|
||||
end
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
<% style = if lecture.start_time.future? then 'background: repeating-linear-gradient(45deg, #f3f4f6, #f3f4f6 10px, white 10px, white 20px);' else '' end %>
|
||||
<tr style="<%= style %>">
|
||||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-6">
|
||||
<%= lecture.recording.nice_title %>
|
||||
<%= lecture.title %>
|
||||
</td>
|
||||
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500">
|
||||
<%= lecture.start_time.to_fs(:dmy) %>
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
Rails.application.routes.draw do
|
||||
namespace :admin do
|
||||
resources :attendances
|
||||
resources :courses
|
||||
resources :lectures
|
||||
resources :attendances
|
||||
resources :courses
|
||||
resources :lectures
|
||||
|
||||
root to: "attendances#index"
|
||||
end
|
||||
|
||||
root to: "attendances#index"
|
||||
end
|
||||
root controller: :attendance_tracker, action: :index
|
||||
end
|
||||
|
||||
8
db/migrate/20231001180954_update_lecture_properties.rb
Normal file
8
db/migrate/20231001180954_update_lecture_properties.rb
Normal file
@ -0,0 +1,8 @@
|
||||
class UpdateLectureProperties < ActiveRecord::Migration[7.0]
|
||||
def change
|
||||
remove_column :lectures, :status
|
||||
|
||||
# Optional association with an event in the calendar
|
||||
add_column :lectures, :event_uuid, :string, null: true
|
||||
end
|
||||
end
|
||||
@ -0,0 +1,5 @@
|
||||
class ChangeRecordingStartTimeType < ActiveRecord::Migration[7.0]
|
||||
def change
|
||||
change_column :recordings, :start_time, :datetime, using: 'start_time::timestamp'
|
||||
end
|
||||
end
|
||||
6
db/schema.rb
generated
6
db/schema.rb
generated
@ -10,7 +10,7 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema[7.0].define(version: 2023_10_01_165128) do
|
||||
ActiveRecord::Schema[7.0].define(version: 2023_10_01_183712) do
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
|
||||
@ -36,18 +36,18 @@ ActiveRecord::Schema[7.0].define(version: 2023_10_01_165128) do
|
||||
create_table "lectures", force: :cascade do |t|
|
||||
t.string "title", null: false
|
||||
t.datetime "start_time", null: false
|
||||
t.integer "status", default: 0, null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.bigint "course_id"
|
||||
t.bigint "recording_id"
|
||||
t.string "event_uuid"
|
||||
t.index ["course_id"], name: "index_lectures_on_course_id"
|
||||
t.index ["recording_id"], name: "index_lectures_on_recording_id"
|
||||
end
|
||||
|
||||
create_table "recordings", force: :cascade do |t|
|
||||
t.string "title", null: false
|
||||
t.string "start_time", null: false
|
||||
t.datetime "start_time", null: false
|
||||
t.string "recording_uuid", null: false
|
||||
t.bigint "course_id", null: false
|
||||
t.datetime "created_at", null: false
|
||||
|
||||
16
db/seeds.rb
16
db/seeds.rb
@ -5,3 +5,19 @@
|
||||
#
|
||||
# movies = Movie.create([{ name: "Star Wars" }, { name: "Lord of the Rings" }])
|
||||
# Character.create(name: "Luke", movie: movies.first)
|
||||
|
||||
Course.create!(
|
||||
title: 'General Relativity',
|
||||
panopto_folders: ["5a77867a-236b-478f-9b0d-af2400ed0989"],
|
||||
toggl_project: 189467492,
|
||||
unit_code: 'PH30101',
|
||||
semester_start_date: Date.parse('2023-02-06'),
|
||||
)
|
||||
|
||||
Course.create!(
|
||||
title: 'Continuum mechanics',
|
||||
panopto_folders: ["dca2c510-49b4-4a24-9c91-b07701022d03"],
|
||||
toggl_project: 195482340,
|
||||
unit_code: 'MA30253',
|
||||
semester_start_date: START_OF_YEAR_5_SEMESTER_1.to_date,
|
||||
)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user