153 lines
4.7 KiB
Ruby
153 lines
4.7 KiB
Ruby
class ExercisesController < ApplicationController
|
|
include Lti
|
|
include SubmissionParameters
|
|
include SubmissionScoring
|
|
|
|
before_action :handle_file_uploads, only: [:create, :update]
|
|
before_action :set_execution_environments, only: [:create, :edit, :new, :update]
|
|
before_action :set_exercise, only: MEMBER_ACTIONS + [:clone, :implement, :run, :statistics, :submit]
|
|
before_action :set_file_types, only: [:create, :edit, :new, :update]
|
|
|
|
def authorize!
|
|
authorize(@exercise || @exercises)
|
|
end
|
|
private :authorize!
|
|
|
|
def clone
|
|
exercise = @exercise.duplicate(public: false, user: current_user)
|
|
if exercise.save
|
|
redirect_to(exercise, notice: t('shared.object_cloned', model: Exercise.model_name.human))
|
|
else
|
|
flash[:danger] = t('shared.message_failure')
|
|
redirect_to(exercises_path)
|
|
end
|
|
end
|
|
|
|
def create
|
|
@exercise = Exercise.new(exercise_params)
|
|
authorize!
|
|
respond_to do |format|
|
|
if @exercise.save
|
|
format.html { redirect_to(@exercise, notice: t('shared.object_created', model: Exercise.model_name.human)) }
|
|
format.json { render(:show, location: @exercise, status: :created) }
|
|
else
|
|
format.html { render(:new) }
|
|
format.json { render(json: @exercise.errors, status: :unprocessable_entity) }
|
|
end
|
|
end
|
|
end
|
|
|
|
def destroy
|
|
@exercise.destroy
|
|
respond_to do |format|
|
|
format.html { redirect_to(exercises_url, notice: t('shared.object_destroyed', model: Exercise.model_name.human)) }
|
|
format.json { head(:no_content) }
|
|
end
|
|
end
|
|
|
|
def edit
|
|
end
|
|
|
|
def exercise_params
|
|
params[:exercise].permit(:description, :execution_environment_id, :file_id, :instructions, :public, :title, files_attributes: file_attributes).merge(user_id: current_user.id, user_type: current_user.class.name)
|
|
end
|
|
private :exercise_params
|
|
|
|
def handle_file_uploads
|
|
exercise_params[:files_attributes].try(:each) do |index, file_attributes|
|
|
if file_attributes[:content].respond_to?(:read)
|
|
file_params = params[:exercise][:files_attributes][index]
|
|
if FileType.find_by(id: file_attributes[:file_type_id]).try(:binary?)
|
|
file_params[:content] = nil
|
|
file_params[:native_file] = file_attributes[:content]
|
|
else
|
|
file_params[:content] = file_attributes[:content].read
|
|
end
|
|
end
|
|
end
|
|
end
|
|
private :handle_file_uploads
|
|
|
|
def implement
|
|
if Submission.exists?(exercise_id: @exercise.id, user_id: current_user.id)
|
|
@submission = Submission.where(exercise_id: @exercise.id, user_id: current_user.id).order('created_at DESC').first
|
|
@files = @submission.collect_files.select(&:visible)
|
|
else
|
|
@files = @exercise.files.visible
|
|
end
|
|
@files = @files.sort_by(&:name_with_extension)
|
|
end
|
|
|
|
def index
|
|
@search = policy_scope(Exercise).search(params[:q])
|
|
@exercises = @search.result.order(:title)
|
|
authorize!
|
|
end
|
|
|
|
def redirect_to_lti_return_path
|
|
path = lti_return_path(consumer_id: session[:consumer_id], submission_id: @submission.id, url: consumer_return_url(build_tool_provider(consumer: Consumer.find_by(id: session[:consumer_id]), parameters: session[:lti_parameters])))
|
|
respond_to do |format|
|
|
format.html { redirect_to(path) }
|
|
format.json { render(json: {redirect: path}) }
|
|
end
|
|
end
|
|
private :redirect_to_lti_return_path
|
|
|
|
def new
|
|
@exercise = Exercise.new
|
|
authorize!
|
|
end
|
|
|
|
def set_execution_environments
|
|
@execution_environments = ExecutionEnvironment.all.order(:name)
|
|
end
|
|
private :set_execution_environments
|
|
|
|
def set_exercise
|
|
@exercise = Exercise.find(params[:id])
|
|
authorize!
|
|
end
|
|
private :set_exercise
|
|
|
|
def set_file_types
|
|
@file_types = FileType.all.order(:name)
|
|
end
|
|
private :set_file_types
|
|
|
|
def show
|
|
end
|
|
|
|
def statistics
|
|
end
|
|
|
|
def submit
|
|
@submission = Submission.create(submission_params)
|
|
score_submission(@submission)
|
|
if lti_outcome_service?
|
|
response = send_score(@submission.normalized_score)
|
|
if response[:status] == 'success'
|
|
redirect_to_lti_return_path
|
|
else
|
|
respond_to do |format|
|
|
format.html { redirect_to(implement_exercise_path(@submission.exercise)) }
|
|
format.json { render(json: {message: I18n.t('exercises.submit.failure')}, status: 503) }
|
|
end
|
|
end
|
|
else
|
|
redirect_to_lti_return_path
|
|
end
|
|
end
|
|
|
|
def update
|
|
respond_to do |format|
|
|
if @exercise.update(exercise_params)
|
|
format.html { redirect_to(@exercise, notice: t('shared.object_updated', model: Exercise.model_name.human)) }
|
|
format.json { render(:show, location: @exercise, status: :ok) }
|
|
else
|
|
format.html { render(:edit) }
|
|
format.json { render(json: @exercise.errors, status: :unprocessable_entity) }
|
|
end
|
|
end
|
|
end
|
|
end
|