Add events for pair programming study

This commit is contained in:
kiragrammel
2023-09-04 23:57:30 +02:00
committed by Sebastian Serth
parent d1d5b0df6f
commit 79422225a8
15 changed files with 224 additions and 15 deletions

View File

@@ -32,6 +32,7 @@ module CodeOcean
has_many :files, class_name: 'CodeOcean::File'
has_many :testruns
has_many :comments
has_many :events_synchronized_editor, class_name: 'Event::SynchronizedEditor'
alias descendants files
mount_uploader :native_file, FileUploader

View File

@@ -3,8 +3,19 @@
class Event < ApplicationRecord
include Creation
belongs_to :exercise
belongs_to :file, class_name: 'CodeOcean::File'
belongs_to :file, class_name: 'CodeOcean::File', optional: true
belongs_to :study_group, optional: true
belongs_to :programming_group, optional: true
validates :category, presence: true
validates :data, presence: true
# We temporary allow an event to be stored without data.
# This is useful if the category (together with the user and exercise) is already enough.
validates :data, presence: true, if: -> { %w[pp_start_chat pp_invalid_partners pp_work_alone].exclude?(category) }
before_validation :data_presence
def data_presence
self.data = data.presence
end
end

View File

@@ -0,0 +1,92 @@
# frozen_string_literal: true
class Event::SynchronizedEditor < ApplicationRecord
self.table_name = 'events_synchronized_editor'
include Creation
belongs_to :programming_group
belongs_to :study_group
belongs_to :file, class_name: 'CodeOcean::File'
enum command: {
editor_change: 0,
connection_change: 1,
hello: 2,
### TODO: Kira's commands
}, _prefix: true
enum status: {
connected: 0,
disconnected: 1,
### TODO: connected, disconnected ...
}, _prefix: true
enum action: {
insertText: 0,
insertLines: 1,
removeText: 2,
removeLines: 3,
changeFold: 4,
removeFold: 5,
### TODO: AceEditor Actions: insertText, insertLines, removeText, removesLines, ...
}, _prefix: true
validates :status, presence: true, if: -> { command_connection_change? }
validates :action, presence: true, if: -> { command_editor_change? }
validates :range_start_row, numericality: {only_integer: true, greater_than_or_equal_to: 0}, if: -> { command_editor_change? }
validates :range_start_column, numericality: {only_integer: true, greater_than_or_equal_to: 0}, if: -> { command_editor_change? }
validates :range_end_row, numericality: {only_integer: true, greater_than_or_equal_to: 0}, if: -> { command_editor_change? }
validates :range_end_column, numericality: {only_integer: true, greater_than_or_equal_to: 0}, if: -> { command_editor_change? }
validates :nl, inclusion: {in: %W[\n \r\n]}, if: -> { action_removeLines? }
validate :either_lines_or_text
def self.create_for_editor_change(event, user, programming_group)
event_copy = event.deep_dup
file = event_copy.delete(:active_file)
delta = event_copy.delete(:delta)[:data]
range = delta.delete(:range)
create!(
user:,
programming_group:,
study_group_id: user.current_study_group_id,
command: event_copy.delete(:command),
action: delta.delete(:action),
file_id: file[:id],
range_start_row: range[:start][:row],
range_start_column: range[:start][:column],
range_end_row: range[:end][:row],
range_end_column: range[:end][:column],
text: delta.delete(:text),
nl: delta.delete(:nl),
lines: delta.delete(:lines),
data: data_attribute(event_copy, delta)
)
end
def self.data_attribute(event, delta)
event[:delta] = {data: delta} if delta.present?
event.presence if event.present? # TODO: As of now, we are storing the `current_user_id` most of the times. Intended?
end
private_class_method :data_attribute
private
def strip_strings
# trim whitespace from beginning and end of string attributes
# except the `text` and `nl` of Event::SynchronizedEditor
attribute_names.without('text', 'nl').each do |name|
if send(name.to_sym).respond_to?(:strip)
send("#{name}=".to_sym, send(name).strip)
end
end
end
def either_lines_or_text
if [lines, text].count(&:present?) > 1
errors.add(:text, "can't be present if lines is also present")
end
end
end

View File

@@ -9,6 +9,8 @@ class ProgrammingGroup < ApplicationRecord
has_many :internal_users, through: :programming_group_memberships, source_type: 'InternalUser', source: :user
has_many :testruns, through: :submissions
has_many :runners, as: :contributor, dependent: :destroy
has_many :events
has_many :events_synchronized_editor, class_name: 'Event::SynchronizedEditor'
belongs_to :exercise
validate :min_group_size

View File

@@ -9,6 +9,8 @@ class StudyGroup < ApplicationRecord
has_many :subscriptions, dependent: :nullify
has_many :authentication_tokens, dependent: :nullify
has_many :lti_parameters, dependent: :delete_all
has_many :events
has_many :events_synchronized_editor, class_name: 'Event::SynchronizedEditor'
belongs_to :consumer
def users