app/models/mail_manager/mailer.rb in mail_manager-3.0.0 vs app/models/mail_manager/mailer.rb in mail_manager-3.2.0

- old
+ new

@@ -10,41 +10,54 @@ test_mailing - sends a test message for a mailing mail - knows how to send any message based on the different "mime" parts its given =end -require 'net/http' -require 'uri' +require 'open-uri' require "base64" begin require "mini_magick" rescue => e + # :nocov: require 'rmagick' rescue nil + # :nocov: end module MailManager class Mailer < ActionMailer::Base - def unsubscribed(message,subscriptions) - @contact = message.contact - @recipients = @contact.email_address - @from = message.from_email_address - @message = message + # send a confirmation email for unsubscribing + def unsubscribed(subscriptions,email_address,contact=nil,message=nil) + @contact = contact + @email_address = email_address + @recipients = @email_address + @from = message.try(:from_email_address) || MailManager.default_from_email_address @mailing_lists = subscriptions.reject{|subscription| subscription.mailing_list.nil?}. collect{|subscription| subscription.mailing_list.name} @subject = "Unsubscribed from #{@mailing_lists.join(',')} at #{MailManager.site_url}" - Rails.logger.debug "Really Sending Unsubscribed from #{@mailing_lists.first} to #{@contact.email_address}" + Rails.logger.debug "Really Sending Unsubscribed from #{@mailing_lists.first} to #{@email_address}" mail(to: @recipients, from: @from, subject: @subject) end - # we do special junk ... so lets make them class methods + def double_opt_in(contact) + @contact = contact + @recipients = @contact.email_address + @subject = "Confirm Newsletter Subscription at #{::MailManager.site_url}" + @from = ::MailManager.signup_email_address + @mailing_list_names = contact.subscriptions.map(&:mailing_list).map(&:name).join(', ') + @headers = {'Return-Path' => ::MailManager.bounce['email_address']} + mail(to: @recipients, from: @from, subject: @subject) + end + class << self + # send a mailing related to the message's data def deliver_message(message) self.send_mail(message.subject,message.email_address_with_name,message.from_email_address, message.parts,message.guid,message.mailing.include_images?) end + # create mailing; parsing html sources for images to attach/include def multipart_with_inline_images(subject,to_email_address,from_email_address,the_parts,message_id=nil,include_images=true) text_source = the_parts.first[1];nil original_html_source = the_parts.last[1];nil mail = Mail.new do to to_email_address @@ -70,10 +83,11 @@ end end mail end + # create mailing without fetching image data def multipart_alternative_without_images(subject,to_email_address,from_email_address,the_parts,message_id=nil,include_images=true) text_source = the_parts.first[1];nil original_html_source = the_parts.last[1];nil mail = Mail.new do to to_email_address @@ -90,10 +104,11 @@ end end mail end + # send the mailing with the given subject, addresses, and parts def send_mail(subject,to_email_address,from_email_address,the_parts,message_id=nil,include_images=true) include_images = (include_images and !MailManager.dont_include_images_domains.detect{|domain| to_email_address.strip =~ /#{domain}>?$/}) mail = if include_images multipart_with_inline_images(subject,to_email_address,from_email_address,the_parts,message_id,include_images) @@ -106,12 +121,15 @@ mail.deliver! Rails.logger.info "Sent mail to: #{to_email_address}" Rails.logger.debug mail.to_s end + # set mail delivery settings def set_mail_settings(mail) - mail.delivery_method ActionMailer::Base.delivery_method.eql?(:letter_opener) ? :test : ActionMailer::Base.delivery_method + delivery_method = ActionMailer::Base.delivery_method + delivery_method = delivery_method.eql?(:letter_opener) ? :test : delivery_method + mail.delivery_method delivery_method # letter opener blows up! # Ex set options! # mail.delivery_method.settings.merge!( { # user_name: 'bobo', # password: 'Secret1!', @@ -121,29 +139,24 @@ # authentication: :plain, # port: 587 # } ) mail.delivery_method.settings.merge!( - (case method + (case delivery_method when :smtp then ActionMailer::Base.smtp_settings + # :nocov: when :sendmail then ActionMailer::Base.sendmail_settings + # :nocov: else {} end rescue {}) ) end - def inline_attachment(params, &block) - params = { :content_type => params } if String === params - params = { :disposition => "inline", - :transfer_encoding => "base64" }.merge(params) - params[:headers] ||= {} - params[:headers]['Content-ID'] = params[:cid] - params - end - + # return mime type for images by extension def image_mime_types(extension) + # :nocov: case extension.downcase when 'bmp' then 'image/bmp' when 'cod' then 'image/cis-cod' when 'gif' then 'image/gif' when 'ief' then 'image/ief' @@ -154,24 +167,34 @@ when 'jfif' then 'image/pipeg' when 'svg' then 'image/svg+xml' when 'tif' then 'image/tiff' when 'tiff' then 'image/tiff' end + # :nocov: end + # find the extension for images by inspecting their data def get_extension_from_data(image_data) if defined?(MiniMagick) - MiniMagick::Image.read(image_data)[:format] || '' + format = '' + file = Tempfile.new('get-extension','tmp') + file.close + File.open(file.path,'wb'){|binfile| binfile.write(image_data)} + MiniMagick::Image.open(file.path)[:format] || '' elsif defined?(Magick) + # :nocov: currently on ly mini_magick is tested Magick::Image.from_blob(image_data).first.format || '' + # :nocov: else '' end rescue => e '' end + + # parses html and retrieves images and inserts them with CID/attachments def inline_html_with_images(html_source) parsed_data = html_source.split(/(<\s*img[^>]+src\s*=\s*["'])([^"']*)(["'])/i) images = Array.new final_html = '' image_errors = '' @@ -198,75 +221,19 @@ final_html << data end end raise image_errors unless image_errors.eql?('') [final_html,images] - # related_part = Mail::Part.new do - # body final_html - # end - # images.each do |image| - # related_part.part inline_attachment(image) - # end - # related_part.content_type = 'multipart/related' - # related_part - - # related_part = Mail::Part.new do - # content_type 'multipart/related' - # # content_type 'text/html; charset=UTF-8' - # # body final_html - # end - # related_part.parts << Mail::Part.new do - # content_type 'text/html; charset=UTF-8' - # body final_html - # end - # images.each do |image| - # related_part.attachments[image[:filename]] = image[:body] - # end - # related_part.content_type = 'multipart/related' - # related_part.parts.first.content_type = 'text/html; charset=UTF-8' - # related_part.parts.first.header['Content-Disposition'] = 'inline' - end - def local_ips - `/sbin/ifconfig` - end - - def request_local?(uri_str) - uri = URI.parse(uri_str) - ip_address = `host #{uri.host}`.gsub(/.*has address ([\d\.]+)\s.*/m,"\\1") - local_ips.include?(ip_address) - rescue => e - false - end - + # fetch the data from a url (used for images) def fetch(uri_str, limit = 10) - # You should choose better exception. - raise ArgumentError, 'HTTP redirect too deep' if limit == 0 uri = URI.parse(uri_str) - request = Net::HTTP::Get.new("#{uri.path}#{"?"+uri.query if uri.query.to_s.strip != ''}") - - response = Net::HTTP.start( - uri.host, uri.port, - :use_ssl => uri.scheme == 'https', - :verify_mode => OpenSSL::SSL::VERIFY_NONE) do |https| - https.request(request) - end - case response - when Net::HTTPSuccess then response.body - when Net::HTTPRedirection then fetch(response['location'], limit - 1) + if uri.scheme.eql?('file') + File.binread(uri_str.gsub(%r#^file://#,'')) else - response.error! + uri.read end - # CURB version - gem wouldn't install anymore on CentOS - # body = '' - # Curl.get(uri_str) do |http| - # http.follow_location = true - # http.interface = '127.0.0.1' if request_local?(uri_str) - # http.on_success{|response| body = response.body} - # end - # raise Exception.new("Couldn't fetch URL: #{uri_str}") unless body.present? - # body end end end end