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.
Files changed (93) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +10 -4
  3. data/.rspec +5 -0
  4. data/Gemfile +1 -12
  5. data/Gemfile.lock +129 -82
  6. data/Guardfile +25 -0
  7. data/LICENSE +10 -0
  8. data/README.md +346 -0
  9. data/Rakefile +5 -0
  10. data/app/controllers/maily_herald/tokens_controller.rb +11 -0
  11. data/app/helpers/maily_herald/tokens_helper.rb +17 -0
  12. data/app/mailers/maily_herald/mailer.rb +91 -0
  13. data/app/models/maily_herald/dispatch.rb +76 -0
  14. data/app/models/maily_herald/list.rb +99 -0
  15. data/app/models/maily_herald/log.rb +67 -0
  16. data/app/models/maily_herald/mailing.rb +139 -7
  17. data/app/models/maily_herald/one_time_mailing.rb +26 -0
  18. data/app/models/maily_herald/periodical_mailing.rb +145 -0
  19. data/app/models/maily_herald/sequence.rb +169 -2
  20. data/app/models/maily_herald/sequence_mailing.rb +71 -0
  21. data/app/models/maily_herald/subscription.rb +67 -0
  22. data/bin/maily_herald +16 -0
  23. data/config/database.yml +5 -0
  24. data/config/locales/en.yml +6 -11
  25. data/config/routes.rb +10 -0
  26. data/config/spring.rb +1 -0
  27. data/db/migrate/20150205120443_create_maily_herald_tables.rb +53 -0
  28. data/db/migrate_legacy/20130711124555_create_maily_herald_tables.rb +67 -0
  29. data/db/migrate_legacy/20140612101023_create_lists.rb +33 -0
  30. data/lib/generators/maily_herald/install_generator.rb +3 -3
  31. data/lib/generators/templates/README +2 -0
  32. data/lib/generators/templates/maily_herald.rb +1 -0
  33. data/lib/maily_herald.rb +345 -23
  34. data/lib/maily_herald/autonaming.rb +34 -0
  35. data/lib/maily_herald/capistrano.rb +5 -0
  36. data/lib/maily_herald/capistrano/tasks.cap +67 -0
  37. data/lib/maily_herald/capistrano/tasks2.rb +20 -0
  38. data/lib/maily_herald/cli.rb +293 -0
  39. data/lib/maily_herald/condition_evaluator.rb +82 -0
  40. data/lib/maily_herald/config.rb +5 -0
  41. data/lib/maily_herald/context.rb +223 -77
  42. data/lib/maily_herald/engine.rb +17 -0
  43. data/lib/maily_herald/logging.rb +90 -0
  44. data/lib/maily_herald/manager.rb +53 -0
  45. data/lib/maily_herald/model_extensions.rb +15 -0
  46. data/lib/maily_herald/template_renderer.rb +16 -0
  47. data/lib/maily_herald/utils.rb +78 -5
  48. data/lib/maily_herald/version.rb +1 -1
  49. data/maily_herald.gemspec +17 -9
  50. data/spec/controllers/maily_herald/tokens_controller_spec.rb +81 -0
  51. data/spec/dummy/Guardfile +35 -0
  52. data/spec/dummy/app/mailers/test_mailer.rb +11 -0
  53. data/spec/dummy/app/models/product.rb +2 -0
  54. data/spec/dummy/app/models/user.rb +4 -0
  55. data/spec/dummy/app/views/test_mailer/sample_mail.text.erb +1 -0
  56. data/spec/dummy/bin/rails +10 -0
  57. data/spec/dummy/bin/rake +7 -0
  58. data/spec/dummy/bin/rspec +7 -0
  59. data/spec/dummy/bin/spring +18 -0
  60. data/spec/dummy/config/application.rb +1 -1
  61. data/spec/dummy/config/environments/development.rb +1 -0
  62. data/spec/dummy/config/environments/test.rb +1 -0
  63. data/spec/dummy/config/initializers/maily_herald.rb +103 -0
  64. data/spec/dummy/config/locales/maily_herald.en.yml +28 -0
  65. data/spec/dummy/db/migrate/20130723074347_create_users.rb +18 -0
  66. data/spec/dummy/db/schema.rb +82 -0
  67. data/spec/factories/products.rb +5 -0
  68. data/spec/factories/users.rb +11 -0
  69. data/spec/lib/context_spec.rb +41 -0
  70. data/spec/lib/maily_herald_spec.rb +32 -0
  71. data/spec/lib/utils_spec.rb +48 -0
  72. data/spec/mailers/maily_herald/mailer_spec.rb +38 -0
  73. data/spec/models/maily_herald/list_spec.rb +64 -0
  74. data/spec/models/maily_herald/log_spec.rb +36 -0
  75. data/spec/models/maily_herald/mailing_spec.rb +34 -0
  76. data/spec/models/maily_herald/one_time_mailing_spec.rb +112 -0
  77. data/spec/models/maily_herald/periodical_mailing_spec.rb +339 -0
  78. data/spec/models/maily_herald/sequence_mailing_spec.rb +18 -0
  79. data/spec/models/maily_herald/sequence_spec.rb +429 -0
  80. data/spec/models/maily_herald/subscription_spec.rb +32 -0
  81. data/spec/spec_helper.rb +31 -11
  82. metadata +199 -54
  83. data/MIT-LICENSE +0 -20
  84. data/README.rdoc +0 -3
  85. data/app/assets/images/maily_herald/.gitkeep +0 -0
  86. data/app/assets/javascripts/maily_herald/application.js +0 -15
  87. data/app/assets/stylesheets/maily_herald/application.css +0 -13
  88. data/app/helpers/maily_herald/application_helper.rb +0 -4
  89. data/app/helpers/maily_herald_helper.rb +0 -9
  90. data/app/models/maily_herald/mailing_record.rb +0 -6
  91. data/app/views/layouts/maily_herald/application.html.erb +0 -14
  92. data/db/migrate/20130711124555_create_maily_herald_tables.rb +0 -38
  93. data/lib/maily_herald/worker.rb +0 -15
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'maily_herald'
5
+ require 'maily_herald/cli'
6
+
7
+ begin
8
+ cli = MailyHerald::CLI.instance
9
+ cli.parse
10
+ cli.paperboy
11
+ rescue => e
12
+ raise e if $DEBUG
13
+ STDERR.puts e.message
14
+ STDERR.puts e.backtrace.join("\n")
15
+ exit 1
16
+ end
@@ -0,0 +1,5 @@
1
+ test:
2
+ adapter: sqlite3
3
+ database: db/test.sqlite3
4
+ pool: 5
5
+ timeout: 5000
@@ -1,13 +1,8 @@
1
1
  en:
2
2
  activerecord:
3
- attributes:
4
- mailing:
5
- name: Name
6
- context: Context
7
- sequence: Sequence
8
- conditions: Conditions
9
- title: Title
10
- sender: Sender
11
- delay: Delay
12
- token: Token
13
- template: Template
3
+ errors:
4
+ models:
5
+ maily_herald/subscription:
6
+ attributes:
7
+ entity:
8
+ wrong_type: is different type than defined in context
@@ -1,2 +1,12 @@
1
1
  MailyHerald::Engine.routes.draw do
2
+ get ":token", to: "tokens#get", as: :token
3
+ end
4
+
5
+ MailyHerald::Engine.routes.url_helpers.class.module_eval do
6
+ def unsubscribe_url(subscription, *args)
7
+ options = args.extract_options! || {}
8
+ options = options.reverse_merge(controller: "/maily_herald/tokens", action: "get", token: subscription.token)
9
+
10
+ MailyHerald::Engine.routes.url_helpers.url_for(options)
11
+ end
2
12
  end
@@ -0,0 +1 @@
1
+ Spring.application_root = "./spec/dummy"
@@ -0,0 +1,53 @@
1
+ class CreateMailyHeraldTables < ActiveRecord::Migration
2
+ def change
3
+ create_table :maily_herald_dispatches do |t|
4
+ t.string :type, null: false
5
+ t.integer :sequence_id
6
+ t.integer :list_id, null: false
7
+ t.text :conditions
8
+ t.text :start_at
9
+ t.string :mailer_name
10
+ t.string :name, null: false
11
+ t.string :title
12
+ t.string :subject
13
+ t.string :from
14
+ t.string :state, default: "disabled"
15
+ t.text :template
16
+ t.integer :absolute_delay
17
+ t.integer :period
18
+ t.boolean :override_subscription
19
+
20
+ t.timestamps
21
+ end
22
+ add_index :maily_herald_dispatches, :name, unique: true
23
+
24
+ create_table :maily_herald_subscriptions do |t|
25
+ t.integer :entity_id, null: false
26
+ t.integer :list_id, null: false
27
+ t.string :entity_type, null: false
28
+ t.string :token, null: false
29
+ t.text :settings
30
+ t.text :data
31
+ t.boolean :active, default: false, null: false
32
+ t.datetime :delivered_at
33
+
34
+ t.timestamps
35
+ end
36
+
37
+ create_table :maily_herald_logs do |t|
38
+ t.integer :entity_id, null: false
39
+ t.string :entity_type, null: false
40
+ t.string :entity_email
41
+ t.integer :mailing_id
42
+ t.string :status, null: false
43
+ t.text :data
44
+ t.datetime :processing_at
45
+ end
46
+
47
+ create_table :maily_herald_lists do |t|
48
+ t.string :name, null: false
49
+ t.string :title
50
+ t.string :context_name
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,67 @@
1
+ class CreateMailyHeraldTables < ActiveRecord::Migration
2
+ def change
3
+ create_table :maily_herald_dispatches do |t|
4
+ t.string :type, null: false
5
+ t.integer :sequence_id
6
+ t.string :context_name
7
+ t.text :conditions
8
+ t.string :trigger
9
+ t.string :mailer_name
10
+ t.string :name, null: false
11
+ t.string :title
12
+ t.string :subject
13
+ t.string :from
14
+ t.text :template
15
+ t.integer :absolute_delay
16
+ t.datetime :start
17
+ t.text :start_var
18
+ t.integer :period
19
+ t.boolean :enabled, default: false
20
+ t.boolean :autosubscribe
21
+ t.boolean :override_subscription
22
+ t.integer :subscription_group_id
23
+ t.string :token_action
24
+
25
+ t.timestamps
26
+ end
27
+ add_index :maily_herald_dispatches, :name, unique: true
28
+ add_index :maily_herald_dispatches, :context_name
29
+ add_index :maily_herald_dispatches, :trigger
30
+
31
+ create_table :maily_herald_subscriptions do |t|
32
+ t.string :type, null: false
33
+ t.integer :entity_id, null: false
34
+ t.string :entity_type, null: false
35
+ t.integer :dispatch_id
36
+ t.string :token, null: false
37
+ t.text :settings
38
+ t.text :data
39
+ t.boolean :active, default: false, null: false
40
+ t.datetime :delivered_at
41
+
42
+ t.timestamps
43
+ end
44
+ #add_index :maily_herald_subscriptions, [:type, :entity_id, :entity_type, :dispatch_id], unique: true, name: "index_maliy_herald_subscriptions_unique"
45
+
46
+ create_table :maily_herald_logs do |t|
47
+ t.integer :entity_id, null: false
48
+ t.string :entity_type, null: false
49
+ t.integer :mailing_id
50
+ t.string :status, default: "delivered", null: false
51
+ t.text :data
52
+ t.datetime :processed_at
53
+ end
54
+
55
+ create_table :maily_herald_subscription_groups do |t|
56
+ t.string :name, null: false
57
+ t.string :title, null: false
58
+ end
59
+
60
+ create_table :maily_herald_aggregated_subscriptions do |t|
61
+ t.integer :entity_id, null: false
62
+ t.string :entity_type, null: false
63
+ t.integer :group_id, null: false
64
+ t.boolean :active, default: false, null: false
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,33 @@
1
+ class CreateLists < ActiveRecord::Migration
2
+ def up
3
+ create_table :maily_herald_lists do |t|
4
+ t.string :name, null: false
5
+ t.string :title
6
+ t.string :context_name
7
+ end
8
+
9
+ remove_column :maily_herald_dispatches, :token_action
10
+ remove_column :maily_herald_dispatches, :subscription_group_id
11
+ remove_column :maily_herald_dispatches, :autosubscribe
12
+ remove_column :maily_herald_dispatches, :start
13
+ remove_column :maily_herald_dispatches, :start_var
14
+ remove_column :maily_herald_dispatches, :trigger
15
+ remove_column :maily_herald_dispatches, :enabled
16
+ remove_column :maily_herald_dispatches, :context_name
17
+ add_column :maily_herald_dispatches, :start_at, :text
18
+ add_column :maily_herald_dispatches, :list_id, :integer
19
+ add_column :maily_herald_dispatches, :state, :string, default: :disabled
20
+
21
+ remove_column :maily_herald_subscriptions, :dispatch_id
22
+ remove_column :maily_herald_subscriptions, :type
23
+ add_column :maily_herald_subscriptions, :list_id, :integer
24
+ #add_column :maily_herald_subscriptions, :next_delivery_at, :datetime
25
+
26
+ drop_table :maily_herald_subscription_groups
27
+ drop_table :maily_herald_aggregated_subscriptions
28
+
29
+ rename_column :maily_herald_logs, :processed_at, :processing_at
30
+ change_column :maily_herald_logs, :status, :string, default: nil
31
+ add_column :maily_herald_logs, :entity_email, :string
32
+ end
33
+ end
@@ -9,9 +9,9 @@ module MailyHerald
9
9
  template "maily_herald.rb", "config/initializers/maily_herald.rb"
10
10
  end
11
11
 
12
- def copy_locale
13
- copy_file "../../../config/locales/en.yml", "config/locales/maily_handler.en.yml"
14
- end
12
+ def copy_locale
13
+ copy_file "../../../config/locales/en.yml", "config/locales/maily_herald.en.yml"
14
+ end
15
15
 
16
16
  def show_readme
17
17
  readme "README" if behavior == :invoke
@@ -0,0 +1,2 @@
1
+ Welcome to MailyHerald!
2
+ Don't forget to create your contexts in initializer (config/initializers/maily_herald.rb).
@@ -1,2 +1,3 @@
1
1
  MailyHerald.setup do |config|
2
+ # Put your contexts and mailing definitions here
2
3
  end
@@ -1,29 +1,351 @@
1
- require "maily_herald/engine"
1
+ require 'maily_herald/version'
2
+
3
+ require 'liquid'
4
+ require 'sidekiq'
5
+ require 'redis'
6
+
7
+ if defined?(::Rails::Engine)
8
+ require "maily_herald/engine"
9
+ end
2
10
 
3
11
  module MailyHerald
4
- autoload :Utils, 'maily_herald/utils'
5
- autoload :Context, 'maily_herald/context'
6
- autoload :Worker, 'maily_herald/worker'
12
+ class Async
13
+ include Sidekiq::Worker
7
14
 
8
- def self.setup
9
- yield self
15
+ def perform args = {}
16
+ if args["logger"]
17
+ logger_opts = {level: args["logger"]["level"], progname: "bkg"}
18
+ logger_opts[:target] = args["logger"]["target"]
19
+ MailyHerald::Logging.initialize(logger_opts)
20
+ end
21
+
22
+ if args["mailing"] && args["entity"]
23
+ MailyHerald::Manager.deliver args["mailing"], args["entity"]
24
+ elsif args["mailing"]
25
+ MailyHerald::Manager.run_mailing args["mailing"]
26
+ elsif args["sequence"]
27
+ MailyHerald::Manager.run_sequence args["sequence"]
28
+ elsif args["simulate"]
29
+ MailyHerald::Manager.simulate args["simulate"]
30
+ else
31
+ MailyHerald::Manager.run_all
32
+ end
33
+ end
10
34
  end
11
35
 
12
- def self.context name, &block
13
- name = name.to_s
14
-
15
- if block_given?
16
- @@contexts ||= {}
17
- @@contexts[name] ||= MailyHerald::Context.new
18
- yield @@contexts[name]
19
- else
20
- @@contexts[name]
21
- end
22
- end
23
-
24
- def self.contexts
25
- @@contexts
26
- end
27
- end
36
+ class ScheduleUpdater
37
+ include Sidekiq::Worker
28
38
 
29
- require 'liquid'
39
+ def perform id
40
+ dispatch = MailyHerald::Dispatch.find(id)
41
+ dispatch.update_schedules if dispatch.respond_to?(:update_schedules)
42
+ end
43
+ end
44
+
45
+ autoload :Utils, 'maily_herald/utils'
46
+ autoload :ConditionEvaluator, 'maily_herald/condition_evaluator'
47
+ autoload :TemplateRenderer, 'maily_herald/template_renderer'
48
+ autoload :ModelExtensions, 'maily_herald/model_extensions'
49
+ autoload :Context, 'maily_herald/context'
50
+ autoload :Manager, 'maily_herald/manager'
51
+ autoload :Config, 'maily_herald/config'
52
+ autoload :Autonaming, 'maily_herald/autonaming'
53
+ autoload :Logging, 'maily_herald/logging'
54
+
55
+ @@token_redirect = nil
56
+
57
+ class << self
58
+ # Returns config options read from config file.
59
+ def options
60
+ @options ||= read_options
61
+ end
62
+
63
+ # Assign config options.
64
+ def options=(opts)
65
+ @options = opts
66
+ end
67
+
68
+ # Get list of locked dispatches.
69
+ def locked_dispatches
70
+ @@locked_dispatches ||= []
71
+ end
72
+
73
+ # Lock a dispatch.
74
+ #
75
+ # @param name [Symbol] Dispatch identifier name.
76
+ def lock_dispatch name
77
+ name = name.to_s
78
+ self.locked_dispatches << name unless @@locked_dispatches.include?(name)
79
+ end
80
+
81
+ # Check if dispatch is locked.
82
+ #
83
+ # @param name [Symbol] Dispatch identifier name.
84
+ def dispatch_locked? name
85
+ self.locked_dispatches.include?(name.to_s)
86
+ end
87
+
88
+ # Get list of locked lists.
89
+ def locked_lists
90
+ @@locked_lists ||= []
91
+ end
92
+
93
+ # Lock a list.
94
+ #
95
+ # @param name [Symbol] List identifier name.
96
+ def lock_list name
97
+ name = name.to_s
98
+ self.locked_lists << name unless @@locked_lists.include?(name)
99
+ end
100
+
101
+ # Check if List is locked.
102
+ #
103
+ # @param name [Symbol] List identifier name.
104
+ def list_locked? name
105
+ self.locked_lists.include?(name.to_s)
106
+ end
107
+
108
+ # Obtains Redis connection.
109
+ def redis
110
+ @redis ||= begin
111
+ client = Redis.new(
112
+ url: options[:redis_url] || 'redis://localhost:6379/0',
113
+ driver: options[:redis_driver] || "ruby"
114
+ )
115
+
116
+ if options[:redis_namespace]
117
+ require 'redis/namespace'
118
+ Redis::Namespace.new(options[:redis_namespace], redis: client)
119
+ else
120
+ client
121
+ end
122
+ end
123
+ end
124
+
125
+ # Gets the Maily logger.
126
+ def logger
127
+ unless MailyHerald::Logging.initialized?
128
+ opts = {
129
+ level: options[:verbose] ? Logger::DEBUG : Logger::INFO,
130
+ }
131
+ opts[:target] = options[:logfile] if options[:logfile]
132
+
133
+ MailyHerald::Logging.initialize(opts)
134
+ end
135
+ MailyHerald::Logging.logger
136
+ end
137
+
138
+ # Performs Maily setup.
139
+ #
140
+ # To be used in initializer file.
141
+ def setup
142
+ @@contexts ||= {}
143
+
144
+ logger.warn("Maily migrations seems to be pending. Skipping setup...") && return if ([MailyHerald::Dispatch, MailyHerald::List, MailyHerald::Log, MailyHerald::Subscription].collect(&:table_exists?).select{|v| !v}.length > 0)
145
+
146
+ yield self
147
+ end
148
+
149
+ # Fetches or defines a {Context}.
150
+ #
151
+ # If no block provided, Context with given +name+ is returned.
152
+ #
153
+ # If block provided, Context with given +name+ is created and then block
154
+ # is evaluated within that Context.
155
+ #
156
+ # @param name [Symbol] Identifier name of the Context.
157
+ def context name, &block
158
+ name = name.to_s
159
+
160
+ if block_given?
161
+ @@contexts ||= {}
162
+ @@contexts[name] ||= MailyHerald::Context.new(name)
163
+ yield @@contexts[name]
164
+ else
165
+ @@contexts[name]
166
+ end
167
+ end
168
+
169
+ # Returns a dispatch with given identifier name.
170
+ #
171
+ # Dispatch is basically any object extending {MailyHerald::Dispatch}.
172
+ #
173
+ # @param name [Symbol] Dispatch identifier name.
174
+ def dispatch name
175
+ MailyHerald::Dispatch.find_by_name(name)
176
+ end
177
+
178
+ # Fetches or defines an {OneTimeMailing}.
179
+ #
180
+ # If no block provided, {OneTimeMailing} with given +name+ is returned.
181
+ #
182
+ # If block provided, {OneTimeMailing} with given +name+ is created or edited
183
+ # and block is evaluated within that mailing.
184
+ #
185
+ # @option options [true, false] :locked (false) Determines whether Mailing is locked.
186
+ # @see Dispatch#locked?
187
+ def one_time_mailing name, options = {}
188
+ mailing = MailyHerald::OneTimeMailing.where(name: name).first
189
+ lock = options.delete(:locked)
190
+
191
+ if block_given? && !self.dispatch_locked?(name) && (!mailing || lock)
192
+ mailing ||= MailyHerald::OneTimeMailing.new(name: name)
193
+ yield(mailing)
194
+ mailing.save!
195
+
196
+ MailyHerald.lock_dispatch(name) if lock
197
+ end
198
+
199
+ mailing
200
+ end
201
+
202
+ # Fetches or defines an {PeriodicalMailing}.
203
+ #
204
+ # If no block provided, {PeriodicalMailing} with given +name+ is returned.
205
+ #
206
+ # If block provided, {PeriodicalMailing} with given +name+ is created or edited
207
+ # and block is evaluated within that mailing.
208
+ #
209
+ # @option options [true, false] :locked (false) Determines whether Mailing is locked.
210
+ # @see Dispatch#locked?
211
+ def periodical_mailing name, options = {}
212
+ mailing = MailyHerald::PeriodicalMailing.where(name: name).first
213
+ lock = options.delete(:locked)
214
+
215
+ if block_given? && !self.dispatch_locked?(name) && (!mailing || lock)
216
+ mailing ||= MailyHerald::PeriodicalMailing.new(name: name)
217
+ yield(mailing)
218
+ mailing.save!
219
+
220
+ self.lock_dispatch(name) if lock
221
+ end
222
+
223
+ mailing
224
+ end
225
+
226
+ # Fetches or defines an {Sequence}.
227
+ #
228
+ # If no block provided, {Sequence} with given +name+ is returned.
229
+ #
230
+ # If block provided, {Sequence} with given +name+ is created or edited
231
+ # and block is evaluated within that mailing.
232
+ # Additionally, within provided block, using {Sequence#mailing} method,
233
+ # {SequenceMailing sequence mailings} can be defined.
234
+ #
235
+ # @option options [true, false] :locked (false) Determines whether Mailing is locked.
236
+ # @see Dispatch#locked?
237
+ # @see Sequence#mailing
238
+ def sequence name, options = {}
239
+ sequence = MailyHerald::Sequence.where(name: name).first
240
+ lock = options.delete(:locked)
241
+
242
+ if block_given? && !self.dispatch_locked?(name) && (!sequence || lock)
243
+ sequence ||= MailyHerald::Sequence.new(name: name)
244
+ yield(sequence)
245
+ sequence.save!
246
+
247
+ self.lock_dispatch(name) if lock
248
+ end
249
+
250
+ sequence
251
+ end
252
+
253
+ # Fetches or defines a {List}.
254
+ #
255
+ # If no block provided, {List} with given +name+ is returned.
256
+ #
257
+ # If block provided, {List} with given +name+ is created or edited
258
+ # and block is evaluated within that list.
259
+ #
260
+ # @option options [true, false] :locked (false) Determines whether {List} is locked.
261
+ # @see List#locked?
262
+ def list name, options = {}
263
+ list = MailyHerald::List.where(name: name).first
264
+ lock = options.delete(:locked)
265
+
266
+ if block_given? && !self.list_locked?(name) && (!list || lock)
267
+ list ||= MailyHerald::List.new(name: name)
268
+ yield(list)
269
+ list.save!
270
+
271
+ self.lock_list(name) if lock
272
+ end
273
+
274
+ list
275
+ end
276
+
277
+ # Subscribe +entity+ to {List lists} identified by +list_names+.
278
+ #
279
+ # @see List#subscribe!
280
+ def subscribe entity, *list_names
281
+ list_names.each do |ln|
282
+ list = MailyHerald.list(ln)
283
+ next unless list
284
+
285
+ list.subscribe! entity
286
+ end
287
+ end
288
+
289
+ # Unsubscribe +entity+ from {List lists} identified by +list_names+.
290
+ #
291
+ # @see List#unsubscribe!
292
+ def unsubscribe entity, *list_names
293
+ list_names.each do |ln|
294
+ list = MailyHerald.list(ln)
295
+ next unless list
296
+
297
+ list.unsubscribe! entity
298
+ end
299
+ end
300
+
301
+ # Return all defined {Context Contexts}.
302
+ def contexts
303
+ @@contexts ||= {}
304
+ end
305
+
306
+ def token_redirect &block
307
+ if block_given?
308
+ @@token_redirect = block
309
+ else
310
+ @@token_redirect
311
+ end
312
+ end
313
+
314
+ def deliver mailing_name, entity_id
315
+ mailing_name = mailing_name.name if mailing_name.is_a?(Mailing)
316
+ entity_id = entity_id.id if !entity_id.is_a?(Fixnum)
317
+
318
+ Async.perform_async mailing: mailing_name, entity: entity_id, logger: MailyHerald::Logging.safe_options
319
+ end
320
+
321
+ def run_sequence seq_name
322
+ seq_name = seq_name.name if seq_name.is_a?(Sequence)
323
+
324
+ Async.perform_async sequence: seq_name, logger: MailyHerald::Logging.safe_options
325
+ end
326
+
327
+ def run_mailing mailing_name
328
+ mailing_name = mailing_name.name if mailing_name.is_a?(Mailing)
329
+
330
+ Async.perform_async mailing: mailing_name, logger: MailyHerald::Logging.safe_options
331
+ end
332
+
333
+ def run_all
334
+ Async.perform_async(logger: MailyHerald::Logging.safe_options)
335
+ end
336
+
337
+ def find_subscription_for mailer_name, mailing_name, entity
338
+ mailing = MailyHerald::Mailing.where(mailer_name: mailer_name, name: mailing_name).first
339
+ mailing.subscription_for entity
340
+ end
341
+
342
+ # Read options from config file
343
+ def read_options cfile = "config/maily_herald.yml"
344
+ opts = {}
345
+ if File.exist?(cfile)
346
+ opts = YAML.load(ERB.new(IO.read(cfile)).result)
347
+ end
348
+ opts
349
+ end
350
+ end
351
+ end