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