Class: MailManager::Mailer

Inherits:
ActionMailer::Base
  • Object
show all
Defined in:
app/models/mail_manager/mailer.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.deliver_message(message) ⇒ Object

send a mailing related to the message’s data



53
54
55
56
# File 'app/models/mail_manager/mailer.rb', line 53

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

.fetch(uri_str, limit = 10) ⇒ Object

fetch the data from a url (used for images)



229
230
231
232
233
234
235
236
# File 'app/models/mail_manager/mailer.rb', line 229

def fetch(uri_str, limit = 10)
  uri = URI.parse(uri_str)
  if uri.scheme.eql?('file')
    File.binread(uri_str.gsub(%r#^file://#,''))
  else
    uri.read
  end
end

.get_extension_from_data(image_data) ⇒ Object

find the extension for images by inspecting their data



176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'app/models/mail_manager/mailer.rb', line 176

def get_extension_from_data(image_data)
  if defined?(MiniMagick)
    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

.image_mime_types(extension) ⇒ Object

return mime type for images by extension



156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'app/models/mail_manager/mailer.rb', line 156

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'
    when 'jpe' then 'image/jpeg'
    when 'jpeg' then 'image/jpeg'
    when 'jpg' then 'image/jpeg'
    when 'png' then 'image/png'
    when 'jfif' then 'image/pipeg'
    when 'svg' then 'image/svg+xml'
    when 'tif' then 'image/tiff'
    when 'tiff' then 'image/tiff'
  end
  # :nocov:
end

.inline_html_with_images(html_source) ⇒ Object

parses html and retrieves images and inserts them with CID/attachments



196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
# File 'app/models/mail_manager/mailer.rb', line 196

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 = ''
  parsed_data.each_with_index do |data,index|
    if(index % 4 == 2)
      image = Hash.new()
      image[:cid] = Base64.encode64(data).gsub(/\s*/,'').reverse[0..59]
      final_html << "cid:#{image[:cid]}"
      #only attach new images!
      next if images.detect{|this_image| this_image[:cid].eql?(image[:cid])}
      begin
        image[:content] = fetch(data)
      rescue => e
        image_errors += "Couldn't fetch url '#{data}'<!--, #{e.message} - #{e.backtrace.join("\n")}-->\n"
      end
      image[:filename] = filename = File.basename(data)
      extension = filename.gsub(/^.*\./,'').downcase
      Rails.logger.debug "Fetching Image for: #{filename} #{image[:content].to_s[0..30]}"
      extension = get_extension_from_data(image[:content]) if image_mime_types(extension).blank?
      image_errors += "Couldn't find mime type for #{extension} on #{data}" if image_mime_types(extension).blank?
      image[:content_type] = image_mime_types(extension)
      images << image
    else
      final_html << data
    end
  end
  raise image_errors unless image_errors.eql?('')
  [final_html,images]
end

.multipart_alternative_without_images(subject, to_email_address, from_email_address, the_parts, message_id = nil, include_images = true) ⇒ Object

create mailing without fetching image data



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'app/models/mail_manager/mailer.rb', line 89

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
    from          from_email_address
    subject       subject

    text_part do
      body text_source
    end

    html_part do
      content_type 'text/html; charset=UTF-8'
      body original_html_source
    end
  end
  mail
end

.multipart_with_inline_images(subject, to_email_address, from_email_address, the_parts, message_id = nil, include_images = true) ⇒ Object

create mailing; parsing html sources for images to attach/include



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'app/models/mail_manager/mailer.rb', line 59

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
    from          from_email_address
    subject       subject
    part :content_type => "multipart/alternative", :content_disposition => "inline" do |main|
      main.part :content_type => "text/plain", :body => text_source
      if include_images
        main.part :content_type => "multipart/related" do |related|
          (html_source,images) = MailManager::Mailer::inline_html_with_images(original_html_source)
          images.each_with_index do |image,index|
            related.attachments.inline[image[:filename]] = {
              :content_id => image[:cid],
              :content => image[:content]
            }
            html_source.gsub!(image[:cid],related.attachments[index].cid)
          end
          related.part :content_type => "text/html; charset=UTF-8", :body => html_source
        end
      else
        main.part :content_type => "text/html; charset=UTF-8", :body => original_html_source
      end
    end
  end
  mail
end

.send_mail(subject, to_email_address, from_email_address, the_parts, message_id = nil, include_images = true) ⇒ Object

send the mailing with the given subject, addresses, and parts



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'app/models/mail_manager/mailer.rb', line 110

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)
  else
    multipart_alternative_without_images(subject,to_email_address,from_email_address,the_parts,message_id,include_images)
  end
  mail.header['Return-Path'] = MailManager.bounce['email_address']
  mail.header['X-Bounce-Guid'] = message_id if message_id
  set_mail_settings(mail)
  mail.deliver!
  Rails.logger.info "Sent mail to: #{to_email_address}"
  Rails.logger.debug mail.to_s
end

.set_mail_settings(mail) ⇒ Object

set mail delivery settings



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'app/models/mail_manager/mailer.rb', line 127

def set_mail_settings(mail)
  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!',
  #   address: 'mail.lnstar.com',
  #   domain: 'mail.lnstar.com',
  #   enable_starttls_auto: true,
  #   authentication: :plain,
  #   port: 587
  # } )

  mail.delivery_method.settings.merge!(
    (case delivery_method 
     when :smtp then ActionMailer::Base.smtp_settings
     # :nocov:
     when :sendmail then ActionMailer::Base.sendmail_settings
     # :nocov:
     else
       {}
     end rescue {})
  )
end

Instance Method Details

#double_opt_in(contact) ⇒ Object



41
42
43
44
45
46
47
48
49
# File 'app/models/mail_manager/mailer.rb', line 41

def double_opt_in(contact)
  @contact = contact
  @recipients = @contact.email_address
  @subject = "Confirm Newsletter Subscription at #{::MailManager.site_url}"
  @from = ::MailManager.
  @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

#unsubscribed(subscriptions, email_address, contact = nil, message = nil) ⇒ Object

send a confirmation email for unsubscribing



29
30
31
32
33
34
35
36
37
38
39
# File 'app/models/mail_manager/mailer.rb', line 29

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 #{@email_address}"
  mail(to: @recipients, from: @from, subject: @subject)
end