Compare commits

...

13 Commits

Author SHA1 Message Date
f81005408e Add functionality to set default live video URL
All checks were successful
Build and Publish Docker Container / build (push) Successful in 6m21s
A new method has been added to the `CoursesController` which allows admins to fill default live video URLs for online lectures that don't have one. This feature is accessible via a button on the courses admin page. The routing for this new action has also been set up.
2024-02-04 15:14:38 +00:00
c97041597b Add renumber lectures button 2024-02-04 15:05:12 +00:00
0a6a68b519 Add the ability to put actions at the bottom of the show page in administrate 2024-02-04 14:53:22 +00:00
d4aa63e66a Add default_live_video_url to the course dashboard 2024-02-04 14:28:21 +00:00
d5faecdd12 Fix the fill_in_default_live_video_url! method 2024-02-04 14:24:55 +00:00
e8e143355d Add online property and live video URL to lecture models, as well as a default value at the course level 2024-02-04 14:23:07 +00:00
4238e4fe4e Hide under-developed work items from the main screen 2024-02-04 14:07:03 +00:00
f0b458f6a1 Improve event summary parsing in course model
This commit refines event summary parsing in the course model. Instead of splitting the summary, it uses regular expressions to extract the unit code and short lecture title more accurately. The update also includes better handling of events that don't match this format.
2024-02-04 14:03:13 +00:00
49282a72bf Add new semester 2 courses 2024-02-04 13:49:44 +00:00
08b83e32ab Add uniqueness constraints to course properties 2024-02-04 13:38:05 +00:00
4485624f79 Add archived to dashboard and change homepage to only show active (ie not archived) courses 2024-02-04 13:35:28 +00:00
04566509dc Add archived property to courses 2024-02-04 13:31:50 +00:00
665713de49 Fix service urls 2024-02-04 13:31:35 +00:00
17 changed files with 198 additions and 15 deletions

View File

@ -1,5 +1,15 @@
module Admin
class CoursesController < Admin::ApplicationController
def renumber_lectures
requested_resource.renumber_lectures!
redirect_to admin_course_url(requested_resource), notice: "Lectures renumbered"
end
def fill_in_default_live_video_url
requested_resource.fill_in_default_live_video_url!
redirect_to admin_course_url(requested_resource), notice: "Filled in default live video URL"
end
# Overwrite any of the RESTful controller actions to implement custom behavior
# For example, you may want to send an email after a foo is updated.
#

View File

@ -1,16 +1,16 @@
class AttendanceTrackerController < ApplicationController
def index
@courses = Course.all.sort_by(&:title)
@courses = Course.active.sort_by(&:title)
@current_lecture = get_current_lecture
end
def overview
@courses = Course.all.sort_by(&:title)
@courses = Course.active.sort_by(&:title)
@current_lecture = get_current_lecture
end
def today
@courses = Course.all.sort_by(&:title)
@courses = Course.active.sort_by(&:title)
@date = Date.today
@current_lecture = get_current_lecture
@lectures = @courses.flat_map { |course| course.lectures.filter { |a| a.start_time.today? } }.sort_by { |l| l.start_time }

View File

@ -15,7 +15,9 @@ class CourseDashboard < Administrate::BaseDashboard
panopto_folders: Field::String.with_options(searchable: false),
semester_start_date: Field::Date,
title: Field::String,
archived: Field::Boolean,
homepage: Field::String,
default_live_video_url: Field::Url,
toggl_project: Field::Number,
unit_code: Field::String,
created_at: Field::DateTime,
@ -30,8 +32,10 @@ class CourseDashboard < Administrate::BaseDashboard
COLLECTION_ATTRIBUTES = %i[
title
unit_code
archived
homepage
lectures
default_live_video_url
work_items
recordings
].freeze
@ -42,11 +46,13 @@ class CourseDashboard < Administrate::BaseDashboard
id
title
unit_code
archived
homepage
panopto_folders
semester_start_date
toggl_project
lectures
default_live_video_url
work_items
recordings
created_at
@ -59,10 +65,12 @@ class CourseDashboard < Administrate::BaseDashboard
FORM_ATTRIBUTES = %i[
title
unit_code
archived
homepage
panopto_folders
semester_start_date
toggl_project
default_live_video_url
].freeze
# COLLECTION_FILTERS
@ -75,7 +83,10 @@ class CourseDashboard < Administrate::BaseDashboard
# COLLECTION_FILTERS = {
# open: ->(resources) { resources.where(open: true) }
# }.freeze
COLLECTION_FILTERS = {}.freeze
COLLECTION_FILTERS = {
archived: ->(resources) { resources.where(archived: true) },
active: ->(resources) { resources.where(archived: false) }
}.freeze
# Overwrite this method to customize how courses are displayed
# across all pages of the admin dashboard.

View File

@ -6,6 +6,8 @@ class Course < ApplicationRecord
# we them independently to avoid re-importing lectures.
has_many :recordings, dependent: :destroy
scope :active, -> { where(archived: false) }
def lectures_and_work_items
(lectures + work_items).sort_by(&:start_time)
end
@ -16,14 +18,15 @@ class Course < ApplicationRecord
calendar = calendars.first
events = calendar.events.map do |event|
# Example title include: PH40065B-Lab, PH40112-Lecc (Wk 19-25, 29-32), MA40049-Leca (LOIL), MA40049-Lecb
summary = event.summary
match = summary.split('-')
match = /(^\w\w\d{5})-(\w+)/.match(summary)
# Handle odd events we don't care about
next if match.length != 2
next if match.nil?
unit_code = match[0]
short_lecture_title = match[1]
unit_code = match[1]
short_lecture_title = match[2]
start_time = event.dtstart.to_time
event_uuid = event.uid.to_s
@ -38,6 +41,7 @@ class Course < ApplicationRecord
short_lecture_title:,
start_time:,
event_uuid:,
online: summary.include?("LOIL"),
}
end
@ -62,6 +66,12 @@ class Course < ApplicationRecord
title: title,
start_time: event[:start_time],
event_uuid: event[:event_uuid],
online: event[:online],
live_video_url: if event[:online]
self.default_live_video_url
else
nil
end,
)
end
end
@ -74,4 +84,9 @@ class Course < ApplicationRecord
end
end
end
def fill_in_default_live_video_url!
raise "No default live video URL set" if self.default_live_video_url.nil?
lectures.where(live_video_url: nil).update_all(live_video_url: self.default_live_video_url)
end
end

View File

@ -39,10 +39,6 @@ class Lecture < ApplicationRecord
tracked_time_entries.review.sum(&:duration).seconds
end
def live_video_url
nil
end
# NAIVE: Assumes that lectures are 50 minutes long, this is true currently but not assured.
def end_time
start_time + 50.hour

View File

@ -0,0 +1,72 @@
<%#
# Show
This view is the template for the show page.
It renders the attributes of a resource,
as well as a link to its edit page.
## Local variables:
- `page`:
An instance of [Administrate::Page::Show][1].
Contains methods for accessing the resource to be displayed on the page,
as well as helpers for describing how each attribute of the resource
should be displayed.
[1]: http://www.rubydoc.info/gems/administrate/Administrate/Page/Show
%>
<style>
.main-content {
display: flex;
flex-direction: column;
}
</style>
<% content_for(:title) { t("administrate.actions.show_resource", name: page.page_title) } %>
<header class="main-content__header">
<h1 class="main-content__page-title">
<%= content_for(:title) %>
</h1>
<div>
<%= link_to(
t("administrate.actions.edit_resource", name: page.page_title),
[:edit, namespace, page.resource],
class: "button",
) if accessible_action?(page.resource, :edit) %>
<%= link_to(
t("administrate.actions.destroy"),
[namespace, page.resource],
class: "button button--danger",
method: :delete,
data: { confirm: t("administrate.actions.confirm") }
) if accessible_action?(page.resource, :destroy) %>
</div>
</header>
<section class="main-content__body">
<dl>
<% page.attributes.each do |attribute| %>
<dt class="attribute-label" id="<%= attribute.name %>">
<%= t(
"helpers.label.#{resource_name}.#{attribute.name}",
default: page.resource.class.human_attribute_name(attribute.name),
) %>
</dt>
<dd class="attribute-data attribute-data--<%= attribute.html_class %>"
><%= render_field attribute, page: page %></dd>
<% end %>
</dl>
</section>
<section class="main-content__body">
<% actions_template = "admin/#{page.resource.class.name.downcase}/actions" %>
<% if lookup_context.template_exists?(actions_template, [], true) %>
<%= render actions_template, { page: } %>
<% end %>
</section>

View File

@ -0,0 +1,11 @@
<%= link_to(
"Renumber lectures",
[namespace, page.resource, :renumber_lectures],
class: "button",
) if accessible_action?(page.resource, :renumber_lectures) %>
<%= link_to(
"Fill in default live video URL",
[namespace, page.resource, :fill_in_default_live_video_url],
class: "button",
) if accessible_action?(page.resource, :fill_in_default_live_video_url) && page.resource.default_live_video_url.present? %>

View File

@ -30,7 +30,7 @@
</thead>
<tbody class="divide-y divide-gray-200 bg-white">
<% course.lectures_and_work_items.group_by { |lecture| lecture.week_number }.each do |(week_number, lectures)| %>
<% course.lectures.group_by { |lecture| lecture.week_number }.each do |(week_number, lectures)| %>
<tr class="border-t border-gray-200">
<th colspan="5" scope="colgroup" class="bg-gray-50 py-2 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">
<div class="flex flex-row justify-between">

View File

@ -1 +1,2 @@
START_OF_YEAR_5_SEMESTER_1 = Time.new('2023-10-02')
START_OF_YEAR_5_SEMESTER_2 = Time.new('2024-02-05')

View File

@ -1,3 +1,3 @@
# TODO: Is there a better way to do this?
TOGGL_PORTAL_URL = ENV['TOGGL_PORTAL_URL'] || 'http://localhost:3005'
TOGGL_PORTAL_URL = ENV['TOGGL_PORTAL_URL'] || 'http://cosmos:7001'
PANOPTO_PORTAL_URL = ENV['PANOPTO_PORTAL_URL'] || 'https://lectures.joshuacoles.me'

View File

@ -7,6 +7,9 @@ Rails.application.routes.draw do
resources :recordings
root to: "courses#index"
get '/courses/:id/renumber_lectures', to: 'courses#renumber_lectures', as: :course_renumber_lectures
get '/courses/:id/fill_in_default_live_video_url', to: 'courses#fill_in_default_live_video_url', as: :course_fill_in_default_live_video_url
end
root controller: :attendance_tracker, action: :index

View File

@ -0,0 +1,5 @@
class AddArchivedToCourse < ActiveRecord::Migration[7.1]
def change
add_column :courses, :archived, :boolean, default: false, null: false
end
end

View File

@ -0,0 +1,6 @@
class AddUniquenessToCourseProperties < ActiveRecord::Migration[7.1]
def change
add_index :courses, :unit_code, unique: true
add_index :courses, :toggl_project, unique: true
end
end

View File

@ -0,0 +1,5 @@
class AddDefaultLiveVideoUrlToCourse < ActiveRecord::Migration[7.1]
def change
add_column :courses, :default_live_video_url, :string
end
end

View File

@ -0,0 +1,6 @@
class AddOnlineAndLiveVideoUrlToLecture < ActiveRecord::Migration[7.1]
def change
add_column :lectures, :online, :boolean, default: false, null: false
add_column :lectures, :live_video_url, :string
end
end

8
db/schema.rb generated
View File

@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[7.1].define(version: 2023_10_08_153855) do
ActiveRecord::Schema[7.1].define(version: 2024_02_04_141120) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@ -23,6 +23,10 @@ ActiveRecord::Schema[7.1].define(version: 2023_10_08_153855) do
t.datetime "updated_at", null: false
t.date "semester_start_date", default: "2023-10-02"
t.string "homepage"
t.boolean "archived", default: false, null: false
t.string "default_live_video_url"
t.index ["toggl_project"], name: "index_courses_on_toggl_project", unique: true
t.index ["unit_code"], name: "index_courses_on_unit_code", unique: true
end
create_table "lectures", force: :cascade do |t|
@ -34,6 +38,8 @@ ActiveRecord::Schema[7.1].define(version: 2023_10_08_153855) do
t.string "event_uuid"
t.boolean "cancelled", default: false
t.integer "kind", default: 0
t.boolean "online", default: false, null: false
t.string "live_video_url"
t.index ["course_id"], name: "index_lectures_on_course_id"
end

View File

@ -37,3 +37,39 @@ Course.create!(
unit_code: 'MA40042',
semester_start_date: START_OF_YEAR_5_SEMESTER_1.to_date,
)
Course.create!(
title: 'Relativistic Cosmology',
panopto_folders: ["dca2c510-49b4-4a24-9c91-b07701022d03"],
toggl_project: 199383703,
unit_code: 'PH40112',
semester_start_date: START_OF_YEAR_5_SEMESTER_2.to_date,
homepage: 'https://moodle.bath.ac.uk/course/view.php?id=58189'
)
Course.create!(
title: 'Advanced Quantum Theory',
panopto_folders: [],
toggl_project: 199383691,
unit_code: 'PH40084',
semester_start_date: START_OF_YEAR_5_SEMESTER_2.to_date,
homepage: 'https://moodle.bath.ac.uk/course/view.php?id=30520'
)
Course.create!(
title: 'Analysis in Hilbert Spaces',
panopto_folders: [],
toggl_project: 199383698,
unit_code: 'MA40256',
semester_start_date: START_OF_YEAR_5_SEMESTER_2.to_date,
homepage: 'https://moodle.bath.ac.uk/course/view.php?id=57713'
)
Course.create!(
title: 'Elasticity',
panopto_folders: [],
toggl_project: 198859760,
unit_code: 'MA40049',
semester_start_date: START_OF_YEAR_5_SEMESTER_2.to_date,
homepage: 'https://moodle.bath.ac.uk/course/view.php?id=1814'
)