144 lines
4.9 KiB
Ruby
144 lines
4.9 KiB
Ruby
# desc "Explaining what the task does"
|
|
namespace :epaper do
|
|
desc 'Send epaper emails'
|
|
task :send_email, [:paper_criteria_id, :domain, :locale] => :environment do |task,args|
|
|
require 'net/protocol'
|
|
require 'timeout'
|
|
require 'net/smtp'
|
|
require 'openssl'
|
|
paper = PaperCriteria.find(args[:paper_criteria_id]) rescue nil
|
|
page = Page.where(:module => "e_paper").first.url rescue ""
|
|
papers_data = Admin::EpaperHelper.get_paper_data(paper)
|
|
domain = args[:domain]
|
|
if !paper.nil?
|
|
email_format = /^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+$/
|
|
subscribers = EPaperSubscriber.where(:language.in=>paper.language_to_send,:email.nin=>['',nil])
|
|
subscribers.update_all(:last_paper_sent => paper.id.to_s)
|
|
emails = subscribers.collect(&:email)
|
|
site = Site.first
|
|
email_limit_reciever = site[:site_settings][:email_limit_reciever].to_i rescue 0
|
|
mail_limit = email_limit_reciever==0 ? 25 : email_limit_reciever
|
|
emails += paper.other_emails_ids
|
|
emails_valid = emails.select do |email|
|
|
tmp = (email_format=~email)
|
|
tmp==0 ? true : false
|
|
end
|
|
emails_invalid = emails - emails_valid
|
|
paper.send_failed_emails = []
|
|
Thread.new do
|
|
tmp = []
|
|
site = Site.first
|
|
@address = site['site_settings']['address']
|
|
@port = (site['site_settings']['port'].to_i rescue 587)
|
|
@open_timeout = 30
|
|
@read_timeout = 60
|
|
@debug_output = nil
|
|
tls = (site['site_settings']['enable_starttls_auto'] == "1")
|
|
from_addr = site['site_settings']['service_email']
|
|
emails_valid.each_slice(mail_limit).each do |slice_emails|
|
|
invalid_mails = epaper_verify_email(from_addr,slice_emails,tls)
|
|
deliver_emails = slice_emails - invalid_mails
|
|
email = Email.new(:mail_subject => paper.sending_title, :mail_lang => args[:locale], :template => "admin/e_paper_criterias/emailer", :template_data => {"paper_id" => paper.id, "page" => "http://" + domain + page, "siteurl" => "http://" + domain, "papers_data" => papers_data }, :mail_to => deliver_emails)
|
|
begin
|
|
email.save
|
|
email.deliver
|
|
puts "Sending #{deliver_emails.count} emails"
|
|
rescue => e
|
|
puts [deliver_emails.inspect,e,e.backtrace]
|
|
tmp += deliver_emails
|
|
end
|
|
error_flag = 0
|
|
begin
|
|
invalid_mails.each do |invalid_mail|
|
|
email = Email.create(:mail_subject => paper.sending_title, :mail_lang => args[:locale], :template => "admin/e_paper_criterias/emailer", :template_data => {"paper_id" => paper.id, "page" => "http://" + domain + page, "siteurl" => "http://" + domain, "papers_data" => papers_data }, :mail_to => invalid_mail)
|
|
end
|
|
rescue => e
|
|
puts [e,e.backtrace]
|
|
error_flag = 1
|
|
end
|
|
raise "There was something went wrong." if error_flag == 1
|
|
tmp += invalid_mails
|
|
end
|
|
paper.update_attributes(:send_failed_emails => tmp)
|
|
end
|
|
paper.invalid_emails = emails_invalid
|
|
paper.save
|
|
end
|
|
end
|
|
def epaper_verify_email(from_addr,check_emails,tls) #true if check_email is ok
|
|
s = Timeout.timeout(@open_timeout, Net::OpenTimeout) do
|
|
TCPSocket.open(@address, @port)
|
|
end
|
|
@socket = epaper_new_internet_message_io(tls ? epaper_tlsconnect(s) : s)
|
|
res = epaper_get_response("MAIL FROM:<#{from_addr}>")
|
|
invalid_emails = []
|
|
check_list = []
|
|
if check_emails.class == String
|
|
if check_emails.include?(",")
|
|
check_list = check_emails.split(",")
|
|
else
|
|
check_list << check_emails
|
|
end
|
|
else
|
|
check_list = check_emails
|
|
end
|
|
check_list.each do |check_email|
|
|
res1 = epaper_get_response("RCPT TO:<#{check_email}>")
|
|
res2 = epaper_get_response("RCPT TO:<#{check_email}>")
|
|
if !(res1.success? && res2.success?)
|
|
invalid_emails << check_email
|
|
puts [check_email,res1.message,res2.message]
|
|
end
|
|
end
|
|
s.close
|
|
invalid_emails
|
|
end
|
|
def epaper_get_response(reqline)
|
|
res = epaper_critical {
|
|
@socket.writeline reqline
|
|
epaper_recv_response()
|
|
}
|
|
return res
|
|
end
|
|
def epaper_recv_response
|
|
buf = ''
|
|
while true
|
|
line = @socket.readline
|
|
buf << line << "\n"
|
|
break unless line[3,1] == '-' # "210-PIPELINING"
|
|
end
|
|
Net::SMTP::Response.parse(buf)
|
|
end
|
|
def epaper_critical
|
|
return Net::SMTP::Response.parse('200 dummy reply code') if @error_occurred
|
|
begin
|
|
return yield()
|
|
rescue Exception
|
|
@error_occurred = true
|
|
raise
|
|
end
|
|
end
|
|
def epaper_ssl_socket(socket, context)
|
|
OpenSSL::SSL::SSLSocket.new socket, context
|
|
end
|
|
def epaper_tlsconnect(s)
|
|
verified = false
|
|
s = epaper_ssl_socket(s, @ssl_context)
|
|
s.sync_close = true
|
|
s.connect
|
|
if @ssl_context.verify_mode != OpenSSL::SSL::VERIFY_NONE
|
|
s.post_connection_check(@address)
|
|
end
|
|
verified = true
|
|
s
|
|
ensure
|
|
s.close unless verified
|
|
end
|
|
def epaper_new_internet_message_io(s)
|
|
io = Net::InternetMessageIO.new(s)
|
|
io.read_timeout = @read_timeout
|
|
io.debug_output = @debug_output
|
|
io
|
|
end
|
|
end
|
|
|