/
issue.rb
186 lines (148 loc) · 3.43 KB
/
issue.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
require 'uri'
class Adva::Issue < ActiveRecord::Base
set_table_name "adva_issues"
belongs_to :newsletter, :counter_cache => true, :class_name => "Adva::Newsletter"
has_one :cronjob, :as => :cronable, :class_name => "Adva::Cronjob"
attr_accessible :title, :body, :body_plain, :filter, :draft, :deliver_at
validates_presence_of :title, :body, :newsletter_id
named_scope :all_included, :include => :newsletter
filtered_column :body
filters_attributes :except => [:body, :body_html]
is_paranoid
def owners
owner.owners << owner
end
def owner
newsletter
end
# public api
def deliver(options = {})
options.assert_valid_keys(:later_at,:to)
deliver_datetime = options[:later_at]
user = options[:to]
if user.nil?
deliver_all(deliver_datetime)
else
deliver_to(user)
end
end
def cancel_delivery
return false unless queued?
published_state!
end
def editable?
!new_record? && (draft? || published?)
end
# attributes
def email
newsletter.email
end
def email_with_name
newsletter.email_with_name
end
# state management
def draft_state!
return nil unless published?
self.state = "draft"
self.published_at = nil
end
def draft=(value)
case value.to_i
when 0
published_state!
when 1
draft_state!
end
end
def published_state!
return nil unless (draft? || queued?)
if queued?
cronjob.destroy if cronjob
reload
end
self.state = "hold" # state should be "published", but it does not make sence with newsletter issue
self.published_at = DateTime.now
save
end
def queued_state!
return nil unless published?
self.state = "queued"
self.queued_at = DateTime.now
save
end
def delivered_state!
return nil unless queued?
self.state = "delivered"
self.delivered_at = DateTime.now
save
end
# state status
def draft?
state == "draft"
end
def draft
published? ? 0 : 1
end
def published?
["hold", "published"].include?(state)
end
def queued?
state == "queued"
end
def delivered?
state == "delivered"
end
def state_time
case state
when "draft"
updated_at
when "hold"
published_at
when "queued"
queued_at
when "delivered"
delivered_at
end
end
# delivery
def deliver_all(datetime = nil)
return nil unless published?
if datetime.nil?
self.deliver_at = (Time.zone.now + 3.minutes)
else
update_attributes(datetime)
end
if save
cronjob = self.build_cronjob :command => "Adva::Issue.find(#{self.id}).create_emails", :due_at => deliver_at
queued_state! if cronjob.save
end
end
def deliver_to(user)
Adva::NewsletterMailer.deliver_issue(self,user)
end
def create_emails
delivered_state!
if newsletter.subscriptions.present?
newsletter.users.each do |user|
create_email_to(user)
end
Adva::Email.start_delivery
end
end
def create_email_to(user)
issue = Adva::NewsletterMailer.create_issue(self,user)
Adva::Email.create(:from => self.newsletter.email,
:to => user.email,
:mail => issue.to_s)
end
def images
@images ||= Adva::IssueImage.parse(body_html)
end
def body_mail
body = body_html.dup
images.each do |image|
body.sub!(image.uri, "cid:#{image.cid_plain}")
end
body
end
end