From e2f4991e5450891dc61f9b4d7e47f702a7035226 Mon Sep 17 00:00:00 2001 From: yqbk Date: Thu, 12 May 2016 17:09:13 +0200 Subject: [PATCH 01/68] change collapsing style --- app/views/exercises/_file_form.html.slim | 2 +- app/views/exercises/show.html.slim | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/exercises/_file_form.html.slim b/app/views/exercises/_file_form.html.slim index c737f068..5cdfdc98 100644 --- a/app/views/exercises/_file_form.html.slim +++ b/app/views/exercises/_file_form.html.slim @@ -4,7 +4,7 @@ li.panel.panel-default div.clearfix role="button" span = f.object.name a.pull-right data-toggle="collapse" data-parent="#files" href="#collapse#{id}" collapse - .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 diff --git a/app/views/exercises/show.html.slim b/app/views/exercises/show.html.slim index fc28272a..ceab96a7 100644 --- a/app/views/exercises/show.html.slim +++ b/app/views/exercises/show.html.slim @@ -29,7 +29,7 @@ ul.list-unstyled.panel-group#files div.clearfix role="button" span.panel-title = file.name_with_extension a.pull-right data-toggle="collapse" data-parent="#files" href="#collapse#{file.id}" collapse - .panel-collapse.collapse.in id="collapse#{file.id}" role="tabpanel" + .panel-collapse.collapse id="collapse#{file.id}" role="tabpanel" .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) From a16eb4b15b9ae9846cb258c1ec775f888c0d829a Mon Sep 17 00:00:00 2001 From: yqbk Date: Thu, 12 May 2016 17:13:30 +0200 Subject: [PATCH 02/68] sorting files alphabetically --- app/views/exercises/_editor.html.slim | 4 ++-- app/views/exercises/show.html.slim | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/views/exercises/_editor.html.slim b/app/views/exercises/_editor.html.slim index 42b12e42..3340d6ac 100644 --- a/app/views/exercises/_editor.html.slim +++ b/app/views/exercises/_editor.html.slim @@ -1,7 +1,7 @@ #editor.row data-exercise-id=exercise.id data-message-depleted=t('exercises.editor.depleted') data-message-timeout=t('exercises.editor.timeout', permitted_execution_time: @exercise.execution_environment.permitted_execution_time) data-errors-url=execution_environment_errors_path(exercise.execution_environment) data-submissions-url=submissions_path data-user-id=@current_user.id div class=(@exercise.hide_file_tree ? 'hidden col-sm-3' : 'col-sm-3') = render('editor_file_tree', files: @files) div id='frames' class=(@exercise.hide_file_tree ? 'col-sm-12' : 'col-sm-9') - - @files.each do |file| + - @files.sort{ |a,b| a[:group][:name] <=> b[:group][:name] }.each do |file| = render('editor_frame', exercise: exercise, file: file) #autosave-label = t('exercises.editor.lastsaved') @@ -38,4 +38,4 @@ = t('exercises.editor.test') = render('editor_button', data: {:'data-placement' => 'top', :'data-tooltip' => true}, icon: 'fa fa-trophy', id: 'assess', label: t('exercises.editor.score'), title: t('shared.tooltips.shortcut', shortcut: 'ALT + s')) -= render('shared/modal', id: 'comment-modal', title: t('exercises.implement.comment.request'), template: 'exercises/_request_comment_dialogcontent') \ No newline at end of file += render('shared/modal', id: 'comment-modal', title: t('exercises.implement.comment.request'), template: 'exercises/_request_comment_dialogcontent') diff --git a/app/views/exercises/show.html.slim b/app/views/exercises/show.html.slim index ceab96a7..85fb09cb 100644 --- a/app/views/exercises/show.html.slim +++ b/app/views/exercises/show.html.slim @@ -23,7 +23,7 @@ h1 h2 = t('activerecord.attributes.exercise.files') ul.list-unstyled.panel-group#files - - @exercise.files.each do |file| + - @exercise.files.order('name').each do |file| li.panel.panel-default .panel-heading role="tab" id="heading" div.clearfix role="button" From 10e68915d82d8db4b39aaea790c3beea1848f905 Mon Sep 17 00:00:00 2001 From: yqbk Date: Thu, 12 May 2016 17:34:30 +0200 Subject: [PATCH 03/68] add key exercise_deadline_passed --- config/locales/de.yml | 2 ++ config/locales/en.yml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/config/locales/de.yml b/config/locales/de.yml index e7d78943..30f4f7ef 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -209,8 +209,10 @@ de: submit: Code zur Bewertung abgeben test: Testen timeout: 'Ausführung gestoppt. Ihr Code hat die erlaubte Ausführungszeit von %{permitted_execution_time} Sekunden überschritten.' + exercise_deadline_passed: 'Die Abgabefrist für diese Aufgabe ist bereits abgelaufen.' tooltips: save: Ihr Code wird automatisch gespeichert, wann immer Sie eine Datei herunterladen, ausführen oder testen. Explizites Speichern ist also selten notwendig. + exercise_deadline_passed: 'Die hier erzielten Punkten können nur bis zum Ablauf der Abgabefrist an die E-Learning-Plattform übertragen werden.' request_for_comments_sent: "Kommentaranfrage gesendet." editor_file_tree: file_root: Dateien diff --git a/config/locales/en.yml b/config/locales/en.yml index f2470fc8..6cc9dcaf 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -209,8 +209,10 @@ en: submit: Submit Code For Assessment test: Test timeout: 'Execution stopped. Your code exceeded the permitted execution time of %{permitted_execution_time} seconds.' + exercise_deadline_passed: 'The deadline for this exercise has already passed' tooltips: save: Your code is automatically saved whenever you download, run, or test it. Therefore, explicitly saving is rarely necessary. + exercise_deadline_passed: 'The results for this exercise can only be submitted to the e-learning platform before the deadline has passed.' request_for_comments_sent: "Request for comments sent." editor_file_tree: file_root: Files From e838f5a1b129c32ff94b73778abd84a4bcffec57 Mon Sep 17 00:00:00 2001 From: yqbk Date: Thu, 12 May 2016 17:35:09 +0200 Subject: [PATCH 04/68] fix submit-button when not active --- app/views/exercises/implement.html.slim | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/views/exercises/implement.html.slim b/app/views/exercises/implement.html.slim index 728492b6..0c5e109b 100644 --- a/app/views/exercises/implement.html.slim +++ b/app/views/exercises/implement.html.slim @@ -78,6 +78,9 @@ br - if session[:lti_parameters].try(:has_key?, 'lis_outcome_service_url') p.text-center = render('editor_button', classes: 'btn-lg btn-success', data: {:'data-url' => submit_exercise_path(@exercise)}, icon: 'fa fa-send', id: 'submit', label: t('exercises.editor.submit')) + - else + p.text-center = render('editor_button', classes: 'btn-lg btn-warning-outline', data: {:'data-placement' => 'bottom', :'data-tooltip' => true} , icon: 'fa fa-clock-o', id: 'submit_outdated', label: t('exercises.editor.exercise_deadline_passed'), title: t('exercises.editor.tooltips.exercise_deadline_passed')) + - if qa_url #questions-column #questions-holder data-url="#{qa_url}/qa/index/#{@exercise.id}/#{@user_id}" From 5c9a9b8a476a8a1b7fe8d9d1b0e60acb6454d12b Mon Sep 17 00:00:00 2001 From: yqbk Date: Thu, 12 May 2016 17:53:21 +0200 Subject: [PATCH 05/68] add alert on submit-button click --- app/assets/javascripts/editor.js.erb | 8 ++++++++ app/views/exercises/_editor.html.slim | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/editor.js.erb b/app/assets/javascripts/editor.js.erb index c69551bb..3d9bb5cb 100644 --- a/app/assets/javascripts/editor.js.erb +++ b/app/assets/javascripts/editor.js.erb @@ -465,6 +465,7 @@ $(function() { $('#start').on('click', showWorkspaceTab); //$('#submit').on('click', confirmSubmission); $('#submit').on('click', submitCode); + $('#submit_outdated').on('click', submitOutdated); }; var initializeWorkspaceButtons = function() { @@ -751,6 +752,13 @@ $(function() { }); }; + var submitOutdated = function(event) { + $.flash.danger({ + icon: ['fa', 'fa-clock-o'], + text: $('#editor').data('message-deadline') + }); + }; + var sendError = function(message, submission_id) { showSpinner($('#render')); var jqxhr = ajax({ diff --git a/app/views/exercises/_editor.html.slim b/app/views/exercises/_editor.html.slim index 3340d6ac..39ef3bd1 100644 --- a/app/views/exercises/_editor.html.slim +++ b/app/views/exercises/_editor.html.slim @@ -1,4 +1,4 @@ -#editor.row data-exercise-id=exercise.id data-message-depleted=t('exercises.editor.depleted') data-message-timeout=t('exercises.editor.timeout', permitted_execution_time: @exercise.execution_environment.permitted_execution_time) data-errors-url=execution_environment_errors_path(exercise.execution_environment) data-submissions-url=submissions_path data-user-id=@current_user.id +#editor.row data-exercise-id=exercise.id data-message-depleted=t('exercises.editor.depleted') data-message-deadline=t('exercises.editor.deadline_alert') data-message-timeout=t('exercises.editor.timeout', permitted_execution_time: @exercise.execution_environment.permitted_execution_time) data-errors-url=execution_environment_errors_path(exercise.execution_environment) data-submissions-url=submissions_path data-user-id=@current_user.id div class=(@exercise.hide_file_tree ? 'hidden col-sm-3' : 'col-sm-3') = render('editor_file_tree', files: @files) div id='frames' class=(@exercise.hide_file_tree ? 'col-sm-12' : 'col-sm-9') - @files.sort{ |a,b| a[:group][:name] <=> b[:group][:name] }.each do |file| From 3189f615353309148ee9a56637ae25e2b635dc0c Mon Sep 17 00:00:00 2001 From: yqbk Date: Thu, 12 May 2016 18:03:33 +0200 Subject: [PATCH 06/68] no alert on outdated button --- app/assets/javascripts/editor.js.erb | 8 -------- app/views/exercises/_editor.html.slim | 2 +- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/app/assets/javascripts/editor.js.erb b/app/assets/javascripts/editor.js.erb index 3d9bb5cb..c69551bb 100644 --- a/app/assets/javascripts/editor.js.erb +++ b/app/assets/javascripts/editor.js.erb @@ -465,7 +465,6 @@ $(function() { $('#start').on('click', showWorkspaceTab); //$('#submit').on('click', confirmSubmission); $('#submit').on('click', submitCode); - $('#submit_outdated').on('click', submitOutdated); }; var initializeWorkspaceButtons = function() { @@ -752,13 +751,6 @@ $(function() { }); }; - var submitOutdated = function(event) { - $.flash.danger({ - icon: ['fa', 'fa-clock-o'], - text: $('#editor').data('message-deadline') - }); - }; - var sendError = function(message, submission_id) { showSpinner($('#render')); var jqxhr = ajax({ diff --git a/app/views/exercises/_editor.html.slim b/app/views/exercises/_editor.html.slim index 39ef3bd1..b9c41863 100644 --- a/app/views/exercises/_editor.html.slim +++ b/app/views/exercises/_editor.html.slim @@ -1,4 +1,4 @@ -#editor.row data-exercise-id=exercise.id data-message-depleted=t('exercises.editor.depleted') data-message-deadline=t('exercises.editor.deadline_alert') data-message-timeout=t('exercises.editor.timeout', permitted_execution_time: @exercise.execution_environment.permitted_execution_time) data-errors-url=execution_environment_errors_path(exercise.execution_environment) data-submissions-url=submissions_path data-user-id=@current_user.id +#editor.row data-exercise-id=exercise.id data-message-depleted=t('exercises.editor.depleted') data-message-depleted=t('exercises.editor.depleted') data-message-timeout=t('exercises.editor.timeout', permitted_execution_time: @exercise.execution_environment.permitted_execution_time) data-errors-url=execution_environment_errors_path(exercise.execution_environment) data-submissions-url=submissions_path data-user-id=@current_user.id div class=(@exercise.hide_file_tree ? 'hidden col-sm-3' : 'col-sm-3') = render('editor_file_tree', files: @files) div id='frames' class=(@exercise.hide_file_tree ? 'col-sm-12' : 'col-sm-9') - @files.sort{ |a,b| a[:group][:name] <=> b[:group][:name] }.each do |file| From d54d1dd3e8b5b8d2b8f1119523f07d046ee85c02 Mon Sep 17 00:00:00 2001 From: yqbk Date: Thu, 12 May 2016 18:22:17 +0200 Subject: [PATCH 07/68] Score given in percentage --- app/assets/javascripts/editor.js.erb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/editor.js.erb b/app/assets/javascripts/editor.js.erb index c69551bb..b40b93ec 100644 --- a/app/assets/javascripts/editor.js.erb +++ b/app/assets/javascripts/editor.js.erb @@ -706,7 +706,8 @@ $(function() { var renderScore = function() { var score = $('#score').data('score'); var maxium_score = $('#score').data('maximum-score'); - $('.score').html((score || '?') + ' / ' + maxium_score); + var percentage_score = score / maxium_score * 100 + $('.score').html((percentage_score || 0) + ' % '); renderProgressBar(score, maxium_score); }; From d05ceac7a346bff9f7864a6491efbff6a5e3cab1 Mon Sep 17 00:00:00 2001 From: yqbk Date: Thu, 12 May 2016 18:30:50 +0200 Subject: [PATCH 08/68] check if score is valid --- app/assets/javascripts/editor.js.erb | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/editor.js.erb b/app/assets/javascripts/editor.js.erb index b40b93ec..1d84361b 100644 --- a/app/assets/javascripts/editor.js.erb +++ b/app/assets/javascripts/editor.js.erb @@ -706,8 +706,13 @@ $(function() { var renderScore = function() { var score = $('#score').data('score'); var maxium_score = $('#score').data('maximum-score'); - var percentage_score = score / maxium_score * 100 - $('.score').html((percentage_score || 0) + ' % '); + if (score >= 0 && score <= maxium_score && maxium_score >0 ) { + var percentage_score = score / maxium_score * 100 + $('.score').html(percentage_score + '%'); + } + else { + $('.score').html( 0 + ' % '); + } renderProgressBar(score, maxium_score); }; From e5b3d33228599f6bf902a260b05eeed5d4404794 Mon Sep 17 00:00:00 2001 From: yqbk Date: Thu, 12 May 2016 18:34:16 +0200 Subject: [PATCH 09/68] delete spaces --- app/assets/javascripts/editor.js.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/javascripts/editor.js.erb b/app/assets/javascripts/editor.js.erb index 1d84361b..0bb22853 100644 --- a/app/assets/javascripts/editor.js.erb +++ b/app/assets/javascripts/editor.js.erb @@ -711,7 +711,7 @@ $(function() { $('.score').html(percentage_score + '%'); } else { - $('.score').html( 0 + ' % '); + $('.score').html( 0 + '%'); } renderProgressBar(score, maxium_score); }; From a2e1b08730daa61476d0c4cd426446cfe9d83e4f Mon Sep 17 00:00:00 2001 From: yqbk Date: Thu, 12 May 2016 18:40:42 +0200 Subject: [PATCH 10/68] delete duplicate depleted --- app/views/exercises/_editor.html.slim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/exercises/_editor.html.slim b/app/views/exercises/_editor.html.slim index b9c41863..3340d6ac 100644 --- a/app/views/exercises/_editor.html.slim +++ b/app/views/exercises/_editor.html.slim @@ -1,4 +1,4 @@ -#editor.row data-exercise-id=exercise.id data-message-depleted=t('exercises.editor.depleted') data-message-depleted=t('exercises.editor.depleted') data-message-timeout=t('exercises.editor.timeout', permitted_execution_time: @exercise.execution_environment.permitted_execution_time) data-errors-url=execution_environment_errors_path(exercise.execution_environment) data-submissions-url=submissions_path data-user-id=@current_user.id +#editor.row data-exercise-id=exercise.id data-message-depleted=t('exercises.editor.depleted') data-message-timeout=t('exercises.editor.timeout', permitted_execution_time: @exercise.execution_environment.permitted_execution_time) data-errors-url=execution_environment_errors_path(exercise.execution_environment) data-submissions-url=submissions_path data-user-id=@current_user.id div class=(@exercise.hide_file_tree ? 'hidden col-sm-3' : 'col-sm-3') = render('editor_file_tree', files: @files) div id='frames' class=(@exercise.hide_file_tree ? 'col-sm-12' : 'col-sm-9') - @files.sort{ |a,b| a[:group][:name] <=> b[:group][:name] }.each do |file| From d26d859df1e532fd8519020a1dd08ed6a689c52b Mon Sep 17 00:00:00 2001 From: yqbk Date: Thu, 12 May 2016 18:45:14 +0200 Subject: [PATCH 11/68] resolve confilts --- app/views/exercises/_editor.html.slim | 2 +- app/views/exercises/_file_form.html.slim | 2 +- app/views/exercises/show.html.slim | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/views/exercises/_editor.html.slim b/app/views/exercises/_editor.html.slim index 3340d6ac..0ce5b73f 100644 --- a/app/views/exercises/_editor.html.slim +++ b/app/views/exercises/_editor.html.slim @@ -1,7 +1,7 @@ #editor.row data-exercise-id=exercise.id data-message-depleted=t('exercises.editor.depleted') data-message-timeout=t('exercises.editor.timeout', permitted_execution_time: @exercise.execution_environment.permitted_execution_time) data-errors-url=execution_environment_errors_path(exercise.execution_environment) data-submissions-url=submissions_path data-user-id=@current_user.id div class=(@exercise.hide_file_tree ? 'hidden col-sm-3' : 'col-sm-3') = render('editor_file_tree', files: @files) div id='frames' class=(@exercise.hide_file_tree ? 'col-sm-12' : 'col-sm-9') - - @files.sort{ |a,b| a[:group][:name] <=> b[:group][:name] }.each do |file| + - @files.each do |file| = render('editor_frame', exercise: exercise, file: file) #autosave-label = t('exercises.editor.lastsaved') diff --git a/app/views/exercises/_file_form.html.slim b/app/views/exercises/_file_form.html.slim index 5cdfdc98..c737f068 100644 --- a/app/views/exercises/_file_form.html.slim +++ b/app/views/exercises/_file_form.html.slim @@ -4,7 +4,7 @@ li.panel.panel-default div.clearfix role="button" span = f.object.name a.pull-right data-toggle="collapse" data-parent="#files" href="#collapse#{id}" collapse - .panel-collapse.collapse id="collapse#{id}" role="tabpanel" + .panel-collapse.collapse.in 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/show.html.slim b/app/views/exercises/show.html.slim index 85fb09cb..fc28272a 100644 --- a/app/views/exercises/show.html.slim +++ b/app/views/exercises/show.html.slim @@ -23,13 +23,13 @@ h1 h2 = t('activerecord.attributes.exercise.files') ul.list-unstyled.panel-group#files - - @exercise.files.order('name').each do |file| + - @exercise.files.each do |file| li.panel.panel-default .panel-heading role="tab" id="heading" div.clearfix role="button" span.panel-title = file.name_with_extension a.pull-right data-toggle="collapse" data-parent="#files" href="#collapse#{file.id}" collapse - .panel-collapse.collapse id="collapse#{file.id}" role="tabpanel" + .panel-collapse.collapse.in id="collapse#{file.id}" role="tabpanel" .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) From f5aa3cef3ce69f453fbf1fecd9c6ebe6599feb1c Mon Sep 17 00:00:00 2001 From: yqbk Date: Thu, 12 May 2016 19:03:17 +0200 Subject: [PATCH 12/68] Problem when no files solved --- app/views/exercises/_editor.html.slim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/exercises/_editor.html.slim b/app/views/exercises/_editor.html.slim index 3340d6ac..0ce5b73f 100644 --- a/app/views/exercises/_editor.html.slim +++ b/app/views/exercises/_editor.html.slim @@ -1,7 +1,7 @@ #editor.row data-exercise-id=exercise.id data-message-depleted=t('exercises.editor.depleted') data-message-timeout=t('exercises.editor.timeout', permitted_execution_time: @exercise.execution_environment.permitted_execution_time) data-errors-url=execution_environment_errors_path(exercise.execution_environment) data-submissions-url=submissions_path data-user-id=@current_user.id div class=(@exercise.hide_file_tree ? 'hidden col-sm-3' : 'col-sm-3') = render('editor_file_tree', files: @files) div id='frames' class=(@exercise.hide_file_tree ? 'col-sm-12' : 'col-sm-9') - - @files.sort{ |a,b| a[:group][:name] <=> b[:group][:name] }.each do |file| + - @files.each do |file| = render('editor_frame', exercise: exercise, file: file) #autosave-label = t('exercises.editor.lastsaved') From 34c9d791f43c83a4b75a7d9ecba28139b0560c29 Mon Sep 17 00:00:00 2001 From: John Geiger Date: Sun, 29 May 2016 17:30:49 +0200 Subject: [PATCH 13/68] Finishing up graphs. Formatting and adding "Runs" lines. --- Gemfile | 2 +- app/assets/javascripts/exercise_graphs.js | 65 ++--- app/assets/javascripts/working_time_graphs.js | 5 +- db/schema.rb | 225 ------------------ 4 files changed, 43 insertions(+), 254 deletions(-) delete mode 100644 db/schema.rb diff --git a/Gemfile b/Gemfile index 540b11b2..bf089d6c 100644 --- a/Gemfile +++ b/Gemfile @@ -37,7 +37,7 @@ gem 'tubesock' gem 'faye-websocket' gem 'nokogiri' gem 'd3-rails' -gem 'rest-client’ +gem 'rest-client' group :development do gem 'better_errors', platform: :ruby diff --git a/app/assets/javascripts/exercise_graphs.js b/app/assets/javascripts/exercise_graphs.js index 2d3588c6..f0a9f0fc 100644 --- a/app/assets/javascripts/exercise_graphs.js +++ b/app/assets/javascripts/exercise_graphs.js @@ -9,6 +9,7 @@ $(function() { submissionsScoreAndTimeAssess = [[0,0]]; submissionsScoreAndTimeSubmits = [[0,0]]; + submissionsScoreAndTimeRuns = []; var maximumValue = 0; var wtimes = $('#wtimes').data('working_times'); //.hidden#wtimes data-working_times=ActiveSupport::JSON.encode(working_times_until) @@ -18,43 +19,38 @@ $(function() { for (var i = 0;i 0) { + submissionArray[1] = workingTime; + } + if(submission.score>maximumValue){ + maximumValue = submission.score; + } if(submission.cause == "assess"){ - var workingTime = get_minutes(wtimes[i]); - var submissionArray = [submission.score, 0]; - - if (workingTime > 0) { - submissionArray[1] = workingTime; - } - - if(submission.score>maximumValue){ - maximumValue = submission.score; - } submissionsScoreAndTimeAssess.push(submissionArray); } else if(submission.cause == "submit"){ - var workingTime = get_minutes(wtimes[i]); - var submissionArray = [submission.score, 0]; - - if (workingTime > 0) { - submissionArray[1] = workingTime; - } - - if(submission.score>maximumValue){ - maximumValue = submission.score; - } submissionsScoreAndTimeSubmits.push(submissionArray); + } else if(submission.cause == "run"){ + submissionsScoreAndTimeRuns.push(submissionArray[1]); } } // console.log(submissionsScoreAndTimeAssess.length); // console.log(submissionsScoreAndTimeSubmits); + // console.log(submissionsScoreAndTimeRuns); function get_minutes (time_stamp) { try { hours = time_stamp.split(":")[0]; minutes = time_stamp.split(":")[1]; seconds = time_stamp.split(":")[2]; - - minutes = parseFloat(hours * 60) + parseInt(minutes); + seconds /= 60; + minutes = parseFloat(hours * 60) + parseInt(minutes) + seconds; if (minutes > 0){ return minutes; } else{ @@ -82,6 +78,9 @@ $(function() { function graph_assesses() { // MAKE THE GRAPH var width_ratio = .8; + if (width_ratio > 1000){ + width_ratio = 1000; + } var height_ratio = .7; // percent of height var margin = {top: 100, right: 20, bottom: 70, left: 70},//30,50 @@ -221,10 +220,21 @@ $(function() { .attr("cx", function(d) { return x(d[1]); }) .attr("cy", function(d) { return y(d[0]); }); + for (var i = 0; i < submissionsScoreAndTimeRuns.length; i++) { + svg.append("line") + .attr("stroke", "red") + .attr("stroke-width", 1) + .attr("fill", "none")// end new + .attr("y1", y(0)) + .attr("y2", 0) + .attr("x1", x(submissionsScoreAndTimeRuns[i])) + .attr("x2", x(submissionsScoreAndTimeRuns[i])); + } var color_hash = { 0 : ["Submissions", "blue"], - 1 : ["Assesses", "orange"] - } + 1 : ["Assesses", "orange"], + 2 : ["Runs", "red"] + }; // add legend var legend = svg.append("g") @@ -234,7 +244,8 @@ $(function() { .attr("height", 100) .attr("width", 100); - var dataset = [submissionsScoreAndTimeSubmits,submissionsScoreAndTimeAssess]; + var dataset = [submissionsScoreAndTimeSubmits,submissionsScoreAndTimeAssess, submissionsScoreAndTimeRuns]; + var yOffset = -70; legend.selectAll('g').data(dataset) .enter() @@ -243,14 +254,14 @@ $(function() { var g = d3.select(this); g.append("rect") .attr("x", 20) - .attr("y", i*25 + 8) + .attr("y", i*25 + yOffset)// + 8 .attr("width", 10) .attr("height", 10) .style("fill", color_hash[String(i)][1]); g.append("text") .attr("x", 40) - .attr("y", i * 25 + 18) + .attr("y", i * 25 + yOffset + 10)// + 18 .attr("height",30) .attr("width",100) .style("fill", color_hash[String(i)][1]) diff --git a/app/assets/javascripts/working_time_graphs.js b/app/assets/javascripts/working_time_graphs.js index 315d2c09..4b6db432 100644 --- a/app/assets/javascripts/working_time_graphs.js +++ b/app/assets/javascripts/working_time_graphs.js @@ -4,7 +4,7 @@ $(function() { if ($.isController('exercises') && $('.graph-functions').isPresent()) { var working_times = $('#data').data('working-time'); - + function get_minutes (time_stamp){ try{ hours = time_stamp.split(":")[0]; @@ -67,6 +67,9 @@ $(function() { // DRAW THE LINE GRAPH ------------------------------------------------------------------------------ function draw_line_graph() { var width_ratio = .8; + if (width_ratio > 1000){ + width_ratio = 1000; + } var height_ratio = .7; // percent of height // currently sets as percentage of window width, however, unfortunately diff --git a/db/schema.rb b/db/schema.rb deleted file mode 100644 index bcf1a675..00000000 --- a/db/schema.rb +++ /dev/null @@ -1,225 +0,0 @@ -# encoding: UTF-8 -# This file is auto-generated from the current state of the database. Instead -# of editing this file, please use the migrations feature of Active Record to -# incrementally modify your database, and then regenerate this schema definition. -# -# Note that this schema.rb definition is the authoritative source for your -# database schema. If you need to create the application database on another -# system, you should be using db:schema:load, not running all the migrations -# from scratch. The latter is a flawed and unsustainable approach (the more migrations -# you'll amass, the slower it'll run and the greater likelihood for issues). -# -# It's strongly recommended that you check this file into your version control system. - -ActiveRecord::Schema.define(version: 20160510145341) do - - # These are extensions that must be enabled in order to support this database - enable_extension "plpgsql" - - create_table "code_harbor_links", force: true do |t| - t.string "oauth2token" - t.datetime "created_at" - t.datetime "updated_at" - t.integer "user_id" - end - - add_index "code_harbor_links", ["user_id"], name: "index_code_harbor_links_on_user_id", using: :btree - - create_table "comments", force: true do |t| - t.integer "user_id" - t.integer "file_id" - t.string "user_type" - t.integer "row" - t.integer "column" - t.string "text" - t.datetime "created_at" - t.datetime "updated_at" - end - - add_index "comments", ["file_id"], name: "index_comments_on_file_id", using: :btree - add_index "comments", ["user_id"], name: "index_comments_on_user_id", using: :btree - - create_table "consumers", force: true do |t| - t.string "name" - t.datetime "created_at" - t.datetime "updated_at" - t.string "oauth_key" - t.string "oauth_secret" - end - - create_table "errors", force: true do |t| - t.integer "execution_environment_id" - t.text "message" - t.datetime "created_at" - t.datetime "updated_at" - t.integer "submission_id" - end - - add_index "errors", ["submission_id"], name: "index_errors_on_submission_id", using: :btree - - create_table "execution_environments", force: true do |t| - t.string "docker_image" - t.string "name" - t.datetime "created_at" - t.datetime "updated_at" - t.string "run_command" - t.string "test_command" - t.string "testing_framework" - t.text "help" - t.string "exposed_ports" - t.integer "permitted_execution_time" - t.integer "user_id" - t.string "user_type" - t.integer "pool_size" - t.integer "file_type_id" - t.integer "memory_limit" - t.boolean "network_enabled" - end - - create_table "exercises", force: true do |t| - t.text "description" - t.integer "execution_environment_id" - t.string "title" - t.datetime "created_at" - t.datetime "updated_at" - t.integer "user_id" - t.text "instructions" - t.boolean "public" - t.string "user_type" - t.string "token" - t.integer "team_id" - t.boolean "hide_file_tree" - t.boolean "allow_file_creation" - 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" - t.string "external_id" - t.string "name" - t.datetime "created_at" - t.datetime "updated_at" - end - - create_table "file_types", force: true do |t| - t.string "editor_mode" - t.string "file_extension" - t.integer "indent_size" - t.string "name" - t.integer "user_id" - t.datetime "created_at" - t.datetime "updated_at" - t.boolean "executable" - t.boolean "renderable" - t.string "user_type" - t.boolean "binary" - end - - create_table "files", force: true do |t| - t.text "content" - t.integer "context_id" - t.string "context_type" - t.integer "file_id" - t.integer "file_type_id" - t.boolean "hidden" - t.string "name" - t.boolean "read_only" - t.datetime "created_at" - t.datetime "updated_at" - t.string "native_file" - t.string "role" - t.string "hashed_content" - t.string "feedback_message" - t.float "weight" - t.string "path" - end - - add_index "files", ["context_id", "context_type"], name: "index_files_on_context_id_and_context_type", using: :btree - - create_table "hints", force: true do |t| - t.integer "execution_environment_id" - t.string "locale" - t.text "message" - t.string "name" - t.string "regular_expression" - t.datetime "created_at" - t.datetime "updated_at" - end - - create_table "internal_users", force: true do |t| - t.integer "consumer_id" - t.string "email" - t.string "name" - t.string "role" - t.datetime "created_at" - t.datetime "updated_at" - t.string "crypted_password" - t.string "salt" - t.integer "failed_logins_count", default: 0 - t.datetime "lock_expires_at" - t.string "unlock_token" - t.string "remember_me_token" - t.datetime "remember_me_token_expires_at" - t.string "reset_password_token" - t.datetime "reset_password_token_expires_at" - t.datetime "reset_password_email_sent_at" - t.string "activation_state" - t.string "activation_token" - t.datetime "activation_token_expires_at" - end - - add_index "internal_users", ["activation_token"], name: "index_internal_users_on_activation_token", using: :btree - add_index "internal_users", ["email"], name: "index_internal_users_on_email", unique: true, using: :btree - add_index "internal_users", ["remember_me_token"], name: "index_internal_users_on_remember_me_token", using: :btree - add_index "internal_users", ["reset_password_token"], name: "index_internal_users_on_reset_password_token", using: :btree - - create_table "internal_users_teams", force: true do |t| - t.integer "internal_user_id" - t.integer "team_id" - end - - add_index "internal_users_teams", ["internal_user_id"], name: "index_internal_users_teams_on_internal_user_id", using: :btree - add_index "internal_users_teams", ["team_id"], name: "index_internal_users_teams_on_team_id", using: :btree - - create_table "request_for_comments", force: true do |t| - t.integer "user_id", null: false - t.integer "exercise_id", null: false - t.integer "file_id", null: false - t.datetime "requested_at" - t.datetime "created_at" - t.datetime "updated_at" - t.string "user_type" - t.text "question" - end - - create_table "submissions", force: true do |t| - t.integer "exercise_id" - t.float "score" - t.integer "user_id" - t.datetime "created_at" - t.datetime "updated_at" - t.string "cause" - 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 From 2ff04cf59df90dd0c3432268b8de784a6ee5d50c Mon Sep 17 00:00:00 2001 From: Ralf Teusner Date: Thu, 2 Jun 2016 15:27:36 +0200 Subject: [PATCH 14/68] fixed scaling of graphs --- app/assets/javascripts/exercise_graphs.js | 4 ++-- app/assets/javascripts/working_time_graphs.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/assets/javascripts/exercise_graphs.js b/app/assets/javascripts/exercise_graphs.js index f0a9f0fc..8b11f668 100644 --- a/app/assets/javascripts/exercise_graphs.js +++ b/app/assets/javascripts/exercise_graphs.js @@ -78,8 +78,8 @@ $(function() { function graph_assesses() { // MAKE THE GRAPH var width_ratio = .8; - if (width_ratio > 1000){ - width_ratio = 1000; + if (getWidth()*width_ratio > 1000){ + width_ratio = 1000/getWidth(); } var height_ratio = .7; // percent of height diff --git a/app/assets/javascripts/working_time_graphs.js b/app/assets/javascripts/working_time_graphs.js index 4b6db432..181b3799 100644 --- a/app/assets/javascripts/working_time_graphs.js +++ b/app/assets/javascripts/working_time_graphs.js @@ -67,8 +67,8 @@ $(function() { // DRAW THE LINE GRAPH ------------------------------------------------------------------------------ function draw_line_graph() { var width_ratio = .8; - if (width_ratio > 1000){ - width_ratio = 1000; + if (getWidth()*width_ratio > 1000){ + width_ratio = 1000/getWidth(); } var height_ratio = .7; // percent of height From 5ba980b31612c092afa8ac98d7470e57705a7636 Mon Sep 17 00:00:00 2001 From: John Geiger Date: Thu, 2 Jun 2016 15:30:18 +0200 Subject: [PATCH 15/68] Fix x-axis domain problem --- app/assets/javascripts/exercise_graphs.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/exercise_graphs.js b/app/assets/javascripts/exercise_graphs.js index 8b11f668..efde486d 100644 --- a/app/assets/javascripts/exercise_graphs.js +++ b/app/assets/javascripts/exercise_graphs.js @@ -130,8 +130,17 @@ $(function() { .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); + var largestSubmittedTimeStamp = submissions[submissions_length-1]; + var largestArrayForRange; + if(largestSubmittedTimeStamp.cause == "assess"){ + largestArrayForRange = submissionsScoreAndTimeAssess; + } else if(largestSubmittedTimeStamp.cause == "submit"){ + largestArrayForRange = submissionsScoreAndTimeSubmits; + } else if(largestSubmittedTimeStamp.cause == "run"){ + largestArrayForRange = submissionsScoreAndTimeRuns; + } - x.domain(d3.extent(submissionsScoreAndTimeAssess, function (d) { + x.domain(d3.extent(largestArrayForRange, function (d) { // console.log(d[1]); return (d[1]); })); From 3c8bd90e2b03fec1d904ccefb3e0ce89346f13e2 Mon Sep 17 00:00:00 2001 From: John Geiger Date: Thu, 2 Jun 2016 15:40:18 +0200 Subject: [PATCH 16/68] fix indexing for x axis --- app/assets/javascripts/exercise_graphs.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/app/assets/javascripts/exercise_graphs.js b/app/assets/javascripts/exercise_graphs.js index efde486d..8e6263bf 100644 --- a/app/assets/javascripts/exercise_graphs.js +++ b/app/assets/javascripts/exercise_graphs.js @@ -131,18 +131,23 @@ $(function() { .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); var largestSubmittedTimeStamp = submissions[submissions_length-1]; + var indexForTime; var largestArrayForRange; if(largestSubmittedTimeStamp.cause == "assess"){ - largestArrayForRange = submissionsScoreAndTimeAssess; + largestArrayForRange = submissionsScoreAndTimeAssess[1]; + indexForTime = 1; } else if(largestSubmittedTimeStamp.cause == "submit"){ - largestArrayForRange = submissionsScoreAndTimeSubmits; + largestArrayForRange = submissionsScoreAndTimeSubmits[1]; + indexForTime = 1; } else if(largestSubmittedTimeStamp.cause == "run"){ - largestArrayForRange = submissionsScoreAndTimeRuns; + largestArrayForRange = submissionsScoreAndTimeRuns[0]; + indexForTime = 0; + } x.domain(d3.extent(largestArrayForRange, function (d) { // console.log(d[1]); - return (d[1]); + return (d[indexForTime]); })); y.domain(d3.extent(submissionsScoreAndTimeAssess, function (d) { // console.log(d[0]); From cd005483ab4814be176f53791f326853c0ee224e Mon Sep 17 00:00:00 2001 From: Ralf Teusner Date: Thu, 2 Jun 2016 16:34:13 +0200 Subject: [PATCH 17/68] removed incorrect array accesses. --- app/assets/javascripts/exercise_graphs.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/assets/javascripts/exercise_graphs.js b/app/assets/javascripts/exercise_graphs.js index 8e6263bf..8e8e15db 100644 --- a/app/assets/javascripts/exercise_graphs.js +++ b/app/assets/javascripts/exercise_graphs.js @@ -134,13 +134,13 @@ $(function() { var indexForTime; var largestArrayForRange; if(largestSubmittedTimeStamp.cause == "assess"){ - largestArrayForRange = submissionsScoreAndTimeAssess[1]; + largestArrayForRange = submissionsScoreAndTimeAssess; indexForTime = 1; } else if(largestSubmittedTimeStamp.cause == "submit"){ - largestArrayForRange = submissionsScoreAndTimeSubmits[1]; + largestArrayForRange = submissionsScoreAndTimeSubmits; indexForTime = 1; } else if(largestSubmittedTimeStamp.cause == "run"){ - largestArrayForRange = submissionsScoreAndTimeRuns[0]; + largestArrayForRange = submissionsScoreAndTimeRuns; indexForTime = 0; } From c8b21dd7ea446987d985c9936773812aecf7a6fb Mon Sep 17 00:00:00 2001 From: Ralf Teusner Date: Fri, 3 Jun 2016 15:26:24 +0200 Subject: [PATCH 18/68] first steps for new mails on comments. --- app/mailers/user_mailer.rb | 5 +++++ app/views/user_mailer/got_new_comment.slim | 1 + 2 files changed, 6 insertions(+) create mode 100644 app/views/user_mailer/got_new_comment.slim diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb index 4b3c71f4..8cb5eed1 100644 --- a/app/mailers/user_mailer.rb +++ b/app/mailers/user_mailer.rb @@ -11,4 +11,9 @@ class UserMailer < ActionMailer::Base @reset_password_url = reset_password_internal_user_url(user, token: user.reset_password_token) mail(subject: t('mailers.user_mailer.reset_password.subject'), to: user.email) end + + def got_new_comment(comment, user, commenting_user) + @commenting_user = commenting_user + mail(subject: t('mailers.user_mailer.got_new_comment.subject'), to: user.email) + end end diff --git a/app/views/user_mailer/got_new_comment.slim b/app/views/user_mailer/got_new_comment.slim new file mode 100644 index 00000000..3b8afa5b --- /dev/null +++ b/app/views/user_mailer/got_new_comment.slim @@ -0,0 +1 @@ +== t('mailers.user_mailer.activation_needed.body', link: link_to(@activation_url, @activation_url)) From a75227c8f7ffcaab447ca5c4b69aaae887a6eafe Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Wed, 8 Jun 2016 11:49:34 +0200 Subject: [PATCH 19/68] Don't call author policy if author is missing --- app/views/exercises/index.html.slim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/exercises/index.html.slim b/app/views/exercises/index.html.slim index 97847f1f..ae018e82 100644 --- a/app/views/exercises/index.html.slim +++ b/app/views/exercises/index.html.slim @@ -27,7 +27,7 @@ h1 = Exercise.model_name.human(count: 2) - @exercises.each do |exercise| tr data-id=exercise.id td = exercise.title - td = link_to_if(policy(exercise.author).show?, exercise.author, exercise.author) + td = link_to_if(exercise.author && policy(exercise.author).show?, exercise.author, exercise.author) td = link_to_if(exercise.execution_environment && policy(exercise.execution_environment).show?, exercise.execution_environment, exercise.execution_environment) td = exercise.files.teacher_defined_tests.count td = exercise.maximum_score From 52ba35d0e4d20f4a41ad7d64a7efde1dcdee770c Mon Sep 17 00:00:00 2001 From: John Geiger Date: Wed, 8 Jun 2016 13:55:09 +0200 Subject: [PATCH 20/68] fixed graph sizing --- app/assets/javascripts/exercise_graphs.js | 38 ++++++++++++++++++----- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/app/assets/javascripts/exercise_graphs.js b/app/assets/javascripts/exercise_graphs.js index 8e8e15db..f5640788 100644 --- a/app/assets/javascripts/exercise_graphs.js +++ b/app/assets/javascripts/exercise_graphs.js @@ -10,6 +10,8 @@ $(function() { submissionsScoreAndTimeAssess = [[0,0]]; submissionsScoreAndTimeSubmits = [[0,0]]; submissionsScoreAndTimeRuns = []; + submissionsSaves = []; + submissionsAutosaves = []; var maximumValue = 0; var wtimes = $('#wtimes').data('working_times'); //.hidden#wtimes data-working_times=ActiveSupport::JSON.encode(working_times_until) @@ -38,6 +40,10 @@ $(function() { submissionsScoreAndTimeSubmits.push(submissionArray); } else if(submission.cause == "run"){ submissionsScoreAndTimeRuns.push(submissionArray[1]); + } else if(submission.cause == "autosave"){ + submissionsAutosaves.push(submissionArray[1]); + } else if(submission.cause == "save"){ + submissionsSaves.push(submissionArray[1]); } } // console.log(submissionsScoreAndTimeAssess.length); @@ -131,8 +137,8 @@ $(function() { .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); var largestSubmittedTimeStamp = submissions[submissions_length-1]; - var indexForTime; var largestArrayForRange; + if(largestSubmittedTimeStamp.cause == "assess"){ largestArrayForRange = submissionsScoreAndTimeAssess; indexForTime = 1; @@ -142,17 +148,33 @@ $(function() { } else if(largestSubmittedTimeStamp.cause == "run"){ largestArrayForRange = submissionsScoreAndTimeRuns; indexForTime = 0; - + x.domain([0,largestArrayForRange[largestArrayForRange.length - 1][1]]).clamp(true); + } else if(largestSubmittedTimeStamp.cause == "submit"){ + largestArrayForRange = submissionsScoreAndTimeSubmits; + x.domain([0,largestArrayForRange[largestArrayForRange.length - 1][1]]).clamp(true); + } else if(largestSubmittedTimeStamp.cause == "run"){ + largestArrayForRange = submissionsScoreAndTimeRuns; + x.domain([0,largestArrayForRange[largestArrayForRange.length - 1][1]]).clamp(true); + } else if(largestSubmittedTimeStamp.cause == "autosave"){ + largestArrayForRange = submissionsAutosaves; + x.domain([0,largestArrayForRange[largestArrayForRange.length - 1]]).clamp(true); + } else if(largestSubmittedTimeStamp.cause == "save"){ + largestArrayForRange = submissionsSaves; + x.domain([0,largestArrayForRange[largestArrayForRange.length - 1]]).clamp(true); } - x.domain(d3.extent(largestArrayForRange, function (d) { - // console.log(d[1]); - return (d[indexForTime]); - })); - y.domain(d3.extent(submissionsScoreAndTimeAssess, function (d) { + // x.domain(d3.extent(largestArrayForRange, function (d) { + // // console.log(d[1]); + // return (d[indexForTime]); + // })); + + // take maximum value between assesses and submits + var yDomain = submissionsScoreAndTimeAssess.concat(submissionsScoreAndTimeSubmits); + y.domain(d3.extent(yDomain, function (d) { // console.log(d[0]); return (d[0]); })); + // y.domain([0,2]).clamp(true); svg.append("g") //x axis .attr("class", "x axis") @@ -298,7 +320,7 @@ $(function() { try{ graph_assesses(); } catch(err){ - // not enough data + alert("could not draw the graph"); } } From 9e5297c1de6b0bc08b9e1d1f4507f69c5ac693a9 Mon Sep 17 00:00:00 2001 From: Ralf Teusner Date: Wed, 8 Jun 2016 14:05:13 +0200 Subject: [PATCH 21/68] re-add schema.rb --- db/schema.rb | 220 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 220 insertions(+) create mode 100644 db/schema.rb diff --git a/db/schema.rb b/db/schema.rb new file mode 100644 index 00000000..f519dfe1 --- /dev/null +++ b/db/schema.rb @@ -0,0 +1,220 @@ +# encoding: UTF-8 +# This file is auto-generated from the current state of the database. Instead +# of editing this file, please use the migrations feature of Active Record to +# incrementally modify your database, and then regenerate this schema definition. +# +# Note that this schema.rb definition is the authoritative source for your +# database schema. If you need to create the application database on another +# system, you should be using db:schema:load, not running all the migrations +# from scratch. The latter is a flawed and unsustainable approach (the more migrations +# you'll amass, the slower it'll run and the greater likelihood for issues). +# +# It's strongly recommended that you check this file into your version control system. + +ActiveRecord::Schema.define(version: 20160512131539) do + + # These are extensions that must be enabled in order to support this database + enable_extension "plpgsql" + + create_table "code_harbor_links", force: true do |t| + t.string "oauth2token" + t.datetime "created_at" + t.datetime "updated_at" + t.integer "user_id" + end + + add_index "code_harbor_links", ["user_id"], name: "index_code_harbor_links_on_user_id", using: :btree + + create_table "comments", force: true do |t| + t.integer "user_id" + t.integer "file_id" + t.string "user_type" + t.integer "row" + t.integer "column" + t.text "text" + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "comments", ["file_id"], name: "index_comments_on_file_id", using: :btree + add_index "comments", ["user_id"], name: "index_comments_on_user_id", using: :btree + + create_table "consumers", force: true do |t| + t.string "name" + t.datetime "created_at" + t.datetime "updated_at" + t.string "oauth_key" + t.string "oauth_secret" + end + + create_table "errors", force: true do |t| + t.integer "execution_environment_id" + t.text "message" + t.datetime "created_at" + t.datetime "updated_at" + t.integer "submission_id" + end + + add_index "errors", ["submission_id"], name: "index_errors_on_submission_id", using: :btree + + create_table "execution_environments", force: true do |t| + t.string "docker_image" + t.string "name" + t.datetime "created_at" + t.datetime "updated_at" + t.string "run_command" + t.string "test_command" + t.string "testing_framework" + t.text "help" + t.string "exposed_ports" + t.integer "permitted_execution_time" + t.integer "user_id" + t.string "user_type" + t.integer "pool_size" + t.integer "file_type_id" + t.integer "memory_limit" + t.boolean "network_enabled" + end + + create_table "exercises", force: true do |t| + t.text "description" + t.integer "execution_environment_id" + t.string "title" + t.datetime "created_at" + t.datetime "updated_at" + t.integer "user_id" + t.text "instructions" + t.boolean "public" + t.string "user_type" + t.string "token" + t.integer "team_id" + t.boolean "hide_file_tree" + t.boolean "allow_file_creation" + end + + create_table "external_users", force: true do |t| + t.integer "consumer_id" + t.string "email" + t.string "external_id" + t.string "name" + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "file_types", force: true do |t| + t.string "editor_mode" + t.string "file_extension" + t.integer "indent_size" + t.string "name" + t.integer "user_id" + t.datetime "created_at" + t.datetime "updated_at" + t.boolean "executable" + t.boolean "renderable" + t.string "user_type" + t.boolean "binary" + end + + create_table "files", force: true do |t| + t.text "content" + t.integer "context_id" + t.string "context_type" + t.integer "file_id" + t.integer "file_type_id" + t.boolean "hidden" + t.string "name" + t.boolean "read_only" + t.datetime "created_at" + t.datetime "updated_at" + t.string "native_file" + t.string "role" + t.string "hashed_content" + t.string "feedback_message" + t.float "weight" + t.string "path" + end + + add_index "files", ["context_id", "context_type"], name: "index_files_on_context_id_and_context_type", using: :btree + + create_table "hints", force: true do |t| + t.integer "execution_environment_id" + t.string "locale" + t.text "message" + t.string "name" + t.string "regular_expression" + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "internal_users", force: true do |t| + t.integer "consumer_id" + t.string "email" + t.string "name" + t.string "role" + t.datetime "created_at" + t.datetime "updated_at" + t.string "crypted_password" + t.string "salt" + t.integer "failed_logins_count", default: 0 + t.datetime "lock_expires_at" + t.string "unlock_token" + t.string "remember_me_token" + t.datetime "remember_me_token_expires_at" + t.string "reset_password_token" + t.datetime "reset_password_token_expires_at" + t.datetime "reset_password_email_sent_at" + t.string "activation_state" + t.string "activation_token" + t.datetime "activation_token_expires_at" + end + + add_index "internal_users", ["activation_token"], name: "index_internal_users_on_activation_token", using: :btree + add_index "internal_users", ["email"], name: "index_internal_users_on_email", unique: true, using: :btree + add_index "internal_users", ["remember_me_token"], name: "index_internal_users_on_remember_me_token", using: :btree + add_index "internal_users", ["reset_password_token"], name: "index_internal_users_on_reset_password_token", using: :btree + + create_table "internal_users_teams", force: true do |t| + t.integer "internal_user_id" + t.integer "team_id" + end + + add_index "internal_users_teams", ["internal_user_id"], name: "index_internal_users_teams_on_internal_user_id", using: :btree + add_index "internal_users_teams", ["team_id"], name: "index_internal_users_teams_on_team_id", using: :btree + + create_table "request_for_comments", force: true do |t| + t.integer "user_id", null: false + t.integer "exercise_id", null: false + t.integer "file_id", null: false + t.datetime "requested_at" + t.datetime "created_at" + t.datetime "updated_at" + t.string "user_type" + t.text "question" + end + + create_table "submissions", force: true do |t| + t.integer "exercise_id" + t.float "score" + t.integer "user_id" + t.datetime "created_at" + t.datetime "updated_at" + t.string "cause" + t.string "user_type" + end + + 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 \ No newline at end of file From 81fe1f1f14a5c2e00ce45968c2e4c4f920d92cc2 Mon Sep 17 00:00:00 2001 From: Ralf Teusner Date: Wed, 8 Jun 2016 14:07:34 +0200 Subject: [PATCH 22/68] fix end-line of schema.rb --- db/schema.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/schema.rb b/db/schema.rb index f519dfe1..104a1469 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -217,4 +217,4 @@ ActiveRecord::Schema.define(version: 20160512131539) do t.datetime "updated_at" end -end \ No newline at end of file +end From 1e4ab7cabe2ea052d4c1251a7c6c7549559b4057 Mon Sep 17 00:00:00 2001 From: Ralf Teusner Date: Fri, 10 Jun 2016 11:54:11 +0200 Subject: [PATCH 23/68] py_unit_adapter now also counts errors, not just failures --- lib/py_unit_adapter.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/py_unit_adapter.rb b/lib/py_unit_adapter.rb index f7f98dae..23b86ae9 100644 --- a/lib/py_unit_adapter.rb +++ b/lib/py_unit_adapter.rb @@ -1,6 +1,6 @@ class PyUnitAdapter < TestingFrameworkAdapter COUNT_REGEXP = /Ran (\d+) test/ - FAILURES_REGEXP = /FAILED \(failures=(\d+)\)/ + FAILURES_REGEXP = /FAILED \((failures)|(errors)=(\d+)\)/ ASSERTION_ERROR_REGEXP = /AssertionError:\s(.*)/ def self.framework_name @@ -10,7 +10,7 @@ class PyUnitAdapter < TestingFrameworkAdapter def parse_output(output) count = COUNT_REGEXP.match(output[:stderr]).captures.first.to_i matches = FAILURES_REGEXP.match(output[:stderr]) - failed = matches ? matches.captures.try(:first).to_i : 0 + failed = matches ? matches.captures.try(:third).to_i : 0 error_matches = ASSERTION_ERROR_REGEXP.match(output[:stderr]).try(:captures) || [] {count: count, failed: failed, error_messages: error_matches} end From 74b33492cb58a25c2efca4fff1f4a9c52c14dd4c Mon Sep 17 00:00:00 2001 From: Ralf Teusner Date: Tue, 14 Jun 2016 10:42:15 +0200 Subject: [PATCH 24/68] fixed python failure regex. --- lib/py_unit_adapter.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/py_unit_adapter.rb b/lib/py_unit_adapter.rb index 23b86ae9..11b8cb09 100644 --- a/lib/py_unit_adapter.rb +++ b/lib/py_unit_adapter.rb @@ -1,6 +1,6 @@ class PyUnitAdapter < TestingFrameworkAdapter COUNT_REGEXP = /Ran (\d+) test/ - FAILURES_REGEXP = /FAILED \((failures)|(errors)=(\d+)\)/ + FAILURES_REGEXP = /FAILED \((failures|errors)=(\d+)\)/ ASSERTION_ERROR_REGEXP = /AssertionError:\s(.*)/ def self.framework_name @@ -10,7 +10,7 @@ class PyUnitAdapter < TestingFrameworkAdapter def parse_output(output) count = COUNT_REGEXP.match(output[:stderr]).captures.first.to_i matches = FAILURES_REGEXP.match(output[:stderr]) - failed = matches ? matches.captures.try(:third).to_i : 0 + failed = matches ? matches.captures.try(:second).to_i : 0 error_matches = ASSERTION_ERROR_REGEXP.match(output[:stderr]).try(:captures) || [] {count: count, failed: failed, error_messages: error_matches} end From f2e2c232e48b42e5c3e7c70299c1e41466ddfc35 Mon Sep 17 00:00:00 2001 From: yqbk Date: Tue, 14 Jun 2016 17:01:50 +0200 Subject: [PATCH 25/68] round result to fixed 2 digits --- app/assets/javascripts/editor.js.erb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/editor.js.erb b/app/assets/javascripts/editor.js.erb index 0bb22853..10123521 100644 --- a/app/assets/javascripts/editor.js.erb +++ b/app/assets/javascripts/editor.js.erb @@ -707,7 +707,8 @@ $(function() { var score = $('#score').data('score'); var maxium_score = $('#score').data('maximum-score'); if (score >= 0 && score <= maxium_score && maxium_score >0 ) { - var percentage_score = score / maxium_score * 100 + var rounded_number = (score / maxium_score ).toFixed(2); + var percentage_score = rounded_number * 100 $('.score').html(percentage_score + '%'); } else { From d5b78c29da39c15df6a61e7de1da83cf2b3f1e63 Mon Sep 17 00:00:00 2001 From: Ralf Teusner Date: Tue, 14 Jun 2016 17:19:52 +0200 Subject: [PATCH 26/68] Fixed rounding issue caused by JavaScript and the conversion to String. --- app/assets/javascripts/editor.js.erb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/assets/javascripts/editor.js.erb b/app/assets/javascripts/editor.js.erb index 10123521..50217b1f 100644 --- a/app/assets/javascripts/editor.js.erb +++ b/app/assets/javascripts/editor.js.erb @@ -707,8 +707,7 @@ $(function() { var score = $('#score').data('score'); var maxium_score = $('#score').data('maximum-score'); if (score >= 0 && score <= maxium_score && maxium_score >0 ) { - var rounded_number = (score / maxium_score ).toFixed(2); - var percentage_score = rounded_number * 100 + var percentage_score = (score / maxium_score * 100 ).toFixed(2); $('.score').html(percentage_score + '%'); } else { From a1ead9658e22f413eadd719a1c251bfbb49c9bce Mon Sep 17 00:00:00 2001 From: tstaubitz Date: Tue, 14 Jun 2016 17:27:15 +0200 Subject: [PATCH 27/68] Update de.yml --- config/locales/de.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/locales/de.yml b/config/locales/de.yml index 30f4f7ef..ae7fb930 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -212,7 +212,7 @@ de: exercise_deadline_passed: 'Die Abgabefrist für diese Aufgabe ist bereits abgelaufen.' tooltips: save: Ihr Code wird automatisch gespeichert, wann immer Sie eine Datei herunterladen, ausführen oder testen. Explizites Speichern ist also selten notwendig. - exercise_deadline_passed: 'Die hier erzielten Punkten können nur bis zum Ablauf der Abgabefrist an die E-Learning-Plattform übertragen werden.' + exercise_deadline_passed: 'Die hier erzielten Punkte können nur bis zum Ablauf der Abgabefrist an die E-Learning-Plattform übertragen werden.' request_for_comments_sent: "Kommentaranfrage gesendet." editor_file_tree: file_root: Dateien From 8ddf1e158e02410874fe4354ae6eb3067f2cdc2e Mon Sep 17 00:00:00 2001 From: Ralf Teusner Date: Tue, 14 Jun 2016 17:53:54 +0200 Subject: [PATCH 28/68] Fixed background and pen coloring on client side (javascript). See: https://github.com/openHPI/codeocean/issues/59 Kudos to waywwaard. --- app/assets/javascripts/turtle.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/app/assets/javascripts/turtle.js b/app/assets/javascripts/turtle.js index f2fa184b..ddbb27eb 100644 --- a/app/assets/javascripts/turtle.js +++ b/app/assets/javascripts/turtle.js @@ -41,8 +41,7 @@ Turtle.prototype.update = function () { var i, k, canvas, ctx, dx, dy, item, c, length; canvas = this.canvas[0]; ctx = canvas.getContext('2d'); - ctx.fillStyle = '#fff'; - ctx.fillRect(0, 0, canvas.width, canvas.height); + ctx.clearRect(0, 0, canvas.width, canvas.height); length = this.items.length; dx = canvas.width / 2; dy = canvas.height / 2; @@ -56,8 +55,8 @@ Turtle.prototype.update = function () { for (k = 2; k < c.length; k += 2) { ctx.lineTo(c[k] + dx, c[k + 1] + dy); } - if (this.fill) { - ctx.strokeStyle = this.fill; + if (item.fill) { + ctx.strokeStyle = item.fill; } ctx.stroke(); From 894f8abda233fd00dd0efe6bcb2b2cd704592f63 Mon Sep 17 00:00:00 2001 From: yqbk Date: Wed, 15 Jun 2016 12:03:34 +0200 Subject: [PATCH 29/68] round result to fixed 0 digits in percentage output --- app/assets/javascripts/editor.js.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/javascripts/editor.js.erb b/app/assets/javascripts/editor.js.erb index 50217b1f..f000a23a 100644 --- a/app/assets/javascripts/editor.js.erb +++ b/app/assets/javascripts/editor.js.erb @@ -707,7 +707,7 @@ $(function() { var score = $('#score').data('score'); var maxium_score = $('#score').data('maximum-score'); if (score >= 0 && score <= maxium_score && maxium_score >0 ) { - var percentage_score = (score / maxium_score * 100 ).toFixed(2); + var percentage_score = (score / maxium_score * 100 ).toFixed(0); $('.score').html(percentage_score + '%'); } else { From fbb83e3057ddb4fe01c77badb8d637bc8df4e618 Mon Sep 17 00:00:00 2001 From: Ralf Teusner Date: Thu, 16 Jun 2016 11:38:16 +0200 Subject: [PATCH 30/68] fix comparison problem caused by javascript comparisons based on Strings. ("1.00" <= "1.0" --> false) --- app/assets/javascripts/editor.js.erb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/editor.js.erb b/app/assets/javascripts/editor.js.erb index f000a23a..1e64195e 100644 --- a/app/assets/javascripts/editor.js.erb +++ b/app/assets/javascripts/editor.js.erb @@ -704,8 +704,8 @@ $(function() { }; var renderScore = function() { - var score = $('#score').data('score'); - var maxium_score = $('#score').data('maximum-score'); + var score = parseFloat($('#score').data('score')); + var maxium_score = parseFloat($('#score').data('maximum-score')); if (score >= 0 && score <= maxium_score && maxium_score >0 ) { var percentage_score = (score / maxium_score * 100 ).toFixed(0); $('.score').html(percentage_score + '%'); From 9e644563e3eae71b48b990323c3d9fd545628cf9 Mon Sep 17 00:00:00 2001 From: Ralf Teusner Date: Thu, 16 Jun 2016 11:39:13 +0200 Subject: [PATCH 31/68] adapt regex for py_unit_adapter once more... hopefully we got all cases now. --- lib/py_unit_adapter.rb | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/py_unit_adapter.rb b/lib/py_unit_adapter.rb index 11b8cb09..1ff5cd98 100644 --- a/lib/py_unit_adapter.rb +++ b/lib/py_unit_adapter.rb @@ -1,6 +1,7 @@ class PyUnitAdapter < TestingFrameworkAdapter COUNT_REGEXP = /Ran (\d+) test/ - FAILURES_REGEXP = /FAILED \((failures|errors)=(\d+)\)/ + FAILURES_REGEXP = /FAILED \(.*failures=(\d+).*\)/ + ERRORS_REGEXP = /FAILED \(.*errors=(\d+).*\)/ ASSERTION_ERROR_REGEXP = /AssertionError:\s(.*)/ def self.framework_name @@ -9,9 +10,11 @@ class PyUnitAdapter < TestingFrameworkAdapter def parse_output(output) count = COUNT_REGEXP.match(output[:stderr]).captures.first.to_i - matches = FAILURES_REGEXP.match(output[:stderr]) - failed = matches ? matches.captures.try(:second).to_i : 0 - error_matches = ASSERTION_ERROR_REGEXP.match(output[:stderr]).try(:captures) || [] - {count: count, failed: failed, error_messages: error_matches} + failures_matches = FAILURES_REGEXP.match(output[:stderr]) + failed = failures_matches ? failures_matches.captures.try(:first).to_i : 0 + error_matches = ERRORS_REGEXP.match(output[:stderr]) + errors = error_matches ? error_matches.captures.try(:first).to_i : 0 + assertion_error_matches = ASSERTION_ERROR_REGEXP.match(output[:stderr]).try(:captures) || [] + {count: count, failed: failed + errors, error_messages: assertion_error_matches} end end From ec26a095f692e2102e8a87ea85d36e1655582099 Mon Sep 17 00:00:00 2001 From: Ralf Teusner Date: Fri, 17 Jun 2016 14:48:57 +0200 Subject: [PATCH 32/68] First working version of mails on comments. --- app/controllers/comments_controller.rb | 14 +++++++++++--- app/mailers/user_mailer.rb | 10 +++++++--- app/views/request_for_comments/show.html.erb | 5 +++-- app/views/user_mailer/got_new_comment.slim | 2 +- config/locales/de.yml | 7 +++++++ config/locales/en.yml | 10 ++++++++++ 6 files changed, 39 insertions(+), 9 deletions(-) diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb index fd6840ff..fe7f454c 100644 --- a/app/controllers/comments_controller.rb +++ b/app/controllers/comments_controller.rb @@ -46,7 +46,11 @@ class CommentsController < ApplicationController # POST /comments # POST /comments.json def create - @comment = Comment.new(comment_params) + @comment = Comment.new(comment_params_without_request_id) + + if comment_params[:request_id] + UserMailer.got_new_comment(@comment, RequestForComment.find(comment_params[:request_id]), current_user) + end respond_to do |format| if @comment.save @@ -64,7 +68,7 @@ class CommentsController < ApplicationController # PATCH/PUT /comments/1.json def update respond_to do |format| - if @comment.update(comment_params) + if @comment.update(comment_params_without_request_id) format.html { head :no_content, notice: 'Comment was successfully updated.' } format.json { render :show, status: :ok, location: @comment } else @@ -101,10 +105,14 @@ class CommentsController < ApplicationController @comment = Comment.find(params[:id]) end + def comment_params_without_request_id + comment_params.except :request_id + end + # Never trust parameters from the scary internet, only allow the white list through. def comment_params #params.require(:comment).permit(:user_id, :file_id, :row, :column, :text) # fuer production mode, damit böse menschen keine falsche user_id uebergeben: - params.require(:comment).permit(:file_id, :row, :column, :text).merge(user_id: current_user.id, user_type: current_user.class.name) + params.require(:comment).permit(:file_id, :row, :column, :text, :request_id).merge(user_id: current_user.id, user_type: current_user.class.name) end end diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb index 8cb5eed1..e1773d48 100644 --- a/app/mailers/user_mailer.rb +++ b/app/mailers/user_mailer.rb @@ -12,8 +12,12 @@ class UserMailer < ActionMailer::Base mail(subject: t('mailers.user_mailer.reset_password.subject'), to: user.email) end - def got_new_comment(comment, user, commenting_user) - @commenting_user = commenting_user - mail(subject: t('mailers.user_mailer.got_new_comment.subject'), to: user.email) + def got_new_comment(comment, request_for_comment, commenting_user) + # todo: check whether we can take the last known locale of the receiver? + @receiver_displayname = request_for_comment.user.displayname + @commenting_user_displayname = commenting_user.displayname + @comment_text = comment.text + @rfc_link = request_for_comment_url(request_for_comment) + mail(subject: t('mailers.user_mailer.got_new_comment.subject', commenting_user_displayname: @commenting_user_displayname), to: request_for_comment.user.email).deliver end end diff --git a/app/views/request_for_comments/show.html.erb b/app/views/request_for_comments/show.html.erb index e4dc7f06..1d6bb54c 100644 --- a/app/views/request_for_comments/show.html.erb +++ b/app/views/request_for_comments/show.html.erb @@ -1,5 +1,5 @@
-

<%= Exercise.find(@request_for_comment.exercise_id) %>

+

<%= Exercise.find(@request_for_comment.exercise_id) %>

<% user = @request_for_comment.user @@ -101,7 +101,8 @@ do not put a carriage return in the line below. it will be present in the presen file_id: file_id, row: row, column: 0, - text: commenttext + text: commenttext, + request_id: $('h4').data('rfc-id') } }, dataType: 'json', diff --git a/app/views/user_mailer/got_new_comment.slim b/app/views/user_mailer/got_new_comment.slim index 3b8afa5b..656e245d 100644 --- a/app/views/user_mailer/got_new_comment.slim +++ b/app/views/user_mailer/got_new_comment.slim @@ -1 +1 @@ -== t('mailers.user_mailer.activation_needed.body', link: link_to(@activation_url, @activation_url)) +== t('mailers.user_mailer.got_new_comment.body', receiver_displayname: @receiver_displayname, link: link_to(@rfc_link, @rfc_link), commenting_user_displayname: @commenting_user_displayname, comment_text: @comment_text) diff --git a/config/locales/de.yml b/config/locales/de.yml index ae7fb930..a3b580b5 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -325,6 +325,13 @@ de: activation_needed: body: 'Bitte besuchen Sie %{link} und wählen Sie ein Passwort, um Ihre Registrierung abzuschließen.' subject: Bitte schließen Sie Ihre Registrierung ab. + got_new_comment: + body: | + Hallo %{receiver_displayname}, + + es gibt einen neuen Kommentar von %{commenting_user_displayname} zu Ihrer Kommentaranfrage auf CodeOcean. + Sie finden ihn hier: %{link} + subject: Sie haben einen neuen Kommentar von %{commenting_user_displayname} auf CodeOcean erhalten. reset_password: body: 'Bitte besuchen Sie %{link}, sofern Sie Ihr Passwort zurücksetzen wollen.' subject: Anweisungen zum Zurücksetzen Ihres Passworts diff --git a/config/locales/en.yml b/config/locales/en.yml index 6cc9dcaf..1162971d 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -325,6 +325,16 @@ en: activation_needed: body: 'Please visit %{link} and set up a password in order to complete your registration.' subject: Please complete your registration. + got_new_comment: + body: | + Dear %{receiver_displayname}, + + you received a new comment from %{commenting_user_displayname} to your request for comments on CodeOcean. + You can find it here: %{link} + + Best regards, + your Teaching Team + subject: 'You received a new comment on CodeOcean from %{commenting_user_displayname}.' reset_password: body: 'Please visit %{link} if you want to reset your password.' subject: Password reset instructions From 003e89b23043645cf0ec01e4473722a8f18f8805 Mon Sep 17 00:00:00 2001 From: John Geiger Date: Fri, 17 Jun 2016 15:03:07 +0200 Subject: [PATCH 33/68] x axis stuff --- app/assets/javascripts/exercise_graphs.js | 33 +++++++---------------- 1 file changed, 10 insertions(+), 23 deletions(-) diff --git a/app/assets/javascripts/exercise_graphs.js b/app/assets/javascripts/exercise_graphs.js index f5640788..f98509b3 100644 --- a/app/assets/javascripts/exercise_graphs.js +++ b/app/assets/javascripts/exercise_graphs.js @@ -141,20 +141,13 @@ $(function() { if(largestSubmittedTimeStamp.cause == "assess"){ largestArrayForRange = submissionsScoreAndTimeAssess; - indexForTime = 1; - } else if(largestSubmittedTimeStamp.cause == "submit"){ - largestArrayForRange = submissionsScoreAndTimeSubmits; - indexForTime = 1; - } else if(largestSubmittedTimeStamp.cause == "run"){ - largestArrayForRange = submissionsScoreAndTimeRuns; - indexForTime = 0; x.domain([0,largestArrayForRange[largestArrayForRange.length - 1][1]]).clamp(true); } else if(largestSubmittedTimeStamp.cause == "submit"){ largestArrayForRange = submissionsScoreAndTimeSubmits; x.domain([0,largestArrayForRange[largestArrayForRange.length - 1][1]]).clamp(true); } else if(largestSubmittedTimeStamp.cause == "run"){ largestArrayForRange = submissionsScoreAndTimeRuns; - x.domain([0,largestArrayForRange[largestArrayForRange.length - 1][1]]).clamp(true); + x.domain([0,largestArrayForRange[largestArrayForRange.length - 1]]).clamp(true); } else if(largestSubmittedTimeStamp.cause == "autosave"){ largestArrayForRange = submissionsAutosaves; x.domain([0,largestArrayForRange[largestArrayForRange.length - 1]]).clamp(true); @@ -162,12 +155,6 @@ $(function() { largestArrayForRange = submissionsSaves; x.domain([0,largestArrayForRange[largestArrayForRange.length - 1]]).clamp(true); } - - // x.domain(d3.extent(largestArrayForRange, function (d) { - // // console.log(d[1]); - // return (d[indexForTime]); - // })); - // take maximum value between assesses and submits var yDomain = submissionsScoreAndTimeAssess.concat(submissionsScoreAndTimeSubmits); y.domain(d3.extent(yDomain, function (d) { @@ -212,15 +199,15 @@ $(function() { .style('font-size', 20) .style('text-decoration', 'underline'); - // - // svg.append("path") - // //.datum() - // .attr("class", "line") - // .attr('id', 'myPath')// new - // .attr("stroke", "black") - // .attr("stroke-width", 5) - // .attr("fill", "none")// end new - // .attr("d", line(submissionsScoreAndTimeAssess));//--- + + svg.append("path") + //.datum() + .attr("class", "line") + .attr('id', 'myPath')// new + .attr("stroke", "black") + .attr("stroke-width", 5) + .attr("fill", "none")// end new + .attr("d", line(submissionsScoreAndTimeAssess));//--- svg.append("path") .datum(submissionsScoreAndTimeAssess) From 5840b626922ba4e990a2f6ff9b11f501594966ad Mon Sep 17 00:00:00 2001 From: Ralf Teusner Date: Fri, 17 Jun 2016 15:04:17 +0200 Subject: [PATCH 34/68] 2nd part of the fix. --- app/assets/javascripts/exercise_graphs.js | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/app/assets/javascripts/exercise_graphs.js b/app/assets/javascripts/exercise_graphs.js index f98509b3..5f521b39 100644 --- a/app/assets/javascripts/exercise_graphs.js +++ b/app/assets/javascripts/exercise_graphs.js @@ -226,20 +226,17 @@ $(function() { .attr("cx", function(d) { return x(d[1]); }) .attr("cy", function(d) { return y(d[0]); }); - - svg.append("path") - .datum(submissionsScoreAndTimeSubmits) - .attr("class", "line2") - .attr('id', 'myPath')// new - .attr("stroke", "blue") - .attr("stroke-width", 5) - .attr("fill", "none")// end new - .attr("d", line);//--- + if (submissionsScoreAndTimeSubmits.length > 0){ + // get rid of the 0 element at the beginning + submissionsScoreAndTimeSubmits.shift(); + } svg.selectAll("dot") // Add dots to submits .data(submissionsScoreAndTimeSubmits) .enter().append("circle") - .attr("r", 3.5) + .attr("r", 6) + .attr("stroke", "black") + .attr("fill", "blue") .attr("cx", function(d) { return x(d[1]); }) .attr("cy", function(d) { return y(d[0]); }); From 918da5270dddb74fd9b985ef7f18547f4b8c5d5c Mon Sep 17 00:00:00 2001 From: Ralf Teusner Date: Wed, 22 Jun 2016 13:06:35 +0200 Subject: [PATCH 35/68] added id for h4 holding the rfc-id updated locales. --- app/views/request_for_comments/show.html.erb | 4 ++-- config/locales/de.yml | 2 ++ config/locales/en.yml | 3 +-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/app/views/request_for_comments/show.html.erb b/app/views/request_for_comments/show.html.erb index 1d6bb54c..3f353e32 100644 --- a/app/views/request_for_comments/show.html.erb +++ b/app/views/request_for_comments/show.html.erb @@ -1,5 +1,5 @@

-

<%= Exercise.find(@request_for_comment.exercise_id) %>

+

<%= Exercise.find(@request_for_comment.exercise_id) %>

<% user = @request_for_comment.user @@ -102,7 +102,7 @@ do not put a carriage return in the line below. it will be present in the presen row: row, column: 0, text: commenttext, - request_id: $('h4').data('rfc-id') + request_id: $('h4#exercise_caption').data('rfc-id') } }, dataType: 'json', diff --git a/config/locales/de.yml b/config/locales/de.yml index a3b580b5..a4d69694 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -331,6 +331,8 @@ de: es gibt einen neuen Kommentar von %{commenting_user_displayname} zu Ihrer Kommentaranfrage auf CodeOcean. Sie finden ihn hier: %{link} + + Diese Mail wurde automatisch von CodeOcean verschickt. subject: Sie haben einen neuen Kommentar von %{commenting_user_displayname} auf CodeOcean erhalten. reset_password: body: 'Bitte besuchen Sie %{link}, sofern Sie Ihr Passwort zurücksetzen wollen.' diff --git a/config/locales/en.yml b/config/locales/en.yml index 1162971d..28344446 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -332,8 +332,7 @@ en: you received a new comment from %{commenting_user_displayname} to your request for comments on CodeOcean. You can find it here: %{link} - Best regards, - your Teaching Team + This mail was automatically sent by CodeOcean. subject: 'You received a new comment on CodeOcean from %{commenting_user_displayname}.' reset_password: body: 'Please visit %{link} if you want to reset your password.' From 83cf3b23212fcf78f3953a9dbb3697cc5dbac6c6 Mon Sep 17 00:00:00 2001 From: Ralf Teusner Date: Wed, 22 Jun 2016 14:16:23 +0200 Subject: [PATCH 36/68] added line breaks (
tags) in the email body. --- config/locales/de.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/config/locales/de.yml b/config/locales/de.yml index a4d69694..32ab47ee 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -327,12 +327,12 @@ de: subject: Bitte schließen Sie Ihre Registrierung ab. got_new_comment: body: | - Hallo %{receiver_displayname}, - + Hallo %{receiver_displayname},
+
es gibt einen neuen Kommentar von %{commenting_user_displayname} zu Ihrer Kommentaranfrage auf CodeOcean. - Sie finden ihn hier: %{link} - - Diese Mail wurde automatisch von CodeOcean verschickt. + Sie finden ihn hier: %{link}
+
+ Diese Mail wurde automatisch von CodeOcean verschickt.
subject: Sie haben einen neuen Kommentar von %{commenting_user_displayname} auf CodeOcean erhalten. reset_password: body: 'Bitte besuchen Sie %{link}, sofern Sie Ihr Passwort zurücksetzen wollen.' From e0eac2036114a75726bb7242dc044cdcec295cff Mon Sep 17 00:00:00 2001 From: Ralf Teusner Date: Wed, 22 Jun 2016 14:21:17 +0200 Subject: [PATCH 37/68] added some more line breaks to the mail bodys of mails on new comments. --- config/locales/de.yml | 2 +- config/locales/en.yml | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/config/locales/de.yml b/config/locales/de.yml index 32ab47ee..7f0afc00 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -329,7 +329,7 @@ de: body: | Hallo %{receiver_displayname},

- es gibt einen neuen Kommentar von %{commenting_user_displayname} zu Ihrer Kommentaranfrage auf CodeOcean. + es gibt einen neuen Kommentar von %{commenting_user_displayname} zu Ihrer Kommentaranfrage auf CodeOcean.
Sie finden ihn hier: %{link}

Diese Mail wurde automatisch von CodeOcean verschickt.
diff --git a/config/locales/en.yml b/config/locales/en.yml index 28344446..d622ea88 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -327,11 +327,11 @@ en: subject: Please complete your registration. got_new_comment: body: | - Dear %{receiver_displayname}, - - you received a new comment from %{commenting_user_displayname} to your request for comments on CodeOcean. - You can find it here: %{link} - + Dear %{receiver_displayname},
+
+ you received a new comment from %{commenting_user_displayname} to your request for comments on CodeOcean.
+ You can find it here: %{link}
+
This mail was automatically sent by CodeOcean. subject: 'You received a new comment on CodeOcean from %{commenting_user_displayname}.' reset_password: From b7ce38996108409242e8335ca769736adcb76d51 Mon Sep 17 00:00:00 2001 From: Ralf Teusner Date: Thu, 23 Jun 2016 10:47:44 +0200 Subject: [PATCH 38/68] Adapted locales so that german as well as english texts are now sent for every new comment. --- config/locales/de.yml | 12 ++++++++++++ config/locales/en.yml | 14 +++++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/config/locales/de.yml b/config/locales/de.yml index 7f0afc00..d227e7b7 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -327,12 +327,24 @@ de: subject: Bitte schließen Sie Ihre Registrierung ab. got_new_comment: body: | + English version below
+ _________________________
+
Hallo %{receiver_displayname},

es gibt einen neuen Kommentar von %{commenting_user_displayname} zu Ihrer Kommentaranfrage auf CodeOcean.
Sie finden ihn hier: %{link}

Diese Mail wurde automatisch von CodeOcean verschickt.
+
+ _________________________
+
+ Dear %{receiver_displayname},
+
+ you received a new comment from %{commenting_user_displayname} to your request for comments on CodeOcean.
+ You can find it here: %{link}
+
+ This mail was automatically sent by CodeOcean.
subject: Sie haben einen neuen Kommentar von %{commenting_user_displayname} auf CodeOcean erhalten. reset_password: body: 'Bitte besuchen Sie %{link}, sofern Sie Ihr Passwort zurücksetzen wollen.' diff --git a/config/locales/en.yml b/config/locales/en.yml index d622ea88..684a350d 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -327,12 +327,24 @@ en: subject: Please complete your registration. got_new_comment: body: | + English version below
+ _________________________
+
+ Hallo %{receiver_displayname},
+
+ es gibt einen neuen Kommentar von %{commenting_user_displayname} zu Ihrer Kommentaranfrage auf CodeOcean.
+ Sie finden ihn hier: %{link}
+
+ Diese Mail wurde automatisch von CodeOcean verschickt.
+
+ _________________________
+
Dear %{receiver_displayname},

you received a new comment from %{commenting_user_displayname} to your request for comments on CodeOcean.
You can find it here: %{link}

- This mail was automatically sent by CodeOcean. + This mail was automatically sent by CodeOcean.
subject: 'You received a new comment on CodeOcean from %{commenting_user_displayname}.' reset_password: body: 'Please visit %{link} if you want to reset your password.' From bd6d4c4d71987ecee9dd7d7237975399a1e27378 Mon Sep 17 00:00:00 2001 From: Ralf Teusner Date: Thu, 23 Jun 2016 14:23:28 +0200 Subject: [PATCH 39/68] Syntax Highlighting for the Request for Comment View --- app/views/request_for_comments/show.html.erb | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/app/views/request_for_comments/show.html.erb b/app/views/request_for_comments/show.html.erb index 3f353e32..a1ffb5ff 100644 --- a/app/views/request_for_comments/show.html.erb +++ b/app/views/request_for_comments/show.html.erb @@ -25,22 +25,32 @@ <% submission.files.each do |file| %> <%= (file.path or "") + "/" + file.name + file.file_type.file_extension %> -

<%= file.content %> +
<%= file.content %>
<% end %> <%= render('shared/modal', id: 'comment-modal', title: t('exercises.implement.comment.dialogtitle'), template: 'exercises/_comment_dialogcontent') %>