Class: MailEngine::MailSchedule
- Inherits:
-
ActiveRecord::Base
- Object
- ActiveRecord::Base
- MailEngine::MailSchedule
- Defined in:
- app/models/mail_engine/mail_schedule.rb
Constant Summary collapse
- PERIOD_TO_UNIT_TABLE =
{ "daily" => ["day", 1], "weekly" => ["week", 7], "monthly" => ["month", 30], "yearly" => ["year", 365] }
Class Method Summary collapse
-
.future_schedules(schedule_count = 5) ⇒ Object
will return an array like.
Instance Method Summary collapse
-
#last_schedule_time ⇒ Object
if a weekly schedule, first send at last monday, and today is tuesday, so the last schedule time should be this monday if a weekly schedule, first send at next monday, and today is tuesday, so the last schedule time should be the first_send_at.
-
#load_payload(user) ⇒ Object
load user info into payload hash used at mail template.
-
#logs(count = 10) ⇒ Object
list mail log with the same mail_template_path to current mail_template’s path.
-
#next_several_schedule_dates(schedule_count = 5) ⇒ Object
FIXME monthly will has some problem due to each month is not exact 30 days.
-
#ready_to_send? ⇒ Boolean
If execute sendmail twice very soon(within 14 minutes), it should not be able to send mail again.
-
#send_test_mail_to!(recipient, sample_user_id) ⇒ Object
send test mail to specific recipient email address, with loading sample_user’s data.
-
#sendmail ⇒ Object
used in Rake task, the main mail sending method.
Class Method Details
.future_schedules(schedule_count = 5) ⇒ Object
will return an array like
[
[MailSchedule#xxx, 2010-01-01 20:15],
[MailSchedule#xxx, 2010-01-01 20:15]
]
42 43 44 45 46 47 48 49 50 51 |
# File 'app/models/mail_engine/mail_schedule.rb', line 42 def self.future_schedules(schedule_count = 5) schedule_count = 5 if schedule_count < 5 all_future_schedules = [] MailEngine::MailSchedule.available.all.each do |schedule| next_schedules = [schedule].product(schedule.next_several_schedule_dates(schedule_count)) all_future_schedules += next_schedules if next_schedules.present? end # sort by date all_future_schedules.sort{|x,y| x[1] <=> y[1]}.slice(1..schedule_count) end |
Instance Method Details
#last_schedule_time ⇒ Object
if a weekly schedule, first send at last monday, and today is tuesday, so the last schedule time should be this monday if a weekly schedule, first send at next monday, and today is tuesday, so the last schedule time should be the first_send_at
77 78 79 80 81 82 83 84 85 86 87 |
# File 'app/models/mail_engine/mail_schedule.rb', line 77 def last_schedule_time period_unit = PERIOD_TO_UNIT_TABLE[period].first period_days = PERIOD_TO_UNIT_TABLE[period].last if first_send_at.past? days_past = ((Time.now - first_send_at)/(3600*24)).round periods_past = days_past / period_days first_send_at + periods_past * 1.send(period_unit) else first_send_at end end |
#load_payload(user) ⇒ Object
load user info into payload hash used at mail template.
95 96 97 98 99 100 101 |
# File 'app/models/mail_engine/mail_schedule.rb', line 95 def load_payload user payload_hash = {} self.payload.split(",").each do |col| payload_hash[col] = user.send(col) end payload_hash end |
#logs(count = 10) ⇒ Object
list mail log with the same mail_template_path to current mail_template’s path
90 91 92 |
# File 'app/models/mail_engine/mail_schedule.rb', line 90 def logs(count = 10) MailEngine::MailLog.where(:mail_template_path => self.mail_template.actual_path).order("id desc").limit(count) end |
#next_several_schedule_dates(schedule_count = 5) ⇒ Object
FIXME monthly will has some problem due to each month is not exact 30 days. this func will return an array of date.
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'app/models/mail_engine/mail_schedule.rb', line 55 def next_several_schedule_dates(schedule_count = 5) # check if send count reached the top limit count. return [] if (sent_count >= count and count != 0) # only send once. if period == 'once' # check if it is still available. if first_send_at > Time.now return [first_send_at] else return [] end end # other periods rest_count = (count == 0 ? schedule_count : count - sent_count) (1..rest_count).map do |i| last_schedule_time + i.send(PERIOD_TO_UNIT_TABLE[period].first) end end |
#ready_to_send? ⇒ Boolean
If execute sendmail twice very soon(within 14 minutes), it should not be able to send mail again.
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 |
# File 'app/models/mail_engine/mail_schedule.rb', line 114 def ready_to_send? # check if send count reached the total count. return false if (sent_count >= count and count != 0) # only send once. return sent_count < 1 if period == 'once' ### ready for first send? # why 15 minutes? because crontab will run each 15 minutes. timespan_since_last_mail = (Time.now.to_i - last_sent_at.to_i).abs timespan_to_first_send_at = (Time.now.to_i - first_send_at.to_i).abs not_sent_mail_within_15_minutes = last_sent_at.nil? || (timespan_since_last_mail >= 60*15) start_first_send_within_15_minutes = (timespan_to_first_send_at < 60*15) # cycle start cycle_start = case period when 'daily' 1.days.ago.to_i <= last_sent_at.to_i when 'weekly' 1.week.ago.to_i <= last_sent_at.to_i when 'monthly' 1.month.ago.to_i <= last_sent_at.to_i else false end not_sent_mail_within_15_minutes and (cycle_start or start_first_send_within_15_minutes) end |
#send_test_mail_to!(recipient, sample_user_id) ⇒ Object
send test mail to specific recipient email address, with loading sample_user’s data.
104 105 106 107 108 109 110 111 |
# File 'app/models/mail_engine/mail_schedule.rb', line 104 def send_test_mail_to!(recipient, sample_user_id) raise "Wrong email format." if recipient.blank? or recipient !~ /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i sample_user = MailEngine::USER_MODEL.find(sample_user_id) I18n.with_locale(mail_template.locale) do MailEngine::MailDispatcher.send( mail_template.template_name.to_sym, :to => recipient, :values => self.load_payload(sample_user) ).deliver end end |
#sendmail ⇒ Object
used in Rake task, the main mail sending method.
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 |
# File 'app/models/mail_engine/mail_schedule.rb', line 142 def sendmail puts "---> Schedule: '#{self.name}'" if Rails.env != 'test' return false unless ready_to_send? # puts "---> not ready" MailEngine::USER_MODEL.send(self.user_group.to_sym).each do |user| puts "-> sending mail to #{user.email}" if Rails.env != 'test' ### FIXME user.email, what if user don't have email column. user_locale = begin user.send(MailEngine::Base.current_config["user_locale_column"]) rescue I18n.default_locale end begin # when there is default_locale been set, should fallback to default_locale template, when can't find the locale user in user settings. if !mail_template.existed_variations.map(&:locale).include?(user_locale) if self.default_locale.present? raise MailEngine::MissingMailTemplate.new("not found template for user locale: #{user_locale}") else raise "skip sending mail since not found correspond locale template." end end I18n.with_locale user_locale do MailEngine::MailDispatcher.send(mail_template.template_name.to_sym, :to => user.email, :values => self.load_payload(user) ).deliver end rescue MailEngine::MissingMailTemplate I18n.with_locale self.default_locale do MailEngine::MailDispatcher.send(mail_template.template_name.to_sym, :to => user.email, :values => self.load_payload(user) ).deliver end rescue # do nothing, just don't sent mail. end end self.update_attributes :last_sent_at => Time.now, :sent_count => self.sent_count + 1 end |