diff --git a/app/controllers/exercises_controller.rb b/app/controllers/exercises_controller.rb index 750028c0..8a9ed527 100644 --- a/app/controllers/exercises_controller.rb +++ b/app/controllers/exercises_controller.rb @@ -123,7 +123,7 @@ class ExercisesController < ApplicationController uuid = params[:uuid] exercise = Exercise.find_by(uuid: uuid) - return render json: {exercise_found: false, message: 'no_exercise'} if exercise.nil? + return render json: {exercise_found: false, message: t('exercises.export_codeharbor.check.no_exercise')} if exercise.nil? render json: {exercise_found: true, message: 'exercise found, be careful when overwriting or else!'} end @@ -136,13 +136,14 @@ class ExercisesController < ApplicationController user = user_for_oauth2_request return render json: {}, status: 401 if user.nil? - exercise = ProformaService::Import.call(zip: tempfile, user: user) - if exercise.save - render json: {}, status: 201 - else - logger.info(exercise.errors.full_messages) - render json: {}, status: 400 + exercise = nil + ActiveRecord::Base.transaction do + exercise = ::ProformaService::Import.call(zip: tempfile, user: user) + exercise.save! + return render json: {}, status: 201 end + logger.info(exercise.errors.full_messages) + render json: {}, status: 400 end def user_for_oauth2_request diff --git a/app/models/code_ocean/file.rb b/app/models/code_ocean/file.rb index a68b585b..91ad6e54 100644 --- a/app/models/code_ocean/file.rb +++ b/app/models/code_ocean/file.rb @@ -7,6 +7,7 @@ module CodeOcean def validate(record) existing_files = File.where(name: record.name, path: record.path, file_type_id: record.file_type_id, context_id: record.context_id, context_type: record.context_type).to_a + unless existing_files.empty? if (not record.context.is_a?(Exercise)) || (record.context.new_record?) record.errors[:base] << 'Duplicate' diff --git a/app/models/exercise.rb b/app/models/exercise.rb index 05e69dcf..f975c45e 100644 --- a/app/models/exercise.rb +++ b/app/models/exercise.rb @@ -35,13 +35,13 @@ class Exercise < ApplicationRecord validates :public, boolean_presence: true validates :title, presence: true validates :token, presence: true, uniqueness: true + validates_uniqueness_of :uuid @working_time_statistics = nil attr_reader :working_time_statistics MAX_EXERCISE_FEEDBACKS = 20 - def average_percentage if average_score and maximum_score != 0.0 and submissions.exists?(cause: 'submit') (average_score / maximum_score * 100).round(2) diff --git a/app/services/proforma_service/import.rb b/app/services/proforma_service/import.rb index a4558870..7ab31055 100644 --- a/app/services/proforma_service/import.rb +++ b/app/services/proforma_service/import.rb @@ -11,8 +11,12 @@ module ProformaService if single_task? importer = Proforma::Importer.new(@zip) @task = importer.perform - exercise = ConvertTaskToExercise.call(task: @task, user: @user) - exercise.save! + + exercise = Exercise.find_by(uuid: @task.uuid) + exercise_files = exercise&.files&.to_a + + exercise = ConvertTaskToExercise.call(task: @task, user: @user, exercise: exercise) + exercise_files&.each(&:destroy) # feels suboptimal exercise else diff --git a/config/locales/en.yml b/config/locales/en.yml index 6b8b243f..af6f191d 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -317,9 +317,11 @@ en: editor_file_tree: file_root: Files export_codeharbor: + check: + no_exercise: No exercise found + fail: Failed to push the exercise to CodeHarbor. label: Export to Codeharbor success: Successfully pushed the exercise to CodeHarbor. - fail: Failed to push the exercise to CodeHarbor. file_form: hints: feedback_message: This message is used as a hint for failing tests.