mailfactory 1.0.2 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (2) hide show
  1. data/lib/mailfactory.rb +90 -29
  2. metadata +2 -2
data/lib/mailfactory.rb CHANGED
@@ -166,15 +166,26 @@ class MailFactory
166
166
  end
167
167
  end
168
168
 
169
-
170
- # returns a formatted email
171
- def to_s()
172
- # all emails get a unique message-id
173
- remove_header("Message-ID")
174
- add_header("Message-ID", "<#{Time.now.to_f()}.#{Process.euid()}.#{String.new.object_id()}>")
175
169
 
176
- if(get_header("Date").length == 0)
177
- add_header("Date", Time.now.strftime("%a, %d %B %Y %H:%M:%S %Z"))
170
+ # builds an email and returns it as a string. Takes the following options:
171
+ # <tt>:messageid</tt>:: Adds a message id to the message based on the from header (defaults to false)
172
+ # <tt>:date</tt>:: Adds a date to the message if one is not present (defaults to true)
173
+ def construct(options = Hash.new)
174
+ if(options[:date] == nil)
175
+ options[:date] = true
176
+ end
177
+
178
+ if(options[:messageid])
179
+ # add a unique message-id
180
+ remove_header("Message-ID")
181
+ sendingdomain = get_header('from')[0].to_s()[/@([-a-zA-Z0-9._]+)/,1].to_s()
182
+ add_header("Message-ID", "<#{Time.now.to_f()}.#{Process.euid()}.#{String.new.object_id()}@#{sendingdomain}>")
183
+ end
184
+
185
+ if(options[:date])
186
+ if(get_header("Date").length == 0)
187
+ add_header("Date", Time.now.strftime("%a, %d %B %Y %H:%M:%S %Z"))
188
+ end
178
189
  end
179
190
 
180
191
  # Add a mime header if we don't already have one and we have multiple parts
@@ -194,6 +205,12 @@ class MailFactory
194
205
 
195
206
  return("#{headers_to_s()}#{body_to_s()}")
196
207
  end
208
+
209
+
210
+ # returns a formatted email - equivalent to construct(:messageid => true)
211
+ def to_s()
212
+ return(construct(:messageid => true))
213
+ end
197
214
 
198
215
 
199
216
  # generates a unique boundary string
@@ -219,19 +236,30 @@ class MailFactory
219
236
 
220
237
  # adds an attachment to the mail. Type may be given as a mime type. If it
221
238
  # is left off and the MIME::Types module is available it will be determined automagically.
222
- def add_attachment(filename, type=nil)
223
- attachment = Array.new()
224
- attachment[0] = Pathname.new(filename).basename
239
+ # If the optional attachemntheaders is given, then they will be added to the attachment
240
+ # boundary in the email, which can be used to produce Content-ID markers. attachmentheaders
241
+ # can be given as an Array or a String.
242
+ def add_attachment(filename, type=nil, attachmentheaders = nil)
243
+ attachment = Hash.new()
244
+ attachment['filename'] = Pathname.new(filename).basename
225
245
  if(type == nil)
226
- attachment[1] = MIME::Types.type_for(filename).to_s
246
+ attachment['mimetype'] = MIME::Types.type_for(filename).to_s
227
247
  else
228
- attachment[1] = type
248
+ attachment['mimetype'] = type
229
249
  end
230
250
 
231
251
  # Open in rb mode to handle Windows, which mangles binary files opened in a text mode
232
252
  File.open(filename, "rb") { |fp|
233
- attachment[2] = Base64.b64encode(fp.read())
253
+ attachment['attachment'] = file_encode(fp.read())
234
254
  }
255
+
256
+ if(attachmentheaders != nil)
257
+ if(!attachmentheaders.kind_of?(Array))
258
+ attachmentheaders = attachmentheaders.split(/\r?\n/)
259
+ end
260
+ attachment['headers'] = attachmentheaders
261
+ end
262
+
235
263
  @attachments << attachment
236
264
  end
237
265
 
@@ -239,25 +267,39 @@ class MailFactory
239
267
  # adds an attachment to the mail as emailfilename. Type may be given as a mime type. If it
240
268
  # is left off and the MIME::Types module is available it will be determined automagically.
241
269
  # file may be given as an IO stream (which will be read until the end) or as a filename.
242
- def add_attachment_as(file, emailfilename, type=nil)
243
- attachment = Array.new()
244
- attachment[0] = emailfilename
245
- if(!file.respond_to?(:stat) and type == nil)
246
- attachment[1] = MIME::Types.type_for(file.to_s()).to_s
270
+ # If the optional attachemntheaders is given, then they will be added to the attachment
271
+ # boundary in the email, which can be used to produce Content-ID markers. attachmentheaders
272
+ # can be given as an Array of a String.
273
+ def add_attachment_as(file, emailfilename, type=nil, attachmentheaders = nil)
274
+ attachment = Hash.new()
275
+ attachment['filename'] = emailfilename
276
+
277
+ if(type != nil)
278
+ attachment['mimetype'] = type.to_s()
279
+ elsif(file.kind_of?(String) or file.kind_of?(Pathname))
280
+ attachment['mimetype'] = MIME::Types.type_for(file.to_s()).to_s
247
281
  else
248
- attachment[1] = type
282
+ attachment['mimetype'] = ''
249
283
  end
250
284
 
251
285
  if(file.kind_of?(String) or file.kind_of?(Pathname))
252
286
  # Open in rb mode to handle Windows, which mangles binary files opened in a text mode
253
287
  File.open(file.to_s(), "rb") { |fp|
254
- attachment[2] = Base64.b64encode(fp.read())
288
+ attachment['attachment'] = file_encode(fp.read())
255
289
  }
256
290
  elsif(file.respond_to?(:read))
257
- attachment[2] = Base64.b64encode(file.read())
291
+ attachment['attachment'] = file_encode(file.read())
258
292
  else
259
- raise(Exception, "file is not a supported type")
293
+ raise(Exception, "file is not a supported type (must be a String, Pathnamem, or support read method)")
294
+ end
295
+
296
+ if(attachmentheaders != nil)
297
+ if(!attachmentheaders.kind_of?(Array))
298
+ attachmentheaders = attachmentheaders.split(/\r?\n/)
299
+ end
300
+ attachment['headers'] = attachmentheaders
260
301
  end
302
+
261
303
  @attachments << attachment
262
304
  end
263
305
 
@@ -295,7 +337,7 @@ protected
295
337
  # and, the attachments
296
338
  if(@attachments.length > 0)
297
339
  @attachments.each() { |attachment|
298
- body << "#{buildattachmentboundary(attachment[1], 'base64', attachment[0])}\r\n\r\n#{attachment[2]}"
340
+ body << "#{buildattachmentboundary(attachment)}\r\n\r\n#{attachment['attachment']}"
299
341
  }
300
342
  body << "\r\n--#{@attachmentboundary}--"
301
343
  end
@@ -314,10 +356,16 @@ protected
314
356
  end
315
357
 
316
358
 
317
- # builds a boundary string for including attachments in the body
318
- def buildattachmentboundary(type, encoding, filename)
319
- disposition = "\r\nContent-Disposition: inline; filename=\"#{filename}\""
320
- return("--#{@attachmentboundary}\r\nContent-Type: #{type}; name=\"#{filename}\"\r\nContent-Transfer-Encoding: #{encoding}#{disposition}")
359
+ # builds a boundary string for including attachments in the body, expects an attachment hash as built by
360
+ # add_attachment and add_attachment_as
361
+ def buildattachmentboundary(attachment)
362
+ disposition = "Content-Disposition: inline; filename=\"#{attachment['filename']}\""
363
+ boundary = "--#{@attachmentboundary}\r\nContent-Type: #{attachment['mimetype']}; name=\"#{attachment['filename']}\"\r\nContent-Transfer-Encoding: base64\r\n#{disposition}"
364
+ if(attachment['headers'])
365
+ boundary = boundary + "\r\n#{attachment['headers'].join("\r\n")}"
366
+ end
367
+
368
+ return(boundary)
321
369
  end
322
370
 
323
371
 
@@ -325,6 +373,19 @@ protected
325
373
  def buildbodyboundary(type, encoding)
326
374
  return("--#{@bodyboundary}\r\nContent-Type: #{type}\r\nContent-Transfer-Encoding: #{encoding}")
327
375
  end
328
-
376
+
377
+
378
+ # returns a base64 encoded version of the contents of str
379
+ def file_encode(str)
380
+ collection = Array.new()
381
+ enc = Base64.encode64(str)
382
+ # while(enc.length > 60)
383
+ # collection << enc.slice!(0..59)
384
+ # end
385
+ # collection << enc
386
+ # return(collection.join("\n"))
387
+ return(enc)
388
+ end
389
+
329
390
  end
330
391
 
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
3
3
  specification_version: 1
4
4
  name: mailfactory
5
5
  version: !ruby/object:Gem::Version
6
- version: 1.0.2
7
- date: 2005-09-16 00:00:00 -04:00
6
+ version: 1.2.1
7
+ date: 2005-10-24 00:00:00 -04:00
8
8
  summary: MailFactory is a pure-ruby MIME mail generator
9
9
  require_paths:
10
10
  - lib