diff --git a/Gemfile b/Gemfile index ed176d3f..14786998 100644 --- a/Gemfile +++ b/Gemfile @@ -55,6 +55,10 @@ gem 'i18n-active_record', github: 'svenfuchs/i18n-active_record', require: 'i18n/active_record' gem 'http_accept_language' +# Remove leading and trailing white spaces +gem 'strip_attributes' +# Track changes to models' data +gem 'paper_trail', '~> 4.0.0.rc' # A superb font to use as icons gem 'font-awesome-sass' @@ -66,7 +70,7 @@ gem 'actionview-encoded_mail_to' gem 'differ' # A generic library to administrate the tool -gem 'activeadmin', github: 'activeadmin' +gem 'activeadmin', '~> 1.0.0.pre1' # A nicer markdown editor in active admin gem 'activeadmin_pagedown' @@ -85,9 +89,6 @@ gem 'geocoder' gem 'tinymce-rails' gem 'tinymce-rails-langs' -# Remove leading and trailing white spaces -gem 'strip_attributes' - # SEO optimisations gem 'meta-tags' diff --git a/Gemfile.lock b/Gemfile.lock index 6a18ec03..68054385 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,21 +1,3 @@ -GIT - remote: git://github.com/activeadmin/activeadmin.git - revision: 0b4b22871fd332c94daec3c5138c0cf9a5b95451 - specs: - activeadmin (1.0.0.pre1) - arbre (~> 1.0, >= 1.0.2) - bourbon - coffee-rails - formtastic (~> 3.1) - formtastic_i18n - inherited_resources (~> 1.6) - jquery-rails - jquery-ui-rails (~> 5.0) - kaminari (~> 0.15) - rails (>= 3.2, < 5.0) - ransack (~> 1.3) - sass-rails - GIT remote: git://github.com/cubus/jquery-sparkline-rails.git revision: c5b531f51e3e734710c7561b06c2c829107f9b38 @@ -34,40 +16,53 @@ GIT GEM remote: https://rubygems.org/ specs: - actionmailer (4.2.1) - actionpack (= 4.2.1) - actionview (= 4.2.1) - activejob (= 4.2.1) + actionmailer (4.2.3) + actionpack (= 4.2.3) + actionview (= 4.2.3) + activejob (= 4.2.3) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 1.0, >= 1.0.5) - actionpack (4.2.1) - actionview (= 4.2.1) - activesupport (= 4.2.1) + actionpack (4.2.3) + actionview (= 4.2.3) + activesupport (= 4.2.3) rack (~> 1.6) rack-test (~> 0.6.2) rails-dom-testing (~> 1.0, >= 1.0.5) - rails-html-sanitizer (~> 1.0, >= 1.0.1) - actionview (4.2.1) - activesupport (= 4.2.1) + rails-html-sanitizer (~> 1.0, >= 1.0.2) + actionview (4.2.3) + activesupport (= 4.2.3) builder (~> 3.1) erubis (~> 2.7.0) rails-dom-testing (~> 1.0, >= 1.0.5) - rails-html-sanitizer (~> 1.0, >= 1.0.1) + rails-html-sanitizer (~> 1.0, >= 1.0.2) actionview-encoded_mail_to (1.0.6) rails + activeadmin (1.0.0.pre1) + arbre (~> 1.0, >= 1.0.2) + bourbon + coffee-rails + formtastic (~> 3.1) + formtastic_i18n + inherited_resources (~> 1.6) + jquery-rails + jquery-ui-rails (~> 5.0) + kaminari (~> 0.15) + rails (>= 3.2, < 5.0) + ransack (~> 1.3) + sass-rails activeadmin_pagedown (0.0.2) activeadmin (>= 0.5.0) - activejob (4.2.1) - activesupport (= 4.2.1) + activejob (4.2.3) + activesupport (= 4.2.3) globalid (>= 0.3.0) - activemodel (4.2.1) - activesupport (= 4.2.1) + activemodel (4.2.3) + activesupport (= 4.2.3) builder (~> 3.1) - activerecord (4.2.1) - activemodel (= 4.2.1) - activesupport (= 4.2.1) + activerecord (4.2.3) + activemodel (= 4.2.3) + activesupport (= 4.2.3) arel (~> 6.0) - activesupport (4.2.1) + activesupport (4.2.3) i18n (~> 0.7) json (~> 1.7, >= 1.7.7) minitest (~> 5.1) @@ -76,32 +71,30 @@ GEM addressable (2.3.8) arbre (1.0.3) activesupport (>= 3.0.0) - arel (6.0.0) + arel (6.0.2) ast (2.0.0) - astrolabe (1.3.0) - parser (>= 2.2.0.pre.3, < 3.0) + astrolabe (1.3.1) + parser (~> 2.2) bcrypt (3.1.10) binding_of_caller (0.7.2) debug_inspector (>= 0.0.1) bourbon (4.2.3) sass (~> 3.4) thor - brakeman (3.0.3) + brakeman (3.0.5) erubis (~> 2.6) fastercsv (~> 1.5) haml (>= 3.0, < 5.0) highline (~> 1.6.20) multi_json (~> 1.2) ruby2ruby (~> 2.1.1) - ruby_parser (~> 3.6.2) + ruby_parser (~> 3.7.0) sass (~> 3.0) terminal-table (~> 1.4) buftok (0.2.0) builder (3.2.2) byebug (5.0.0) columnize (= 0.9.0) - celluloid (0.16.0) - timers (~> 4.0.0) chunky_png (1.3.4) coderay (1.1.0) coffee-rails (4.1.0) @@ -136,7 +129,7 @@ GEM responders thread_safe (~> 0.1) warden (~> 1.2.3) - devise-i18n (0.12.0) + devise-i18n (0.12.1) differ (0.1.2) docile (1.1.5) em-websocket (0.5.1) @@ -151,7 +144,7 @@ GEM faraday (0.9.1) multipart-post (>= 1.2, < 3) fastercsv (1.5.5) - ffi (1.9.8) + ffi (1.9.10) font-awesome-sass (4.3.2.1) sass (~> 3.2) formatador (0.2.5) @@ -161,9 +154,9 @@ GEM geocoder (1.2.9) globalid (0.3.5) activesupport (>= 4.1.0) - guard (2.12.6) + guard (2.12.9) formatador (>= 0.2.4) - listen (~> 2.7) + listen (>= 2.7, <= 4.0) lumberjack (~> 1.0) nenv (~> 0.1) notiffany (~> 0.0) @@ -209,7 +202,6 @@ GEM activesupport (>= 3.2, < 5) highline (1.6.21) hike (1.2.3) - hitimes (1.2.2) html2haml (2.0.0) erubis (~> 2.7.0) haml (~> 4.0.0) @@ -225,10 +217,10 @@ GEM has_scope (~> 0.6.0.rc) railties (>= 3.2, < 5) responders - jbuilder (2.2.16) + jbuilder (2.3.1) activesupport (>= 3.0.0, < 5) multi_json (~> 1.2) - jquery-rails (4.0.3) + jquery-rails (4.0.4) rails-dom-testing (~> 1.0) railties (>= 4.2.0) thor (>= 0.14, < 2.0) @@ -244,9 +236,8 @@ GEM leaflet-markercluster-rails (0.7.0) railties (>= 3.1) leaflet-rails (0.7.4) - libv8 (3.16.14.7) - listen (2.10.0) - celluloid (~> 0.16.0) + libv8 (3.16.14.11) + listen (3.0.3) rb-fsevent (>= 0.9.3) rb-inotify (>= 0.9) loofah (2.0.2) @@ -263,7 +254,7 @@ GEM mini_portile (0.6.2) minitest (5.7.0) modernizr-rails (2.7.1) - multi_json (1.11.1) + multi_json (1.11.2) multipart-post (2.0.0) mysql2 (0.3.18) naught (1.0.0) @@ -274,7 +265,11 @@ GEM nenv (~> 0.1) shellany (~> 0.0) orm_adapter (0.5.0) - parser (2.3.0.pre.1) + paper_trail (4.0.0.rc2) + activerecord (>= 3.0, < 6.0) + activesupport (>= 3.0, < 6.0) + request_store (~> 1.1) + parser (2.2.2.6) ast (>= 1.1, < 3.0) polyamorous (1.2.0) activerecord (>= 3.0) @@ -285,19 +280,19 @@ GEM slop (~> 3.4) quiet_assets (1.1.0) railties (>= 3.1, < 5.0) - rack (1.6.1) + rack (1.6.4) rack-test (0.6.3) rack (>= 1.0) - rails (4.2.1) - actionmailer (= 4.2.1) - actionpack (= 4.2.1) - actionview (= 4.2.1) - activejob (= 4.2.1) - activemodel (= 4.2.1) - activerecord (= 4.2.1) - activesupport (= 4.2.1) + rails (4.2.3) + actionmailer (= 4.2.3) + actionpack (= 4.2.3) + actionview (= 4.2.3) + activejob (= 4.2.3) + activemodel (= 4.2.3) + activerecord (= 4.2.3) + activesupport (= 4.2.3) bundler (>= 1.3.0, < 2.0) - railties (= 4.2.1) + railties (= 4.2.3) sprockets-rails rails-deprecated_sanitizer (1.0.3) activesupport (>= 4.2.0.alpha) @@ -310,9 +305,9 @@ GEM rails-i18n (4.0.4) i18n (~> 0.6) railties (~> 4.0) - railties (4.2.1) - actionpack (= 4.2.1) - activesupport (= 4.2.1) + railties (4.2.3) + actionpack (= 4.2.3) + activesupport (= 4.2.3) rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) rainbow (2.0.0) @@ -328,11 +323,12 @@ GEM ffi (>= 0.5.0) rdoc (4.2.0) json (~> 1.4) - redcarpet (3.3.1) - ref (1.0.5) + redcarpet (3.3.2) + ref (2.0.0) + request_store (1.2.0) responders (2.1.0) railties (>= 4.2.0, < 5) - rubocop (0.32.0) + rubocop (0.32.1) astrolabe (~> 1.3) parser (>= 2.2.2.5, < 3.0) powerpack (~> 0.1) @@ -342,9 +338,9 @@ GEM ruby2ruby (2.1.4) ruby_parser (~> 3.1) sexp_processor (~> 4.0) - ruby_parser (3.6.6) + ruby_parser (3.7.0) sexp_processor (~> 4.1) - sass (3.4.14) + sass (3.4.16) sass-rails (5.0.1) railties (>= 4.0.0, < 5.0) sass (~> 3.1) @@ -368,12 +364,12 @@ GEM simplecov-html (0.10.0) slop (3.6.0) spring (1.3.6) - sprockets (2.12.3) + sprockets (2.12.4) hike (~> 1.2) multi_json (~> 1.0) rack (~> 1.0) tilt (~> 1.1, != 1.3.0) - sprockets-rails (2.3.1) + sprockets-rails (2.3.2) actionpack (>= 3.0) activesupport (>= 3.0) sprockets (>= 2.8, < 4.0) @@ -381,16 +377,14 @@ GEM strip_attributes (1.7.0) activemodel (>= 3.0, < 5.0) sysexits (1.2.0) - terminal-table (1.4.5) + terminal-table (1.5.2) therubyracer (0.12.2) libv8 (~> 3.16.14.0) ref thor (0.19.1) thread_safe (0.3.5) tilt (1.4.1) - timers (4.0.1) - hitimes - tinymce-rails (4.1.6) + tinymce-rails (4.2.2) railties (>= 3.1.1) tinymce-rails-langs (4.20140129) tinymce-rails (~> 4.0) @@ -414,13 +408,13 @@ GEM json (>= 1.8.0) warden (1.2.3) rack (>= 1.0) - web-console (2.1.2) + web-console (2.2.1) activemodel (>= 4.0) binding_of_caller (>= 0.7.2) railties (>= 4.0) sprockets-rails (>= 2.0, < 4.0) webrick (1.3.1) - webshims-rails (1.15.6.4) + webshims-rails (1.15.8) rails (> 3.1.0) PLATFORMS @@ -428,7 +422,7 @@ PLATFORMS DEPENDENCIES actionview-encoded_mail_to - activeadmin! + activeadmin (~> 1.0.0.pre1) activeadmin_pagedown brakeman byebug @@ -460,6 +454,7 @@ DEPENDENCIES meta-tags modernizr-rails mysql2 + paper_trail (~> 4.0.0.rc) quiet_assets rails rails-i18n @@ -481,3 +476,6 @@ DEPENDENCIES web-console (~> 2.0) webrick (>= 1.3.1) webshims-rails + +BUNDLED WITH + 1.10.5 diff --git a/app/assets/stylesheets/events.css.sass b/app/assets/stylesheets/events.css.sass index 5e4b59be..c37226ef 100644 --- a/app/assets/stylesheets/events.css.sass +++ b/app/assets/stylesheets/events.css.sass @@ -107,7 +107,7 @@ a#banner margin-left: 5% padding-left: 2px -body.events.show main +body.events.show main, body.orgas.show main padding: 1em max-width: 60em +box-shadow(1px 1px 5px gray) diff --git a/app/controllers/moderations_controller.rb b/app/controllers/moderations_controller.rb index 592f5c1a..bb031cd4 100644 --- a/app/controllers/moderations_controller.rb +++ b/app/controllers/moderations_controller.rb @@ -8,6 +8,7 @@ class ModerationsController < ApplicationController def index @events = Event.unmoderated + @orgas = Orga.unmoderated end def preview diff --git a/app/controllers/orgas_controller.rb b/app/controllers/orgas_controller.rb index 14cd693c..b588d296 100644 --- a/app/controllers/orgas_controller.rb +++ b/app/controllers/orgas_controller.rb @@ -1,11 +1,13 @@ # Groups life cycle class OrgasController < ApplicationController before_action :set_orga, except: [:index, :new, :create] - before_action :authenticate_user!, only: [:edit, :update, :destroy], + before_action :set_mailer_host + before_action :authenticate_user!, only: [:edit, :update, :cancel, :destroy], unless: :check_secret + before_action :authenticate_user!, only: [:validate, :accept] def index - @search = Orga.search params[:q] + @search = Orga.moderated.search params[:q] @search.sorts = 'name' if @search.sorts.empty? @orgas = @search.result.page params[:page] end @@ -54,6 +56,26 @@ class OrgasController < ApplicationController end end + # PATCH/PUT /accept/1 + # PATCH/PUT /accept/1.json + def accept + @orga.update moderated: true + respond_to do |format| + format.html { redirect_to :orgas, notice: t('.ok') } + format.json { head :no_content } + end + end + + # DELETE /orgas/1 + # DELETE /orgas/1.json + def destroy + @orga.destroy + respond_to do |format| + format.html { redirect_to :root, notice: t('.ok') } + format.json { head :no_content } + end + end + private # Use callbacks to share common setup or constraints between actions. diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb new file mode 100644 index 00000000..dec257ec --- /dev/null +++ b/app/mailers/application_mailer.rb @@ -0,0 +1,4 @@ +# Top mailer class, from which all others are inheritors +class ApplicationMailer < ActionMailer::Base + layout 'mailer' +end diff --git a/app/mailers/event_mailer.rb b/app/mailers/event_mailer.rb index 9fff27e8..050ea3d4 100644 --- a/app/mailers/event_mailer.rb +++ b/app/mailers/event_mailer.rb @@ -1,5 +1,5 @@ # Sending mails related to events life cycle -class EventMailer < ActionMailer::Base +class EventMailer < ApplicationMailer helper :events def create(event) diff --git a/app/mailers/moderation_mailer.rb b/app/mailers/moderation_mailer.rb index 39d4e61a..ac4535db 100644 --- a/app/mailers/moderation_mailer.rb +++ b/app/mailers/moderation_mailer.rb @@ -1,5 +1,5 @@ # Sending mails related to events' moderation -class ModerationMailer < ActionMailer::Base +class ModerationMailer < ApplicationMailer helper :events def create(event) diff --git a/app/mailers/note_mailer.rb b/app/mailers/note_mailer.rb index eff7f579..b2b9f67c 100644 --- a/app/mailers/note_mailer.rb +++ b/app/mailers/note_mailer.rb @@ -1,5 +1,5 @@ # Sending mails related to events' notes -class NoteMailer < ActionMailer::Base +class NoteMailer < ApplicationMailer helper :events def notify(note) diff --git a/app/mailers/orga_mailer.rb b/app/mailers/orga_mailer.rb new file mode 100644 index 00000000..abe313f9 --- /dev/null +++ b/app/mailers/orga_mailer.rb @@ -0,0 +1,66 @@ +# Send mails to check on organisations life cycle +class OrgaMailer < ApplicationMailer + # Subject can be set in your I18n file at config/locales/en.yml + # with the following lookup: + # + # en.orga_mailer.create.subject + # + def create(orga) + @orga = orga + + mail 'Message-ID' => + "", + to: orga.submitter, + subject: "#{t 'mail_prefix'}#{t 'orga_mailer.create.subject', + subject: orga.name}" + end + + # Subject can be set in your I18n file at config/locales/en.yml + # with the following lookup: + # + # en.orga_mailer.update.subject + # + def update(orga) + @orga = orga + @current_user = User.find_by id: orga.paper_trail_originator + + mail 'Message-ID' => + "", + to: orga.submitter, + subject: "#{t 'mail_prefix'}#{t 'orga_mailer.update.subject', + subject: orga.name}" + end + + # Subject can be set in your I18n file at config/locales/en.yml + # with the following lookup: + # + # en.orga_mailer.accept.subject + # + def accept(orga) + @orga = orga + @current_user = User.find_by id: orga.paper_trail_originator + + mail 'In-Reply-To' => + "", + to: orga.submitter, + subject: "#{t 'mail_prefix'}#{t 'orga_mailer.accept.subject', + subject: orga.name}" + end + + # Subject can be set in your I18n file at config/locales/en.yml + # with the following lookup: + # + # en.orga_mailer.destroy.subject + # + def destroy(orga, reason = '') + @orga = orga + @current_user = User.find_by id: orga.paper_trail_originator + @reason = reason + + mail 'In-Reply-To' => + "", + to: orga.submitter, + subject: "#{t 'mail_prefix'}#{t 'orga_mailer.destroy.subject', + subject: orga.name}" + end +end diff --git a/app/models/event.rb b/app/models/event.rb index 9e056d48..5ae0b74e 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -4,6 +4,7 @@ class Event < ActiveRecord::Base extend SimpleCalendar strip_attributes + has_paper_trail belongs_to :region has_many :notes, dependent: :destroy diff --git a/app/models/orga.rb b/app/models/orga.rb index b6446d4d..8a9db508 100644 --- a/app/models/orga.rb +++ b/app/models/orga.rb @@ -1,5 +1,7 @@ # Groups related to this agenda class Orga < ActiveRecord::Base + has_paper_trail + belongs_to :region belongs_to :kind @@ -11,6 +13,9 @@ class Orga < ActiveRecord::Base validates :contact, presence: true, email: true validates :submitter, allow_blank: true, email: true + scope :moderated, -> { where moderated: true } + scope :unmoderated, -> { where moderated: false } + before_validation do self.secret ||= SecureRandom.urlsafe_base64(32)[0...32] self.submission_time ||= Time.zone.now @@ -18,4 +23,26 @@ class Orga < ActiveRecord::Base # Populate submitter using contact info if absent self.submitter ||= contact end + + after_create do + send_secret + end + + before_update do + send_secret if secret_changed? + + if moderated_changed? + OrgaMailer.accept(self).deliver_now! + elsif previous_changes + OrgaMailer.update(self).deliver_now! + end + end + + before_destroy do + OrgaMailer.destroy(self).deliver_now! + end + + def send_secret + OrgaMailer.create(self).deliver_now! + end end diff --git a/app/views/event_mailer/accept.text.haml b/app/views/event_mailer/accept.text.haml index 8e72a071..2728ddae 100644 --- a/app/views/event_mailer/accept.text.haml +++ b/app/views/event_mailer/accept.text.haml @@ -1,14 +1,12 @@ -=t '.title' -\ -=t '.body', moderator: @current_user += t '.body', moderator: @current_user = event_url @event \ -=t '.edit_link' += t '.edit_link' = edit_event_url @event, secret: @event.secret \ -=t '.delete_link' += t '.delete_link' = cancel_event_url @event, secret: @event.secret \ = render file: '/events/show' \ -=t '.signature' += t '.signature' diff --git a/app/views/event_mailer/create.text.haml b/app/views/event_mailer/create.text.haml index 853c7db4..e2998631 100644 --- a/app/views/event_mailer/create.text.haml +++ b/app/views/event_mailer/create.text.haml @@ -1,9 +1,8 @@ -=t '.title' -\ -=t '.body', subject: @event.title, start_time: l(@event.start_time, format: :at) += t '.body', subject: @event.title, + start_time: l(@event.start_time, format: :at) = edit_event_url @event, secret: @event.secret \ -=t '.delete_link' += t '.delete_link' = cancel_event_url @event, secret: @event.secret \ -=t '.signature' += t '.signature' diff --git a/app/views/event_mailer/destroy.text.haml b/app/views/event_mailer/destroy.text.haml index b0546d71..fbdb16e2 100644 --- a/app/views/event_mailer/destroy.text.haml +++ b/app/views/event_mailer/destroy.text.haml @@ -1,12 +1,10 @@ -=t '.title' -\ -=t '.body', author: @current_user += t '.body', author: @current_user \ = @reason \ -=t '.reclamation' += t '.reclamation' \ -=t '.reminder' += t '.reminder' = render file: '/events/show' \ -=t '.signature' += t '.signature' diff --git a/app/views/events/cancel.html.haml b/app/views/events/cancel.html.haml index 967df523..54353772 100644 --- a/app/views/events/cancel.html.haml +++ b/app/views/events/cancel.html.haml @@ -1,18 +1,18 @@ %h2 %em.fa.fa-trash-o - =t '.title' + = t '.title' - if @event.moderated? - %h3.warning=t '.already_moderated' + %h3.warning= t '.already_moderated' %fieldset = form_for @event, method: :delete do |f| = hidden_field_tag :secret, params[:secret] - %h2=t '.confirm' + %h2= t '.confirm' = f.submit t('.ok'), name: :yes = link_to t('.ko'), @event, class: :button %fieldset - %legend=Event.model_name.human + %legend= Event.model_name.human = render file: '/events/show' diff --git a/app/views/layouts/mailer.html.haml b/app/views/layouts/mailer.html.haml new file mode 100644 index 00000000..28739ee9 --- /dev/null +++ b/app/views/layouts/mailer.html.haml @@ -0,0 +1,3 @@ +%hmtl + %body + = yield \ No newline at end of file diff --git a/app/views/layouts/mailer.text.haml b/app/views/layouts/mailer.text.haml new file mode 100644 index 00000000..03af2013 --- /dev/null +++ b/app/views/layouts/mailer.text.haml @@ -0,0 +1,5 @@ += t '.title' +\ += yield +\-- += t 'layouts.application.title' diff --git a/app/views/moderation_mailer/accept.text.haml b/app/views/moderation_mailer/accept.text.haml index 6a600d84..8a23fd8e 100644 --- a/app/views/moderation_mailer/accept.text.haml +++ b/app/views/moderation_mailer/accept.text.haml @@ -1,10 +1,8 @@ -=t '.title' -\ -=t '.body', author: @current_user += t '.body', author: @current_user \ = render file: '/events/show' \ -=t '.access' += t '.access' = event_url @event \ -=t '.signature' += t '.signature' diff --git a/app/views/moderation_mailer/create.text.haml b/app/views/moderation_mailer/create.text.haml index 885ff11b..35d5832d 100644 --- a/app/views/moderation_mailer/create.text.haml +++ b/app/views/moderation_mailer/create.text.haml @@ -1,8 +1,7 @@ -=t '.title' -\ -=t '.body', subject: @event.title, start_time: l(@event.start_time, format: :at) += t '.body', subject: @event.title, start_time: l(@event.start_time, + format: :at) = moderations_url \ = render file: '/events/show' \ -=t '.signature' += t '.signature' diff --git a/app/views/moderation_mailer/destroy.text.haml b/app/views/moderation_mailer/destroy.text.haml index fbba7da5..3867f329 100644 --- a/app/views/moderation_mailer/destroy.text.haml +++ b/app/views/moderation_mailer/destroy.text.haml @@ -1,10 +1,8 @@ -=t '.title' -\ -=t '.body', subject: @event.title, author: @current_user += t '.body', subject: @event.title, author: @current_user \ = @reason \ -=t '.reminder' += t '.reminder' = render file: '/events/show' \ -=t '.signature' += t '.signature' diff --git a/app/views/moderation_mailer/update.text.haml b/app/views/moderation_mailer/update.text.haml index 87dfec7b..cb2ca126 100644 --- a/app/views/moderation_mailer/update.text.haml +++ b/app/views/moderation_mailer/update.text.haml @@ -1,17 +1,16 @@ -=t '.title' -\ -=t '.body', subject: @event.title, author: @current_user||t('.submitter') += t '.body', subject: @event.title, author: @current_user || t('.submitter') -- new = render file: '/events/show' +:ruby + new = render file: '/events/show' -- former = @event -- @event = @older_event + former = @event + @event = @older_event -- prev = render file: '/events/show' -- @event = former + prev = render file: '/events/show' + @event = former -- require 'differ/format/patch' -- Differ.format = Differ::Format::Patch + require 'differ/format/patch' + Differ.format = Differ::Format::Patch = Differ.diff new, prev \ - if @current_user @@ -19,4 +18,4 @@ - else = edit_event_url @event, secret: @event.secret \ -=t '.signature' += t '.signature' diff --git a/app/views/moderations/index.html.haml b/app/views/moderations/index.html.haml index 08eb6bd4..ec1b0b7c 100644 --- a/app/views/moderations/index.html.haml +++ b/app/views/moderations/index.html.haml @@ -5,57 +5,88 @@ :markdown #### #{t '.rules'} -%table.list - %thead - %tr - %th= Event.human_attribute_name :title - %th - = Event.human_attribute_name :start_time - \- - = Event.human_attribute_name :end_time - %th= Event.human_attribute_name :city - %th= Event.human_attribute_name :region - %th= Event.human_attribute_name :submission_time - %th= t '.actions' - - %tbody - - @events.each do |event| +- if @orgas.present? + %table.list + %thead %tr - %td= event.title - %td= display_date event - %td= event.city - %td= event.region.name - %td= time_ago_in_words event.submission_time - %th.actions - = link_to edit_moderation_path event do - %em.fa.fa-pencil - = t 'edit' - \- - = link_to validate_moderation_path event do - %em.fa.fa-thumbs-up - = t 'validate' - \- - = link_to refuse_moderation_path event do - %em.fa.fa-thumbs-down - = t 'refuse' - \- - = link_to new_moderation_note_path event, envoiParMail: :oui do - %em.fa.fa-bullhorn - = t '.askInfos' - \- - = link_to new_moderation_note_path event do - %em.fa.fa-paperclip - = t '.createNote' + %th= Orga.human_attribute_name :name + %th= Orga.human_attribute_name :city + %th= Orga.human_attribute_name :region + %th= Orga.human_attribute_name :submission_time + %th= t '.actions' - - event.notes.each do |note| + %tbody + - @orgas.each do |orga| %tr - %td.empty/ - %td.note(colspan="5") - = raw note.contents - %em.author - = t '.posted_by', - author: "#{note.author.firstname} #{note.author.lastname}", - date: l(note.date, format: :at) rescue nil + %td= orga.name + %td= orga.city + %td= orga.region + %td= time_ago_in_words orga.submission_time + %th.actions + = link_to edit_orga_path orga do + %em.fa.fa-pencil + = t 'edit' + \- + = link_to validate_orga_path orga do + %em.fa.fa-thumbs-up + = t 'validate' + \- + = link_to cancel_orga_path orga do + %em.fa.fa-thumbs-down + = t 'refuse' + +- if @events.present? + %table.list + %thead + %tr + %th= Event.human_attribute_name :title + %th + = Event.human_attribute_name :start_time + \- + = Event.human_attribute_name :end_time + %th= Event.human_attribute_name :city + %th= Event.human_attribute_name :region + %th= Event.human_attribute_name :submission_time + %th= t '.actions' + + %tbody + - @events.each do |event| + %tr + %td= event.title + %td= display_date event + %td= event.city + %td= event.region.name + %td= time_ago_in_words event.submission_time + %th.actions + = link_to edit_moderation_path event do + %em.fa.fa-pencil + = t 'edit' + \- + = link_to validate_moderation_path event do + %em.fa.fa-thumbs-up + = t 'validate' + \- + = link_to refuse_moderation_path event do + %em.fa.fa-thumbs-down + = t 'refuse' + \- + = link_to new_moderation_note_path event, envoiParMail: :oui do + %em.fa.fa-bullhorn + = t '.askInfos' + \- + = link_to new_moderation_note_path event do + %em.fa.fa-paperclip + = t '.createNote' + + - event.notes.each do |note| + %tr + %td.empty/ + %td.note(colspan="5") + = raw note.contents + %em.author + = t '.posted_by', + author: "#{note.author.firstname} #{note.author.lastname}", + date: l(note.date, format: :at) rescue nil .logout = link_to destroy_user_session_path, method: :delete do diff --git a/app/views/orga_mailer/accept.text.haml b/app/views/orga_mailer/accept.text.haml new file mode 100644 index 00000000..4e4640a5 --- /dev/null +++ b/app/views/orga_mailer/accept.text.haml @@ -0,0 +1,8 @@ += t '.body', author: @current_user +\ += render file: '/orgas/show' +\ += t '.access' += orga_url @orga +\ += t '.signature' diff --git a/app/views/orga_mailer/create.text.haml b/app/views/orga_mailer/create.text.haml new file mode 100644 index 00000000..e124a824 --- /dev/null +++ b/app/views/orga_mailer/create.text.haml @@ -0,0 +1,7 @@ += t '.body', subject: @orga.name += edit_orga_url @orga, secret: @orga.secret +\ += t '.delete_link' += cancel_orga_url @orga, secret: @orga.secret +\ += t '.signature' diff --git a/app/views/orga_mailer/destroy.text.haml b/app/views/orga_mailer/destroy.text.haml new file mode 100644 index 00000000..20356819 --- /dev/null +++ b/app/views/orga_mailer/destroy.text.haml @@ -0,0 +1,10 @@ += t '.body', author: @current_user +\ += @reason +\ += t '.reclamation' +\ += t '.reminder' += render file: '/orgas/show' +\ += t '.signature' diff --git a/app/views/orga_mailer/update.text.haml b/app/views/orga_mailer/update.text.haml new file mode 100644 index 00000000..402f6a3b --- /dev/null +++ b/app/views/orga_mailer/update.text.haml @@ -0,0 +1,8 @@ += t '.body', subject: @orga.name, author: @current_user || t('.submitter') +\ += render file: '/orgas/show' +\ += t '.access' += orga_url @orga +\ += t '.signature' diff --git a/app/views/orgas/_form.html.haml b/app/views/orgas/_form.html.haml index c95aa1c6..c0f8e1ba 100644 --- a/app/views/orgas/_form.html.haml +++ b/app/views/orgas/_form.html.haml @@ -1,4 +1,7 @@ = form_for @orga do |f| + - if @orga.persisted? + = hidden_field_tag :secret, params[:secret] + - if @orga.errors.any? #flash_messages - @orga.errors.full_messages.each do |msg| diff --git a/app/views/orgas/cancel.html.haml b/app/views/orgas/cancel.html.haml new file mode 100644 index 00000000..cf8b04bd --- /dev/null +++ b/app/views/orgas/cancel.html.haml @@ -0,0 +1,18 @@ +%h2 + %em.fa.fa-trash-o + = t '.title' + +- if @orga.moderated? + %h3.warning= t '.already_moderated' + +%fieldset + = form_for @orga, method: :delete do |f| + = hidden_field_tag :secret, params[:secret] + %h2= t '.confirm' + + = f.submit t('.ok'), name: :yes + = link_to t('.ko'), @orga, class: :button + +%fieldset + %legend= Orga.model_name.human + = render file: '/orgas/show' diff --git a/app/views/orgas/show.html.haml b/app/views/orgas/show.html.haml index 456c8d5c..f85528cf 100644 --- a/app/views/orgas/show.html.haml +++ b/app/views/orgas/show.html.haml @@ -1,19 +1,24 @@ - set_orga_meta -= render 'search' +%h2 + - if @orga.kind + %em.fa{ class: "fa-#{@orga.kind.icon}", + title: Kind.human_attribute_name("name_#{@orga.kind.name}") } + = title @orga.name + = image_tag @orga.url + '/favicon.ico', alt: '', class: :favicon -%nav - = link_to orgas_path(q: params[:q], page: params[:page]), class: :back do - %em.fa.fa-arrow-left - = Orga.model_name.human.pluralize - -%fieldset.orga +- if controller.controller_name == 'orgas' && controller.action_name == 'show' %aside %h1 %em.fa.fa-link = t '.links' %ul.fa-ul + %li + = link_to orgas_path(q: params[:q], page: params[:page]), + class: :back do + %em.fa.fa-li.fa-arrow-left + = Orga.model_name.human.pluralize %li = link_to events_path tag: @orga.name do %em.fa.fa-li.fa-calendar @@ -47,52 +52,49 @@ = link_to edit_orga_path @orga do %em.fa.fa-lg.fa-pencil = t '.edit' + %h2 + = link_to cancel_orga_path @orga do + %em.fa.fa-lg.fa-thumbs-down + = t '.cancel' - %h2 - - if @orga.kind - %em.fa{ class: "fa-#{@orga.kind.icon}", - title: Kind.human_attribute_name("name_#{@orga.kind.name}") } - = title @orga.name - = image_tag @orga.url + '/favicon.ico', alt: '', class: :favicon +%dl + - if @orga.city.present? + %dt + %em.fa.fa-compress + = Orga.human_attribute_name :city + %dd= @orga.city + - if @orga.department.present? + %dt= Orga.human_attribute_name :department + %dd= @orga.department + - if @orga.region.present? + %dt + %em.fa.fa-shield + = Orga.human_attribute_name :region + %dd= @orga.region + - if @orga.url.present? + %dt + %em.fa.fa-external-link + = Orga.human_attribute_name :url + %dd= link_to @orga.url, @orga.url + - if @orga.feed.present? + %dt + %em.fa.fa-rss + = Orga.human_attribute_name :feed + %dd= link_to @orga.feed, @orga.feed + - if @orga.contact.present? + %dt + %em.fa.fa-envelope + = Event.human_attribute_name :contact + %dd= mail_to @orga.contact, nil, + encode: (request.format == 'text/html' ? :javascript : nil), + replace_at: ' CHEZ ', replace_dot: ' POINT ' - %dl - - if @orga.city.present? - %dt - %em.fa.fa-compress - = Orga.human_attribute_name :city - %dd= @orga.city - - if @orga.department.present? - %dt= Orga.human_attribute_name :department - %dd= @orga.department - - if @orga.region.present? - %dt - %em.fa.fa-shield - = Orga.human_attribute_name :region - %dd= @orga.region - - if @orga.url.present? - %dt - %em.fa.fa-external-link - = Orga.human_attribute_name :url - %dd= link_to @orga.url, @orga.url - - if @orga.feed.present? - %dt - %em.fa.fa-rss - = Orga.human_attribute_name :feed - %dd= link_to @orga.feed, @orga.feed - - if @orga.contact.present? - %dt - %em.fa.fa-envelope - = Event.human_attribute_name :contact - %dd= mail_to @orga.contact, nil, - encode: (request.format == 'text/html' ? :javascript : nil), - replace_at: ' CHEZ ', replace_dot: ' POINT ' - - - if @events_future.any? - %dt= t '.future' - %dd= t '.count', count: @events_future.count - - if @events_past.any? - %dt= t '.past' - %dd= t '.count', count: @events_past.count + - if @events_future && @events_future.any? + %dt= t '.future' + %dd= t '.count', count: @events_future.count + - if @events_future && @events_past.any? + %dt= t '.past' + %dd= t '.count', count: @events_past.count .events#map{ data: { url: maps_path(format: :json, tag: @orga.name, future: false) } } diff --git a/app/views/orgas/show.text.haml b/app/views/orgas/show.text.haml new file mode 100644 index 00000000..708383e5 --- /dev/null +++ b/app/views/orgas/show.text.haml @@ -0,0 +1,9 @@ +===================================================== +#{Orga.human_attribute_name(:kind).concat(':').ljust 12 } #{@orga.kind.name} +#{Orga.human_attribute_name(:name).concat(':').ljust 12 } #{@orga.name} +#{Orga.human_attribute_name(:region).concat(':').ljust 12 } #{@orga.region} +#{Orga.human_attribute_name(:url).concat(':').ljust 12 } #{@orga.url} +#{Orga.human_attribute_name(:feed).concat(':').ljust 12 } #{@orga.feed} +#{Orga.human_attribute_name(:contact).concat(':').ljust 12 } #{@orga.contact} +#{Orga.human_attribute_name(:submitter).concat(':').ljust 12 } #{@orga.submitter} +===================================================== diff --git a/app/views/orgas/validate.html.haml b/app/views/orgas/validate.html.haml new file mode 100644 index 00000000..908ee1cf --- /dev/null +++ b/app/views/orgas/validate.html.haml @@ -0,0 +1,18 @@ +%h2 + %em.fa.fa-exclamation-triangle + = t '.title' + += form_for @orga, url: { action: :accept }, html: { method: :put } do |f| + = link_to moderations_path do + %em.fa.fa-arrow-left + = t '.ko' + + = f.button do + %em.fa.fa-thumbs-up + = t '.ok' + +%fieldset + %legend + %em.fa.fa-calendar + = Orga.model_name.human + = render file: '/orgas/show' diff --git a/app/views/stats/index.html.haml b/app/views/stats/index.html.haml index 51063d2f..a941280b 100644 --- a/app/views/stats/index.html.haml +++ b/app/views/stats/index.html.haml @@ -3,15 +3,21 @@ = title t '.title' %dl - %dt=t '.all' - %dd.quantity= number_with_delimiter Event.count + %dt= t '.allEvents' + %dd.quantity= number_with_delimiter Event.moderated.count - %dt=t '.allModeration' - %dd.quantity= number_with_delimiter Event.unscoped.where(moderated: 0).count + %dt= t '.awaitingModeration' + %dd.quantity= number_with_delimiter Event.unmoderated.count + + %dt= t '.allOrgas' + %dd.quantity= number_with_delimiter Orga.moderated.count + + %dt= t '.awaitingModeration' + %dd.quantity= number_with_delimiter Orga.unmoderated.count %h3 %em.fa.fa-calendar - =t '.dates' + = t '.dates' %table.list.dates %thead @@ -33,17 +39,17 @@ %tfoot %tr - %th=t '.total' + %th= t '.total' - @years.each do |year| %th.quantity= number_with_delimiter year[1] %tr %th/ - %td.sparkline(colspan="#{@years.size}")/ + %td.sparkline{ colspan: @years.size } %h3 %em.fa.fa-shield - =t '.regional' + = t '.regional' %table.list.dates %thead @@ -51,7 +57,7 @@ %th/ - @years.each do |year| %th= year[0] - %th=t '.total' + %th= t '.total' %th/ %tbody - Region.all.each do |region| @@ -66,16 +72,16 @@ %th.quantity.total= number_with_delimiter total %td.sparkline/ -%h3=t '.city' +%h3= t '.city' -%p=t '.city_conditions' +%p= t '.city_conditions' %dl - @city_events.each do |city| %dt.item= city[0] %dd.quantity= number_with_delimiter city[1] -%h3=t '.web' +%h3= t '.web' :markdown #{t '.webalizer'} diff --git a/config/application.rb b/config/application.rb index 1308dec9..19dfde6a 100644 --- a/config/application.rb +++ b/config/application.rb @@ -40,5 +40,7 @@ module AgendaDuLibreRails config.action_dispatch.default_headers .merge! 'X-Frame-Options' => 'ALLOWALL' + + config.active_record.raise_in_transactional_callbacks = true end end diff --git a/config/locales/views/en.yml b/config/locales/views/en.yml index 1252b2b0..695bf299 100644 --- a/config/locales/views/en.yml +++ b/config/locales/views/en.yml @@ -53,10 +53,10 @@ en: infos: Informations new: title: Propose an event - subtitle: This page lets you submit an event in the Agenda du Libre. It - will not appear automatically in the Agenda, it will first be validated - by a moderator. An electronic mail will be sent to the submitter's - email when the event will be moderated. + subtitle: This page lets you submit an event. It will not appear + automatically, it will first be validated by a moderator. An electronic + mail will be sent to the submitter's email when the event will be + moderated. advises: "# Important recommandations \n \n* The event must relate to **Free Software**. The agenda is not intended for @@ -106,7 +106,7 @@ it more readable or agreable. cancel: title: Cancel event already_moderated: 'Event already moderated: this cancellation will - remove it from Agenda du Libre' + delete it' confirm: Do you confirm this event cancellation? preview: Event visualisation ok: Yes @@ -132,8 +132,9 @@ it more readable or agreable. stats: index: title: Statistics - all: Validated events - allModeration: Waiting for validation + allEvents: Validated events + allOrgas: Validated organisations + awaitingModeration: Waiting for validation dates: Per date regional: Per region city: Per city @@ -193,8 +194,8 @@ it more readable or agreable. about an expensive event or formation. If the event does relate to Free Software and this is not a paying formation, do not hesitate to submit it again with a clearer description. - reason_r_2_long: "Your event is relevant to the Agenda du Libre, but -moderators think its description is not complete enough to be validated. + reason_r_2_long: "Your event is relevant, but moderators think its +description is not complete enough to be validated. \n \nDescription must be comprehensible by a newcomer to Free Software, and must thus detail the meeting cause, the targeted audience, the role of the presented @@ -203,8 +204,7 @@ don't hesitate to repeat each time these informations, they are important. \n \nWe strongly invite you to submit again this event with a more complete description." - reason_r_3_long: Your event is relevant to the Agenda du Libre, but is - already present there. + reason_r_3_long: Your event is relevant, but has already been submitted. reason: Your reason destroy: ok: Event rejected @@ -266,6 +266,20 @@ description." about her acceptation or rejection. If this address is absent, the contact's will be used save: Save + validate: + ok: Yes + ko: Moderation + accept: + ok: Organisation accepted + cancel: + title: Delete organisation + already_moderated: 'Organisation already moderated: this will delete it' + confirm: Do you confirm this event cancellation? + preview: Organisation + ok: Yes + ko: No + destroy: + ok: Organisation was deleted devise: sessions: @@ -276,98 +290,107 @@ description." event_mailer: create: subject: "Your event: '%{subject}' is waiting for moderation" - title: Hello, body: "Your event titled '%{subject}', -\nwhich will take place on the '%{start_time}' has been recorded in the Agenda -du Libre. +\nwhich will take place on the '%{start_time}' has been recorded. \n \nThe moderation team will take charge of it very soon. \n -\nMeanwhile, and later if your event is accepted, you can edit it the address:" +\nMeanwhile, and later if your event is accepted, you can edit it at the +\nfollowing address:" delete_link: "and you can cancel it using the address:" - signature: "Thanks for your participation! -\n -\n-- -\nAgenda du Libre" + signature: Thanks for your participation! accept: subject: "Event '%{subject}' moderated" - title: Hello, body: "The event you submitted was moderated by %{moderator}. It is now - visible in the Agenda at the address:" + visible at the address:" edit_link: "You can modify this event later to add details at the address:" delete_link: "You can can also cancel it at the address:" - signature: "Thank you for your contribution at the Agenda du Libre and -see you soon! -\n -\n-- -\nThe moderation team" + signature: Thank you for your contribution and see you soon! destroy: subject: "Event '%{subject}' refused" - title: Hello, - body: You have submitted the following event in the Agenda du Libre, and - we thank you for this contribution. - reminder: "Reminder, here is your event's content:" + body: You have submitted the following event, and we thank you for this + contribution. reclamation: For any reclamation, don't hesitate to contact the moderation team. - signature: "With all our thanks for your contribution, -\n -\n-- -\nThe moderation team" + reminder: "Reminder, here is your event's content:" + signature: With all our thanks for your contribution moderation_mailer: create: subject: "New event to moderate: '%{subject}'" - title: Hello, body: A new event is to be moderated on - signature: "Thank you! -\n -\n-- -\nAgenda du Libre" + signature: Thank you! update: subject: "Event '%{subject}' edition" - title: Hello, body: "Event '%{subject}' has been modified by %{author}. \n \nModifications:" submitter: the submitter - signature: "Have a good day -\n -\n-- -\nThe moderation team" + signature: Have a good day accept: subject: "Event '%{subject}' moderated" - title: Hello, body: The event has been moderated by %{author}. access: "You can consult it here:" - signature: "-- -\nThe moderation team" + signature: Thanks for your contribution! destroy: subject: "Event '%{subject}' refused" - title: Hello, body: "The event '%{subject}' was rejected by %{author} for the following reason: \n \n" reminder: "The event:" - signature: "-- -\nThe Agenda du Libre moderation team" + signature: Thank you for your contribution note_mailer: notify: subject: "Demand for more information on event '%{subject}'" - title: Hello, body: "We have received your event proposal '%{subject}', -\nit is relevant to the Agenda du Libre. Nonetheless, before acceptation we -\nneed some supplementary informations:" +\nit is relevant. Nonetheless, before acceptation we need some complementary +\ninformations:" edit_link: "We invite you to directly add these informations to the \nevent at the following address:" - signature: "With all our thanks for your contribution, -\n -\n-- -\nThe Agenda du Libre moderation team" + signature: Thank you for your contribution create: subject: "A note was added to event '%{subject}'" - title: Hello, body: "A comment was added to '%{subject}':" - signature: "-- -\nModeration team" + signature: Thank you for your contribution + orga_mailer: + create: + subject: Organisation '%{subject}' is awaiting moderation + body: "Organisation titled '%{subject}' has been recorded. +\n +\nThe moderation team will take charge of it very soon. +\n +\nMeanwhile, and later if this organisation is accepted, you can edit it at the +\nfollowing address:" + delete_link: "and you can delete it using the address:" + signature: Thank you for your contribution and see you soon! + update: + subject: "Organisation '%{subject}' modified" + body: "Organisation '%{subject}' has been modified by %{author}. +\n +\nModifications:" + submitter: the submitter + access: "You can consult it here:" + signature: Have a good day! + accept: + subject: "Organisation '%{subject}' moderated" + body: "Organisation has been modérée by %{moderator}. +\nYou can acces it here:" + edit_link: "Vous pouvez modifier cette organisation ultérieurement pour y ajouter des +\nprécisions en vous rendant à l'adresse:" + delete_link: "You can also delete it using the address:" + signature: Thank you for your contribution and see you soon! + accept: + subject: "Organisation '%{subject}' moderated" + body: The orgnisation has been moderated by %{author}. + access: "You can consult it here:" + signature: Thanks for your contribution! + destroy: + subject: Organisation '%{subject}' deleted + body: You submitted the following organisation, and we thank you for this + contribution. + reclamation: For any reclamation, don't hesitate to contact the + moderation team. + reminder: "Reminder, here is your organisation's content:" + signature: With all our thanks for your contribution diff --git a/config/locales/views/fr.yml b/config/locales/views/fr.yml index 7141503b..7dc40b0f 100644 --- a/config/locales/views/fr.yml +++ b/config/locales/views/fr.yml @@ -29,6 +29,8 @@ fr: stats: Statistiques contact: Contact moderation: Modération + mailer: + title: Bonjour, events: index: calendar_in: Ce calendrier en %{rss}, %{webcal} ou %{ical} @@ -53,11 +55,10 @@ fr: infos: Informations new: title: Proposer un événement - subtitle: Cette page permet de soumettre un événement dans l'Agenda du - Libre. Celui-ci n'apparaîtra pas automatiquement dans l'Agenda, il sera - tout d'abord validé par un modérateur. Un courrier électronique sera - envoyé à l'adresse e-mail du soumetteur donnée ci-dessous lorsque - l'événement aura été modéré. + subtitle: Cette page permet de soumettre un événement. Celui-ci + n'apparaîtra pas automatiquement, il sera tout d'abord validé par un + modérateur. Un courrier électronique sera envoyé à l'adresse e-mail du + soumetteur donnée ci-dessous lorsque l'événement aura été modéré. preview: Prévisualisation edit: Création create: @@ -100,8 +101,7 @@ fr: visualise: Visualiser cancel: title: Annulation de l'événement - already_moderated: "Événement déjà modéré: cette annulation le fera - disparaître de l'Agenda du Libre" + already_moderated: 'Événement déjà modéré: cette annulation le supprimera' confirm: Confirmez-vous l'annulation de cet événement? preview: Visualisation de l'événement ok: Oui @@ -120,7 +120,7 @@ fr: \n * Vous pouvez limiter les évènements à un certain tag, en passant le paramètre `tag`. Cela permet par exemple de récupérer un flux des - évènements de votre organisation, à partir du moment où vous pensez à + évènements d'une organisation, à partir du moment où vous pensez à marquer tous vos évènements avec un tag précis. \n Exemple: `%{tag}`\n * Vous pouvez modifier la limite des 30 prochains jours des flux en @@ -129,8 +129,9 @@ fr: stats: index: title: Statistiques - all: Événements validés - allModeration: En cours de modération + allEvents: Événements validés + allOrgas: Organisations validées + awaitingModeration: En cours de modération dates: Par date regional: Par région city: Par ville @@ -193,9 +194,9 @@ fr: concerne vraiment le Logiciel Libre et qu'il ne s'agit pas d'une formation payante, n'hésitez pas à le soumettre à nouveau avec une description plus claire. - reason_r_2_long: "Votre événement a tout à fait sa place dans l'Agenda du -Libre, mais les modérateurs trouvent que la description de celui-ci n'est pas -assez complète pour être validée. + reason_r_2_long: "Votre événement a tout à fait sa place ici, mais les +modérateurs trouvent que la description de celui-ci n'est pas assez complète +pour être validée. \n \nLa description doit être compréhensible par un nouveau venu dans le monde du Libre, et doit donc préciser le principe de la rencontre, le public visé, le @@ -205,8 +206,8 @@ répéter à chaque fois ces informations, elles sont importantes. \n \nNous vous invitons donc vivement à soumettre à nouveau cet événement avec une description plus complète." - reason_r_3_long: Votre événement a tout à fait sa place dans l'Agenda du - Libre, mais il est déjà enregistré dans celui-ci. + reason_r_3_long: Votre événement a tout à fait sa place ici, mais il a + déjà été enregistré. reason: Votre raison destroy: ok: Événement rejeté @@ -268,6 +269,20 @@ description plus complète." rejet. Si cette adresse n'est pas présente, l'adresse de contact sera utilisée save: Envoyer + validate: + ok: Oui + ko: Modération + accept: + ok: Organisation acceptée + cancel: + title: Suppression de l'organisation + already_moderated: 'Organisation déjà modérée: cela la supprimera' + confirm: Confirmez-vous la suppression de cette organisation? + preview: Organisation + ok: Oui + ko: Non + destroy: + ok: L'organisation a bien été supprimée devise: sessions: @@ -279,99 +294,98 @@ description plus complète." create: subject: "Votre événement: '%{subject}' est en attente de modération" - title: Bonjour, body: "Votre événement intitulé '%{subject}', -\nqui aura lieu le '%{start_time}' a bien été enregistré dans l'Agenda du -Libre. +\nqui aura lieu le '%{start_time}' a bien été enregistré. \n \nL'équipe de modération le prendra en charge très prochainement. \n \nPendant la modération et après celle-ci si votre événement est validé, vous pouvez éditer votre événement à l'adresse:" delete_link: "et vous pouvez l'annuler en utilisant l'adresse:" - signature: "Merci de votre participation! -\n -\n-- -\nAgenda du Libre" + signature: Merci de votre participation! accept: subject: "Événement '%{subject}' modéré" - title: Bonjour, body: "L'événement que vous avez soumis a été modéré par %{moderator}. Il -est maintenant visible dans l'Agenda à l'adresse:" +est maintenant visible à l'adresse:" edit_link: "Vous pouvez modifier cet événement ultérieurement pour y ajouter des précisions en vous rendant à l'adresse:" delete_link: "Vous pouvez également l'annuler en vous rendant à l'adresse:" - signature: "Merci de votre contribution à l'Agenda du Libre et à -bientôt! -\n -\n-- -\nL'équipe de modération" + signature: Merci de votre contribution et à bientôt! destroy: subject: "Événement '%{subject}' refusé" - title: Bonjour, - body: Vous avez soumis l'événement suivant dans l'Agenda du Libre, et - nous vous remercions de cette contribution. - reminder: "Pour rappel, voici le contenu de votre événement:" + body: Vous avez soumis l'événement suivant, et nous vous remercions de + cette contribution. reclamation: Pour toute réclamation, n'hésitez pas à contacter l'équipe de modérateurs. - signature: "Avec tous nos remerciements pour votre contribution, -\n -\n-- -\nL'équipe de modération" + reminder: "Pour rappel, voici le contenu de votre événement:" + signature: Avec tous nos remerciements pour votre contribution moderation_mailer: create: subject: "Nouvel événement à modérer: '%{subject}'" - title: Bonjour, body: Un nouvel événement est à modérer sur - signature: "Merci! -\n -\n-- -\nAgenda du Libre" + signature: Merci! update: subject: "Édition de l'événement '%{subject}'" - title: Bonjour, body: "L'événement '%{subject}' a été modifié par %{author}. \n \nModifications apportées:" submitter: le soumetteur - signature: "Bonne journée -\n -\n-- -\nL'équipe de modération" + signature: Bonne journée accept: subject: "Événement '%{subject}' modéré" - title: Bonjour, body: L'événement a été modéré par %{author}. access: "Vous pouvez le consulter ici:" - signature: "-- -\nL'équipe de modération" + signature: Merci pour votre contribution! destroy: subject: "Événement '%{subject}' refusé" - title: Bonjour, body: "L'événement '%{subject}' a été rejeté par %{author} pour la raison suivante:" reminder: "Pour rappel, l'événement:" - signature: "-- -\nL'équipe des modérateurs de l'Agenda du Libre" + signature: Merci pour votre contribution note_mailer: notify: subject: "Demande d'informations sur l'événement '%{subject}'" - title: Bonjour, body: "Nous avons bien reçu votre proposition d'événement '%{subject}', -\net celui-ci a toute sa place dans l'Agenda du Libre. Néanmoins, avant -\nd'être validé, nous avons besoin de quelques informations -\ncomplémentaires sur cet événement:" +\net celui-ci a toute sa place ici. Néanmoins, avant d'être validé, nous +\navons besoin de quelques informations complémentaires sur cet événement:" edit_link: "Nous vous invitons à ajouter ces informations en éditant directement \nl'événement à l'adresse suivante:" - signature: "Avec tous nos remerciements pour votre contribution, -\n -\n-- -\nL'équipe des modérateurs de l'Agenda du Libre" + signature: Avec tous nos remerciements pour votre contribution create: subject: "Une note a été rajoutée à l'événement '%{subject}'" - title: Bonjour, body: "Une note a été rajoutée à '%{subject}':" - signature: "-- -\nL'équipe de modération" + signature: Merci pour votre contribution + orga_mailer: + create: + subject: Organisation '%{subject}' en attente de modération + body: "Organisation '%{subject}' a bien été enregistrée. +\n +\nL'équipe de modération la prendra en charge très prochainement. +\n +\nPendant la modération et après celle-ci si cette organisation est validée, +\nvous pouvez l'éditer à l'adresse:" + delete_link: "et vous pouvez l'annuler en utilisant l'adresse:" + signature: Merci de votre participation! + update: + subject: "Organisation '%{subject}' modifiée" + body: "L'organisation '%{subject}' a été modifiée par %{author}. +\n +\nModifications apportées:" + submitter: le soumetteur + access: "Vous pouvez la consulter ici:" + signature: Bonne journée + accept: + subject: "Organisation '%{subject}' modérée" + body: L'organisation a été modérée par %{author}. + access: "Vous pouvez la consulter ici:" + signature: Merci pour votre contribution! + destroy: + subject: Organisation '%{subject}' supprimée + body: Vous avez soumis l'organisation suivante, et nous vous remercions + de cette contribution. + reclamation: Pour toute réclamation, n'hésitez pas à contacter l'équipe + de modérateurs. + reminder: "Pour rappel, voici le contenu de l'organisation:" + signature: Avec tous nos remerciements pour votre contribution diff --git a/config/routes.rb b/config/routes.rb index a76fcb77..8005e48e 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -19,7 +19,10 @@ Rails.application.routes.draw do resources :regions, only: [:index] resources :tags, only: [:index, :show] resources :maps, only: [:index] - resources :orgas + resources :orgas do + get :cancel, :validate, :refuse, on: :member + put :accept, on: :member + end # Manage former php pages get 'showevent.php', to: redirect { |_, req| "events/#{req.params[:id]}" } diff --git a/db/migrate/20150711164423_create_versions.rb b/db/migrate/20150711164423_create_versions.rb new file mode 100644 index 00000000..ea506fb2 --- /dev/null +++ b/db/migrate/20150711164423_create_versions.rb @@ -0,0 +1,14 @@ +# Add the version table necessary to paper trail +class CreateVersions < ActiveRecord::Migration + def change + create_table :versions do |t| + t.string :item_type, null: false + t.integer :item_id, null: false + t.string :event, null: false + t.string :whodunnit + t.text :object + t.datetime :created_at + end + add_index :versions, [:item_type, :item_id] + end +end diff --git a/db/schema.rb b/db/schema.rb index beaf0b73..0329fd25 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -1,5 +1,4 @@ # encoding: UTF-8 -# rubocop:disable all # 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. @@ -12,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20150301223829) do +ActiveRecord::Schema.define(version: 20150711164423) do create_table "active_admin_comments", force: :cascade do |t| t.string "namespace", limit: 255 @@ -25,9 +24,9 @@ ActiveRecord::Schema.define(version: 20150301223829) do t.datetime "updated_at" end - add_index "active_admin_comments", ["author_type", "author_id"], name: "index_active_admin_comments_on_author_type_and_author_id", using: :btree - add_index "active_admin_comments", ["namespace"], name: "index_active_admin_comments_on_namespace", using: :btree - add_index "active_admin_comments", ["resource_type", "resource_id"], name: "index_active_admin_comments_on_resource_type_and_resource_id", using: :btree + add_index "active_admin_comments", ["author_type", "author_id"], name: "index_active_admin_comments_on_author_type_and_author_id" + add_index "active_admin_comments", ["namespace"], name: "index_active_admin_comments_on_namespace" + add_index "active_admin_comments", ["resource_type", "resource_id"], name: "index_active_admin_comments_on_resource_type_and_resource_id" create_table "admin_users", force: :cascade do |t| t.string "email", limit: 255, default: "", null: false @@ -44,8 +43,8 @@ ActiveRecord::Schema.define(version: 20150301223829) do t.datetime "updated_at" end - add_index "admin_users", ["email"], name: "index_admin_users_on_email", unique: true, using: :btree - add_index "admin_users", ["reset_password_token"], name: "index_admin_users_on_reset_password_token", unique: true, using: :btree + add_index "admin_users", ["email"], name: "index_admin_users_on_email", unique: true + add_index "admin_users", ["reset_password_token"], name: "index_admin_users_on_reset_password_token", unique: true create_table "cities", force: :cascade do |t| t.string "name", limit: 255, default: "", null: false @@ -57,7 +56,7 @@ ActiveRecord::Schema.define(version: 20150301223829) do t.float "longitude", limit: 24 end - add_index "cities", ["name"], name: "cities_name", using: :btree + add_index "cities", ["name"], name: "cities_name" create_table "events", force: :cascade do |t| t.string "title", limit: 255, default: "", null: false @@ -84,7 +83,7 @@ ActiveRecord::Schema.define(version: 20150301223829) do t.string "place_name", limit: 255 end - add_index "events", ["start_time", "end_time"], name: "events_date", using: :btree + add_index "events", ["start_time", "end_time"], name: "events_date" create_table "kinds", force: :cascade do |t| t.string "name", limit: 255, null: false @@ -117,12 +116,32 @@ ActiveRecord::Schema.define(version: 20150301223829) do t.boolean "deleted", limit: 1, default: false, null: false end - add_index "orgas", ["kind_id"], name: "index_orgas_on_kind_id", using: :btree + add_index "orgas", ["kind_id"], name: "index_orgas_on_kind_id" create_table "regions", force: :cascade do |t| t.string "name", limit: 255, default: "", null: false end + create_table "taggings", force: :cascade do |t| + t.integer "tag_id" + t.integer "taggable_id" + t.string "taggable_type", limit: 255 + t.integer "tagger_id" + t.string "tagger_type", limit: 255 + t.string "context", limit: 128 + t.datetime "created_at" + end + + add_index "taggings", ["tag_id", "taggable_id", "taggable_type", "context", "tagger_id", "tagger_type"], name: "taggings_idx", unique: true + add_index "taggings", ["taggable_id", "taggable_type", "context"], name: "index_taggings_on_taggable_id_and_taggable_type_and_context" + + create_table "tags", force: :cascade do |t| + t.string "name", limit: 255 + t.integer "taggings_count", default: 0 + end + + add_index "tags", ["name"], name: "index_tags_on_name", unique: true + create_table "translations", force: :cascade do |t| t.string "locale", limit: 255 t.string "key", limit: 255 @@ -139,4 +158,15 @@ ActiveRecord::Schema.define(version: 20150301223829) do t.string "firstname", limit: 255, default: "", null: false end + create_table "versions", force: :cascade do |t| + t.string "item_type", null: false + t.integer "item_id", null: false + t.string "event", null: false + t.string "whodunnit" + t.text "object" + t.datetime "created_at" + end + + add_index "versions", ["item_type", "item_id"], name: "index_versions_on_item_type_and_item_id" + end diff --git a/test/controllers/notes_controller_test.rb b/test/controllers/notes_controller_test.rb index 98938349..82ad020b 100644 --- a/test/controllers/notes_controller_test.rb +++ b/test/controllers/notes_controller_test.rb @@ -16,7 +16,7 @@ class NotesControllerTest < ActionController::TestCase end test 'should create note' do - assert_difference('Note.count') do + assert_difference 'Note.count' do post :create, moderation_id: @note.event.id, note: { contents: @note.contents } @@ -26,7 +26,7 @@ class NotesControllerTest < ActionController::TestCase end test 'should send mail' do - assert_difference('Note.count') do + assert_difference 'Note.count' do post :create, moderation_id: @note.event.id, envoiParMail: 'oui', note: { contents: @note.contents } @@ -38,7 +38,7 @@ class NotesControllerTest < ActionController::TestCase end test 'should not create note' do - assert_no_difference('Note.count') do + assert_no_difference 'Note.count' do post :create, moderation_id: @note.event.id, note: { nothing: 'almost' } diff --git a/test/controllers/orgas_controller_test.rb b/test/controllers/orgas_controller_test.rb index 25d9de83..8748cb0a 100644 --- a/test/controllers/orgas_controller_test.rb +++ b/test/controllers/orgas_controller_test.rb @@ -3,6 +3,7 @@ require 'test_helper' # Free Software groups life cycle class OrgasControllerTest < ActionController::TestCase include Devise::TestHelpers + setup do @orga = orgas :one end diff --git a/test/fixtures/notes.yml b/test/fixtures/notes.yml index 0e6f3493..9dc058d9 100644 --- a/test/fixtures/notes.yml +++ b/test/fixtures/notes.yml @@ -4,10 +4,10 @@ one: event: one author: one contents: MyText - date: 2014-01-11 10:55:54 + date: <%= 2.days.ago %> two: event: one author: one contents: MyText - date: 2014-01-11 10:55:54 + date: <%= 20.days.ago %> diff --git a/test/fixtures/orgas.yml b/test/fixtures/orgas.yml index d9ed9150..3e8cbecf 100644 --- a/test/fixtures/orgas.yml +++ b/test/fixtures/orgas.yml @@ -10,7 +10,9 @@ one: feed: http://april.org/index.rss contact: test@exemple.com submitter: test@exemple.com + submission_time: 2013-12-28 16:04:56 secret: my_secret + moderated: true two: kind: provider @@ -22,3 +24,4 @@ two: feed: http://april.org/index.rss contact: test@exemple.com submitter: test@exemple.com + submission_time: 2013-12-28 16:04:56 diff --git a/test/fixtures/users.yml b/test/fixtures/users.yml index 17627694..c5a47648 100644 --- a/test/fixtures/users.yml +++ b/test/fixtures/users.yml @@ -3,5 +3,9 @@ one: firstname: first lastname: last login: aNiceLogin + two: email: two@example.com + firstname: second + lastname: last + login: secondLogin diff --git a/test/mailers/orga_mailer_test.rb b/test/mailers/orga_mailer_test.rb new file mode 100644 index 00000000..c98e2d66 --- /dev/null +++ b/test/mailers/orga_mailer_test.rb @@ -0,0 +1,47 @@ +require 'test_helper' + +# Test and check how the organisations mailer is working +class OrgaMailerTest < ActionMailer::TestCase + setup do + ActionMailer::Base.default_url_options[:host] = 'localhost:3000' + + @config = Rails.application.config + end + + test 'create' do + mail = OrgaMailer.create Orga.last + assert_match(/Organisation .* en attente de modération/, + mail.subject) + assert_equal [Orga.last.submitter], mail.to + assert_equal [@config.action_mailer.default_options[:from]], + mail.from + assert_match 'Bonjour', mail.body.encoded + end + + test 'update' do + mail = OrgaMailer.update Orga.last + assert_match(/Organisation .* modifiée/, mail.subject) + assert_equal [Orga.last.submitter], mail.to + assert_equal [@config.action_mailer.default_options[:from]], + mail.from + assert_match 'Bonjour', mail.body.encoded + end + + test 'accept' do + mail = OrgaMailer.accept Orga.last + assert_match(/Organisation .* modérée/, mail.subject) + assert_equal [Orga.last.submitter], mail.to + assert_equal [@config.action_mailer.default_options[:from]], + mail.from + assert_match 'Bonjour', mail.body.encoded + end + + test 'destroy' do + mail = OrgaMailer.destroy Orga.last, 'hello world' + assert_match(/Organisation .* supprimée/, mail.subject) + assert_equal [Orga.last.submitter], mail.to + assert_equal [@config.action_mailer.default_options[:from]], + mail.from + assert_match 'Bonjour', mail.body.encoded + end +end diff --git a/test/mailers/previews/note_mailer_preview.rb b/test/mailers/previews/note_mailer_preview.rb index 997a7739..230f7434 100644 --- a/test/mailers/previews/note_mailer_preview.rb +++ b/test/mailers/previews/note_mailer_preview.rb @@ -3,6 +3,11 @@ class NoteMailerPreview < ActionMailer::Preview # Preview this email at http://localhost:3000/rails/mailers/note_mailer/notify def notify ActionMailer::Base.default_url_options[:host] = 'localhost:3000' + puts 'XXXXXXXX' + puts Note.all + puts User.all + puts Event.count + puts Note.last.event NoteMailer.notify Note.last end diff --git a/test/mailers/previews/orga_mailer_preview.rb b/test/mailers/previews/orga_mailer_preview.rb new file mode 100644 index 00000000..6a91fbcd --- /dev/null +++ b/test/mailers/previews/orga_mailer_preview.rb @@ -0,0 +1,26 @@ +# Preview all emails at http://localhost:3000/rails/mailers/orga_mailer +class OrgaMailerPreview < ActionMailer::Preview + # Preview this email at http://localhost:3000/rails/mailers/orga_mailer/create + def create + ActionMailer::Base.default_url_options[:host] = 'localhost:3000' + OrgaMailer.create Orga.last + end + + # Preview this email at http://localhost:3000/rails/mailers/orga_mailer/update + def update + ActionMailer::Base.default_url_options[:host] = 'localhost:3000' + OrgaMailer.update Orga.last + end + + # Preview this email at http://localhost:3000/rails/mailers/orga_mailer/accept + def accept + ActionMailer::Base.default_url_options[:host] = 'localhost:3000' + OrgaMailer.accept Orga.last + end + + # Preview this email at http://localhost:3000/rails/mailers/orga_mailer/destroy + def destroy + ActionMailer::Base.default_url_options[:host] = 'localhost:3000' + OrgaMailer.destroy Orga.last, 'hello world' + end +end diff --git a/test/models/orga_test.rb b/test/models/orga_test.rb index 38981707..d35f6d7c 100644 --- a/test/models/orga_test.rb +++ b/test/models/orga_test.rb @@ -1,7 +1,55 @@ require 'test_helper' +# Verify the organisation creatino and mail workflow class OrgaTest < ActiveSupport::TestCase - # test "the truth" do - # assert true - # end + setup do + ActionMailer::Base.default_url_options[:host] = 'localhost:3000' + + @config = Rails.application.config + end + + test 'propose orga' do + assert_difference 'ActionMailer::Base.deliveries.size', 1 do + Orga.create!( + kind: Kind.first, + name: 'Tested organisation', + url: 'http://example.com', + region: Region.first, + contact: 'contact@example.com' + ) + end + end + + test 'set and send secret' do + @orga = orgas(:two) + assert_nil @orga.secret + assert_difference 'ActionMailer::Base.deliveries.size', 2 do + @orga.name = 'hop hop hop' + @orga.save! + end + assert_not_nil @orga.secret + end + + test 'edit orga' do + @orga = orgas(:one) + assert_difference 'ActionMailer::Base.deliveries.size' do + @orga.name += ' addition added as an edit :)' + @orga.save! + end + end + + test 'accept orga' do + @orga = orgas(:two) + assert_difference 'ActionMailer::Base.deliveries.size', 2 do + @orga.moderated = true + @orga.save! + end + end + + test 'refuse orga' do + @orga = orgas(:two) + assert_difference 'ActionMailer::Base.deliveries.size' do + @orga.destroy! + end + end end