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
@@ -0,0 +1,26 @@
|
|
1
|
+
module MailyHerald
|
2
|
+
class OneTimeMailing < Mailing
|
3
|
+
validates :list, presence: true
|
4
|
+
|
5
|
+
# Returns array of Mail::Message
|
6
|
+
def run
|
7
|
+
self.list.subscriptions.collect do |subscription|
|
8
|
+
entity = subscription.entity
|
9
|
+
|
10
|
+
next unless processable?(entity)
|
11
|
+
|
12
|
+
deliver_to entity
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# Returns single Mail::Message
|
17
|
+
def deliver_with_mailer_to entity
|
18
|
+
attrs = super entity
|
19
|
+
Log.create_for(self, entity, attrs) if attrs
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_s
|
23
|
+
"<OneTimeMailing: #{self.title || self.name}>"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,145 @@
|
|
1
|
+
module MailyHerald
|
2
|
+
class PeriodicalMailing < Mailing
|
3
|
+
if Rails::VERSION::MAJOR == 3
|
4
|
+
attr_accessible :period, :period_in_days
|
5
|
+
end
|
6
|
+
|
7
|
+
validates :list, presence: true
|
8
|
+
validates :start_at, presence: true
|
9
|
+
validates :period, presence: true, numericality: {greater_than: 0}
|
10
|
+
|
11
|
+
after_save :update_schedules_callback, if: Proc.new{|m| m.state_changed? || m.period_changed? || m.start_at_changed? || m.override_subscription?}
|
12
|
+
|
13
|
+
def period_in_days
|
14
|
+
"%.2f" % (self.period.to_f / 1.day.seconds)
|
15
|
+
end
|
16
|
+
def period_in_days= d
|
17
|
+
self.period = d.to_f.days
|
18
|
+
end
|
19
|
+
|
20
|
+
def deliver_to entity
|
21
|
+
super(entity)
|
22
|
+
end
|
23
|
+
|
24
|
+
def deliver_with_mailer_to entity
|
25
|
+
current_time = Time.now
|
26
|
+
|
27
|
+
schedule = schedule_for entity
|
28
|
+
|
29
|
+
schedule.with_lock do
|
30
|
+
# make sure schedule hasn't been processed in the meantime
|
31
|
+
if schedule && schedule.processing_at <= current_time && schedule.scheduled?
|
32
|
+
attrs = super(entity)
|
33
|
+
if attrs
|
34
|
+
schedule.attributes = attrs
|
35
|
+
schedule.processing_at = current_time
|
36
|
+
schedule.save!
|
37
|
+
set_schedule_for entity, schedule
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end if schedule
|
41
|
+
end
|
42
|
+
|
43
|
+
def run
|
44
|
+
# TODO better scope here to exclude schedules for users outside context scope
|
45
|
+
schedules.where("processing_at <= (?)", Time.now).each do |schedule|
|
46
|
+
if schedule.entity
|
47
|
+
deliver_to schedule.entity
|
48
|
+
else
|
49
|
+
MailyHerald.logger.log_processing(schedule.mailing, {:class => schedule.entity_type, :id => schedule.entity_id}, prefix: "Removing schedule for non-existing entity")
|
50
|
+
schedule.destroy
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def processed_logs entity
|
56
|
+
Log.ordered.for_entity(entity).for_mailing(self).processed
|
57
|
+
end
|
58
|
+
|
59
|
+
def start_processing_time entity
|
60
|
+
if processed_logs(entity).first
|
61
|
+
processed_logs(entity).first.processed_at
|
62
|
+
else
|
63
|
+
begin
|
64
|
+
Time.parse(self.start_at)
|
65
|
+
rescue
|
66
|
+
subscription = self.list.subscription_for(entity)
|
67
|
+
evaluator = Utils::MarkupEvaluator.new(self.list.context.drop_for(entity, subscription))
|
68
|
+
|
69
|
+
evaluator.evaluate_variable(self.start_at)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def last_processing_time entity
|
75
|
+
processed_logs(entity).last.try(:processing_at)
|
76
|
+
end
|
77
|
+
|
78
|
+
def set_schedule_for entity, last_log = nil
|
79
|
+
# support entity with joined subscription table for better performance
|
80
|
+
if entity.has_attribute?(:maily_subscription_id)
|
81
|
+
subscribed = !!entity.maily_subscription_active
|
82
|
+
else
|
83
|
+
subscribed = self.list.subscribed?(entity)
|
84
|
+
end
|
85
|
+
|
86
|
+
if !self.period || !self.start_at || !enabled? || !(self.override_subscription? || subscribed)
|
87
|
+
log = schedule_for(entity)
|
88
|
+
log.try(:destroy)
|
89
|
+
return
|
90
|
+
end
|
91
|
+
|
92
|
+
log = schedule_for(entity)
|
93
|
+
last_log ||= processed_logs(entity).last
|
94
|
+
|
95
|
+
log ||= Log.new
|
96
|
+
log.with_lock do
|
97
|
+
log.set_attributes_for(self, entity, {
|
98
|
+
status: :scheduled,
|
99
|
+
processing_at: calculate_processing_time(entity, last_log)
|
100
|
+
})
|
101
|
+
log.save!
|
102
|
+
end
|
103
|
+
log
|
104
|
+
end
|
105
|
+
|
106
|
+
def update_schedules
|
107
|
+
self.list.context.scope_with_subscription(self.list, :outer).each do |entity|
|
108
|
+
MailyHerald.logger.debug "Updating schedule of #{self} periodical for entity ##{entity.id} #{entity}"
|
109
|
+
set_schedule_for entity
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def update_schedules_callback
|
114
|
+
Rails.env.test? ? update_schedules : MailyHerald::ScheduleUpdater.perform_in(10.seconds, self.id)
|
115
|
+
end
|
116
|
+
|
117
|
+
def schedule_for entity
|
118
|
+
schedules.for_entity(entity).first
|
119
|
+
end
|
120
|
+
|
121
|
+
def schedules
|
122
|
+
Log.ordered.scheduled.for_mailing(self)
|
123
|
+
end
|
124
|
+
|
125
|
+
def calculate_processing_time entity, last_log = nil
|
126
|
+
last_log ||= processed_logs(entity).last
|
127
|
+
|
128
|
+
if last_log && last_log.processing_at
|
129
|
+
last_log.processing_at + self.period
|
130
|
+
elsif start_processing_time(entity)
|
131
|
+
start_processing_time(entity)
|
132
|
+
else
|
133
|
+
nil
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def next_processing_time entity
|
138
|
+
schedule_for(entity).processing_at
|
139
|
+
end
|
140
|
+
|
141
|
+
def to_s
|
142
|
+
"<PeriodicalMailing: #{self.title || self.name}>"
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
@@ -1,5 +1,172 @@
|
|
1
1
|
module MailyHerald
|
2
|
-
|
3
|
-
|
2
|
+
MailyHerald::Subscription #TODO fix this autoload for dev
|
3
|
+
|
4
|
+
class Sequence < Dispatch
|
5
|
+
if Rails::VERSION::MAJOR == 3
|
6
|
+
attr_accessible :name, :title, :override_subscription,
|
7
|
+
:conditions, :start_at, :period
|
8
|
+
end
|
9
|
+
|
10
|
+
include MailyHerald::Autonaming
|
11
|
+
|
12
|
+
has_many :logs, class_name: "MailyHerald::Log", through: :mailings
|
13
|
+
if Rails::VERSION::MAJOR == 3
|
14
|
+
has_many :mailings, class_name: "MailyHerald::SequenceMailing", order: "absolute_delay ASC", dependent: :destroy
|
15
|
+
else
|
16
|
+
has_many :mailings, -> { order("absolute_delay ASC") }, class_name: "MailyHerald::SequenceMailing", dependent: :destroy
|
17
|
+
end
|
18
|
+
|
19
|
+
validates :list, presence: true
|
20
|
+
|
21
|
+
before_validation do
|
22
|
+
write_attribute(:name, self.title.downcase.gsub(/\W/, "_")) if self.title && (!self.name || self.name.empty?)
|
23
|
+
end
|
24
|
+
|
25
|
+
after_initialize do
|
26
|
+
if self.new_record?
|
27
|
+
self.override_subscription = false
|
28
|
+
end
|
29
|
+
end
|
30
|
+
after_save :update_schedules_callback, if: Proc.new{|s| s.state_changed? || s.start_at_changed?}
|
31
|
+
|
32
|
+
def mailing name, options = {}
|
33
|
+
if SequenceMailing.table_exists?
|
34
|
+
mailing = SequenceMailing.find_by_name(name)
|
35
|
+
lock = options.delete(:locked)
|
36
|
+
|
37
|
+
if block_given? && !MailyHerald.dispatch_locked?(name) && (!mailing || lock)
|
38
|
+
mailing ||= self.mailings.build(name: name)
|
39
|
+
mailing.sequence = self
|
40
|
+
yield(mailing)
|
41
|
+
mailing.skip_updating_schedules = true if self.new_record?
|
42
|
+
mailing.save!
|
43
|
+
|
44
|
+
MailyHerald.lock_dispatch(name) if lock
|
45
|
+
end
|
46
|
+
|
47
|
+
mailing
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def run
|
52
|
+
# TODO better scope here to exclude schedules for users outside context scope
|
53
|
+
schedules.where("processing_at <= (?)", Time.now).each do |schedule|
|
54
|
+
if schedule.entity
|
55
|
+
schedule.mailing.deliver_to schedule.entity
|
56
|
+
else
|
57
|
+
MailyHerald.logger.log_processing(schedule.mailing, {:class => schedule.entity_type, :id => schedule.entity_id}, prefix: "Removing schedule for non-existing entity")
|
58
|
+
schedule.destroy
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def processed_logs entity
|
64
|
+
Log.ordered.processed.for_entity(entity).for_mailings(self.mailings.select(:id))
|
65
|
+
end
|
66
|
+
|
67
|
+
def processed_logs_for entity, mailing
|
68
|
+
Log.ordered.processed.for_entity(entity).for_mailing(self.mailings.find(mailing))
|
69
|
+
end
|
70
|
+
|
71
|
+
def last_processing_time entity
|
72
|
+
ls = processed_logs(entity)
|
73
|
+
ls.last.processing_at if ls.last
|
74
|
+
end
|
75
|
+
|
76
|
+
def pending_mailings entity
|
77
|
+
ls = processed_logs(entity)
|
78
|
+
ls.empty? ? self.mailings.enabled : self.mailings.enabled.where("id not in (?)", ls.map(&:mailing_id))
|
79
|
+
end
|
80
|
+
|
81
|
+
def processed_mailings entity
|
82
|
+
ls = processed_logs(entity)
|
83
|
+
ls.empty? ? self.mailings.where(id: nil) : self.mailings.where("id in (?)", ls.map(&:mailing_id))
|
84
|
+
end
|
85
|
+
|
86
|
+
def last_processed_mailing entity
|
87
|
+
processed_mailings(entity).last
|
88
|
+
end
|
89
|
+
|
90
|
+
def next_mailing entity
|
91
|
+
pending_mailings(entity).first
|
92
|
+
end
|
93
|
+
|
94
|
+
def mailing_processing_log_for entity, mailing
|
95
|
+
Log.ordered.processed.for_entity(entity).for_mailing(mailing).last
|
96
|
+
end
|
97
|
+
|
98
|
+
def set_schedule_for entity
|
99
|
+
# TODO handle override subscription?
|
100
|
+
|
101
|
+
# support entity with joined subscription table for better performance
|
102
|
+
if entity.has_attribute?(:maily_subscription_id)
|
103
|
+
subscribed = !!entity.maily_subscription_active
|
104
|
+
else
|
105
|
+
subscribed = self.list.subscribed?(entity)
|
106
|
+
end
|
107
|
+
|
108
|
+
if !subscribed || !self.start_at || !enabled? || !(mailing = next_mailing(entity))
|
109
|
+
log = schedule_for(entity)
|
110
|
+
log.try(:destroy)
|
111
|
+
return
|
112
|
+
end
|
113
|
+
|
114
|
+
log = schedule_for(entity)
|
115
|
+
log ||= Log.new
|
116
|
+
log.with_lock do
|
117
|
+
log.set_attributes_for(mailing, entity, {
|
118
|
+
status: :scheduled,
|
119
|
+
processing_at: calculate_processing_time_for(entity, mailing)
|
120
|
+
})
|
121
|
+
log.save!
|
122
|
+
end
|
123
|
+
log
|
124
|
+
end
|
125
|
+
|
126
|
+
def update_schedules
|
127
|
+
self.list.context.scope_with_subscription(self.list, :outer).each do |entity|
|
128
|
+
MailyHerald.logger.debug "Updating schedule of #{self} sequence for entity ##{entity.id} #{entity}"
|
129
|
+
set_schedule_for entity
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def update_schedules_callback
|
134
|
+
Rails.env.test? ? update_schedules : MailyHerald::ScheduleUpdater.perform_in(10.seconds, self.id)
|
135
|
+
end
|
136
|
+
|
137
|
+
def schedule_for entity
|
138
|
+
schedules.for_entity(entity).first
|
139
|
+
end
|
140
|
+
|
141
|
+
def schedules
|
142
|
+
Log.ordered.scheduled.for_mailings(self.mailings.select(:id))
|
143
|
+
end
|
144
|
+
|
145
|
+
def calculate_processing_time_for entity, mailing = nil
|
146
|
+
mailing ||= next_mailing(entity)
|
147
|
+
ls = processed_logs(entity)
|
148
|
+
|
149
|
+
if ls.first
|
150
|
+
ls.last.processing_at + (mailing.absolute_delay - ls.last.mailing.absolute_delay)
|
151
|
+
else
|
152
|
+
begin
|
153
|
+
Time.parse(self.start_at) + mailing.absolute_delay
|
154
|
+
rescue
|
155
|
+
subscription = self.list.subscription_for(entity)
|
156
|
+
evaluator = Utils::MarkupEvaluator.new(self.list.context.drop_for(entity, subscription))
|
157
|
+
evaluated_start = evaluator.evaluate_variable(self.start_at)
|
158
|
+
|
159
|
+
evaluated_start + mailing.absolute_delay
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
def next_processing_time entity
|
165
|
+
schedule_for(entity).try(:processing_at)
|
166
|
+
end
|
167
|
+
|
168
|
+
def to_s
|
169
|
+
"<Sequence: #{self.title || self.name}>"
|
170
|
+
end
|
4
171
|
end
|
5
172
|
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module MailyHerald
|
2
|
+
class SequenceMailing < Mailing
|
3
|
+
if Rails::VERSION::MAJOR == 3
|
4
|
+
attr_accessible :absolute_delay_in_days
|
5
|
+
end
|
6
|
+
|
7
|
+
attr_accessor :skip_updating_schedules
|
8
|
+
|
9
|
+
belongs_to :sequence, class_name: "MailyHerald::Sequence"
|
10
|
+
|
11
|
+
validates :absolute_delay,presence: true, numericality: true
|
12
|
+
validates :sequence, presence: true
|
13
|
+
validate do
|
14
|
+
self.errors.add(:list_id, :invalid) if self.list_id != self.sequence.try(:list_id)
|
15
|
+
end
|
16
|
+
|
17
|
+
delegate :subscription, to: :sequence
|
18
|
+
delegate :list, to: :sequence
|
19
|
+
|
20
|
+
before_validation do
|
21
|
+
self.list_id = self.sequence.list_id
|
22
|
+
end
|
23
|
+
|
24
|
+
after_save if: Proc.new{|m| !m.skip_updating_schedules && (m.state_changed? || m.absolute_delay_changed?)} do
|
25
|
+
self.sequence.update_schedules_callback
|
26
|
+
end
|
27
|
+
|
28
|
+
def absolute_delay_in_days
|
29
|
+
"%.2f" % (self.absolute_delay.to_f / 1.day.seconds)
|
30
|
+
end
|
31
|
+
def absolute_delay_in_days= d
|
32
|
+
self.absolute_delay = d.to_f.days
|
33
|
+
end
|
34
|
+
|
35
|
+
def processed_to? entity
|
36
|
+
self.sequence.processed_mailings_for(entity).include?(self)
|
37
|
+
end
|
38
|
+
|
39
|
+
def deliver_to entity
|
40
|
+
super(entity)
|
41
|
+
end
|
42
|
+
|
43
|
+
def deliver_with_mailer_to entity
|
44
|
+
current_time = Time.now
|
45
|
+
|
46
|
+
schedule = self.sequence.schedule_for(entity)
|
47
|
+
|
48
|
+
schedule.with_lock do
|
49
|
+
# make sure schedule hasn't been processed in the meantime
|
50
|
+
if schedule && schedule.mailing == self && schedule.processing_at && schedule.processing_at <= current_time && schedule.scheduled?
|
51
|
+
|
52
|
+
attrs = super entity
|
53
|
+
if attrs
|
54
|
+
schedule.attributes = attrs
|
55
|
+
schedule.processing_at = current_time
|
56
|
+
schedule.save!
|
57
|
+
self.sequence.set_schedule_for(entity)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end if schedule
|
61
|
+
end
|
62
|
+
|
63
|
+
def override_subscription?
|
64
|
+
self.sequence.override_subscription? || super
|
65
|
+
end
|
66
|
+
|
67
|
+
def processable? entity
|
68
|
+
self.sequence.enabled? && super
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module MailyHerald
|
2
|
+
class Subscription < ActiveRecord::Base
|
3
|
+
belongs_to :entity, polymorphic: true
|
4
|
+
belongs_to :list, class_name: "MailyHerald::List"
|
5
|
+
|
6
|
+
validates :entity, presence: true
|
7
|
+
validates :list, presence: true
|
8
|
+
validates :token, presence: true, uniqueness: true
|
9
|
+
validate do
|
10
|
+
self.errors.add(:entity, :wrong_type) if self.entity_type != self.list.context.model.base_class.to_s
|
11
|
+
end
|
12
|
+
|
13
|
+
scope :for_entity, lambda {|entity| where(entity_id: entity.id, entity_type: entity.class.base_class.to_s) }
|
14
|
+
scope :active, lambda { where(active: true) }
|
15
|
+
scope :for_model, lambda {|model| joins("JOIN #{model.table_name} ON #{model.table_name}.id = #{Subscription.table_name}.entity_id AND #{Subscription.table_name}.entity_type = '#{model.base_class.to_s}'") }
|
16
|
+
|
17
|
+
serialize :data, Hash
|
18
|
+
serialize :settings, Hash
|
19
|
+
|
20
|
+
after_initialize do
|
21
|
+
if self.new_record?
|
22
|
+
self.token = MailyHerald::Utils.random_hex(20)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
after_save :update_schedules, if: Proc.new{|s| s.active_changed?}
|
27
|
+
|
28
|
+
def active?
|
29
|
+
!new_record? && read_attribute(:active)
|
30
|
+
end
|
31
|
+
|
32
|
+
def deactivate!
|
33
|
+
update_attribute(:active, false)
|
34
|
+
end
|
35
|
+
|
36
|
+
def activate!
|
37
|
+
update_attribute(:active, true)
|
38
|
+
end
|
39
|
+
|
40
|
+
def toggle!
|
41
|
+
active? ? deactivate! : activate!
|
42
|
+
end
|
43
|
+
|
44
|
+
def token_url
|
45
|
+
MailyHerald::Engine.routes.url_helpers.ubsubscribe_url(self)
|
46
|
+
end
|
47
|
+
|
48
|
+
def to_liquid
|
49
|
+
{
|
50
|
+
"token_url" => token_url
|
51
|
+
}
|
52
|
+
end
|
53
|
+
|
54
|
+
def update_schedules
|
55
|
+
PeriodicalMailing.where(list_id: self.list).each do |m|
|
56
|
+
m.set_schedule_for self.entity
|
57
|
+
end
|
58
|
+
Sequence.where(list_id: self.list).each do |s|
|
59
|
+
s.set_schedule_for self.entity
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def logs
|
64
|
+
self.list.logs.for_entity(self.entity)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|