smailer 0.7.8 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,88 +1,105 @@
1
1
  class CreateSmailerTables < ActiveRecord::Migration
2
2
  def self.up
3
- create_table "mailing_lists", :force => true do |t|
4
- t.string "name"
3
+ create_table "finished_mails", :force => :cascade do |t|
4
+ t.integer "mail_campaign_id"
5
+ t.string "from"
6
+ t.string "to"
7
+ t.string "subject"
8
+ t.text "body_html"
9
+ t.integer "retries"
10
+ t.datetime "last_retry_at"
11
+ t.string "last_error"
12
+ t.datetime "sent_at"
13
+ t.integer "status"
5
14
  t.datetime "created_at"
6
15
  t.datetime "updated_at"
16
+ t.text "body_text"
17
+ t.boolean "opened", :default => false, :null => false
18
+ t.string "key"
7
19
  end
8
20
 
9
- create_table "mail_campaigns", :force => true do |t|
21
+ add_index "finished_mails", ["key"], :name => "index_finished_mails_on_key", :unique => true
22
+ add_index "finished_mails", ["mail_campaign_id", "status"], :name => "index_finished_mails_on_mail_campain_id_and_status"
23
+ add_index "finished_mails", ["to", "mail_campaign_id"], :name => "index_finished_mails_on_to_and_mail_campaign_id"
24
+
25
+ create_table "mail_attachments", :force => :cascade do |t|
26
+ t.string "filename", :null => false
27
+ t.string "path", :limit => 2048
28
+ t.datetime "created_at"
29
+ t.datetime "updated_at"
30
+ t.integer "mail_template_id"
31
+ end
32
+
33
+ add_index "mail_attachments", ["mail_template_id"], :name => "index_mail_attachments_on_mail_template_id"
34
+
35
+ create_table "mail_campaigns", :force => :cascade do |t|
10
36
  t.integer "mailing_list_id"
11
- t.string "from"
12
- t.string "subject"
13
- t.text "body_html"
14
37
  t.integer "unsubscribe_methods"
15
38
  t.datetime "created_at"
16
39
  t.datetime "updated_at"
17
- t.text "body_text"
18
40
  t.integer "sent_mails_count", :default => 0, :null => false
19
41
  t.integer "opened_mails_count", :default => 0, :null => false
20
42
  end
43
+
21
44
  add_index "mail_campaigns", ["mailing_list_id"], :name => "index_mail_campaigns_on_mailing_list_id"
22
45
 
23
- create_table "queued_mails", :force => true do |t|
46
+ create_table "mail_keys", :force => :cascade do |t|
47
+ t.string "email"
48
+ t.string "key"
49
+ t.datetime "created_at"
50
+ t.datetime "updated_at"
51
+ end
52
+
53
+ add_index "mail_keys", ["email"], :name => "index_mail_keys_on_email", :unique => true
54
+ add_index "mail_keys", ["key"], :name => "index_mail_keys_on_key", :unique => true
55
+
56
+ create_table "mail_templates", :force => :cascade do |t|
24
57
  t.integer "mail_campaign_id"
25
- t.string "to"
26
- t.integer "retries", :default => 0, :null => false
27
- t.datetime "last_retry_at"
28
- t.string "last_error"
29
- t.boolean "locked", :default => false, :null => false
30
- t.datetime "locked_at"
58
+ t.integer "queued_mail_id"
59
+ t.string "from"
60
+ t.string "subject"
61
+ t.text "body_html"
62
+ t.text "body_text"
31
63
  t.datetime "created_at"
32
64
  t.datetime "updated_at"
33
- t.string "key"
34
65
  end
35
- add_index "queued_mails", ["mail_campaign_id", "to"], :name => "index_queued_mails_on_mail_campain_id_and_to", :unique => true
36
- add_index "queued_mails", ["retries", "locked"], :name => "index_queued_mails_on_retries_and_locked"
37
- add_index "queued_mails", ["locked", "retries", "id"], :name => "index_queued_mails_on_locked_retries_and_id"
38
- add_index "queued_mails", ["locked", "locked_at"], :name => "index_queued_mails_on_locked_and_locked_at"
39
66
 
40
- create_table "mail_campaign_attachments", :force => true do |t|
41
- t.integer "mail_campaign_id", :null => false
42
- t.string "filename", :null => false
43
- t.string "path", :limit => 2048
67
+ add_index "mail_templates", ["mail_campaign_id"], :name => "index_mail_templates_on_mail_campaign_id"
68
+ add_index "mail_templates", ["queued_mail_id"], :name => "index_mail_templates_on_queued_mail_id"
69
+
70
+ create_table "mailing_lists", :force => :cascade do |t|
71
+ t.string "name"
44
72
  t.datetime "created_at"
45
73
  t.datetime "updated_at"
46
74
  end
47
- add_index "mail_campaign_attachments", "mail_campaign_id"
48
75
 
49
- create_table "finished_mails", :force => true do |t|
76
+ create_table "queued_mails", :force => :cascade do |t|
50
77
  t.integer "mail_campaign_id"
51
- t.string "from"
52
78
  t.string "to"
53
- t.string "subject"
54
- t.text "body_html"
55
- t.integer "retries"
79
+ t.integer "retries", :default => 0, :null => false
56
80
  t.datetime "last_retry_at"
57
81
  t.string "last_error"
58
- t.datetime "sent_at"
59
- t.integer "status"
82
+ t.boolean "locked", :default => false, :null => false
83
+ t.datetime "locked_at"
60
84
  t.datetime "created_at"
61
85
  t.datetime "updated_at"
62
- t.text "body_text"
63
- t.boolean "opened", :default => false, :null => false
64
86
  t.string "key"
87
+ t.boolean "require_uniqueness", :default => true
65
88
  end
66
- add_index "finished_mails", ["key"], :name => "index_finished_mails_on_key", :unique => true
67
- add_index "finished_mails", ["mail_campaign_id", "status"], :name => "index_finished_mails_on_mail_campain_id_and_status"
68
- add_index "finished_mails", ["to", "mail_campaign_id"], :name => "index_finished_mails_on_to_and_mail_campaign_id"
69
89
 
70
- create_table "mail_keys", :force => true do |t|
71
- t.string "email"
72
- t.string "key"
73
- t.datetime "created_at"
74
- t.datetime "updated_at"
75
- end
76
- add_index "mail_keys", ["email"], :name => "index_mail_keys_on_email", :unique => true
77
- add_index "mail_keys", ["key"], :name => "index_mail_keys_on_key", :unique => true
90
+ add_index "queued_mails", ["locked", "locked_at"], :name => "index_queued_mails_on_locked_and_locked_at"
91
+ add_index "queued_mails", ["locked", "retries", "id"], :name => "index_queued_mails_on_locked_retries_and_id"
92
+ add_index "queued_mails", ["mail_campaign_id", "to", "require_uniqueness"], :name => "index_queued_mails_uniqueness_for_to", :unique => true
93
+ add_index "queued_mails", ["retries", "locked"], :name => "index_queued_mails_on_retries_and_locked"
78
94
 
79
- create_table "smailer_properties", :force => true do |t|
95
+ create_table "smailer_properties", :force => :cascade do |t|
80
96
  t.string "name"
81
97
  t.text "value"
82
98
  t.datetime "created_at"
83
99
  t.datetime "updated_at"
84
100
  t.string "notes"
85
101
  end
102
+
86
103
  add_index "smailer_properties", ["name"], :name => "index_smailer_properties_on_name", :unique => true
87
104
  end
88
105
 
@@ -91,8 +108,9 @@ class CreateSmailerTables < ActiveRecord::Migration
91
108
  drop_table :mail_keys
92
109
  drop_table :finished_mails
93
110
  drop_table :queued_mails
94
- drop_table :mail_campaign_attachments
111
+ drop_table :mail_attachments
95
112
  drop_table :mail_campaigns
113
+ drop_table :mail_templates
96
114
  drop_table :mailing_lists
97
115
  end
98
- end
116
+ end
@@ -1,88 +1,105 @@
1
1
  class CreateSmailerTables < ActiveRecord::Migration
2
2
  def self.up
3
- create_table "mailing_lists", :force => true do |t|
4
- t.string "name"
3
+ create_table "finished_mails", :force => :cascade do |t|
4
+ t.integer "mail_campaign_id"
5
+ t.string "from"
6
+ t.string "to"
7
+ t.string "subject"
8
+ t.text "body_html"
9
+ t.integer "retries"
10
+ t.datetime "last_retry_at"
11
+ t.string "last_error"
12
+ t.datetime "sent_at"
13
+ t.integer "status"
5
14
  t.datetime "created_at"
6
15
  t.datetime "updated_at"
16
+ t.text "body_text"
17
+ t.boolean "opened", :default => false, :null => false
18
+ t.string "key"
7
19
  end
8
20
 
9
- create_table "mail_campaigns", :force => true do |t|
21
+ add_index "finished_mails", ["key"], :name => "index_finished_mails_on_key", :unique => true
22
+ add_index "finished_mails", ["mail_campaign_id", "status"], :name => "index_finished_mails_on_mail_campain_id_and_status"
23
+ add_index "finished_mails", ["to", "mail_campaign_id"], :name => "index_finished_mails_on_to_and_mail_campaign_id"
24
+
25
+ create_table "mail_attachments", :force => :cascade do |t|
26
+ t.string "filename", :null => false
27
+ t.string "path", :limit => 2048
28
+ t.datetime "created_at"
29
+ t.datetime "updated_at"
30
+ t.integer "mail_template_id"
31
+ end
32
+
33
+ add_index "mail_attachments", ["mail_template_id"], :name => "index_mail_attachments_on_mail_template_id"
34
+
35
+ create_table "mail_campaigns", :force => :cascade do |t|
10
36
  t.integer "mailing_list_id"
11
- t.string "from"
12
- t.string "subject"
13
- t.text "body_html"
14
37
  t.integer "unsubscribe_methods"
15
38
  t.datetime "created_at"
16
39
  t.datetime "updated_at"
17
- t.text "body_text"
18
40
  t.integer "sent_mails_count", :default => 0, :null => false
19
41
  t.integer "opened_mails_count", :default => 0, :null => false
20
42
  end
43
+
21
44
  add_index "mail_campaigns", ["mailing_list_id"], :name => "index_mail_campaigns_on_mailing_list_id"
22
45
 
23
- create_table "queued_mails", :force => true do |t|
46
+ create_table "mail_keys", :force => :cascade do |t|
47
+ t.string "email"
48
+ t.string "key"
49
+ t.datetime "created_at"
50
+ t.datetime "updated_at"
51
+ end
52
+
53
+ add_index "mail_keys", ["email"], :name => "index_mail_keys_on_email", :unique => true
54
+ add_index "mail_keys", ["key"], :name => "index_mail_keys_on_key", :unique => true
55
+
56
+ create_table "mail_templates", :force => :cascade do |t|
24
57
  t.integer "mail_campaign_id"
25
- t.string "to"
26
- t.integer "retries", :default => 0, :null => false
27
- t.datetime "last_retry_at"
28
- t.string "last_error"
29
- t.boolean "locked", :default => false, :null => false
30
- t.datetime "locked_at"
58
+ t.integer "queued_mail_id"
59
+ t.string "from"
60
+ t.string "subject"
61
+ t.text "body_html"
62
+ t.text "body_text"
31
63
  t.datetime "created_at"
32
64
  t.datetime "updated_at"
33
- t.string "key"
34
65
  end
35
- add_index "queued_mails", ["mail_campaign_id", "to"], :name => "index_queued_mails_on_mail_campain_id_and_to", :unique => true
36
- add_index "queued_mails", ["retries", "locked"], :name => "index_queued_mails_on_retries_and_locked"
37
- add_index "queued_mails", ["locked", "retries", "id"], :name => "index_queued_mails_on_locked_retries_and_id"
38
- add_index "queued_mails", ["locked", "locked_at"], :name => "index_queued_mails_on_locked_and_locked_at"
39
66
 
40
- create_table "mail_campaign_attachments", :force => true do |t|
41
- t.integer "mail_campaign_id", :null => false
42
- t.string "filename", :null => false
43
- t.string "path", :limit => 2048
67
+ add_index "mail_templates", ["mail_campaign_id"], :name => "index_mail_templates_on_mail_campaign_id"
68
+ add_index "mail_templates", ["queued_mail_id"], :name => "index_mail_templates_on_queued_mail_id"
69
+
70
+ create_table "mailing_lists", :force => :cascade do |t|
71
+ t.string "name"
44
72
  t.datetime "created_at"
45
73
  t.datetime "updated_at"
46
74
  end
47
- add_index "mail_campaign_attachments", "mail_campaign_id"
48
75
 
49
- create_table "finished_mails", :force => true do |t|
76
+ create_table "queued_mails", :force => :cascade do |t|
50
77
  t.integer "mail_campaign_id"
51
- t.string "from"
52
78
  t.string "to"
53
- t.string "subject"
54
- t.text "body_html"
55
- t.integer "retries"
79
+ t.integer "retries", :default => 0, :null => false
56
80
  t.datetime "last_retry_at"
57
81
  t.string "last_error"
58
- t.datetime "sent_at"
59
- t.integer "status"
82
+ t.boolean "locked", :default => false, :null => false
83
+ t.datetime "locked_at"
60
84
  t.datetime "created_at"
61
85
  t.datetime "updated_at"
62
- t.text "body_text"
63
- t.boolean "opened", :default => false, :null => false
64
86
  t.string "key"
87
+ t.boolean "require_uniqueness", :default => true
65
88
  end
66
- add_index "finished_mails", ["key"], :name => "index_finished_mails_on_key", :unique => true
67
- add_index "finished_mails", ["mail_campaign_id", "status"], :name => "index_finished_mails_on_mail_campain_id_and_status"
68
- add_index "finished_mails", ["to", "mail_campaign_id"], :name => "index_finished_mails_on_to_and_mail_campaign_id"
69
89
 
70
- create_table "mail_keys", :force => true do |t|
71
- t.string "email"
72
- t.string "key"
73
- t.datetime "created_at"
74
- t.datetime "updated_at"
75
- end
76
- add_index "mail_keys", ["email"], :name => "index_mail_keys_on_email", :unique => true
77
- add_index "mail_keys", ["key"], :name => "index_mail_keys_on_key", :unique => true
90
+ add_index "queued_mails", ["locked", "locked_at"], :name => "index_queued_mails_on_locked_and_locked_at"
91
+ add_index "queued_mails", ["locked", "retries", "id"], :name => "index_queued_mails_on_locked_retries_and_id"
92
+ add_index "queued_mails", ["mail_campaign_id", "to", "require_uniqueness"], :name => "index_queued_mails_uniqueness_for_to", :unique => true
93
+ add_index "queued_mails", ["retries", "locked"], :name => "index_queued_mails_on_retries_and_locked"
78
94
 
79
- create_table "smailer_properties", :force => true do |t|
95
+ create_table "smailer_properties", :force => :cascade do |t|
80
96
  t.string "name"
81
97
  t.text "value"
82
98
  t.datetime "created_at"
83
99
  t.datetime "updated_at"
84
100
  t.string "notes"
85
101
  end
102
+
86
103
  add_index "smailer_properties", ["name"], :name => "index_smailer_properties_on_name", :unique => true
87
104
  end
88
105
 
@@ -91,8 +108,9 @@ class CreateSmailerTables < ActiveRecord::Migration
91
108
  drop_table :mail_keys
92
109
  drop_table :finished_mails
93
110
  drop_table :queued_mails
94
- drop_table :mail_campaign_attachments
111
+ drop_table :mail_attachments
95
112
  drop_table :mail_campaigns
113
+ drop_table :mail_templates
96
114
  drop_table :mailing_lists
97
115
  end
98
- end
116
+ end
@@ -1,11 +1,12 @@
1
1
  module Smailer
2
2
  module Models
3
3
  autoload :MailingList, 'smailer/models/mailing_list'
4
+ autoload :MailTemplate, 'smailer/models/mail_template'
4
5
  autoload :MailCampaign, 'smailer/models/mail_campaign'
5
- autoload :MailCampaignAttachment, 'smailer/models/mail_campaign_attachment'
6
+ autoload :MailAttachment, 'smailer/models/mail_attachment'
6
7
  autoload :MailKey, 'smailer/models/mail_key'
7
8
  autoload :QueuedMail, 'smailer/models/queued_mail'
8
9
  autoload :FinishedMail, 'smailer/models/finished_mail'
9
10
  autoload :Property, 'smailer/models/property'
10
11
  end
11
- end
12
+ end
@@ -2,18 +2,16 @@ require 'open-uri'
2
2
 
3
3
  module Smailer
4
4
  module Models
5
- class MailCampaignAttachment < ActiveRecord::Base
5
+ class MailAttachment < ActiveRecord::Base
6
+ belongs_to :mail_template, :inverse_of => :attachments
6
7
 
7
- belongs_to :mail_campaign
8
- validates_presence_of :mail_campaign_id
9
- validates_numericality_of :mail_campaign_id
10
8
  validates_presence_of :path
11
9
  validates_presence_of :filename
10
+ validates_presence_of :mail_template
12
11
 
13
12
  def body
14
13
  open(self.path).read
15
14
  end
16
-
17
15
  end
18
16
  end
19
17
  end
@@ -10,8 +10,11 @@ module Smailer
10
10
  belongs_to :mailing_list
11
11
  has_many :queued_mails, :dependent => :destroy
12
12
  has_many :finished_mails, :dependent => :destroy
13
- has_many :attachments,
14
- :class_name => '::Smailer::Models::MailCampaignAttachment'
13
+
14
+ has_one :mail_template, :dependent => :destroy, :autosave => true, :inverse_of => :mail_campaign
15
+
16
+ delegate :from, :subject, :body_html, :body_text, :to => :my_mail_template, :allow_nil => true
17
+ delegate :from=, :subject=, :body_html=, :body_text=, :to => :my_mail_template
15
18
 
16
19
  validates_presence_of :mailing_list_id, :from
17
20
  validates_numericality_of :mailing_list_id, :unsubscribe_methods, :only_integer => true, :allow_nil => true
@@ -54,8 +57,12 @@ module Smailer
54
57
  opened_mails_count.to_f / sent_mails_count
55
58
  end
56
59
 
60
+ def attachments
61
+ my_mail_template.attachments
62
+ end
63
+
57
64
  def add_attachment(filename, path)
58
- self.attachments.create!(:filename => filename, :path => path)
65
+ my_mail_template.attachments.build(:filename => filename, :path => path)
59
66
  end
60
67
 
61
68
  def self.unsubscribe_methods
@@ -69,6 +76,10 @@ module Smailer
69
76
 
70
77
  private
71
78
 
79
+ def my_mail_template
80
+ mail_template || build_mail_template
81
+ end
82
+
72
83
  def unsubscribe_methods_list_from(method_specification)
73
84
  if method_specification == :all
74
85
  self.class.unsubscribe_methods.keys
@@ -78,4 +89,4 @@ module Smailer
78
89
  end
79
90
  end
80
91
  end
81
- end
92
+ end
@@ -0,0 +1,13 @@
1
+ module Smailer
2
+ module Models
3
+ class MailTemplate < ActiveRecord::Base
4
+ belongs_to :mail_campaign, :inverse_of => :mail_template
5
+ belongs_to :queued_mail, :inverse_of => :mail_template
6
+
7
+ has_many :attachments, :class_name => '::Smailer::Models::MailAttachment', :autosave => true, :inverse_of => :mail_template
8
+
9
+ validates_presence_of :from
10
+ validates_length_of :from, :subject, :maximum => 255, :allow_nil => true
11
+ end
12
+ end
13
+ end
@@ -1,31 +1,39 @@
1
1
  require 'digest/md5'
2
+ require 'securerandom'
2
3
 
3
4
  module Smailer
4
5
  module Models
5
6
  class QueuedMail < ActiveRecord::Base
6
7
  belongs_to :mail_campaign
7
8
 
9
+ has_one :mail_template, :dependent => :destroy, :autosave => true, :inverse_of => :queued_mail
10
+ has_many :attachments, :through => :mail_template
11
+
8
12
  validates_presence_of :mail_campaign_id, :to
9
- validates_uniqueness_of :to, :scope => :mail_campaign_id
13
+ validates_uniqueness_of :to, :scope => :mail_campaign_id, :if => proc { |queued_mail| queued_mail.require_uniqueness }
10
14
  validates_uniqueness_of :key
11
15
  validates_numericality_of :mail_campaign_id, :retries, :only_integer => true, :allow_nil => true
12
16
  validates_length_of :to, :last_error, :maximum => 255, :allow_nil => true
13
17
 
14
18
  unless Smailer::Compatibility.rails_4?
15
- attr_accessible :mail_campaign_id, :to
19
+ attr_accessible :mail_campaign_id, :to, :from, :subject, :body_html, :body_text, :require_uniqueness
16
20
  end
17
21
 
18
- delegate :from, :subject, :mailing_list, :to => :mail_campaign, :allow_nil => true
19
-
20
22
  before_validation :initialize_message_key
21
23
  before_save :initialize_message_key
22
24
 
25
+ before_save :nullify_false_require_uniqueness
26
+
27
+ delegate :mailing_list, :to => :mail_campaign, :allow_nil => true
28
+ delegate :from, :subject, :to => :active_mail_template, :allow_nil => true
29
+ delegate :from=, :subject=, :body_html=, :body_text, :to => :my_mail_template
30
+
23
31
  def body_html
24
- interpolate mail_campaign.body_html
32
+ interpolate active_mail_template.body_html
25
33
  end
26
34
 
27
35
  def body_text
28
- interpolate mail_campaign.body_text
36
+ interpolate active_mail_template.body_text
29
37
  end
30
38
 
31
39
  def key
@@ -33,10 +41,39 @@ module Smailer
33
41
  self[:key]
34
42
  end
35
43
 
44
+ def attachments
45
+ active_mail_template.attachments
46
+ end
47
+
48
+ def add_attachment(filename, path)
49
+ my_mail_template.attachments.build(:filename => filename, :path => path)
50
+ end
51
+
36
52
  protected
37
53
 
54
+ def active_mail_template
55
+ mail_template || mail_campaign.try(:mail_template)
56
+ end
57
+
58
+ def my_mail_template
59
+ return mail_template if mail_template.present?
60
+
61
+ build_mail_template.tap do |template|
62
+ if mail_campaign.present?
63
+ campaign_template = mail_campaign.mail_template
64
+
65
+ template.from = campaign_template.from
66
+ template.subject = campaign_template.subject
67
+ template.body_html = campaign_template.body_html
68
+ template.body_text = campaign_template.body_text
69
+
70
+ template.attachments = campaign_template.attachments.map(&:dup)
71
+ end
72
+ end
73
+ end
74
+
38
75
  def initialize_message_key
39
- self.key = Digest::MD5.hexdigest("#{mail_campaign_id}, #{to} and #{id} compose this key.")
76
+ self.key = Digest::MD5.hexdigest("#{mail_campaign_id}, #{to}, #{SecureRandom.hex(15)} and #{id} compose this key.")
40
77
  end
41
78
 
42
79
  def interpolate(text)
@@ -57,6 +94,13 @@ module Smailer
57
94
 
58
95
  text
59
96
  end
97
+
98
+ # Prevents the unique index in the database from firing
99
+ def nullify_false_require_uniqueness
100
+ unless self.require_uniqueness
101
+ self.require_uniqueness = nil
102
+ end
103
+ end
60
104
  end
61
105
  end
62
106
  end