sup 0.11 → 0.12
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 +16 -5
- data/History.txt +9 -0
- data/ReleaseNotes +9 -0
- data/bin/sup +9 -24
- data/bin/sup-add +3 -3
- data/bin/sup-config +1 -1
- data/bin/sup-dump +22 -9
- data/bin/sup-recover-sources +1 -11
- data/bin/sup-sync +65 -130
- data/bin/sup-sync-back +6 -5
- data/bin/sup-tweak-labels +5 -6
- data/lib/sup.rb +89 -71
- data/lib/sup/account.rb +3 -2
- data/lib/sup/buffer.rb +28 -16
- data/lib/sup/client.rb +92 -0
- data/lib/sup/crypto.rb +91 -49
- data/lib/sup/draft.rb +14 -17
- data/lib/sup/hook.rb +10 -5
- data/lib/sup/index.rb +72 -28
- data/lib/sup/logger.rb +1 -1
- data/lib/sup/maildir.rb +55 -112
- data/lib/sup/mbox.rb +151 -6
- data/lib/sup/message-chunks.rb +20 -4
- data/lib/sup/message.rb +183 -76
- data/lib/sup/modes/compose-mode.rb +2 -1
- data/lib/sup/modes/console-mode.rb +4 -1
- data/lib/sup/modes/edit-message-mode.rb +50 -5
- data/lib/sup/modes/line-cursor-mode.rb +1 -0
- data/lib/sup/modes/reply-mode.rb +17 -11
- data/lib/sup/modes/thread-index-mode.rb +10 -9
- data/lib/sup/modes/thread-view-mode.rb +48 -2
- data/lib/sup/poll.rb +56 -60
- data/lib/sup/protocol.rb +161 -0
- data/lib/sup/sent.rb +8 -11
- data/lib/sup/server.rb +116 -0
- data/lib/sup/source.rb +15 -33
- data/lib/sup/thread.rb +6 -0
- data/lib/sup/util.rb +44 -39
- metadata +126 -88
- data/lib/sup/connection.rb +0 -63
- data/lib/sup/imap.rb +0 -349
- data/lib/sup/mbox/loader.rb +0 -180
- data/lib/sup/mbox/ssh-file.rb +0 -254
- data/lib/sup/mbox/ssh-loader.rb +0 -74
data/lib/sup/sent.rb
CHANGED
@@ -19,29 +19,24 @@ class SentManager
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def default_source
|
22
|
-
@source =
|
22
|
+
@source = SentLoader.new
|
23
23
|
@source_uri = @source.uri
|
24
24
|
@source
|
25
25
|
end
|
26
26
|
|
27
27
|
def write_sent_message date, from_email, &block
|
28
28
|
@source.store_message date, from_email, &block
|
29
|
-
|
30
|
-
PollManager.each_message_from(@source) do |m|
|
31
|
-
m.remove_label :unread
|
32
|
-
m.add_label :sent
|
33
|
-
PollManager.add_new_message m
|
34
|
-
end
|
29
|
+
PollManager.poll_from @source
|
35
30
|
end
|
36
31
|
end
|
37
32
|
|
38
|
-
class SentLoader < MBox
|
39
|
-
yaml_properties
|
33
|
+
class SentLoader < MBox
|
34
|
+
yaml_properties
|
40
35
|
|
41
|
-
def initialize
|
36
|
+
def initialize
|
42
37
|
@filename = Redwood::SENT_FN
|
43
38
|
File.open(@filename, "w") { } unless File.exists? @filename
|
44
|
-
super "mbox://" + @filename,
|
39
|
+
super "mbox://" + @filename, true, true
|
45
40
|
end
|
46
41
|
|
47
42
|
def file_path; @filename end
|
@@ -51,6 +46,8 @@ class SentLoader < MBox::Loader
|
|
51
46
|
|
52
47
|
def id; 9998; end
|
53
48
|
def labels; [:inbox, :sent]; end
|
49
|
+
def default_labels; []; end
|
50
|
+
def read?; true; end
|
54
51
|
end
|
55
52
|
|
56
53
|
end
|
data/lib/sup/server.rb
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
require 'sup/protocol'
|
2
|
+
|
3
|
+
module Redwood
|
4
|
+
|
5
|
+
class Server < EM::P::RedwoodServer
|
6
|
+
def initialize index
|
7
|
+
super
|
8
|
+
@index = index
|
9
|
+
end
|
10
|
+
|
11
|
+
def receive_message type, tag, params
|
12
|
+
if respond_to? :"request_#{type}"
|
13
|
+
send :"request_#{type}", tag, params
|
14
|
+
else
|
15
|
+
send_message 'error', tag, 'description' => "invalid request type #{type.inspect}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def request_query tag, a
|
20
|
+
q = @index.parse_query a['query']
|
21
|
+
query q, a['offset'], a['limit'], a['raw'] do |r|
|
22
|
+
send_message 'message', tag, r
|
23
|
+
end
|
24
|
+
send_message 'done', tag
|
25
|
+
end
|
26
|
+
|
27
|
+
def request_count tag, a
|
28
|
+
q = @index.parse_query a['query']
|
29
|
+
c = count q
|
30
|
+
send_message 'count', tag, 'count' => c
|
31
|
+
end
|
32
|
+
|
33
|
+
def request_label tag, a
|
34
|
+
q = @index.parse_query a['query']
|
35
|
+
label q, a['add'], a['remove']
|
36
|
+
send_message 'done', tag
|
37
|
+
end
|
38
|
+
|
39
|
+
def request_add tag, a
|
40
|
+
add a['raw'], a['labels']
|
41
|
+
send_message 'done', tag
|
42
|
+
end
|
43
|
+
|
44
|
+
def request_thread tag, a
|
45
|
+
thread a['message_id'], a['raw'] do |r|
|
46
|
+
send_message 'message', tag, r
|
47
|
+
end
|
48
|
+
send_message 'done', tag
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def result_from_message m, raw
|
54
|
+
mkperson = lambda { |p| { :email => p.email, :name => p.name } }
|
55
|
+
{
|
56
|
+
'summary' => {
|
57
|
+
'message_id' => m.id,
|
58
|
+
'date' => m.date,
|
59
|
+
'from' => mkperson[m.from],
|
60
|
+
'to' => m.to.map(&mkperson),
|
61
|
+
'cc' => m.cc.map(&mkperson),
|
62
|
+
'bcc' => m.bcc.map(&mkperson),
|
63
|
+
'subject' => m.subj,
|
64
|
+
'refs' => m.refs,
|
65
|
+
'replytos' => m.replytos,
|
66
|
+
'labels' => m.labels.map(&:to_s),
|
67
|
+
},
|
68
|
+
'raw' => raw ? m.raw_message : nil,
|
69
|
+
}
|
70
|
+
end
|
71
|
+
|
72
|
+
def query query, offset, limit, raw
|
73
|
+
c = 0
|
74
|
+
@index.each_message query do |m|
|
75
|
+
next if c < offset
|
76
|
+
break if c >= offset + limit if limit
|
77
|
+
yield result_from_message(m, raw)
|
78
|
+
c += 1
|
79
|
+
end
|
80
|
+
nil
|
81
|
+
end
|
82
|
+
|
83
|
+
def count query
|
84
|
+
@index.num_results_for query
|
85
|
+
end
|
86
|
+
|
87
|
+
def label query, remove_labels, add_labels
|
88
|
+
@index.each_message query do |m|
|
89
|
+
remove_labels.each { |l| m.remove_label l }
|
90
|
+
add_labels.each { |l| m.add_label l }
|
91
|
+
@index.update_message_state m
|
92
|
+
end
|
93
|
+
nil
|
94
|
+
end
|
95
|
+
|
96
|
+
def add raw, labels
|
97
|
+
SentManager.source.store_message Time.now, "test@example.com" do |io|
|
98
|
+
io.write raw
|
99
|
+
end
|
100
|
+
PollManager.poll_from SentManager.source do |sym,m,old_m,progress|
|
101
|
+
next unless sym == :add
|
102
|
+
m.labels = labels
|
103
|
+
end
|
104
|
+
nil
|
105
|
+
end
|
106
|
+
|
107
|
+
def thread msg_id, raw
|
108
|
+
msg = @index.build_message msg_id
|
109
|
+
@index.each_message_in_thread_for msg do |id, builder|
|
110
|
+
m = builder.call
|
111
|
+
yield result_from_message(m, raw)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
data/lib/sup/source.rb
CHANGED
@@ -59,50 +59,37 @@ class Source
|
|
59
59
|
## Examples for you to look at: mbox/loader.rb, imap.rb, and
|
60
60
|
## maildir.rb.
|
61
61
|
|
62
|
-
|
63
|
-
|
64
|
-
## dirty? means cur_offset has changed, so the source info needs to
|
65
|
-
## be re-saved to sources.yaml.
|
66
|
-
bool_reader :usual, :archived, :dirty
|
67
|
-
attr_reader :uri, :cur_offset
|
62
|
+
bool_accessor :usual, :archived
|
63
|
+
attr_reader :uri
|
68
64
|
attr_accessor :id
|
69
65
|
|
70
|
-
def initialize uri,
|
66
|
+
def initialize uri, usual=true, archived=false, id=nil
|
71
67
|
raise ArgumentError, "id must be an integer: #{id.inspect}" unless id.is_a? Fixnum if id
|
72
68
|
|
73
69
|
@uri = uri
|
74
|
-
@cur_offset = initial_offset
|
75
70
|
@usual = usual
|
76
71
|
@archived = archived
|
77
72
|
@id = id
|
78
|
-
@dirty = false
|
79
73
|
end
|
80
74
|
|
81
75
|
## overwrite me if you have a disk incarnation (currently used only for sup-sync-back)
|
82
76
|
def file_path; nil end
|
83
77
|
|
84
78
|
def to_s; @uri.to_s; end
|
85
|
-
def seek_to! o; self.cur_offset = o; end
|
86
|
-
def reset!; seek_to! start_offset; end
|
87
79
|
def == o; o.uri == uri; end
|
88
|
-
def done?; start_offset.nil? || (self.cur_offset ||= start_offset) >= end_offset; end
|
89
80
|
def is_source_for? uri; uri == @uri; end
|
90
81
|
|
91
|
-
|
92
|
-
## if it can detect a problem. it is called when the sup starts up
|
93
|
-
## to proactively notify the user of any source problems.
|
94
|
-
def check; end
|
82
|
+
def read?; false; end
|
95
83
|
|
96
|
-
##
|
97
|
-
##
|
98
|
-
##
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
end
|
84
|
+
## Yields values of the form [Symbol, Hash]
|
85
|
+
## add: info, labels, progress
|
86
|
+
## delete: info, progress
|
87
|
+
def poll
|
88
|
+
unimplemented
|
89
|
+
end
|
90
|
+
|
91
|
+
def valid? info
|
92
|
+
true
|
106
93
|
end
|
107
94
|
|
108
95
|
## utility method to read a raw email header from an IO stream and turn it
|
@@ -154,11 +141,6 @@ protected
|
|
154
141
|
def Source.expand_filesystem_uri uri
|
155
142
|
uri.gsub "~", File.expand_path("~")
|
156
143
|
end
|
157
|
-
|
158
|
-
def cur_offset= o
|
159
|
-
@cur_offset = o
|
160
|
-
@dirty = true
|
161
|
-
end
|
162
144
|
end
|
163
145
|
|
164
146
|
## if you have a @labels instance variable, include this
|
@@ -210,7 +192,7 @@ class SourceManager
|
|
210
192
|
def unusual_sources; sources.find_all { |s| !s.usual? }; end
|
211
193
|
|
212
194
|
def load_sources fn=Redwood::SOURCE_FN
|
213
|
-
source_array =
|
195
|
+
source_array = Redwood::load_yaml_obj(fn) || []
|
214
196
|
@source_mutex.synchronize do
|
215
197
|
@sources = Hash[*(source_array).map { |s| [s.id, s] }.flatten]
|
216
198
|
@sources_dirty = false
|
@@ -219,7 +201,7 @@ class SourceManager
|
|
219
201
|
|
220
202
|
def save_sources fn=Redwood::SOURCE_FN
|
221
203
|
@source_mutex.synchronize do
|
222
|
-
if @sources_dirty
|
204
|
+
if @sources_dirty
|
223
205
|
bakfn = fn + ".bak"
|
224
206
|
if File.exists? fn
|
225
207
|
File.chmod 0600, fn
|
data/lib/sup/thread.rb
CHANGED
@@ -85,6 +85,7 @@ class Thread
|
|
85
85
|
end
|
86
86
|
|
87
87
|
def first; each { |m, *o| return m if m }; nil; end
|
88
|
+
def has_message?; any? { |m, *o| m.is_a? Message }; end
|
88
89
|
def dirty?; any? { |m, *o| m && m.dirty? }; end
|
89
90
|
def date; map { |m, *o| m.date if m }.compact.max; end
|
90
91
|
def snippet
|
@@ -146,6 +147,11 @@ class Thread
|
|
146
147
|
def to_s
|
147
148
|
"<thread containing: #{@containers.join ', '}>"
|
148
149
|
end
|
150
|
+
|
151
|
+
def sort_key
|
152
|
+
m = latest_message
|
153
|
+
m ? [-m.date.to_i, m.id] : [-Time.now.to_i, ""]
|
154
|
+
end
|
149
155
|
end
|
150
156
|
|
151
157
|
## recursive structure used internally to represent message trees as
|
data/lib/sup/util.rb
CHANGED
@@ -3,8 +3,18 @@ require 'lockfile'
|
|
3
3
|
require 'mime/types'
|
4
4
|
require 'pathname'
|
5
5
|
require 'set'
|
6
|
+
require 'enumerator'
|
7
|
+
require 'benchmark'
|
6
8
|
|
7
9
|
## time for some monkeypatching!
|
10
|
+
class Symbol
|
11
|
+
unless method_defined? :to_proc
|
12
|
+
def to_proc
|
13
|
+
proc { |obj, *args| obj.send(self, *args) }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
8
18
|
class Lockfile
|
9
19
|
def gen_lock_id
|
10
20
|
Hash[
|
@@ -88,6 +98,19 @@ module RMail
|
|
88
98
|
a
|
89
99
|
end
|
90
100
|
end
|
101
|
+
|
102
|
+
class Serialize
|
103
|
+
## Don't add MIME-Version headers on serialization. Sup sometimes want's to serialize
|
104
|
+
## message parts where these headers are not needed and messing with the message on
|
105
|
+
## serialization breaks gpg signatures. The commented section shows the original RMail
|
106
|
+
## code.
|
107
|
+
def calculate_boundaries(message)
|
108
|
+
calculate_boundaries_low(message, [])
|
109
|
+
# unless message.header['MIME-Version']
|
110
|
+
# message.header['MIME-Version'] = "1.0"
|
111
|
+
# end
|
112
|
+
end
|
113
|
+
end
|
91
114
|
end
|
92
115
|
|
93
116
|
class Range
|
@@ -175,6 +198,13 @@ class Object
|
|
175
198
|
EOF
|
176
199
|
end
|
177
200
|
end
|
201
|
+
|
202
|
+
def benchmark s, &b
|
203
|
+
ret = nil
|
204
|
+
times = Benchmark.measure { ret = b.call }
|
205
|
+
debug "benchmark #{s}: #{times}"
|
206
|
+
ret
|
207
|
+
end
|
178
208
|
end
|
179
209
|
|
180
210
|
class String
|
@@ -207,7 +237,7 @@ class String
|
|
207
237
|
## a very complicated regex found on teh internets to split on
|
208
238
|
## commas, unless they occurr within double quotes.
|
209
239
|
def split_on_commas
|
210
|
-
split(/,\s*(?=(?:[^"]*"[^"]*")*(?![^"]*"))/)
|
240
|
+
normalize_whitespace().split(/,\s*(?=(?:[^"]*"[^"]*")*(?![^"]*"))/)
|
211
241
|
end
|
212
242
|
|
213
243
|
## ok, here we do it the hard way. got to have a remainder for purposes of
|
@@ -301,7 +331,7 @@ class String
|
|
301
331
|
end
|
302
332
|
|
303
333
|
## takes a list of words, and returns an array of symbols. typically used in
|
304
|
-
## Sup for translating
|
334
|
+
## Sup for translating Xapian's representation of a list of labels (a string)
|
305
335
|
## to an array of label symbols.
|
306
336
|
##
|
307
337
|
## split_on will be passed to String#split, so you can leave this nil for space.
|
@@ -459,6 +489,15 @@ module Enumerable
|
|
459
489
|
def max_of
|
460
490
|
map { |e| yield e }.max
|
461
491
|
end
|
492
|
+
|
493
|
+
## returns all the entries which are equal to startline up to endline
|
494
|
+
def between startline, endline
|
495
|
+
select { |l| true if l == startline .. l == endline }
|
496
|
+
end
|
497
|
+
end
|
498
|
+
|
499
|
+
unless Object.const_defined? :Enumerator
|
500
|
+
Enumerator = Enumerable::Enumerator
|
462
501
|
end
|
463
502
|
|
464
503
|
class Array
|
@@ -570,7 +609,7 @@ module Singleton
|
|
570
609
|
@instance.send meth, *a, &b
|
571
610
|
end
|
572
611
|
def init *args
|
573
|
-
raise "there can be only one! (instance)" if
|
612
|
+
raise "there can be only one! (instance)" if instantiated?
|
574
613
|
@instance = new(*args)
|
575
614
|
end
|
576
615
|
end
|
@@ -581,40 +620,6 @@ module Singleton
|
|
581
620
|
end
|
582
621
|
end
|
583
622
|
|
584
|
-
## wraps an object. if it throws an exception, keeps a copy.
|
585
|
-
class Recoverable
|
586
|
-
def initialize o
|
587
|
-
@o = o
|
588
|
-
@error = nil
|
589
|
-
@mutex = Mutex.new
|
590
|
-
end
|
591
|
-
|
592
|
-
attr_accessor :error
|
593
|
-
|
594
|
-
def clear_error!; @error = nil; end
|
595
|
-
def has_errors?; !@error.nil?; end
|
596
|
-
|
597
|
-
def method_missing m, *a, &b; __pass m, *a, &b end
|
598
|
-
|
599
|
-
def id; __pass :id; end
|
600
|
-
def to_s; __pass :to_s; end
|
601
|
-
def to_yaml x; __pass :to_yaml, x; end
|
602
|
-
def is_a? c; @o.is_a? c; end
|
603
|
-
|
604
|
-
def respond_to?(m, include_private=false)
|
605
|
-
@o.respond_to?(m, include_private)
|
606
|
-
end
|
607
|
-
|
608
|
-
def __pass m, *a, &b
|
609
|
-
begin
|
610
|
-
@o.send(m, *a, &b)
|
611
|
-
rescue Exception => e
|
612
|
-
@error ||= e
|
613
|
-
raise
|
614
|
-
end
|
615
|
-
end
|
616
|
-
end
|
617
|
-
|
618
623
|
## acts like a hash with an initialization block, but saves any
|
619
624
|
## newly-created value even upon lookup.
|
620
625
|
##
|
@@ -707,9 +712,9 @@ class Iconv
|
|
707
712
|
end
|
708
713
|
|
709
714
|
begin
|
710
|
-
returning(Iconv.iconv(target, charset, text + " ").join[0 .. -2]) { |str| str.check }
|
715
|
+
returning(Iconv.iconv(target + "//IGNORE", charset, text + " ").join[0 .. -2]) { |str| str.check }
|
711
716
|
rescue Errno::EINVAL, Iconv::InvalidEncoding, Iconv::InvalidCharacter, Iconv::IllegalSequence, String::CheckError
|
712
|
-
debug "couldn't transcode text from #{orig_charset} (#{charset}) to #{target}
|
717
|
+
debug "couldn't transcode text from #{orig_charset} (#{charset}) to #{target} (#{text[0 ... 20].inspect}...): got #{$!.class} (#{$!.message})"
|
713
718
|
text.ascii
|
714
719
|
end
|
715
720
|
end
|
metadata
CHANGED
@@ -1,7 +1,11 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sup
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 12
|
8
|
+
version: "0.12"
|
5
9
|
platform: ruby
|
6
10
|
authors:
|
7
11
|
- William Morgan
|
@@ -9,100 +13,132 @@ autorequire:
|
|
9
13
|
bindir: bin
|
10
14
|
cert_chain: []
|
11
15
|
|
12
|
-
date:
|
16
|
+
date: 2011-01-14 21:13:42 -08:00
|
13
17
|
default_executable:
|
14
18
|
dependencies:
|
15
19
|
- !ruby/object:Gem::Dependency
|
16
20
|
name: xapian-full
|
17
|
-
|
18
|
-
|
19
|
-
|
21
|
+
prerelease: false
|
22
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
23
|
+
none: false
|
20
24
|
requirements:
|
21
25
|
- - ">="
|
22
26
|
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 1
|
29
|
+
- 1
|
30
|
+
- 3
|
31
|
+
- 1
|
23
32
|
version: 1.1.3.1
|
24
|
-
|
33
|
+
type: :runtime
|
34
|
+
version_requirements: *id001
|
25
35
|
- !ruby/object:Gem::Dependency
|
26
36
|
name: ncurses
|
27
|
-
|
28
|
-
|
29
|
-
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
30
40
|
requirements:
|
31
41
|
- - ">="
|
32
42
|
- !ruby/object:Gem::Version
|
43
|
+
segments:
|
44
|
+
- 0
|
33
45
|
version: "0"
|
34
|
-
|
46
|
+
type: :runtime
|
47
|
+
version_requirements: *id002
|
35
48
|
- !ruby/object:Gem::Dependency
|
36
49
|
name: rmail
|
37
|
-
|
38
|
-
|
39
|
-
|
50
|
+
prerelease: false
|
51
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
40
53
|
requirements:
|
41
54
|
- - ">="
|
42
55
|
- !ruby/object:Gem::Version
|
56
|
+
segments:
|
57
|
+
- 0
|
58
|
+
- 17
|
43
59
|
version: "0.17"
|
44
|
-
|
60
|
+
type: :runtime
|
61
|
+
version_requirements: *id003
|
45
62
|
- !ruby/object:Gem::Dependency
|
46
63
|
name: highline
|
47
|
-
|
48
|
-
|
49
|
-
|
64
|
+
prerelease: false
|
65
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
50
67
|
requirements:
|
51
68
|
- - ">="
|
52
69
|
- !ruby/object:Gem::Version
|
70
|
+
segments:
|
71
|
+
- 0
|
53
72
|
version: "0"
|
54
|
-
|
73
|
+
type: :runtime
|
74
|
+
version_requirements: *id004
|
55
75
|
- !ruby/object:Gem::Dependency
|
56
76
|
name: net-ssh
|
57
|
-
|
58
|
-
|
59
|
-
|
77
|
+
prerelease: false
|
78
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
79
|
+
none: false
|
60
80
|
requirements:
|
61
81
|
- - ">="
|
62
82
|
- !ruby/object:Gem::Version
|
83
|
+
segments:
|
84
|
+
- 0
|
63
85
|
version: "0"
|
64
|
-
|
86
|
+
type: :runtime
|
87
|
+
version_requirements: *id005
|
65
88
|
- !ruby/object:Gem::Dependency
|
66
89
|
name: trollop
|
67
|
-
|
68
|
-
|
69
|
-
|
90
|
+
prerelease: false
|
91
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
92
|
+
none: false
|
70
93
|
requirements:
|
71
94
|
- - ">="
|
72
95
|
- !ruby/object:Gem::Version
|
96
|
+
segments:
|
97
|
+
- 1
|
98
|
+
- 12
|
73
99
|
version: "1.12"
|
74
|
-
|
100
|
+
type: :runtime
|
101
|
+
version_requirements: *id006
|
75
102
|
- !ruby/object:Gem::Dependency
|
76
103
|
name: lockfile
|
77
|
-
|
78
|
-
|
79
|
-
|
104
|
+
prerelease: false
|
105
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
106
|
+
none: false
|
80
107
|
requirements:
|
81
108
|
- - ">="
|
82
109
|
- !ruby/object:Gem::Version
|
110
|
+
segments:
|
111
|
+
- 0
|
83
112
|
version: "0"
|
84
|
-
|
113
|
+
type: :runtime
|
114
|
+
version_requirements: *id007
|
85
115
|
- !ruby/object:Gem::Dependency
|
86
116
|
name: mime-types
|
87
|
-
|
88
|
-
|
89
|
-
|
117
|
+
prerelease: false
|
118
|
+
requirement: &id008 !ruby/object:Gem::Requirement
|
119
|
+
none: false
|
90
120
|
requirements:
|
91
121
|
- - ~>
|
92
122
|
- !ruby/object:Gem::Version
|
123
|
+
segments:
|
124
|
+
- 1
|
93
125
|
version: "1"
|
94
|
-
|
126
|
+
type: :runtime
|
127
|
+
version_requirements: *id008
|
95
128
|
- !ruby/object:Gem::Dependency
|
96
129
|
name: gettext
|
97
|
-
|
98
|
-
|
99
|
-
|
130
|
+
prerelease: false
|
131
|
+
requirement: &id009 !ruby/object:Gem::Requirement
|
132
|
+
none: false
|
100
133
|
requirements:
|
101
134
|
- - ">="
|
102
135
|
- !ruby/object:Gem::Version
|
136
|
+
segments:
|
137
|
+
- 0
|
103
138
|
version: "0"
|
104
|
-
|
105
|
-
|
139
|
+
type: :runtime
|
140
|
+
version_requirements: *id009
|
141
|
+
description: "Sup is a console-based email client for people with a lot of email. It supports tagging, very fast full-text search, automatic contact-list management, and more. If you're the type of person who treats email as an extension of your long-term memory, Sup is for you. Sup makes it easy to: - Handle massive amounts of email. - Mix email from different sources: mbox files (even across different machines), Maildir directories, POP accounts, and GMail accounts. - Instantaneously search over your entire email collection. Search over body text, or use a query language to combine search predicates in any way. - Handle multiple accounts. Replying to email sent to a particular account will use the correct SMTP server, signature, and from address. - Add custom code to handle certain types of messages or to handle certain types of text within messages. - Organize email with user-defined labels, automatically track recent contacts, and much more! The goal of Sup is to become the email client of choice for nerds everywhere."
|
106
142
|
email: wmorgan-sup@masanjin.net
|
107
143
|
executables:
|
108
144
|
- sup
|
@@ -132,66 +168,64 @@ files:
|
|
132
168
|
- bin/sup-sync-back
|
133
169
|
- bin/sup-tweak-labels
|
134
170
|
- lib/sup.rb
|
135
|
-
- lib/sup/account.rb
|
136
|
-
- lib/sup/interactive-lock.rb
|
137
|
-
- lib/sup/message.rb
|
138
|
-
- lib/sup/rfc2047.rb
|
139
|
-
- lib/sup/buffer.rb
|
140
|
-
- lib/sup/textfield.rb
|
141
|
-
- lib/sup/sent.rb
|
142
171
|
- lib/sup/colormap.rb
|
143
|
-
- lib/sup/logger.rb
|
144
|
-
- lib/sup/mbox.rb
|
145
172
|
- lib/sup/draft.rb
|
146
|
-
- lib/sup/contact.rb
|
147
|
-
- lib/sup/thread.rb
|
148
|
-
- lib/sup/mode.rb
|
149
|
-
- lib/sup/keymap.rb
|
150
|
-
- lib/sup/person.rb
|
151
|
-
- lib/sup/connection.rb
|
152
|
-
- lib/sup/message-chunks.rb
|
153
173
|
- lib/sup/source.rb
|
154
|
-
- lib/sup/
|
155
|
-
- lib/sup/
|
156
|
-
- lib/sup/
|
174
|
+
- lib/sup/message-chunks.rb
|
175
|
+
- lib/sup/person.rb
|
176
|
+
- lib/sup/logger.rb
|
177
|
+
- lib/sup/index.rb
|
178
|
+
- lib/sup/message.rb
|
157
179
|
- lib/sup/search.rb
|
158
|
-
- lib/sup/util.rb
|
159
|
-
- lib/sup/update.rb
|
160
180
|
- lib/sup/idle.rb
|
181
|
+
- lib/sup/mode.rb
|
182
|
+
- lib/sup/client.rb
|
183
|
+
- lib/sup/contact.rb
|
184
|
+
- lib/sup/poll.rb
|
185
|
+
- lib/sup/update.rb
|
186
|
+
- lib/sup/keymap.rb
|
187
|
+
- lib/sup/server.rb
|
188
|
+
- lib/sup/undo.rb
|
189
|
+
- lib/sup/protocol.rb
|
161
190
|
- lib/sup/hook.rb
|
162
|
-
- lib/sup/
|
191
|
+
- lib/sup/label.rb
|
192
|
+
- lib/sup/sent.rb
|
193
|
+
- lib/sup/tagger.rb
|
163
194
|
- lib/sup/maildir.rb
|
164
|
-
- lib/sup/crypto.rb
|
165
|
-
- lib/sup/imap.rb
|
166
195
|
- lib/sup/horizontal-selector.rb
|
167
|
-
- lib/sup/
|
168
|
-
- lib/sup/
|
196
|
+
- lib/sup/util.rb
|
197
|
+
- lib/sup/crypto.rb
|
198
|
+
- lib/sup/mbox.rb
|
199
|
+
- lib/sup/textfield.rb
|
200
|
+
- lib/sup/account.rb
|
201
|
+
- lib/sup/rfc2047.rb
|
202
|
+
- lib/sup/thread.rb
|
203
|
+
- lib/sup/buffer.rb
|
204
|
+
- lib/sup/interactive-lock.rb
|
205
|
+
- lib/sup/modes/compose-mode.rb
|
206
|
+
- lib/sup/modes/reply-mode.rb
|
207
|
+
- lib/sup/modes/forward-mode.rb
|
208
|
+
- lib/sup/modes/line-cursor-mode.rb
|
209
|
+
- lib/sup/modes/label-list-mode.rb
|
169
210
|
- lib/sup/modes/file-browser-mode.rb
|
211
|
+
- lib/sup/modes/contact-list-mode.rb
|
212
|
+
- lib/sup/modes/thread-view-mode.rb
|
213
|
+
- lib/sup/modes/person-search-results-mode.rb
|
214
|
+
- lib/sup/modes/inbox-mode.rb
|
215
|
+
- lib/sup/modes/search-list-mode.rb
|
216
|
+
- lib/sup/modes/poll-mode.rb
|
217
|
+
- lib/sup/modes/thread-index-mode.rb
|
218
|
+
- lib/sup/modes/scroll-mode.rb
|
170
219
|
- lib/sup/modes/completion-mode.rb
|
171
|
-
- lib/sup/modes/
|
172
|
-
- lib/sup/modes/console-mode.rb
|
220
|
+
- lib/sup/modes/search-results-mode.rb
|
173
221
|
- lib/sup/modes/help-mode.rb
|
174
|
-
- lib/sup/modes/label-search-results-mode.rb
|
175
|
-
- lib/sup/modes/label-list-mode.rb
|
176
|
-
- lib/sup/modes/thread-index-mode.rb
|
177
|
-
- lib/sup/modes/line-cursor-mode.rb
|
178
|
-
- lib/sup/modes/text-mode.rb
|
179
|
-
- lib/sup/modes/compose-mode.rb
|
180
222
|
- lib/sup/modes/log-mode.rb
|
181
223
|
- lib/sup/modes/edit-message-mode.rb
|
182
|
-
- lib/sup/modes/
|
183
|
-
- lib/sup/modes/poll-mode.rb
|
184
|
-
- lib/sup/modes/reply-mode.rb
|
185
|
-
- lib/sup/modes/forward-mode.rb
|
224
|
+
- lib/sup/modes/text-mode.rb
|
186
225
|
- lib/sup/modes/buffer-list-mode.rb
|
187
|
-
- lib/sup/modes/
|
188
|
-
- lib/sup/modes/search-results-mode.rb
|
189
|
-
- lib/sup/modes/
|
190
|
-
- lib/sup/modes/thread-view-mode.rb
|
191
|
-
- lib/sup/modes/contact-list-mode.rb
|
192
|
-
- lib/sup/mbox/ssh-file.rb
|
193
|
-
- lib/sup/mbox/loader.rb
|
194
|
-
- lib/sup/mbox/ssh-loader.rb
|
226
|
+
- lib/sup/modes/resume-mode.rb
|
227
|
+
- lib/sup/modes/label-search-results-mode.rb
|
228
|
+
- lib/sup/modes/console-mode.rb
|
195
229
|
has_rdoc: true
|
196
230
|
homepage: http://sup.rubyforge.org/
|
197
231
|
licenses: []
|
@@ -202,21 +236,25 @@ rdoc_options: []
|
|
202
236
|
require_paths:
|
203
237
|
- lib
|
204
238
|
required_ruby_version: !ruby/object:Gem::Requirement
|
239
|
+
none: false
|
205
240
|
requirements:
|
206
241
|
- - ">="
|
207
242
|
- !ruby/object:Gem::Version
|
243
|
+
segments:
|
244
|
+
- 0
|
208
245
|
version: "0"
|
209
|
-
version:
|
210
246
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
247
|
+
none: false
|
211
248
|
requirements:
|
212
249
|
- - ">="
|
213
250
|
- !ruby/object:Gem::Version
|
251
|
+
segments:
|
252
|
+
- 0
|
214
253
|
version: "0"
|
215
|
-
version:
|
216
254
|
requirements: []
|
217
255
|
|
218
256
|
rubyforge_project:
|
219
|
-
rubygems_version: 1.3.
|
257
|
+
rubygems_version: 1.3.7
|
220
258
|
signing_key:
|
221
259
|
specification_version: 3
|
222
260
|
summary: A console-based email client with the best features of GMail, mutt, and emacs. Features full text search, labels, tagged operations, multiple buffers, recent contacts, and more.
|