mail_engine 0.1.2 → 0.1.3

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 (34) hide show
  1. data/Gemfile +1 -0
  2. data/VERSION +1 -1
  3. data/app/controllers/mail_engine/application_controller.rb +2 -1
  4. data/app/controllers/mail_engine/dashboard_controller.rb +1 -3
  5. data/app/controllers/mail_engine/mail_templates_controller.rb +12 -0
  6. data/app/controllers/mail_engine/reports_controller.rb +1 -2
  7. data/app/helpers/mail_engine/mail_engine_helper.rb +1 -1
  8. data/app/models/mail_engine/mail_log.rb +48 -33
  9. data/app/models/mail_engine/mail_schedule.rb +65 -6
  10. data/app/models/mail_engine/mail_template.rb +67 -63
  11. data/app/models/mail_engine/mail_template_file.rb +12 -0
  12. data/app/models/mail_engine/template_partial.rb +10 -0
  13. data/app/views/layouts/mail_engine/mail_engine.html.erb +1 -0
  14. data/app/views/mail_engine/dashboard/index.html.erb +32 -2
  15. data/app/views/mail_engine/mail_schedules/index.html.erb +18 -16
  16. data/app/views/mail_engine/mail_schedules/show.html.erb +8 -0
  17. data/app/views/mail_engine/mail_templates/import.html.erb +41 -0
  18. data/app/views/mail_engine/mail_templates/index.html.erb +34 -21
  19. data/config/routes.rb +2 -0
  20. data/db/migrate/20110114030841_create_table_mail_template.rb +1 -1
  21. data/lib/mail_engine/action_mailer_patch.rb +11 -0
  22. data/lib/mail_engine/engine.rb +1 -1
  23. data/lib/mail_engine/mail_template_resolver.rb +63 -0
  24. data/lib/mail_engine.rb +1 -0
  25. data/mail_engine.gemspec +11 -2
  26. data/test/dummy/app/mailers/test/test_mailer.rb +4 -0
  27. data/test/dummy/app/views/user_mailer/notify.html.erb +1 -0
  28. data/test/dummy/app/views/user_mailer/notify.text.erb +1 -0
  29. data/test/dummy/config/application.rb +1 -1
  30. data/test/dummy/db/migrate/20110114030841_create_table_mail_template.rb +1 -1
  31. data/test/dummy/db/schema.rb +1 -1
  32. data/test/unit/mail_engine/mail_schedule_test.rb +4 -0
  33. data/test/unit/mail_engine/mail_template_test.rb +9 -2
  34. metadata +29 -9
data/Gemfile CHANGED
@@ -12,6 +12,7 @@ gem 'kaminari', :git => 'https://github.com/amatsuda/kaminari.git'
12
12
  gem "carrierwave", :git => "git://github.com/jnicklas/carrierwave.git"
13
13
 
14
14
  group :development do
15
+ gem "annotate"
15
16
  gem "bluecloth"
16
17
  gem "yard"
17
18
  gem "bundler"
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.2
1
+ 0.1.3
@@ -1,5 +1,6 @@
1
1
  class MailEngine::ApplicationController < ApplicationController
2
- prepend_view_path MailEngine::MailTemplate::Resolver.instance
2
+ # used when mail_template preview.
3
+ prepend_view_path MailEngine::MailTemplateResolver.instance
3
4
  layout 'mail_engine/mail_engine'
4
5
 
5
6
  # set the access check method.
@@ -1,9 +1,7 @@
1
1
  class MailEngine::DashboardController < MailEngine::ApplicationController
2
2
  def index
3
3
  @pie_chart_columns = ["bounces", "unique_opens", "spamreports", "blocks", "unopened"]
4
-
5
- @stats_data = MailEngine::Sendgrid::RestApi.stats(:days => 6)
6
- @data_of_today = @stats_data.last
4
+ @data_of_today = MailEngine::Sendgrid::RestApi.stats
7
5
  @data_of_today.merge!("unopened" => (@data_of_today["delivered"].to_i - @data_of_today["unique_opens"].to_i))
8
6
  end
9
7
  end
@@ -132,6 +132,18 @@ class MailEngine::MailTemplatesController < MailEngine::ApplicationController
132
132
  def edit
133
133
  end
134
134
 
135
+ def import
136
+ end
137
+
138
+ def import_from_files
139
+ MailEngine::MailTemplate.import_from_files!(params[:import][:mailer_name])
140
+ flash[:notice] = "Import successfully!"
141
+ rescue => e
142
+ flash[:notice] = "Import failed due to: #{e.to_s}"
143
+ ensure
144
+ render :import
145
+ end
146
+
135
147
  # def send_test_mail
136
148
  # @mail_template.send_test_mail_to!(params[:recipient])
137
149
  # render :text => "alert('Test Mail sent to #{params[:recipient]}'); $('#recipient').val('');"
@@ -21,9 +21,8 @@ class MailEngine::ReportsController < MailEngine::ApplicationController
21
21
  @stats_data = if params[:report] and params[:report][:from] and params[:report][:to]
22
22
  MailEngine::Sendgrid::RestApi.stats(:start_date => params[:report][:from], :end_date => params[:report][:to])
23
23
  else
24
- MailEngine::Sendgrid::RestApi.stats(:days => 6)
24
+ MailEngine::Sendgrid::RestApi.stats(:days => 7)
25
25
  end
26
- @data_of_today = @stats_data.last
27
26
  end
28
27
 
29
28
  def chart
@@ -2,7 +2,7 @@ module MailEngine
2
2
  module MailEngineHelper
3
3
 
4
4
  def show_no_record collection, &block
5
- if collection.all.blank?
5
+ if collection.is_a?(Array) ? collection.blank? : collection.all.blank?
6
6
  return raw("<div class='notice' style='margin-top:10px'>No Record</div>")
7
7
  else
8
8
  block.call
@@ -1,36 +1,51 @@
1
+ # == Schema Information
2
+ #
3
+ # Table name: mail_logs
4
+ #
5
+ # id :integer not null, primary key
6
+ # mail_template_path :string(255)
7
+ # recipient :string(255)
8
+ # sender :string(255)
9
+ # subject :string(255)
10
+ # mime_type :string(255)
11
+ # raw_body :text
12
+ # created_at :datetime
13
+ # updated_at :datetime
14
+ #
15
+
1
16
  class MailEngine::MailLog < ActiveRecord::Base
2
17
  validates_presence_of :mail_template_path
3
18
 
4
- # Callback of Mail gem when delivering mails
5
- def self.delivering_email mail
6
- # pp email.body.raw_source
7
- # pp email.to
8
- # pp email.from
9
- # pp email.subject
10
- # pp email.mime_type
11
-
12
- ##################
13
- # pp mail.mime_type
14
- # pp mail.content_type
15
- # pp mail.from #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
16
- # pp mail.to #=> 'bob@test.lindsaar.net'
17
- # pp mail.subject #=> "This is the subject"
18
- # pp mail.body.decoded #=> 'This is the body of the email...
19
- ###################
20
-
21
- # pp mail.parts.map { |p| p.content_type } #=> ['text/plain', 'application/pdf']
22
- # pp mail.parts.map { |p| p.class } #=> [Mail::Message, Mail::Message]
23
- # pp mail.parts[0].content_type_parameters #=> {'charset' => 'ISO-8859-1'}
24
- # pp mail.parts[1].content_type_parameters #=> {'name' => 'my.pdf'}
25
-
26
- # mail_type = email.header["X-mail-type"].value
27
- # record = create! :recipient => email.to.join(","), :mail_type => mail_type
28
- # email.encoded # kick email to set content_transfer_encoding
29
- # # The new body needs to be already encoded, as Mail expects the body to be encoded already (after calling #encoded)
30
- # encoding = Mail::Encodings.get_encoding email.content_transfer_encoding
31
- # new_body = encoding.encode email.body.to_s.sub("/t/id.gif", "/t/#{record.open_token}.gif")
32
- # email.body(new_body)
33
- #
34
- # record.update_attributes! :body => email.body.to_s, :raw_text => email.encoded
35
- end
36
- end
19
+ # # Callback of Mail gem when delivering mails
20
+ # def self.delivering_email mail
21
+ # # pp email.body.raw_source
22
+ # # pp email.to
23
+ # # pp email.from
24
+ # # pp email.subject
25
+ # # pp email.mime_type
26
+ #
27
+ # ##################
28
+ # # pp mail.mime_type
29
+ # # pp mail.content_type
30
+ # # pp mail.from #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
31
+ # # pp mail.to #=> 'bob@test.lindsaar.net'
32
+ # # pp mail.subject #=> "This is the subject"
33
+ # # pp mail.body.decoded #=> 'This is the body of the email...
34
+ # ###################
35
+ #
36
+ # # pp mail.parts.map { |p| p.content_type } #=> ['text/plain', 'application/pdf']
37
+ # # pp mail.parts.map { |p| p.class } #=> [Mail::Message, Mail::Message]
38
+ # # pp mail.parts[0].content_type_parameters #=> {'charset' => 'ISO-8859-1'}
39
+ # # pp mail.parts[1].content_type_parameters #=> {'name' => 'my.pdf'}
40
+ #
41
+ # # mail_type = email.header["X-mail-type"].value
42
+ # # record = create! :recipient => email.to.join(","), :mail_type => mail_type
43
+ # # email.encoded # kick email to set content_transfer_encoding
44
+ # # # The new body needs to be already encoded, as Mail expects the body to be encoded already (after calling #encoded)
45
+ # # encoding = Mail::Encodings.get_encoding email.content_transfer_encoding
46
+ # # new_body = encoding.encode email.body.to_s.sub("/t/id.gif", "/t/#{record.open_token}.gif")
47
+ # # email.body(new_body)
48
+ # #
49
+ # # record.update_attributes! :body => email.body.to_s, :raw_text => email.encoded
50
+ # end
51
+ end
@@ -1,8 +1,43 @@
1
+ # == Schema Information
2
+ #
3
+ # Table name: mail_schedules
4
+ #
5
+ # id :integer not null, primary key
6
+ # name :string(255)
7
+ # mail_template_id :integer
8
+ # user_group :string(255)
9
+ # count :integer default(0)
10
+ # sent_count :integer default(0)
11
+ # period :string(255)
12
+ # payload :string(255)
13
+ # first_send_at :datetime
14
+ # last_sent_at :datetime
15
+ # created_at :datetime
16
+ # updated_at :datetime
17
+ #
18
+
1
19
  class MailEngine::MailSchedule < ActiveRecord::Base
2
20
  validates_presence_of :name, :user_group, :mail_template_id, :period, :count, :first_send_at
21
+ validates_inclusion_of :period, :in => %w( once daily weekly monthly yearly), :message => "period should in 'daily', 'weekly' and 'monthly'"
3
22
  belongs_to :mail_template
4
23
  scope :available, where("sent_count < count OR count = 0")
5
24
 
25
+ PERIOD_TO_UNIT_TABLE = {
26
+ "daily" => "day",
27
+ "weekly" => "week",
28
+ "monthly" => "month",
29
+ "yearly" => "year"
30
+ }
31
+
32
+ def self.future_schedules
33
+ all_future_schedules = []
34
+ MailEngine::MailSchedule.available.all.each do |schedule|
35
+ next_schedules = [schedule].product(schedule.next_several_schedules)
36
+ all_future_schedules << next_schedules.flatten if next_schedules.present?
37
+ end
38
+ all_future_schedules.sort {|x,y| x[1] <=> y[1]}
39
+ end
40
+
6
41
  # list mail log with the same mail_template_path to current mail_template's path
7
42
  def logs(count = 10)
8
43
  MailEngine::MailLog.where(:mail_template_path => self.mail_template.actual_path).order("id desc").limit(count)
@@ -27,6 +62,26 @@ class MailEngine::MailSchedule < ActiveRecord::Base
27
62
  end
28
63
  end
29
64
 
65
+ def next_several_schedules(schedule_count = 5)
66
+ # check if send count reached the total count.
67
+ return [] if (sent_count >= count and count != 0)
68
+ # only send once.
69
+ if period == 'once'
70
+ if first_send_at > Time.now
71
+ return [first_send_at]
72
+ else
73
+ return []
74
+ end
75
+ end
76
+
77
+ # other period
78
+ rest_count = (count == 0 ? schedule_count : count - sent_count)
79
+ start_datetime = Time.parse("#{(last_sent_at||first_send_at).strftime("%D")} #{first_send_at.strftime("%T")}")
80
+ (1..rest_count).map do |i|
81
+ start_datetime + i.send(PERIOD_TO_UNIT_TABLE[period])
82
+ end
83
+ end
84
+
30
85
  # If execute sendmail twice very soon(within 14 minutes), it should not be able to send mail again.
31
86
  def ready_to_send?
32
87
  # check if send count reached the total count.
@@ -34,10 +89,15 @@ class MailEngine::MailSchedule < ActiveRecord::Base
34
89
  # only send once.
35
90
  return sent_count < 1 if period == 'once'
36
91
 
37
- # why 15 minutes? for tolerance.
38
- not_sent_mail_within_15_minutes = last_sent_at.nil? || ((Time.now.to_i - last_sent_at.to_i).abs >= 60*15)
39
- ready_to_send = not_sent_mail_within_15_minutes and (Time.now.to_i - first_send_at.to_i).abs < 60*15
40
- result_by_period = case period
92
+ ### ready for first send?
93
+ # why 15 minutes? because crontab will run each 15 minutes.
94
+ timespan_since_last_mail = (Time.now.to_i - last_sent_at.to_i).abs
95
+ timespan_to_first_send_at = (Time.now.to_i - first_send_at.to_i).abs
96
+ not_sent_mail_within_15_minutes = last_sent_at.nil? || (timespan_since_last_mail >= 60*15)
97
+ start_first_send_within_15_minutes = (timespan_to_first_send_at < 60*15)
98
+
99
+ # cycle start
100
+ cycle_start = case period
41
101
  when 'daily'
42
102
  1.days.ago.to_i <= last_sent_at.to_i
43
103
  when 'weekly'
@@ -47,8 +107,7 @@ class MailEngine::MailSchedule < ActiveRecord::Base
47
107
  else
48
108
  false
49
109
  end
50
-
51
- ready_to_send or (not_sent_mail_within_15_minutes and result_by_period)
110
+ not_sent_mail_within_15_minutes and (cycle_start or start_first_send_within_15_minutes)
52
111
  end
53
112
 
54
113
  # used in Rake task, the main mail sending method.
@@ -1,3 +1,22 @@
1
+ # == Schema Information
2
+ #
3
+ # Table name: mail_templates
4
+ #
5
+ # id :integer not null, primary key
6
+ # name :string(255)
7
+ # subject :string(255)
8
+ # path :string(255)
9
+ # format :string(255) default("html")
10
+ # locale :string(255)
11
+ # handler :string(255) default("liquid")
12
+ # body :text
13
+ # partial :boolean default(FALSE)
14
+ # for_marketing :boolean default(FALSE)
15
+ # layout :string(255) default("none")
16
+ # zip_file :string(255)
17
+ # created_at :datetime
18
+ # updated_at :datetime
19
+ #
1
20
  class MailEngine::MailTemplate < ActiveRecord::Base
2
21
  attr_accessor :create_by_upload
3
22
 
@@ -37,7 +56,7 @@ class MailEngine::MailTemplate < ActiveRecord::Base
37
56
  before_save :delete_partials_if_new_partials_added
38
57
  after_save do
39
58
  # clear cached paths
40
- MailEngine::MailTemplate::Resolver.instance.clear_cache
59
+ MailEngine::MailTemplateResolver.instance.clear_cache
41
60
 
42
61
  # update subject
43
62
  MailEngine::MailTemplate.update_all(["subject=?", self.subject], ["path = ? AND locale = ?", self.path, self.locale])
@@ -45,10 +64,56 @@ class MailEngine::MailTemplate < ActiveRecord::Base
45
64
 
46
65
  # class methods
47
66
  class << self
67
+ # get subject from other templates with same path
48
68
  def get_subject_from_bother_template(path, locale, for_marketing)
49
69
  return nil if path.blank?
50
70
  MailEngine::MailTemplate.where(:path => path, :locale => locale, :for_marketing => for_marketing, :partial => false).select("subject").first.try(:subject)
51
71
  end
72
+
73
+ # import all mail template from exist system.
74
+ # format like: views/user_mailer/index.en.html.erb
75
+ def import_from_files!(mailer_name)
76
+ mailer = mailer_name.classify.constantize
77
+ raise "not a mailer or doesn't provide mailer." unless mailer.ancestors.include?(ActionMailer::Base)
78
+
79
+ # prepare data
80
+ mailer_actions = mailer.action_methods
81
+ file_view_paths = mailer.view_paths.select {|path| path.is_a?(ActionView::FileSystemResolver)}
82
+ available_formats = [:text, :html]
83
+ available_handlers = [:erb, :liquid, :rhtml]
84
+ available_locales = I18n.available_locales
85
+
86
+ # collect all possible combinations
87
+ search_envs = file_view_paths.product(mailer_actions, available_formats, available_handlers, available_locales)
88
+
89
+ # [#<ActionView::FileSystemResolver>, "notify_to_user", :text, :erb, :zh]
90
+ search_envs.map { |resolver, action, format, handler, locale|
91
+ template_files = resolver.find_all "#{mailer.to_s.underscore}/#{action}", {}, false, {
92
+ :locale => Array.wrap(locale),
93
+ :formats => Array.wrap(format),
94
+ :handlers => Array.wrap(handler)
95
+ }
96
+
97
+ # file_path => app/views/user_mailer/notify.html.erb
98
+ template_files.map do |file_path|
99
+ template = MailEngine::MailTemplate.create(
100
+ :name => "#{mailer.to_s.underscore}/#{action} - #{format}",
101
+ :subject => "#{mailer.to_s.underscore}/#{action} - #{format}",
102
+ :path => "#{mailer.to_s.underscore}/#{action}",
103
+ :format => format.to_s,
104
+ :locale => locale.to_s,
105
+ :body => File.read(file_path.identifier)
106
+ )
107
+ end
108
+ }.compact.flatten.uniq # search_envs
109
+ end
110
+
111
+ def all_system_mailers
112
+ mailer_path = File.join(Rails.root, "app", "mailers")
113
+ mailers_found_on_system = `find #{mailer_path} -name *.rb`.split("\n")
114
+ # remove mailer_path just show file names
115
+ mailers_found_on_system.map {|mailer| mailer.sub(/^#{mailer_path}\//, '')}
116
+ end
52
117
  end
53
118
 
54
119
  # detect if current partial template is used by other templates.
@@ -232,65 +297,4 @@ class MailEngine::MailTemplate < ActiveRecord::Base
232
297
  # ).deliver
233
298
  # end
234
299
  # end
235
-
236
-
237
- ###############################
238
- # path resolver, used for find template by provided path.
239
- class Resolver < ActionView::Resolver
240
- require "singleton"
241
- include Singleton
242
-
243
- def find_templates(name, prefix, partial, details)
244
- template_path_and_name = prefix.include?("mail_engine/mail_dispatcher") ? normalize_path(name, nil) : normalize_path(name, prefix)
245
-
246
- conditions = {
247
- :path => template_path_and_name,
248
- :locale => normalize_array(details[:locale]).first,
249
- :format => normalize_array(details[:formats]).first,
250
- :handler => normalize_array(details[:handlers]),
251
- :partial => partial || false
252
- }
253
-
254
- MailEngine::MailTemplate.where(conditions).map do |record|
255
- initialize_template(record)
256
- end
257
- end
258
-
259
- # Normalize name and prefix, so the tuple ["index", "users"] becomes
260
- # "users/index" and the tuple ["template", nil] becomes "template".
261
- def normalize_path(name, prefix)
262
- prefix.present? ? "#{prefix}/#{name}" : name
263
- end
264
-
265
- # Normalize arrays by converting all symbols to strings.
266
- def normalize_array(array)
267
- array.map(&:to_s)
268
- end
269
-
270
- # Initialize an ActionView::Template object based on the record found.
271
- def initialize_template(record)
272
- source = record.body
273
-
274
- identifier = "mail template - #{record.id} - #{record.path.inspect}"
275
- handler = ActionView::Template.registered_template_handler(record.handler)
276
-
277
- details = {
278
- :format => Mime[record.format],
279
- :updated_at => record.updated_at,
280
- :virtual_path => virtual_path(record.path, record.partial)
281
- }
282
-
283
- ActionView::Template.new(source, identifier, handler, details)
284
- end
285
-
286
- # Make paths as "users/user" become "users/_user" for partials.
287
- def virtual_path(path, partial)
288
- return path unless partial
289
- if index = path.rindex("/")
290
- path.insert(index + 1, "_")
291
- else
292
- "_#{path}"
293
- end
294
- end
295
- end # Resolver
296
- end
300
+ end
@@ -1,3 +1,15 @@
1
+ # == Schema Information
2
+ #
3
+ # Table name: mail_template_files
4
+ #
5
+ # id :integer not null, primary key
6
+ # mail_template_id :integer
7
+ # file :string(255)
8
+ # size :integer
9
+ # created_at :datetime
10
+ # updated_at :datetime
11
+ #
12
+
1
13
  class MailEngine::MailTemplateFile < ActiveRecord::Base
2
14
  mount_uploader :file, MailEngine::TemplateFileUploader
3
15
 
@@ -1,3 +1,13 @@
1
+ # == Schema Information
2
+ #
3
+ # Table name: template_partials
4
+ #
5
+ # id :integer not null, primary key
6
+ # placeholder_name :string(255)
7
+ # mail_template_id :integer
8
+ # partial_id :integer
9
+ #
10
+
1
11
  class MailEngine::TemplatePartial < ActiveRecord::Base
2
12
  validates_presence_of :partial_id, :placeholder_name
3
13
 
@@ -80,6 +80,7 @@
80
80
  <li <%= "class='current-tab'" if controller_name == 'mail_templates' and params[:type] == 'system' %>><%= link_to "Sytem Mail Templates", mail_templates_path(:type => 'system') %></li>
81
81
  <li <%= "class='current-tab'" if controller_name == 'mail_templates' and params[:type] == 'marketing' %>><%= link_to "Marketing Mail Templates", mail_templates_path(:type => 'marketing') %></li>
82
82
  <li <%= "class='current-tab'" if controller_name == 'mail_templates' and params[:type] == 'partial' %>><%= link_to "Template Partials", mail_templates_path(:type => 'partial') %></li>
83
+ <li <%= "class='current-tab'" if controller_name == 'mail_templates' and action_name == 'import_from_files' %>><%= link_to "Import From System Templates", import_mail_templates_path %></li>
83
84
  </ul>
84
85
  <div class="clearer">&nbsp;</div>
85
86
  </div>
@@ -25,7 +25,7 @@
25
25
  </script>
26
26
 
27
27
  <div class="today-report left">
28
-
28
+
29
29
  <h2>Report of Today</h2>
30
30
  <div class="clearer"></div>
31
31
 
@@ -73,9 +73,39 @@
73
73
  <tr>
74
74
  <th>Schedule Name</th><th width="120">Send Time</th>
75
75
  </tr>
76
+ <% MailEngine::MailSchedule.future_schedules.each do |schedule, scheduled_time| %>
76
77
  <tr>
77
- <td>New Jobs Newsletter</td><td>2011-3-4 12:00</td>
78
+ <td><%= link_to schedule.name, mail_schedule_path(schedule) %></td><td><%= scheduled_time.to_s(:db) %></td>
79
+ </tr>
80
+ <% end %>
81
+ </table>
82
+ </div>
83
+ <div class="clearer"></div>
84
+
85
+ <div class="today-report left">
86
+ <h2>Recently Sent Mails</h2>
87
+ <div class="clearer"></div>
88
+
89
+ <table class="data-table" style="width: 910px; margin-top: 30px; margin-right: 30px">
90
+ <tr>
91
+ <th>Subject</th>
92
+ <th>Sender</th>
93
+ <th>Recipient</th>
94
+ <th>mime_type</th>
95
+ <th>Sent at</th>
96
+ <th width="20"></th>
97
+ </tr>
98
+
99
+ <% MailEngine::MailLog.order("id desc").limit(10).each do |log| %>
100
+ <tr class="even">
101
+ <td><%= log.subject %></td>
102
+ <td><%= log.sender %></td>
103
+ <td><%= log.recipient %></td>
104
+ <td><%= log.mime_type %></td>
105
+ <td><%= log.created_at %></td>
106
+ <td><%= link_to image_tag('mail_engine/icons/show.png'), mail_log_path(log) %></td>
78
107
  </tr>
108
+ <% end %>
79
109
  </table>
80
110
  </div>
81
111
  <div class="clearer"></div>
@@ -4,26 +4,28 @@
4
4
  <%= show_no_record(@mail_schedules) do %>
5
5
  <table class="data-table">
6
6
  <tr>
7
- <th>Name</th>
8
- <th>Template</th>
9
- <th>User Group</th>
10
- <th>Total Count</th>
11
- <th>Sent Count</th>
12
- <th>Period</th>
13
- <th>Payload</th>
14
- <th></th>
7
+ <th>Schedule Info</th>
8
+ <th width="230"></th>
15
9
  </tr>
16
10
 
17
11
  <% @mail_schedules.each do |mail_schedule| %>
18
12
  <tr class="even">
19
- <td><%= mail_schedule.name %></td>
20
- <td><%= mail_schedule.mail_template.name %></td>
21
- <td><%= mail_schedule.user_group %></td>
22
- <td><%= mail_schedule.count %></td>
23
- <td><%= mail_schedule.sent_count %></td>
24
- <td><%= mail_schedule.period %></td>
25
- <td><%= raw mail_schedule.payload.gsub(",", "<br/>") %></td>
26
- <td>
13
+ <td style="vertical-align:top">
14
+ <table class="data-table" style="margin-bottom: 0px">
15
+ <tr><th width="100">Name</th><td><%= mail_schedule.name %></td></tr>
16
+ <tr><th>Template</th><td><%= mail_schedule.mail_template.name %></td></tr>
17
+ <tr><th>User Group</th><td><%= mail_schedule.user_group %></td></tr>
18
+ <tr><th>Total Count</th><td><%= mail_schedule.count %></td></tr>
19
+ <tr><th>Sent Count</th><td><%= mail_schedule.sent_count %></td></tr>
20
+ <tr><th>Period</th><td><%= mail_schedule.period %></td></tr>
21
+ <tr><th>First Send At</th><td><%= mail_schedule.first_send_at %></td></tr>
22
+ <tr><th>Last Sent At</th><td><%= mail_schedule.last_sent_at %></td></tr>
23
+ <tr><th>Payload</th>
24
+ <td><%= raw mail_schedule.payload.gsub(",", "<br/>") %></td>
25
+ </tr>
26
+ </table>
27
+ </td>
28
+ <td style="vertical-align:top">
27
29
  <%= link_to image_tag('mail_engine/icons/show.png'), mail_schedule_path(mail_schedule) %>
28
30
  <%= link_to image_tag('mail_engine/icons/edit.gif'), edit_mail_schedule_path(mail_schedule) %>
29
31
  <%= link_to image_tag('mail_engine/icons/delete.png'), mail_schedule_path(mail_schedule), :confirm => 'Are you sure?', :method => :delete %>
@@ -29,6 +29,14 @@
29
29
  <td>Period</td>
30
30
  <td><%= @mail_schedule.period %></td>
31
31
  </tr>
32
+ <tr>
33
+ <td>First send at</td>
34
+ <td><%= @mail_schedule.first_send_at %></td>
35
+ </tr>
36
+ <tr>
37
+ <td>Last send at</td>
38
+ <td><%= @mail_schedule.last_sent_at %></td>
39
+ </tr>
32
40
  <tr>
33
41
  <td>Payload</td>
34
42
  <td><%= @mail_schedule.payload %></td>
@@ -0,0 +1,41 @@
1
+ <div class="post">
2
+ <div class="post-title">
3
+ <h2>
4
+ Import Mail Template From System Files
5
+ </h2>
6
+ </div>
7
+ <div class="post-body">
8
+ <%= form_for(:import, :url => import_from_files_mail_templates_path) do |f| %>
9
+ <!-- basic columns -->
10
+ <div class="field">
11
+ <%= f.label :mailer_name %><br />
12
+ <%= f.text_field :mailer_name, :class => "text" %>
13
+ </div>
14
+
15
+ <div class="actions">
16
+ <%= f.submit :class => "button" %>
17
+ </div>
18
+
19
+ <% if @mailers_found_on_system = MailEngine::MailTemplate.all_system_mailers %>
20
+ <div class="field quiet" style="margin-top: 20px">
21
+ <label>Mailers Found on current system under "app/mailers":</label>
22
+ <ul>
23
+ <% @mailers_found_on_system.each do |mailer| %>
24
+ <li><%= mailer %></li>
25
+ <% end %>
26
+ </ul>
27
+ </div>
28
+ <% end %>
29
+
30
+ <div class="field quiet" style="margin-top: 20px">
31
+ <label>Your mail template file name have to abide the convention like:</label>
32
+ <ul>
33
+ <li>xxx.html.erb</li>
34
+ <li>xxx.text.erb</li>
35
+ <li>xxx.html.liquid</li>
36
+ <li>xxx.text.liquid</li>
37
+ </ul>
38
+ </div>
39
+ <% end %>
40
+ </div>
41
+ </div>
@@ -4,35 +4,37 @@
4
4
  <%= show_no_record(@mail_templates) do %>
5
5
  <table class="data-table">
6
6
  <tr>
7
- <th>Name</th>
8
- <th>Template Path</th>
9
- <% if params[:type] != 'partial' %>
10
- <th>Subject</th>
11
- <th>Layout</th>
12
- <th>Partials</th>
13
- <% end %>
14
- <th>Variations</th>
7
+ <th>Template Info</th>
8
+ <th>Variations
9
+ <a href="javascript:void()" class="show_all_variations_link">All</a>
10
+ </th>
15
11
  </tr>
16
12
 
17
13
  <% @mail_templates.each do |mail_template| %>
18
14
  <tr class="even">
19
- <td><%= mail_template.name %></td>
20
- <td><%= mail_template.path %></td>
21
- <% if params[:type] != 'partial' %>
22
- <td><%= mail_template.subject %></td>
23
- <td><%= mail_template.layout %></td>
24
- <td><%= mail_template.partials.map(&:name).join(" , ") %></td>
25
- <% end %>
26
- <td style="width: 200px;">
15
+ <td style="vertical-align:top">
16
+ <table class="data-table" style="margin-bottom: 0px">
17
+ <tr><th width="100">Name</th><td><%= mail_template.name %></td></tr>
18
+ <tr><th>Path</th><td><%= mail_template.path %></td></tr>
19
+ <% if params[:type] != 'partial' %>
20
+ <tr><th>Subject</th><td><%= mail_template.subject %></td></tr>
21
+ <tr><th>Layout</th><td><%= mail_template.layout %></td></tr>
22
+ <tr><th>Partials</th><td><%= mail_template.partials.map(&:name).join(" , ") %></td></tr>
23
+ <% end %>
24
+ </table>
25
+ </td>
26
+ <td style="width: 200px; vertical-align: top;">
27
+ <!-- variation list -->
27
28
  <table style="margin-bottom: 0px;">
28
29
  <% mail_template.variations(params[:type] == 'partial').group_by(&:locale).each do |locale, templates| %>
29
- <tr>
30
+ <tr class="<%= "hideable" unless templates.detect {|t| t.persisted? } %>">
30
31
  <td colspan="2" style="background-color: grey; font-weight: bold; color: white; padding: 2px 5px"><%= locale.humanize %></td>
31
32
  </tr>
33
+
32
34
  <% templates.each do |template| %>
33
35
  <% if template.persisted? %>
34
36
  <tr>
35
- <td><%= template.locale %>.<%= template.format %></td>
37
+ <td><b><%= template.locale %>.<%= template.format %></b></td>
36
38
  <td>
37
39
  <%= link_to image_tag('mail_engine/icons/show.png', :alt => "Show"), mail_template_path(template) %>
38
40
  <%= link_to image_tag('mail_engine/icons/edit.gif', :alt => "Edit"), edit_mail_template_path(template) %>
@@ -42,16 +44,16 @@
42
44
  </tr>
43
45
  <% else %>
44
46
  <tr>
45
- <td class='quiet' colspan='2'>
47
+ <td class='quiet hideable' colspan='2'>
46
48
  <%= image_tag('mail_engine/icons/missing.png', :alt => "Missing", :class=>"left", :style => "margin-bottom: 0px") %>
47
49
  Missing: <%= template.locale %>.<%= template.format %>
48
50
  </td>
49
- <%#= link_to image_tag('mail_engine/icons/add.png', :alt => "Add"), new_mail_template_path(:type => params[:type]) %>
50
51
  </tr>
51
52
  <% end %>
52
53
  <% end %>
53
54
  <% end %>
54
55
  </table>
56
+
55
57
  </td>
56
58
  </tr>
57
59
  <% end %>
@@ -70,4 +72,15 @@
70
72
  </h5>
71
73
  <div class="clearer">&nbsp;</div>
72
74
  </div>
73
- </div>
75
+ </div>
76
+
77
+ <script>
78
+ $(function(){
79
+ $(".hideable").hide();
80
+
81
+ $(".show_all_variations_link").click(function(){
82
+ $(".hideable").toggle();
83
+ $(this).html($(this).html() == 'All' ? "Available" : "All")
84
+ });
85
+ });
86
+ </script>
data/config/routes.rb CHANGED
@@ -20,6 +20,8 @@ module MailEngine
20
20
  # used before mail template been saved
21
21
  post :preview
22
22
 
23
+ get :import
24
+ post :import_from_files
23
25
  get :get_existed_subject
24
26
  get :new_by_upload
25
27
  post :create_by_upload
@@ -10,7 +10,7 @@ class CreateTableMailTemplate < ActiveRecord::Migration
10
10
  t.text :body
11
11
  t.boolean :partial, :default => false
12
12
  t.boolean :for_marketing, :default => false
13
- t.string :layout
13
+ t.string :layout, :default => 'none'
14
14
  t.string :zip_file
15
15
 
16
16
  t.timestamps
@@ -8,6 +8,17 @@ module ActionMailer
8
8
  headers[:subject] = current_template.subject if headers[:subject].blank? && current_template.present?
9
9
  headers[:message_id] = "#{controller_path}/#{action_name}"
10
10
 
11
+ unless block_given?
12
+ puts "\e[1;31;40m[Mail Engine Warning]\e[0m Please pass a block to 'mail' method as below style,
13
+ mail engine needs you to specify the format to send:
14
+ \e[1;34;40m
15
+ mail :to => 'xxx@xxx.com' do |format|
16
+ format.text
17
+ format.html
18
+ end
19
+ \e[0m"
20
+ end
21
+
11
22
  # Add sendgrid header before sending mail.
12
23
  # Why here but not add to default_params of action_mailer? because the receiver email [:to] only can get here.
13
24
  if self.sendgrid_config
@@ -18,7 +18,7 @@ module MailEngine
18
18
 
19
19
  initializer "mail_engine.register_database_template" do
20
20
  ActionMailer::Base.layout "layouts/mail_engine/mail_template_layouts/none"
21
- ActionMailer::Base.send(:prepend_view_path, MailEngine::MailTemplate::Resolver.instance)
21
+ ActionMailer::Base.send(:prepend_view_path, MailEngine::MailTemplateResolver.instance)
22
22
  end
23
23
 
24
24
  initializer "mail_engine.add_acts_as_mail_receiver" do
@@ -0,0 +1,63 @@
1
+ module MailEngine
2
+
3
+ ###############################
4
+ # path resolver, used for find template by provided path.
5
+ class MailTemplateResolver < ActionView::Resolver
6
+ require "singleton"
7
+ include Singleton
8
+
9
+ def find_templates(name, prefix, partial, details)
10
+ template_path_and_name = prefix.include?("mail_engine/mail_dispatcher") ? normalize_path(name, nil) : normalize_path(name, prefix)
11
+
12
+ conditions = {
13
+ :path => template_path_and_name,
14
+ :locale => normalize_array(details[:locale]).first,
15
+ :format => normalize_array(details[:formats]).first,
16
+ :handler => normalize_array(details[:handlers]),
17
+ :partial => partial || false
18
+ }
19
+
20
+ MailTemplate.where(conditions).map do |record|
21
+ initialize_template(record)
22
+ end
23
+ end
24
+
25
+ # Normalize name and prefix, so the tuple ["index", "users"] becomes
26
+ # "users/index" and the tuple ["template", nil] becomes "template".
27
+ def normalize_path(name, prefix)
28
+ prefix.present? ? "#{prefix}/#{name}" : name
29
+ end
30
+
31
+ # Normalize arrays by converting all symbols to strings.
32
+ def normalize_array(array)
33
+ array.map(&:to_s)
34
+ end
35
+
36
+ # Initialize an ActionView::Template object based on the record found.
37
+ def initialize_template(record)
38
+ source = record.body
39
+
40
+ identifier = "mail template - #{record.id} - #{record.path.inspect}"
41
+ handler = ActionView::Template.registered_template_handler(record.handler)
42
+
43
+ details = {
44
+ :format => Mime[record.format],
45
+ :updated_at => record.updated_at,
46
+ :virtual_path => virtual_path(record.path, record.partial)
47
+ }
48
+
49
+ ActionView::Template.new(source, identifier, handler, details)
50
+ end
51
+
52
+ # Make paths as "users/user" become "users/_user" for partials.
53
+ def virtual_path(path, partial)
54
+ return path unless partial
55
+ if index = path.rindex("/")
56
+ path.insert(index + 1, "_")
57
+ else
58
+ "_#{path}"
59
+ end
60
+ end
61
+ end # Resolver
62
+
63
+ end
data/lib/mail_engine.rb CHANGED
@@ -20,5 +20,6 @@ module MailEngine
20
20
  autoload :Mailer
21
21
  autoload :ActsAsMailReceiver
22
22
  autoload :Configuration
23
+ autoload :MailTemplateResolver
23
24
  end
24
25
 
data/mail_engine.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{mail_engine}
8
- s.version = "0.1.2"
8
+ s.version = "0.1.3"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["michael he"]
12
- s.date = %q{2011-03-05}
12
+ s.date = %q{2011-03-06}
13
13
  s.description = %q{Rails system mail management solution.}
14
14
  s.email = %q{hlxwell@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -132,6 +132,7 @@ Gem::Specification.new do |s|
132
132
  "app/views/mail_engine/mail_templates/_layout_selector.html.erb",
133
133
  "app/views/mail_engine/mail_templates/duplicate.html.erb",
134
134
  "app/views/mail_engine/mail_templates/edit.html.erb",
135
+ "app/views/mail_engine/mail_templates/import.html.erb",
135
136
  "app/views/mail_engine/mail_templates/index.html.erb",
136
137
  "app/views/mail_engine/mail_templates/new.html.erb",
137
138
  "app/views/mail_engine/mail_templates/new_by_upload.html.erb",
@@ -203,6 +204,7 @@ Gem::Specification.new do |s|
203
204
  "lib/mail_engine/html_document_assets_replacer.rb",
204
205
  "lib/mail_engine/liquid_view_patch/liquid_view.rb",
205
206
  "lib/mail_engine/mail_log_subscriber.rb",
207
+ "lib/mail_engine/mail_template_resolver.rb",
206
208
  "lib/mail_engine/sendgrid.rb",
207
209
  "lib/mail_engine/sendgrid/base.rb",
208
210
  "lib/mail_engine/sendgrid/rest_api.rb",
@@ -356,8 +358,11 @@ Gem::Specification.new do |s|
356
358
  "test/dummy/Rakefile",
357
359
  "test/dummy/app/controllers/application_controller.rb",
358
360
  "test/dummy/app/helpers/application_helper.rb",
361
+ "test/dummy/app/mailers/test/test_mailer.rb",
359
362
  "test/dummy/app/mailers/user_mailer.rb",
360
363
  "test/dummy/app/models/user.rb",
364
+ "test/dummy/app/views/user_mailer/notify.html.erb",
365
+ "test/dummy/app/views/user_mailer/notify.text.erb",
361
366
  "test/dummy/config.ru",
362
367
  "test/dummy/config/application.rb",
363
368
  "test/dummy/config/boot.rb",
@@ -551,6 +556,7 @@ Gem::Specification.new do |s|
551
556
  s.test_files = [
552
557
  "test/dummy/app/controllers/application_controller.rb",
553
558
  "test/dummy/app/helpers/application_helper.rb",
559
+ "test/dummy/app/mailers/test/test_mailer.rb",
554
560
  "test/dummy/app/mailers/user_mailer.rb",
555
561
  "test/dummy/app/models/user.rb",
556
562
  "test/dummy/config/application.rb",
@@ -604,6 +610,7 @@ Gem::Specification.new do |s|
604
610
  s.add_runtime_dependency(%q<liquid>, [">= 0"])
605
611
  s.add_runtime_dependency(%q<kaminari>, [">= 0"])
606
612
  s.add_runtime_dependency(%q<carrierwave>, [">= 0"])
613
+ s.add_development_dependency(%q<annotate>, [">= 0"])
607
614
  s.add_development_dependency(%q<bluecloth>, [">= 0"])
608
615
  s.add_development_dependency(%q<yard>, [">= 0"])
609
616
  s.add_development_dependency(%q<bundler>, [">= 0"])
@@ -620,6 +627,7 @@ Gem::Specification.new do |s|
620
627
  s.add_dependency(%q<liquid>, [">= 0"])
621
628
  s.add_dependency(%q<kaminari>, [">= 0"])
622
629
  s.add_dependency(%q<carrierwave>, [">= 0"])
630
+ s.add_dependency(%q<annotate>, [">= 0"])
623
631
  s.add_dependency(%q<bluecloth>, [">= 0"])
624
632
  s.add_dependency(%q<yard>, [">= 0"])
625
633
  s.add_dependency(%q<bundler>, [">= 0"])
@@ -637,6 +645,7 @@ Gem::Specification.new do |s|
637
645
  s.add_dependency(%q<liquid>, [">= 0"])
638
646
  s.add_dependency(%q<kaminari>, [">= 0"])
639
647
  s.add_dependency(%q<carrierwave>, [">= 0"])
648
+ s.add_dependency(%q<annotate>, [">= 0"])
640
649
  s.add_dependency(%q<bluecloth>, [">= 0"])
641
650
  s.add_dependency(%q<yard>, [">= 0"])
642
651
  s.add_dependency(%q<bundler>, [">= 0"])
@@ -0,0 +1,4 @@
1
+ class Test::TestMailer < ActionMailer::Base
2
+ def nothing
3
+ end
4
+ end
@@ -0,0 +1 @@
1
+ html notify content
@@ -0,0 +1 @@
1
+ text notify content here.
@@ -28,7 +28,7 @@ module Dummy
28
28
 
29
29
  # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
30
30
  # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
31
- # config.time_zone = 'Central Time (US & Canada)'
31
+ config.time_zone = 'Beijing'
32
32
 
33
33
  # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
34
34
  # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
@@ -10,7 +10,7 @@ class CreateTableMailTemplate < ActiveRecord::Migration
10
10
  t.text :body
11
11
  t.boolean :partial, :default => false
12
12
  t.boolean :for_marketing, :default => false
13
- t.string :layout
13
+ t.string :layout, :default => 'none'
14
14
  t.string :zip_file
15
15
 
16
16
  t.timestamps
@@ -55,7 +55,7 @@ ActiveRecord::Schema.define(:version => 20110217062316) do
55
55
  t.text "body"
56
56
  t.boolean "partial", :default => false
57
57
  t.boolean "for_marketing", :default => false
58
- t.string "layout"
58
+ t.string "layout", :default => "none"
59
59
  t.string "zip_file"
60
60
  t.datetime "created_at"
61
61
  t.datetime "updated_at"
@@ -33,6 +33,10 @@ class MailEngine::MailScheduleTest < ActiveSupport::TestCase
33
33
  @schedule.send_test_mail_to!("hlxwell@gmail.com", 0)
34
34
  end
35
35
  end
36
+
37
+ should "be able to get next_several_schedules" do
38
+ assert_equal [], @schedule.next_several_schedules
39
+ end
36
40
  end
37
41
 
38
42
  context "once sending only schedule" do
@@ -15,7 +15,14 @@ class MailEngine::MailTemplateTest < ActiveSupport::TestCase
15
15
  end
16
16
  end
17
17
 
18
- context "Template" do
18
+ context "Template class" do
19
+ setup do
20
+ end
21
+ should "be able to get_subject_from_bother_template"
22
+ should "be able to import templates from exist system"
23
+ end
24
+
25
+ context "A Template" do
19
26
  setup do
20
27
  @template = FactoryGirl.create(:system_mail_template_with_footer, :format => "html")
21
28
  end
@@ -102,7 +109,7 @@ class MailEngine::MailTemplateTest < ActiveSupport::TestCase
102
109
  # should "clone mail template files" do
103
110
  # assert_equal @clone_template.mail_template_files.count, @zipmail_template.mail_template_files.count, "clone template has different files with original one."
104
111
  # end
105
- #
112
+ #
106
113
  # should "has the same files" do
107
114
  # @clone_template.mail_template_files.each_with_index do |f, index|
108
115
  # assert_equal File.basename(f.file.path), @zipmail_template.mail_template_files[index].try(:attributes).try(:[], "file")
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mail_engine
3
3
  version: !ruby/object:Gem::Version
4
- hash: 31
4
+ hash: 29
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 2
10
- version: 0.1.2
9
+ - 3
10
+ version: 0.1.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - michael he
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-03-05 00:00:00 +08:00
18
+ date: 2011-03-06 00:00:00 +08:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -158,7 +158,7 @@ dependencies:
158
158
  version: "0"
159
159
  requirement: *id010
160
160
  prerelease: false
161
- name: bluecloth
161
+ name: annotate
162
162
  type: :development
163
163
  - !ruby/object:Gem::Dependency
164
164
  version_requirements: &id011 !ruby/object:Gem::Requirement
@@ -172,7 +172,7 @@ dependencies:
172
172
  version: "0"
173
173
  requirement: *id011
174
174
  prerelease: false
175
- name: yard
175
+ name: bluecloth
176
176
  type: :development
177
177
  - !ruby/object:Gem::Dependency
178
178
  version_requirements: &id012 !ruby/object:Gem::Requirement
@@ -186,7 +186,7 @@ dependencies:
186
186
  version: "0"
187
187
  requirement: *id012
188
188
  prerelease: false
189
- name: bundler
189
+ name: yard
190
190
  type: :development
191
191
  - !ruby/object:Gem::Dependency
192
192
  version_requirements: &id013 !ruby/object:Gem::Requirement
@@ -200,7 +200,7 @@ dependencies:
200
200
  version: "0"
201
201
  requirement: *id013
202
202
  prerelease: false
203
- name: jeweler
203
+ name: bundler
204
204
  type: :development
205
205
  - !ruby/object:Gem::Dependency
206
206
  version_requirements: &id014 !ruby/object:Gem::Requirement
@@ -214,7 +214,7 @@ dependencies:
214
214
  version: "0"
215
215
  requirement: *id014
216
216
  prerelease: false
217
- name: rcov
217
+ name: jeweler
218
218
  type: :development
219
219
  - !ruby/object:Gem::Dependency
220
220
  version_requirements: &id015 !ruby/object:Gem::Requirement
@@ -228,6 +228,20 @@ dependencies:
228
228
  version: "0"
229
229
  requirement: *id015
230
230
  prerelease: false
231
+ name: rcov
232
+ type: :development
233
+ - !ruby/object:Gem::Dependency
234
+ version_requirements: &id016 !ruby/object:Gem::Requirement
235
+ none: false
236
+ requirements:
237
+ - - ">="
238
+ - !ruby/object:Gem::Version
239
+ hash: 3
240
+ segments:
241
+ - 0
242
+ version: "0"
243
+ requirement: *id016
244
+ prerelease: false
231
245
  name: reek
232
246
  type: :development
233
247
  description: Rails system mail management solution.
@@ -355,6 +369,7 @@ files:
355
369
  - app/views/mail_engine/mail_templates/_layout_selector.html.erb
356
370
  - app/views/mail_engine/mail_templates/duplicate.html.erb
357
371
  - app/views/mail_engine/mail_templates/edit.html.erb
372
+ - app/views/mail_engine/mail_templates/import.html.erb
358
373
  - app/views/mail_engine/mail_templates/index.html.erb
359
374
  - app/views/mail_engine/mail_templates/new.html.erb
360
375
  - app/views/mail_engine/mail_templates/new_by_upload.html.erb
@@ -426,6 +441,7 @@ files:
426
441
  - lib/mail_engine/html_document_assets_replacer.rb
427
442
  - lib/mail_engine/liquid_view_patch/liquid_view.rb
428
443
  - lib/mail_engine/mail_log_subscriber.rb
444
+ - lib/mail_engine/mail_template_resolver.rb
429
445
  - lib/mail_engine/sendgrid.rb
430
446
  - lib/mail_engine/sendgrid/base.rb
431
447
  - lib/mail_engine/sendgrid/rest_api.rb
@@ -579,8 +595,11 @@ files:
579
595
  - test/dummy/Rakefile
580
596
  - test/dummy/app/controllers/application_controller.rb
581
597
  - test/dummy/app/helpers/application_helper.rb
598
+ - test/dummy/app/mailers/test/test_mailer.rb
582
599
  - test/dummy/app/mailers/user_mailer.rb
583
600
  - test/dummy/app/models/user.rb
601
+ - test/dummy/app/views/user_mailer/notify.html.erb
602
+ - test/dummy/app/views/user_mailer/notify.text.erb
584
603
  - test/dummy/config.ru
585
604
  - test/dummy/config/application.rb
586
605
  - test/dummy/config/boot.rb
@@ -802,6 +821,7 @@ summary: Mail Management Solution
802
821
  test_files:
803
822
  - test/dummy/app/controllers/application_controller.rb
804
823
  - test/dummy/app/helpers/application_helper.rb
824
+ - test/dummy/app/mailers/test/test_mailer.rb
805
825
  - test/dummy/app/mailers/user_mailer.rb
806
826
  - test/dummy/app/models/user.rb
807
827
  - test/dummy/config/application.rb