sup 0.0.1 → 0.0.2
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/History.txt +7 -0
- data/Manifest.txt +2 -0
- data/README.txt +25 -21
- data/bin/sup +29 -25
- data/bin/sup-import +43 -13
- data/doc/FAQ.txt +8 -6
- data/doc/Philosophy.txt +17 -18
- data/doc/TODO +6 -0
- data/lib/sup.rb +7 -6
- data/lib/sup/buffer.rb +28 -17
- data/lib/sup/draft.rb +27 -23
- data/lib/sup/imap.rb +107 -0
- data/lib/sup/index.rb +47 -55
- data/lib/sup/logger.rb +1 -2
- data/lib/sup/mbox.rb +2 -2
- data/lib/sup/mbox/loader.rb +63 -66
- data/lib/sup/message.rb +45 -25
- data/lib/sup/mode.rb +1 -0
- data/lib/sup/modes/buffer-list-mode.rb +4 -4
- data/lib/sup/modes/edit-message-mode.rb +4 -4
- data/lib/sup/modes/inbox-mode.rb +2 -0
- data/lib/sup/modes/label-list-mode.rb +1 -1
- data/lib/sup/modes/log-mode.rb +1 -1
- data/lib/sup/modes/poll-mode.rb +2 -2
- data/lib/sup/modes/reply-mode.rb +6 -3
- data/lib/sup/modes/resume-mode.rb +25 -0
- data/lib/sup/modes/scroll-mode.rb +7 -0
- data/lib/sup/modes/thread-index-mode.rb +8 -11
- data/lib/sup/modes/thread-view-mode.rb +31 -3
- data/lib/sup/poll.rb +24 -10
- data/lib/sup/sent.rb +8 -8
- data/lib/sup/source.rb +64 -0
- data/lib/sup/thread.rb +3 -0
- data/lib/sup/util.rb +2 -2
- metadata +4 -2
data/History.txt
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
== 0.0.2 / 2006-12-10
|
2
|
+
|
3
|
+
* IMAP support
|
4
|
+
* Better handling of broken sources. (Everything won't just die.)
|
5
|
+
* You will need to rebuild both your index, and sources.yaml.
|
6
|
+
Sorry!
|
7
|
+
|
1
8
|
== 0.0.1 / 2006-11-28
|
2
9
|
|
3
10
|
* Initial release. Unix-centrism, support for mbox only, no i18n.
|
data/Manifest.txt
CHANGED
data/README.txt
CHANGED
@@ -31,16 +31,15 @@ Features:
|
|
31
31
|
message level. Entire threads are manipulated and viewed (with
|
32
32
|
redundancies removed) at a time.
|
33
33
|
|
34
|
-
- Labels
|
35
|
-
much easier it is to organize email.
|
34
|
+
- Labels instead of folders. Drop that tired old metaphor and you'll
|
35
|
+
see how much easier it is to organize email.
|
36
36
|
|
37
37
|
- GMail-style thread management. Archive a thread, and it will
|
38
38
|
disappear from your inbox until someone replies. Kill a thread, and
|
39
39
|
it will never come back to your inbox. (But it will still show up in
|
40
40
|
searches, of course.)
|
41
41
|
|
42
|
-
- Console based
|
43
|
-
clicking required!
|
42
|
+
- Console based interface. No mouse clicking required!
|
44
43
|
|
45
44
|
- Programmability. It's in Ruby. The code is good. It's easy to
|
46
45
|
extend.
|
@@ -48,39 +47,45 @@ Features:
|
|
48
47
|
- Multiple buffer support. Why be limited to viewing one thread at a
|
49
48
|
time?
|
50
49
|
|
51
|
-
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
- Mutt-style MIME attachment viewing.
|
50
|
+
- Tons of other little features, like automatic context-sensitive
|
51
|
+
help, multi-message operations, MIME attachment viewing, recent
|
52
|
+
contact list generation, etc.
|
56
53
|
|
57
54
|
Current limitations which will be fixed:
|
58
55
|
|
59
|
-
- Support for mbox
|
60
|
-
GMail
|
56
|
+
- Support for mbox and IMAP only at this point. No support for POP, mh,
|
57
|
+
or GMail mailstores.
|
61
58
|
|
62
59
|
- No internationalization support. No wide characters, no subject
|
63
60
|
demangling.
|
64
61
|
|
65
|
-
-
|
62
|
+
- Unix-centrism in MIME attachment handling and in sendmail
|
63
|
+
invocation.
|
66
64
|
|
67
|
-
-
|
65
|
+
- Several obvious missing features, like undo, filters / saved
|
66
|
+
searches, message annotations, etc.
|
68
67
|
|
69
68
|
== SYNOPSYS:
|
70
69
|
|
71
|
-
1. sup-import <
|
70
|
+
1. sup-import <source>+
|
72
71
|
2. sup
|
73
72
|
3. edit ~/.sup/config.yaml for the (very few) settings sup has
|
74
73
|
|
74
|
+
Where <source> is a filename (for mbox files), or an imap or imaps
|
75
|
+
url. In the case of imap, don't put the username and password in
|
76
|
+
the URI (which is a terrible, terrible idea). You will be prompted
|
77
|
+
for them.
|
78
|
+
|
75
79
|
sup-import has several options which control whether you want
|
76
80
|
messages from particular mailboxes not to be added to the inbox,
|
77
81
|
or not to be marked as new, so run it with -h for help.
|
78
82
|
|
79
|
-
Note that Sup
|
80
|
-
shouldn't ever corrupt your mail. The flip
|
81
|
-
change a mailbox (e.g. delete
|
83
|
+
Note that Sup never changes the contents of any mailboxes; it only
|
84
|
+
indexes in to them. So it shouldn't ever corrupt your mail. The flip
|
85
|
+
side is that if you change a mailbox (e.g. delete messages, or, in
|
86
|
+
the case of mbox files, read an unread message) then Sup may crash,
|
82
87
|
and will tell you to run sup-import --rebuild to recalculate the
|
83
|
-
offsets within the mailbox
|
88
|
+
offsets within the mailbox.
|
84
89
|
|
85
90
|
== REQUIREMENTS:
|
86
91
|
|
@@ -93,10 +98,9 @@ Current limitations which will be fixed:
|
|
93
98
|
* gem install sup -y
|
94
99
|
* Then, in rmail, change line 159 of multipart.rb to:
|
95
100
|
chunk = chunk[0..start]
|
96
|
-
(Sorry
|
101
|
+
(Sorry; it's an unsupported package.) You might be able to get away
|
97
102
|
without doing this but if you get frozen string exceptions when
|
98
|
-
reading in multipart
|
99
|
-
change.
|
103
|
+
reading in multipart messages, this is what you need to change.
|
100
104
|
|
101
105
|
== LICENSE:
|
102
106
|
|
data/bin/sup
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#!/bin/env ruby
|
1
|
+
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require 'rubygems'
|
4
4
|
require 'ncurses'
|
@@ -7,6 +7,17 @@ require "sup"
|
|
7
7
|
module Redwood
|
8
8
|
|
9
9
|
$exception = nil
|
10
|
+
def reporting_thread
|
11
|
+
::Thread.new do
|
12
|
+
begin
|
13
|
+
yield
|
14
|
+
rescue Exception => e
|
15
|
+
$exception ||= e
|
16
|
+
raise
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
module_function :reporting_thread
|
10
21
|
|
11
22
|
global_keymap = Keymap.new do |k|
|
12
23
|
k.add :quit, "Quit Redwood", 'q'
|
@@ -99,15 +110,6 @@ begin
|
|
99
110
|
log "initializing buffer manager"
|
100
111
|
bm = BufferManager.new
|
101
112
|
|
102
|
-
if Index.usual_sources.any? { |s| !s.done? }
|
103
|
-
log "polling for new mail"
|
104
|
-
pmode = PollMode.new
|
105
|
-
pbuf = bm.spawn "load new messages", pmode
|
106
|
-
pmode.poll
|
107
|
-
# sleep 1
|
108
|
-
# bm.kill_buffer pbuf
|
109
|
-
end
|
110
|
-
|
111
113
|
log "initializing mail index buffer"
|
112
114
|
imode = InboxMode.new
|
113
115
|
ibuf = bm.spawn "inbox", imode
|
@@ -118,6 +120,8 @@ begin
|
|
118
120
|
bm.draw_screen
|
119
121
|
imode.load_more_threads ibuf.content_height
|
120
122
|
|
123
|
+
reporting_thread { sleep 3; PollManager.poll }
|
124
|
+
|
121
125
|
until $exception
|
122
126
|
bm.draw_screen
|
123
127
|
c = Ncurses.nonblocking_getch
|
@@ -139,7 +143,7 @@ begin
|
|
139
143
|
when :roll_buffers_backwards
|
140
144
|
bm.roll_buffers_backwards
|
141
145
|
when :kill_buffer
|
142
|
-
bm.kill_buffer bm.focus_buf
|
146
|
+
bm.kill_buffer bm.focus_buf if bm.focus_buf.mode.killable?
|
143
147
|
when :list_buffers
|
144
148
|
bm.spawn_unless_exists("Buffer List") { BufferListMode.new }
|
145
149
|
when :list_contacts
|
@@ -168,10 +172,8 @@ begin
|
|
168
172
|
bm.spawn "new message", mode
|
169
173
|
mode.edit
|
170
174
|
when :poll
|
171
|
-
|
172
|
-
|
173
|
-
end
|
174
|
-
b.mode.poll
|
175
|
+
BufferManager.raise_to_front PollManager.buffer
|
176
|
+
PollManager.poll
|
175
177
|
when :nothing
|
176
178
|
when :redraw
|
177
179
|
bm.completely_redraw_screen
|
@@ -193,21 +195,25 @@ end
|
|
193
195
|
Index.save unless $exception # TODO: think about this
|
194
196
|
|
195
197
|
if $exception
|
196
|
-
|
198
|
+
case $exception
|
199
|
+
when IndexError
|
197
200
|
$stderr.puts <<EOS
|
198
|
-
An error occurred while
|
201
|
+
An error occurred while parsing a message from source:
|
202
|
+
#{$exception.source}.
|
199
203
|
Typically, this means that the source has been modified in some
|
200
|
-
way which has rendered the messages invalid.
|
204
|
+
way which has rendered the messages invalid. For example, if it's
|
205
|
+
an mbox file, you may have read or deleted messages using another
|
206
|
+
mail client.
|
201
207
|
|
202
208
|
You must rebuild the index for this source. Please run:
|
203
209
|
sup-import --rebuild #{$exception.source}
|
204
210
|
to correct this error.
|
205
211
|
EOS
|
206
|
-
|
212
|
+
#' stupid ruby-mode
|
207
213
|
else
|
208
214
|
$stderr.puts <<EOS
|
209
|
-
|
210
|
-
I'm very sorry, but it seems that an error occurred in
|
215
|
+
----------------------------------------------------------------
|
216
|
+
I'm very sorry, but it seems that an error occurred in Sup.
|
211
217
|
Please accept my sincere apologies. If you don't mind, please
|
212
218
|
send the backtrace below and a brief report of the circumstances
|
213
219
|
to user wmorgan-sup at site masanjin dot net so that I might
|
@@ -215,15 +221,13 @@ address this problem. Thank you!
|
|
215
221
|
|
216
222
|
Sincerely,
|
217
223
|
William
|
218
|
-
|
224
|
+
----------------------------------------------------------------
|
219
225
|
|
220
226
|
The problem was: #{$exception.message} (error type #{$exception.class.name})
|
221
227
|
A backtrace follows:
|
222
228
|
EOS
|
223
|
-
raise $exception
|
224
229
|
end
|
230
|
+
raise $exception
|
225
231
|
end
|
226
232
|
|
227
|
-
|
228
233
|
end
|
229
|
-
|
data/bin/sup-import
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#!/bin/env ruby
|
1
|
+
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require "sup"
|
4
4
|
|
@@ -27,7 +27,7 @@ source list.
|
|
27
27
|
Usage:
|
28
28
|
sup-import [options] <source>*
|
29
29
|
where <source>* is zero or more source descriptions (e.g., mbox
|
30
|
-
filenames on disk).
|
30
|
+
filenames on disk, or imap/imaps URIs).
|
31
31
|
|
32
32
|
If the sources listed are not already in the Sup source list,
|
33
33
|
they will be added to it, as parameterized by the following options:
|
@@ -54,7 +54,6 @@ The following options can also be specified:
|
|
54
54
|
--optimize: optimize the index after adding any new messages.
|
55
55
|
--help: don't do anything, just show this message.
|
56
56
|
EOS
|
57
|
-
#' stupid ruby-mode
|
58
57
|
exit
|
59
58
|
end
|
60
59
|
|
@@ -68,6 +67,12 @@ the_usual = ARGV.delete "--the-usual"
|
|
68
67
|
rebuild = ARGV.delete "--rebuild"
|
69
68
|
force_rebuild = ARGV.delete "--force-rebuild"
|
70
69
|
optimize = ARGV.delete "--optimize"
|
70
|
+
start_at = # ok really need to use optparse or something now
|
71
|
+
if(i = ARGV.index("--start-at"))
|
72
|
+
raise "start-at requires a numeric argument: #{ARGV[i + 1].inspect}" unless ARGV.length > (i + 1) && ARGV[i + 1] =~ /\d/
|
73
|
+
ARGV.delete_at i
|
74
|
+
ARGV.delete_at(i).to_i # whoa!
|
75
|
+
end
|
71
76
|
|
72
77
|
if(o = ARGV.find { |x| x =~ /^--/ })
|
73
78
|
$stderr.puts "error: unknown option #{o}"
|
@@ -77,24 +82,45 @@ end
|
|
77
82
|
puts "loading index..."
|
78
83
|
index = Redwood::Index.new
|
79
84
|
index.load
|
80
|
-
pre_nm = index.size
|
81
85
|
puts "loaded index of #{index.size} messages"
|
82
86
|
|
83
87
|
sources = ARGV.map do |fn|
|
88
|
+
fn = "mbox://#{fn}" unless fn =~ %r!://!
|
84
89
|
source = index.source_for fn
|
85
90
|
unless source
|
86
|
-
source =
|
91
|
+
source =
|
92
|
+
case fn
|
93
|
+
when %r!^imaps?://!
|
94
|
+
print "Username for #{fn}: "
|
95
|
+
username = $stdin.gets.chomp
|
96
|
+
print "Password for #{fn} (warning: cleartext): "
|
97
|
+
password = $stdin.gets.chomp
|
98
|
+
Redwood::IMAP.new(fn, username, password, nil, !unusual, !!archive)
|
99
|
+
else
|
100
|
+
Redwood::MBox::Loader.new(fn, nil, !unusual, !!archive)
|
101
|
+
end
|
87
102
|
index.add_source source
|
88
103
|
end
|
89
104
|
source
|
90
105
|
end
|
106
|
+
|
91
107
|
sources = (sources + index.usual_sources).uniq if the_usual
|
92
|
-
|
108
|
+
if rebuild || force_rebuild
|
109
|
+
if start_at
|
110
|
+
sources.each { |s| s.seek_to! start_at }
|
111
|
+
else
|
112
|
+
sources.each { |s| s.reset! }
|
113
|
+
end
|
114
|
+
end
|
93
115
|
|
94
116
|
found = {}
|
95
117
|
start = Time.now
|
96
118
|
begin
|
97
119
|
sources.each do |source|
|
120
|
+
if source.broken?
|
121
|
+
puts "error loading messages from #{source}: #{source.broken_msg}"
|
122
|
+
next
|
123
|
+
end
|
98
124
|
next if source.done?
|
99
125
|
puts "loading from #{source}... "
|
100
126
|
num = 0
|
@@ -104,15 +130,15 @@ begin
|
|
104
130
|
labels -= [:inbox] if force_archive
|
105
131
|
labels -= [:unread] if force_read
|
106
132
|
begin
|
107
|
-
m = Redwood::Message.new source, offset, labels
|
133
|
+
m = Redwood::Message.new :source => source, :source_info => offset, :labels => labels
|
108
134
|
if found[m.id]
|
109
135
|
puts "skipping duplicate message #{m.id}"
|
110
136
|
next
|
111
137
|
else
|
112
138
|
found[m.id] = true
|
113
139
|
end
|
114
|
-
|
115
|
-
|
140
|
+
m.remove_label :unread if m.status == "RO" unless force_read
|
141
|
+
puts "# message at #{offset}, labels: #{labels * ', '}" unless rebuild || force_rebuild
|
116
142
|
if (rebuild || force_rebuild) &&
|
117
143
|
(docid, entry = index.load_entry_for_id(m.id)) && entry
|
118
144
|
if force_rebuild || entry[:source_info].to_i != offset
|
@@ -123,7 +149,7 @@ begin
|
|
123
149
|
else
|
124
150
|
num += 1 if index.add_message m
|
125
151
|
end
|
126
|
-
rescue Redwood::MessageFormatError => e
|
152
|
+
rescue Redwood::MessageFormatError, Redwood::SourceError => e
|
127
153
|
$stderr.puts "ignoring erroneous message at #{source}##{offset}: #{e.message}"
|
128
154
|
end
|
129
155
|
if num % 1000 == 0 && num > 0
|
@@ -141,18 +167,22 @@ end
|
|
141
167
|
|
142
168
|
if rebuild || force_rebuild
|
143
169
|
puts "deleting missing messages from the index..."
|
144
|
-
numdel = 0
|
170
|
+
numdel = num = 0
|
145
171
|
sources.each do |source|
|
146
172
|
raise "no source id for #{source}" unless source.id
|
147
|
-
|
173
|
+
q = "+source_id:#{source.id}"
|
174
|
+
q += " +source_info: >= #{start_at}" if start_at
|
175
|
+
#p q
|
176
|
+
num += index.index.search_each(q, :limit => :all) do |docid, score|
|
148
177
|
mid = index.index[docid][:message_id]
|
149
178
|
next if found[mid]
|
150
179
|
puts "deleting #{mid}"
|
151
180
|
index.index.delete docid
|
152
181
|
numdel += 1
|
153
182
|
end
|
183
|
+
#p num
|
154
184
|
end
|
155
|
-
puts "deleted #{numdel} messages"
|
185
|
+
puts "deleted #{numdel} / #{num} messages"
|
156
186
|
end
|
157
187
|
|
158
188
|
if optimize
|
data/doc/FAQ.txt
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
Sup FAQ
|
2
2
|
-------
|
3
|
+
Q: What does Sup stand for?
|
4
|
+
A: "What's up?".
|
3
5
|
|
4
6
|
Q: How is Sup even possible?
|
5
7
|
A: Sup is only possible through the hard work of Dave Balmain, the
|
@@ -7,17 +9,17 @@ A: Sup is only possible through the hard work of Dave Balmain, the
|
|
7
9
|
|
8
10
|
I started using Ferret when it was still slightly buggy, and it
|
9
11
|
seemed like every week Dave released a bugfix or a speed
|
10
|
-
improvement that directly affected sup.
|
11
|
-
first-class piece of software, and it's
|
12
|
-
|
12
|
+
improvement that directly affected sup. Ferret has become a
|
13
|
+
first-class piece of software, and it's due to the tremendous
|
14
|
+
amount of time and effort he's put in to it.
|
13
15
|
|
14
16
|
Q: Why the console?
|
15
17
|
A: As the millions (ok, hundreds) of mutt users will tell you, there are
|
16
18
|
many advantages to the console:
|
17
|
-
- You don't need
|
18
|
-
- You can ssh and check your mail on another machine.
|
19
|
+
- You don't need web browser.
|
19
20
|
- Instantaneous interaction.
|
20
|
-
- A few keystrokes
|
21
|
+
- A few keystrokes can accomplish the work of a hundred mouse
|
22
|
+
clicks.
|
21
23
|
|
22
24
|
Q: If you love GMail so much, why not just use it?
|
23
25
|
A: I hate using a mouse, and I hate ads, and I hate non-programmability.
|
data/doc/Philosophy.txt
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
Should an email client have a philosophy? I think so. For many people,
|
2
|
+
email is our primary means of communication. Something so important
|
3
|
+
ought to warrant a little thought.
|
4
4
|
|
5
5
|
So here's Sup's philosophy.
|
6
6
|
|
@@ -8,10 +8,10 @@ Using "traditional" email clients today is increasingly problematic.
|
|
8
8
|
Anyone who's on a high-traffic mailing list knows this. My ruby-talk
|
9
9
|
folder is 350 megs and Mutt sits there for 60 seconds while it opens
|
10
10
|
it. Keeping up with the all the new traffic is painful, even with
|
11
|
-
Mutt's excellent threading features,
|
12
|
-
it
|
13
|
-
best email client out there in
|
14
|
-
support.
|
11
|
+
Mutt's excellent threading features, simply because there's so much of
|
12
|
+
it---a single thread can span several pages, and God help you if you
|
13
|
+
lag behind. And Mutt is probably the best email client out there in
|
14
|
+
terms of threading and mailing list support.
|
15
15
|
|
16
16
|
The principle problem with traditional clients is that they place a
|
17
17
|
high mental cost on the user for each incoming email, by forcing them
|
@@ -29,15 +29,16 @@ to answer.
|
|
29
29
|
As a long-time Mutt user, when I watched people use GMail, I saw them
|
30
30
|
use email differently from how I had ever used it. I saw that making
|
31
31
|
certain operations quantitatively easier (namely, search) resulted in
|
32
|
-
a qualitative difference in usage
|
33
|
-
|
32
|
+
a qualitative difference in usage. And I saw that thread-centrism had
|
33
|
+
many advantages over message-centrism, especially when volume was high.
|
34
34
|
|
35
35
|
So, in many ways, I believe GMail has taken the right approach to
|
36
36
|
handle both of the factors above, and much of the inspiration for Sup
|
37
|
-
was based on
|
38
|
-
|
37
|
+
was based on GMail. Ultimately, GMail wasn't right for me, which is
|
38
|
+
why the idea for Sup was born.
|
39
39
|
|
40
|
-
Sup is based on the following principles, which I
|
40
|
+
Sup is based on the following principles, which I more or less stole
|
41
|
+
directly from GMail:
|
41
42
|
|
42
43
|
- An immediately accessible and fast search capability over the
|
43
44
|
entire email archive eliminates most of the need for folders,
|
@@ -50,10 +51,8 @@ Sup is based on the following principles, which I learned from GMail:
|
|
50
51
|
and its content deserve the same treatment in the vast majority
|
51
52
|
of cases.
|
52
53
|
|
53
|
-
Sup is also based on many ideas from mutt
|
54
|
-
|
55
|
-
application,
|
56
|
-
|
57
|
-
less of the philosophy and more of the general usefulness of Sup.
|
58
|
-
|
54
|
+
Sup is also based on many ideas from mutt and Emacs and vi, having to
|
55
|
+
do with the fantastic productivity of a console- and keyboard-based
|
56
|
+
application, the usefulness of multiple buffers, the necessity of
|
57
|
+
handling multiple email accounts, etc.
|
59
58
|
|