Skip to content

Commit 7328040

Browse files
author
dcparker
committed
Fixed attaching a file to an empty message.
1 parent f99b383 commit 7328040

File tree

4 files changed

+34
-16
lines changed

4 files changed

+34
-16
lines changed

History.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
=== 0.0.8 / 2009/12-23
2+
3+
* 1 bugfix
4+
5+
* Fixed attaching a file to an empty message
6+
17
=== 0.0.7 / 2009-12-23
28

39
* 1 bugfix

lib/gmail.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
require 'smtp_tls'
44

55
class Gmail
6-
VERSION = '0.0.7'
6+
VERSION = '0.0.8'
77

88
class NoLabel < RuntimeError; end
99

lib/mime/entity.rb

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,14 @@ def self.capitalize_header(header_name)
1010
header_name.gsub(/^(\w)/) {|m| m.capitalize}.gsub(/-(\w)/) {|n| '-' + n[1].chr.capitalize}
1111
end
1212
class Entity
13-
def initialize(arg=nil)
14-
if arg.is_a?(String)
15-
@raw = arg.gsub(/\r/,'').gsub(/\n/, "\r\n") # normalizes end-of-line characters
13+
def initialize(one=nil,two=nil)
14+
if one.is_a?(Hash) || two.is_a?(Hash)
15+
@headers = one.is_a?(Hash) ? one : two
16+
set_content one if one.is_a?(String)
17+
@encoding = 'quoted-printable' unless encoding
18+
elsif one.is_a?(String)
19+
@raw = one.gsub(/\r/,'').gsub(/\n/, "\r\n") # normalizes end-of-line characters
1620
from_parsed(IETF::RFC2045.parse_rfc2045_from(@raw))
17-
elsif arg.is_a?(Hash)
18-
@headers = arg
1921
end
2022
end
2123

@@ -72,12 +74,12 @@ def headers
7274
# Macro Methods #
7375

7476
def multipart?
75-
!!(headers['content-type'] =~ /multipart\//)
77+
!!(headers['content-type'] =~ /multipart\//) if headers['content-type']
7678
end
7779
def multipart_type
7880
if headers['content-type'] =~ /multipart\/(\w+)/
7981
$1
80-
end
82+
end if headers['content-type']
8183
end
8284
# Auto-generates a boundary if one doesn't yet exist.
8385
def multipart_boundary
@@ -90,24 +92,28 @@ def multipart_boundary
9092
end
9193
end
9294
def attachment?
93-
headers['content-disposition'] =~ /^attachment(?=;|$)/ || headers['content-disposition'] =~ /^form-data;.* filename=[\"\']?[^\"\']+[\"\']?/
95+
headers['content-disposition'] =~ /^attachment(?=;|$)/ || headers['content-disposition'] =~ /^form-data;.* filename=[\"\']?[^\"\']+[\"\']?/ if headers['content-disposition']
9496
end
9597
alias :file? :attachment?
9698
def part_filename
9799
# Content-Disposition: attachment; filename="summary.txt"
98100
if headers['content-disposition'] =~ /; filename=[\"\']?([^\"\']+)/
99101
$1
100-
end
102+
end if headers['content-disposition']
101103
end
102-
attr_writer :encoding
104+
103105
def encoding
104106
@encoding ||= headers['content-transfer-encoding'] || nil
105107
end
108+
attr_writer :encoding
109+
alias :set_encoding :encoding=
110+
106111
def find_part(options)
107112
find_parts(options).first
108113
end
109114
def find_parts(options)
110115
parts = []
116+
return nil unless (options[:content_type] && headers['content-type']) || (options[:content_disposition] && headers['content-disposition'])
111117
# Do I match your search?
112118
iam = true
113119
iam = false if options[:content_type] && headers['content-type'] !~ /^#{options[:content_type]}(?=;|$)/
@@ -167,7 +173,7 @@ def decoded_content
167173
end
168174

169175
# You can set new content, and it will be saved in encoded form.
170-
def content=(raw)
176+
def set_content(raw)
171177
@content = raw.is_a?(Array) ? raw :
172178
case encoding.to_s.downcase
173179
when 'quoted-printable'
@@ -178,10 +184,11 @@ def content=(raw)
178184
raw
179185
end
180186
end
187+
alias :content= :set_content
181188

182189
private
183190
def transfer_to(other)
184-
other.instance_variable_set(:@content, @content.dup)
191+
other.instance_variable_set(:@content, @content.dup) if @content
185192
other.headers.clear
186193
other.headers.merge!(Hash[*headers.dup.select {|k,v| k =~ /content/}.flatten])
187194
end

lib/mime/message.rb

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,17 @@ def self.generate
1212

1313
def to(addressee=nil)
1414
headers['to'] = addressee if addressee
15-
headers['to'].match(/([A-Z0-9._%+-]+@[A-Z0-9._%+-]+\.[A-Z]+)/i)[1]
15+
headers['to'].match(/([A-Z0-9._%+-]+@[A-Z0-9._%+-]+\.[A-Z]+)/i)[1] if headers['to'].respond_to?(:match)
1616
end
1717

1818
def subject(subj=nil)
1919
headers['subject'] = subj if subj
2020
headers['subject']
2121
end
2222

23-
def from
24-
headers['from'].match(/([A-Z0-9._%+-]+@[A-Z0-9._%+-]+\.[A-Z]+)/i)[1]
23+
def from(dummy=nil)
24+
raise "Can't set FROM address in the message - will be set automatically when the message is sent." if dummy
25+
headers['from'].match(/([A-Z0-9._%+-]+@[A-Z0-9._%+-]+\.[A-Z]+)/i)[1] if headers['from'].respond_to?(:match)
2526
end
2627

2728
def attachments
@@ -47,6 +48,7 @@ def generate_multipart(*content_types)
4748
end
4849

4950
def attach_file(filename)
51+
raise ArgumentError, "Currently the <filename> given must be a String (path to a file)." unless filename.is_a?(String)
5052
short_filename = filename.match(/([^\\\/]+)$/)[1]
5153

5254
# Generate the attachment piece
@@ -62,12 +64,15 @@ def attach_file(filename)
6264
# If already enclosed, all we have to do is add the attachment part
6365
(@content ||= []) << attachment
6466
else
67+
# If there is no content, add a little message about the attachment(s).
68+
set_content 'See attachment(s)' if @content.nil?
6569
# Generate the new top-level multipart, transferring what is here already into a child object
6670
new_content = Entity.new
6771
# Whatever it is, since it's not multipart/mixed, transfer it into a child object and add the attachment.
6872
transfer_to(new_content)
6973
headers.reject! {|k,v| k =~ /content/}
7074
headers['content-type'] = 'multipart/mixed'
75+
headers.delete 'content-transfer-encoding' # because now it's useless.
7176
@content = [new_content, attachment]
7277
end
7378

0 commit comments

Comments
 (0)