merged master into disable_rfcs
This commit is contained in:
@ -13,7 +13,7 @@ module SubmissionScoring
|
||||
submission.exercise.execution_environment.error_templates.each do |template|
|
||||
pattern = Regexp.new(template.signature).freeze
|
||||
if pattern.match(testrun_output)
|
||||
StructuredError.create_from_template(template, testrun_output)
|
||||
StructuredError.create_from_template(template, testrun_output, submission)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -1,7 +1,7 @@
|
||||
class ExerciseCollectionsController < ApplicationController
|
||||
include CommonBehavior
|
||||
|
||||
before_action :set_exercise_collection, only: [:show, :edit, :update, :destroy]
|
||||
before_action :set_exercise_collection, only: [:show, :edit, :update, :destroy, :statistics]
|
||||
|
||||
def index
|
||||
@exercise_collections = ExerciseCollection.all.paginate(:page => params[:page])
|
||||
@ -9,6 +9,7 @@ class ExerciseCollectionsController < ApplicationController
|
||||
end
|
||||
|
||||
def show
|
||||
@exercises = @exercise_collection.exercises.paginate(:page => params[:page])
|
||||
end
|
||||
|
||||
def new
|
||||
@ -34,6 +35,9 @@ class ExerciseCollectionsController < ApplicationController
|
||||
update_and_respond(object: @exercise_collection, params: exercise_collection_params)
|
||||
end
|
||||
|
||||
def statistics
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_exercise_collection
|
||||
@ -46,6 +50,6 @@ class ExerciseCollectionsController < ApplicationController
|
||||
end
|
||||
|
||||
def exercise_collection_params
|
||||
params[:exercise_collection].permit(:name, :exercise_ids => [])
|
||||
params[:exercise_collection].permit(:name, :use_anomaly_detection, :user_id, :user_type, :exercise_ids => []).merge(user_type: InternalUser.name)
|
||||
end
|
||||
end
|
||||
|
@ -346,6 +346,16 @@ class ExercisesController < ApplicationController
|
||||
|
||||
def statistics
|
||||
if(@external_user)
|
||||
@submissions = Submission.where("user_id = ? AND exercise_id = ?", @external_user.id, @exercise.id).order("created_at")
|
||||
@submissions_and_interventions = (@submissions + UserExerciseIntervention.where("user_id = ? AND exercise_id = ?", @external_user.id, @exercise.id)).sort_by { |a| a.created_at }
|
||||
deltas = @submissions.map.with_index do |item, index|
|
||||
delta = item.created_at - @submissions[index - 1].created_at if index > 0
|
||||
if delta == nil or delta > 10 * 60 then 0 else delta end
|
||||
end
|
||||
@working_times_until = []
|
||||
@submissions_and_interventions.each_with_index do |submission, index|
|
||||
@working_times_until.push((Time.at(deltas[1..index].inject(:+)).utc.strftime("%H:%M:%S") if index > 0))
|
||||
end
|
||||
render 'exercises/external_users/statistics'
|
||||
else
|
||||
user_statistics = {}
|
||||
|
59
app/controllers/statistics_controller.rb
Normal file
59
app/controllers/statistics_controller.rb
Normal file
@ -0,0 +1,59 @@
|
||||
class StatisticsController < ApplicationController
|
||||
include StatisticsHelper
|
||||
|
||||
before_action :authorize!, only: [:show, :graphs, :user_activity, :user_activity_history, :rfc_activity,
|
||||
:rfc_activity_history]
|
||||
|
||||
def policy_class
|
||||
StatisticsPolicy
|
||||
end
|
||||
|
||||
def show
|
||||
respond_to do |format|
|
||||
format.html
|
||||
format.json { render(json: statistics_data) }
|
||||
end
|
||||
end
|
||||
|
||||
def graphs
|
||||
end
|
||||
|
||||
def user_activity
|
||||
respond_to do |format|
|
||||
format.json { render(json: user_activity_live_data) }
|
||||
end
|
||||
end
|
||||
|
||||
def user_activity_history
|
||||
respond_to do |format|
|
||||
format.html { render('activity_history', locals: {resource: :user}) }
|
||||
format.json { render_ranged_data :ranged_user_data}
|
||||
end
|
||||
end
|
||||
|
||||
def rfc_activity
|
||||
respond_to do |format|
|
||||
format.json { render(json: rfc_activity_data) }
|
||||
end
|
||||
end
|
||||
|
||||
def rfc_activity_history
|
||||
respond_to do |format|
|
||||
format.html { render('activity_history', locals: {resource: :rfc}) }
|
||||
format.json { render_ranged_data :ranged_rfc_data }
|
||||
end
|
||||
end
|
||||
|
||||
def render_ranged_data(data_source)
|
||||
interval = params[:interval].to_s.empty? ? 'year' : params[:interval]
|
||||
from = DateTime.strptime(params[:from], '%Y-%m-%d') rescue DateTime.new(0)
|
||||
to = DateTime.strptime(params[:to], '%Y-%m-%d') rescue DateTime.now
|
||||
render(json: self.send(data_source, interval, from, to))
|
||||
end
|
||||
|
||||
def authorize!
|
||||
authorize self
|
||||
end
|
||||
private :authorize!
|
||||
|
||||
end
|
@ -197,7 +197,8 @@ class SubmissionsController < ApplicationController
|
||||
|
||||
def kill_socket(tubesock)
|
||||
# search for errors and save them as StructuredError (for scoring runs see submission_scoring.rb)
|
||||
extract_errors
|
||||
errors = extract_errors
|
||||
send_hints(tubesock, errors)
|
||||
|
||||
# save the output of this "run" as a "testrun" (scoring runs are saved in submission_scoring.rb)
|
||||
save_run_output
|
||||
@ -284,14 +285,16 @@ class SubmissionsController < ApplicationController
|
||||
end
|
||||
|
||||
def extract_errors
|
||||
results = []
|
||||
unless @raw_output.blank?
|
||||
@submission.exercise.execution_environment.error_templates.each do |template|
|
||||
pattern = Regexp.new(template.signature).freeze
|
||||
if pattern.match(@raw_output)
|
||||
StructuredError.create_from_template(template, @raw_output, @submission)
|
||||
results << StructuredError.create_from_template(template, @raw_output, @submission)
|
||||
end
|
||||
end
|
||||
end
|
||||
results
|
||||
end
|
||||
|
||||
def score
|
||||
@ -303,11 +306,22 @@ class SubmissionsController < ApplicationController
|
||||
# to ensure responsiveness, we therefore open a thread here.
|
||||
Thread.new {
|
||||
tubesock.send_data JSON.dump(score_submission(@submission))
|
||||
|
||||
# To enable hints when scoring a submission, uncomment the next line:
|
||||
#send_hints(tubesock, StructuredError.where(submission: @submission))
|
||||
|
||||
tubesock.send_data JSON.dump({'cmd' => 'exit'})
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def send_hints(tubesock, errors)
|
||||
errors = errors.to_a.uniq { |e| e.hint}
|
||||
errors.each do | error |
|
||||
tubesock.send_data JSON.dump({cmd: 'hint', hint: error.hint, description: error.error_template.description})
|
||||
end
|
||||
end
|
||||
|
||||
def set_docker_client
|
||||
@docker_client = DockerClient.new(execution_environment: @submission.execution_environment)
|
||||
end
|
||||
|
@ -69,7 +69,8 @@ class UserExerciseFeedbacksController < ApplicationController
|
||||
@texts = comment_presets.to_a
|
||||
@times = time_presets.to_a
|
||||
@uef = UserExerciseFeedback.new
|
||||
@exercise = Exercise.find(params[:user_exercise_feedback][:exercise_id])
|
||||
exercise_id = if params[:user_exercise_feedback].nil? then params[:exercise_id] else params[:user_exercise_feedback][:exercise_id] end
|
||||
@exercise = Exercise.find(exercise_id)
|
||||
authorize!
|
||||
end
|
||||
|
||||
|
Reference in New Issue
Block a user