mail_manager 3.0.0 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (204) hide show
  1. checksums.yaml +5 -13
  2. data/.gitignore +5 -0
  3. data/.rspec +1 -0
  4. data/.ruby-version +1 -1
  5. data/Gemfile +27 -10
  6. data/LICENSE.txt +2 -2
  7. data/MIT-LICENSE +1 -1
  8. data/README.md +97 -15
  9. data/{features/bounce_management.feature → app/assets/images/mail_manager/.gitkeep} +0 -0
  10. data/app/assets/images/mail_manager/BottomRight.gif +0 -0
  11. data/app/assets/images/mail_manager/MidRight.gif +0 -0
  12. data/app/assets/images/mail_manager/TopCenter.gif +0 -0
  13. data/app/assets/images/mail_manager/TopRight.gif +0 -0
  14. data/app/assets/images/mail_manager/calendar_date_select/calendar.gif +0 -0
  15. data/app/assets/images/mail_manager/iReach_logo.gif +0 -0
  16. data/app/assets/images/mail_manager/spacer.gif +0 -0
  17. data/app/assets/images/mail_manager/topMid.gif +0 -0
  18. data/app/assets/javascripts/mail_manager/application.js +19 -1
  19. data/app/assets/javascripts/mail_manager/jquery-ui-timepicker-addon.js +2134 -0
  20. data/app/assets/stylesheets/mail_manager/admin.css +261 -0
  21. data/app/assets/stylesheets/mail_manager/application.css +3 -1
  22. data/app/assets/stylesheets/mail_manager/nav.css +68 -0
  23. data/app/assets/stylesheets/mail_manager/timepicker.css +11 -0
  24. data/app/controllers/mail_manager/application_controller.rb +7 -2
  25. data/app/controllers/mail_manager/bounces_controller.rb +5 -10
  26. data/app/controllers/mail_manager/contacts_controller.rb +42 -20
  27. data/app/controllers/mail_manager/mailing_lists_controller.rb +5 -12
  28. data/app/controllers/mail_manager/mailings_controller.rb +18 -18
  29. data/app/controllers/mail_manager/messages_controller.rb +3 -10
  30. data/app/controllers/mail_manager/subscriptions_controller.rb +16 -75
  31. data/app/helpers/mail_manager/layout_helper.rb +43 -0
  32. data/app/models/mail_manager/bounce.rb +16 -5
  33. data/app/models/mail_manager/contact.rb +64 -1
  34. data/app/models/mail_manager/mailable.rb +14 -0
  35. data/app/models/mail_manager/mailer.rb +48 -81
  36. data/app/models/mail_manager/mailing.rb +23 -42
  37. data/app/models/mail_manager/message.rb +52 -8
  38. data/app/models/mail_manager/subscription.rb +9 -3
  39. data/app/models/status_history.rb +3 -2
  40. data/app/views/layouts/mail_manager/application.html.erb +33 -5
  41. data/app/views/layouts/mail_manager/layout.html.erb +15 -0
  42. data/app/views/mail_manager/bounces/index.html.erb +6 -4
  43. data/app/views/mail_manager/bounces/show.html.erb +3 -3
  44. data/app/views/mail_manager/contacts/_form.html.erb +7 -23
  45. data/app/views/mail_manager/contacts/edit.html.erb +3 -3
  46. data/app/views/mail_manager/contacts/index.html.erb +14 -28
  47. data/app/views/mail_manager/contacts/new.html.erb +2 -2
  48. data/app/views/mail_manager/contacts/show.html.erb +5 -5
  49. data/app/views/mail_manager/contacts/subscribe.html.erb +1 -1
  50. data/app/views/mail_manager/mailer/double_opt_in.erb +1 -1
  51. data/app/views/mail_manager/mailer/double_opt_in.html.erb +6 -0
  52. data/app/views/mail_manager/mailer/unsubscribed.erb +1 -1
  53. data/app/views/mail_manager/mailer/unsubscribed.html.erb +1 -1
  54. data/app/views/mail_manager/mailing_lists/_form.html.erb +8 -17
  55. data/app/views/mail_manager/mailing_lists/edit.html.erb +4 -4
  56. data/app/views/mail_manager/mailing_lists/index.html.erb +6 -5
  57. data/app/views/mail_manager/mailing_lists/new.html.erb +3 -3
  58. data/app/views/mail_manager/mailings/_form.html.erb +22 -44
  59. data/app/views/mail_manager/mailings/edit.html.erb +3 -3
  60. data/app/views/mail_manager/mailings/index.html.erb +23 -27
  61. data/app/views/mail_manager/mailings/new.html.erb +2 -2
  62. data/app/views/mail_manager/mailings/test.html.erb +3 -3
  63. data/app/views/mail_manager/messages/index.html.erb +2 -2
  64. data/app/views/mail_manager/subscriptions/_form.html.erb +1 -1
  65. data/app/views/mail_manager/subscriptions/_subscriptions.html.erb +2 -2
  66. data/app/views/mail_manager/subscriptions/edit.html.erb +2 -2
  67. data/app/views/mail_manager/subscriptions/index.html.erb +3 -3
  68. data/app/views/mail_manager/subscriptions/new.html.erb +1 -1
  69. data/app/views/mail_manager/subscriptions/unsubscribe.html.erb +1 -1
  70. data/app/views/mail_manager/subscriptions/unsubscribe_by_email_address.html.erb +3 -3
  71. data/config/locales/en.yml +13 -0
  72. data/config/locales/mailings.en.yml +52 -0
  73. data/config/routes.rb +21 -19
  74. data/db/migrate/008_add_bounces_count_to_mailings.rb +14 -0
  75. data/db/migrate/009_add_messages_count_to_mailings.rb +14 -0
  76. data/db/migrate/010_add_login_token_to_contact.rb +11 -0
  77. data/db/migrate/011_add_deleted_at_to_mailing.rb +11 -0
  78. data/lib/delayed/mailer.rb +9 -5
  79. data/lib/delayed/status.rb +6 -2
  80. data/lib/delayed_overrides/worker.rb +21 -0
  81. data/lib/deleteable.rb +13 -14
  82. data/lib/mail_manager/config.rb +3 -3
  83. data/lib/mail_manager/engine.rb +136 -7
  84. data/lib/mail_manager/lock.rb +1 -0
  85. data/lib/mail_manager/version.rb +1 -1
  86. data/lib/tasks/mail_manager.rake +92 -56
  87. data/mail_manager.gemspec +4 -0
  88. data/spec/rails_helper.rb +50 -0
  89. data/spec/spec_helper.rb +87 -48
  90. data/spec/test_app/.env.development +3 -0
  91. data/spec/test_app/.env.test +2 -0
  92. data/spec/test_app/.rspec +1 -0
  93. data/spec/test_app/Procfile +3 -0
  94. data/spec/test_app/app/controllers/application_controller.rb +4 -0
  95. data/spec/test_app/app/models/ability.rb +7 -0
  96. data/spec/test_app/app/models/user.rb +8 -2
  97. data/spec/test_app/app/models/user_with_role.rb +22 -0
  98. data/spec/test_app/config/database.postgres.yml +21 -0
  99. data/spec/test_app/config/database.sqlite.yml +2 -2
  100. data/spec/test_app/config/environment.rb +2 -2
  101. data/spec/test_app/config/environments/test.rb +13 -0
  102. data/spec/test_app/config/mail_manager.yml +66 -2
  103. data/spec/test_app/config/routes.rb +0 -1
  104. data/spec/test_app/db/migrate/20150420163235_add_bounces_count_to_mailings.rb +14 -0
  105. data/spec/test_app/db/migrate/20150420163804_add_messages_count_to_mailings.rb +14 -0
  106. data/spec/test_app/db/migrate/20150421151457_add_login_token_to_contact.rb +11 -0
  107. data/spec/test_app/db/migrate/20150423143754_add_deleted_at_to_mailing.rb +11 -0
  108. data/spec/test_app/db/schema.rb +10 -5
  109. data/spec/test_app/db/structure.sql +150 -15
  110. data/spec/test_app/features/bounce_management.feature +11 -0
  111. data/spec/test_app/features/contact_management.feature +91 -0
  112. data/{features → spec/test_app/features}/mailable.feature +3 -1
  113. data/spec/test_app/features/mailing_list_management.feature +39 -0
  114. data/spec/test_app/features/mailing_management.feature +60 -0
  115. data/{features → spec/test_app/features}/message.feature +4 -4
  116. data/spec/test_app/features/message_management.feature +22 -0
  117. data/spec/test_app/features/step_definitions/bounce_steps.rb +4 -0
  118. data/spec/test_app/features/step_definitions/contact_steps.rb +63 -0
  119. data/spec/test_app/features/step_definitions/debugging_steps.rb +3 -0
  120. data/spec/test_app/features/step_definitions/email_steps.rb +6 -0
  121. data/spec/test_app/features/step_definitions/job_steps.rb +25 -0
  122. data/spec/test_app/features/step_definitions/login_steps.rb +4 -0
  123. data/spec/test_app/features/step_definitions/mailing_list.rb +17 -0
  124. data/spec/test_app/features/step_definitions/mailing_steps.rb +51 -0
  125. data/spec/test_app/features/step_definitions/subscription_steps.rb +26 -0
  126. data/{features → spec/test_app/features}/step_definitions/webrat_steps.rb +10 -6
  127. data/spec/test_app/features/subscription_management.feature +62 -0
  128. data/spec/test_app/features/support/env.rb +37 -0
  129. data/spec/test_app/features/support/paths.rb +36 -0
  130. data/spec/test_app/lib/debugging.rb +61 -0
  131. data/spec/test_app/lib/post_office_manager.rb +71 -0
  132. data/spec/test_app/public/subscribe.html +40 -0
  133. data/spec/test_app/script/full_suite +50 -0
  134. data/spec/test_app/script/post_office +25 -0
  135. data/spec/test_app/script/rails +20 -0
  136. data/spec/test_app/script/rspec_multi_db +34 -0
  137. data/spec/test_app/spec/controllers/mail_manager/bounces_controller_spec.rb +59 -0
  138. data/spec/test_app/spec/controllers/mail_manager/contacts_controller_spec.rb +178 -0
  139. data/spec/test_app/spec/controllers/mail_manager/mailing_lists_controller_spec.rb +164 -0
  140. data/spec/test_app/spec/controllers/mail_manager/mailings_controller_spec.rb +184 -0
  141. data/spec/test_app/spec/controllers/users_controller_spec.rb +47 -46
  142. data/spec/test_app/spec/factories/_functions.rb +27 -0
  143. data/spec/test_app/spec/factories/contacts.rb +7 -0
  144. data/spec/test_app/spec/factories/mail_manager_bounces.rb +13 -0
  145. data/spec/test_app/spec/factories/mailable.rb +8 -0
  146. data/spec/test_app/spec/factories/mailings.rb +7 -1
  147. data/spec/test_app/spec/factories/message.rb +7 -0
  148. data/spec/test_app/spec/factories/users.rb +19 -7
  149. data/spec/test_app/spec/features/mail_manager/bounce_spec.rb +73 -0
  150. data/spec/test_app/spec/features/mail_manager/double_opt_in_spec.rb +62 -0
  151. data/spec/test_app/spec/features/mail_manager/mailing_spec.rb +46 -0
  152. data/spec/test_app/spec/features/navigation_spec.rb +9 -0
  153. data/spec/test_app/spec/helpers/mail_manager/layout_helper_spec.rb +41 -0
  154. data/spec/test_app/spec/helpers/mail_manager/subscriptions_helper_spec.rb +14 -0
  155. data/spec/test_app/spec/models/delayed/mailer_spec.rb +27 -0
  156. data/spec/test_app/spec/models/delayed/status_job_spec.rb +13 -0
  157. data/spec/test_app/spec/models/delayed/status_spec.rb +37 -0
  158. data/spec/test_app/spec/models/mail_manager/bounce_spec.rb +23 -3
  159. data/spec/test_app/spec/models/mail_manager/engine_spec.rb +79 -0
  160. data/spec/test_app/spec/models/mail_manager/mailable_spec.rb +10 -0
  161. data/spec/test_app/spec/models/mail_manager/mailer_spec.rb +35 -3
  162. data/spec/test_app/spec/models/mail_manager/mailing_list_spec.rb +5 -5
  163. data/spec/test_app/spec/models/mail_manager/mailing_spec.rb +58 -0
  164. data/spec/test_app/spec/models/mail_manager/message_spec.rb +112 -0
  165. data/spec/test_app/spec/models/user_spec.rb +10 -8
  166. data/spec/test_app/spec/rails_helper.rb +86 -0
  167. data/spec/test_app/spec/requests/users_spec.rb +3 -3
  168. data/spec/test_app/spec/routing/mail_manager/bounces_routing_spec.rb +27 -0
  169. data/spec/test_app/spec/routing/mail_manager/contacts_routing_spec.rb +36 -0
  170. data/spec/test_app/spec/routing/mail_manager/mailing_lists_routing_spec.rb +36 -0
  171. data/spec/test_app/spec/routing/mail_manager/mailings_routing_spec.rb +36 -0
  172. data/spec/test_app/spec/spec_helper.rb +82 -32
  173. data/spec/test_app/spec/support/continuance.rb +18 -0
  174. data/spec/test_app/spec/support/custom_matchers.rb +17 -0
  175. data/spec/test_app/spec/support/database_cleaner.rb +10 -1
  176. data/spec/test_app/spec/views/mail_manager/bounces/index.html.erb_spec.rb +32 -0
  177. data/spec/test_app/spec/views/mail_manager/bounces/show.html.erb_spec.rb +12 -0
  178. data/spec/test_app/spec/views/users/edit.html.erb_spec.rb +8 -5
  179. data/spec/test_app/spec/views/users/index.html.erb_spec.rb +10 -19
  180. data/spec/test_app/spec/views/users/new.html.erb_spec.rb +9 -6
  181. data/spec/test_app/spec/views/users/show.html.erb_spec.rb +8 -9
  182. metadata +231 -75
  183. data/.DS_Store +0 -0
  184. data/README.rdoc +0 -3
  185. data/app/.DS_Store +0 -0
  186. data/app/controllers/mail_manager/base_controller.rb +0 -22
  187. data/app/models/.DS_Store +0 -0
  188. data/features/contact_management.feature +0 -24
  189. data/features/mailing_management.feature +0 -78
  190. data/features/step_definitions/email_steps.rb +0 -50
  191. data/features/step_definitions/mlm_steps.rb +0 -11
  192. data/features/step_definitions/pickle_steps.rb +0 -41
  193. data/features/subscription_management.feature +0 -17
  194. data/features/support/env.rb +0 -11
  195. data/features/support/paths.rb +0 -44
  196. data/lib/tasks/mail_manager_tasks.rake +0 -4
  197. data/lib/tasks/rspec.rake +0 -165
  198. data/spec/test_app/bin/cucumber +0 -7
  199. data/spec/test_app/bin/rails +0 -10
  200. data/spec/test_app/bin/rake +0 -7
  201. data/spec/test_app/bin/rspec +0 -7
  202. data/spec/test_app/bin/spring +0 -18
  203. data/spec/test_app/spec/routing/users_routing_spec.rb +0 -35
  204. data/spec/test_app/spec/support/post_office.rb +0 -13
@@ -1,9 +1,9 @@
1
- <% title "New Mailing" %>
1
+ <%= title "New Mailing" %>
2
2
 
3
3
  <%= render :partial => 'form' %>
4
4
 
5
5
  <%= content_for :page_navigation do %>
6
6
  <div>
7
- <%= link_to "Back", mail_manager.mailings_path, :class => 'button' %><div class="linkbuttonEnding"></div>
7
+ <%= link_to "Back", mail_manager.mailings_path, :class => 'button' %>
8
8
  </div>
9
9
  <% end %>
@@ -1,12 +1,12 @@
1
- <% title "Send Test for #{@mailing.subject}" %>
1
+ <%= title "Send Test for #{@mailing.subject}" %>
2
2
  <%= form_tag mail_manager.send_test_mailing_path(@mailing) do %>
3
3
  <table cellpadding="1" cellspacing="0" border="0">
4
4
  <tr valign="top">
5
- <td width="150"><%= label_tag "Test Email Address" %></td>
5
+ <td width="150"><%= label_tag :test_email_addresses, "Test Email Address" %></td>
6
6
  <td><%= text_field_tag "test_email_addresses", @current_user ? @current_user.email : '' %></td>
7
7
  </tr>
8
8
  <tr valign="top">
9
- <td colspan="2" align="right"><%= submit_tag "Send Test Email", :class => 'button' %><div class="buttonEnding"></div></td>
9
+ <td colspan="2" align="right"><%= submit_tag "Send Test Email", :class => 'button' %></td>
10
10
  </tr>
11
11
  </table>
12
12
  <% end %>
@@ -1,4 +1,4 @@
1
- <% title "Listing Messages for #{@mailing.subject} " %>
1
+ <%= title "Listing Messages for #{@mailing.subject}" %>
2
2
 
3
3
  <%= content_for :subnav do %>
4
4
  <ul>
@@ -8,7 +8,7 @@
8
8
 
9
9
  <%= will_paginate @messages %>
10
10
  <%= form_tag mail_manager.mailing_messages_path(@mailing), :id => 'search_form', :method => 'GET' do %>
11
- Status:<%= select_tag "message[status]", options_for_select(@valid_statuses,params[:message][:status]), :onChange => "$('#search_form').submit()" %>
11
+ <%= label_tag :message_status, "Status:" %><%= select_tag "message[status]", options_for_select(@valid_statuses,params[:message][:status]), :onChange => "$('#search_form').submit()" %>
12
12
  <% end %>
13
13
  <% if @messages.length == 0 %>
14
14
  <h3>No messages found for your query.</h3>
@@ -30,7 +30,7 @@ end
30
30
  <% end
31
31
  %>
32
32
  <tr>
33
- <td colspan="2" align="right"><%= f.submit 'Save', :class => 'button' %><div class="buttonEnding"></div>
33
+ <td colspan="2" align="right"><%= f.submit 'Save', :class => 'button' %>
34
34
  <%= f.hidden_field :mailing_list_id %></td>
35
35
  </tr>
36
36
  <% end %>
@@ -2,8 +2,8 @@
2
2
  <%= contactable_form.fields_for :subscriptions do |subscription_fields| %>
3
3
  <% subscription = subscription_fields.object %>
4
4
  <div class="field">
5
- <%= subscription_fields.label :status, subscription.mailing_list.try(:name) %><br/>
6
- <%= subscription_fields.check_box :status, {}, 'active', subscription.status.eql?('active') ? unsubscribed_status : subscription.status %>
5
+ <%= subscription_fields.label :status, subscription.mailing_list.try(:name) %>
6
+ <%= subscription_fields.check_box :status, {}, 'active', subscription.status.eql?('active') ? unsubscribed_status : subscription.status %><br />
7
7
  <%= subscription_fields.hidden_field :mailing_list_id %>
8
8
  </div>
9
9
  <% end %>
@@ -1,8 +1,8 @@
1
- <% title "Editing Subscription for #{@subscription.contact.full_name} " %>
1
+ <%= title "Editing Subscription for #{@subscription.contact.full_name} " %>
2
2
 
3
3
  <%= content_for :subnav do %>
4
4
  <div>
5
- <%= link_to 'Back', mail_manager.mailing_list_subscriptions_path(@mailing_list), :class => 'button' %><div class='linkbuttonEnding'></div>
5
+ <%= link_to 'Back', mail_manager.mailing_list_subscriptions_path(@mailing_list), :class => 'button' %>
6
6
  </div>
7
7
  <% end %>
8
8
 
@@ -1,8 +1,8 @@
1
- <% title "Listing Subsciptions for #{@mailing_list.name} " %>
1
+ <%= title "Listing Subsciptions for #{@mailing_list.name} " %>
2
2
 
3
3
  <%= content_for :page_navigation do %>
4
4
  <div>
5
- <%= link_to 'New Subscription', mail_manager.new_mailing_list_subscription_path(@mailing_list), :class => 'button' %><div class='linkbuttonEnding'></div>
5
+ <%= link_to 'New Subscription', mail_manager.new_mailing_list_subscription_path(@mailing_list), :class => 'button' %>
6
6
  <% end %>
7
7
 
8
8
  <%= form_tag mail_manager.mailing_list_subscriptions_path(@mailing_list), :id => 'search_form', :method => 'GET' do %>
@@ -25,7 +25,7 @@
25
25
 
26
26
  <td class="item"><%=h subscription.contact.full_name %> <%=h subscription.email_address %></td>
27
27
  <td><%=h subscription.contactable.try(:client_company).try(:name) %></td>
28
- <td><%= link_to 'Edit', mail_manager.edit_subscription_path(subscription), :class => 'button' %><div class="linkbuttonEnding"></div></td>
28
+ <td><%= link_to 'Edit', mail_manager.edit_subscription_path(subscription), :class => 'button' %></td>
29
29
  </tr>
30
30
  <% end %>
31
31
  </table>
@@ -1,4 +1,4 @@
1
- <% title "New Subscription for #{@mailing_list.name}" %>
1
+ <%= title "New Subscription for #{@mailing_list.name}" %>
2
2
 
3
3
  <%= content_for :subnav do %>
4
4
  <ul>
@@ -1,2 +1,2 @@
1
1
  <h1>Unsubscribed</h1>
2
- <p>You have successfully unsubscribed '<%= @contact.email_address %>' from '<%= @mailing_lists.join("', '") %>' at <%= link_to site_url, site_url%>. You should receive a message shortly confirming your change in subscription.</p>
2
+ <p>You have successfully unsubscribed '<%= @email_address %>' from '<%= @mailing_lists.join("', '") %>' at <%= link_to site_url, site_url%>. You should receive a message shortly confirming your change in subscription.</p>
@@ -1,5 +1,5 @@
1
- <%= form_tag mail_manager.unsubscribe_by_email_address_path do %>
2
- <% title "Unsubscribe" %>
1
+ <%= form_tag main_app.unsubscribe_by_email_address_path do %>
2
+ <%= title "Unsubscribe" %>
3
3
  <p>Please enter your email address below to unsubscribe from all of our lists.</p>
4
4
  <table cellpadding="0" cellspacing="2" border="0">
5
5
  <tr>
@@ -7,7 +7,7 @@
7
7
  <td><%= text_field_tag :email_address %></td>
8
8
  </tr>
9
9
  <tr>
10
- <td colspan="2" align="right"><%= submit_tag 'Unsubscribe', :class => 'button' %><div class="buttonEnding"></div>
10
+ <td colspan="2" align="right"><%= submit_tag 'Unsubscribe', :class => 'button' %>
11
11
  </tr>
12
12
  <% end %>
13
13
  </table>
@@ -0,0 +1,13 @@
1
+ # Rails Guides: http://guides.rubyonrails.org/i18n.html
2
+ # see (available from page) for some activemodel/support defaults
3
+ # https://github.com/rails/rails/blob/master/activemodel/lib/active_model/locale/en.yml
4
+ # https://github.com/rails/rails/blob/master/activesupport/lib/active_support/locale/en.yml
5
+
6
+ en:
7
+ date:
8
+ formats:
9
+ default: "%b %d, %Y"
10
+ time:
11
+ formats:
12
+ default: "%b %d, %Y %I:%M %P"
13
+
@@ -0,0 +1,52 @@
1
+ en:
2
+ activerecord:
3
+ models:
4
+ mail_manager/mailing:
5
+ one: "Mailing"
6
+ other: "Mailings"
7
+
8
+ attributes:
9
+ mail_manager/mailing:
10
+ subject: "Email subject"
11
+ from_email_address: "From email address"
12
+ scheduled_at: "Send emails at"
13
+ include_images: "Include images?"
14
+
15
+ errors:
16
+ models:
17
+ mail_manager/mailing:
18
+ attributes:
19
+ subject: "Subject"
20
+
21
+ navigation:
22
+ mail_manager/mailing: "Mailings"
23
+
24
+ helpers:
25
+
26
+ submit:
27
+ mail_manager/mailing:
28
+ create: "Add Mailing"
29
+ update: "Update Mailing"
30
+
31
+ button:
32
+ campaign:
33
+
34
+ messages:
35
+ mail_manager/mailing:
36
+ created: "Mailing has been created."
37
+ updated: "Mailing has been updated."
38
+ none: "There are no Mailings yet. Click 'New Mailing' to get started."
39
+
40
+ mail_manager/mailing:
41
+
42
+ links:
43
+ back_to_index: "Back to Mailing"
44
+
45
+ index:
46
+ title: "Listing Mailings"
47
+ new:
48
+ title: "New Mailing"
49
+ edit:
50
+ title: "Edit %{subject}"
51
+ show:
52
+ title: "Mailing"
data/config/routes.rb CHANGED
@@ -3,9 +3,8 @@ MailManager::Engine.routes.draw do
3
3
  member do
4
4
  post :send_test
5
5
  get :test
6
- get :schedule
7
- get :pause
8
- get :cancel
6
+ put :schedule
7
+ put :cancel
9
8
  end
10
9
  resources :messages, only: [:index]
11
10
  end
@@ -17,27 +16,30 @@ MailManager::Engine.routes.draw do
17
16
  end
18
17
  end
19
18
 
20
- resources :mailing_lists do
21
- resources :subscriptions, only: [:index,:new]
22
- end
19
+ resources :mailing_lists
23
20
 
24
21
  resources :contacts do
25
22
  member do
26
- get :send_one_off_message
23
+ delete :delete
24
+ put :undelete
27
25
  end
28
26
  end
29
27
  end
30
-
31
28
  Rails.application.routes.draw do # NOT MyEngineName::Engine.routes.draw
32
- begin
33
- unsubscribe_path = "#{MailManager.site_path}#{MailManager.unsubscribe_path}"
34
- rescue => e
35
- unsubscribe_path = '/listmgr'
36
- end
37
- unsubscribe_path = '/listmgr' if unsubscribe_path.blank?
29
+ unsubscribe_path = (MailManager.unsubscribe_path rescue "/listmgr")
30
+ subscribe_path = (MailManager.subscribe_path rescue "/listmgr/subscribe")
31
+ double_opt_in_path = (MailManager.double_opt_in_path rescue "/listmgr/confirm")
32
+ subscribe_thank_you_path = (MailManager.subscribe_thank_you_path rescue "/listmgr/subscribe_thank_you")
38
33
 
39
- match "#{unsubscribe_path}/:guid", :controller => 'mail_manager/subscriptions',
40
- :action => 'unsubscribe'
41
- match '/unsubscribe_by_email_address' => 'mail_manager/subscriptions#unsubscribe_by_email_address', as: 'unsubscribe_by_email_address'
42
-
43
- end
34
+ post subscribe_path, to: 'mail_manager/contacts#subscribe',
35
+ as: :subscribe
36
+ get subscribe_thank_you_path, to: 'mail_manager/contacts#thank_you',
37
+ as: :subscribe_thank_you
38
+ get "#{double_opt_in_path}/:login_token", to: 'mail_manager/contacts#double_opt_in',
39
+ as: :double_opt_in
40
+ get "#{unsubscribe_path}/:guid", to: 'mail_manager/subscriptions#unsubscribe',
41
+ as: :unsubscribe
42
+ match '/unsubscribe_by_email_address',
43
+ to: 'mail_manager/subscriptions#unsubscribe_by_email_address',
44
+ as: 'unsubscribe_by_email_address'
45
+ end
@@ -0,0 +1,14 @@
1
+ class AddBouncesCountToMailings < ActiveRecord::Migration
2
+ def table_prefix
3
+ MailManager.table_prefix
4
+ rescue
5
+ 'mail_manager_'
6
+ end
7
+ def change
8
+ add_column :"#{table_prefix}mailings", :bounces_count, :integer, default: 0
9
+ MailManager::Mailing.reset_column_information
10
+ MailManager::Mailing.find_each do |m|
11
+ MailManager::Mailing.reset_counters m.id, :bounces
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ class AddMessagesCountToMailings < ActiveRecord::Migration
2
+ def table_prefix
3
+ MailManager.table_prefix
4
+ rescue
5
+ 'mail_manager_'
6
+ end
7
+ def change
8
+ add_column :"#{table_prefix}mailings", :messages_count, :integer, default: 0
9
+ MailManager::Mailing.reset_column_information
10
+ MailManager::Mailing.find_each do |m|
11
+ MailManager::Mailing.reset_counters m.id, :messages
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,11 @@
1
+ class AddLoginTokenToContact < ActiveRecord::Migration
2
+ def table_prefix
3
+ MailManager.table_prefix
4
+ rescue
5
+ 'mail_manager_'
6
+ end
7
+ def change
8
+ add_column :"#{table_prefix}contacts", :login_token, :string
9
+ add_column :"#{table_prefix}contacts", :login_token_created_at, :datetime
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ class AddDeletedAtToMailing < ActiveRecord::Migration
2
+ def table_prefix
3
+ MailManager.table_prefix
4
+ rescue
5
+ 'mail_manager_'
6
+ end
7
+
8
+ def change
9
+ add_column :"#{table_prefix}mailings", :deleted_at, :datetime
10
+ end
11
+ end
@@ -1,8 +1,12 @@
1
1
  class Delayed::Mailer < ActionMailer::Base
2
- def exception_notification(job,error,emails)
3
- recipients emails
4
- from Conf.exception_notification['sender_address']
5
- subject "* [JOB] #{job.name}(#{job.id}) failed on #{`hostname`} in #{Rails.root}"
6
- body "* [JOB] #{job.name}(#{job.id}) failed with #{error.class.name}: #{error.message} - #{job.attempts} failed attempts\n #{error.backtrace.join("\n ")}"
2
+ def exception_notification(job)
3
+ return if MailManager.exception_notification[:to_addresses].blank? ||
4
+ MailManager.exception_notification[:from_address].blank?
5
+ mail(to: MailManager.exception_notification[:to_addresses],
6
+ from: MailManager.exception_notification[:from_address],
7
+ subject: "* [JOB] #{job.name}(#{job.id}) failed on #{`hostname`} in #{Rails.root}",
8
+ body: "* [JOB] #{job.name}(#{job.id}) failed with #{job.last_error} - #{
9
+ job.attempts} failed attempts"
10
+ )
7
11
  end
8
12
  end
@@ -4,9 +4,13 @@ module ::Delayed
4
4
  class Status
5
5
  def self.ok?(overdue=15.minutes)
6
6
  job = ::Delayed::StatusJob.first || ::Delayed::StatusJob.enqueue(::Delayed::StatusJob.new)
7
+ failed_count = Delayed::Job.where('failed_at is not null').count
8
+ raise(::Delayed::StatusException, "There are #{failed_count} failed jobs!"
9
+ ) if failed_count > 0
7
10
  elapsed_time = (Time.now - job.updated_at).to_i
8
- raise(::Delayed::StatusException, "Rails3 Status job has failed at #{job.failed_at} with message: #{job.last_error}") if job.failed?
9
- raise(::Delayed::StatusException, "Rails3 Status job hasn't run for #{elapsed_time} seconds") if elapsed_time > overdue
11
+ raise(::Delayed::StatusException,
12
+ "Rails3 Status job hasn't run for #{elapsed_time} seconds"
13
+ ) if elapsed_time > overdue
10
14
  true
11
15
  end
12
16
  end
@@ -0,0 +1,21 @@
1
+ require 'delayed_job'
2
+ require 'delayed/worker'
3
+ if defined?(Delayed::Worker)
4
+ require File.join(MailManager::PLUGIN_ROOT,'lib','delayed','mailer')
5
+
6
+ class Delayed::Worker
7
+ def failed(job)
8
+ self.class.lifecycle.run_callbacks(:failure, self, job) do
9
+ begin
10
+ job.hook(:failure)
11
+ rescue => error
12
+ say "Error when running failure callback: #{error}", 'error'
13
+ say error.backtrace.join("\n"), 'error'
14
+ ensure
15
+ self.class.destroy_failed_jobs ? job.destroy : job.fail!
16
+ Delayed::Mailer.exception_notification(job).deliver
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
data/lib/deleteable.rb CHANGED
@@ -2,6 +2,9 @@ module Deleteable
2
2
 
3
3
  def self.included(receiver)
4
4
  receiver.extend ClassMethods
5
+ receiver.class_eval do
6
+ default_scope where("deleted_at IS NULL")
7
+ end
5
8
  end
6
9
 
7
10
  def is_deleted?
@@ -17,15 +20,8 @@ module Deleteable
17
20
  end
18
21
 
19
22
  module ClassMethods
20
- def find(*args)
21
- if args[0] == (:exclusive_scope)
22
- args.shift
23
- super
24
- else
25
- with_scope(:find => {:conditions => ["#{table_name}.deleted_at is null"]}) do
26
- super
27
- end
28
- end
23
+ def deleted
24
+ unscoped.where("deleted_at IS NOT NULL")
29
25
  end
30
26
  end
31
27
 
@@ -37,14 +33,17 @@ module DeleteableActions
37
33
  end
38
34
 
39
35
  def destroy
40
- thing = controller_name.singularize.split('_').collect{|string| string.capitalize}.join.constantize.find(params[:id])
36
+ thing = self.class.name.gsub(/s?Controller$/,'').constantize.find(params[:id])
41
37
  thing.delete
42
- redirect_to(eval("#{controller_name}_path(derailed_params)"))
38
+ flash[:info] = "#{thing.class.name.gsub(/^.*::/,'').humanize} successfully deleted."
39
+ redirect_to(action: :index)
43
40
  end
44
41
 
42
+ # :nocov: - not currently supported
45
43
  def undelete
46
- thing = controller_name.singularize.split('_').collect{|string| string.capitalize}.join.constantize.find(:exclusive_scope,params[:id])
44
+ thing = self.class.name.gsub(/s?Controller$/,'').constantize.find(params[:id])
47
45
  thing.undelete
48
- redirect_to(eval("#{controller_name}_path(derailed_params)"))
46
+ redirect_to(action: :index)
49
47
  end
50
- end
48
+ # :nocov:
49
+ end
@@ -41,10 +41,10 @@ class MailManager::Config
41
41
  $stderr.puts "Missing Configuration: either define ::Conf with proper values or create a config/mail_manager.yml with rake mail_manager:default_app_config"
42
42
  end
43
43
  c = ::MailManager::Config.new
44
- c.use_file!("#{Rails.root}/config/mail_manager.yml")
45
- c.use_file!("#{Rails.root}/config/mail_manager.local.yml")
44
+ c.use_file!(standard_file)
45
+ c.use_file!(local_file)
46
46
  c.use_section!(Rails.env)
47
47
  c
48
48
  end
49
49
 
50
- end
50
+ end
@@ -1,9 +1,63 @@
1
1
  module MailManager
2
- mattr_accessor :secret, :site_url, :dont_include_images_domains, :sleep_time_between_messages, :table_prefix,
3
- :default_from_email_address, :bounce, :unsubscribe_path, :site_path, :layout, :use_show_for_resources
2
+ # set up accessors for configuration options from config/mail_manager.yml
3
+ # table_prefix: prefix for database table names to avoid collisions within another app
4
+ mattr_accessor :table_prefix
5
+ # secret: a secret for encrypting tokens and guids
6
+ mattr_accessor :secret
7
+ # site_url: used in various places to get the url of the site (such as in mailings templates)
8
+ mattr_accessor :site_url
9
+ # dont_include_images_domains: a list of domains that won't include images in the email, whether or not the mailing is set to include them
10
+ mattr_accessor :dont_include_images_domains
11
+ # sleep_time_between_messages: a timeout between messages to slow the output of emails to your email server; you should probably limit with your mail server itself if possible
12
+ mattr_accessor :sleep_time_between_messages
13
+ # default_from_email_address: where any public messages from the app default to for the "FROM:" header
14
+ mattr_accessor :default_from_email_address
15
+ # bounce: (a grouping for 'POP' settings for bounce messages and the RETURN_PATH: header)
16
+ # email_address: the account for POPing bounces and RETURN_PATH
17
+ # login: login for account for POPing
18
+ # password: password for account for POPing
19
+ # pop_server: POP server
20
+ # port: PORT of pop server
21
+ # ssl: true/false whether you want to enable ssl for pop
22
+ mattr_accessor :bounce
23
+ # unsubscribe_path: public url for unsubscribing ... this is a prefix and is followed by a message 'guid', defaults to '/listmgr' and routes as '/listmgr/:guid'
24
+ mattr_accessor :unsubscribe_path
25
+ # site_path: used in case your rails site is at a sub-path of your domain
26
+ mattr_accessor :site_path
27
+ # layout: layout used for mail manager administratin pages
28
+ mattr_accessor :layout
29
+ # public_layout: layout used for public facing pages like unsubscribing and opt-in pages
30
+ mattr_accessor :public_layout
31
+ # subscribe_path: public path for double-opt-in 'subscribe' step which sends the email
32
+ mattr_accessor :subscribe_path
33
+ # subscribe_thank_you_path: public path for double-opt-in 'thank you' default path
34
+ mattr_accessor :subscribe_thank_you_path
35
+ # honey_pot_field: used to set a field name which will ignore submissions to the subscribe action if filled
36
+ mattr_accessor :honey_pot_field
37
+ # double_opt_in_path: path to route the double-opt-in confirmation action to
38
+ mattr_accessor :double_opt_in_path
39
+ # signup_email_address: email address for the FROM: of a double opt in/subscribe email
40
+ mattr_accessor :signup_email_address
41
+ # exception_notification: (grouping for who gets notified of exceptions)
42
+ # to_addresses: an array of recipients for exceptions
43
+ # from_address: who the exception appears to be from
44
+ mattr_accessor :exception_notification
45
+ # requires_authentication: whether the mail manager app requires login
46
+ mattr_accessor :requires_authentication
47
+ # authorized_roles: array of role names that can administer the mail manager
48
+ mattr_accessor :authorized_roles
49
+ # roles_method: the method that your "current_user" object defines its role names(returns a list of strings)
50
+ mattr_accessor :roles_method
51
+
52
+ # The following 2 might be deprecated soon
53
+ # show_title: can be used in templates/layouts to see whether you should show a title
54
+ # use_show_for_resources: whether to have links to "show" actions - we don't use them really in this app..
55
+ # and the 'show' actions aren't really currently supported
56
+ mattr_accessor :show_title
57
+ mattr_accessor :use_show_for_resources
4
58
  class Engine < ::Rails::Engine
5
- isolate_namespace MailManager
6
- initializer "MailManager.config" do |app|
59
+ isolate_namespace MailManager
60
+ initializer "MailManager.config" do |app|
7
61
  if File.exist?(File.join(Rails.root,'config','mail_manager.yml'))
8
62
  require 'mail_manager/config'
9
63
  MailManager.initialize_with_config(MailManager::Config.initialize!)
@@ -17,13 +71,69 @@ module MailManager
17
71
  g.fixture_replacement :factory_girl, :dir => 'spec/factories'
18
72
  end
19
73
  end
74
+
75
+ # used to easily know where the mail manager gem files are
20
76
  PLUGIN_ROOT = File.expand_path(File.join(File.dirname(__FILE__),'..','..'))
77
+
78
+ # checks if the given 'user' has a role
79
+ def self.authorized_for_roles?(user,roles=[])
80
+ return true unless roles.present?
81
+ user_roles = if ::MailManager.roles_method.present?
82
+ if user.respond_to? ::MailManager.roles_method
83
+ user.send(::MailManager.roles_method)
84
+ else
85
+ false
86
+ end
87
+ elsif user.respond_to?(:roles)
88
+ user.roles
89
+ elsif user.respond_to?(:role)
90
+ [user.role]
91
+ else
92
+ []
93
+ end
94
+ return false unless user_roles.present?
95
+ user_roles = [user_roles] unless user_roles.is_a?(Array)
96
+ roles.detect{|role| user_roles.map(&:to_sym).map(&:to_s).include?(role.to_s)}.present?
97
+ end
98
+
99
+ # logic for authorization mail manager
100
+ def self.authorized?(user)
101
+ return true unless ::MailManager.requires_authentication
102
+ return false if user.blank?
103
+ return true unless ::MailManager.authorized_roles.present?
104
+ authorized_for_roles?(user, ::MailManager.authorized_roles)
105
+ end
106
+
107
+ # can be used to inject cancan abilities into your application
108
+ def self.abilities
109
+ <<-EOT
110
+ if MailManager.authorized?(user)
111
+ can :manage, [
112
+ MailManager::Mailing,
113
+ MailManager::MailingList,
114
+ MailManager::Contact,
115
+ MailManager::Subscription,
116
+ MailManager::Bounce,
117
+ MailManager::Message
118
+ ]
119
+ end
120
+ EOT
121
+ end
122
+
123
+ # gives the url for a contactable object (such as users or members or whatever
124
+ # you set up for mapping to your contacts
21
125
  def self.edit_route_for(contactable)
22
126
  ContactableRegistry.edit_route_for(contactable.is_a?(String) ? contactable : contactable.class.name)
23
127
  end
128
+
129
+ # easily get a path to the gem's assets
24
130
  def self.assets_path
25
131
  File.join(PLUGIN_ROOT,'assets')
26
132
  end
133
+
134
+ # sets up your MailManager.blah configuration options from
135
+ # config/mail_manager.yml and can override those with
136
+ # config/mail_manager.local.yml for development environments
27
137
  def self.initialize_with_config(conf)
28
138
  MailManager.secret ||= conf.secret rescue nil
29
139
  default_url_options = ActionController::Base.default_url_options
@@ -33,16 +143,33 @@ module MailManager
33
143
  MailManager.sleep_time_between_messages ||= conf.sleep_time_between_messages || 0.3 rescue 0.3
34
144
  MailManager.table_prefix ||= conf.table_prefix || 'mail_manager_' rescue 'mail_manager_'
35
145
  MailManager.default_from_email_address ||= conf.default_from_email_address rescue nil
146
+ MailManager.signup_email_address ||= conf.signup_email_address rescue nil
36
147
  MailManager.bounce ||= conf.bounce || {} rescue {}
37
148
  MailManager.unsubscribe_path ||= conf.unsubscribe_path || "/listmgr" rescue "/listmgr"
149
+ MailManager.subscribe_path ||= conf.subscribe_path || "/listmgr/subscribe" rescue "/listmgr/subscribe"
150
+ MailManager.double_opt_in_path ||= conf.double_opt_in_path || "/listmgr/confirm" rescue "/listmgr/confirm"
151
+ MailManager.honey_pot_field ||= conf.honey_pot_field || "company_name" rescue "company_name"
152
+ MailManager.subscribe_thank_you_path ||= conf.subscribe_thank_you_path || "/listmgr/subscribe_thank_you" rescue "/listmgr/subscribe_thank_you"
38
153
  MailManager.site_path ||= conf.site_path || "/" rescue "/"
39
- MailMatager.layout ||= conf.layout || "application" rescue "application"
40
- MailMatager.use_show_for_resources ||= conf.use_show_for_resources || false rescue false
154
+ MailManager.layout ||= conf.layout || "mail_manager/application" rescue "mail_manager/application"
155
+ MailManager.public_layout ||= conf.public_layout || "mail_manager/application" rescue "mail_manager/application"
156
+ MailManager.use_show_for_resources ||= conf.use_show_for_resources || false rescue false
157
+ MailManager.show_title ||= conf.show_title || true rescue true
158
+ MailManager.requires_authentication ||= conf.requires_authentication || false rescue false
159
+ MailManager.authorized_roles ||= conf.authorized_roles || [] rescue []
160
+ MailManager.roles_method ||= conf.roles_method || nil rescue nil
161
+ MailManager.exception_notification = {}
162
+ MailManager.exception_notification[:to_addresses] ||= conf.exception_notification['to_addresses'] || [] rescue []
163
+ MailManager.exception_notification[:from_address] ||= conf.exception_notification['from_address'] || nil rescue nil
41
164
  end
42
165
  end
166
+
167
+ # load needed libraries for locking and delaying work
43
168
  MailManager::Engine.config.to_prepare do
44
169
  ApplicationController.helper(MailManager::SubscriptionsHelper)
45
- load File.join(MailManager::PLUGIN_ROOT,'lib','mail_manager','lock.rb')
170
+ unless defined? MailManager::Lock
171
+ load File.join(MailManager::PLUGIN_ROOT,'lib','mail_manager','lock.rb')
172
+ end
46
173
  begin
47
174
  require 'delayed_job'
48
175
  defined?(::Delayed::Job) or die "Cannot load Delayed::Job object!"
@@ -50,5 +177,7 @@ MailManager::Engine.config.to_prepare do
50
177
  rescue NameError => e
51
178
  rescue LoadError => le
52
179
  end
180
+ load File.join(MailManager::PLUGIN_ROOT,'lib','delayed_overrides','worker.rb')
53
181
  end
182
+
54
183
  require 'will_paginate'