sup 0.6 → 0.7
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of sup might be problematic. Click here for more details.
- data/CONTRIBUTORS +7 -3
- data/History.txt +12 -0
- data/README.txt +2 -2
- data/ReleaseNotes +11 -0
- data/bin/sup +26 -5
- data/bin/sup-tweak-labels +5 -0
- data/lib/sup.rb +2 -1
- data/lib/sup/buffer.rb +3 -3
- data/lib/sup/crypto.rb +1 -1
- data/lib/sup/draft.rb +4 -1
- data/lib/sup/hook.rb +12 -1
- data/lib/sup/imap.rb +24 -4
- data/lib/sup/index.rb +154 -98
- data/lib/sup/label.rb +1 -1
- data/lib/sup/mbox.rb +8 -8
- data/lib/sup/message-chunks.rb +5 -3
- data/lib/sup/message.rb +4 -4
- data/lib/sup/modes/thread-index-mode.rb +2 -1
- data/lib/sup/modes/thread-view-mode.rb +16 -2
- data/lib/sup/rfc2047.rb +1 -6
- data/lib/sup/textfield.rb +1 -1
- data/lib/sup/util.rb +17 -0
- metadata +56 -81
- data/HACKING +0 -42
- data/Manifest.txt +0 -75
- data/Rakefile +0 -60
- data/doc/FAQ.txt +0 -132
- data/doc/Hooks.txt +0 -38
- data/doc/NewUserGuide.txt +0 -255
- data/doc/Philosophy.txt +0 -69
- data/test/test_mbox_parsing.rb +0 -114
- data/test/test_message.rb +0 -441
data/doc/Philosophy.txt
DELETED
@@ -1,69 +0,0 @@
|
|
1
|
-
Should an email client have a philosophy? For many people, email is
|
2
|
-
one of our primary means of communication, and email archives are an
|
3
|
-
integral part of our long-term memory. Something so important ought to
|
4
|
-
warrant a little thought.
|
5
|
-
|
6
|
-
Here's Sup's philosophy.
|
7
|
-
|
8
|
-
Using "traditional" email clients today is increasingly problematic.
|
9
|
-
Anyone who's on a high-traffic mailing list knows this. My ruby-talk
|
10
|
-
folder is 430 megs and Mutt sits there for 60 seconds while it opens
|
11
|
-
it. Keeping up with the all the new traffic is impossible, even with
|
12
|
-
Mutt's excellent threading features, simply because there's so much of
|
13
|
-
it. A single thread can span several pages in the folder index view
|
14
|
-
alone! And Mutt is probably the fastest, most mailing-list aware email
|
15
|
-
client out there. God help me if I try and use Thunderbird.
|
16
|
-
|
17
|
-
The problem with traditional clients like Mutt is that they deal with
|
18
|
-
individual pieces of email. This places a high mental cost on the user
|
19
|
-
for each incoming email, by forcing them to ask: Should I keep this
|
20
|
-
email, or delete it? If I keep it, where should I file it? I've spent
|
21
|
-
the last 10 years of my life laboriously hand-filing every email
|
22
|
-
message I received and feeling a mild sense of panic every time an
|
23
|
-
email was both "from Mom" and "about school". The massive amounts of
|
24
|
-
email that many people receive, and the cheap cost of storage, have
|
25
|
-
made these questions both more costly and less useful to answer.
|
26
|
-
|
27
|
-
Contrast that with using Gmail. As a long-time Mutt user, I was blown
|
28
|
-
away when I first saw someone use Gmail. They treated their email
|
29
|
-
differently from how I ever had. They never filed email and they never
|
30
|
-
deleted it. They relied on an immediate, global, full-text search, and
|
31
|
-
thread-level tagging, to do everything I'd ever done with Mutt, but
|
32
|
-
with a trivial cost to the user at message receipt time.
|
33
|
-
|
34
|
-
From Gmail I learned that making certain operations quantitatively
|
35
|
-
easier (namely, search) resulted in a qualitative improvement in
|
36
|
-
usage. I also learned how thread-centrism was advantageous over
|
37
|
-
message-centrism when message volume was high: most of the time, a
|
38
|
-
message and its context deserve the same treatment. I think it's to
|
39
|
-
the Gmail designers' credit that they started with a somewhat ad-hoc
|
40
|
-
idea (hey, we're really good at search engines, so maybe we can build
|
41
|
-
an email client on top of one) and managed to build something that was
|
42
|
-
actually better than everything else out there. At least, that's how I
|
43
|
-
imagine in happened. Maybe they knew what they were doing from the
|
44
|
-
start.
|
45
|
-
|
46
|
-
Unfortunately, there's a lot to Gmail I can't tolerate (top posting,
|
47
|
-
HTML mail, one-level threads, and ads come to mind, never mind the
|
48
|
-
fact that it's not FOSS). Thus Sup was born.
|
49
|
-
|
50
|
-
Sup is based on the following principles, which I stole directly from
|
51
|
-
Gmail:
|
52
|
-
|
53
|
-
- An immediately accessible and fast search capability over the entire
|
54
|
-
email archive eliminates most of the need for folders, and most of
|
55
|
-
the necessity of deleting email.
|
56
|
-
|
57
|
-
- Labels eliminate what little need for folders search doesn't cover.
|
58
|
-
|
59
|
-
- A thread-centric approach to the UI is much more in line with how
|
60
|
-
people operate than dealing with individual messages is. In the vast
|
61
|
-
majority of cases, a message and its context should be subject to
|
62
|
-
the same treatment.
|
63
|
-
|
64
|
-
Sup is also based on many ideas from mutt and Emacs and vi, having to
|
65
|
-
do with the fantastic productivity of a console- and keyboard-based
|
66
|
-
application, the usefulness of multiple buffers, the necessity of
|
67
|
-
handling multiple email accounts, etc. But those are just details!
|
68
|
-
|
69
|
-
Try it and let me know what you think.
|
data/test/test_mbox_parsing.rb
DELETED
@@ -1,114 +0,0 @@
|
|
1
|
-
#!/usr/bin/ruby
|
2
|
-
|
3
|
-
require 'test/unit'
|
4
|
-
require 'sup'
|
5
|
-
require 'stringio'
|
6
|
-
|
7
|
-
include Redwood
|
8
|
-
|
9
|
-
class TestMessage < Test::Unit::TestCase
|
10
|
-
def setup
|
11
|
-
end
|
12
|
-
|
13
|
-
def teardown
|
14
|
-
end
|
15
|
-
|
16
|
-
def test_normal_headers
|
17
|
-
h = MBox.read_header StringIO.new(<<EOS)
|
18
|
-
From: Bob <bob@bob.com>
|
19
|
-
To: Sally <sally@sally.com>
|
20
|
-
EOS
|
21
|
-
|
22
|
-
assert_equal "Bob <bob@bob.com>", h["From"]
|
23
|
-
assert_equal "Sally <sally@sally.com>", h["To"]
|
24
|
-
assert_nil h["Message-Id"]
|
25
|
-
end
|
26
|
-
|
27
|
-
## this is shitty behavior in retrospect, but it's built in now.
|
28
|
-
def test_message_id_stripping
|
29
|
-
h = MBox.read_header StringIO.new("Message-Id: <one@bob.com>\n")
|
30
|
-
assert_equal "one@bob.com", h["Message-Id"]
|
31
|
-
|
32
|
-
h = MBox.read_header StringIO.new("Message-Id: one@bob.com\n")
|
33
|
-
assert_equal "one@bob.com", h["Message-Id"]
|
34
|
-
end
|
35
|
-
|
36
|
-
def test_multiline
|
37
|
-
h = MBox.read_header StringIO.new(<<EOS)
|
38
|
-
From: Bob <bob@bob.com>
|
39
|
-
Subject: one two three
|
40
|
-
four five six
|
41
|
-
To: Sally <sally@sally.com>
|
42
|
-
References: seven
|
43
|
-
eight
|
44
|
-
Seven: Eight
|
45
|
-
EOS
|
46
|
-
|
47
|
-
assert_equal "one two three four five six", h["Subject"]
|
48
|
-
assert_equal "Sally <sally@sally.com>", h["To"]
|
49
|
-
assert_equal "seven eight", h["References"]
|
50
|
-
end
|
51
|
-
|
52
|
-
def test_ignore_spacing
|
53
|
-
variants = [
|
54
|
-
"Subject:one two three end\n",
|
55
|
-
"Subject: one two three end\n",
|
56
|
-
"Subject: one two three end \n",
|
57
|
-
]
|
58
|
-
variants.each do |s|
|
59
|
-
h = MBox.read_header StringIO.new(s)
|
60
|
-
assert_equal "one two three end", h["Subject"]
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
def test_message_id_ignore_spacing
|
65
|
-
variants = [
|
66
|
-
"Message-Id: <one@bob.com> \n",
|
67
|
-
"Message-Id: one@bob.com \n",
|
68
|
-
"Message-Id:<one@bob.com> \n",
|
69
|
-
"Message-Id:one@bob.com \n",
|
70
|
-
]
|
71
|
-
variants.each do |s|
|
72
|
-
h = MBox.read_header StringIO.new(s)
|
73
|
-
assert_equal "one@bob.com", h["Message-Id"]
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
def test_ignore_empty_lines
|
78
|
-
variants = [
|
79
|
-
"",
|
80
|
-
"Message-Id: \n",
|
81
|
-
"Message-Id:\n",
|
82
|
-
]
|
83
|
-
variants.each do |s|
|
84
|
-
h = MBox.read_header StringIO.new(s)
|
85
|
-
assert_nil h["Message-Id"]
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
def test_detect_end_of_headers
|
90
|
-
h = MBox.read_header StringIO.new(<<EOS)
|
91
|
-
From: Bob <bob@bob.com>
|
92
|
-
|
93
|
-
To: a dear friend
|
94
|
-
EOS
|
95
|
-
assert_equal "Bob <bob@bob.com>", h["From"]
|
96
|
-
assert_nil h["To"]
|
97
|
-
|
98
|
-
h = MBox.read_header StringIO.new(<<EOS)
|
99
|
-
From: Bob <bob@bob.com>
|
100
|
-
\r
|
101
|
-
To: a dear friend
|
102
|
-
EOS
|
103
|
-
assert_equal "Bob <bob@bob.com>", h["From"]
|
104
|
-
assert_nil h["To"]
|
105
|
-
|
106
|
-
h = MBox.read_header StringIO.new(<<EOS)
|
107
|
-
From: Bob <bob@bob.com>
|
108
|
-
\r\n\r
|
109
|
-
To: a dear friend
|
110
|
-
EOS
|
111
|
-
assert_equal "Bob <bob@bob.com>", h["From"]
|
112
|
-
assert_nil h["To"]
|
113
|
-
end
|
114
|
-
end
|
data/test/test_message.rb
DELETED
@@ -1,441 +0,0 @@
|
|
1
|
-
#!/usr/bin/ruby
|
2
|
-
|
3
|
-
require 'test/unit'
|
4
|
-
require 'sup'
|
5
|
-
require 'stringio'
|
6
|
-
|
7
|
-
require 'dummy_source'
|
8
|
-
|
9
|
-
# override File.exists? to make it work with StringIO for testing.
|
10
|
-
# FIXME: do aliasing to avoid breaking this when sup moves from
|
11
|
-
# File.exists? to File.exist?
|
12
|
-
|
13
|
-
class File
|
14
|
-
|
15
|
-
def File.exists? file
|
16
|
-
# puts "fake File::exists?"
|
17
|
-
|
18
|
-
if file.is_a?(StringIO)
|
19
|
-
return false
|
20
|
-
end
|
21
|
-
# use the different function
|
22
|
-
File.exist?(file)
|
23
|
-
end
|
24
|
-
|
25
|
-
end
|
26
|
-
|
27
|
-
module Redwood
|
28
|
-
|
29
|
-
class TestMessage < Test::Unit::TestCase
|
30
|
-
|
31
|
-
def setup
|
32
|
-
person_file = StringIO.new("")
|
33
|
-
# this is a singleton
|
34
|
-
if not PersonManager.instantiated?
|
35
|
-
@person_manager = PersonManager.new(person_file)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
def teardown
|
40
|
-
end
|
41
|
-
|
42
|
-
def test_simple_message
|
43
|
-
|
44
|
-
message = <<EOS
|
45
|
-
Return-path: <fake_sender@example.invalid>
|
46
|
-
Envelope-to: fake_receiver@localhost
|
47
|
-
Delivery-date: Sun, 09 Dec 2007 21:48:19 +0200
|
48
|
-
Received: from fake_sender by localhost.localdomain with local (Exim 4.67)
|
49
|
-
(envelope-from <fake_sender@example.invalid>)
|
50
|
-
id 1J1S8R-0006lA-MJ
|
51
|
-
for fake_receiver@localhost; Sun, 09 Dec 2007 21:48:19 +0200
|
52
|
-
Date: Sun, 9 Dec 2007 21:48:19 +0200
|
53
|
-
Mailing-List: contact example-help@example.invalid; run by ezmlm
|
54
|
-
Precedence: bulk
|
55
|
-
List-Id: <example.list-id.example.invalid>
|
56
|
-
List-Post: <mailto:example@example.invalid>
|
57
|
-
List-Help: <mailto:example-help@example.invalid>
|
58
|
-
List-Unsubscribe: <mailto:example-unsubscribe@example.invalid>
|
59
|
-
List-Subscribe: <mailto:example-subscribe@example.invalid>
|
60
|
-
Delivered-To: mailing list example@example.invalid
|
61
|
-
Delivered-To: moderator for example@example.invalid
|
62
|
-
From: Fake Sender <fake_sender@example.invalid>
|
63
|
-
To: Fake Receiver <fake_receiver@localhost>
|
64
|
-
Subject: Re: Test message subject
|
65
|
-
Message-ID: <20071209194819.GA25972@example.invalid>
|
66
|
-
References: <E1J1Rvb-0006k2-CE@localhost.localdomain>
|
67
|
-
MIME-Version: 1.0
|
68
|
-
Content-Type: text/plain; charset=us-ascii
|
69
|
-
Content-Disposition: inline
|
70
|
-
In-Reply-To: <E1J1Rvb-0006k2-CE@localhost.localdomain>
|
71
|
-
User-Agent: Sup/0.3
|
72
|
-
|
73
|
-
Test message!
|
74
|
-
EOS
|
75
|
-
|
76
|
-
source = DummySource.new("sup-test://test_simple_message")
|
77
|
-
source.messages = [ message ]
|
78
|
-
source_info = 0
|
79
|
-
|
80
|
-
sup_message = Message.new( {:source => source, :source_info => source_info } )
|
81
|
-
|
82
|
-
# see how well parsing the header went
|
83
|
-
|
84
|
-
to = sup_message.to
|
85
|
-
# "to" is an Array containing person items
|
86
|
-
|
87
|
-
# there should be only one item
|
88
|
-
assert_equal(1, to.length)
|
89
|
-
|
90
|
-
# sup doesn't do capitalized letters in email addresses
|
91
|
-
assert_equal("fake_receiver@localhost", to[0].email)
|
92
|
-
assert_equal("Fake Receiver", to[0].name)
|
93
|
-
|
94
|
-
from = sup_message.from
|
95
|
-
# "from" is just a simple person item
|
96
|
-
|
97
|
-
assert_equal("fake_sender@example.invalid", from.email)
|
98
|
-
assert_equal("Fake Sender", from.name)
|
99
|
-
|
100
|
-
subj = sup_message.subj
|
101
|
-
assert_equal("Re: Test message subject", subj)
|
102
|
-
|
103
|
-
list_subscribe = sup_message.list_subscribe
|
104
|
-
assert_equal("<mailto:example-subscribe@example.invalid>", list_subscribe)
|
105
|
-
|
106
|
-
list_unsubscribe = sup_message.list_unsubscribe
|
107
|
-
assert_equal("<mailto:example-unsubscribe@example.invalid>", list_unsubscribe)
|
108
|
-
|
109
|
-
list_address = sup_message.list_address
|
110
|
-
assert_equal("example@example.invalid", list_address.email)
|
111
|
-
assert_equal("example", list_address.name)
|
112
|
-
|
113
|
-
date = sup_message.date
|
114
|
-
assert_equal(Time.parse("Sun, 9 Dec 2007 21:48:19 +0200"), date)
|
115
|
-
|
116
|
-
id = sup_message.id
|
117
|
-
assert_equal("20071209194819.GA25972@example.invalid", id)
|
118
|
-
|
119
|
-
refs = sup_message.refs
|
120
|
-
assert_equal(1, refs.length)
|
121
|
-
assert_equal("E1J1Rvb-0006k2-CE@localhost.localdomain", refs[0])
|
122
|
-
|
123
|
-
replytos = sup_message.replytos
|
124
|
-
assert_equal(1, replytos.length)
|
125
|
-
assert_equal("E1J1Rvb-0006k2-CE@localhost.localdomain", replytos[0])
|
126
|
-
|
127
|
-
cc = sup_message.cc
|
128
|
-
# there are no ccs
|
129
|
-
assert_equal(0, cc.length)
|
130
|
-
|
131
|
-
bcc = sup_message.bcc
|
132
|
-
# there are no bccs
|
133
|
-
assert_equal(0, bcc.length)
|
134
|
-
|
135
|
-
recipient_email = sup_message.recipient_email
|
136
|
-
assert_equal("fake_receiver@localhost", recipient_email)
|
137
|
-
|
138
|
-
message_source = sup_message.source
|
139
|
-
assert_equal(message_source, source)
|
140
|
-
|
141
|
-
message_source_info = sup_message.source_info
|
142
|
-
assert_equal(message_source_info, source_info)
|
143
|
-
|
144
|
-
# read the message body chunks
|
145
|
-
|
146
|
-
chunks = sup_message.load_from_source!
|
147
|
-
|
148
|
-
# there should be only one chunk
|
149
|
-
assert_equal(1, chunks.length)
|
150
|
-
|
151
|
-
lines = chunks[0].lines
|
152
|
-
|
153
|
-
# there should be only one line
|
154
|
-
assert_equal(1, lines.length)
|
155
|
-
|
156
|
-
assert_equal("Test message!", lines[0])
|
157
|
-
|
158
|
-
end
|
159
|
-
|
160
|
-
def test_multipart_message
|
161
|
-
|
162
|
-
message = <<EOS
|
163
|
-
From fake_receiver@localhost Sun Dec 09 22:33:37 +0200 2007
|
164
|
-
Subject: Re: Test message subject
|
165
|
-
From: Fake Receiver <fake_receiver@localhost>
|
166
|
-
To: Fake Sender <fake_sender@example.invalid>
|
167
|
-
References: <E1J1Rvb-0006k2-CE@localhost.localdomain> <20071209194819.GA25972example.invalid>
|
168
|
-
In-Reply-To: <20071209194819.GA25972example.invalid>
|
169
|
-
Date: Sun, 09 Dec 2007 22:33:37 +0200
|
170
|
-
Message-Id: <1197232243-sup-2663example.invalid>
|
171
|
-
User-Agent: Sup/0.3
|
172
|
-
Content-Type: multipart/mixed; boundary="=-1197232418-506707-26079-6122-2-="
|
173
|
-
MIME-Version: 1.0
|
174
|
-
|
175
|
-
|
176
|
-
--=-1197232418-506707-26079-6122-2-=
|
177
|
-
Content-Type: text/plain; charset=utf-8
|
178
|
-
Content-Disposition: inline
|
179
|
-
|
180
|
-
Excerpts from Fake Sender's message of Sun Dec 09 21:48:19 +0200 2007:
|
181
|
-
> Test message!
|
182
|
-
|
183
|
-
Thanks for the message!
|
184
|
-
--=-1197232418-506707-26079-6122-2-=
|
185
|
-
Content-Disposition: attachment; filename="HACKING"
|
186
|
-
Content-Type: application/octet-stream; name="HACKING"
|
187
|
-
Content-Transfer-Encoding: base64
|
188
|
-
|
189
|
-
UnVubmluZyBTdXAgbG9jYWxseQotLS0tLS0tLS0tLS0tLS0tLS0tCkludm9r
|
190
|
-
ZSBpdCBsaWtlIHRoaXM6CgpydWJ5IC1JIGxpYiAtdyBiaW4vc3VwCgpZb3Un
|
191
|
-
bGwgaGF2ZSB0byBpbnN0YWxsIGFsbCBnZW1zIG1lbnRpb25lZCBpbiB0aGUg
|
192
|
-
UmFrZWZpbGUgKGxvb2sgZm9yIHRoZSBsaW5lCnNldHRpbmcgcC5leHRyYV9k
|
193
|
-
ZXBzKS4gSWYgeW91J3JlIG9uIGEgRGViaWFuIG9yIERlYmlhbi1iYXNlZCBz
|
194
|
-
eXN0ZW0gKGUuZy4KVWJ1bnR1KSwgeW91J2xsIGhhdmUgdG8gbWFrZSBzdXJl
|
195
|
-
IHlvdSBoYXZlIGEgY29tcGxldGUgUnVieSBpbnN0YWxsYXRpb24sCmVzcGVj
|
196
|
-
aWFsbHkgbGlic3NsLXJ1YnkuCgpDb2Rpbmcgc3RhbmRhcmRzCi0tLS0tLS0t
|
197
|
-
LS0tLS0tLS0KCi0gRG9uJ3Qgd3JhcCBjb2RlIHVubGVzcyBpdCByZWFsbHkg
|
198
|
-
YmVuZWZpdHMgZnJvbSBpdC4gVGhlIGRheXMgb2YKICA4MC1jb2x1bW4gZGlz
|
199
|
-
cGxheXMgYXJlIGxvbmcgb3Zlci4gQnV0IGRvIHdyYXAgY29tbWVudHMgYW5k
|
200
|
-
IG90aGVyCiAgdGV4dCBhdCB3aGF0ZXZlciBFbWFjcyBtZXRhLVEgZG9lcy4K
|
201
|
-
LSBJIGxpa2UgcG9ldHJ5IG1vZGUuCi0gVXNlIHt9IGZvciBvbmUtbGluZXIg
|
202
|
-
YmxvY2tzIGFuZCBkby9lbmQgZm9yIG11bHRpLWxpbmUgYmxvY2tzLgoK
|
203
|
-
|
204
|
-
--=-1197232418-506707-26079-6122-2-=
|
205
|
-
Content-Disposition: attachment; filename="Manifest.txt"
|
206
|
-
Content-Type: text/plain; name="Manifest.txt"
|
207
|
-
Content-Transfer-Encoding: quoted-printable
|
208
|
-
|
209
|
-
HACKING
|
210
|
-
History.txt
|
211
|
-
LICENSE
|
212
|
-
Manifest.txt
|
213
|
-
README.txt
|
214
|
-
Rakefile
|
215
|
-
bin/sup
|
216
|
-
bin/sup-add
|
217
|
-
bin/sup-config
|
218
|
-
bin/sup-dump
|
219
|
-
bin/sup-recover-sources
|
220
|
-
bin/sup-sync
|
221
|
-
bin/sup-sync-back
|
222
|
-
|
223
|
-
--=-1197232418-506707-26079-6122-2-=--
|
224
|
-
EOS
|
225
|
-
source = DummySource.new("sup-test://test_multipart_message")
|
226
|
-
source.messages = [ message ]
|
227
|
-
source_info = 0
|
228
|
-
|
229
|
-
sup_message = Message.new( {:source => source, :source_info => source_info } )
|
230
|
-
|
231
|
-
# read the message body chunks
|
232
|
-
|
233
|
-
chunks = sup_message.load_from_source!
|
234
|
-
|
235
|
-
# this time there should be four chunks: first the quoted part of
|
236
|
-
# the message, then the non-quoted part, then the two attachments
|
237
|
-
assert_equal(4, chunks.length)
|
238
|
-
|
239
|
-
assert_equal(chunks[0].class, Redwood::Chunk::Quote)
|
240
|
-
assert_equal(chunks[1].class, Redwood::Chunk::Text)
|
241
|
-
assert_equal(chunks[2].class, Redwood::Chunk::Attachment)
|
242
|
-
assert_equal(chunks[3].class, Redwood::Chunk::Attachment)
|
243
|
-
|
244
|
-
# further testing of chunks will happen in test_message_chunks.rb
|
245
|
-
# (possibly not yet implemented)
|
246
|
-
|
247
|
-
end
|
248
|
-
|
249
|
-
def test_broken_message_1
|
250
|
-
|
251
|
-
# an example of a broken message, missing "to" and "from" fields
|
252
|
-
|
253
|
-
message = <<EOS
|
254
|
-
Return-path: <fake_sender@example.invalid>
|
255
|
-
Envelope-to: fake_receiver@localhost
|
256
|
-
Delivery-date: Sun, 09 Dec 2007 21:48:19 +0200
|
257
|
-
Received: from fake_sender by localhost.localdomain with local (Exim 4.67)
|
258
|
-
(envelope-from <fake_sender@example.invalid>)
|
259
|
-
id 1J1S8R-0006lA-MJ
|
260
|
-
for fake_receiver@localhost; Sun, 09 Dec 2007 21:48:19 +0200
|
261
|
-
Date: Sun, 9 Dec 2007 21:48:19 +0200
|
262
|
-
Subject: Re: Test message subject
|
263
|
-
Message-ID: <20071209194819.GA25972@example.invalid>
|
264
|
-
References: <E1J1Rvb-0006k2-CE@localhost.localdomain>
|
265
|
-
MIME-Version: 1.0
|
266
|
-
Content-Type: text/plain; charset=us-ascii
|
267
|
-
Content-Disposition: inline
|
268
|
-
In-Reply-To: <E1J1Rvb-0006k2-CE@localhost.localdomain>
|
269
|
-
User-Agent: Sup/0.3
|
270
|
-
|
271
|
-
Test message!
|
272
|
-
EOS
|
273
|
-
|
274
|
-
source = DummySource.new("sup-test://test_broken_message_1")
|
275
|
-
source.messages = [ message ]
|
276
|
-
source_info = 0
|
277
|
-
|
278
|
-
sup_message = Message.new( {:source => source, :source_info => source_info } )
|
279
|
-
|
280
|
-
to = sup_message.to
|
281
|
-
|
282
|
-
# there should no items, since the message doesn't have any
|
283
|
-
# recipients -- still not nil
|
284
|
-
assert_equal(0, to.length)
|
285
|
-
|
286
|
-
# from will have bogus values
|
287
|
-
from = sup_message.from
|
288
|
-
# very basic email address check
|
289
|
-
assert_match(/\w+@\w+\.\w{2,4}/, from.email)
|
290
|
-
assert_not_nil(from.name)
|
291
|
-
|
292
|
-
end
|
293
|
-
|
294
|
-
def test_broken_message_2
|
295
|
-
|
296
|
-
# an example of a broken message, no body at all
|
297
|
-
|
298
|
-
message = <<EOS
|
299
|
-
Return-path: <fake_sender@example.invalid>
|
300
|
-
From: Fake Sender <fake_sender@example.invalid>
|
301
|
-
To: Fake Receiver <fake_receiver@localhost>
|
302
|
-
Envelope-to: fake_receiver@localhost
|
303
|
-
Delivery-date: Sun, 09 Dec 2007 21:48:19 +0200
|
304
|
-
Received: from fake_sender by localhost.localdomain with local (Exim 4.67)
|
305
|
-
(envelope-from <fake_sender@example.invalid>)
|
306
|
-
id 1J1S8R-0006lA-MJ
|
307
|
-
for fake_receiver@localhost; Sun, 09 Dec 2007 21:48:19 +0200
|
308
|
-
Date: Sun, 9 Dec 2007 21:48:19 +0200
|
309
|
-
Subject: Re: Test message subject
|
310
|
-
Message-ID: <20071209194819.GA25972@example.invalid>
|
311
|
-
References: <E1J1Rvb-0006k2-CE@localhost.localdomain>
|
312
|
-
MIME-Version: 1.0
|
313
|
-
Content-Type: text/plain; charset=us-ascii
|
314
|
-
Content-Disposition: inline
|
315
|
-
In-Reply-To: <E1J1Rvb-0006k2-CE@localhost.localdomain>
|
316
|
-
User-Agent: Sup/0.3
|
317
|
-
EOS
|
318
|
-
|
319
|
-
source = DummySource.new("sup-test://test_broken_message_1")
|
320
|
-
source.messages = [ message ]
|
321
|
-
source_info = 0
|
322
|
-
|
323
|
-
sup_message = Message.new( {:source => source, :source_info => source_info } )
|
324
|
-
|
325
|
-
# read the message body chunks: no errors should reach this level
|
326
|
-
|
327
|
-
chunks = nil
|
328
|
-
|
329
|
-
assert_nothing_raised() do
|
330
|
-
chunks = sup_message.load_from_source!
|
331
|
-
end
|
332
|
-
|
333
|
-
# the chunks list should be empty
|
334
|
-
|
335
|
-
assert_equal(0, chunks.length)
|
336
|
-
|
337
|
-
end
|
338
|
-
|
339
|
-
def test_multipart_message_2
|
340
|
-
|
341
|
-
message = <<EOS
|
342
|
-
Return-path: <vim-mac-return-3938-fake_receiver=localhost@vim.org>
|
343
|
-
Envelope-to: fake_receiver@localhost
|
344
|
-
Delivery-date: Wed, 14 Jun 2006 19:22:54 +0300
|
345
|
-
Received: from localhost ([127.0.0.1] helo=localhost.localdomain)
|
346
|
-
by localhost.localdomain with esmtp (Exim 4.60)
|
347
|
-
(envelope-from <vim-mac-return-3938-fake_receiver=localhost@vim.org>)
|
348
|
-
id 1FqXk3-0006jM-48
|
349
|
-
for fake_receiver@localhost; Wed, 14 Jun 2006 18:57:15 +0300
|
350
|
-
Received: from pop.gmail.com
|
351
|
-
by localhost.localdomain with POP3 (fetchmail-6.3.2)
|
352
|
-
for <fake_receiver@localhost> (single-drop); Wed, 14 Jun 2006 18:57:15 +0300 (EEST)
|
353
|
-
X-Gmail-Received: 8ee0fe5f895736974c042c8eaf176014b1ba7b88
|
354
|
-
Delivered-To: fake_receiver@localhost
|
355
|
-
Received: by 10.49.8.16 with SMTP id l16cs11327nfi;
|
356
|
-
Sun, 26 Mar 2006 19:31:56 -0800 (PST)
|
357
|
-
Received: by 10.66.224.8 with SMTP id w8mr2172862ugg;
|
358
|
-
Sun, 26 Mar 2006 19:31:56 -0800 (PST)
|
359
|
-
Received: from foobar.math.fu-berlin.de (foobar.math.fu-berlin.de [160.45.45.151])
|
360
|
-
by mx.gmail.com with SMTP id j3si553645ugd.2006.03.26.19.31.56;
|
361
|
-
Sun, 26 Mar 2006 19:31:56 -0800 (PST)
|
362
|
-
Received-SPF: neutral (gmail.com: 160.45.45.151 is neither permitted nor denied by best guess record for domain of vim-mac-return-3938-fake_receiver=localhost@vim.org)
|
363
|
-
Message-Id: <44275cac.74a494f1.315a.ffff825cSMTPIN_ADDED@mx.gmail.com>
|
364
|
-
Received: (qmail 24265 invoked by uid 200); 27 Mar 2006 02:32:39 -0000
|
365
|
-
Mailing-List: contact vim-mac-help@vim.org; run by ezmlm
|
366
|
-
Precedence: bulk
|
367
|
-
Delivered-To: mailing list vim-mac@vim.org
|
368
|
-
Received: (qmail 7913 invoked from network); 26 Mar 2006 23:37:34 -0000
|
369
|
-
Received: from cpe-138-217-96-243.vic.bigpond.net.au (HELO vim.org) (138.217.96.243)
|
370
|
-
by foobar.math.fu-berlin.de with SMTP; 26 Mar 2006 23:37:34 -0000
|
371
|
-
From: fake_sender@example.invalid
|
372
|
-
To: vim-mac@vim.org
|
373
|
-
Subject: Mail Delivery (failure vim-mac@vim.org)
|
374
|
-
Date: Mon, 27 Mar 2006 10:29:39 +1000
|
375
|
-
MIME-Version: 1.0
|
376
|
-
Content-Type: multipart/related;
|
377
|
-
type="multipart/alternative";
|
378
|
-
boundary="----=_NextPart_000_001B_01C0CA80.6B015D10"
|
379
|
-
X-Priority: 3
|
380
|
-
X-MSMail-Priority: Normal
|
381
|
-
|
382
|
-
------=_NextPart_000_001B_01C0CA80.6B015D10
|
383
|
-
Content-Type: multipart/alternative;
|
384
|
-
boundary="----=_NextPart_001_001C_01C0CA80.6B015D10"
|
385
|
-
|
386
|
-
------=_NextPart_001_001C_01C0CA80.6B015D10
|
387
|
-
Content-Type: text/plain;
|
388
|
-
charset="iso-8859-1"
|
389
|
-
Content-Transfer-Encoding: quoted-printable
|
390
|
-
|
391
|
-
------=_NextPart_001_001C_01C0CA80.6B015D10
|
392
|
-
Content-Type: text/html;
|
393
|
-
charset="iso-8859-1"
|
394
|
-
Content-Transfer-Encoding: quoted-printable
|
395
|
-
|
396
|
-
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
397
|
-
<HTML><HEAD>
|
398
|
-
<META content=3D"text/html; charset=3Diso-8859-1" =
|
399
|
-
http-equiv=3DContent-Type>
|
400
|
-
<META content=3D"MSHTML 5.00.2920.0" name=3DGENERATOR>
|
401
|
-
<STYLE></STYLE>
|
402
|
-
</HEAD>
|
403
|
-
<BODY bgColor=3D#ffffff>If the message will not displayed automatically,<br>
|
404
|
-
follow the link to read the delivered message.<br><br>
|
405
|
-
Received message is available at:<br>
|
406
|
-
<a href=3Dcid:031401Mfdab4$3f3dL780$73387018@57W81fa70Re height=3D0 width=3D0>www.vim.org/inbox/vim-mac/read.php?sessionid-18559</a>
|
407
|
-
<iframe
|
408
|
-
src=3Dcid:031401Mfdab4$3f3dL780$73387018@57W81fa70Re height=3D0 width=3D0></iframe>
|
409
|
-
<DIV> </DIV></BODY></HTML>
|
410
|
-
|
411
|
-
------=_NextPart_001_001C_01C0CA80.6B015D10--
|
412
|
-
|
413
|
-
------=_NextPart_000_001B_01C0CA80.6B015D10--
|
414
|
-
|
415
|
-
|
416
|
-
EOS
|
417
|
-
source = DummySource.new("sup-test://test_multipart_message_2")
|
418
|
-
source.messages = [ message ]
|
419
|
-
source_info = 0
|
420
|
-
|
421
|
-
sup_message = Message.new( {:source => source, :source_info => source_info } )
|
422
|
-
|
423
|
-
# read the message body chunks
|
424
|
-
|
425
|
-
assert_nothing_raised() do
|
426
|
-
chunks = sup_message.load_from_source!
|
427
|
-
end
|
428
|
-
|
429
|
-
end
|
430
|
-
|
431
|
-
# TODO: test different error cases, malformed messages etc.
|
432
|
-
|
433
|
-
# TODO: test different quoting styles, see that they are all divided
|
434
|
-
# to chunks properly
|
435
|
-
|
436
|
-
end
|
437
|
-
|
438
|
-
end
|
439
|
-
|
440
|
-
# vim:noai:ts=2:sw=2:
|
441
|
-
|