Files
codeocean/app/controllers/exercises_controller.rb

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