diff --git a/Gemfile b/Gemfile index e70fc4d..356b938 100644 --- a/Gemfile +++ b/Gemfile @@ -13,7 +13,7 @@ gem 'localeapp' gem 'bbq', :github => 'drugpl/bbq' gem 'paperclip' gem 'whenever', require: false -gem 'resque' +gem 'sidekiq' gem 'sqlite3' @@ -36,6 +36,7 @@ group :development do gem 'awesome_print' gem 'factory_girl_rails', require: false gem 'minitest-rails' + gem 'letter_opener' end group :production do diff --git a/Gemfile.lock b/Gemfile.lock index b8f8ac3..6336967 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -59,6 +59,9 @@ GEM cells (3.8.5) actionpack (~> 3.0) railties (~> 3.0) + celluloid (0.12.4) + facter (>= 1.6.12) + timers (>= 1.0.0) childprocess (0.3.6) ffi (~> 1.0, >= 1.0.6) chronic (0.9.0) @@ -74,6 +77,7 @@ GEM erubis (2.7.0) execjs (1.4.0) multi_json (~> 1.0) + facter (1.6.17) factory_girl (4.1.0) activesupport (>= 3.0.0) factory_girl_rails (4.1.0) @@ -104,6 +108,10 @@ GEM actionpack (>= 3.0.0) activesupport (>= 3.0.0) kgio (2.7.4) + launchy (2.2.0) + addressable (~> 2.3) + letter_opener (1.1.0) + launchy (~> 2.2.0) libwebsocket (0.1.7.1) addressable websocket @@ -164,8 +172,6 @@ GEM rack (1.4.4) rack-cache (1.2) rack (>= 0.4) - rack-protection (1.3.2) - rack rack-ssl (1.3.2) rack rack-test (0.6.2) @@ -192,11 +198,6 @@ GEM redis (3.0.2) redis-namespace (1.2.1) redis (~> 3.0.0) - resque (1.23.0) - multi_json (~> 1.0) - redis-namespace (~> 1.0) - sinatra (>= 0.9.2) - vegas (~> 0.1.2) rest-client (1.6.7) mime-types (>= 1.16) ri_cal (0.8.8) @@ -211,10 +212,12 @@ GEM libwebsocket (~> 0.1.3) multi_json (~> 1.0) rubyzip - sinatra (1.3.3) - rack (~> 1.3, >= 1.3.6) - rack-protection (~> 1.2) - tilt (~> 1.3, >= 1.3.3) + sidekiq (2.7.2) + celluloid (~> 0.12.0) + connection_pool (~> 1.0) + multi_json (~> 1) + redis (~> 3) + redis-namespace sprockets (2.2.2) hike (~> 1.2) multi_json (~> 1.0) @@ -223,6 +226,7 @@ GEM sqlite3 (1.3.6) thor (0.16.0) tilt (1.3.3) + timers (1.1.0) treetop (1.4.12) polyglot polyglot (>= 0.3.1) @@ -234,8 +238,6 @@ GEM kgio (~> 2.6) rack raindrops (~> 0.7) - vegas (0.1.11) - rack (>= 1.0.0) websocket (1.0.6) whenever (0.8.1) activesupport (>= 2.3.4) @@ -261,6 +263,7 @@ DEPENDENCIES haml (~> 3.1) jquery-rails kaminari + letter_opener localeapp minitest-rails neat (~> 1.0.2) @@ -270,9 +273,9 @@ DEPENDENCIES paperclip pg rails (~> 3.2.11) - resque ri_cal sass-rails (~> 3.2.3) + sidekiq sqlite3 uglifier (>= 1.0.3) unicorn diff --git a/app/controllers/participants_messages_controller.rb b/app/controllers/participants_messages_controller.rb index f5586e1..e0cec64 100644 --- a/app/controllers/participants_messages_controller.rb +++ b/app/controllers/participants_messages_controller.rb @@ -10,7 +10,7 @@ def create @message.author = current_user @message.event = @event @message.save! - Resque.enqueue(ParticipantsMessagesWorker, @message.id) + ParticipantsMessagesWorker.perform_async(@message.id) redirect_to admin_events_path, notice: "Message sent!" rescue ActiveRecord::RecordInvalid => invalid @message = invalid.record diff --git a/app/mailers/remainder_mailer.rb b/app/mailers/remainder_mailer.rb new file mode 100644 index 0000000..cd70176 --- /dev/null +++ b/app/mailers/remainder_mailer.rb @@ -0,0 +1,23 @@ +class RemainderMailer < ActionMailer::Base + default from: ENV['CONTACT_EMAIL'] + + def day_before(receiver, event) + @event = event + generate_cat_stuff + + mail to: receiver.email, subject: "#{@event.title} IS COMING" + end + + def today(receiver, event) + @event = event + generate_cat_stuff + + mail to: receiver.email, subject: "#{@event.title} IS COMING" + end + +private + def generate_cat_stuff + @width = 100 + rand(701) + @height = (@width.to_f * 3 / 4).to_i + end +end diff --git a/app/models/person.rb b/app/models/person.rb index b57f5d5..2c42377 100644 --- a/app/models/person.rb +++ b/app/models/person.rb @@ -1,7 +1,8 @@ class Person < ActiveRecord::Base class AlreadySignedException < StandardError; end - attr_accessible :full_name, :irc_nickname, :rss_url, :description + attr_accessible :full_name, :irc_nickname, :rss_url, :description, :remainder_day_before_drug, + :remainder_at_day_of_drug, :remainder_even_if_not_attending has_and_belongs_to_many :presentations, foreign_key: :person_id has_many :participations, dependent: :destroy diff --git a/app/models/presentation.rb b/app/models/presentation.rb index b5cc846..bfa4019 100644 --- a/app/models/presentation.rb +++ b/app/models/presentation.rb @@ -11,7 +11,7 @@ class Presentation < ActiveRecord::Base scope :not_postponed, where("status != 'postponed'") scope :done, where(status: 'done') - delegate :full_name, to: :person, prefix: true + delegate :full_name, to: :lead_speaker, prefix: true delegate :title, to: :event, prefix: true def postpone! diff --git a/app/views/people/edit.html.haml b/app/views/people/edit.html.haml index 5ccb15b..70b9520 100644 --- a/app/views/people/edit.html.haml +++ b/app/views/people/edit.html.haml @@ -18,6 +18,17 @@ .field = f.label :description = f.text_area :description + %h2 + Remainders + .field + = f.label :remainder_day_before_drug + = f.check_box :remainder_day_before_drug + .field + = f.label :remainder_at_day_of_drug + = f.check_box :remainder_at_day_of_drug + .field + = f.label :remainder_even_if_not_attending + = f.check_box :remainder_even_if_not_attending = f.submit diff --git a/app/views/remainder_mailer/day_before.html.erb b/app/views/remainder_mailer/day_before.html.erb new file mode 100644 index 0000000..1379d46 --- /dev/null +++ b/app/views/remainder_mailer/day_before.html.erb @@ -0,0 +1,16 @@ +
+

<%= @event.title %>

+

is coming

+ + Tomorrow, at 19 in <%= @event.venue_name_with_address %>. + We will be talking about:
+ <% @event.presentations.not_postponed.each do |presentation| %> + <%= presentation.title %> (<%= presentation.lead_speaker_full_name %>)
+ <% end %> +
+ After official part, as always, there will be unofficial part with moar beer. +
+
+ And since you are programmer, here is nice cat photo for you:
+ +
\ No newline at end of file diff --git a/app/views/remainder_mailer/day_before.text.erb b/app/views/remainder_mailer/day_before.text.erb new file mode 100644 index 0000000..e0a19ee --- /dev/null +++ b/app/views/remainder_mailer/day_before.text.erb @@ -0,0 +1,10 @@ +There will be <%= @event.title %> tommorow. +Are you ready for that? +Be at 19 in <%= @event.venue_name_with_address %>. + +We will be talking about: +<% @event.presentations.not_postponed.each do |presentation| %> + <%= presentation.title %> (<%= presentation.lead_speaker_full_name %>) +<% end %> + +After official part, as always, there will be unofficial part with moar beer. \ No newline at end of file diff --git a/app/views/remainder_mailer/today.html.erb b/app/views/remainder_mailer/today.html.erb new file mode 100644 index 0000000..3f46566 --- /dev/null +++ b/app/views/remainder_mailer/today.html.erb @@ -0,0 +1,16 @@ +
+

<%= @event.title %>

+

is coming

+ + Today, at 19 in <%= @event.venue_name_with_address %>. + We will be talking about:
+ <% @event.presentations.not_postponed.each do |presentation| %> + <%= presentation.title %> (<%= presentation.lead_speaker_full_name %>)
+ <% end %> +
+ After official part, as always, there will be unofficial part with moar beer. +
+
+ And since you are programmer, here is nice cat photo for you:
+ +
\ No newline at end of file diff --git a/app/views/remainder_mailer/today.text.erb b/app/views/remainder_mailer/today.text.erb new file mode 100644 index 0000000..89a6e44 --- /dev/null +++ b/app/views/remainder_mailer/today.text.erb @@ -0,0 +1,10 @@ +There will be <%= @event.title %> today. +Are you ready for that? +Be at 19 in <%= @event.venue_name_with_address %>. + +We will be talking about: +<% @event.presentations.not_postponed.each do |presentation| %> + <%= presentation.title %> (<%= presentation.lead_speaker_full_name %>) +<% end %> + +After official part, as always, there will be unofficial part with moar beer. \ No newline at end of file diff --git a/app/workers/participants_messages_worker.rb b/app/workers/participants_messages_worker.rb index 7c2c50c..a7dd242 100644 --- a/app/workers/participants_messages_worker.rb +++ b/app/workers/participants_messages_worker.rb @@ -1,7 +1,7 @@ class ParticipantsMessagesWorker - @queue = :mailer + include Sidekiq::Worker - def self.perform(participants_message_id) + def perform(participants_message_id) @message = ParticipantsMessage.find(participants_message_id) @message.event.participants.each do |person| ParticipantsMessageMailer.participants_message(@message, person).deliver! diff --git a/config/environments/development.rb b/config/environments/development.rb index fa9b73b..8241f1f 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -37,4 +37,6 @@ # Local domain config.action_mailer.default_url_options = { :host => "drug.dev" } + + config.action_mailer.delivery_method = :letter_opener end diff --git a/config/schedule.rb b/config/schedule.rb index aa9272e..dcba634 100644 --- a/config/schedule.rb +++ b/config/schedule.rb @@ -9,4 +9,9 @@ every 1.day, at: '5:00 am' do runner 'site=DrugSite.new;site.keep_upcoming_event_alive' +end + +every 1.day, at: '7:00am' do + rake "remainders:day_before" + rake "remainders:at_day_of" end \ No newline at end of file diff --git a/db/migrate/20130211112126_add_notification_preferences_to_people.rb b/db/migrate/20130211112126_add_notification_preferences_to_people.rb new file mode 100644 index 0000000..030094c --- /dev/null +++ b/db/migrate/20130211112126_add_notification_preferences_to_people.rb @@ -0,0 +1,7 @@ +class AddNotificationPreferencesToPeople < ActiveRecord::Migration + def change + add_column :people, :remainder_day_before_drug, :boolean + add_column :people, :remainder_at_day_of_drug, :boolean + add_column :people, :remainder_even_if_not_attending, :boolean + end +end diff --git a/db/schema.rb b/db/schema.rb index 09f6759..2e329eb 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20130126140317) do +ActiveRecord::Schema.define(:version => 20130211112126) do create_table "contacts", :force => true do |t| t.string "name", :null => false @@ -60,18 +60,21 @@ end create_table "people", :force => true do |t| - t.string "email", :default => "" + t.string "email", :default => "" t.datetime "created_at" t.datetime "updated_at" t.string "full_name" t.string "facebook_uid" t.string "github_uid" - t.boolean "publicized", :default => false - t.integer "irc_points", :default => 0 + t.boolean "publicized", :default => false + t.integer "irc_points", :default => 0 t.string "irc_nickname" t.string "github_nickname" t.string "rss_url" t.text "description" + t.boolean "remainder_day_before_drug" + t.boolean "remainder_at_day_of_drug" + t.boolean "remainder_even_if_not_attending" end create_table "people_presentations", :force => true do |t| diff --git a/lib/tasks/resque.rake b/lib/tasks/resque.rake deleted file mode 100644 index b7b6499..0000000 --- a/lib/tasks/resque.rake +++ /dev/null @@ -1 +0,0 @@ -require 'resque/tasks' \ No newline at end of file diff --git a/lib/tasks/whenever.rake b/lib/tasks/whenever.rake new file mode 100644 index 0000000..faf8d23 --- /dev/null +++ b/lib/tasks/whenever.rake @@ -0,0 +1,25 @@ +namespace :remainders do + desc "Send remainders 'day_before' to people." + task :day_before => :environment do + event = Event.closest_upcoming + + if Date.today.tomorrow == event.starting_at.to_date + Person.where(remainder_day_before_drug: true).each do |person| + RemainderMailer.day_before(person, event).deliver! if + person.remainder_even_if_not_attending || person.attend?(event) + end + end + end + + desc "Send remainders 'at_day_of' to people." + task :at_day_of => :environment do + event = Event.closest_upcoming + + if Date.today == event.starting_at.to_date + Person.where(remainder_at_day_of_drug: true).each do |person| + RemainderMailer.today(person, event).deliver! if + person.remainder_even_if_not_attending || person.attend?(event) + end + end + end +end \ No newline at end of file diff --git a/spec/factories/presentations.rb b/spec/factories/presentations.rb index 1cd1e68..633fc65 100644 --- a/spec/factories/presentations.rb +++ b/spec/factories/presentations.rb @@ -3,6 +3,6 @@ FactoryGirl.define do factory :presentation do sequence(:title) { |n| "presentation_title_#{n}" } - association :person + association :speakers end end diff --git a/test/unit/event_test.rb b/test/unit/event_test.rb index f9b002a..7d28ce1 100644 --- a/test/unit/event_test.rb +++ b/test/unit/event_test.rb @@ -1,12 +1,10 @@ require 'minitest_helper' -class TestMeme < MiniTest::Unit::TestCase +class EventTest < MiniTest::Unit::TestCase def setup @event = Event.new end - # I know that these tests are pretty dumb and basic, - # but I use minitest first time, so I wanted to write sth simple. def test_future_if_event_not_happened @event.starting_at = Time.now + 1.month assert @event.future? @@ -17,5 +15,11 @@ def test_future_if_event_happened refute @event.future? end - + def test_closest_upcoming + event1 = FactoryGirl.create(:event, starting_at: (Time.now + 1.month)) + event2 = FactoryGirl.create(:event, starting_at: (Time.now + 2.months)) + closest = Event.closest_upcoming + + assert_equal closest, event1 + end end \ No newline at end of file diff --git a/test/unit/person_test.rb b/test/unit/person_test.rb new file mode 100644 index 0000000..64a99ec --- /dev/null +++ b/test/unit/person_test.rb @@ -0,0 +1,42 @@ +require 'minitest_helper' + +class PersonTest < MiniTest::Unit::TestCase + def setup + @person = Person.create + end + + def test_attend + @event = FactoryGirl.create(:event) + + refute @person.attend?(@event) + + @person.attend!(@event) + refute_empty Participation.where(person_id: @person.id, event_id: @event.id) + + assert @person.attend?(@event) + + assert_raises Person::AlreadySignedException do + @person.attend!(@event) + end + end + + def test_membership + # shoud be unpublicized by default + refute @person.publicized? + + @person.change_membership! + assert @person.publicized? + + @person.change_membership! + refute @person.publicized? + end + + def test_amount_of_presentations + submitted = FactoryGirl.create(:presentation, speakers: [@person], status: 'submitted') + postponed = FactoryGirl.create(:presentation, speakers: [@person], status: 'postponed') + done = FactoryGirl.create(:presentation, speakers: [@person], status: 'done') + + assert_equal @person.amount_of_presentations, 1 + assert_equal @person.karma, Person::PresentationsKarma + end +end \ No newline at end of file diff --git a/test/unit/presentation_test.rb b/test/unit/presentation_test.rb new file mode 100644 index 0000000..4c75316 --- /dev/null +++ b/test/unit/presentation_test.rb @@ -0,0 +1,28 @@ +require 'minitest_helper' + +class PresentationTest < MiniTest::Unit::TestCase + def setup + @presentation = Presentation.create(title: "DRUG fact - It's an anarchy") + end + + def test_postponing + refute @presentation.postponed? + + @presentation.postpone! + assert @presentation.postponed? + + @presentation.cancel_postponement! + assert_equal @presentation.status, 'submitted' + end + + def test_speakers + speaker1 = Person.create + speaker2 = Person.create + + @presentation.speakers << speaker1 + @presentation.speakers << speaker2 + + assert @presentation.speakers.size, 2 + assert_equal @presentation.lead_speaker, speaker1 + end +end \ No newline at end of file