diff --git a/Capfile b/Capfile index 17e03a6f8..053d1feb9 100644 --- a/Capfile +++ b/Capfile @@ -9,6 +9,7 @@ require 'capistrano/bundler' #require 'capistrano/rails/assets' require 'capistrano/rails/migrations' #require 'capistrano/passenger' +require 'capistrano/delayed-job' # Load custom tasks from `lib/capistrano/tasks` if you have any defined Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r } diff --git a/Gemfile b/Gemfile index a986bf6e2..6913ddb52 100644 --- a/Gemfile +++ b/Gemfile @@ -43,6 +43,9 @@ gem 'paranoia' gem 'savon' gem 'dalli' gem 'rollbar', '~> 2.2.1' +gem 'delayed_job_active_record' +gem 'daemons' +gem 'devise-async' gem 'ahoy_matey', '~> 1.2.1' gem 'groupdate' # group temporary data @@ -66,6 +69,7 @@ group :development, :test do gem "capistrano-bundler", '1.1.4', require: false gem "capistrano-rails", '1.1.3', require: false gem "capistrano-rvm", require: false + gem 'capistrano3-delayed-job', '~> 1.0' gem "bullet" gem "faker" end diff --git a/Gemfile.lock b/Gemfile.lock index 26b825c0d..7d5ebee59 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -79,6 +79,8 @@ GEM capistrano-rvm (0.1.2) capistrano (~> 3.0) sshkit (~> 1.2) + capistrano3-delayed-job (1.4.0) + capistrano (>= 3.0.0) capybara (2.5.0) mime-types (>= 1.16) nokogiri (>= 1.3.3) @@ -107,9 +109,15 @@ GEM simplecov (~> 0.10.0) term-ansicolor (~> 1.3) thor (~> 0.19.1) + daemons (1.2.3) dalli (2.7.4) database_cleaner (1.5.0) debug_inspector (0.0.2) + delayed_job (4.0.6) + activesupport (>= 3.0, < 5.0) + delayed_job_active_record (4.0.3) + activerecord (>= 3.0, < 5.0) + delayed_job (>= 3.0, < 4.1) devise (3.5.2) bcrypt (~> 3.0) orm_adapter (~> 0.1) @@ -117,6 +125,8 @@ GEM responders thread_safe (~> 0.1) warden (~> 1.2.3) + devise-async (0.10.1) + devise (~> 3.2) diff-lcs (1.2.5) docile (1.1.5) domain_name (0.5.24) @@ -238,7 +248,7 @@ GEM orm_adapter (0.5.0) paranoia (2.1.3) activerecord (~> 4.0) - pg (0.18.2) + pg (0.18.3) poltergeist (1.6.0) capybara (~> 2.1) cliver (~> 0.3.1) @@ -307,12 +317,12 @@ GEM rspec-support (3.3.0) ruby-progressbar (1.7.5) sass (3.4.18) - sass-rails (5.0.3) + sass-rails (5.0.4) railties (>= 4.0.0, < 5.0) sass (~> 3.1) sprockets (>= 2.8, < 4.0) sprockets-rails (>= 2.0, < 4.0) - tilt (~> 1.1) + tilt (>= 1.1, < 3) savon (2.11.1) akami (~> 1.2) builder (>= 2.1.2) @@ -348,7 +358,7 @@ GEM thor (0.19.1) thread (0.2.2) thread_safe (0.3.5) - tilt (1.4.1) + tilt (2.0.1) tins (1.6.0) turbolinks (2.5.3) coffee-rails @@ -398,13 +408,17 @@ DEPENDENCIES capistrano-bundler (= 1.1.4) capistrano-rails (= 1.1.3) capistrano-rvm + capistrano3-delayed-job (~> 1.0) capybara ckeditor coffee-rails (~> 4.1.0) coveralls + daemons dalli database_cleaner + delayed_job_active_record devise + devise-async email_spec factory_girl_rails faker diff --git a/app/assets/images/header_bg.jpg b/app/assets/images/header_bg.jpg index 8d991b8f8..78e357c44 100644 Binary files a/app/assets/images/header_bg.jpg and b/app/assets/images/header_bg.jpg differ diff --git a/app/assets/javascripts/ckeditor/reinit.js b/app/assets/javascripts/ckeditor/reinit.js new file mode 100644 index 000000000..fe8e8cff3 --- /dev/null +++ b/app/assets/javascripts/ckeditor/reinit.js @@ -0,0 +1,7 @@ +$(document).bind('page:change', function() { + if (typeof(CKEDITOR) != "undefined"){ + for(name in CKEDITOR.instances){ + try{CKEDITOR.replace(name);}catch(err){}; + } + } +}); \ No newline at end of file diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb index f07507600..96aecf083 100644 --- a/app/controllers/comments_controller.rb +++ b/app/controllers/comments_controller.rb @@ -8,8 +8,8 @@ class CommentsController < ApplicationController def create if @comment.save - Mailer.comment(@comment).deliver_now if email_on_debate_comment? - Mailer.reply(@comment).deliver_now if email_on_comment_reply? + Mailer.comment(@comment).deliver_later if email_on_debate_comment? + Mailer.reply(@comment).deliver_later if email_on_comment_reply? else render :new end diff --git a/app/controllers/verification/email_controller.rb b/app/controllers/verification/email_controller.rb index 1c07b1457..cb7542c80 100644 --- a/app/controllers/verification/email_controller.rb +++ b/app/controllers/verification/email_controller.rb @@ -16,7 +16,7 @@ class Verification::EmailController < ApplicationController @email = Verification::Email.new(@verified_user) if @email.save current_user.reload - Mailer.email_verification(current_user, @email.recipient, @email.encrypted_token).deliver_now + Mailer.email_verification(current_user, @email.recipient, @email.encrypted_token).deliver_later redirect_to account_path, notice: t('verification.email.create.flash.success', email: @verified_user.email) else redirect_to verified_user_path, alert: t('verification.email.create.alert.failure') diff --git a/app/models/user.rb b/app/models/user.rb index d03cac6e4..7d6ca2380 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -6,7 +6,7 @@ class User < ActiveRecord::Base apply_simple_captcha devise :database_authenticatable, :registerable, :confirmable, - :recoverable, :rememberable, :trackable, :validatable, :omniauthable + :recoverable, :rememberable, :trackable, :validatable, :omniauthable, :async acts_as_voter acts_as_paranoid column: :hidden_at diff --git a/app/views/shared/_locale_switcher.html.erb b/app/views/shared/_locale_switcher.html.erb index c95ad58a1..24165f2af 100644 --- a/app/views/shared/_locale_switcher.html.erb +++ b/app/views/shared/_locale_switcher.html.erb @@ -1,16 +1,18 @@ -
- - - <%= t("layouts.header.locale") %> - -
- -
-
+<% if I18n.available_locales.size > 1 %> +
+ + + <%= t("layouts.header.locale") %> + +
+ +
+
+<% end %> diff --git a/bin/delayed_job b/bin/delayed_job new file mode 100755 index 000000000..edf195985 --- /dev/null +++ b/bin/delayed_job @@ -0,0 +1,5 @@ +#!/usr/bin/env ruby + +require File.expand_path(File.join(File.dirname(__FILE__), '..', 'config', 'environment')) +require 'delayed/command' +Delayed::Command.new(ARGV).daemonize diff --git a/config/application.rb b/config/application.rb index 8cd17632d..76466329e 100644 --- a/config/application.rb +++ b/config/application.rb @@ -33,5 +33,6 @@ module Participacion # Add lib to the autoload path config.autoload_paths << Rails.root.join('lib') config.time_zone = 'Madrid' + config.active_job.queue_adapter = :delayed_job end end diff --git a/config/deploy.rb b/config/deploy.rb index 5a8ec62aa..75a84a1e0 100644 --- a/config/deploy.rb +++ b/config/deploy.rb @@ -36,6 +36,8 @@ set :local_user, ENV['USER'] # Run test before deploy set :tests, ["spec"] +set :delayed_job_workers, 2 + # Config files should be copied by deploy:setup_config set(:config_files, %w( log_rotation @@ -57,4 +59,6 @@ namespace :deploy do after :finishing, 'deploy:cleanup' # Restart unicorn after 'deploy:publishing', 'deploy:restart' + # Restart Delayed Jobs + after 'deploy:published', 'delayed_job:restart' end diff --git a/config/deploy/production.rb b/config/deploy/production.rb index 83c691aa5..49968fc51 100644 --- a/config/deploy/production.rb +++ b/config/deploy/production.rb @@ -6,7 +6,7 @@ set :ssh_options, port: deploysecret(:ssh_port) set :stage, :production set :rails_env, :production -server deploysecret(:server1), user: deploysecret(:user), roles: %w(web app db importer) +#server deploysecret(:server1), user: deploysecret(:user), roles: %w(web app db importer) server deploysecret(:server2), user: deploysecret(:user), roles: %w(web app db importer) server deploysecret(:server3), user: deploysecret(:user), roles: %w(web app db importer) server deploysecret(:server4), user: deploysecret(:user), roles: %w(web app db importer) diff --git a/config/environments/production.rb b/config/environments/production.rb index 941ac300e..5e4698336 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -78,4 +78,6 @@ Rails.application.configure do # Do not dump schema after migrations. config.active_record.dump_schema_after_migration = false + + config.i18n.available_locales = [:es] end diff --git a/config/initializers/delayed_job_config.rb b/config/initializers/delayed_job_config.rb new file mode 100644 index 000000000..07e961c9d --- /dev/null +++ b/config/initializers/delayed_job_config.rb @@ -0,0 +1,13 @@ +if Rails.env.test? || Rails.env.development? + Delayed::Worker.delay_jobs = false +else + Delayed::Worker.delay_jobs = true +end +Delayed::Worker.destroy_failed_jobs = false +Delayed::Worker.sleep_delay = 2 +Delayed::Worker.max_attempts = 3 +Delayed::Worker.max_run_time = 30.seconds +Delayed::Worker.read_ahead = 10 +Delayed::Worker.default_queue_name = 'default' +Delayed::Worker.raise_signal_exceptions = :term +Delayed::Worker.logger = Logger.new(File.join(Rails.root, 'log', 'delayed_job.log')) \ No newline at end of file diff --git a/config/initializers/devise_async.rb b/config/initializers/devise_async.rb new file mode 100644 index 000000000..47b01e7f4 --- /dev/null +++ b/config/initializers/devise_async.rb @@ -0,0 +1,8 @@ +Devise::Async.setup do |config| + if Rails.env.test? || Rails.env.development? + config.enabled = false + else + config.enabled = true + end + config.backend = :delayed_job +end \ No newline at end of file diff --git a/db/migrate/20150903200440_create_delayed_jobs.rb b/db/migrate/20150903200440_create_delayed_jobs.rb new file mode 100644 index 000000000..27fdcf6cc --- /dev/null +++ b/db/migrate/20150903200440_create_delayed_jobs.rb @@ -0,0 +1,22 @@ +class CreateDelayedJobs < ActiveRecord::Migration + def self.up + create_table :delayed_jobs, force: true do |table| + table.integer :priority, default: 0, null: false # Allows some jobs to jump to the front of the queue + table.integer :attempts, default: 0, null: false # Provides for retries, but still fail eventually. + table.text :handler, null: false # YAML-encoded string of the object that will do work + table.text :last_error # reason for last failure (See Note below) + table.datetime :run_at # When to run. Could be Time.zone.now for immediately, or sometime in the future. + table.datetime :locked_at # Set when a client is working on this object + table.datetime :failed_at # Set when all retries have failed (actually, by default, the record is deleted instead) + table.string :locked_by # Who is working on this object (if locked) + table.string :queue # The name of the queue this job is in + table.timestamps null: true + end + + add_index :delayed_jobs, [:priority, :run_at], name: "delayed_jobs_priority" + end + + def self.down + drop_table :delayed_jobs + end +end diff --git a/db/schema.rb b/db/schema.rb index c6c4baf2a..13705eb14 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: 20150903171309) do +ActiveRecord::Schema.define(version: 20150903200440) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -90,8 +90,8 @@ ActiveRecord::Schema.define(version: 20150903171309) do t.integer "author_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false - t.datetime "hidden_at" t.string "visit_id" + t.datetime "hidden_at" t.integer "flags_count", default: 0 t.datetime "ignored_flag_at" t.integer "cached_votes_total", default: 0 @@ -110,6 +110,22 @@ ActiveRecord::Schema.define(version: 20150903171309) do add_index "debates", ["cached_votes_up"], name: "index_debates_on_cached_votes_up", using: :btree add_index "debates", ["hidden_at"], name: "index_debates_on_hidden_at", using: :btree + create_table "delayed_jobs", force: :cascade do |t| + t.integer "priority", default: 0, null: false + t.integer "attempts", default: 0, null: false + t.text "handler", null: false + t.text "last_error" + t.datetime "run_at" + t.datetime "locked_at" + t.datetime "failed_at" + t.string "locked_by" + t.string "queue" + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "delayed_jobs", ["priority", "run_at"], name: "delayed_jobs_priority", using: :btree + create_table "flags", force: :cascade do |t| t.integer "user_id" t.string "flaggable_type" @@ -132,16 +148,6 @@ ActiveRecord::Schema.define(version: 20150903171309) do add_index "identities", ["user_id"], name: "index_identities_on_user_id", using: :btree - create_table "inappropiate_flags", force: :cascade do |t| - t.integer "user_id" - t.string "flaggable_type" - t.integer "flaggable_id" - t.datetime "created_at" - t.datetime "updated_at" - end - - add_index "inappropiate_flags", ["flaggable_type", "flaggable_id"], name: "index_inappropiate_flags_on_flaggable_type_and_flaggable_id", using: :btree - create_table "moderators", force: :cascade do |t| t.integer "user_id" end @@ -211,13 +217,12 @@ ActiveRecord::Schema.define(version: 20150903171309) do t.string "unconfirmed_email" t.boolean "email_on_debate_comment", default: false t.boolean "email_on_comment_reply", default: false + t.string "phone_number", limit: 30 t.string "official_position" t.integer "official_level", default: 0 t.datetime "hidden_at" - t.string "phone_number", limit: 30 - t.string "username" - t.datetime "confirmed_hide_at" t.string "sms_confirmation_code" + t.string "username" t.string "document_number" t.string "document_type" t.datetime "residence_verified_at" @@ -229,6 +234,7 @@ ActiveRecord::Schema.define(version: 20150903171309) do t.string "unconfirmed_phone" t.string "confirmed_phone" t.datetime "letter_requested_at" + t.datetime "confirmed_hide_at" t.string "letter_verification_code" end diff --git a/spec/features/debates_spec.rb b/spec/features/debates_spec.rb index 7ea8ad459..433ce1083 100644 --- a/spec/features/debates_spec.rb +++ b/spec/features/debates_spec.rb @@ -69,6 +69,20 @@ feature 'Debates' do expect(page).to have_content I18n.l(Debate.last.created_at.to_date) end + scenario 'CKEditor is present before & after turbolinks update page', :js do + author = create(:user) + login_as(author) + + visit new_debate_path + + expect(page).to have_css "#cke_debate_description" + + click_link 'Debates' + click_link 'Start a debate' + + expect(page).to have_css "#cke_debate_description" + end + scenario 'Captcha is required for debate creation' do login_as(create(:user)) diff --git a/spec/features/localization_spec.rb b/spec/features/localization_spec.rb index 974753eb3..0066efbbd 100644 --- a/spec/features/localization_spec.rb +++ b/spec/features/localization_spec.rb @@ -32,4 +32,15 @@ feature 'Localization' do expect(page).to_not have_content('Language') expect(page).to have_select('locale-switcher', selected: 'EspaƱol') end + + scenario 'Locale switcher not present if only one locale' do + initial_locales = I18n.available_locales + I18n.available_locales = [:en] + + visit '/' + expect(page).to_not have_content('Language') + expect(page).to_not have_css('div.locale') + + I18n.available_locales = initial_locales + end end