sup 0.8.1 → 0.9
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 +13 -6
- data/History.txt +19 -0
- data/ReleaseNotes +35 -0
- data/bin/sup +82 -77
- data/bin/sup-add +7 -7
- data/bin/sup-config +104 -85
- data/bin/sup-dump +4 -5
- data/bin/sup-recover-sources +9 -10
- data/bin/sup-sync +121 -100
- data/bin/sup-sync-back +18 -15
- data/bin/sup-tweak-labels +24 -21
- data/lib/sup.rb +53 -33
- data/lib/sup/account.rb +0 -2
- data/lib/sup/buffer.rb +47 -22
- data/lib/sup/colormap.rb +6 -6
- data/lib/sup/contact.rb +0 -2
- data/lib/sup/crypto.rb +34 -23
- data/lib/sup/draft.rb +6 -14
- data/lib/sup/ferret_index.rb +471 -0
- data/lib/sup/hook.rb +30 -43
- data/lib/sup/hook.rb.BACKUP.8625.rb +158 -0
- data/lib/sup/hook.rb.BACKUP.8681.rb +158 -0
- data/lib/sup/hook.rb.BASE.8625.rb +155 -0
- data/lib/sup/hook.rb.BASE.8681.rb +155 -0
- data/lib/sup/hook.rb.LOCAL.8625.rb +142 -0
- data/lib/sup/hook.rb.LOCAL.8681.rb +142 -0
- data/lib/sup/hook.rb.REMOTE.8625.rb +145 -0
- data/lib/sup/hook.rb.REMOTE.8681.rb +145 -0
- data/lib/sup/imap.rb +18 -8
- data/lib/sup/index.rb +70 -528
- data/lib/sup/interactive-lock.rb +74 -0
- data/lib/sup/keymap.rb +26 -26
- data/lib/sup/label.rb +2 -4
- data/lib/sup/logger.rb +54 -35
- data/lib/sup/maildir.rb +41 -6
- data/lib/sup/mbox.rb +1 -1
- data/lib/sup/mbox/loader.rb +18 -6
- data/lib/sup/mbox/ssh-file.rb +1 -7
- data/lib/sup/message-chunks.rb +36 -23
- data/lib/sup/message.rb +126 -46
- data/lib/sup/mode.rb +3 -2
- data/lib/sup/modes/console-mode.rb +108 -0
- data/lib/sup/modes/edit-message-mode.rb +15 -5
- data/lib/sup/modes/inbox-mode.rb +2 -4
- data/lib/sup/modes/label-list-mode.rb +1 -1
- data/lib/sup/modes/line-cursor-mode.rb +18 -18
- data/lib/sup/modes/log-mode.rb +29 -16
- data/lib/sup/modes/poll-mode.rb +7 -9
- data/lib/sup/modes/reply-mode.rb +5 -3
- data/lib/sup/modes/scroll-mode.rb +2 -2
- data/lib/sup/modes/search-results-mode.rb +9 -11
- data/lib/sup/modes/text-mode.rb +2 -2
- data/lib/sup/modes/thread-index-mode.rb +26 -16
- data/lib/sup/modes/thread-view-mode.rb +84 -39
- data/lib/sup/person.rb +6 -8
- data/lib/sup/poll.rb +46 -47
- data/lib/sup/rfc2047.rb +1 -5
- data/lib/sup/sent.rb +27 -20
- data/lib/sup/source.rb +90 -13
- data/lib/sup/textfield.rb +4 -4
- data/lib/sup/thread.rb +15 -13
- data/lib/sup/undo.rb +0 -1
- data/lib/sup/update.rb +0 -1
- data/lib/sup/util.rb +51 -43
- data/lib/sup/xapian_index.rb +566 -0
- metadata +57 -46
- data/lib/sup/suicide.rb +0 -36
data/CONTRIBUTORS
CHANGED
@@ -1,4 +1,8 @@
|
|
1
|
+
William Morgan <wmorgan-sup at the masanjin dot nets>
|
2
|
+
Rich Lane <rlane at the club.cc.cmu dot edus>
|
3
|
+
Ismo Puustinen <ismo at the iki dot fis>
|
1
4
|
Nicolas Pouillard <nicolas.pouillard at the gmail dot coms>
|
5
|
+
Ben Walton <bwalton at the artsci.utoronto dot cas>
|
2
6
|
Mike Stipicevic <stipim at the rpi dot edus>
|
3
7
|
Marcus Williams <marcus-sup at the bar-coded dot nets>
|
4
8
|
Lionel Ott <white.magic at the gmx dot des>
|
@@ -6,17 +10,20 @@ Ingmar Vanhassel <ingmar at the exherbo dot orgs>
|
|
6
10
|
Mark Alexander <marka at the pobox dot coms>
|
7
11
|
Christopher Warrington <chrisw at the rice dot edus>
|
8
12
|
Richard Brown <rbrown at the exherbo dot orgs>
|
9
|
-
Ben Walton <bwalton at the artsci.utoronto dot cas>
|
10
13
|
Marc Hartstein <marc.hartstein at the alum.vassar dot edus>
|
14
|
+
Israel Herraiz <israel.herraiz at the gmail dot coms>
|
11
15
|
Grant Hollingworth <grant at the antiflux dot orgs>
|
16
|
+
Adeodato Simó <dato at the net.com.org dot ess>
|
12
17
|
Steve Goldman <sgoldman at the tower-research dot coms>
|
18
|
+
Edward Z. Yang <ezyang at the mit dot edus>
|
13
19
|
Decklin Foster <decklin at the red-bean dot coms>
|
14
|
-
|
20
|
+
Alex Vandiver <alex at the chmrr dot nets>
|
15
21
|
Jeff Balogh <its.jeff.balogh at the gmail dot coms>
|
16
|
-
|
22
|
+
Carl Worth <cworth at the cworth dot orgs>
|
23
|
+
Kornilios Kourtis <kkourt at the cslab.ece.ntua dot grs>
|
17
24
|
Giorgio Lando <patroclo7 at the gmail dot coms>
|
18
|
-
|
25
|
+
Benoît PIERRE <benoit.pierre at the gmail dot coms>
|
19
26
|
Ian Taylor <ian at the lorf dot orgs>
|
20
|
-
Stefan Lundström
|
21
|
-
|
27
|
+
Stefan Lundström
|
28
|
+
Michael Hamann <michael at the content-space dot des>
|
22
29
|
Kirill Smelkov <kirr at the landau.phys.spbu dot rus>
|
data/History.txt
CHANGED
@@ -1,3 +1,22 @@
|
|
1
|
+
== 0.9 / 2009-10-01
|
2
|
+
* Experimental Xapian backend to replace Ferret. Not everything works with it,
|
3
|
+
but it's fast and less likely to barf. See release notes.
|
4
|
+
* New keybinding: "G" for reply-all.
|
5
|
+
* New hook: custom-search, for adding your own query expansions.
|
6
|
+
* Better preemptive thread loading.
|
7
|
+
* Random UI tweaks: display labels before subjects, change thread-view-mode's
|
8
|
+
'n' and 'p' commands slightly
|
9
|
+
* Better killing of other Sup processes.
|
10
|
+
* Die gracefully upon SIGKILL.
|
11
|
+
* Finally figure out the curses+ruby magic to make SIGWINCH (i.e. xterm
|
12
|
+
resizing) work correctly.
|
13
|
+
* Add a console mode (press ~) for interactively playing with the index.
|
14
|
+
* Finally figure out the curses magic to stop the weird keyboard behavior after
|
15
|
+
leaving the editor.
|
16
|
+
* Improved logging. Logging now supports SUP_LOG_LEVEL environment variable.
|
17
|
+
Set this to "debug" for verbiage.
|
18
|
+
* As always, many bugfixes and tweaks.
|
19
|
+
|
1
20
|
== 0.8.1 / 2009-06-15
|
2
21
|
* make multibyte display "work" for non-utf8 locales
|
3
22
|
* fix reply-mode always selecting "Customized"
|
data/ReleaseNotes
CHANGED
@@ -1,3 +1,38 @@
|
|
1
|
+
Release 0.9:
|
2
|
+
|
3
|
+
There's a new Xapian backend as an alternative to the Ferret one. It's still in
|
4
|
+
a beta stage. It's much faster and much less prone to the random crashes than
|
5
|
+
Ferret, but certain things don't work yet, most noticeably the unread message
|
6
|
+
counts in label-list-mode.
|
7
|
+
|
8
|
+
You can switch back and forth between both indexes without harm, *except* any
|
9
|
+
new messages added to the one index won't be picked up by the other. Follow
|
10
|
+
these instructions:
|
11
|
+
|
12
|
+
To TRY the Xapian index, without screwing Ferret up:
|
13
|
+
|
14
|
+
1. sup-dump > dump # takes a while
|
15
|
+
2. export SUP_INDEX=xapian # or however you do it in your shell
|
16
|
+
3. sup-sync --all --all-sources --restore dump # takes a long time
|
17
|
+
4. sup -n # -n ensures that no polling is done. don't hit 'P' either
|
18
|
+
|
19
|
+
Step 1 will take a long time, and step 3 will take a very long time.
|
20
|
+
|
21
|
+
At this point, whenever you run Sup, the SUP_INDEX environment variable will
|
22
|
+
determine which index you use. If it's unset, or "ferret", you will use the
|
23
|
+
ferret index. If it's "xapian", the Xapian index. Make sure when you run sup
|
24
|
+
with the Xapian index, you use -n and don't hit 'P', to avoid loading new
|
25
|
+
messages into it.
|
26
|
+
|
27
|
+
If you want to switch to Xapian permanently, you can then:
|
28
|
+
|
29
|
+
1. rm -rf ~/.sup/ferret
|
30
|
+
2. permanently set SUP_INDEX=xapian according to your shell
|
31
|
+
3. Run sup as normal, i.e. without -n.
|
32
|
+
|
33
|
+
If you want to go back to Ferret, you can just rm -rf ~/.sup/xapian and make
|
34
|
+
sure your SUP_INDEX environment variable is unset.
|
35
|
+
|
1
36
|
Release 0.8.1:
|
2
37
|
|
3
38
|
A bugfix release with fixes for quote parsing (bad behavior in certain long
|
data/bin/sup
CHANGED
@@ -5,10 +5,9 @@ require 'ncurses'
|
|
5
5
|
require 'curses'
|
6
6
|
require 'fileutils'
|
7
7
|
require 'trollop'
|
8
|
-
require 'fastthread'
|
9
8
|
require "sup"
|
10
9
|
|
11
|
-
BIN_VERSION = "0.
|
10
|
+
BIN_VERSION = "0.9"
|
12
11
|
|
13
12
|
unless Redwood::VERSION == BIN_VERSION
|
14
13
|
$stderr.puts <<EOS
|
@@ -59,6 +58,7 @@ if $opts[:list_hooks]
|
|
59
58
|
end
|
60
59
|
|
61
60
|
Thread.abort_on_exception = true # make debugging possible
|
61
|
+
Thread.current.priority = 1 # keep ui responsive
|
62
62
|
|
63
63
|
module Redwood
|
64
64
|
|
@@ -79,6 +79,8 @@ global_keymap = Keymap.new do |k|
|
|
79
79
|
k.add :compose, "Compose new message", 'm', 'c'
|
80
80
|
k.add :nothing, "Do nothing", :ctrl_g
|
81
81
|
k.add :recall_draft, "Edit most recent draft message", 'R'
|
82
|
+
k.add :show_inbox, "Show the Inbox buffer", 'I'
|
83
|
+
k.add :show_console, "Show the Console buffer", '~'
|
82
84
|
end
|
83
85
|
|
84
86
|
## the following magic enables wide characters when used with a ruby
|
@@ -89,24 +91,24 @@ end
|
|
89
91
|
## BSD users: if libc.so.6 is not found, try installing compat6x.
|
90
92
|
require 'dl/import'
|
91
93
|
module LibC
|
92
|
-
extend DL::Importable
|
94
|
+
extend DL.const_defined?(:Importer) ? DL::Importer : DL::Importable
|
93
95
|
setlocale_lib = case Config::CONFIG['arch']
|
94
96
|
when /darwin/; "libc.dylib"
|
95
97
|
when /cygwin/; "cygwin1.dll"
|
96
98
|
else; "libc.so.6"
|
97
99
|
end
|
98
100
|
|
99
|
-
|
101
|
+
debug "dynamically loading setlocale() from #{setlocale_lib}"
|
100
102
|
begin
|
101
103
|
dlload setlocale_lib
|
102
104
|
extern "void setlocale(int, const char *)"
|
103
|
-
|
105
|
+
debug "setting locale..."
|
104
106
|
LibC.setlocale(6, "") # LC_ALL == 6
|
105
107
|
rescue RuntimeError => e
|
106
|
-
|
107
|
-
|
108
|
+
warn "cannot dlload setlocale(); ncurses wide character support probably broken."
|
109
|
+
warn "dlload error was #{e.class}: #{e.message}"
|
108
110
|
if Config::CONFIG['arch'] =~ /bsd/
|
109
|
-
|
111
|
+
warn "BSD variant detected. You may have to install a compat6x package to acquire libc."
|
110
112
|
end
|
111
113
|
end
|
112
114
|
end
|
@@ -130,80 +132,68 @@ def stop_cursing
|
|
130
132
|
end
|
131
133
|
module_function :start_cursing, :stop_cursing
|
132
134
|
|
133
|
-
Index.
|
134
|
-
|
135
|
-
Index.lock
|
136
|
-
rescue Index::LockError => e
|
137
|
-
require 'highline'
|
138
|
-
|
139
|
-
h = HighLine.new
|
140
|
-
h.wrap_at = :auto
|
141
|
-
h.say Index.fancy_lock_error_message_for(e)
|
142
|
-
|
143
|
-
case h.ask("Should I ask that process to kill itself? ")
|
144
|
-
when /^\s*y(es)?\s*$/i
|
145
|
-
h.say "Ok, suggesting seppuku..."
|
146
|
-
FileUtils.touch Redwood::SUICIDE_FN
|
147
|
-
sleep SuicideManager::DELAY * 2
|
148
|
-
FileUtils.rm_f Redwood::SUICIDE_FN
|
149
|
-
h.say "Let's try that again."
|
150
|
-
retry
|
151
|
-
else
|
152
|
-
h.say <<EOS
|
153
|
-
Ok, giving up. If the process crashed and left a stale lockfile, you
|
154
|
-
can fix this by manually deleting #{Index.lockfile}.
|
155
|
-
EOS
|
156
|
-
exit
|
157
|
-
end
|
158
|
-
end
|
135
|
+
Index.init
|
136
|
+
Index.lock_interactively or exit
|
159
137
|
|
160
138
|
begin
|
161
139
|
Redwood::start
|
162
140
|
Index.load
|
163
141
|
|
164
|
-
|
142
|
+
$die = false
|
143
|
+
trap("TERM") { |x| $die = true }
|
144
|
+
trap("WINCH") { |x| BufferManager.sigwinch_happened! }
|
145
|
+
|
146
|
+
if(s = Redwood::SourceManager.source_for DraftManager.source_name)
|
165
147
|
DraftManager.source = s
|
166
148
|
else
|
167
|
-
|
168
|
-
|
149
|
+
debug "no draft source, auto-adding..."
|
150
|
+
Redwood::SourceManager.add_source DraftManager.new_source
|
169
151
|
end
|
170
152
|
|
171
|
-
if(s =
|
153
|
+
if(s = Redwood::SourceManager.source_for SentManager.source_uri)
|
172
154
|
SentManager.source = s
|
173
155
|
else
|
174
|
-
Redwood::
|
175
|
-
Index.add_source SentManager.new_source
|
156
|
+
Redwood::SourceManager.add_source SentManager.default_source
|
176
157
|
end
|
177
158
|
|
178
159
|
HookManager.run "startup"
|
179
160
|
|
180
|
-
|
161
|
+
debug "starting curses"
|
162
|
+
Redwood::Logger.remove_sink $stderr
|
181
163
|
start_cursing
|
182
164
|
|
183
|
-
bm = BufferManager.
|
165
|
+
bm = BufferManager.init
|
184
166
|
Colormap.new.populate_colormap
|
185
167
|
|
186
|
-
|
168
|
+
debug "initializing log buffer"
|
169
|
+
lmode = Redwood::LogMode.new "system log"
|
170
|
+
lmode.on_kill { Logger.clear! }
|
171
|
+
Logger.add_sink lmode
|
172
|
+
Logger.force_message "Welcome to Sup! Log level is set to #{Logger.level}."
|
173
|
+
if Logger::LEVELS.index(Logger.level) > 0
|
174
|
+
Logger.force_message "For more verbose logging, restart with SUP_LOG_LEVEL=#{Logger::LEVELS[Logger::LEVELS.index(Logger.level)-1]}."
|
175
|
+
end
|
176
|
+
|
177
|
+
debug "initializing inbox buffer"
|
187
178
|
imode = InboxMode.new
|
188
179
|
ibuf = bm.spawn "Inbox", imode
|
189
180
|
|
190
|
-
|
191
|
-
Logger.make_buf
|
181
|
+
debug "ready for interaction!"
|
192
182
|
|
193
183
|
bm.draw_screen
|
194
184
|
|
195
|
-
|
185
|
+
Redwood::SourceManager.usual_sources.each do |s|
|
196
186
|
next unless s.respond_to? :connect
|
197
187
|
reporting_thread("call #connect on #{s}") do
|
198
188
|
begin
|
199
189
|
s.connect
|
200
190
|
rescue SourceError => e
|
201
|
-
|
191
|
+
error "fatal error loading from #{s}: #{e.message}"
|
202
192
|
end
|
203
193
|
end
|
204
194
|
end unless $opts[:no_initial_poll]
|
205
|
-
|
206
|
-
imode.load_threads :num => ibuf.content_height, :when_done => lambda { reporting_thread("poll after loading inbox") { sleep 1; PollManager.poll } unless $opts[:no_threads] || $opts[:no_initial_poll] }
|
195
|
+
|
196
|
+
imode.load_threads :num => ibuf.content_height, :when_done => lambda { |num| reporting_thread("poll after loading inbox") { sleep 1; PollManager.poll } unless $opts[:no_threads] || $opts[:no_initial_poll] }
|
207
197
|
|
208
198
|
if $opts[:compose]
|
209
199
|
ComposeMode.spawn_nicely :to_default => $opts[:compose]
|
@@ -211,7 +201,6 @@ begin
|
|
211
201
|
|
212
202
|
unless $opts[:no_threads]
|
213
203
|
PollManager.start
|
214
|
-
SuicideManager.start
|
215
204
|
Index.start_lock_update_thread
|
216
205
|
end
|
217
206
|
|
@@ -219,30 +208,40 @@ begin
|
|
219
208
|
SearchResultsMode.spawn_from_query $opts[:search]
|
220
209
|
end
|
221
210
|
|
222
|
-
until Redwood::exceptions.nonempty? ||
|
223
|
-
c =
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
211
|
+
until Redwood::exceptions.nonempty? || $die
|
212
|
+
c = begin
|
213
|
+
Ncurses.nonblocking_getch
|
214
|
+
rescue Interrupt
|
215
|
+
raise if BufferManager.ask_yes_or_no "Die ungracefully now?"
|
216
|
+
BufferManager.draw_screen
|
217
|
+
nil
|
218
|
+
end
|
219
|
+
|
220
|
+
if c.nil?
|
221
|
+
if BufferManager.sigwinch_happened?
|
222
|
+
debug "redrawing screen on sigwinch"
|
223
|
+
BufferManager.completely_redraw_screen
|
224
|
+
end
|
225
|
+
next
|
226
|
+
end
|
227
|
+
|
228
|
+
if c == 410
|
229
|
+
## this is ncurses's way of telling us it's detected a refresh.
|
230
|
+
## since we have our own sigwinch handler, we don't do anything.
|
231
|
+
next
|
232
|
+
end
|
233
|
+
|
234
234
|
bm.erase_flash
|
235
235
|
|
236
|
-
action =
|
237
|
-
|
238
|
-
if bm.handle_input c
|
239
|
-
:nothing
|
240
|
-
else
|
241
|
-
bm.resolve_input_with_keymap c, global_keymap
|
242
|
-
end
|
243
|
-
rescue InputSequenceAborted
|
236
|
+
action = begin
|
237
|
+
if bm.handle_input c
|
244
238
|
:nothing
|
239
|
+
else
|
240
|
+
bm.resolve_input_with_keymap c, global_keymap
|
245
241
|
end
|
242
|
+
rescue InputSequenceAborted
|
243
|
+
:nothing
|
244
|
+
end
|
246
245
|
case action
|
247
246
|
when :quit_now
|
248
247
|
break if bm.kill_all_buffers_safely
|
@@ -298,6 +297,11 @@ begin
|
|
298
297
|
b, new = BufferManager.spawn_unless_exists("All drafts") { LabelSearchResultsMode.new [:draft] }
|
299
298
|
b.mode.load_threads :num => b.content_height if new
|
300
299
|
end
|
300
|
+
when :show_inbox
|
301
|
+
BufferManager.raise_to_front ibuf
|
302
|
+
when :show_console
|
303
|
+
b, new = bm.spawn_unless_exists("Console", :system => true) { ConsoleMode.new }
|
304
|
+
b.mode.run
|
301
305
|
when :nothing, InputSequenceAborted
|
302
306
|
when :redraw
|
303
307
|
bm.completely_redraw_screen
|
@@ -308,13 +312,12 @@ begin
|
|
308
312
|
bm.draw_screen
|
309
313
|
end
|
310
314
|
|
311
|
-
bm.kill_all_buffers if
|
315
|
+
bm.kill_all_buffers if $die
|
312
316
|
rescue Exception => e
|
313
317
|
Redwood::record_exception e, "main"
|
314
318
|
ensure
|
315
319
|
unless $opts[:no_threads]
|
316
320
|
PollManager.stop if PollManager.instantiated?
|
317
|
-
SuicideManager.stop if PollManager.instantiated?
|
318
321
|
Index.stop_lock_update_thread
|
319
322
|
end
|
320
323
|
|
@@ -322,17 +325,19 @@ ensure
|
|
322
325
|
|
323
326
|
Redwood::finish
|
324
327
|
stop_cursing
|
325
|
-
Redwood::
|
328
|
+
Redwood::Logger.remove_all_sinks!
|
329
|
+
Redwood::Logger.add_sink $stderr, false
|
330
|
+
debug "stopped cursing"
|
326
331
|
|
327
|
-
if
|
328
|
-
|
332
|
+
if $die
|
333
|
+
info "I've been ordered to commit seppuku. I obey!"
|
329
334
|
end
|
330
335
|
|
331
336
|
if Redwood::exceptions.empty?
|
332
|
-
|
337
|
+
debug "no fatal errors. good job, william."
|
333
338
|
Index.save
|
334
339
|
else
|
335
|
-
|
340
|
+
error "oh crap, an exception"
|
336
341
|
end
|
337
342
|
|
338
343
|
Index.unlock
|
data/bin/sup-add
CHANGED
@@ -77,17 +77,17 @@ end
|
|
77
77
|
|
78
78
|
$terminal.wrap_at = :auto
|
79
79
|
Redwood::start
|
80
|
-
index = Redwood::Index.
|
80
|
+
index = Redwood::Index.init
|
81
81
|
|
82
|
-
index.
|
82
|
+
index.lock_interactively or exit
|
83
83
|
|
84
84
|
begin
|
85
|
-
|
85
|
+
Redwood::SourceManager.load_sources
|
86
86
|
|
87
87
|
ARGV.each do |uri|
|
88
88
|
labels = $opts[:labels] ? $opts[:labels].split(/\s*,\s*/).uniq : []
|
89
89
|
|
90
|
-
if !$opts[:force_new] &&
|
90
|
+
if !$opts[:force_new] && Redwood::SourceManager.source_for(uri)
|
91
91
|
say "Already know about #{uri}; skipping."
|
92
92
|
next
|
93
93
|
end
|
@@ -99,10 +99,10 @@ begin
|
|
99
99
|
when "mbox+ssh"
|
100
100
|
say "For SSH connections, if you will use public key authentication, you may leave the username and password blank."
|
101
101
|
say ""
|
102
|
-
username, password = get_login_info uri,
|
102
|
+
username, password = get_login_info uri, Redwood::SourceManager.sources
|
103
103
|
Redwood::MBox::SSHLoader.new uri, username, password, nil, !$opts[:unusual], $opts[:archive], nil, labels
|
104
104
|
when "imap", "imaps"
|
105
|
-
username, password = get_login_info uri,
|
105
|
+
username, password = get_login_info uri, Redwood::SourceManager.sources
|
106
106
|
Redwood::IMAP.new uri, username, password, nil, !$opts[:unusual], $opts[:archive], nil, labels
|
107
107
|
when "maildir"
|
108
108
|
Redwood::Maildir.new uri, nil, !$opts[:unusual], $opts[:archive], nil, labels
|
@@ -114,7 +114,7 @@ begin
|
|
114
114
|
Trollop::die "Unknown source type #{parsed_uri.scheme.inspect}"
|
115
115
|
end
|
116
116
|
say "Adding #{source}..."
|
117
|
-
|
117
|
+
Redwood::SourceManager.add_source source
|
118
118
|
end
|
119
119
|
ensure
|
120
120
|
index.save
|
data/bin/sup-config
CHANGED
@@ -17,15 +17,14 @@ Usage:
|
|
17
17
|
|
18
18
|
Options:
|
19
19
|
EOS
|
20
|
-
end
|
20
|
+
end
|
21
21
|
|
22
22
|
def axe q, default=nil
|
23
|
-
ans =
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
end
|
23
|
+
ans = if default && !default.empty?
|
24
|
+
ask "#{q} (enter for \"#{default}\"): "
|
25
|
+
else
|
26
|
+
ask "#{q}: "
|
27
|
+
end
|
29
28
|
ans.empty? ? default : ans
|
30
29
|
end
|
31
30
|
|
@@ -54,64 +53,62 @@ def add_source
|
|
54
53
|
while true do
|
55
54
|
say "Ok, now for the details."
|
56
55
|
|
57
|
-
default_labels, components =
|
58
|
-
|
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
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
host, port = srv, nil
|
103
|
-
end
|
104
|
-
[Redwood::IMAP.suggest_labels_for(fn),
|
105
|
-
{ :scheme => type.to_s, :host => host, :port => port, :path => fn }]
|
106
|
-
end
|
107
|
-
|
108
|
-
uri =
|
109
|
-
begin
|
110
|
-
URI::Generic.build components
|
111
|
-
rescue URI::Error => e
|
112
|
-
say "Whoopsie! I couldn't build a URI from that: #{e.message}"
|
113
|
-
if axe_yes("Try again?") then next else return end
|
56
|
+
default_labels, components = case type
|
57
|
+
when :mbox
|
58
|
+
$last_fn ||= ENV["MAIL"]
|
59
|
+
fn = axe "What's the full path to the mbox file?", $last_fn
|
60
|
+
return if fn.nil? || fn.empty?
|
61
|
+
|
62
|
+
$last_fn = fn
|
63
|
+
[Redwood::MBox::Loader.suggest_labels_for(fn),
|
64
|
+
{ :scheme => "mbox", :path => fn }]
|
65
|
+
when :maildir
|
66
|
+
$last_fn ||= ENV["MAIL"]
|
67
|
+
fn = axe "What's the full path to the maildir directory?", $last_fn
|
68
|
+
return if fn.nil? || fn.empty?
|
69
|
+
|
70
|
+
$last_fn = fn
|
71
|
+
[Redwood::Maildir.suggest_labels_for(fn),
|
72
|
+
{ :scheme => "maildir", :path => fn }]
|
73
|
+
when :mboxssh
|
74
|
+
$last_server ||= "localhost"
|
75
|
+
srv = axe "What machine is the mbox file located on?", $last_server
|
76
|
+
return if srv.nil? || srv.empty?
|
77
|
+
$last_server = srv
|
78
|
+
|
79
|
+
fn = axe "What's the path to the mbox file?", $last_fn
|
80
|
+
return if fn.nil? || fn.empty?
|
81
|
+
$last_fn = fn
|
82
|
+
fn = "/#{fn}" # lame
|
83
|
+
[Redwood::MBox::SSHLoader.suggest_labels_for(fn),
|
84
|
+
{ :scheme => "mbox+ssh", :host => srv, :path => fn }]
|
85
|
+
when :imap, :imaps
|
86
|
+
$last_server ||= "localhost"
|
87
|
+
srv = axe "What is the IMAP server (host, or host:port notation)?", $last_server
|
88
|
+
return if srv.nil? || srv.empty?
|
89
|
+
$last_server = srv
|
90
|
+
|
91
|
+
$last_folder ||= "INBOX"
|
92
|
+
fn = axe "What's the folder path?", $last_folder
|
93
|
+
return if fn.nil? || fn.empty?
|
94
|
+
$last_folder = fn
|
95
|
+
|
96
|
+
fn = "/#{fn}"
|
97
|
+
if srv =~ /^(\S+):(\d+)$/
|
98
|
+
host, port = $1, $2.to_i
|
99
|
+
else
|
100
|
+
host, port = srv, nil
|
114
101
|
end
|
102
|
+
[Redwood::IMAP.suggest_labels_for(fn),
|
103
|
+
{ :scheme => type.to_s, :host => host, :port => port, :path => fn }]
|
104
|
+
end
|
105
|
+
|
106
|
+
uri = begin
|
107
|
+
URI::Generic.build components
|
108
|
+
rescue URI::Error => e
|
109
|
+
say "Whoopsie! I couldn't build a URI from that: #{e.message}"
|
110
|
+
if axe_yes("Try again?") then next else return end
|
111
|
+
end
|
115
112
|
|
116
113
|
say "I'm going to add this source: #{uri}"
|
117
114
|
unless axe("Does that look right?", "y") =~ /^y|yes$/i
|
@@ -123,13 +120,12 @@ def add_source
|
|
123
120
|
|
124
121
|
labels_str = axe("Enter any labels to be automatically added to all messages from this source, separated by spaces (or 'none')", default_labels.join(","))
|
125
122
|
|
126
|
-
labels =
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
123
|
+
labels = if labels_str =~ /^\s*none\s*$/i
|
124
|
+
nil
|
125
|
+
else
|
126
|
+
labels_str.split(/\s+/)
|
127
|
+
end
|
128
|
+
|
133
129
|
cmd = build_cmd "sup-add"
|
134
130
|
cmd += " --unusual" unless usual
|
135
131
|
cmd += " --archive" if archive
|
@@ -151,8 +147,8 @@ end
|
|
151
147
|
|
152
148
|
$terminal.wrap_at = :auto
|
153
149
|
Redwood::start
|
154
|
-
index = Redwood::Index.
|
155
|
-
|
150
|
+
index = Redwood::Index.init
|
151
|
+
Redwood::SourceManager.load_sources
|
156
152
|
|
157
153
|
say <<EOS
|
158
154
|
Howdy neighbor! This here's sup-config, ready to help you jack in to
|
@@ -164,14 +160,13 @@ nary a click of the mouse!
|
|
164
160
|
Just answer these simple questions and you'll be on your way.
|
165
161
|
|
166
162
|
EOS
|
167
|
-
#' stupid ruby-mode
|
168
163
|
|
169
164
|
account = $config[:accounts][:default]
|
170
165
|
|
171
166
|
name = axe "What's your name?", account[:name]
|
172
|
-
email = axe "What's your (primary) email address?", account[:email]
|
167
|
+
email = axe "What's your (primary) email address?", account[:email]
|
173
168
|
|
174
|
-
say "Ok, your header will look like this:"
|
169
|
+
say "Ok, your from header will look like this:"
|
175
170
|
say " From: #{name} <#{email}>"
|
176
171
|
|
177
172
|
say "\nDo you have any alternate email addresses that also receive email?"
|
@@ -187,19 +182,15 @@ $config[:accounts][:default][:alternates] = alts
|
|
187
182
|
$config[:accounts][:default][:signature] = sigfn
|
188
183
|
$config[:editor] = editor
|
189
184
|
|
190
|
-
Redwood::save_yaml_obj $config, Redwood::CONFIG_FN
|
191
|
-
|
192
|
-
say "Ok, I've saved you up a nice lil' #{Redwood::CONFIG_FN}."
|
193
|
-
|
194
185
|
done = false
|
195
186
|
until done
|
196
187
|
say "\nNow, we'll tell Sup where to find all your email."
|
197
|
-
|
188
|
+
Redwood::SourceManager.load_sources
|
198
189
|
say "Current sources:"
|
199
|
-
if
|
190
|
+
if Redwood::SourceManager.sources.empty?
|
200
191
|
say " No sources!"
|
201
192
|
else
|
202
|
-
|
193
|
+
Redwood::SourceManager.sources.each { |s| puts "* #{s}" }
|
203
194
|
end
|
204
195
|
|
205
196
|
say "\n"
|
@@ -210,14 +201,42 @@ until done
|
|
210
201
|
end
|
211
202
|
end
|
212
203
|
|
204
|
+
say "\nSup needs to know where to store your sent messages."
|
205
|
+
say "Only sources capable of storing mail will be listed.\n\n"
|
206
|
+
|
207
|
+
Redwood::SourceManager.load_sources
|
208
|
+
if Redwood::SourceManager.sources.empty?
|
209
|
+
say "\nUsing the default sup://sent, since you haven't configured other sources yet."
|
210
|
+
$config[:sent_source] = 'sup://sent'
|
211
|
+
else
|
212
|
+
# this handles the event that source.yaml already contains the SentLoader
|
213
|
+
# source.
|
214
|
+
have_sup_sent = false
|
215
|
+
|
216
|
+
choose do |menu|
|
217
|
+
menu.prompt = "Store my sent mail in? "
|
218
|
+
|
219
|
+
menu.choice('Default (an mbox in ~/.sup, aka sup://sent)') { $config[:sent_source] = 'sup://sent'} unless have_sup_sent
|
220
|
+
|
221
|
+
valid_sents = Redwood::SourceManager.sources.each do |s|
|
222
|
+
have_sup_sent = true if s.to_s.eql?('sup://sent')
|
223
|
+
menu.choice(s.to_s) { $config[:sent_source] = s.to_s } if s.respond_to? :store_message
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
Redwood::save_yaml_obj $config, Redwood::CONFIG_FN
|
229
|
+
|
230
|
+
say "Ok, I've saved you up a nice lil' #{Redwood::CONFIG_FN}."
|
231
|
+
|
213
232
|
say <<EOS
|
214
233
|
|
215
|
-
|
234
|
+
The final step is to import all your messages into the Sup index.
|
216
235
|
Depending on how many messages are in the sources, this could take
|
217
236
|
quite a while.
|
218
237
|
|
219
238
|
EOS
|
220
|
-
|
239
|
+
|
221
240
|
if axe_yes "Run sup-sync to import all messages now?"
|
222
241
|
while true
|
223
242
|
cmd = build_cmd("sup-sync") + " --all-sources"
|