# 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_sentdate = paper.get_email_sentdate email_format = /^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+$/ subscribers = EPaperSubscriber.where(:language.in=>paper.language_to_send,:email.nin=>['',nil],:subscribed.ne=>false) 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.uniq! emails_valid = emails.select do |email| tmp = (email_format=~email.to_s) tmp==0 ? true : false end emails_invalid = emails - emails_valid paper.send_failed_emails = [] paper.invalid_emails = emails_invalid paper.save Thread.new do tmp = [] site = Site.first if site[:gmail_login_flag] @address = '127.0.0.1' @port = 25 tls = false from_addr = site.gmail else @address = site['site_settings']['address'] @port = (site['site_settings']['port'].to_i rescue 587) tls = (site['site_settings']['enable_starttls_auto'] == "1") from_addr = site['site_settings']['service_email'] end @open_timeout = 10 @read_timeout = 60 @debug_output = nil 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, :module_app_key=>'e_paper', :mail_sentdate=> email_sentdate) begin email.save if email_sentdate puts "Emails will be sent at #{email_sentdate.strftime("%Y-%m-%d %H:%M")}" else email.deliver puts "Sending #{deliver_emails.count} emails: #{deliver_emails}" end 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, :module_app_key=>'e_paper', :mail_sentdate=> email_sentdate) 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 end end def epaper_verify_email(from_addr,check_emails,tls) #true if check_email is ok return [] if @mail_server_broken begin s = Timeout.timeout(@open_timeout, Net::OpenTimeout) do TCPSocket.open(@address, @port) end rescue => e puts [e.to_s, e.backtrace] @mail_server_broken = true 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| begin 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 rescue => e puts e.to_s invalid_emails << check_email 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