From c8b21dd7ea446987d985c9936773812aecf7a6fb Mon Sep 17 00:00:00 2001 From: Ralf Teusner Date: Fri, 3 Jun 2016 15:26:24 +0200 Subject: [PATCH 01/42] 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 1cd879bcb6560ed43f35a366281f40042d6c1370 Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Thu, 9 Jun 2016 22:38:19 +0200 Subject: [PATCH 02/42] Scaffold file templates --- .../javascripts/file_templates.js.coffee | 3 + .../stylesheets/file_templates.css.scss | 3 + app/controllers/file_templates_controller.rb | 86 +++++++++++++++++++ app/models/file_template.rb | 10 +++ app/models/file_type.rb | 1 + app/policies/file_template_policy.rb | 7 ++ app/views/file_templates/_form.html.slim | 12 +++ app/views/file_templates/edit.html.slim | 3 + app/views/file_templates/index.html.slim | 20 +++++ app/views/file_templates/new.html.slim | 3 + app/views/file_templates/show.html.slim | 7 ++ config/locales/de.yml | 4 + config/locales/en.yml | 4 + config/routes.rb | 1 + .../20160609185708_create_file_templates.rb | 10 +++ db/schema.rb | 10 ++- 16 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 app/assets/javascripts/file_templates.js.coffee create mode 100644 app/assets/stylesheets/file_templates.css.scss create mode 100644 app/controllers/file_templates_controller.rb create mode 100644 app/models/file_template.rb create mode 100644 app/policies/file_template_policy.rb create mode 100644 app/views/file_templates/_form.html.slim create mode 100644 app/views/file_templates/edit.html.slim create mode 100644 app/views/file_templates/index.html.slim create mode 100644 app/views/file_templates/new.html.slim create mode 100644 app/views/file_templates/show.html.slim create mode 100644 db/migrate/20160609185708_create_file_templates.rb diff --git a/app/assets/javascripts/file_templates.js.coffee b/app/assets/javascripts/file_templates.js.coffee new file mode 100644 index 00000000..24f83d18 --- /dev/null +++ b/app/assets/javascripts/file_templates.js.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/app/assets/stylesheets/file_templates.css.scss b/app/assets/stylesheets/file_templates.css.scss new file mode 100644 index 00000000..bf8e27e8 --- /dev/null +++ b/app/assets/stylesheets/file_templates.css.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the FileTemplates controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/controllers/file_templates_controller.rb b/app/controllers/file_templates_controller.rb new file mode 100644 index 00000000..45636d61 --- /dev/null +++ b/app/controllers/file_templates_controller.rb @@ -0,0 +1,86 @@ +class FileTemplatesController < ApplicationController + before_action :set_file_template, only: [:show, :edit, :update, :destroy] + + def authorize! + authorize(@file_template || @file_templates) + end + private :authorize! + + # GET /file_templates + # GET /file_templates.json + def index + @file_templates = FileTemplate.all.order(:file_type_id).paginate(page: params[:page]) + authorize! + end + + # GET /file_templates/1 + # GET /file_templates/1.json + def show + authorize! + end + + # GET /file_templates/new + def new + @file_template = FileTemplate.new + authorize! + end + + # GET /file_templates/1/edit + def edit + authorize! + end + + # POST /file_templates + # POST /file_templates.json + def create + @file_template = FileTemplate.new(file_template_params) + authorize! + + respond_to do |format| + if @file_template.save + format.html { redirect_to @file_template, notice: 'File template was successfully created.' } + format.json { render :show, status: :created, location: @file_template } + else + format.html { render :new } + format.json { render json: @file_template.errors, status: :unprocessable_entity } + end + end + end + + # PATCH/PUT /file_templates/1 + # PATCH/PUT /file_templates/1.json + def update + authorize! + respond_to do |format| + if @file_template.update(file_template_params) + format.html { redirect_to @file_template, notice: 'File template was successfully updated.' } + format.json { render :show, status: :ok, location: @file_template } + else + format.html { render :edit } + format.json { render json: @file_template.errors, status: :unprocessable_entity } + end + end + end + + # DELETE /file_templates/1 + # DELETE /file_templates/1.json + def destroy + authorize! + @file_template.destroy + respond_to do |format| + format.html { redirect_to file_templates_url, notice: 'File template was successfully destroyed.' } + format.json { head :no_content } + end + end + + private + # Use callbacks to share common setup or constraints between actions. + def set_file_template + @file_template = FileTemplate.find(params[:id]) + end + + # Never trust parameters from the scary internet, only allow the white list through. + def file_template_params + params[:file_template].permit(:name, :file_type_id, :content) + end +end diff --git a/app/models/file_template.rb b/app/models/file_template.rb new file mode 100644 index 00000000..ef068e13 --- /dev/null +++ b/app/models/file_template.rb @@ -0,0 +1,10 @@ +class FileTemplate < ActiveRecord::Base + + belongs_to :file_type + + + def to_s + name + end + +end diff --git a/app/models/file_type.rb b/app/models/file_type.rb index 53bf18dc..d3b519d5 100644 --- a/app/models/file_type.rb +++ b/app/models/file_type.rb @@ -12,6 +12,7 @@ class FileType < ActiveRecord::Base has_many :execution_environments has_many :files + has_many :file_templates validates :binary, boolean_presence: true validates :editor_mode, presence: true, unless: :binary? diff --git a/app/policies/file_template_policy.rb b/app/policies/file_template_policy.rb new file mode 100644 index 00000000..b2f780a8 --- /dev/null +++ b/app/policies/file_template_policy.rb @@ -0,0 +1,7 @@ +class FileTemplatePolicy < AdminOnlyPolicy + + def show? + everyone + end + +end diff --git a/app/views/file_templates/_form.html.slim b/app/views/file_templates/_form.html.slim new file mode 100644 index 00000000..1a5c34bc --- /dev/null +++ b/app/views/file_templates/_form.html.slim @@ -0,0 +1,12 @@ += form_for(@file_template) do |f| + = render('shared/form_errors', object: @file_template) + .form-group + = f.label(:name) + = f.text_field(:name, class: 'form-control', required: true) + .form-group + = f.label(:file_type_id) + = f.collection_select(:file_type_id, FileType.all.order(:name), :id, :name, {}, class: 'form-control') + .form-group + = f.label(:content) + = f.text_area(:content, class: 'form-control') + .actions = render('shared/submit_button', f: f, object: @file_template) diff --git a/app/views/file_templates/edit.html.slim b/app/views/file_templates/edit.html.slim new file mode 100644 index 00000000..c198271f --- /dev/null +++ b/app/views/file_templates/edit.html.slim @@ -0,0 +1,3 @@ +h1 = @file_template + += render('form') diff --git a/app/views/file_templates/index.html.slim b/app/views/file_templates/index.html.slim new file mode 100644 index 00000000..3022ea53 --- /dev/null +++ b/app/views/file_templates/index.html.slim @@ -0,0 +1,20 @@ +h1 = FileTemplate.model_name.human(count: 2) + +.table-responsive + table.table + thead + tr + th = t('activerecord.attributes.file_template.name') + th = t('activerecord.attributes.file_template.file_type') + th colspan=3 = t('shared.actions') + tbody + - @file_templates.each do |file_template| + tr + td = file_template.name + td = link_to(file_template.file_type, file_type_path(file_template.file_type)) + td = link_to(t('shared.show'), file_template) + td = link_to(t('shared.edit'), edit_file_template_path(file_template)) + td = link_to(t('shared.destroy'), file_template, data: {confirm: t('shared.confirm_destroy')}, method: :delete) + += render('shared/pagination', collection: @file_templates) +p = render('shared/new_button', model: FileTemplate) diff --git a/app/views/file_templates/new.html.slim b/app/views/file_templates/new.html.slim new file mode 100644 index 00000000..bf434860 --- /dev/null +++ b/app/views/file_templates/new.html.slim @@ -0,0 +1,3 @@ +h1 = t('shared.new_model', model: FileTemplate.model_name.human) + += render('form') diff --git a/app/views/file_templates/show.html.slim b/app/views/file_templates/show.html.slim new file mode 100644 index 00000000..19f0d28f --- /dev/null +++ b/app/views/file_templates/show.html.slim @@ -0,0 +1,7 @@ +h1 + = @file_template + = render('shared/edit_button', object: @file_template) + += row(label: 'file_template.name', value: @file_template.name) += row(label: 'file_template.file_type', value: link_to(@file_template.file_type, file_type_path(@file_template.file_type))) += row(label: 'file_template.content', value: @file_template.content) diff --git a/config/locales/de.yml b/config/locales/de.yml index e7d78943..4a98e0a0 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -93,6 +93,10 @@ de: team: internal_user_ids: Mitglieder name: Name + file_template: + name: "Name" + file_type: "Dateityp" + content: "Code" models: code_harbor_link: one: CodeHarbor-Link diff --git a/config/locales/en.yml b/config/locales/en.yml index f2470fc8..de0f3aa4 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -93,6 +93,10 @@ en: team: internal_user_ids: Members name: Name + file_template: + name: "Name" + file_type: "File Type" + content: "Content" models: code_harbor_link: one: CodeHarbor Link diff --git a/config/routes.rb b/config/routes.rb index 72ccb489..7965f0a3 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,6 +1,7 @@ FILENAME_REGEXP = /[\w\.]+/ unless Kernel.const_defined?(:FILENAME_REGEXP) Rails.application.routes.draw do + resources :file_templates resources :code_harbor_links resources :request_for_comments get '/my_request_for_comments', as: 'my_request_for_comments', to: 'request_for_comments#get_my_comment_requests' diff --git a/db/migrate/20160609185708_create_file_templates.rb b/db/migrate/20160609185708_create_file_templates.rb new file mode 100644 index 00000000..43cde0d0 --- /dev/null +++ b/db/migrate/20160609185708_create_file_templates.rb @@ -0,0 +1,10 @@ +class CreateFileTemplates < ActiveRecord::Migration + def change + create_table :file_templates do |t| + t.string :name + t.text :content + t.belongs_to :file_type + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 104a1469..4f7fc833 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: 20160512131539) do +ActiveRecord::Schema.define(version: 20160609185708) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -101,6 +101,14 @@ ActiveRecord::Schema.define(version: 20160512131539) do t.datetime "updated_at" end + create_table "file_templates", force: true do |t| + t.string "name" + t.text "content" + t.integer "file_type_id" + 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" From 4f8feb38e10c7e3591a6f7c60436c45dbd67e29d Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Fri, 10 Jun 2016 13:41:38 +0200 Subject: [PATCH 03/42] Use file template to generate new file content --- app/controllers/code_ocean/files_controller.rb | 3 +++ app/controllers/concerns/file_parameters.rb | 2 +- app/views/code_ocean/files/_form.html.slim | 3 +++ config/locales/de.yml | 1 + config/locales/en.yml | 1 + db/migrate/20160610111602_add_file_template_to_file.rb | 5 +++++ db/schema.rb | 3 ++- 7 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 db/migrate/20160610111602_add_file_template_to_file.rb diff --git a/app/controllers/code_ocean/files_controller.rb b/app/controllers/code_ocean/files_controller.rb index 74c1932f..e38607c2 100644 --- a/app/controllers/code_ocean/files_controller.rb +++ b/app/controllers/code_ocean/files_controller.rb @@ -10,6 +10,9 @@ module CodeOcean def create @file = CodeOcean::File.new(file_params) + if @file.file_template_id + @file.content = FileTemplate.find(@file.file_template_id).content + end authorize! create_and_respond(object: @file, path: proc { implement_exercise_path(@file.context.exercise, tab: 2) }) end diff --git a/app/controllers/concerns/file_parameters.rb b/app/controllers/concerns/file_parameters.rb index e61e719e..295b66c3 100644 --- a/app/controllers/concerns/file_parameters.rb +++ b/app/controllers/concerns/file_parameters.rb @@ -1,6 +1,6 @@ module FileParameters def file_attributes - %w(content context_id feedback_message file_id file_type_id hidden id name native_file path read_only role weight) + %w(content context_id feedback_message file_id file_type_id hidden id name native_file path read_only role weight file_template_id) end private :file_attributes end diff --git a/app/views/code_ocean/files/_form.html.slim b/app/views/code_ocean/files/_form.html.slim index 07dd3355..ee74f4b8 100644 --- a/app/views/code_ocean/files/_form.html.slim +++ b/app/views/code_ocean/files/_form.html.slim @@ -8,5 +8,8 @@ .form-group = f.label(:file_type_id, t('activerecord.attributes.file.file_type_id')) = f.collection_select(:file_type_id, FileType.where(binary: false).order(:name), :id, :name, {selected: @exercise.execution_environment.file_type.try(:id)}, class: 'form-control') + .form-group + = f.label(:file_template_id, t('activerecord.attributes.file.file_template_id')) + = f.collection_select(:file_template_id, FileTemplate.all.order(:name), :id, :name, {}, class: 'form-control') = f.hidden_field(:context_id) .actions = render('shared/submit_button', f: f, object: CodeOcean::File.new) diff --git a/config/locales/de.yml b/config/locales/de.yml index 4a98e0a0..9a48ee4f 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -54,6 +54,7 @@ de: read_only: Schreibgeschützt role: Rolle weight: Punktzahl + file_template_id: "Dateivorlage" file_type: binary: Binär editor_mode: Editor-Modus diff --git a/config/locales/en.yml b/config/locales/en.yml index de0f3aa4..49fc8bbb 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -54,6 +54,7 @@ en: read_only: Read-only role: Role weight: Score + file_template_id: "File Template" file_type: binary: Binary editor_mode: Editor Mode diff --git a/db/migrate/20160610111602_add_file_template_to_file.rb b/db/migrate/20160610111602_add_file_template_to_file.rb new file mode 100644 index 00000000..a595e90b --- /dev/null +++ b/db/migrate/20160610111602_add_file_template_to_file.rb @@ -0,0 +1,5 @@ +class AddFileTemplateToFile < ActiveRecord::Migration + def change + add_reference :files, :file_template + end +end diff --git a/db/schema.rb b/db/schema.rb index 4f7fc833..bed23c98 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: 20160609185708) do +ActiveRecord::Schema.define(version: 20160610111602) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -140,6 +140,7 @@ ActiveRecord::Schema.define(version: 20160609185708) do t.string "feedback_message" t.float "weight" t.string "path" + t.integer "file_template_id" end add_index "files", ["context_id", "context_type"], name: "index_files_on_context_id_and_context_type", using: :btree From c10b07690ad29138dd7be79bc2fdf21836b90b48 Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Fri, 10 Jun 2016 13:46:13 +0200 Subject: [PATCH 04/42] Make file template optional --- app/views/code_ocean/files/_form.html.slim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/code_ocean/files/_form.html.slim b/app/views/code_ocean/files/_form.html.slim index ee74f4b8..4b44647d 100644 --- a/app/views/code_ocean/files/_form.html.slim +++ b/app/views/code_ocean/files/_form.html.slim @@ -10,6 +10,6 @@ = f.collection_select(:file_type_id, FileType.where(binary: false).order(:name), :id, :name, {selected: @exercise.execution_environment.file_type.try(:id)}, class: 'form-control') .form-group = f.label(:file_template_id, t('activerecord.attributes.file.file_template_id')) - = f.collection_select(:file_template_id, FileTemplate.all.order(:name), :id, :name, {}, class: 'form-control') + = f.collection_select(:file_template_id, FileTemplate.all.order(:name), :id, :name, {:include_blank => true}, class: 'form-control') = f.hidden_field(:context_id) .actions = render('shared/submit_button', f: f, object: CodeOcean::File.new) From 4d2676fea75a724faed1ef7a2beaf0d04d22c4c2 Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Fri, 10 Jun 2016 17:48:04 +0200 Subject: [PATCH 05/42] Only show file templates which are available for the selected file type --- app/assets/javascripts/exercises.js | 20 ++++++++++++++++++++ app/controllers/file_templates_controller.rb | 8 ++++++++ app/policies/file_template_policy.rb | 4 ++++ app/views/code_ocean/files/_form.html.slim | 1 + config/locales/de.yml | 2 ++ config/locales/en.yml | 2 ++ config/routes.rb | 6 +++++- 7 files changed, 42 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/exercises.js b/app/assets/javascripts/exercises.js index 1f861ef6..0e3805db 100644 --- a/app/assets/javascripts/exercises.js +++ b/app/assets/javascripts/exercises.js @@ -148,6 +148,22 @@ $(function() { }); }; + var updateFileTemplates = function(fileType) { + var jqxhr = $.ajax({ + url: '/file_templates/by_file_type/' + fileType + '.json', + dataType: 'json' + }); + jqxhr.done(function(response) { + var noTemplateLabel = $('#noTemplateLabel').data('text'); + var options = ""; + for (var i = 0; i < response.length; i++) { + options += "" + } + $("#code_ocean_file_file_template_id").find('option').remove().end().append($(options)); + }); + jqxhr.fail(ajaxError); + } + if ($.isController('exercises')) { if ($('table').isPresent()) { enableBatchUpdate(); @@ -162,6 +178,10 @@ $(function() { inferFileAttributes(); observeFileRoleChanges(); overrideTextareaTabBehavior(); + } else if ($('#files.jstree').isPresent()) { + var fileTypeSelect = $('#code_ocean_file_file_type_id'); + fileTypeSelect.on("change", function() {updateFileTemplates(fileTypeSelect.val())}); + updateFileTemplates(fileTypeSelect.val()); } toggleCodeHeight(); if (window.hljs) { diff --git a/app/controllers/file_templates_controller.rb b/app/controllers/file_templates_controller.rb index 45636d61..a6039500 100644 --- a/app/controllers/file_templates_controller.rb +++ b/app/controllers/file_templates_controller.rb @@ -6,6 +6,14 @@ class FileTemplatesController < ApplicationController end private :authorize! + def by_file_type + @file_templates = FileTemplate.where(:file_type_id => params[:file_type_id]) + authorize! + respond_to do |format| + format.json { render :show, status: :ok, json: @file_templates.to_json } + end + end + # GET /file_templates # GET /file_templates.json def index diff --git a/app/policies/file_template_policy.rb b/app/policies/file_template_policy.rb index b2f780a8..92ced442 100644 --- a/app/policies/file_template_policy.rb +++ b/app/policies/file_template_policy.rb @@ -4,4 +4,8 @@ class FileTemplatePolicy < AdminOnlyPolicy everyone end + def by_file_type? + everyone + end + end diff --git a/app/views/code_ocean/files/_form.html.slim b/app/views/code_ocean/files/_form.html.slim index 4b44647d..46c5b2c2 100644 --- a/app/views/code_ocean/files/_form.html.slim +++ b/app/views/code_ocean/files/_form.html.slim @@ -12,4 +12,5 @@ = f.label(:file_template_id, t('activerecord.attributes.file.file_template_id')) = f.collection_select(:file_template_id, FileTemplate.all.order(:name), :id, :name, {:include_blank => true}, class: 'form-control') = f.hidden_field(:context_id) + .hidden#noTemplateLabel data-text=t('file_template.no_template_label') .actions = render('shared/submit_button', f: f, object: CodeOcean::File.new) diff --git a/config/locales/de.yml b/config/locales/de.yml index 9a48ee4f..c0aa4b13 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -432,3 +432,5 @@ de: next_label: 'Nächste Seite →' page_gap: '…' previous_label: '← Vorherige Seite' + file_template: + no_template_label: "Leere Datei" diff --git a/config/locales/en.yml b/config/locales/en.yml index 49fc8bbb..f03e42fb 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -432,3 +432,5 @@ en: next_label: 'Next Page →' page_gap: '…' previous_label: '← Previous Page' + file_template: + no_template_label: "Empty File" diff --git a/config/routes.rb b/config/routes.rb index 7965f0a3..afd8c8ce 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,7 +1,11 @@ FILENAME_REGEXP = /[\w\.]+/ unless Kernel.const_defined?(:FILENAME_REGEXP) Rails.application.routes.draw do - resources :file_templates + resources :file_templates do + collection do + get 'by_file_type/:file_type_id', as: :by_file_type, to: :by_file_type + end + end resources :code_harbor_links resources :request_for_comments get '/my_request_for_comments', as: 'my_request_for_comments', to: 'request_for_comments#get_my_comment_requests' From 8d030e42e9621391c4c9aa4a7de32eb731cdba27 Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Fri, 10 Jun 2016 18:08:57 +0200 Subject: [PATCH 06/42] Allow templates to include the file name as a macro --- app/controllers/code_ocean/files_controller.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/controllers/code_ocean/files_controller.rb b/app/controllers/code_ocean/files_controller.rb index e38607c2..55d8b369 100644 --- a/app/controllers/code_ocean/files_controller.rb +++ b/app/controllers/code_ocean/files_controller.rb @@ -11,7 +11,9 @@ module CodeOcean def create @file = CodeOcean::File.new(file_params) if @file.file_template_id - @file.content = FileTemplate.find(@file.file_template_id).content + content = FileTemplate.find(@file.file_template_id).content + content.sub! '{{file_name}}', @file.name + @file.content = content end authorize! create_and_respond(object: @file, path: proc { implement_exercise_path(@file.context.exercise, tab: 2) }) From 7ef401f75aa97c9dd4fc86ec7deb87151891d187 Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Fri, 10 Jun 2016 18:15:37 +0200 Subject: [PATCH 07/42] Add navigation item for file templates --- app/views/application/_navigation.html.slim | 2 +- config/locales/de.yml | 3 +++ config/locales/en.yml | 3 +++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/views/application/_navigation.html.slim b/app/views/application/_navigation.html.slim index 4ab39e30..0f859844 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, Consumer, CodeHarborLink, ExternalUser, FileType, InternalUser, Submission, Team].sort_by { |model| model.model_name.human(count: 2) } + - models = [ExecutionEnvironment, Exercise, Consumer, CodeHarborLink, ExternalUser, FileType, FileTemplate, InternalUser, Submission, Team].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")) diff --git a/config/locales/de.yml b/config/locales/de.yml index c0aa4b13..c0013777 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -120,6 +120,9 @@ de: file: one: Datei other: Dateien + file_template: + one: Dateivorlage + other: Dateivorlagen file_type: one: Dateityp other: Dateitypen diff --git a/config/locales/en.yml b/config/locales/en.yml index f03e42fb..1d597bf8 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -120,6 +120,9 @@ en: file: one: File other: Files + file_template: + one: File Template + other: File Templates file_type: one: File Type other: File Types From ec26a095f692e2102e8a87ea85d36e1655582099 Mon Sep 17 00:00:00 2001 From: Ralf Teusner Date: Fri, 17 Jun 2016 14:48:57 +0200 Subject: [PATCH 08/42] 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 918da5270dddb74fd9b985ef7f18547f4b8c5d5c Mon Sep 17 00:00:00 2001 From: Ralf Teusner Date: Wed, 22 Jun 2016 13:06:35 +0200 Subject: [PATCH 09/42] 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 10/42] 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 11/42] 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 12/42] 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 13/42] 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') %>