merge master
This commit is contained in:
@@ -19,6 +19,10 @@ $(function() {
|
||||
var SERVER_SEND_EVENT = 2;
|
||||
|
||||
var editors = [];
|
||||
var editor_for_file = new Map();
|
||||
var regex_for_language = new Map();
|
||||
var tracepositions_regex;
|
||||
|
||||
var active_file = undefined;
|
||||
var active_frame = undefined;
|
||||
var running = false;
|
||||
@@ -404,12 +408,18 @@ $(function() {
|
||||
editor.setTheme(THEME);
|
||||
editor.commands.bindKey("ctrl+alt+0", null);
|
||||
editors.push(editor);
|
||||
editor_for_file.set($(element).parent().data('filename'), editor);
|
||||
var session = editor.getSession();
|
||||
session.setMode($(element).data('mode'));
|
||||
session.setTabSize($(element).data('indent-size'));
|
||||
session.setUseSoftTabs(true);
|
||||
session.setUseWrapMode(true);
|
||||
|
||||
// set regex for parsing error traces based on the mode of the main file.
|
||||
if( $(element).parent().data('role') == "main_file"){
|
||||
tracepositions_regex = regex_for_language.get($(element).data('mode'));
|
||||
}
|
||||
|
||||
var file_id = $(element).data('id');
|
||||
|
||||
/*
|
||||
@@ -457,6 +467,12 @@ $(function() {
|
||||
$('#request-for-comments').on('click', requestComments);
|
||||
};
|
||||
|
||||
|
||||
var initializeRegexes = function(){
|
||||
regex_for_language.set("ace/mode/python", /File "(.+?)", line (\d+)/g);
|
||||
regex_for_language.set("ace/mode/java", /(.*\.java):(\d+):/g);
|
||||
}
|
||||
|
||||
var initializeTooltips = function() {
|
||||
$('[data-tooltip]').tooltip();
|
||||
};
|
||||
@@ -587,7 +603,7 @@ $(function() {
|
||||
} else if (output.stdout) {
|
||||
//if (output_mode_is_streaming){
|
||||
element.addClass('text-success').append(output.stdout);
|
||||
flowrOutputBuffer += output.stdout;
|
||||
// flowrOutputBuffer += output.stdout;
|
||||
//}else{
|
||||
// element.addClass('text-success');
|
||||
// element.data('content_buffer' , element.data('content_buffer') + output.stdout);
|
||||
@@ -876,7 +892,9 @@ $(function() {
|
||||
}
|
||||
|
||||
var showWorkspaceTab = function(event) {
|
||||
event.preventDefault();
|
||||
if(event){
|
||||
event.preventDefault();
|
||||
}
|
||||
showTab(0);
|
||||
};
|
||||
|
||||
@@ -1036,6 +1054,7 @@ $(function() {
|
||||
case 'exit':
|
||||
killWebsocketAndContainer();
|
||||
handleStderrOutputForFlowr();
|
||||
augmentStacktraceInOutput();
|
||||
break;
|
||||
case 'timeout':
|
||||
// just show the timeout message here. Another exit command is sent by the rails backend when the socket to the docker container closes.
|
||||
@@ -1047,6 +1066,41 @@ $(function() {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
var jumpToSourceLine = function(event){
|
||||
var file = $(event.target).data('file');
|
||||
var line = $(event.target).data('line');
|
||||
|
||||
showWorkspaceTab(null);
|
||||
// set active file ?!?!
|
||||
|
||||
var frame = $('div.frame[data-filename="' + file + '"]');
|
||||
showFrame(frame);
|
||||
|
||||
var editor = editor_for_file.get(file);
|
||||
editor.gotoLine(line, 0);
|
||||
|
||||
};
|
||||
|
||||
var augmentStacktraceInOutput = function() {
|
||||
if(tracepositions_regex){
|
||||
var element = $('#output>pre');
|
||||
var text = element.text();
|
||||
element.on( "click", "a", jumpToSourceLine);
|
||||
|
||||
var matches;
|
||||
|
||||
while(matches = tracepositions_regex.exec(text)){
|
||||
var frame = $('div.frame[data-filename="' + matches[1] + '"]')
|
||||
|
||||
if(frame.length > 0){
|
||||
element.html(text.replace(matches[0], "<a href='#' data-file='" + matches[1] + "' data-line='" + matches[2] + "'>" + matches[0] + "</a>"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
var renderWebsocketOutput = function(msg){
|
||||
var element = findOrCreateRenderElement(0);
|
||||
element.append(msg.data);
|
||||
@@ -1208,6 +1262,7 @@ $(function() {
|
||||
|
||||
if ($('#editor').isPresent()) {
|
||||
if (isBrowserSupported()) {
|
||||
initializeRegexes();
|
||||
initializeCodePilot();
|
||||
$('.score, #development-environment').show();
|
||||
configureEditors();
|
||||
|
@@ -9,7 +9,6 @@ class ExercisesController < ApplicationController
|
||||
before_action :set_exercise, only: MEMBER_ACTIONS + [:clone, :implement, :run, :statistics, :submit, :reload]
|
||||
before_action :set_external_user, only: [:statistics]
|
||||
before_action :set_file_types, only: [:create, :edit, :new, :update]
|
||||
before_action :set_teams, only: [:create, :edit, :new, :update]
|
||||
|
||||
skip_before_filter :verify_authenticity_token, only: [:import_proforma_xml]
|
||||
skip_after_action :verify_authorized, only: [:import_proforma_xml]
|
||||
@@ -119,7 +118,7 @@ class ExercisesController < ApplicationController
|
||||
private :user_by_code_harbor_token
|
||||
|
||||
def exercise_params
|
||||
params[:exercise].permit(:description, :execution_environment_id, :file_id, :instructions, :public, :hide_file_tree, :allow_file_creation, :team_id, :title, files_attributes: file_attributes).merge(user_id: current_user.id, user_type: current_user.class.name)
|
||||
params[:exercise].permit(:description, :execution_environment_id, :file_id, :instructions, :public, :hide_file_tree, :allow_file_creation, :title, files_attributes: file_attributes).merge(user_id: current_user.id, user_type: current_user.class.name)
|
||||
end
|
||||
private :exercise_params
|
||||
|
||||
@@ -195,11 +194,6 @@ class ExercisesController < ApplicationController
|
||||
end
|
||||
private :set_file_types
|
||||
|
||||
def set_teams
|
||||
@teams = Team.all.order(:name)
|
||||
end
|
||||
private :set_teams
|
||||
|
||||
def show
|
||||
end
|
||||
|
||||
|
@@ -1,51 +0,0 @@
|
||||
class TeamsController < ApplicationController
|
||||
include CommonBehavior
|
||||
|
||||
before_action :set_team, only: MEMBER_ACTIONS
|
||||
|
||||
def authorize!
|
||||
authorize(@team || @teams)
|
||||
end
|
||||
private :authorize!
|
||||
|
||||
def create
|
||||
@team = Team.new(team_params)
|
||||
authorize!
|
||||
create_and_respond(object: @team)
|
||||
end
|
||||
|
||||
def destroy
|
||||
destroy_and_respond(object: @team)
|
||||
end
|
||||
|
||||
def edit
|
||||
end
|
||||
|
||||
def index
|
||||
@teams = Team.all.includes(:internal_users).order(:name).paginate(page: params[:page])
|
||||
authorize!
|
||||
end
|
||||
|
||||
def new
|
||||
@team = Team.new
|
||||
authorize!
|
||||
end
|
||||
|
||||
def set_team
|
||||
@team = Team.find(params[:id])
|
||||
authorize!
|
||||
end
|
||||
private :set_team
|
||||
|
||||
def show
|
||||
end
|
||||
|
||||
def team_params
|
||||
params[:team].permit(:name, internal_user_ids: [])
|
||||
end
|
||||
private :team_params
|
||||
|
||||
def update
|
||||
update_and_respond(object: @team, params: team_params)
|
||||
end
|
||||
end
|
@@ -11,7 +11,6 @@ class Exercise < ActiveRecord::Base
|
||||
|
||||
belongs_to :execution_environment
|
||||
has_many :submissions
|
||||
belongs_to :team
|
||||
|
||||
has_many :external_users, source: :user, source_type: ExternalUser, through: :submissions
|
||||
has_many :internal_users, source: :user, source_type: InternalUser, through: :submissions
|
||||
|
@@ -3,8 +3,6 @@ class InternalUser < ActiveRecord::Base
|
||||
|
||||
authenticates_with_sorcery!
|
||||
|
||||
has_and_belongs_to_many :teams
|
||||
|
||||
validates :email, presence: true, uniqueness: true
|
||||
validates :password, confirmation: true, if: :password_void?, on: :update, presence: true
|
||||
validates :role, inclusion: {in: ROLES}
|
||||
|
@@ -1,10 +0,0 @@
|
||||
class Team < ActiveRecord::Base
|
||||
has_and_belongs_to_many :internal_users
|
||||
alias_method :members, :internal_users
|
||||
|
||||
validates :name, presence: true
|
||||
|
||||
def to_s
|
||||
name
|
||||
end
|
||||
end
|
@@ -13,24 +13,19 @@ class ExercisePolicy < AdminOrAuthorPolicy
|
||||
end
|
||||
|
||||
[:clone?, :destroy?, :edit?, :statistics?, :update?].each do |action|
|
||||
define_method(action) { admin? || author? || team_member? }
|
||||
define_method(action) { admin? || author?}
|
||||
end
|
||||
|
||||
[:implement?, :submit?, :reload?].each do |action|
|
||||
define_method(action) { everyone }
|
||||
end
|
||||
|
||||
def team_member?
|
||||
@record.team.try(:members, []).include?(@user) if @record.team
|
||||
end
|
||||
private :team_member?
|
||||
|
||||
class Scope < Scope
|
||||
def resolve
|
||||
if @user.admin?
|
||||
@scope.all
|
||||
elsif @user.internal_user?
|
||||
@scope.where('user_id = ? OR public = TRUE OR (team_id IS NOT NULL AND team_id IN (SELECT t.id FROM teams t JOIN internal_users_teams iut ON t.id = iut.team_id WHERE iut.internal_user_id = ?))', @user.id, @user.id)
|
||||
@scope.where('user_id = ? OR public = TRUE', @user.id)
|
||||
else
|
||||
@scope.none
|
||||
end
|
||||
|
@@ -1,14 +0,0 @@
|
||||
class TeamPolicy < ApplicationPolicy
|
||||
[:create?, :index?, :new?].each do |action|
|
||||
define_method(action) { admin? }
|
||||
end
|
||||
|
||||
[:destroy?, :edit?, :show?, :update?].each do |action|
|
||||
define_method(action) { admin? || member? }
|
||||
end
|
||||
|
||||
def member?
|
||||
@record.members.include?(@user)
|
||||
end
|
||||
private :member?
|
||||
end
|
@@ -8,7 +8,7 @@
|
||||
- if current_user.admin?
|
||||
li = link_to(t('breadcrumbs.dashboard.show'), admin_dashboard_path)
|
||||
li.divider
|
||||
- models = [ExecutionEnvironment, Exercise, Consumer, CodeHarborLink, ExternalUser, FileType, InternalUser, Submission, Team].sort_by { |model| model.model_name.human(count: 2) }
|
||||
- models = [ExecutionEnvironment, Exercise, Consumer, CodeHarborLink, ExternalUser, FileType, InternalUser, Submission].sort_by { |model| model.model_name.human(count: 2) }
|
||||
- models.each do |model|
|
||||
- if policy(model).index?
|
||||
li = link_to(model.model_name.human(count: 2), send(:"#{model.model_name.collection}_path"))
|
||||
|
@@ -17,9 +17,6 @@
|
||||
= f.label(:instructions)
|
||||
= f.hidden_field(:instructions)
|
||||
.form-control.markdown
|
||||
/.form-group
|
||||
= f.label(:team_id)
|
||||
= f.collection_select(:team_id, @teams, :id, :name, {include_blank: true}, class: 'form-control')
|
||||
.checkbox
|
||||
label
|
||||
= f.check_box(:public)
|
||||
|
@@ -50,9 +50,9 @@ h1 = "#{@exercise} (external user #{@external_user})"
|
||||
td
|
||||
-submission.testruns.each do |run|
|
||||
- if run.passed
|
||||
.unit-test-result.positive-result
|
||||
.unit-test-result.positive-result title=run.output
|
||||
- else
|
||||
.unit-test-result.negative-result
|
||||
.unit-test-result.negative-result title=run.output
|
||||
td = Time.at(deltas[1..index].inject(:+)).utc.strftime("%H:%M:%S") if index > 0
|
||||
-working_times_until.push((Time.at(deltas[1..index].inject(:+)).utc.strftime("%H:%M:%S") if index > 0))
|
||||
p = t('.addendum')
|
||||
|
@@ -12,7 +12,6 @@ h1
|
||||
= row(label: 'exercise.description', value: render_markdown(@exercise.description))
|
||||
= 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)
|
||||
= row(label: 'exercise.public', value: @exercise.public?)
|
||||
= row(label: 'exercise.hide_file_tree', value: @exercise.hide_file_tree?)
|
||||
|
@@ -1,9 +0,0 @@
|
||||
= form_for(@team) do |f|
|
||||
= render('shared/form_errors', object: @team)
|
||||
.form-group
|
||||
= f.label(:name)
|
||||
= f.text_field(:name, class: 'form-control', required: true)
|
||||
.form-group
|
||||
= f.label(:internal_user_ids)
|
||||
= f.collection_select(:internal_user_ids, InternalUser.all.order(:name), :id, :name, {}, {class: 'form-control', multiple: true})
|
||||
.actions = render('shared/submit_button', f: f, object: @team)
|
@@ -1,3 +0,0 @@
|
||||
h1 = @hint
|
||||
|
||||
= render('form')
|
@@ -1,20 +0,0 @@
|
||||
h1 = Team.model_name.human(count: 2)
|
||||
|
||||
.table-responsive
|
||||
table.table
|
||||
thead
|
||||
tr
|
||||
th = t('activerecord.attributes.team.name')
|
||||
th = t('activerecord.attributes.team.internal_user_ids')
|
||||
th colspan=3 = t('shared.actions')
|
||||
tbody
|
||||
- @teams.each do |team|
|
||||
tr
|
||||
td = team.name
|
||||
td = team.members.count
|
||||
td = link_to(t('shared.show'), team_path(team.id))
|
||||
td = link_to(t('shared.edit'), edit_team_path(team.id))
|
||||
td = link_to(t('shared.destroy'), team_path(team.id), data: {confirm: t('shared.confirm_destroy')}, method: :delete)
|
||||
|
||||
= render('shared/pagination', collection: @teams)
|
||||
p = render('shared/new_button', model: Team, path: new_team_path)
|
@@ -1,3 +0,0 @@
|
||||
h1 = t('shared.new_model', model: Team.model_name.human)
|
||||
|
||||
= render('form')
|
@@ -1,9 +0,0 @@
|
||||
h1
|
||||
= @team
|
||||
= render('shared/edit_button', object: @team, path: edit_team_path(@team.id))
|
||||
|
||||
= row(label: 'team.name', value: @team.name)
|
||||
= row(label: 'team.internal_user_ids') do
|
||||
ul.list-unstyled
|
||||
- @team.members.order(:name).each do |internal_user|
|
||||
li = link_to(internal_user, internal_user)
|
Reference in New Issue
Block a user