maily_herald 0.0.1 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +10 -4
- data/.rspec +5 -0
- data/Gemfile +1 -12
- data/Gemfile.lock +129 -82
- data/Guardfile +25 -0
- data/LICENSE +10 -0
- data/README.md +346 -0
- data/Rakefile +5 -0
- data/app/controllers/maily_herald/tokens_controller.rb +11 -0
- data/app/helpers/maily_herald/tokens_helper.rb +17 -0
- data/app/mailers/maily_herald/mailer.rb +91 -0
- data/app/models/maily_herald/dispatch.rb +76 -0
- data/app/models/maily_herald/list.rb +99 -0
- data/app/models/maily_herald/log.rb +67 -0
- data/app/models/maily_herald/mailing.rb +139 -7
- data/app/models/maily_herald/one_time_mailing.rb +26 -0
- data/app/models/maily_herald/periodical_mailing.rb +145 -0
- data/app/models/maily_herald/sequence.rb +169 -2
- data/app/models/maily_herald/sequence_mailing.rb +71 -0
- data/app/models/maily_herald/subscription.rb +67 -0
- data/bin/maily_herald +16 -0
- data/config/database.yml +5 -0
- data/config/locales/en.yml +6 -11
- data/config/routes.rb +10 -0
- data/config/spring.rb +1 -0
- data/db/migrate/20150205120443_create_maily_herald_tables.rb +53 -0
- data/db/migrate_legacy/20130711124555_create_maily_herald_tables.rb +67 -0
- data/db/migrate_legacy/20140612101023_create_lists.rb +33 -0
- data/lib/generators/maily_herald/install_generator.rb +3 -3
- data/lib/generators/templates/README +2 -0
- data/lib/generators/templates/maily_herald.rb +1 -0
- data/lib/maily_herald.rb +345 -23
- data/lib/maily_herald/autonaming.rb +34 -0
- data/lib/maily_herald/capistrano.rb +5 -0
- data/lib/maily_herald/capistrano/tasks.cap +67 -0
- data/lib/maily_herald/capistrano/tasks2.rb +20 -0
- data/lib/maily_herald/cli.rb +293 -0
- data/lib/maily_herald/condition_evaluator.rb +82 -0
- data/lib/maily_herald/config.rb +5 -0
- data/lib/maily_herald/context.rb +223 -77
- data/lib/maily_herald/engine.rb +17 -0
- data/lib/maily_herald/logging.rb +90 -0
- data/lib/maily_herald/manager.rb +53 -0
- data/lib/maily_herald/model_extensions.rb +15 -0
- data/lib/maily_herald/template_renderer.rb +16 -0
- data/lib/maily_herald/utils.rb +78 -5
- data/lib/maily_herald/version.rb +1 -1
- data/maily_herald.gemspec +17 -9
- data/spec/controllers/maily_herald/tokens_controller_spec.rb +81 -0
- data/spec/dummy/Guardfile +35 -0
- data/spec/dummy/app/mailers/test_mailer.rb +11 -0
- data/spec/dummy/app/models/product.rb +2 -0
- data/spec/dummy/app/models/user.rb +4 -0
- data/spec/dummy/app/views/test_mailer/sample_mail.text.erb +1 -0
- data/spec/dummy/bin/rails +10 -0
- data/spec/dummy/bin/rake +7 -0
- data/spec/dummy/bin/rspec +7 -0
- data/spec/dummy/bin/spring +18 -0
- data/spec/dummy/config/application.rb +1 -1
- data/spec/dummy/config/environments/development.rb +1 -0
- data/spec/dummy/config/environments/test.rb +1 -0
- data/spec/dummy/config/initializers/maily_herald.rb +103 -0
- data/spec/dummy/config/locales/maily_herald.en.yml +28 -0
- data/spec/dummy/db/migrate/20130723074347_create_users.rb +18 -0
- data/spec/dummy/db/schema.rb +82 -0
- data/spec/factories/products.rb +5 -0
- data/spec/factories/users.rb +11 -0
- data/spec/lib/context_spec.rb +41 -0
- data/spec/lib/maily_herald_spec.rb +32 -0
- data/spec/lib/utils_spec.rb +48 -0
- data/spec/mailers/maily_herald/mailer_spec.rb +38 -0
- data/spec/models/maily_herald/list_spec.rb +64 -0
- data/spec/models/maily_herald/log_spec.rb +36 -0
- data/spec/models/maily_herald/mailing_spec.rb +34 -0
- data/spec/models/maily_herald/one_time_mailing_spec.rb +112 -0
- data/spec/models/maily_herald/periodical_mailing_spec.rb +339 -0
- data/spec/models/maily_herald/sequence_mailing_spec.rb +18 -0
- data/spec/models/maily_herald/sequence_spec.rb +429 -0
- data/spec/models/maily_herald/subscription_spec.rb +32 -0
- data/spec/spec_helper.rb +31 -11
- metadata +199 -54
- data/MIT-LICENSE +0 -20
- data/README.rdoc +0 -3
- data/app/assets/images/maily_herald/.gitkeep +0 -0
- data/app/assets/javascripts/maily_herald/application.js +0 -15
- data/app/assets/stylesheets/maily_herald/application.css +0 -13
- data/app/helpers/maily_herald/application_helper.rb +0 -4
- data/app/helpers/maily_herald_helper.rb +0 -9
- data/app/models/maily_herald/mailing_record.rb +0 -6
- data/app/views/layouts/maily_herald/application.html.erb +0 -14
- data/db/migrate/20130711124555_create_maily_herald_tables.rb +0 -38
- data/lib/maily_herald/worker.rb +0 -15
data/Rakefile
CHANGED
@@ -12,6 +12,8 @@ rescue LoadError
|
|
12
12
|
RDoc::Task = Rake::RDocTask
|
13
13
|
end
|
14
14
|
|
15
|
+
require 'thor'
|
16
|
+
|
15
17
|
RDoc::Task.new(:rdoc) do |rdoc|
|
16
18
|
rdoc.rdoc_dir = 'rdoc'
|
17
19
|
rdoc.title = 'MailyHerald'
|
@@ -20,4 +22,7 @@ RDoc::Task.new(:rdoc) do |rdoc|
|
|
20
22
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
21
23
|
end
|
22
24
|
|
25
|
+
APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
|
26
|
+
load 'rails/tasks/engine.rake'
|
27
|
+
|
23
28
|
Bundler::GemHelper.install_tasks
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module MailyHerald
|
2
|
+
class TokensController < MailyHerald::ApplicationController
|
3
|
+
def get
|
4
|
+
@subscription = MailyHerald::Subscription.find_by_token(params[:token])
|
5
|
+
@subscription.try(:deactivate!)
|
6
|
+
|
7
|
+
redirect_to MailyHerald.token_redirect.try(:call, self, @subscription) || "/",
|
8
|
+
notice: @subscription ? t('maily_herald.subscription.deactivated') : t('maily_herald.subscription.undefined_token')
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module MailyHerald
|
2
|
+
# This helper helps overwriting Maily TokensController and/or views in main app
|
3
|
+
module TokensHelper
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
# Cover *_url and *_path generated methods
|
7
|
+
def method_missing(method, *args, &block)
|
8
|
+
method.to_s.end_with?("_url", "_path") ? main_app.send(method, *args, &block) : (raise NoMethodError)
|
9
|
+
rescue NoMethodError
|
10
|
+
super
|
11
|
+
end
|
12
|
+
|
13
|
+
included do
|
14
|
+
delegate :url_for, to: :main_app
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module MailyHerald
|
2
|
+
class Mailer < ActionMailer::Base
|
3
|
+
attr_reader :entity
|
4
|
+
|
5
|
+
def generic entity, mailing
|
6
|
+
destination = mailing.destination(entity)
|
7
|
+
subject = mailing.render_subject(entity)
|
8
|
+
content = mailing.render_template(entity)
|
9
|
+
|
10
|
+
opts = {
|
11
|
+
to: destination,
|
12
|
+
subject: subject
|
13
|
+
}
|
14
|
+
opts[:from] = mailing.from if mailing.from.present?
|
15
|
+
|
16
|
+
mail(opts) do |format|
|
17
|
+
format.text { render text: content }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class << self
|
22
|
+
#TODO make it instance method so we get access to instance attributes
|
23
|
+
def deliver_mail(mail) #:nodoc:
|
24
|
+
mailing = mail.maily_herald_data[:mailing]
|
25
|
+
entity = mail.maily_herald_data[:entity]
|
26
|
+
|
27
|
+
|
28
|
+
if mailing && entity
|
29
|
+
mailing.deliver_with_mailer_to(entity) do
|
30
|
+
ActiveSupport::Notifications.instrument("deliver.action_mailer") do |payload|
|
31
|
+
self.set_payload_for_mail(payload, mail)
|
32
|
+
yield # Let Mail do the delivery actions
|
33
|
+
end
|
34
|
+
mail
|
35
|
+
end
|
36
|
+
else
|
37
|
+
MailyHerald.logger.log_processing(mailing, entity, mail, prefix: "Delivery outside Maily")
|
38
|
+
|
39
|
+
ActiveSupport::Notifications.instrument("deliver.action_mailer") do |payload|
|
40
|
+
self.set_payload_for_mail(payload, mail)
|
41
|
+
yield # Let Mail do the delivery actions
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def mail(headers = {}, &block)
|
48
|
+
return @_message if @_mail_was_called && headers.blank? && !block
|
49
|
+
|
50
|
+
# Assign instance variables availabe for template
|
51
|
+
@maily_subscription = @_message.maily_herald_data[:subscription]
|
52
|
+
@maily_entity = @_message.maily_herald_data[:entity]
|
53
|
+
@maily_mailing = @_message.maily_herald_data[:mailing]
|
54
|
+
|
55
|
+
super
|
56
|
+
end
|
57
|
+
|
58
|
+
protected
|
59
|
+
|
60
|
+
def process(*args) #:nodoc:
|
61
|
+
class << @_message
|
62
|
+
attr_accessor :maily_herald_data
|
63
|
+
|
64
|
+
def maily_herald_processable?
|
65
|
+
@maily_herald_processable ||= maily_herald_data[:mailing].processable?(maily_herald_data[:entity])
|
66
|
+
end
|
67
|
+
|
68
|
+
def maily_herald_conditions_met?
|
69
|
+
@maily_herald_conditions_met ||= maily_herald_data[:mailing].conditions_met?(maily_herald_data[:entity])
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
mailing = args[0].to_s == "generic" ? args[2] : MailyHerald.dispatch(args[0])
|
74
|
+
entity = args[1]
|
75
|
+
|
76
|
+
@_message.maily_herald_data = {
|
77
|
+
mailing: mailing,
|
78
|
+
entity: entity,
|
79
|
+
subscription: mailing.subscription_for(entity),
|
80
|
+
}
|
81
|
+
|
82
|
+
lookup_context.skip_default_locale!
|
83
|
+
super
|
84
|
+
|
85
|
+
@_message.to = mailing.destination(entity) unless @_message.to
|
86
|
+
@_message.from = mailing.from unless @_message.from
|
87
|
+
|
88
|
+
@_message
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module MailyHerald
|
2
|
+
class Dispatch < ActiveRecord::Base
|
3
|
+
belongs_to :list, class_name: "MailyHerald::List"
|
4
|
+
|
5
|
+
validates :list, presence: true
|
6
|
+
validates :state, presence: true, inclusion: {in: [:enabled, :disabled, :archived]}
|
7
|
+
validate do |dispatch|
|
8
|
+
dispatch.errors.add(:base, "Can't change this dispatch because it is locked.") if dispatch.locked?
|
9
|
+
end
|
10
|
+
before_destroy do |dispatch|
|
11
|
+
if dispatch.locked?
|
12
|
+
dispatch.errors.add(:base, "Can't destroy this dispatch because it is locked.")
|
13
|
+
false
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
delegate :subscription_for, to: :list
|
18
|
+
|
19
|
+
scope :enabled, lambda { where(state: :enabled) }
|
20
|
+
scope :disabled, lambda { where(state: :disabled) }
|
21
|
+
scope :archived, lambda { where(state: :archived) }
|
22
|
+
scope :not_archived, lambda { where("state != (?)", :archived) }
|
23
|
+
|
24
|
+
scope :sequence, lambda { where(type: Sequence) }
|
25
|
+
scope :one_time_mailing, lambda { where(type: OneTimeMailing) }
|
26
|
+
scope :periodical_mailing, lambda { where(type: PeriodicalMailing) }
|
27
|
+
|
28
|
+
def state
|
29
|
+
read_attribute(:state).to_sym
|
30
|
+
end
|
31
|
+
|
32
|
+
def enabled?
|
33
|
+
self.state == :enabled
|
34
|
+
end
|
35
|
+
def disabled?
|
36
|
+
self.state == :disabled
|
37
|
+
end
|
38
|
+
def archived?
|
39
|
+
self.state == :archived
|
40
|
+
end
|
41
|
+
|
42
|
+
def enable!
|
43
|
+
update_attribute(:state, "enabled")
|
44
|
+
end
|
45
|
+
def disable!
|
46
|
+
update_attribute(:state, "disabled")
|
47
|
+
end
|
48
|
+
def archive!
|
49
|
+
update_attribute(:state, "archived")
|
50
|
+
end
|
51
|
+
|
52
|
+
def enable
|
53
|
+
write_attribute(:state, "enabled")
|
54
|
+
end
|
55
|
+
def disable
|
56
|
+
write_attribute(:state, "disabled")
|
57
|
+
end
|
58
|
+
def archive
|
59
|
+
write_attribute(:state, "archived")
|
60
|
+
end
|
61
|
+
|
62
|
+
def list= l
|
63
|
+
l = MailyHerald::List.find_by_name(l.to_s) if l.is_a?(String) || l.is_a?(Symbol)
|
64
|
+
super(l)
|
65
|
+
end
|
66
|
+
|
67
|
+
def processable? entity
|
68
|
+
self.enabled? && (self.override_subscription? || self.list.subscribed?(entity)) && self.list.context.scope.exists?(entity)
|
69
|
+
end
|
70
|
+
|
71
|
+
def locked?
|
72
|
+
MailyHerald.dispatch_locked?(self.name)
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
module MailyHerald
|
2
|
+
class List < ActiveRecord::Base
|
3
|
+
include MailyHerald::Autonaming
|
4
|
+
|
5
|
+
if Rails::VERSION::MAJOR == 3
|
6
|
+
attr_accessible :name, :title, :context_name
|
7
|
+
end
|
8
|
+
|
9
|
+
has_many :dispatches, class_name: "MailyHerald::Dispatch"
|
10
|
+
has_many :subscriptions, class_name: "MailyHerald::Subscription"
|
11
|
+
|
12
|
+
validate do |list|
|
13
|
+
list.errors.add(:base, "Can't change this list because it is locked.") if list.locked?
|
14
|
+
end
|
15
|
+
before_destroy do |list|
|
16
|
+
if list.locked?
|
17
|
+
list.errors.add(:base, "Can't destroy this list because it is locked.")
|
18
|
+
false
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def context
|
23
|
+
@context ||= MailyHerald.context self.context_name
|
24
|
+
end
|
25
|
+
|
26
|
+
def subscribe! entity
|
27
|
+
s = subscription_for(entity)
|
28
|
+
s ? s.activate! : s = create_subscription_for(entity, true)
|
29
|
+
s
|
30
|
+
end
|
31
|
+
|
32
|
+
def unsubscribe! entity
|
33
|
+
s = subscription_for(entity)
|
34
|
+
s ? s.deactivate! : s = create_subscription_for(entity, false)
|
35
|
+
s
|
36
|
+
end
|
37
|
+
|
38
|
+
def subscribed? entity
|
39
|
+
subscription_for(entity).try(:active?)
|
40
|
+
end
|
41
|
+
|
42
|
+
# true if user has inactive subscription or never been subscribed
|
43
|
+
def unsubscribed? entity
|
44
|
+
s = subscription_for(entity)
|
45
|
+
s ? !s.active? : true
|
46
|
+
end
|
47
|
+
|
48
|
+
# true only if user was intentionally unsubscribed
|
49
|
+
def opted_out? entity
|
50
|
+
s = subscription_for(entity)
|
51
|
+
s ? !s.active? : false
|
52
|
+
end
|
53
|
+
|
54
|
+
def subscription_for entity
|
55
|
+
self.subscriptions.for_entity(entity).first
|
56
|
+
end
|
57
|
+
|
58
|
+
def active_subscription_count
|
59
|
+
subscribers.count(:id)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Returns entities within the context's scope with active subscription
|
63
|
+
def subscribers
|
64
|
+
context.scope_with_subscription(self).where("#{Subscription.table_name}.active = (?)", true).where("#{Subscription.table_name}.list_id = (?)", self.id)
|
65
|
+
end
|
66
|
+
|
67
|
+
# Returns entities within the context's scope with inactive subscription
|
68
|
+
def opt_outs
|
69
|
+
context.scope_with_subscription(self).where("#{Subscription.table_name}.active = (?)", false).where("#{Subscription.table_name}.list_id = (?)", self.id)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Returns entities within the context's scope without subscription
|
73
|
+
def potential_subscribers
|
74
|
+
sq = context.scope_with_subscription(self, :outer).where("#{Subscription.table_name}.list_id = (?)", self.id).pluck("#{context.model.table_name}.id")
|
75
|
+
context.scope.where(context.model.arel_table[:id].not_in(sq))
|
76
|
+
end
|
77
|
+
|
78
|
+
def logs
|
79
|
+
#Log.for_mailings(self.dispatches.select("id"))
|
80
|
+
Log.for_mailings(Dispatch.where("sequence_id IN (?) OR list_id = (?)", Sequence.where(list_id: self.id).select("id"), self.id).select("id"))
|
81
|
+
end
|
82
|
+
|
83
|
+
def locked?
|
84
|
+
MailyHerald.list_locked?(self.name)
|
85
|
+
end
|
86
|
+
|
87
|
+
private
|
88
|
+
|
89
|
+
def create_subscription_for entity, active = false
|
90
|
+
s = self.subscriptions.build.tap do |s|
|
91
|
+
s.entity = entity
|
92
|
+
s.active = active
|
93
|
+
end
|
94
|
+
s.save!
|
95
|
+
s
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module MailyHerald
|
2
|
+
class Log < ActiveRecord::Base
|
3
|
+
AVAILABLE_STATUSES = [:scheduled, :delivered, :skipped, :error]
|
4
|
+
|
5
|
+
belongs_to :entity, polymorphic: true
|
6
|
+
belongs_to :mailing, class_name: "MailyHerald::Dispatch", foreign_key: :mailing_id
|
7
|
+
|
8
|
+
validates :entity, presence: true
|
9
|
+
validates :mailing, presence: true
|
10
|
+
validates :status, presence: true, inclusion: {in: AVAILABLE_STATUSES}
|
11
|
+
|
12
|
+
validates :processing_at, presence: true, if: :scheduled?
|
13
|
+
|
14
|
+
scope :ordered, lambda { order("processing_at asc") }
|
15
|
+
scope :for_entity, lambda {|entity| where(entity_id: entity.id, entity_type: entity.class.base_class) }
|
16
|
+
scope :for_mailing, lambda {|mailing| where(mailing_id: mailing.id) }
|
17
|
+
scope :for_mailings, lambda {|mailings| where("mailing_id in (?)", mailings) }
|
18
|
+
scope :delivered, lambda { where(status: :delivered) }
|
19
|
+
scope :skipped, lambda { where(status: :skipped) }
|
20
|
+
scope :error, lambda { where(status: :error) }
|
21
|
+
scope :scheduled, lambda { where(status: :scheduled) }
|
22
|
+
scope :processed, lambda { where(status: [:delivered, :skipped, :error]) }
|
23
|
+
|
24
|
+
serialize :data, Hash
|
25
|
+
|
26
|
+
if Rails::VERSION::MAJOR == 3
|
27
|
+
attr_accessible :status, :data
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.create_for mailing, entity, attributes = {}
|
31
|
+
log = Log.new
|
32
|
+
log.set_attributes_for mailing, entity, attributes
|
33
|
+
log.save!
|
34
|
+
log
|
35
|
+
end
|
36
|
+
|
37
|
+
def set_attributes_for mailing, entity, attributes = {}
|
38
|
+
self.mailing = mailing
|
39
|
+
self.entity = entity
|
40
|
+
self.entity_email = mailing.destination(entity)
|
41
|
+
|
42
|
+
self.processing_at = attributes[:processing_at] || DateTime.now
|
43
|
+
self.status = attributes[:status]
|
44
|
+
self.data = attributes[:data]
|
45
|
+
end
|
46
|
+
|
47
|
+
def status
|
48
|
+
read_attribute(:status).to_sym
|
49
|
+
end
|
50
|
+
|
51
|
+
def delivered?
|
52
|
+
self.status == :delivered
|
53
|
+
end
|
54
|
+
|
55
|
+
def skipped?
|
56
|
+
self.status == :skipped
|
57
|
+
end
|
58
|
+
|
59
|
+
def error?
|
60
|
+
self.status == :error
|
61
|
+
end
|
62
|
+
|
63
|
+
def scheduled?
|
64
|
+
self.status == :scheduled
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -1,12 +1,144 @@
|
|
1
1
|
module MailyHerald
|
2
|
-
class Mailing <
|
3
|
-
|
2
|
+
class Mailing < Dispatch
|
3
|
+
include MailyHerald::TemplateRenderer
|
4
|
+
include MailyHerald::Autonaming
|
4
5
|
|
5
|
-
|
6
|
-
|
6
|
+
if Rails::VERSION::MAJOR == 3
|
7
|
+
attr_accessible :name, :title, :subject, :context_name, :override_subscription,
|
8
|
+
:sequence, :conditions, :mailer_name, :title, :from, :relative_delay, :template, :start_at, :period
|
9
|
+
end
|
7
10
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
+
has_many :logs, class_name: "MailyHerald::Log"
|
12
|
+
|
13
|
+
validates :subject, presence: true, if: :generic_mailer?
|
14
|
+
validates :template, presence: true, if: :generic_mailer?
|
15
|
+
validate :template_syntax
|
16
|
+
validate :validate_conditions
|
17
|
+
|
18
|
+
before_validation do
|
19
|
+
write_attribute(:name, self.title.downcase.gsub(/\W/, "_")) if self.title && (!self.name || self.name.empty?)
|
20
|
+
end
|
21
|
+
|
22
|
+
after_initialize do
|
23
|
+
if self.new_record?
|
24
|
+
self.override_subscription = false
|
25
|
+
self.mailer_name = :generic
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def periodical?
|
30
|
+
self.class == PeriodicalMailing
|
31
|
+
end
|
32
|
+
|
33
|
+
def one_time?
|
34
|
+
self.class == OneTimeMailing
|
35
|
+
end
|
36
|
+
|
37
|
+
def sequence?
|
38
|
+
self.class == SequenceMailing
|
39
|
+
end
|
40
|
+
|
41
|
+
def mailer_name
|
42
|
+
read_attribute(:mailer_name).to_sym
|
43
|
+
end
|
44
|
+
|
45
|
+
def mailer
|
46
|
+
if generic_mailer?
|
47
|
+
MailyHerald::Mailer
|
48
|
+
else
|
49
|
+
self.mailer_name.to_s.constantize
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def has_conditions?
|
54
|
+
self.conditions && !self.conditions.empty?
|
55
|
+
end
|
56
|
+
|
57
|
+
def generic_mailer?
|
58
|
+
self.mailer_name == :generic
|
59
|
+
end
|
60
|
+
|
61
|
+
def conditions_met? entity
|
62
|
+
subscription = self.list.subscription_for(entity)
|
63
|
+
|
64
|
+
if self.list.context.attributes
|
65
|
+
evaluator = Utils::MarkupEvaluator.new(self.list.context.drop_for(entity, subscription))
|
66
|
+
evaluator.evaluate_conditions(self.conditions)
|
67
|
+
else
|
68
|
+
true
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def destination entity
|
73
|
+
self.list.context.destination_for(entity)
|
74
|
+
end
|
75
|
+
|
76
|
+
def render_template entity
|
77
|
+
subscription = self.list.subscription_for(entity)
|
78
|
+
return unless subscription
|
79
|
+
|
80
|
+
drop = self.list.context.drop_for entity, subscription
|
81
|
+
perform_template_rendering drop, self.template
|
82
|
+
end
|
83
|
+
|
84
|
+
def render_subject entity
|
85
|
+
subscription = self.list.subscription_for(entity)
|
86
|
+
return unless subscription
|
87
|
+
|
88
|
+
drop = self.list.context.drop_for entity, subscription
|
89
|
+
perform_template_rendering drop, self.subject
|
90
|
+
end
|
91
|
+
|
92
|
+
def build_mail entity
|
93
|
+
if generic_mailer?
|
94
|
+
Mailer.generic(entity, self)
|
95
|
+
else
|
96
|
+
self.mailer.send(self.name, entity)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def deliver_to entity
|
101
|
+
build_mail(entity).deliver
|
102
|
+
end
|
103
|
+
|
104
|
+
protected
|
105
|
+
|
106
|
+
# Called from Mailer, block required
|
107
|
+
def deliver_with_mailer_to entity
|
108
|
+
unless processable?(entity)
|
109
|
+
MailyHerald.logger.log_processing(self, entity, prefix: "Not processable", level: :debug)
|
110
|
+
return
|
111
|
+
end
|
112
|
+
|
113
|
+
unless conditions_met?(entity)
|
114
|
+
MailyHerald.logger.log_processing(self, entity, prefix: "Conditions not met", level: :debug)
|
115
|
+
return {status: :skipped}
|
116
|
+
end
|
117
|
+
|
118
|
+
mail = yield # Let mailer do his job
|
119
|
+
|
120
|
+
MailyHerald.logger.log_processing(self, entity, mail, prefix: "Processed")
|
121
|
+
|
122
|
+
return {status: :delivered, data: {content: mail.to_s}}
|
123
|
+
rescue StandardError => e
|
124
|
+
MailyHerald.logger.log_processing(self, entity, prefix: "Error", level: :error)
|
125
|
+
return {status: :error, data: {msg: "#{e.to_s}\n\n#{e.backtrace.join("\n")}"}}
|
126
|
+
end
|
127
|
+
|
128
|
+
private
|
129
|
+
|
130
|
+
def template_syntax
|
131
|
+
begin
|
132
|
+
template = Liquid::Template.parse(self.template)
|
133
|
+
rescue StandardError => e
|
134
|
+
errors.add(:template, e.to_s)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def validate_conditions
|
139
|
+
evaluator = Utils::MarkupEvaluator.test_conditions(self.conditions)
|
140
|
+
rescue StandardError => e
|
141
|
+
errors.add(:conditions, e.to_s)
|
142
|
+
end
|
11
143
|
end
|
12
144
|
end
|