georgia_mailer 0.1.3 → 0.8.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.
- checksums.yaml +4 -4
- data/MIT-LICENSE +1 -1
- data/README.md +3 -11
- data/app/assets/javascripts/georgia_mailer/components/message_table.js.coffee +32 -26
- data/app/assets/stylesheets/georgia_mailer/application.css.scss +1 -0
- data/app/assets/stylesheets/georgia_mailer/components/_button.scss +4 -0
- data/app/assets/stylesheets/georgia_mailer/{modules → components}/_message.scss +4 -7
- data/app/assets/stylesheets/georgia_mailer/modules/_categories.scss +17 -0
- data/app/assets/stylesheets/georgia_mailer/modules/_messages.scss +7 -0
- data/app/controllers/georgia/mailer/messages_controller.rb +38 -0
- data/app/controllers/georgia/messages_controller.rb +71 -36
- data/app/decorators/georgia/mailer/message_decorator.rb +23 -0
- data/app/helpers/georgia/messages_helper.rb +1 -1
- data/app/mailers/georgia/mailer/notifier.rb +20 -0
- data/app/models/georgia/mailer/message.rb +54 -0
- data/app/policies/georgia/mailer/mailer_policy.rb +52 -0
- data/app/presenters/georgia/mailer/message_actions_presenter.rb +42 -0
- data/app/searches/georgia/mailer/message_search.rb +7 -0
- data/app/services/georgia/mailer/spam_check.rb +19 -0
- data/app/views/georgia/header/_messages.html.erb +1 -1
- data/app/views/georgia/{georgia_mailer → mailer}/messages/_message.html.erb +2 -0
- data/app/views/{georgia_mailer → georgia/mailer}/messages/create.js.erb +0 -0
- data/app/views/{georgia_mailer → georgia/mailer}/notifier/new_message_notification.html.erb +10 -3
- data/app/views/georgia/messages/destroy.js.erb +4 -0
- data/app/views/georgia/messages/ham.js.erb +7 -0
- data/app/views/georgia/messages/search.html.erb +55 -37
- data/app/views/georgia/messages/show.html.erb +8 -8
- data/app/views/georgia/messages/spam.js.erb +7 -0
- data/app/views/public_activity/georgia_mailer_message/_create.html.erb +17 -0
- data/app/workers/georgia/mailer/destroy_all_spam_worker.rb +18 -0
- data/app/workers/georgia/mailer/email_delivery_worker.rb +21 -0
- data/app/workers/georgia/mailer/spam_worker.rb +20 -0
- data/config/routes.rb +3 -3
- data/lib/generators/georgia/mailer/install/install_generator.rb +24 -0
- data/lib/georgia/mailer/engine.rb +12 -0
- data/lib/georgia/mailer/version.rb +5 -0
- data/lib/georgia_mailer.rb +20 -7
- data/lib/tasks/georgia_mailer_tasks.rake +17 -17
- metadata +54 -47
- data/app/controllers/georgia_mailer/messages_controller.rb +0 -35
- data/app/decorators/georgia_mailer/message_decorator.rb +0 -21
- data/app/mailers/georgia_mailer/notifier.rb +0 -18
- data/app/models/georgia_mailer/message.rb +0 -32
- data/app/presenters/georgia_mailer/message_actions_presenter.rb +0 -53
- data/app/services/georgia_mailer/spam_check.rb +0 -17
- data/app/workers/georgia_mailer/email_delivery_worker.rb +0 -19
- data/app/workers/georgia_mailer/spam_worker.rb +0 -18
- data/lib/generators/georgia_mailer/install/install_generator.rb +0 -23
- data/lib/georgia/indexer/extensions/solr_adapter/georgia_mailer/message.rb +0 -44
- data/lib/georgia/indexer/extensions/tire_adapter/georgia_mailer/message.rb +0 -46
- data/lib/georgia_mailer/engine.rb +0 -10
- data/lib/georgia_mailer/version.rb +0 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7f893d6dbc6b8bac397826c8a7dbf28b15423b8e
|
|
4
|
+
data.tar.gz: a76f6eb928d97f65df463684027791dcee62bfe4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 594e8787b0b2350a5390020e488716beb50bb140afeff5ab4364ebae6a49026c512c4ed33209bc65bb6f6b8df5674903bace4f4ed89cbfb768edc492ce31328d
|
|
7
|
+
data.tar.gz: 9e64674780aeaf658e8576ff4bcb71b5eb07dba10bc2bb840bcb1fa7cab964f5968032e13a5fc1fde9ce384ef429bdc61009996f84af96b30401df49fe42771d
|
data/MIT-LICENSE
CHANGED
data/README.md
CHANGED
|
@@ -10,21 +10,13 @@ The install generator will add missing migrations and automatically migrate your
|
|
|
10
10
|
If you selected ElasticSearch as your indexer with Tire, your index will be created.
|
|
11
11
|
Finally, it will mount the engine in your routes.rb file under '/mailer'
|
|
12
12
|
|
|
13
|
-
rails generate
|
|
13
|
+
rails generate georgia:mailer:install
|
|
14
14
|
|
|
15
15
|
### Heroku
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
Generate Georgia::Mailer::Message index:
|
|
18
18
|
|
|
19
|
-
heroku
|
|
20
|
-
|
|
21
|
-
Generate GeorgiaMailer::Message index:
|
|
22
|
-
|
|
23
|
-
heroku run rake environment tire:import CLASS=GeorgiaMailer::Message FORCE=true
|
|
24
|
-
|
|
25
|
-
Add sidekiq to your Procfile:
|
|
26
|
-
|
|
27
|
-
worker: bundle exec sidekiq
|
|
19
|
+
heroku run rake environment georgia:mailer:create_indices
|
|
28
20
|
|
|
29
21
|
### Spam filtering
|
|
30
22
|
|
|
@@ -1,36 +1,49 @@
|
|
|
1
|
-
class @MessagesTable
|
|
2
|
-
|
|
3
|
-
constructor: (element) ->
|
|
4
|
-
|
|
5
|
-
@
|
|
6
|
-
@
|
|
7
|
-
@
|
|
8
|
-
@hamBtn = @element.find('.js-ham')
|
|
1
|
+
class @MessagesTable extends @Table
|
|
2
|
+
|
|
3
|
+
constructor: (element, checkboxable) ->
|
|
4
|
+
super(element, checkboxable)
|
|
5
|
+
@deleteBtn = @element.find('.js-delete')
|
|
6
|
+
@spamBtn = @element.find('.js-spam')
|
|
7
|
+
@hamBtn = @element.find('.js-ham')
|
|
9
8
|
@setBindings()
|
|
10
9
|
|
|
11
10
|
setBindings: () =>
|
|
12
|
-
@checkboxes.on('change', @update)
|
|
13
11
|
@deleteBtn.on('click', @delete)
|
|
14
12
|
@spamBtn.on('click', @spam)
|
|
15
13
|
@hamBtn.on('click', @ham)
|
|
16
14
|
|
|
17
|
-
update: () =>
|
|
18
|
-
if @getChecked().length then @enableActions() else @disableActions()
|
|
19
|
-
|
|
20
15
|
delete: (event) =>
|
|
21
16
|
@stopEvent(event)
|
|
22
17
|
$.ajax(
|
|
23
18
|
url: "/admin/messages/#{@getIds()}"
|
|
24
19
|
type: 'DELETE'
|
|
25
|
-
|
|
20
|
+
dataType: "JSON"
|
|
21
|
+
success: @removeMessages
|
|
22
|
+
).always(@notify)
|
|
26
23
|
|
|
27
|
-
spam: (event)
|
|
24
|
+
spam: (event) =>
|
|
28
25
|
@stopEvent(event)
|
|
29
|
-
|
|
26
|
+
$.ajax(
|
|
27
|
+
type: "POST"
|
|
28
|
+
dataType: "JSON"
|
|
29
|
+
url: "/admin/messages/#{@getIds()}/spam"
|
|
30
|
+
success: @removeMessages
|
|
31
|
+
).always(@notify)
|
|
30
32
|
|
|
31
|
-
ham: (event)
|
|
33
|
+
ham: (event) =>
|
|
32
34
|
@stopEvent(event)
|
|
33
|
-
|
|
35
|
+
$.ajax(
|
|
36
|
+
type: "POST"
|
|
37
|
+
dataType: "JSON"
|
|
38
|
+
url: "/admin/messages/#{@getIds()}/ham"
|
|
39
|
+
success: @removeMessages
|
|
40
|
+
).always(@notify)
|
|
41
|
+
|
|
42
|
+
removeMessages: () =>
|
|
43
|
+
$.each @getIds(), (i, message_id) => @removeMessage(message_id)
|
|
44
|
+
|
|
45
|
+
removeMessage: (message_id) ->
|
|
46
|
+
$("tr#message_#{message_id}").remove();
|
|
34
47
|
|
|
35
48
|
enableActions: () =>
|
|
36
49
|
@spamBtn.removeClass('disabled').addClass('btn-warning')
|
|
@@ -42,17 +55,10 @@ class @MessagesTable
|
|
|
42
55
|
@hamBtn.addClass('disabled').removeClass('btn-warning')
|
|
43
56
|
@deleteBtn.addClass('disabled').removeClass('btn-danger')
|
|
44
57
|
|
|
45
|
-
stopEvent: (event) ->
|
|
46
|
-
event.stopPropagation()
|
|
47
|
-
event.preventDefault()
|
|
48
|
-
|
|
49
|
-
getChecked: () => @element.find("input:checkbox:checked[data-checkbox='child']")
|
|
50
|
-
getId: (c) => $(c).data('id')
|
|
51
|
-
getIds: () => $.map(@getChecked(), (c) => @getId(c))
|
|
52
|
-
|
|
53
58
|
$.fn.actsAsMessagesTable = () ->
|
|
54
59
|
@each ->
|
|
55
|
-
new
|
|
60
|
+
checkboxable = new Checkboxable($(this))
|
|
61
|
+
new MessagesTable($(this), checkboxable)
|
|
56
62
|
|
|
57
63
|
jQuery ->
|
|
58
64
|
$("table.messages.js-checkboxable").each ->
|
|
@@ -25,13 +25,10 @@
|
|
|
25
25
|
border-top: 1px solid #cbcbcb;
|
|
26
26
|
border-bottom: 1px solid #cbcbcb;
|
|
27
27
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
border-right: 3px solid;
|
|
31
|
-
|
|
32
|
-
margin: 0;
|
|
33
|
-
&.spam { border-color: $red; }
|
|
34
|
-
&.clean { border-color: $green; }
|
|
28
|
+
|
|
29
|
+
td.status {
|
|
30
|
+
&.spam { border-right: 3px solid $red; }
|
|
31
|
+
&.clean { border-right: 3px solid $green; }
|
|
35
32
|
}
|
|
36
33
|
|
|
37
34
|
.message-name span {
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
.inbox-categories {
|
|
2
|
+
border-top: 1px solid #ddd;
|
|
3
|
+
margin-top: 52px;
|
|
4
|
+
padding-top: 5px;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.inbox-category-link {
|
|
8
|
+
display: block;
|
|
9
|
+
padding: 5px 5px 5px 10px;
|
|
10
|
+
margin-top: 5px;
|
|
11
|
+
&.active {
|
|
12
|
+
font-weight: bold;
|
|
13
|
+
color: #FFF;
|
|
14
|
+
background-color: #2c3e50;
|
|
15
|
+
&:hover { text-decoration: none; }
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module Georgia
|
|
2
|
+
module Mailer
|
|
3
|
+
class MessagesController < ::ApplicationController
|
|
4
|
+
|
|
5
|
+
def create
|
|
6
|
+
@message = Message.new(message_params)
|
|
7
|
+
if @message.save
|
|
8
|
+
Georgia::CreateActivity.new(@message, :create).call
|
|
9
|
+
EmailDeliveryWorker.new.async.later(60, @message.id)
|
|
10
|
+
SpamWorker.new.async.perform(@message.id)
|
|
11
|
+
respond_to do |format|
|
|
12
|
+
format.html { redirect_to :back, notice: 'Message delivered successfully' }
|
|
13
|
+
format.js { render layout: false }
|
|
14
|
+
end
|
|
15
|
+
else
|
|
16
|
+
respond_to do |format|
|
|
17
|
+
format.html { redirect_to :back, alert: 'Oups. Something went wrong.' }
|
|
18
|
+
format.js { render layout: false }
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
def message_params
|
|
26
|
+
@message_params = {}
|
|
27
|
+
params[:message].each do |key, value|
|
|
28
|
+
@message_params[key] = value.encode('UTF-8', 'binary', invalid: :replace, undef: :replace, replace: '')
|
|
29
|
+
end
|
|
30
|
+
@message_params[:referrer] = request.referrer
|
|
31
|
+
@message_params[:user_ip] = request.remote_ip
|
|
32
|
+
@message_params[:user_agent] = request.user_agent
|
|
33
|
+
@message_params
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -1,63 +1,78 @@
|
|
|
1
1
|
module Georgia
|
|
2
|
-
class MessagesController <
|
|
2
|
+
class MessagesController < Georgia::ApplicationController
|
|
3
3
|
|
|
4
|
-
load_and_authorize_resource class: GeorgiaMailer::Message
|
|
5
|
-
|
|
6
|
-
before_filter :prepare_search, only: [:search, :show, :spam, :ham]
|
|
7
4
|
|
|
5
|
+
def show
|
|
6
|
+
begin
|
|
7
|
+
@message = Georgia::Mailer::Message.find(params[:id]).decorate
|
|
8
|
+
authorize @message
|
|
9
|
+
rescue ActiveRecord::RecordNotFound
|
|
10
|
+
authorize Georgia::Mailer::Message
|
|
11
|
+
redirect_to search_messages_path, alert: 'This message could not be found.'
|
|
12
|
+
end
|
|
13
|
+
end
|
|
8
14
|
|
|
9
15
|
def index
|
|
16
|
+
authorize Georgia::Mailer::Message
|
|
10
17
|
redirect_to georgia.search_messages_path
|
|
11
18
|
end
|
|
12
19
|
|
|
13
20
|
def search
|
|
21
|
+
authorize Georgia::Mailer::Message
|
|
22
|
+
search_definition = Georgia::Mailer::MessageSearch.new(params).definition
|
|
23
|
+
@search = Georgia::Mailer::Message.search(search_definition).page(params[:page])
|
|
24
|
+
@messages = Georgia::Mailer::MessageDecorator.decorate_collection(@search.records)
|
|
14
25
|
end
|
|
15
26
|
|
|
16
|
-
# Destroy multiple assets
|
|
17
27
|
def destroy
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
24
|
-
format.js { render layout: false }
|
|
25
|
-
end
|
|
28
|
+
set_messages
|
|
29
|
+
authorize @messages
|
|
30
|
+
messages_count = @messages.length
|
|
31
|
+
if @messages.destroy_all
|
|
32
|
+
render_success("#{'Message'.pluralize(messages_count)} successfully deleted.")
|
|
26
33
|
else
|
|
27
|
-
|
|
28
|
-
format.html {redirect_to georgia.search_messages_path, alert: 'Oups. Something went wrong.'}
|
|
29
|
-
format.js {head :internal_server_error}
|
|
30
|
-
end
|
|
34
|
+
render_error('Oups. Something went wrong.')
|
|
31
35
|
end
|
|
32
36
|
end
|
|
33
37
|
|
|
34
|
-
def
|
|
35
|
-
|
|
38
|
+
def destroy_all_spam
|
|
39
|
+
authorize Georgia::Mailer::Message
|
|
40
|
+
Georgia::Mailer::DestroyAllSpamWorker.new.async.perform
|
|
41
|
+
redirect_to search_messages_path(s: true), notice: 'Busy purging all spam messages.'
|
|
36
42
|
end
|
|
37
43
|
|
|
38
44
|
def spam
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
+
set_messages
|
|
46
|
+
authorize @messages
|
|
47
|
+
begin
|
|
48
|
+
if !@messages.map(&:report_spam).include?(false)
|
|
49
|
+
render_success("#{'Message'.pluralize(@messages.length)} successfully reported as spam.")
|
|
50
|
+
else
|
|
51
|
+
render_error('Oups. Something went wrong.')
|
|
52
|
+
end
|
|
53
|
+
rescue Rakismet::Undefined => ex
|
|
54
|
+
render_error(ex.message)
|
|
45
55
|
end
|
|
46
56
|
end
|
|
47
57
|
|
|
48
58
|
def ham
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
59
|
+
set_messages
|
|
60
|
+
authorize @messages
|
|
61
|
+
begin
|
|
62
|
+
if !@messages.map(&:move_to_inbox).include?(false)
|
|
63
|
+
render_success("#{'Message'.pluralize(@messages.length)} successfully moved to your inbox.")
|
|
64
|
+
else
|
|
65
|
+
render_error('Oups. Something went wrong.')
|
|
66
|
+
end
|
|
67
|
+
rescue => ex
|
|
68
|
+
render_error(ex.message)
|
|
55
69
|
end
|
|
56
70
|
end
|
|
57
71
|
|
|
58
72
|
def resend_notification
|
|
59
|
-
@message =
|
|
60
|
-
|
|
73
|
+
@message = Georgia::Mailer::Message.find(params[:id])
|
|
74
|
+
authorize @message
|
|
75
|
+
if Georgia::Mailer::Notifier.new_message_notification(@message).deliver
|
|
61
76
|
redirect_to :back, notice: 'Notification successfully sent.'
|
|
62
77
|
else
|
|
63
78
|
redirect_to :back, alert: 'Oups. Something went wrong. Message could not be delivered.'
|
|
@@ -66,9 +81,29 @@ module Georgia
|
|
|
66
81
|
|
|
67
82
|
private
|
|
68
83
|
|
|
69
|
-
def
|
|
70
|
-
|
|
71
|
-
@messages =
|
|
84
|
+
def set_messages
|
|
85
|
+
ids = params[:id].split(',')
|
|
86
|
+
@messages = Georgia::Mailer::Message.where(id: ids)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def render_success success_message
|
|
90
|
+
@status_message = success_message
|
|
91
|
+
@status = :notice
|
|
92
|
+
respond_to do |format|
|
|
93
|
+
format.html { redirect_to :back, notice: @status_message }
|
|
94
|
+
format.js { render layout: false }
|
|
95
|
+
format.json { render json: { ids: @messages.map(&:id), message: @status_message, status: @status } }
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def render_error error_message
|
|
100
|
+
@status_message = error_message
|
|
101
|
+
@status = :alert
|
|
102
|
+
respond_to do |format|
|
|
103
|
+
format.html { redirect_to :back, alert: @status_message }
|
|
104
|
+
format.js { render layout: false }
|
|
105
|
+
format.json { render json: { message: @status_message, status: @status } }
|
|
106
|
+
end
|
|
72
107
|
end
|
|
73
108
|
|
|
74
109
|
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module Georgia
|
|
2
|
+
module Mailer
|
|
3
|
+
class MessageDecorator < ::Georgia::ApplicationDecorator
|
|
4
|
+
|
|
5
|
+
def phone_or_none
|
|
6
|
+
phone.present? ? phone : h.content_tag(:span, 'no phone', class: 'muted')
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def subject_truncated
|
|
10
|
+
h.truncate(h.strip_tags(subject), length: 60, separator: ' ').html_safe if subject.present?
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def message_truncated
|
|
14
|
+
h.truncate(h.strip_tags(message), length: 200, separator: ' ').html_safe if message.present?
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def name_or_anonymous
|
|
18
|
+
name || 'Anonymous'
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module Georgia
|
|
2
|
+
module Mailer
|
|
3
|
+
class Notifier < ActionMailer::Base
|
|
4
|
+
|
|
5
|
+
def new_message_notification(message)
|
|
6
|
+
@message = MessageDecorator.decorate(message)
|
|
7
|
+
emails_to = Georgia::User.where(receives_notifications: true).map(&:email)
|
|
8
|
+
unless emails_to.empty?
|
|
9
|
+
mail(
|
|
10
|
+
from: "noreply@georgiacms.org",
|
|
11
|
+
to: "noreply@georgiacms.org",
|
|
12
|
+
bcc: emails_to,
|
|
13
|
+
subject: "New message from #{Georgia.title}"
|
|
14
|
+
)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
module Georgia
|
|
2
|
+
module Mailer
|
|
3
|
+
class Message < ActiveRecord::Base
|
|
4
|
+
|
|
5
|
+
include Elasticsearch::Model
|
|
6
|
+
include Elasticsearch::Model::Callbacks
|
|
7
|
+
|
|
8
|
+
include PublicActivity::Common
|
|
9
|
+
|
|
10
|
+
delegate :url, :current_path, :size, :content_type, :filename, to: :attachment
|
|
11
|
+
|
|
12
|
+
validates :name, presence: true
|
|
13
|
+
validates :email, format: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i
|
|
14
|
+
validates :message, presence: true
|
|
15
|
+
|
|
16
|
+
mount_uploader :attachment, Ckeditor::AttachmentFileUploader
|
|
17
|
+
|
|
18
|
+
# Anti Spam: check https://github.com/joshfrench/rakismet for more details
|
|
19
|
+
include Rakismet::Model
|
|
20
|
+
rakismet_attrs author: :name, author_email: :email, content: :message, comment_type: 'message'
|
|
21
|
+
# attr_accessible :user_ip, :user_agent, :referrer, :spam, :verified_at
|
|
22
|
+
attr_accessor :permalink, :author_url
|
|
23
|
+
|
|
24
|
+
scope :spam, -> { where(spam: true) }
|
|
25
|
+
scope :ham, -> { where(spam: false) }
|
|
26
|
+
scope :latest, -> { order("created_at DESC") }
|
|
27
|
+
|
|
28
|
+
def status
|
|
29
|
+
@status ||= spam ? 'spam' : 'clean'
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def report_spam
|
|
33
|
+
if self.spam!
|
|
34
|
+
self.update_attribute(:spam, true)
|
|
35
|
+
else
|
|
36
|
+
false
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def move_to_inbox
|
|
41
|
+
if !self.ham!
|
|
42
|
+
self.update_attribute(:spam, false)
|
|
43
|
+
else
|
|
44
|
+
false
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def self.policy_class
|
|
49
|
+
Georgia::Mailer::MailerPolicy
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|