From ce2823e871f9e6e33a595efd62d5fa1a276be6bc Mon Sep 17 00:00:00 2001 From: Ralf Teusner Date: Mon, 3 Apr 2017 15:26:02 +0200 Subject: [PATCH 01/96] restrict name to be set to lis_person_name_full (should be display name) or to lis_person_name_given (should be first name). don't use xikolo api any longer for consumer openHPI, use the values in CodeOcean. --- app/controllers/concerns/lti.rb | 6 +++--- app/models/external_user.rb | 8 +++----- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/app/controllers/concerns/lti.rb b/app/controllers/concerns/lti.rb index 7483327d..0068afe1 100644 --- a/app/controllers/concerns/lti.rb +++ b/app/controllers/concerns/lti.rb @@ -42,12 +42,12 @@ module Lti private :external_user_email def external_user_name(provider) + # save person_name_full if supplied. this is the display_name, if it is set. + # else only save the firstname, we don't want lastnames (family names) if provider.lis_person_name_full provider.lis_person_name_full - elsif provider.lis_person_name_given && provider.lis_person_name_family - "#{provider.lis_person_name_given} #{provider.lis_person_name_family}" else - provider.lis_person_name_given || provider.lis_person_name_family + provider.lis_person_name_given end end private :external_user_name diff --git a/app/models/external_user.rb b/app/models/external_user.rb index 54d5d526..3eebc205 100644 --- a/app/models/external_user.rb +++ b/app/models/external_user.rb @@ -5,11 +5,9 @@ class ExternalUser < ActiveRecord::Base validates :external_id, presence: true def displayname - result = "User " + id.to_s - if(!consumer.nil? && consumer.name == 'openHPI') - result = Rails.cache.fetch("#{cache_key}/displayname", expires_in: 12.hours) do - Xikolo::UserClient.get(external_id.to_s)[:display_name] - end + result = name + if(result == nil || discount == "") + result = "User " + id.to_s end result end From 8197d40c6cc0f7d16d314ba79eecfa1bfb71d3ad Mon Sep 17 00:00:00 2001 From: Ralf Teusner Date: Mon, 3 Apr 2017 17:20:50 +0200 Subject: [PATCH 02/96] fixed copy and paste error... --- app/models/external_user.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/external_user.rb b/app/models/external_user.rb index 3eebc205..b7a0ebc5 100644 --- a/app/models/external_user.rb +++ b/app/models/external_user.rb @@ -6,7 +6,7 @@ class ExternalUser < ActiveRecord::Base def displayname result = name - if(result == nil || discount == "") + if(result == nil || result == "") result = "User " + id.to_s end result From 86495bec7c0e6cbb6b7e8801f24535f4503107e8 Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Wed, 23 Aug 2017 17:43:13 +0200 Subject: [PATCH 03/96] Restructure modal --- .../stylesheets/request-for-comments.css.scss | 14 ++++++++++++++ .../exercises/_comment_dialogcontent.html.slim | 9 +++++---- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/app/assets/stylesheets/request-for-comments.css.scss b/app/assets/stylesheets/request-for-comments.css.scss index 6448e6e7..63027531 100644 --- a/app/assets/stylesheets/request-for-comments.css.scss +++ b/app/assets/stylesheets/request-for-comments.css.scss @@ -64,3 +64,17 @@ p.comment { overflow: hidden; margin-bottom: 10px; } + +#otherComments { + h5 { + margin-top: 0px; + } +} + +#myComment { + margin-bottom: 10px; + + textarea { + resize: none; + } +} \ No newline at end of file diff --git a/app/views/exercises/_comment_dialogcontent.html.slim b/app/views/exercises/_comment_dialogcontent.html.slim index 4c78035a..988c5311 100644 --- a/app/views/exercises/_comment_dialogcontent.html.slim +++ b/app/views/exercises/_comment_dialogcontent.html.slim @@ -1,9 +1,10 @@ -h5 =t('exercises.implement.comment.addyours') - -textarea.form-control(style='resize:none;') #otherComments h5 =t('exercises.implement.comment.others') pre#otherCommentsTextfield -p = '' + +#myComment + h5 =t('exercises.implement.comment.addyours') + textarea.form-control + button#addCommentButton.btn.btn-block.btn-primary(type='button') =t('exercises.implement.comment.addCommentButton') button#removeAllButton.btn.btn-block.btn-warning(type='button') =t('exercises.implement.comment.removeAllOnLine') \ No newline at end of file From ce3bf525092812c150ba69a261744099bef5cbb0 Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Wed, 23 Aug 2017 17:52:16 +0200 Subject: [PATCH 04/96] Remove old code --- app/views/request_for_comments/show.html.erb | 28 -------------------- 1 file changed, 28 deletions(-) diff --git a/app/views/request_for_comments/show.html.erb b/app/views/request_for_comments/show.html.erb index ab60ef91..470dcf8f 100644 --- a/app/views/request_for_comments/show.html.erb +++ b/app/views/request_for_comments/show.html.erb @@ -82,7 +82,6 @@ also, all settings from the rails model needed for the editor configuration in t From be5b1df76aeeff4966722a21818032ed4c83215c Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Wed, 20 Sep 2017 17:14:55 +0200 Subject: [PATCH 58/96] Make subscriptions insert-only --- app/controllers/comments_controller.rb | 3 ++- app/controllers/subscriptions_controller.rb | 5 +++-- app/views/exercises/_comment_dialogcontent.html.slim | 2 +- db/migrate/20170920145852_add_deleted_to_subscription.rb | 5 +++++ db/schema.rb | 3 ++- 5 files changed, 13 insertions(+), 5 deletions(-) create mode 100644 db/migrate/20170920145852_add_deleted_to_subscription.rb diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb index 948f3e5b..90a4bcf1 100644 --- a/app/controllers/comments_controller.rb +++ b/app/controllers/comments_controller.rb @@ -123,7 +123,8 @@ class CommentsController < ApplicationController request_for_comment.commenters.each do |commenter| subscriptions = Subscription.where( :request_for_comment_id => request_for_comment.id, - :user_id => commenter.id, :user_type => commenter.class.name) + :user_id => commenter.id, :user_type => commenter.class.name, + :deleted => false) subscriptions.each do |subscription| if (subscription.subscription_type == 'author' and current_user == request_for_comment.user) or subscription.subscription_type == 'all' if subscription.user != current_user diff --git a/app/controllers/subscriptions_controller.rb b/app/controllers/subscriptions_controller.rb index 21321caf..232e9f01 100644 --- a/app/controllers/subscriptions_controller.rb +++ b/app/controllers/subscriptions_controller.rb @@ -32,7 +32,8 @@ class SubscriptionsController < ApplicationController else authorize! rfc = @subscription.try(:request_for_comment) - if @subscription.destroy + @subscription.deleted = true + if @subscription.save respond_to do |format| format.html { redirect_to request_for_comment_url(rfc), notice: t('subscriptions.successfully_unsubscribed') } format.json { render json: {message: t('subscriptions.successfully_unsubscribed')}, status: :ok} @@ -55,7 +56,7 @@ class SubscriptionsController < ApplicationController def subscription_params current_user_id = current_user.try(:id) current_user_class_name = current_user.try(:class).try(:name) - params[:subscription].permit(:request_for_comment_id, :subscription_type).merge(user_id: current_user_id, user_type: current_user_class_name) + params[:subscription].permit(:request_for_comment_id, :subscription_type).merge(user_id: current_user_id, user_type: current_user_class_name, deleted: false) end private :subscription_params end diff --git a/app/views/exercises/_comment_dialogcontent.html.slim b/app/views/exercises/_comment_dialogcontent.html.slim index 29fb8208..f543f21d 100644 --- a/app/views/exercises/_comment_dialogcontent.html.slim +++ b/app/views/exercises/_comment_dialogcontent.html.slim @@ -2,7 +2,7 @@ h5 =t('exercises.implement.comment.others') .container label - input#subscribe type='checkbox' title=t('request_for_comments.subscribe_to_author') data-subscription=Subscription.where(user: current_user, request_for_comment_id: @request_for_comment.id).try(:first).try(:id) + input#subscribe type='checkbox' title=t('request_for_comments.subscribe_to_author') data-subscription=Subscription.where(user: current_user, request_for_comment_id: @request_for_comment.id, subscription_type: 'author', deleted: false).try(:first).try(:id) = t('request_for_comments.subscribe_to_author') #myComment diff --git a/db/migrate/20170920145852_add_deleted_to_subscription.rb b/db/migrate/20170920145852_add_deleted_to_subscription.rb new file mode 100644 index 00000000..eb1d47c4 --- /dev/null +++ b/db/migrate/20170920145852_add_deleted_to_subscription.rb @@ -0,0 +1,5 @@ +class AddDeletedToSubscription < ActiveRecord::Migration + def change + add_column :subscriptions, :deleted, :boolean + end +end diff --git a/db/schema.rb b/db/schema.rb index c31baf1c..e7e0c6d6 100644 --- a/db/schema.rb +++ b/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: 20170913054203) do +ActiveRecord::Schema.define(version: 20170920145852) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -288,6 +288,7 @@ ActiveRecord::Schema.define(version: 20170913054203) do t.string "subscription_type" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.boolean "deleted" end create_table "tags", force: :cascade do |t| From c32320503627c21805f5bb07e9e13dd7180f3682 Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Wed, 20 Sep 2017 17:23:49 +0200 Subject: [PATCH 59/96] Only send one email per user when subscription gets a new comment --- app/controllers/comments_controller.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb index 90a4bcf1..d292804e 100644 --- a/app/controllers/comments_controller.rb +++ b/app/controllers/comments_controller.rb @@ -121,14 +121,16 @@ class CommentsController < ApplicationController def send_mail_to_subscribers(comment, request_for_comment) request_for_comment.commenters.each do |commenter| + already_sent_mail = false subscriptions = Subscription.where( :request_for_comment_id => request_for_comment.id, :user_id => commenter.id, :user_type => commenter.class.name, :deleted => false) subscriptions.each do |subscription| if (subscription.subscription_type == 'author' and current_user == request_for_comment.user) or subscription.subscription_type == 'all' - if subscription.user != current_user + unless subscription.user == current_user or already_sent_mail UserMailer.got_new_comment_for_subscription(comment, subscription, current_user).deliver_now + already_sent_mail = true end end end From df5e8133d29b19df3216521279cac45d5253fed2 Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Wed, 20 Sep 2017 17:27:47 +0200 Subject: [PATCH 60/96] Move subscribe box out of other comments container --- app/assets/stylesheets/request-for-comments.css.scss | 8 ++++---- app/views/exercises/_comment_dialogcontent.html.slim | 7 ++++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/app/assets/stylesheets/request-for-comments.css.scss b/app/assets/stylesheets/request-for-comments.css.scss index e0ff5fa0..8fb7bfea 100644 --- a/app/assets/stylesheets/request-for-comments.css.scss +++ b/app/assets/stylesheets/request-for-comments.css.scss @@ -127,11 +127,11 @@ } } } +} - input#subscribe { - margin-top: 5px; - margin-right: 5px; - } +input#subscribe { + margin-top: 5px; + margin-right: 5px; } #myComment { diff --git a/app/views/exercises/_comment_dialogcontent.html.slim b/app/views/exercises/_comment_dialogcontent.html.slim index f543f21d..ab6dc6b4 100644 --- a/app/views/exercises/_comment_dialogcontent.html.slim +++ b/app/views/exercises/_comment_dialogcontent.html.slim @@ -1,9 +1,10 @@ #otherComments h5 =t('exercises.implement.comment.others') .container - label - input#subscribe type='checkbox' title=t('request_for_comments.subscribe_to_author') data-subscription=Subscription.where(user: current_user, request_for_comment_id: @request_for_comment.id, subscription_type: 'author', deleted: false).try(:first).try(:id) - = t('request_for_comments.subscribe_to_author') + +label + input#subscribe type='checkbox' title=t('request_for_comments.subscribe_to_author') data-subscription=Subscription.where(user: current_user, request_for_comment_id: @request_for_comment.id, subscription_type: 'author', deleted: false).try(:first).try(:id) + = t('request_for_comments.subscribe_to_author') #myComment h5 =t('exercises.implement.comment.addyours') From 827f30b9e7cd04b92e4feefd4e8a92170e83e936 Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Thu, 21 Sep 2017 16:01:07 +0200 Subject: [PATCH 61/96] Wrap tags in collapsable container --- app/views/exercises/_form.html.slim | 33 ++++++++++++++++++----------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/app/views/exercises/_form.html.slim b/app/views/exercises/_form.html.slim index 5ab8502b..25966cf0 100644 --- a/app/views/exercises/_form.html.slim +++ b/app/views/exercises/_form.html.slim @@ -38,19 +38,28 @@ .form-group = f.label(t('activerecord.attributes.exercise.worktime')) = f.number_field "expected_worktime_minutes", value: @exercise.expected_worktime_seconds / 60, in: 1..1000, step: 1 + h2 Tags - .table-responsive - table.table#tags-table - thead - tr - th = t('activerecord.attributes.exercise.selection') - th = sort_link(@search, :title, t('activerecord.attributes.tag.name')) - th = t('activerecord.attributes.tag.difficulty') - = collection_check_boxes :exercise, :tag_ids, @exercise_tags, :tag_id, :id do |b| - tr - td = b.check_box - td = b.object.tag.name - td = number_field "tag_factors[#{b.object.tag.id}]", :factor, :value => b.object.factor, in: 1..10, step: 1 + ul.list-unstyled.panel-group + li.panel.panel-default + .panel-heading role="tab" id="heading" + a.file-heading data-toggle="collapse" href="#tag-collapse" + div.clearfix role="button" + span Click to expand/collapse... + .panel-collapse.collapse id="tag-collapse" role="tabpanel" + .table-responsive + table.table#tags-table + thead + tr + th = t('activerecord.attributes.exercise.selection') + th = sort_link(@search, :title, t('activerecord.attributes.tag.name')) + th = t('activerecord.attributes.tag.difficulty') + = collection_check_boxes :exercise, :tag_ids, @exercise_tags, :tag_id, :id do |b| + tr + td = b.check_box + td = b.object.tag.name + td = number_field "tag_factors[#{b.object.tag.id}]", :factor, :value => b.object.factor, in: 1..10, step: 1 + h2 = t('activerecord.attributes.exercise.files') ul#files.list-unstyled.panel-group = f.fields_for :files do |files_form| From a6bc971659cbb04e36dd1520e531656ec2cc6ce8 Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Thu, 21 Sep 2017 16:15:17 +0200 Subject: [PATCH 62/96] Add I18n for tags --- app/views/exercises/_form.html.slim | 4 ++-- config/locales/de.yml | 2 ++ config/locales/en.yml | 2 ++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/app/views/exercises/_form.html.slim b/app/views/exercises/_form.html.slim index 25966cf0..bb4aa851 100644 --- a/app/views/exercises/_form.html.slim +++ b/app/views/exercises/_form.html.slim @@ -39,13 +39,13 @@ = f.label(t('activerecord.attributes.exercise.worktime')) = f.number_field "expected_worktime_minutes", value: @exercise.expected_worktime_seconds / 60, in: 1..1000, step: 1 - h2 Tags + h2 = t('exercises.form.tags') ul.list-unstyled.panel-group li.panel.panel-default .panel-heading role="tab" id="heading" a.file-heading data-toggle="collapse" href="#tag-collapse" div.clearfix role="button" - span Click to expand/collapse... + span = t('exercises.form.click_to_collapse') .panel-collapse.collapse id="tag-collapse" role="tabpanel" .table-responsive table.table#tags-table diff --git a/config/locales/de.yml b/config/locales/de.yml index 62fc76b5..0f066fde 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -260,6 +260,8 @@ de: path: 'Pfad der Datei im Projektverzeichnis. Kann auch leer gelassen werden.' form: add_file: Datei hinzufügen + tags: "Tags" + click_to_collapse: "Zum Aus-/Einklappen hier klicken..." implement: alert: text: 'Ihr Browser unterstützt nicht alle Funktionalitäten, die %{application_name} benötigt. Bitte nutzen Sie einen modernen Browser, um %{application_name} zu besuchen.' diff --git a/config/locales/en.yml b/config/locales/en.yml index 1e13f929..f3aa6735 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -260,6 +260,8 @@ en: path: "The file's path in the project tree. Can be left blank." form: add_file: Add file + tags: "Tags" + click_to_collapse: "Click to expand/collapse..." implement: alert: text: 'Your browser does not support features required for using %{application_name}. Please access %{application_name} using a modern browser.' From 8c6b3c8e57d65990c17ab4a3e081c78a623c039c Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Thu, 21 Sep 2017 16:23:09 +0200 Subject: [PATCH 63/96] Add space below exercise form --- app/assets/stylesheets/exercises.css.scss | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/assets/stylesheets/exercises.css.scss b/app/assets/stylesheets/exercises.css.scss index eb1b5300..73c0b26e 100644 --- a/app/assets/stylesheets/exercises.css.scss +++ b/app/assets/stylesheets/exercises.css.scss @@ -62,7 +62,9 @@ a.file-heading { fill: #ffd897; } - +.container > form > .actions { + margin-bottom: 200px; +} .d3-tip { line-height: 1; From acf2bfb28e311c50792274706fa3f173437b81ca Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Thu, 21 Sep 2017 16:24:21 +0200 Subject: [PATCH 64/96] Collapse files by default --- app/views/exercises/_file_form.html.slim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/exercises/_file_form.html.slim b/app/views/exercises/_file_form.html.slim index 065eca66..3c43cd65 100644 --- a/app/views/exercises/_file_form.html.slim +++ b/app/views/exercises/_file_form.html.slim @@ -5,7 +5,7 @@ li.panel.panel-default a.file-heading data-toggle="collapse" data-parent="#files" href="#collapse#{id}" div.clearfix role="button" span = f.object.name - .panel-collapse.collapse-in id="collapse#{id}" role="tabpanel" + .panel-collapse.collapse id="collapse#{id}" role="tabpanel" .panel-body .clearfix = link_to(t('shared.destroy'), '#', class:'btn btn-warning btn-sm discard-file pull-right') .form-group From bbf94859eb7d28e1851f8edd90e0246f78873bfb Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Thu, 21 Sep 2017 16:31:30 +0200 Subject: [PATCH 65/96] Enable expanding multiple files at the same time --- app/views/exercises/_file_form.html.slim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/exercises/_file_form.html.slim b/app/views/exercises/_file_form.html.slim index 3c43cd65..b1c292cd 100644 --- a/app/views/exercises/_file_form.html.slim +++ b/app/views/exercises/_file_form.html.slim @@ -2,7 +2,7 @@ li.panel.panel-default .panel-heading role="tab" id="heading" - a.file-heading data-toggle="collapse" data-parent="#files" href="#collapse#{id}" + a.file-heading data-toggle="collapse" href="#collapse#{id}" div.clearfix role="button" span = f.object.name .panel-collapse.collapse id="collapse#{id}" role="tabpanel" From 10600045f4837b9758d0003f257546ae58954a3e Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Thu, 21 Sep 2017 17:09:27 +0200 Subject: [PATCH 66/96] Auto-expand new files --- app/views/exercises/_file_form.html.slim | 2 +- app/views/exercises/_form.html.slim | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/views/exercises/_file_form.html.slim b/app/views/exercises/_file_form.html.slim index b1c292cd..5ed70fcb 100644 --- a/app/views/exercises/_file_form.html.slim +++ b/app/views/exercises/_file_form.html.slim @@ -5,7 +5,7 @@ li.panel.panel-default a.file-heading data-toggle="collapse" href="#collapse#{id}" div.clearfix role="button" span = f.object.name - .panel-collapse.collapse id="collapse#{id}" role="tabpanel" + .panel-collapse.collapse class=('in' if new_file) id="collapse#{id}" role="tabpanel" .panel-body .clearfix = link_to(t('shared.destroy'), '#', class:'btn btn-warning btn-sm discard-file pull-right') .form-group diff --git a/app/views/exercises/_form.html.slim b/app/views/exercises/_form.html.slim index bb4aa851..b70ef447 100644 --- a/app/views/exercises/_form.html.slim +++ b/app/views/exercises/_form.html.slim @@ -63,10 +63,10 @@ h2 = t('activerecord.attributes.exercise.files') ul#files.list-unstyled.panel-group = f.fields_for :files do |files_form| - = render('file_form', f: files_form) + = render('file_form', f: files_form, new_file: false) a#add-file.btn.btn-default.btn-sm.pull-right href='#' = t('.add_file') ul#dummies.hidden = f.fields_for(:files, CodeOcean::File.new, child_index: 'index') do |files_form| - = render('file_form', f: files_form) + = render('file_form', f: files_form, new_file: true) .actions = render('shared/submit_button', f: f, object: @exercise) \ No newline at end of file From d5aed4f7b64a301acae796da444feb1ab20526c1 Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Thu, 21 Sep 2017 17:15:01 +0200 Subject: [PATCH 67/96] Don't rely on parameter; use non-existing file name as indicator instead --- app/views/exercises/_file_form.html.slim | 2 +- app/views/exercises/_form.html.slim | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/views/exercises/_file_form.html.slim b/app/views/exercises/_file_form.html.slim index 5ed70fcb..75deeeb5 100644 --- a/app/views/exercises/_file_form.html.slim +++ b/app/views/exercises/_file_form.html.slim @@ -5,7 +5,7 @@ li.panel.panel-default a.file-heading data-toggle="collapse" href="#collapse#{id}" div.clearfix role="button" span = f.object.name - .panel-collapse.collapse class=('in' if new_file) id="collapse#{id}" role="tabpanel" + .panel-collapse.collapse class=('in' if f.object.name.nil?) id="collapse#{id}" role="tabpanel" .panel-body .clearfix = link_to(t('shared.destroy'), '#', class:'btn btn-warning btn-sm discard-file pull-right') .form-group diff --git a/app/views/exercises/_form.html.slim b/app/views/exercises/_form.html.slim index b70ef447..bb4aa851 100644 --- a/app/views/exercises/_form.html.slim +++ b/app/views/exercises/_form.html.slim @@ -63,10 +63,10 @@ h2 = t('activerecord.attributes.exercise.files') ul#files.list-unstyled.panel-group = f.fields_for :files do |files_form| - = render('file_form', f: files_form, new_file: false) + = render('file_form', f: files_form) a#add-file.btn.btn-default.btn-sm.pull-right href='#' = t('.add_file') ul#dummies.hidden = f.fields_for(:files, CodeOcean::File.new, child_index: 'index') do |files_form| - = render('file_form', f: files_form, new_file: true) + = render('file_form', f: files_form) .actions = render('shared/submit_button', f: f, object: @exercise) \ No newline at end of file From 194984a62067883779dcf62ac3d11fc165c4777e Mon Sep 17 00:00:00 2001 From: Ralf Teusner Date: Wed, 13 Sep 2017 13:28:31 +0200 Subject: [PATCH 68/96] add cause to testruns trigger run and assess on request_for_comment --- .../editor/participantsupport.js.erb | 4 +-- .../javascripts/editor/submissions.js.erb | 28 ++++++++++--------- app/assets/stylesheets/statistics.css.scss | 8 ++++++ .../concerns/submission_scoring.rb | 2 +- .../request_for_comments_controller.rb | 5 ++++ app/controllers/submissions_controller.rb | 2 +- .../external_users/statistics.html.slim | 4 ++- .../20170830083601_add_cause_to_testruns.rb | 18 ++++++++++++ 8 files changed, 53 insertions(+), 18 deletions(-) create mode 100644 db/migrate/20170830083601_add_cause_to_testruns.rb diff --git a/app/assets/javascripts/editor/participantsupport.js.erb b/app/assets/javascripts/editor/participantsupport.js.erb index 91e9f0d1..63787f4a 100644 --- a/app/assets/javascripts/editor/participantsupport.js.erb +++ b/app/assets/javascripts/editor/participantsupport.js.erb @@ -59,8 +59,6 @@ CodeOceanEditorCodePilot = { } }; -//Request for comments does currently not work on staging platform (no relative root_url used here). -//To fix this rely on ruby routes CodeOceanEditorRequestForComments = { requestComments: function () { var user_id = $('#editor').data('user-id'); @@ -83,6 +81,8 @@ CodeOceanEditorRequestForComments = { }).done(function () { this.hideSpinner(); $.flash.success({text: $('#askForCommentsButton').data('message-success')}); + // trigger a run + this.runSubmission.call(this, submission); }.bind(this)).error(this.ajaxError.bind(this)); }; diff --git a/app/assets/javascripts/editor/submissions.js.erb b/app/assets/javascripts/editor/submissions.js.erb index 20d8cd10..21250f7e 100644 --- a/app/assets/javascripts/editor/submissions.js.erb +++ b/app/assets/javascripts/editor/submissions.js.erb @@ -142,19 +142,21 @@ CodeOceanEditorSubmissions = { * Execution-Logic */ runCode: function(event) { - event.preventDefault(); - if ($('#run').is(':visible')) { - this.createSubmission('#run', null, function(response) { - //Run part starts here - $('#stop').data('url', response.stop_url); - this.running = true; - this.showSpinner($('#run')); - $('#score_div').addClass('hidden'); - this.toggleButtonStates(); - var url = response.run_url.replace(this.FILENAME_URL_PLACEHOLDER, this.active_file.filename.replace(/#$/,'')); // remove # if it is the last character, this is not part of the filename and just an anchor - this.initializeSocketForRunning(url); - }.bind(this)); - } + event.preventDefault(); + if ($('#run').is(':visible')) { + this.createSubmission('#run', null, this.runSubmission.bind(this)); + } + }, + + runSubmission: function (submission) { + //Run part starts here + $('#stop').data('url', submission.stop_url); + this.running = true; + this.showSpinner($('#run')); + $('#score_div').addClass('hidden'); + this.toggleButtonStates(); + var url = submission.run_url.replace(this.FILENAME_URL_PLACEHOLDER, this.active_file.filename.replace(/#$/,'')); // remove # if it is the last character, this is not part of the filename and just an anchor + this.initializeSocketForRunning(url); }, saveCode: function(event) { diff --git a/app/assets/stylesheets/statistics.css.scss b/app/assets/stylesheets/statistics.css.scss index f656cd9a..a5ea4430 100644 --- a/app/assets/stylesheets/statistics.css.scss +++ b/app/assets/stylesheets/statistics.css.scss @@ -42,6 +42,14 @@ div.positive-result { box-shadow: 0px 0px 11px 1px rgba(44,222,0,1); } +div.unknown-result { + border-radius: 50%; + background-color: #ffca00; + -webkit-box-shadow: 0px 0px 11px 1px rgb(255, 202, 0); + -moz-box-shadow: 0px 0px 11px 1px rgb(255, 202, 0); + box-shadow: 0px 0px 11px 1px rgb(255, 202, 0); +} + div.negative-result { border-radius: 50%; background-color: #ff2600; diff --git a/app/controllers/concerns/submission_scoring.rb b/app/controllers/concerns/submission_scoring.rb index 16f1f061..41f9ff26 100644 --- a/app/controllers/concerns/submission_scoring.rb +++ b/app/controllers/concerns/submission_scoring.rb @@ -9,7 +9,7 @@ module SubmissionScoring assessment = assessor.assess(output) passed = ((assessment[:passed] == assessment[:count]) and (assessment[:score] > 0)) testrun_output = passed ? nil : output[:stderr] - Testrun.new(submission: submission, file: file, passed: passed, output: testrun_output).save + Testrun.new(submission: submission, cause: 'assess', file: file, passed: passed, output: testrun_output).save output.merge!(assessment) output.merge!(filename: file.name_with_extension, message: feedback_message(file, output[:score]), weight: file.weight) end diff --git a/app/controllers/request_for_comments_controller.rb b/app/controllers/request_for_comments_controller.rb index 8ef8f866..4fd19a92 100644 --- a/app/controllers/request_for_comments_controller.rb +++ b/app/controllers/request_for_comments_controller.rb @@ -1,4 +1,5 @@ class RequestForCommentsController < ApplicationController + include SubmissionScoring before_action :set_request_for_comment, only: [:show, :edit, :update, :destroy, :mark_as_solved, :set_thank_you_note] skip_after_action :verify_authorized @@ -107,6 +108,10 @@ class RequestForCommentsController < ApplicationController @request_for_comment = RequestForComment.new(request_for_comment_params) respond_to do |format| if @request_for_comment.save + # create thread here and execute tests. A run is triggered from the frontend and does not need to be handled here. + Thread.new do + score_submission(@request_for_comment.submission) + end format.json { render :show, status: :created, location: @request_for_comment } else format.html { render :new } diff --git a/app/controllers/submissions_controller.rb b/app/controllers/submissions_controller.rb index 9b37fde0..52baefe1 100644 --- a/app/controllers/submissions_controller.rb +++ b/app/controllers/submissions_controller.rb @@ -262,7 +262,7 @@ class SubmissionsController < ApplicationController def save_run_output if !@message_buffer.blank? @message_buffer = @message_buffer[(0..max_message_buffer_size-1)] # trim the string to max_message_buffer_size chars - Testrun.create(file: @file, submission: @submission, output: @message_buffer) + Testrun.create(file: @file, cause: 'run', submission: @submission, output: @message_buffer) end end diff --git a/app/views/exercises/external_users/statistics.html.slim b/app/views/exercises/external_users/statistics.html.slim index 313a19b0..8b5c3b30 100644 --- a/app/views/exercises/external_users/statistics.html.slim +++ b/app/views/exercises/external_users/statistics.html.slim @@ -54,8 +54,10 @@ h1 = "#{@exercise} (external user #{@external_user})" -submission_or_intervention.testruns.each do |run| - if run.passed .unit-test-result.positive-result title=run.output - - else + - elsif run.failed .unit-test-result.negative-result title=run.output + - else + .unit-test-result.unknown-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)) - elsif submission_or_intervention.is_a? UserExerciseIntervention diff --git a/db/migrate/20170830083601_add_cause_to_testruns.rb b/db/migrate/20170830083601_add_cause_to_testruns.rb new file mode 100644 index 00000000..f9a859c4 --- /dev/null +++ b/db/migrate/20170830083601_add_cause_to_testruns.rb @@ -0,0 +1,18 @@ +class AddCauseToTestruns < ActiveRecord::Migration + def up + add_column :testruns, :cause, :string + Testrun.reset_column_information + Testrun.all.each{ |testrun| + if(testrun.submission.nil?) + say_with_time "#{testrun.id} has no submission" do end + else + testrun.cause = testrun.submission.cause + testrun.save + end + } + end + + def down + remove_column :testruns, :cause + end +end From da4d54859c52d2fdc1910694d290c8d38566143a Mon Sep 17 00:00:00 2001 From: Ralf Teusner Date: Wed, 20 Sep 2017 13:10:37 +0200 Subject: [PATCH 69/96] save run outputs with cause requestComments with more content (5000 chars instead of 500). Always save full JSON content. --- app/controllers/submissions_controller.rb | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/app/controllers/submissions_controller.rb b/app/controllers/submissions_controller.rb index 52baefe1..4dfa182c 100644 --- a/app/controllers/submissions_controller.rb +++ b/app/controllers/submissions_controller.rb @@ -13,8 +13,12 @@ class SubmissionsController < ApplicationController before_action :set_mime_type, only: [:download_file, :render_file] skip_before_action :verify_authenticity_token, only: [:download_file, :render_file] - def max_message_buffer_size - 500 + def max_run_output_buffer_size + if(@submission.cause == 'requestComments') + 5000 + else + 500 + end end def authorize! @@ -196,7 +200,7 @@ class SubmissionsController < ApplicationController end def handle_message(message, tubesock, container) - @message_buffer ||= "" + @run_output ||= "" # Handle special commands first if (/^#exit/.match(message)) # Just call exit_container on the docker_client. @@ -205,19 +209,19 @@ class SubmissionsController < ApplicationController # kill_socket is called in the "on close handler" of the websocket to the container @docker_client.exit_container(container) elsif /^#timeout/.match(message) - @message_buffer = 'timeout: ' + @message_buffer # add information that this run timed out to the buffer + @run_output = 'timeout: ' + @run_output # add information that this run timed out to the buffer else # Filter out information about run_command, test_command, user or working directory run_command = @submission.execution_environment.run_command % command_substitutions(params[:filename]) test_command = @submission.execution_environment.test_command % command_substitutions(params[:filename]) if !(/root|workspace|#{run_command}|#{test_command}/.match(message)) - @message_buffer += message if @message_buffer.size <= max_message_buffer_size parse_message(message, 'stdout', tubesock) end end end def parse_message(message, output_stream, socket, recursive = true) + parsed = ''; begin parsed = JSON.parse(message) if(parsed.class == Hash && parsed.key?('cmd')) @@ -256,13 +260,16 @@ class SubmissionsController < ApplicationController socket.send_data JSON.dump(parsed) Rails.logger.info('parse_message sent: ' + JSON.dump(parsed)) end + ensure + # save the data that was send to the run_output if there is enough space left. this will be persisted as a testrun with cause "run" + @run_output += JSON.dump(parsed) if @run_output.size <= max_run_output_buffer_size end end def save_run_output - if !@message_buffer.blank? - @message_buffer = @message_buffer[(0..max_message_buffer_size-1)] # trim the string to max_message_buffer_size chars - Testrun.create(file: @file, cause: 'run', submission: @submission, output: @message_buffer) + if !@run_output.blank? + @run_output = @run_output[(0..max_run_output_buffer_size-1)] # trim the string to max_message_buffer_size chars + Testrun.create(file: @file, cause: 'run', submission: @submission, output: @run_output) end end From 1e71b46960db13db309636be6175e94c2e585215 Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Thu, 21 Sep 2017 17:20:21 +0200 Subject: [PATCH 70/96] Update schema --- db/schema.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/db/schema.rb b/db/schema.rb index e7e0c6d6..988cd447 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -304,6 +304,7 @@ ActiveRecord::Schema.define(version: 20170920145852) do t.integer "submission_id" t.datetime "created_at" t.datetime "updated_at" + t.string "cause" end create_table "user_exercise_feedbacks", force: :cascade do |t| From f62b8f12c4e14c0ecec1bc154cedaf67739af1f8 Mon Sep 17 00:00:00 2001 From: Ralf Teusner Date: Thu, 21 Sep 2017 17:35:48 +0200 Subject: [PATCH 71/96] remove email adress from statistics view (also for admins) --- app/views/exercises/statistics.html.slim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/exercises/statistics.html.slim b/app/views/exercises/statistics.html.slim index 89b7d6a1..d39c514b 100644 --- a/app/views/exercises/statistics.html.slim +++ b/app/views/exercises/statistics.html.slim @@ -35,7 +35,7 @@ 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})" + - label = "#{user.displayname}" tr 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 From 0e93a0bb2ea0cef27b8a67817cd16e2485d914d6 Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Thu, 21 Sep 2017 17:36:52 +0200 Subject: [PATCH 72/96] Pull out admin menu --- .../request_for_comments/_admin_menu.html.slim | 9 +++++++++ app/views/request_for_comments/show.html.erb | 17 +++-------------- 2 files changed, 12 insertions(+), 14 deletions(-) create mode 100644 app/views/request_for_comments/_admin_menu.html.slim diff --git a/app/views/request_for_comments/_admin_menu.html.slim b/app/views/request_for_comments/_admin_menu.html.slim new file mode 100644 index 00000000..3f71b2ed --- /dev/null +++ b/app/views/request_for_comments/_admin_menu.html.slim @@ -0,0 +1,9 @@ +br +h4 Admin Menu +h5 + ul + li = link_to "User's current status of this exercise", statistics_external_user_exercise_path(id: @request_for_comment.exercise_id, external_user_id: @request_for_comment.user_id) + li = link_to "All exercises of this user", statistics_external_user_path(id: @request_for_comment.user_id) + ul + li = link_to "Implement the exercise yourself", implement_exercise_path(id: @request_for_comment.exercise_id) + li = link_to "Show the exercise", exercise_path(id: @request_for_comment.exercise_id) diff --git a/app/views/request_for_comments/show.html.erb b/app/views/request_for_comments/show.html.erb index 83741a87..3814ba21 100644 --- a/app/views/request_for_comments/show.html.erb +++ b/app/views/request_for_comments/show.html.erb @@ -44,21 +44,10 @@ <% end %> - - - <% if @current_user.admin? && user.is_a?(ExternalUser) %> -
-
-

Admin Menu

-
-
    -
  • <%= link_to "User's current status of this exercise", statistics_external_user_exercise_path(id: @request_for_comment.exercise_id, external_user_id: @request_for_comment.user_id) %>
  • -
  • <%= link_to "All exercises of this user", statistics_external_user_path(id: @request_for_comment.user_id) %>

  • -
  • <%= link_to "Implement the exercise yourself", implement_exercise_path(id: @request_for_comment.exercise_id) %>
  • -
  • <%= link_to "Show the exercise", exercise_path(id: @request_for_comment.exercise_id) %>
  • -
-
+ <% if @current_user.admin? && user.is_a?(ExternalUser) %> + <%= render('admin_menu') %> <% end %> +
<%= t('request_for_comments.howto_title') %>
<%= render_markdown(t('request_for_comments.howto')) %>
From d902a42962dc420d256bab431acb2b9f414c55d4 Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Thu, 21 Sep 2017 17:41:21 +0200 Subject: [PATCH 73/96] Pull out mark as solved button --- .../_mark_as_solved.html.slim | 7 +++++++ app/views/request_for_comments/show.html.erb | 16 +--------------- 2 files changed, 8 insertions(+), 15 deletions(-) create mode 100644 app/views/request_for_comments/_mark_as_solved.html.slim diff --git a/app/views/request_for_comments/_mark_as_solved.html.slim b/app/views/request_for_comments/_mark_as_solved.html.slim new file mode 100644 index 00000000..b3df57fd --- /dev/null +++ b/app/views/request_for_comments/_mark_as_solved.html.slim @@ -0,0 +1,7 @@ +button.btn.btn-primary#mark-as-solved-button = t('request_for_comments.mark_as_solved') + +#thank-you-container + p = t('request_for_comments.write_a_thank_you_node') + textarea#thank-you-note + button.btn.btn-primary#send-thank-you-note = t('request_for_comments.send_thank_you_note') + button.btn.btn-default#cancel-thank-you-note = t('request_for_comments.cancel_thank_you_note') diff --git a/app/views/request_for_comments/show.html.erb b/app/views/request_for_comments/show.html.erb index 3814ba21..8ef7e16e 100644 --- a/app/views/request_for_comments/show.html.erb +++ b/app/views/request_for_comments/show.html.erb @@ -27,21 +27,7 @@ <% if (policy(@request_for_comment).mark_as_solved? and not @request_for_comment.solved?) %> - -
-

- <%= t('request_for_comments.write_a_thank_you_node') %> -

- - - -
+ <%= render('mark_as_solved') %> <% end %> <% if @current_user.admin? && user.is_a?(ExternalUser) %> From d94c5404aae929877786f4be7abdd8389a4281ec Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Thu, 21 Sep 2017 17:42:24 +0200 Subject: [PATCH 74/96] Clean up conditionals --- app/views/request_for_comments/show.html.erb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/request_for_comments/show.html.erb b/app/views/request_for_comments/show.html.erb index 8ef7e16e..b8a143f9 100644 --- a/app/views/request_for_comments/show.html.erb +++ b/app/views/request_for_comments/show.html.erb @@ -1,6 +1,6 @@

- <% if (@request_for_comment.solved?) %> + <% if @request_for_comment.solved? %> <% end %> <%= link_to(@request_for_comment.exercise.title, [:implement, @request_for_comment.exercise]) %> @@ -26,7 +26,7 @@ <% end %>

- <% if (policy(@request_for_comment).mark_as_solved? and not @request_for_comment.solved?) %> + <% if policy(@request_for_comment).mark_as_solved? and not @request_for_comment.solved? %> <%= render('mark_as_solved') %> <% end %> From ca040503443018b534bf5d37956d8ab02ebee8f6 Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Sat, 23 Sep 2017 09:05:58 +0200 Subject: [PATCH 75/96] Display output and test results below RfC description --- .../stylesheets/request-for-comments.css.scss | 36 +++++++++++++++++++ app/views/request_for_comments/show.html.erb | 26 ++++++++++++++ config/locales/de.yml | 3 ++ config/locales/en.yml | 3 ++ 4 files changed, 68 insertions(+) diff --git a/app/assets/stylesheets/request-for-comments.css.scss b/app/assets/stylesheets/request-for-comments.css.scss index 8fb7bfea..e88ed573 100644 --- a/app/assets/stylesheets/request-for-comments.css.scss +++ b/app/assets/stylesheets/request-for-comments.css.scss @@ -151,3 +151,39 @@ input#subscribe { color: #008cba; margin-top: 10px; } + +.testrun-assess-results { + + display: flex; + + .result { + margin-right: 10px; + width: 10px; + height: 10px; + } + + .passed { + border-radius: 50%; + background-color: #8efa00; + -webkit-box-shadow: 0 0 11px 1px rgba(44,222,0,1); + -moz-box-shadow: 0 0 11px 1px rgba(44,222,0,1); + box-shadow: 0 0 11px 1px rgba(44,222,0,1); + } + + .unknown { + border-radius: 50%; + background-color: #ffca00; + -webkit-box-shadow: 0 0 11px 1px rgb(255, 202, 0); + -moz-box-shadow: 0 0 11px 1px rgb(255, 202, 0); + box-shadow: 0 0 11px 1px rgb(255, 202, 0); + } + + .failed { + border-radius: 50%; + background-color: #ff2600; + -webkit-box-shadow: 0 0 11px 1px rgba(222,0,0,1); + -moz-box-shadow: 0 0 11px 1px rgba(222,0,0,1); + box-shadow: 0 0 11px 1px rgba(222,0,0,1); + } + +} diff --git a/app/views/request_for_comments/show.html.erb b/app/views/request_for_comments/show.html.erb index b8a143f9..156543c1 100644 --- a/app/views/request_for_comments/show.html.erb +++ b/app/views/request_for_comments/show.html.erb @@ -9,6 +9,7 @@ <% user = @request_for_comment.user submission = @request_for_comment.submission + testruns = Testrun.where(:submission_id => @request_for_comment.submission) %> <%= user.displayname %> | <%= @request_for_comment.created_at.localtime %> @@ -37,6 +38,31 @@
<%= t('request_for_comments.howto_title') %>
<%= render_markdown(t('request_for_comments.howto')) %>
+ + + <% if testruns.size > 0 %> +
+ <% output_runs = testruns.select { |run| run.cause == 'run' } %> + <% if output_runs.size > 0 %> +
<%= t('request_for_comments.runtime_output') %>
+
+ <% output_runs.each do |testrun| %> +

<%= testrun.try(:message) or t('request_for_comments.no_output') %>

+ <% end %> +
+ <% end %> + + <% assess_runs = testruns.select { |run| run.cause == 'assess' } %> + <% if assess_runs.size > 0 %> +
<%= t('request_for_comments.test_results') %>
+
+ <% assess_runs.each do |testrun| %> +
+ <% end %> +
+ <% end %> +
+ <% end %>

diff --git a/config/locales/de.yml b/config/locales/de.yml index 62fc76b5..88a3b1c0 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -514,6 +514,9 @@ de: modal_title: "Einen Kommentar in Zeile ${line} hinzufügen" click_for_more_comments: "Klicken um ${numComments} weitere Kommentare zu sehen..." subscribe_to_author: "Bei neuen Kommentaren des Autors per E-Mail benachrichtigt werden" + no_output: "Keine Ausgabe." + runtime_output: "Programmausgabe" + test_results: "Testergebnisse" sessions: create: failure: Fehlerhafte E-Mail oder Passwort. diff --git a/config/locales/en.yml b/config/locales/en.yml index 1e13f929..5d9b78d8 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -514,6 +514,9 @@ en: modal_title: "Add a comment to line ${line}" click_for_more_comments: "Click to view ${numComments} more comments..." subscribe_to_author: "Receive E-Mail notifications for new comments of the original author" + no_output: "No output." + runtime_output: "Runtime Output" + test_results: "Test Results" sessions: create: failure: Invalid email or password. From d119ef6a38ad09c3c29fa0de8a078268ffe1377d Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Sat, 23 Sep 2017 09:10:26 +0200 Subject: [PATCH 76/96] Fix message name --- app/views/request_for_comments/show.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/request_for_comments/show.html.erb b/app/views/request_for_comments/show.html.erb index 156543c1..78f9accc 100644 --- a/app/views/request_for_comments/show.html.erb +++ b/app/views/request_for_comments/show.html.erb @@ -47,7 +47,7 @@
<%= t('request_for_comments.runtime_output') %>
<% output_runs.each do |testrun| %> -

<%= testrun.try(:message) or t('request_for_comments.no_output') %>

+

<%= testrun.try(:output) or t('request_for_comments.no_output') %>

<% end %>
<% end %> From 7a0c7389d4402635b593113cfc74a57d7e491a49 Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Sun, 24 Sep 2017 11:15:05 +0200 Subject: [PATCH 77/96] Refactor RfC UI; decouple style from structure --- .../stylesheets/request-for-comments.css.scss | 22 ++++ app/views/request_for_comments/show.html.erb | 108 ++++++++++-------- 2 files changed, 82 insertions(+), 48 deletions(-) diff --git a/app/assets/stylesheets/request-for-comments.css.scss b/app/assets/stylesheets/request-for-comments.css.scss index e88ed573..a0418e48 100644 --- a/app/assets/stylesheets/request-for-comments.css.scss +++ b/app/assets/stylesheets/request-for-comments.css.scss @@ -152,6 +152,28 @@ input#subscribe { margin-top: 10px; } +.rfc { + + h5 { + text-decoration: underline; + } + + .text { + font-size: larger; + } + + .question { + display: flex; + align-items: baseline; + + .text { + margin-left: 10px; + } + + } + +} + .testrun-assess-results { display: flex; diff --git a/app/views/request_for_comments/show.html.erb b/app/views/request_for_comments/show.html.erb index 78f9accc..0fbeef37 100644 --- a/app/views/request_for_comments/show.html.erb +++ b/app/views/request_for_comments/show.html.erb @@ -14,55 +14,67 @@ <%= user.displayname %> | <%= @request_for_comment.created_at.localtime %>

- -
- <%= t('activerecord.attributes.exercise.description') %>: <%= render_markdown(@request_for_comment.exercise.description) %> -
- -
- <% if @request_for_comment.question and not @request_for_comment.question == '' %> - <%= t('activerecord.attributes.request_for_comments.question')%>: "<%= @request_for_comment.question %>" - <% else %> - <%= t('activerecord.attributes.request_for_comments.question')%>: <%= t('request_for_comments.no_question') %> - <% end %> -
- - <% if policy(@request_for_comment).mark_as_solved? and not @request_for_comment.solved? %> - <%= render('mark_as_solved') %> - <% end %> - - <% if @current_user.admin? && user.is_a?(ExternalUser) %> - <%= render('admin_menu') %> - <% end %> - -
- <%= t('request_for_comments.howto_title') %>
<%= render_markdown(t('request_for_comments.howto')) %> -
- - - <% if testruns.size > 0 %> -
- <% output_runs = testruns.select { |run| run.cause == 'run' } %> - <% if output_runs.size > 0 %> -
<%= t('request_for_comments.runtime_output') %>
-
- <% output_runs.each do |testrun| %> -

<%= testrun.try(:output) or t('request_for_comments.no_output') %>

- <% end %> -
- <% end %> - - <% assess_runs = testruns.select { |run| run.cause == 'assess' } %> - <% if assess_runs.size > 0 %> -
<%= t('request_for_comments.test_results') %>
-
- <% assess_runs.each do |testrun| %> -
- <% end %> -
- <% end %> +
+
+
+ <%= t('activerecord.attributes.exercise.description') %>: +
+
+ <%= render_markdown(@request_for_comment.exercise.description) %> +
- <% end %> + +
+
+ <%= t('activerecord.attributes.request_for_comments.question')%>: +
+
+ <%= @request_for_comment.question or t('request_for_comments.no_question')%> +
+
+ + <% if policy(@request_for_comment).mark_as_solved? and not @request_for_comment.solved? %> + <%= render('mark_as_solved') %> + <% end %> + + <% if @current_user.admin? && user.is_a?(ExternalUser) %> + <%= render('admin_menu') %> + <% end %> + +
+
+ <%= t('request_for_comments.howto_title') %> +
+
+ <%= render_markdown(t('request_for_comments.howto')) %> +
+
+ + + <% if testruns.size > 0 %> +
+ <% output_runs = testruns.select { |run| run.cause == 'run' } %> + <% if output_runs.size > 0 %> +
<%= t('request_for_comments.runtime_output') %>
+
+ <% output_runs.each do |testrun| %> +

<%= testrun.try(:output) or t('request_for_comments.no_output') %>

+ <% end %> +
+ <% end %> + + <% assess_runs = testruns.select { |run| run.cause == 'assess' } %> + <% if assess_runs.size > 0 %> +
<%= t('request_for_comments.test_results') %>
+
+ <% assess_runs.each do |testrun| %> +
+ <% end %> +
+ <% end %> +
+ <% end %> +

From dad1c2f1a3712d02e58ebb9395b19c5252457d6e Mon Sep 17 00:00:00 2001 From: Ralf Teusner Date: Wed, 27 Sep 2017 09:50:45 +0200 Subject: [PATCH 78/96] change margin top to margin bottom on request_for_comment editor (commentitor). --- app/assets/stylesheets/request-for-comments.css.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/stylesheets/request-for-comments.css.scss b/app/assets/stylesheets/request-for-comments.css.scss index 8fb7bfea..e4b56e2e 100644 --- a/app/assets/stylesheets/request-for-comments.css.scss +++ b/app/assets/stylesheets/request-for-comments.css.scss @@ -1,5 +1,5 @@ #commentitor { - margin-top: 2rem; + margin-bottom: 2rem; height: 600px; background-color:#f9f9f9 } From 5498269aec22841e406a74b55e4e2dd2ced759c3 Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Wed, 27 Sep 2017 10:21:43 +0200 Subject: [PATCH 79/96] Reorder RfC description --- app/views/request_for_comments/show.html.erb | 29 ++++++++++---------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/app/views/request_for_comments/show.html.erb b/app/views/request_for_comments/show.html.erb index 0fbeef37..4ac65629 100644 --- a/app/views/request_for_comments/show.html.erb +++ b/app/views/request_for_comments/show.html.erb @@ -37,19 +37,6 @@ <%= render('mark_as_solved') %> <% end %> - <% if @current_user.admin? && user.is_a?(ExternalUser) %> - <%= render('admin_menu') %> - <% end %> - -
-
- <%= t('request_for_comments.howto_title') %> -
-
- <%= render_markdown(t('request_for_comments.howto')) %> -
-
- <% if testruns.size > 0 %>
@@ -74,9 +61,23 @@ <% end %>
<% end %> + + <% if @current_user.admin? && user.is_a?(ExternalUser) %> + <%= render('admin_menu') %> + <% end %> + +
+ +
+
+ <%= t('request_for_comments.howto_title') %> +
+
+ <%= render_markdown(t('request_for_comments.howto')) %> +
+
-
<% if testruns.size > 0 %> -
+
<% output_runs = testruns.select { |run| run.cause == 'run' } %> <% if output_runs.size > 0 %>
<%= t('request_for_comments.runtime_output') %>
+ <% output_runs.each do |testrun| %> -

<%= testrun.try(:output) or t('request_for_comments.no_output') %>

+
<%= testrun.try(:output) or t('request_for_comments.no_output') %>
<% end %>
<% end %> @@ -142,6 +143,12 @@ also, all settings from the rails model needed for the editor configuration in t thankYouContainer.hide(); }); + $('.text > .collapse-button').on('click', function(e) { + $(this).toggleClass('fa-chevron-down'); + $(this).toggleClass('fa-chevron-up'); + $(this).parent().toggleClass('collapsed'); + }); + // set file paths for ace var ACE_FILES_PATH = '/assets/ace/'; _.each(['modePath', 'themePath', 'workerPath'], function(attribute) { diff --git a/config/locales/de.yml b/config/locales/de.yml index 88a3b1c0..f2a080de 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -494,7 +494,7 @@ de: Um Kommentare zu einer Programmzeile hinzuzufügen, kann einfach auf die jeweilige Zeilennummer auf der linken Seite geklickt werden.
Es öffnet sich ein Textfeld, in dem der Kommentar eingetragen werden kann.
Mit "Kommentar abschicken" wird der Kommentar dann gesichert und taucht als Sprechblase neben der Zeile auf. - howto_title: 'Anleitung:' + howto_title: 'Anleitung' index: get_my_comment_requests: Meine Kommentaranfragen all: "Alle Kommentaranfragen" diff --git a/config/locales/en.yml b/config/locales/en.yml index 5d9b78d8..0542bfd4 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -494,7 +494,7 @@ en: To leave comments to a specific code line, click on the respective line number.
Enter your comment in the popup and save it by clicking "Comment this".
Your comment will show up next to the line number as a speech bubble symbol. - howto_title: 'How to comment:' + howto_title: 'How to comment' index: all: All Requests for Comments get_my_comment_requests: My Requests for Comments From 54f312dfd395b4cbf8fc4ad405288d7cd3970dba Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Wed, 27 Sep 2017 15:04:52 +0200 Subject: [PATCH 82/96] Remove comment --- app/views/request_for_comments/show.html.erb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/views/request_for_comments/show.html.erb b/app/views/request_for_comments/show.html.erb index a95970f6..eb88caf1 100644 --- a/app/views/request_for_comments/show.html.erb +++ b/app/views/request_for_comments/show.html.erb @@ -36,8 +36,7 @@ <% if policy(@request_for_comment).mark_as_solved? and not @request_for_comment.solved? %> <%= render('mark_as_solved') %> <% end %> - - + <% if testruns.size > 0 %>
<% output_runs = testruns.select { |run| run.cause == 'run' } %> From 44a3cabe988df187755a69da3e285b4a6c85be12 Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Wed, 27 Sep 2017 16:08:56 +0200 Subject: [PATCH 83/96] Scaffold exercise collection routes --- .../exercise_collections_controller.rb | 24 +++++++++++++++++++ app/policies/exercise_collection_policy.rb | 3 +++ .../exercise_collections/index.html.slim | 1 + app/views/exercise_collections/show.html.slim | 1 + config/routes.rb | 2 ++ .../exercise_collections_controller_test.rb | 14 +++++++++++ 6 files changed, 45 insertions(+) create mode 100644 app/controllers/exercise_collections_controller.rb create mode 100644 app/policies/exercise_collection_policy.rb create mode 100644 app/views/exercise_collections/index.html.slim create mode 100644 app/views/exercise_collections/show.html.slim create mode 100644 test/controllers/exercise_collections_controller_test.rb diff --git a/app/controllers/exercise_collections_controller.rb b/app/controllers/exercise_collections_controller.rb new file mode 100644 index 00000000..359ed7b8 --- /dev/null +++ b/app/controllers/exercise_collections_controller.rb @@ -0,0 +1,24 @@ +class ExerciseCollectionsController < ApplicationController + + before_action :set_exercise_collection, only: [:show] + + def index + @exercise_collections = ExerciseCollection.all + authorize! + end + + def show + end + + + private + + def set_exercise_collection + @exercise_collection = ExerciseCollection.find(params[:id]) + authorize! + end + + def authorize! + authorize(@exercise_collection || @exercise_collections) + end +end diff --git a/app/policies/exercise_collection_policy.rb b/app/policies/exercise_collection_policy.rb new file mode 100644 index 00000000..ff150290 --- /dev/null +++ b/app/policies/exercise_collection_policy.rb @@ -0,0 +1,3 @@ +class ExerciseCollectionPolicy < AdminOnlyPolicy + +end diff --git a/app/views/exercise_collections/index.html.slim b/app/views/exercise_collections/index.html.slim new file mode 100644 index 00000000..03f4829c --- /dev/null +++ b/app/views/exercise_collections/index.html.slim @@ -0,0 +1 @@ +h1 = 'ExerciseCollections#index' diff --git a/app/views/exercise_collections/show.html.slim b/app/views/exercise_collections/show.html.slim new file mode 100644 index 00000000..6ed2b5f7 --- /dev/null +++ b/app/views/exercise_collections/show.html.slim @@ -0,0 +1 @@ +h1 = 'ExerciseCollection#show' diff --git a/config/routes.rb b/config/routes.rb index eb243464..7f254f1d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -74,6 +74,8 @@ Rails.application.routes.draw do end end + resources :exercise_collections + resources :proxy_exercises do member do post :clone diff --git a/test/controllers/exercise_collections_controller_test.rb b/test/controllers/exercise_collections_controller_test.rb new file mode 100644 index 00000000..699c9271 --- /dev/null +++ b/test/controllers/exercise_collections_controller_test.rb @@ -0,0 +1,14 @@ +require 'test_helper' + +class ExerciseCollectionsControllerTest < ActionController::TestCase + test "should get index" do + get :index + assert_response :success + end + + test "should get show" do + get :show + assert_response :success + end + +end From 93797a665de07cfd9b8fd70a6a4375a599218798 Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Wed, 27 Sep 2017 16:37:52 +0200 Subject: [PATCH 84/96] Implement index page --- .../exercise_collections_controller.rb | 2 +- .../exercise_collections/index.html.slim | 25 ++++++++++++++++++- config/locales/de.yml | 8 ++++++ config/locales/en.yml | 8 ++++++ 4 files changed, 41 insertions(+), 2 deletions(-) diff --git a/app/controllers/exercise_collections_controller.rb b/app/controllers/exercise_collections_controller.rb index 359ed7b8..fb4e9ba2 100644 --- a/app/controllers/exercise_collections_controller.rb +++ b/app/controllers/exercise_collections_controller.rb @@ -3,7 +3,7 @@ class ExerciseCollectionsController < ApplicationController before_action :set_exercise_collection, only: [:show] def index - @exercise_collections = ExerciseCollection.all + @exercise_collections = ExerciseCollection.all.paginate(:page => params[:page]) authorize! end diff --git a/app/views/exercise_collections/index.html.slim b/app/views/exercise_collections/index.html.slim index 03f4829c..98de8a20 100644 --- a/app/views/exercise_collections/index.html.slim +++ b/app/views/exercise_collections/index.html.slim @@ -1 +1,24 @@ -h1 = 'ExerciseCollections#index' +h1 = ExerciseCollection.model_name.human(count: 2) + +.table-responsive + table.table + thead + tr + th = t('activerecord.attributes.exercise_collections.id') + th = t('activerecord.attributes.exercise_collections.name') + th = t('activerecord.attributes.exercise_collections.updated_at') + th = t('activerecord.attributes.exercise_collections.exercises') + th colspan=3 = t('shared.actions') + tbody + - @exercise_collections.each do |collection| + tr + td = collection.id + td = link_to(collection.name, collection) + td = collection.updated_at + td = collection.exercises.size + td = link_to(t('shared.show'), collection) + td = link_to(t('shared.edit'), edit_exercise_collection_path(collection)) + td = link_to(t('shared.destroy'), collection, data: {confirm: t('shared.confirm_destroy')}, method: :delete) + += render('shared/pagination', collection: @exercise_collections) +p = render('shared/new_button', model: ExerciseCollection) \ No newline at end of file diff --git a/config/locales/de.yml b/config/locales/de.yml index 2ab23322..23232f19 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -111,6 +111,11 @@ de: name: "Name" file_type: "Dateityp" content: "Code" + exercise_collections: + id: "ID" + name: "Name" + updated_at: "Letzte Änderung" + exercises: "Aufgaben" models: code_harbor_link: one: CodeHarbor-Link @@ -127,6 +132,9 @@ de: exercise: one: Aufgabe other: Aufgaben + exercise_collection: + one: Aufgabesammlung + other: Aufgabensammlungen proxy_exercise: one: Proxy Aufgabe other: Proxy Aufgaben diff --git a/config/locales/en.yml b/config/locales/en.yml index e2cba090..543d9cd0 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -111,6 +111,11 @@ en: name: "Name" file_type: "File Type" content: "Content" + exercise_collections: + id: "ID" + name: "Name" + updated_at: "Last Update" + exercises: "Exercises" models: code_harbor_link: one: CodeHarbor Link @@ -127,6 +132,9 @@ en: exercise: one: Exercise other: Exercises + exercise_collection: + one: Exercise Collection + other: Exercise Collections proxy_exercise: one: Proxy Exercise other: Proxy Exercises From f0c0621b3114d17ffd7d54f959fb53d866c6d628 Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Wed, 27 Sep 2017 16:52:42 +0200 Subject: [PATCH 85/96] Implement show route --- app/models/exercise_collection.rb | 4 ++++ app/views/exercise_collections/show.html.slim | 12 +++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/app/models/exercise_collection.rb b/app/models/exercise_collection.rb index 2dca0e9d..f672554d 100644 --- a/app/models/exercise_collection.rb +++ b/app/models/exercise_collection.rb @@ -2,4 +2,8 @@ class ExerciseCollection < ActiveRecord::Base has_and_belongs_to_many :exercises + def to_s + "#{I18n.t('activerecord.models.exercise_collection.one')}: #{name} (#{id})" + end + end \ No newline at end of file diff --git a/app/views/exercise_collections/show.html.slim b/app/views/exercise_collections/show.html.slim index 6ed2b5f7..89081efe 100644 --- a/app/views/exercise_collections/show.html.slim +++ b/app/views/exercise_collections/show.html.slim @@ -1 +1,11 @@ -h1 = 'ExerciseCollection#show' +h1 + = @exercise_collection + = render('shared/edit_button', object: @exercise_collection) + += row(label: 'exercise_collections.name', value: @exercise_collection.name) += row(label: 'exercise_collections.updated_at', value: @exercise_collection.updated_at) + +h4 = t('activerecord.attributes.exercise_collections.exercises') +ul.list-unstyled + - @exercise_collection.exercises.sort_by{|c| c.title}.each do |exercise| + li = exercise \ No newline at end of file From 2806d9bf8547869d7cba08173d5b1688ce56e853 Mon Sep 17 00:00:00 2001 From: Ralf Teusner Date: Fri, 29 Sep 2017 16:09:42 +0200 Subject: [PATCH 86/96] specify API version in url used to open the websocket. With version 1.28 and up, docker uses binary frame format for websockets which does not seem to work with FAYE websocket. For API version 1.27 and below, text frame format is used. + short fix improvement for empty responses --- lib/docker_client.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/docker_client.rb b/lib/docker_client.rb index 76451096..add507ba 100644 --- a/lib/docker_client.rb +++ b/lib/docker_client.rb @@ -72,7 +72,7 @@ class DockerClient # Headers are required by Docker headers = {'Origin' => 'http://localhost'} - socket_url = DockerClient.config['ws_host'] + '/containers/' + @container.id + '/attach/ws?' + query_params + socket_url = DockerClient.config['ws_host'] + '/v1.27/containers/' + @container.id + '/attach/ws?' + query_params socket = Faye::WebSocket::Client.new(socket_url, [], :headers => headers) Rails.logger.debug "Opening Websocket on URL " + socket_url @@ -399,6 +399,9 @@ class DockerClient output = container.exec(['bash', '-c', command]) Rails.logger.debug "output from container.exec" Rails.logger.debug output + if(output == nil) + kill_container(container) + end result = {status: output[2] == 0 ? :ok : :failed, stdout: output[0].join.force_encoding('utf-8'), stderr: output[1].join.force_encoding('utf-8')} end # if we use pooling and recylce the containers, put it back. otherwise, destroy it. From 7cb7146e7ef190f4dcc3fec2c74a615e034e77b3 Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Wed, 4 Oct 2017 11:35:51 +0200 Subject: [PATCH 87/96] Implement update --- app/controllers/exercise_collections_controller.rb | 13 ++++++++++++- app/views/exercise_collections/_form.html.slim | 11 +++++++++++ app/views/exercise_collections/edit.html.slim | 1 + 3 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 app/views/exercise_collections/_form.html.slim create mode 100644 app/views/exercise_collections/edit.html.slim diff --git a/app/controllers/exercise_collections_controller.rb b/app/controllers/exercise_collections_controller.rb index fb4e9ba2..a00f48fd 100644 --- a/app/controllers/exercise_collections_controller.rb +++ b/app/controllers/exercise_collections_controller.rb @@ -1,6 +1,7 @@ class ExerciseCollectionsController < ApplicationController + include CommonBehavior - before_action :set_exercise_collection, only: [:show] + before_action :set_exercise_collection, only: [:show, :edit, :update] def index @exercise_collections = ExerciseCollection.all.paginate(:page => params[:page]) @@ -10,6 +11,12 @@ class ExerciseCollectionsController < ApplicationController def show end + def edit + end + + def update + update_and_respond(object: @exercise_collection, params: exercise_collection_params) + end private @@ -21,4 +28,8 @@ class ExerciseCollectionsController < ApplicationController def authorize! authorize(@exercise_collection || @exercise_collections) end + + def exercise_collection_params + params[:exercise_collection].permit(:name, :exercise_ids) + end end diff --git a/app/views/exercise_collections/_form.html.slim b/app/views/exercise_collections/_form.html.slim new file mode 100644 index 00000000..a8ebf0b2 --- /dev/null +++ b/app/views/exercise_collections/_form.html.slim @@ -0,0 +1,11 @@ +- exercises = Exercise.all + += form_for(@exercise_collection, data: {exercises: exercises}, multipart: true) do |f| + = render('shared/form_errors', object: @exercise_collection) + .form-group + = f.label(:name) + = f.text_field(:name, class: 'form-control', required: true) + .form-group + = f.label(:exercises) + = f.collection_select(:exercise_ids, exercises, :id, :title, {}, {class: 'form-control', multiple: true}) + .actions = render('shared/submit_button', f: f, object: @exercise_collection) \ No newline at end of file diff --git a/app/views/exercise_collections/edit.html.slim b/app/views/exercise_collections/edit.html.slim new file mode 100644 index 00000000..4e864ab1 --- /dev/null +++ b/app/views/exercise_collections/edit.html.slim @@ -0,0 +1 @@ += render('form') \ No newline at end of file From 8e4a6946900b99485d66392271b5c58137db3db2 Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Wed, 4 Oct 2017 11:37:21 +0200 Subject: [PATCH 88/96] Add title --- app/views/exercise_collections/edit.html.slim | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/views/exercise_collections/edit.html.slim b/app/views/exercise_collections/edit.html.slim index 4e864ab1..a3694a25 100644 --- a/app/views/exercise_collections/edit.html.slim +++ b/app/views/exercise_collections/edit.html.slim @@ -1 +1,3 @@ +h1 = @exercise_collection + = render('form') \ No newline at end of file From e74c25746cb791b3ae8c4ca4dcf260b80fea0049 Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Wed, 4 Oct 2017 12:40:37 +0200 Subject: [PATCH 89/96] Implement new action --- .../exercise_collections_controller.rb | 20 +++++++++++++++++-- app/views/exercise_collections/new.html.slim | 3 +++ 2 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 app/views/exercise_collections/new.html.slim diff --git a/app/controllers/exercise_collections_controller.rb b/app/controllers/exercise_collections_controller.rb index a00f48fd..4861a062 100644 --- a/app/controllers/exercise_collections_controller.rb +++ b/app/controllers/exercise_collections_controller.rb @@ -1,7 +1,7 @@ class ExerciseCollectionsController < ApplicationController include CommonBehavior - before_action :set_exercise_collection, only: [:show, :edit, :update] + before_action :set_exercise_collection, only: [:show, :edit, :update, :destroy] def index @exercise_collections = ExerciseCollection.all.paginate(:page => params[:page]) @@ -11,6 +11,22 @@ class ExerciseCollectionsController < ApplicationController def show end + def new + @exercise_collection = ExerciseCollection.new + authorize! + end + + def create + @exercise_collection = ExerciseCollection.new(exercise_collection_params) + authorize! + create_and_respond(object: @exercise_collection) + end + + def destroy + authorize! + destroy_and_respond(object: @exercise_collection) + end + def edit end @@ -30,6 +46,6 @@ class ExerciseCollectionsController < ApplicationController end def exercise_collection_params - params[:exercise_collection].permit(:name, :exercise_ids) + params[:exercise_collection].permit(:name, :exercise_ids => []) end end diff --git a/app/views/exercise_collections/new.html.slim b/app/views/exercise_collections/new.html.slim new file mode 100644 index 00000000..21a299f2 --- /dev/null +++ b/app/views/exercise_collections/new.html.slim @@ -0,0 +1,3 @@ +h1 = t('shared.new_model', model: ExerciseCollection.model_name.human) + += render('form') \ No newline at end of file From 70eb0d19b89049e16e44b69b51d5624f2f8a83a3 Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Wed, 4 Oct 2017 12:47:59 +0200 Subject: [PATCH 90/96] Link to exercises contained in collections --- app/views/exercise_collections/show.html.slim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/exercise_collections/show.html.slim b/app/views/exercise_collections/show.html.slim index 89081efe..ac2d0a37 100644 --- a/app/views/exercise_collections/show.html.slim +++ b/app/views/exercise_collections/show.html.slim @@ -8,4 +8,4 @@ h1 h4 = t('activerecord.attributes.exercise_collections.exercises') ul.list-unstyled - @exercise_collection.exercises.sort_by{|c| c.title}.each do |exercise| - li = exercise \ No newline at end of file + li = link_to(exercise, exercise) \ No newline at end of file From 06e99059d494a265711b29662d9a7d7974439a07 Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Wed, 4 Oct 2017 12:53:09 +0200 Subject: [PATCH 91/96] Add new lines at eof --- app/models/exercise_collection.rb | 2 +- app/views/exercise_collections/_form.html.slim | 2 +- app/views/exercise_collections/edit.html.slim | 2 +- app/views/exercise_collections/index.html.slim | 2 +- app/views/exercise_collections/new.html.slim | 2 +- app/views/exercise_collections/show.html.slim | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/models/exercise_collection.rb b/app/models/exercise_collection.rb index f672554d..10946962 100644 --- a/app/models/exercise_collection.rb +++ b/app/models/exercise_collection.rb @@ -6,4 +6,4 @@ class ExerciseCollection < ActiveRecord::Base "#{I18n.t('activerecord.models.exercise_collection.one')}: #{name} (#{id})" end -end \ No newline at end of file +end diff --git a/app/views/exercise_collections/_form.html.slim b/app/views/exercise_collections/_form.html.slim index a8ebf0b2..5acfd466 100644 --- a/app/views/exercise_collections/_form.html.slim +++ b/app/views/exercise_collections/_form.html.slim @@ -8,4 +8,4 @@ .form-group = f.label(:exercises) = f.collection_select(:exercise_ids, exercises, :id, :title, {}, {class: 'form-control', multiple: true}) - .actions = render('shared/submit_button', f: f, object: @exercise_collection) \ No newline at end of file + .actions = render('shared/submit_button', f: f, object: @exercise_collection) diff --git a/app/views/exercise_collections/edit.html.slim b/app/views/exercise_collections/edit.html.slim index a3694a25..187f31d2 100644 --- a/app/views/exercise_collections/edit.html.slim +++ b/app/views/exercise_collections/edit.html.slim @@ -1,3 +1,3 @@ h1 = @exercise_collection -= render('form') \ No newline at end of file += render('form') diff --git a/app/views/exercise_collections/index.html.slim b/app/views/exercise_collections/index.html.slim index 98de8a20..75a9d011 100644 --- a/app/views/exercise_collections/index.html.slim +++ b/app/views/exercise_collections/index.html.slim @@ -21,4 +21,4 @@ h1 = ExerciseCollection.model_name.human(count: 2) td = link_to(t('shared.destroy'), collection, data: {confirm: t('shared.confirm_destroy')}, method: :delete) = render('shared/pagination', collection: @exercise_collections) -p = render('shared/new_button', model: ExerciseCollection) \ No newline at end of file +p = render('shared/new_button', model: ExerciseCollection) diff --git a/app/views/exercise_collections/new.html.slim b/app/views/exercise_collections/new.html.slim index 21a299f2..0e48ccd9 100644 --- a/app/views/exercise_collections/new.html.slim +++ b/app/views/exercise_collections/new.html.slim @@ -1,3 +1,3 @@ h1 = t('shared.new_model', model: ExerciseCollection.model_name.human) -= render('form') \ No newline at end of file += render('form') diff --git a/app/views/exercise_collections/show.html.slim b/app/views/exercise_collections/show.html.slim index ac2d0a37..65c28283 100644 --- a/app/views/exercise_collections/show.html.slim +++ b/app/views/exercise_collections/show.html.slim @@ -8,4 +8,4 @@ h1 h4 = t('activerecord.attributes.exercise_collections.exercises') ul.list-unstyled - @exercise_collection.exercises.sort_by{|c| c.title}.each do |exercise| - li = link_to(exercise, exercise) \ No newline at end of file + li = link_to(exercise, exercise) From e7adb00dc1e1b68a4090c2b342d8b34b675e7b42 Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Wed, 4 Oct 2017 13:22:47 +0200 Subject: [PATCH 92/96] Fix empty questions in new RFC UI --- app/views/request_for_comments/show.html.erb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/views/request_for_comments/show.html.erb b/app/views/request_for_comments/show.html.erb index eb88caf1..d3751d0b 100644 --- a/app/views/request_for_comments/show.html.erb +++ b/app/views/request_for_comments/show.html.erb @@ -29,7 +29,8 @@ <%= t('activerecord.attributes.request_for_comments.question')%>
- <%= @request_for_comment.question or t('request_for_comments.no_question')%> + <% question = @request_for_comment.question %> + <%= question.nil? or question.empty? ? t('request_for_comments.no_question') : question %>
From 2582f55b1eca96f729e716e24ec0bd4053ce2fbf Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Wed, 4 Oct 2017 14:12:54 +0200 Subject: [PATCH 93/96] Add navigation link to exercise collections --- app/views/application/_navigation.html.slim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/application/_navigation.html.slim b/app/views/application/_navigation.html.slim index fbeca1c3..19f10a85 100644 --- a/app/views/application/_navigation.html.slim +++ b/app/views/application/_navigation.html.slim @@ -8,7 +8,7 @@ - if current_user.admin? li = link_to(t('breadcrumbs.dashboard.show'), admin_dashboard_path) li.divider - - models = [ExecutionEnvironment, Exercise, ProxyExercise, Tag, Consumer, CodeHarborLink, ExternalUser, FileType, FileTemplate, InternalUser].sort_by { |model| model.model_name.human(count: 2) } + - models = [ExecutionEnvironment, Exercise, ExerciseCollection, ProxyExercise, Tag, Consumer, CodeHarborLink, ExternalUser, FileType, FileTemplate, InternalUser].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")) From ee5825c71b7c5e376e53ccd68112ffc42d08618a Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Wed, 4 Oct 2017 15:42:33 +0200 Subject: [PATCH 94/96] Order exercises in form --- app/views/exercise_collections/_form.html.slim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/exercise_collections/_form.html.slim b/app/views/exercise_collections/_form.html.slim index 5acfd466..3c336a62 100644 --- a/app/views/exercise_collections/_form.html.slim +++ b/app/views/exercise_collections/_form.html.slim @@ -1,4 +1,4 @@ -- exercises = Exercise.all +- exercises = Exercise.order(:title) = form_for(@exercise_collection, data: {exercises: exercises}, multipart: true) do |f| = render('shared/form_errors', object: @exercise_collection) From b078cddc68e556f59c01ce5b4f6b8ee474fa532f Mon Sep 17 00:00:00 2001 From: Ralf Teusner Date: Wed, 4 Oct 2017 16:18:24 +0200 Subject: [PATCH 95/96] enhance testrun output --- app/controllers/concerns/submission_scoring.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/concerns/submission_scoring.rb b/app/controllers/concerns/submission_scoring.rb index 41f9ff26..f845ed0a 100644 --- a/app/controllers/concerns/submission_scoring.rb +++ b/app/controllers/concerns/submission_scoring.rb @@ -8,7 +8,7 @@ module SubmissionScoring output = execute_test_file(file, submission) assessment = assessor.assess(output) passed = ((assessment[:passed] == assessment[:count]) and (assessment[:score] > 0)) - testrun_output = passed ? nil : output[:stderr] + testrun_output = passed ? nil : 'message: ' + output[:message].to_s + '\n stdout: ' + output[:stdout].to_s + '\n stderr: ' + output[:stderr].to_s Testrun.new(submission: submission, cause: 'assess', file: file, passed: passed, output: testrun_output).save output.merge!(assessment) output.merge!(filename: file.name_with_extension, message: feedback_message(file, output[:score]), weight: file.weight) From e52c9213a1515eed2258dfe9b381267fb9ed1d83 Mon Sep 17 00:00:00 2001 From: Ralf Teusner Date: Wed, 4 Oct 2017 16:42:42 +0200 Subject: [PATCH 96/96] try to activate interpretation of carriage return --- app/controllers/concerns/submission_scoring.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/concerns/submission_scoring.rb b/app/controllers/concerns/submission_scoring.rb index f845ed0a..8891332a 100644 --- a/app/controllers/concerns/submission_scoring.rb +++ b/app/controllers/concerns/submission_scoring.rb @@ -8,7 +8,7 @@ module SubmissionScoring output = execute_test_file(file, submission) assessment = assessor.assess(output) passed = ((assessment[:passed] == assessment[:count]) and (assessment[:score] > 0)) - testrun_output = passed ? nil : 'message: ' + output[:message].to_s + '\n stdout: ' + output[:stdout].to_s + '\n stderr: ' + output[:stderr].to_s + testrun_output = passed ? nil : 'message: ' + output[:message].to_s + "\n stdout: " + output[:stdout].to_s + "\n stderr: " + output[:stderr].to_s Testrun.new(submission: submission, cause: 'assess', file: file, passed: passed, output: testrun_output).save output.merge!(assessment) output.merge!(filename: file.name_with_extension, message: feedback_message(file, output[:score]), weight: file.weight)