@ -17,4 +17,8 @@ class InternalUser < ActiveRecord::Base
|
||||
activation_token? || reset_password_token?
|
||||
end
|
||||
private :password_void?
|
||||
|
||||
def teacher?
|
||||
role == 'teacher'
|
||||
end
|
||||
end
|
||||
|
4
app/models/testrun.rb
Normal file
4
app/models/testrun.rb
Normal file
@ -0,0 +1,4 @@
|
||||
class Testrun < ActiveRecord::Base
|
||||
belongs_to :file
|
||||
belongs_to :submission
|
||||
end
|
@ -1,4 +1,4 @@
|
||||
class ExecutionEnvironmentPolicy < AdminOrAuthorPolicy
|
||||
class ExecutionEnvironmentPolicy < AdminOnlyPolicy
|
||||
def author?
|
||||
@user == @record.author
|
||||
end
|
||||
|
@ -8,7 +8,11 @@ class ExercisePolicy < AdminOrAuthorPolicy
|
||||
admin?
|
||||
end
|
||||
|
||||
[:clone?, :destroy?, :edit?, :show?, :statistics?, :update?].each do |action|
|
||||
def show?
|
||||
@user.internal_user?
|
||||
end
|
||||
|
||||
[:clone?, :destroy?, :edit?, :statistics?, :update?].each do |action|
|
||||
define_method(action) { admin? || author? || team_member? }
|
||||
end
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
class ExternalUserPolicy < AdminOnlyPolicy
|
||||
def statistics?
|
||||
admin? || author? || team_member?
|
||||
admin?
|
||||
end
|
||||
end
|
||||
|
@ -1,4 +1,4 @@
|
||||
class FileTypePolicy < AdminOrAuthorPolicy
|
||||
class FileTypePolicy < AdminOnlyPolicy
|
||||
def author?
|
||||
@user == @record.author
|
||||
end
|
||||
|
@ -1,6 +1,6 @@
|
||||
class TeamPolicy < ApplicationPolicy
|
||||
[:create?, :index?, :new?].each do |action|
|
||||
define_method(action) { @user.internal_user? }
|
||||
define_method(action) { admin? }
|
||||
end
|
||||
|
||||
[:destroy?, :edit?, :show?, :update?].each do |action|
|
||||
|
@ -38,14 +38,17 @@ h1 = "#{@exercise} (external user #{@external_user})"
|
||||
table.table
|
||||
thead
|
||||
tr
|
||||
- ['.time', '.cause', '.score'].each do |title|
|
||||
- ['.time', '.cause', '.score', '.time_difference'].each do |title|
|
||||
th.header = t(title)
|
||||
tbody
|
||||
- submissions.each do |submission|
|
||||
- deltas = submissions.map.with_index {|item, index| delta = item.created_at - submissions[index - 1].created_at if index > 0; if delta == nil or delta > 30*60 then 0 else delta end}
|
||||
- submissions.each_with_index do |submission, index|
|
||||
tr data-id=submission.id
|
||||
td.clickable = submission.created_at.strftime("%F %T")
|
||||
td = submission.cause
|
||||
td = submission.score
|
||||
td = Time.at(deltas[1..index].inject(:+)).utc.strftime("%H:%M:%S") if index > 0
|
||||
p = t('.addendum')
|
||||
|
||||
- else
|
||||
p = t('.no_data_available')
|
||||
|
@ -27,17 +27,17 @@ h1 = Exercise.model_name.human(count: 2)
|
||||
- @exercises.each do |exercise|
|
||||
tr data-id=exercise.id
|
||||
td = exercise.title
|
||||
td = link_to(exercise.author, exercise.author)
|
||||
td = link_to(exercise.execution_environment, exercise.execution_environment)
|
||||
td = link_to_if(policy(exercise.author).show?, exercise.author, exercise.author)
|
||||
td = link_to_if(policy(exercise.execution_environment).show?, exercise.execution_environment, exercise.execution_environment)
|
||||
td = exercise.files.teacher_defined_tests.count
|
||||
td = exercise.maximum_score
|
||||
td.public data-value=exercise.public? = symbol_for(exercise.public?)
|
||||
td = link_to(t('shared.show'), exercise)
|
||||
td = link_to(t('shared.edit'), edit_exercise_path(exercise))
|
||||
td = link_to(t('shared.destroy'), exercise, data: {confirm: t('shared.confirm_destroy')}, method: :delete)
|
||||
td = link_to(t('.clone'), clone_exercise_path(exercise), data: {confirm: t('shared.confirm_destroy')}, method: :post)
|
||||
td = link_to(t('.implement'), implement_exercise_path(exercise))
|
||||
td = link_to(t('shared.statistics'), statistics_exercise_path(exercise))
|
||||
td = link_to(t('shared.show'), exercise) if policy(exercise).show?
|
||||
td = link_to(t('shared.edit'), edit_exercise_path(exercise)) if policy(exercise).edit?
|
||||
td = link_to(t('shared.destroy'), exercise, data: {confirm: t('shared.confirm_destroy')}, method: :delete) if policy(exercise).destroy?
|
||||
td = link_to(t('.clone'), clone_exercise_path(exercise), data: {confirm: t('shared.confirm_destroy')}, method: :post) if policy(exercise).clone?
|
||||
td = link_to(t('.implement'), implement_exercise_path(exercise)) if policy(exercise).implement?
|
||||
td = link_to(t('shared.statistics'), statistics_exercise_path(exercise)) if policy(exercise).statistics?
|
||||
|
||||
= render('shared/pagination', collection: @exercises)
|
||||
p = render('shared/new_button', model: Exercise)
|
@ -4,12 +4,13 @@
|
||||
|
||||
h1
|
||||
= @exercise
|
||||
- if policy(@exercise).edit?
|
||||
= render('shared/edit_button', object: @exercise)
|
||||
|
||||
= row(label: 'exercise.title', value: @exercise.title)
|
||||
= row(label: 'exercise.user', value: link_to(@exercise.author, @exercise.author))
|
||||
= row(label: 'exercise.user', value: link_to_if(policy(@exercise.author).show?, @exercise.author, @exercise.author))
|
||||
= row(label: 'exercise.description', value: @exercise.description)
|
||||
= row(label: 'exercise.execution_environment', value: link_to(@exercise.execution_environment, @exercise.execution_environment))
|
||||
= row(label: 'exercise.execution_environment', value: link_to_if(policy(@exercise.execution_environment).show?, @exercise.execution_environment, @exercise.execution_environment))
|
||||
= row(label: 'exercise.instructions', value: render_markdown(@exercise.instructions))
|
||||
= row(label: 'exercise.team', value: @exercise.team ? link_to(@exercise.team, @exercise.team) : nil)
|
||||
= row(label: 'exercise.maximum_score', value: @exercise.maximum_score)
|
||||
@ -26,5 +27,6 @@ ul.list-unstyled
|
||||
.panel-heading
|
||||
h3.panel-title = file.name_with_extension
|
||||
.panel-body
|
||||
- if policy(file).destroy?
|
||||
.clearfix = link_to(t('shared.destroy'), file, class:'btn btn-warning btn-sm pull-right', data: {confirm: t('shared.confirm_destroy')}, method: :delete)
|
||||
= render('shared/file', file: file)
|
||||
|
@ -22,8 +22,9 @@ h1 = @exercise
|
||||
tbody
|
||||
- @exercise.send(symbol).distinct().each do |user|
|
||||
- if user_statistics[user.id] then us = user_statistics[user.id] else us = {"maximum_score" => nil, "runs" => nil}
|
||||
- label = current_user.teacher? ? "#{user.name}" : "#{user.name} (#{user.email})"
|
||||
tr
|
||||
td = link_to_if symbol==:external_users, "#{user.name} (#{user.email})", {controller: "exercises", action: "statistics", external_user_id: user.id, id: @exercise.id}
|
||||
td = link_to_if symbol==:external_users, label, {controller: "exercises", action: "statistics", external_user_id: user.id, id: @exercise.id}
|
||||
td = us['maximum_score'] or 0
|
||||
td = us['runs']
|
||||
td = @exercise.average_working_time_for(user.id) or 0
|
||||
|
@ -3,7 +3,7 @@ h1 = t('.title')
|
||||
- exercises = Exercise.where(:id => @user.submissions.group(:exercise_id).select(:exercise_id).distinct())
|
||||
|
||||
.table-responsive
|
||||
table.table
|
||||
table.table.table-striped.sortable
|
||||
thead
|
||||
tr
|
||||
- ['.exercise', '.score', '.runs', '.worktime'].each do |title|
|
||||
|
@ -1,6 +1,6 @@
|
||||
= row(label: 'file.name', value: file.name)
|
||||
= row(label: 'file.path', value: file.path)
|
||||
= row(label: 'file.file_type', value: link_to(file.file_type, file.file_type))
|
||||
= row(label: 'file.file_type', value: link_to_if(policy(file).show?, file.file_type, file.file_type))
|
||||
= row(label: 'file.role', value: file.role? ? t("files.roles.#{file.role}") : '')
|
||||
= row(label: 'file.hidden', value: file.hidden)
|
||||
= row(label: 'file.read_only', value: file.read_only)
|
||||
|
@ -269,6 +269,8 @@ de:
|
||||
time: Zeit
|
||||
cause: Grund
|
||||
score: Punktzahl
|
||||
time_difference: 'Arbeitszeit bis hier*'
|
||||
addendum: '* Differenzen von mehr als 30 Minuten werden ignoriert.'
|
||||
external_users:
|
||||
statistics:
|
||||
title: Statistiken für Externe Benutzer
|
||||
|
@ -269,6 +269,8 @@ en:
|
||||
time: Time
|
||||
cause: Cause
|
||||
score: Score
|
||||
time_difference: 'Working Time until here*'
|
||||
addendum: '* Deltas longer than 30 minutes are ignored.'
|
||||
external_users:
|
||||
statistics:
|
||||
title: External User Statistics
|
||||
|
13
db/migrate/20160302133540_create_testruns.rb
Normal file
13
db/migrate/20160302133540_create_testruns.rb
Normal file
@ -0,0 +1,13 @@
|
||||
class CreateTestruns < ActiveRecord::Migration
|
||||
def change
|
||||
create_table :testruns do |t|
|
||||
t.boolean :passed
|
||||
t.text :output
|
||||
|
||||
t.belongs_to :file
|
||||
t.belongs_to :submission
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
16
db/schema.rb
16
db/schema.rb
@ -11,7 +11,7 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20160204111716) do
|
||||
ActiveRecord::Schema.define(version: 20160302133540) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
@ -91,6 +91,8 @@ ActiveRecord::Schema.define(version: 20160204111716) do
|
||||
t.boolean "hide_file_tree"
|
||||
end
|
||||
|
||||
add_index "exercises", ["execution_environment_id"], name: "test3", using: :btree
|
||||
|
||||
create_table "external_users", force: true do |t|
|
||||
t.integer "consumer_id"
|
||||
t.string "email"
|
||||
@ -200,10 +202,22 @@ ActiveRecord::Schema.define(version: 20160204111716) do
|
||||
t.string "user_type"
|
||||
end
|
||||
|
||||
add_index "submissions", ["exercise_id"], name: "test1", where: "((user_type)::text = 'ExternalUser'::text)", using: :btree
|
||||
add_index "submissions", ["exercise_id"], name: "test2", using: :btree
|
||||
|
||||
create_table "teams", force: true do |t|
|
||||
t.string "name"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
end
|
||||
|
||||
create_table "testruns", force: true do |t|
|
||||
t.boolean "passed"
|
||||
t.text "output"
|
||||
t.integer "file_id"
|
||||
t.integer "submission_id"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
end
|
||||
|
||||
end
|
||||
|
Reference in New Issue
Block a user