sup 0.15.4 → 0.16.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -13
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/CONTRIBUTORS +16 -13
- data/History.txt +8 -0
- data/README.md +0 -3
- data/ReleaseNotes +10 -0
- data/bin/sup-psych-ify-config-files +5 -0
- data/lib/sup/interactive_lock.rb +47 -32
- data/lib/sup/mbox.rb +0 -2
- data/lib/sup/message_chunks.rb +18 -22
- data/lib/sup/modes/contact_list_mode.rb +1 -1
- data/lib/sup/modes/inbox_mode.rb +0 -42
- data/lib/sup/modes/thread_index_mode.rb +42 -0
- data/lib/sup/modes/thread_view_mode.rb +9 -0
- data/lib/sup/person.rb +1 -1
- data/lib/sup/source.rb +1 -1
- data/lib/sup/util.rb +8 -0
- data/lib/sup/version.rb +1 -1
- metadata +71 -76
- metadata.gz.sig +0 -0
- data/bin/sup-sync-back-mbox +0 -181
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
YTA5YmU2MDgwNGZkZDc1MjMxMzg0NmJiNTg3NDU5NDNlMWIwMTUzNw==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 58f12f8b8d3223e51c43fad6ebad16a8621992cb
|
4
|
+
data.tar.gz: b5d08b2c0a7734cd83b4d0613ce209b2b81b757e
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
OTg1OTUyNzNiZTI0NTI1YWJjMmNhMjIwM2I3NTAyOWYzOWRmZmE5N2ExNGMy
|
11
|
-
NjJlMGRiYzMyZWE3ZDVhMzc2NDIwMWQ5OTMxNmI4YmQ3M2I3NTg=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
NjcyZTBkMzMxYTU3OTg5Njc3NmNjOThhOGViYzYwZmUwODhkYTFkMWMxY2Nl
|
14
|
-
ZDE3NGE3MWY4YWZkNjU1MzYwZjc3MGE0MzU5NTRmOTQ5OWYzZTBiZmU2MTIx
|
15
|
-
YWI0ZDNiZGExZDNlNGM2NDAxMDk4MTAxOTNjMjhhMjJhZWNjMjM=
|
6
|
+
metadata.gz: 084e53c311359b9bcb0e97e57ebbb4d49b7a30a1697492522c8cd799fc86ce9b289c46ddc21a8b597a06f737923f2c6303c57bbf85343647f74e2c50fd68da85
|
7
|
+
data.tar.gz: 307daf56455e61012cb480d5bed83781a395c38233cdc545b1bf58d0bfac3286b66f580d3e3880e96e5b5338013c65388f8b3950af1630f3ba2be9a29ad1a148
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/CONTRIBUTORS
CHANGED
@@ -18,10 +18,12 @@ Clint Byrum <clint at the ubuntu dot coms>
|
|
18
18
|
Marcus Williams <marcus-sup at the bar-coded dot nets>
|
19
19
|
Lionel Ott <white.magic at the gmx dot des>
|
20
20
|
Gaudenz Steinlin <gaudenz at the soziologie dot chs>
|
21
|
-
|
21
|
+
Matthieu Rakotojaona <matthieu.rakotojaona at the gmail dot coms>
|
22
22
|
Ingmar Vanhassel <ingmar at the exherbo dot orgs>
|
23
|
+
Mark Alexander <marka at the pobox dot coms>
|
23
24
|
Edward Z. Yang <ezyang at the mit dot edus>
|
24
|
-
|
25
|
+
Timon Vonk <timonv at the gmail dot coms>
|
26
|
+
julien@macbook <julien.stechele at the gmail dot coms>
|
25
27
|
Christopher Warrington <chrisw at the rice dot edus>
|
26
28
|
W. Trevor King <wking at the drexel dot edus>
|
27
29
|
Richard Brown <rbrown at the exherbo dot orgs>
|
@@ -29,13 +31,14 @@ Anthony Martinez <pi+sup at the pihost dot uss>
|
|
29
31
|
Marc Hartstein <marc.hartstein at the alum.vassar dot edus>
|
30
32
|
Israel Herraiz <israel.herraiz at the gmail dot coms>
|
31
33
|
Bo Borgerson <gigabo at the gmail dot coms>
|
34
|
+
Atte Kojo <atte.kojo at the reaktor dot fis>
|
32
35
|
Michael Hamann <michael at the content-space dot des>
|
33
|
-
Jonathan Lassoff <jof at the thejof dot coms>
|
34
36
|
William Erik Baxter <web at the superscript dot coms>
|
35
|
-
|
36
|
-
Adeodato Simó <dato at the net.com.org dot ess>
|
37
|
+
Jonathan Lassoff <jof at the thejof dot coms>
|
37
38
|
Markus Klinik <markus.klinik at the gmx dot des>
|
39
|
+
Grant Hollingworth <grant at the antiflux dot orgs>
|
38
40
|
Ico Doornekamp <ico at the pruts dot nls>
|
41
|
+
Adeodato Simó <dato at the net.com.org dot ess>
|
39
42
|
Daniel Schoepe <daniel.schoepe at the googlemail dot coms>
|
40
43
|
Jason Petsod <jason at the petsod dot orgs>
|
41
44
|
James Taylor <james at the jamestaylor dot orgs>
|
@@ -46,8 +49,8 @@ Decklin Foster <decklin at the red-bean dot coms>
|
|
46
49
|
Cameron Matheson <cam+sup at the cammunism dot orgs>
|
47
50
|
Carl Worth <cworth at the cworth dot orgs>
|
48
51
|
Alex Vandiver <alex at the chmrr dot nets>
|
49
|
-
Andrew Pimlott <andrew at the pimlott dot nets>
|
50
52
|
Jeff Balogh <its.jeff.balogh at the gmail dot coms>
|
53
|
+
Andrew Pimlott <andrew at the pimlott dot nets>
|
51
54
|
Matías Aguirre <matiasaguirre at the gmail dot coms>
|
52
55
|
Kornilios Kourtis <kkourt at the cslab.ece.ntua dot grs>
|
53
56
|
Lars Fischer <fischer at the wiwi.uni-siegen dot des>
|
@@ -58,18 +61,18 @@ Alvaro Herrera <alvherre at the alvh.no-ip dot orgs>
|
|
58
61
|
Steven Lawrance <stl at the koffein dot nets>
|
59
62
|
Jonah <Jonah at the GoodCoffee dot cas>
|
60
63
|
ian <itaylor at the uark dot edus>
|
61
|
-
|
64
|
+
MichaelRevell <mikearevell at the gmail dot coms>
|
62
65
|
Per Andersson <avtobiff at the gmail dot coms>
|
66
|
+
Todd Eisenberger <teisenbe at the andrew.cmu dot edus>
|
67
|
+
Gregor Hoffleit <gregor at the sam.mediasupervision dot des>
|
63
68
|
Adam Lloyd <adam at the alloy-d dot nets>
|
64
|
-
MichaelRevell <mikearevell at the gmail dot coms>
|
65
69
|
0xACE <0xACE at the users.noreply.github dot coms>
|
66
|
-
Gregor Hoffleit <gregor at the sam.mediasupervision dot des>
|
67
70
|
Steven Walter <swalter at the monarch.(none)>
|
68
|
-
|
69
|
-
|
71
|
+
Jon M. Dugan <jdugan at the es dot nets>
|
72
|
+
Horacio Sanson <horacio at the skillupjapan.co dot jps>
|
70
73
|
Matthias Vallentin <vallentin at the icir dot orgs>
|
71
74
|
akojo <atte.kojo at the gmail dot coms>
|
72
|
-
|
73
|
-
|
75
|
+
William A. Kennington III <william at the wkennington dot coms>
|
76
|
+
Stefan Lundström <lundst at the snabb.(none)>
|
74
77
|
Johannes Larsen <johs.a.larsen at the gmail dot coms>
|
75
78
|
Kirill Smelkov <kirr at the landau.phys.spbu dot rus>
|
data/History.txt
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
== 0.16.0 / 2014-03-21
|
2
|
+
|
3
|
+
* sup-sync-back-mbox removed.
|
4
|
+
* safer mime-view attachment file name handling
|
5
|
+
* show thread labels in thread-view-mode
|
6
|
+
* remove lock file if there is no sup alive
|
7
|
+
* deprecate migration script on ruby > 2.1
|
8
|
+
|
1
9
|
== 0.15.4 / 2014-02-06
|
2
10
|
|
3
11
|
* Various bugfixes
|
data/README.md
CHANGED
@@ -20,9 +20,6 @@ Features:
|
|
20
20
|
|
21
21
|
Current limitations:
|
22
22
|
|
23
|
-
* [Ruby 2.0 support][ruby20] is very fresh, consider it experimental. Patches
|
24
|
-
are welcome
|
25
|
-
|
26
23
|
* Sup does in general not play nicely with other mail clients, not all
|
27
24
|
changes can be synced back to the mail source. Refer to [Maildir Syncback][maildir-syncback]
|
28
25
|
in the wiki for this recently included feature. Maildir Syncback
|
data/ReleaseNotes
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
Release 0.16.0:
|
2
|
+
|
3
|
+
Removed unfinished and abandoned sup-sync-back-mbox.
|
4
|
+
|
5
|
+
Safer mime-view attachment file name handling, a temp file name is used
|
6
|
+
while the extension is only used if it is alphanumeric.
|
7
|
+
|
8
|
+
The migration script for YAML documents is now deprecated for ruby > 2.1
|
9
|
+
and will be removed in the future.
|
10
|
+
|
1
11
|
Release 0.15.4:
|
2
12
|
|
3
13
|
Bugfixes.
|
data/lib/sup/interactive_lock.rb
CHANGED
@@ -25,49 +25,64 @@ module InteractiveLock
|
|
25
25
|
begin
|
26
26
|
Index.lock
|
27
27
|
rescue Index::LockError => e
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
28
|
+
begin
|
29
|
+
Process.kill 0, e.pid.to_i # 0 signal test the existence of PID
|
30
|
+
stream.puts <<EOS
|
31
|
+
Error: the index is locked by another process! User '#{e.user}' on
|
32
|
+
host '#{e.host}' is running #{e.pname} with pid #{e.pid}.
|
33
|
+
The process was alive as of at least #{time_ago_in_words e.mtime} ago.
|
32
34
|
|
33
35
|
EOS
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
success = if $stdin.gets =~ /^\s*y(es)?\s*$/i
|
38
|
-
stream.puts "Ok, trying to kill process..."
|
39
|
-
|
40
|
-
begin
|
36
|
+
stream.print "Should I ask that process to kill itself (y/n)? "
|
37
|
+
stream.flush
|
38
|
+
if $stdin.gets =~ /^\s*y(es)?\s*$/i
|
41
39
|
Process.kill "TERM", e.pid.to_i
|
42
40
|
sleep DELAY
|
43
|
-
|
44
|
-
|
41
|
+
stream.puts "Let's try that again."
|
42
|
+
begin
|
43
|
+
Index.lock
|
44
|
+
rescue Index::LockError => e
|
45
|
+
stream.puts "I couldn't lock the index. The lockfile might just be stale."
|
46
|
+
stream.print "Should I just remove it and continue? (y/n) "
|
47
|
+
stream.flush
|
48
|
+
if $stdin.gets =~ /^\s*y(es)?\s*$/i
|
49
|
+
begin
|
50
|
+
FileUtils.rm e.path
|
51
|
+
rescue Errno::ENOENT
|
52
|
+
stream.puts "The lockfile doesn't exists. We continue."
|
53
|
+
end
|
54
|
+
stream.puts "Let's try that one more time."
|
55
|
+
begin
|
56
|
+
Index.lock
|
57
|
+
rescue Index::LockError => e
|
58
|
+
stream.puts "I couldn't unlock the index."
|
59
|
+
return false
|
60
|
+
end
|
61
|
+
return true
|
62
|
+
end
|
63
|
+
end
|
45
64
|
end
|
46
|
-
|
47
|
-
stream.puts "
|
65
|
+
rescue Errno::ESRCH # no such process
|
66
|
+
stream.puts "I couldn't lock the index. The lockfile might just be stale."
|
67
|
+
begin
|
68
|
+
FileUtils.rm e.path
|
69
|
+
rescue Errno::ENOENT
|
70
|
+
stream.puts "The lockfile doesn't exists. We continue."
|
71
|
+
end
|
72
|
+
stream.puts "Let's try that one more time."
|
48
73
|
begin
|
74
|
+
sleep DELAY
|
49
75
|
Index.lock
|
50
76
|
rescue Index::LockError => e
|
51
|
-
stream.puts "I couldn't
|
52
|
-
|
53
|
-
stream.flush
|
54
|
-
|
55
|
-
if $stdin.gets =~ /^\s*y(es)?\s*$/i
|
56
|
-
FileUtils.rm e.path
|
57
|
-
|
58
|
-
stream.puts "Let's try that one more time."
|
59
|
-
begin
|
60
|
-
Index.lock
|
61
|
-
true
|
62
|
-
rescue Index::LockError => e
|
63
|
-
end
|
64
|
-
end
|
77
|
+
stream.puts "I couldn't unlock the index."
|
78
|
+
return false
|
65
79
|
end
|
80
|
+
return true
|
66
81
|
end
|
67
|
-
|
68
|
-
|
69
|
-
success
|
82
|
+
stream.puts "Sorry, couldn't unlock the index."
|
83
|
+
return false
|
70
84
|
end
|
85
|
+
return true
|
71
86
|
end
|
72
87
|
end
|
73
88
|
|
data/lib/sup/mbox.rb
CHANGED
@@ -119,8 +119,6 @@ class MBox < Source
|
|
119
119
|
## we're just moving messages around on disk, than reading things
|
120
120
|
## into memory with raw_message.
|
121
121
|
##
|
122
|
-
## i hoped never to have to move shit around on disk but
|
123
|
-
## sup-sync-back-mbox has to do it.
|
124
122
|
def each_raw_message_line offset
|
125
123
|
@mutex.synchronize do
|
126
124
|
ensure_open
|
data/lib/sup/message_chunks.rb
CHANGED
@@ -60,8 +60,6 @@ end
|
|
60
60
|
module Redwood
|
61
61
|
module Chunk
|
62
62
|
class Attachment
|
63
|
-
## please see note in write_to_disk on important usage
|
64
|
-
## of quotes to avoid remote command injection.
|
65
63
|
HookManager.register "mime-decode", <<EOS
|
66
64
|
Decodes a MIME attachment into text form. The text will be displayed
|
67
65
|
directly in Sup. For attachments that you wish to use a separate program
|
@@ -79,8 +77,6 @@ Return value:
|
|
79
77
|
EOS
|
80
78
|
|
81
79
|
|
82
|
-
## please see note in write_to_disk on important usage
|
83
|
-
## of quotes to avoid remote command injection.
|
84
80
|
HookManager.register "mime-view", <<EOS
|
85
81
|
Views a non-text MIME attachment. This hook allows you to run
|
86
82
|
third-party programs for attachments that require such a thing (e.g.
|
@@ -132,8 +128,6 @@ EOS
|
|
132
128
|
when /^text\/plain\b/
|
133
129
|
@raw_content
|
134
130
|
else
|
135
|
-
## please see note in write_to_disk on important usage
|
136
|
-
## of quotes to avoid remote command injection.
|
137
131
|
HookManager.run "mime-decode", :content_type => @content_type,
|
138
132
|
:filename => lambda { write_to_disk },
|
139
133
|
:charset => encoded_content.charset,
|
@@ -171,8 +165,6 @@ EOS
|
|
171
165
|
def initial_state; :open end
|
172
166
|
def viewable?; @lines.nil? end
|
173
167
|
def view_default! path
|
174
|
-
## please see note in write_to_disk on important usage
|
175
|
-
## of quotes to avoid remote command injection.
|
176
168
|
case RbConfig::CONFIG['arch']
|
177
169
|
when /darwin/
|
178
170
|
cmd = "open #{path}"
|
@@ -185,28 +177,32 @@ EOS
|
|
185
177
|
end
|
186
178
|
|
187
179
|
def view!
|
188
|
-
|
189
|
-
## of quotes to avoid remote command injection.
|
190
|
-
write_to_disk do |file|
|
191
|
-
|
192
|
-
@@view_tempfiles.push file # make sure the tempfile is not garbage collected before sup stops
|
193
|
-
|
180
|
+
write_to_disk do |path|
|
194
181
|
ret = HookManager.run "mime-view", :content_type => @content_type,
|
195
|
-
:filename =>
|
196
|
-
ret || view_default!(
|
182
|
+
:filename => path
|
183
|
+
ret || view_default!(path)
|
197
184
|
end
|
198
185
|
end
|
199
186
|
|
200
|
-
## note that the path returned from write_to_disk is
|
201
|
-
## Shellwords.escaped and is intended to be used without single
|
202
|
-
## or double quotes. the use of either opens sup up for remote
|
203
|
-
## code injection through the file name.
|
204
187
|
def write_to_disk
|
205
188
|
begin
|
206
|
-
|
189
|
+
# Add the original extension to the generated tempfile name only if the
|
190
|
+
# extension is "safe" (won't be interpreted by the shell). Since
|
191
|
+
# Tempfile.new always generates safe file names this should prevent
|
192
|
+
# attacking the user with funny attachment file names.
|
193
|
+
tempname = if (File.extname @filename) =~ /^\.[[:alnum:]]+$/ then
|
194
|
+
["sup-attachment", File.extname(@filename)]
|
195
|
+
else
|
196
|
+
"sup-attachment"
|
197
|
+
end
|
198
|
+
|
199
|
+
file = Tempfile.new(tempname)
|
207
200
|
file.print @raw_content
|
208
201
|
file.flush
|
209
|
-
|
202
|
+
|
203
|
+
@@view_tempfiles.push file # make sure the tempfile is not garbage collected before sup stops
|
204
|
+
|
205
|
+
yield file.path if block_given?
|
210
206
|
return file.path
|
211
207
|
ensure
|
212
208
|
file.close
|
@@ -130,7 +130,7 @@ protected
|
|
130
130
|
def text_for_contact p
|
131
131
|
aalias = ContactManager.alias_for(p) || ""
|
132
132
|
[[:tagged_color, @tags.tagged?(p) ? ">" : " "],
|
133
|
-
[:
|
133
|
+
[:text_color, sprintf("%-#{@awidth}s %-#{@nwidth}s %s", aalias, p.name, p.email)]]
|
134
134
|
end
|
135
135
|
|
136
136
|
def regen_text
|
data/lib/sup/modes/inbox_mode.rb
CHANGED
@@ -6,7 +6,6 @@ class InboxMode < ThreadIndexMode
|
|
6
6
|
register_keymap do |k|
|
7
7
|
## overwrite toggle_archived with archive
|
8
8
|
k.add :archive, "Archive thread (remove from inbox)", 'a'
|
9
|
-
k.add :read_and_archive, "Archive thread (remove from inbox) and mark read", 'A'
|
10
9
|
k.add :refine_search, "Refine search", '|'
|
11
10
|
end
|
12
11
|
|
@@ -64,47 +63,6 @@ class InboxMode < ThreadIndexMode
|
|
64
63
|
threads.each { |t| Index.save_thread t }
|
65
64
|
end
|
66
65
|
|
67
|
-
def read_and_archive
|
68
|
-
return unless cursor_thread
|
69
|
-
thread = cursor_thread # to make sure lambda only knows about 'old' cursor_thread
|
70
|
-
|
71
|
-
was_unread = thread.labels.member? :unread
|
72
|
-
UndoManager.register "reading and archiving thread" do
|
73
|
-
thread.apply_label :inbox
|
74
|
-
thread.apply_label :unread if was_unread
|
75
|
-
add_or_unhide thread.first
|
76
|
-
Index.save_thread thread
|
77
|
-
end
|
78
|
-
|
79
|
-
cursor_thread.remove_label :unread
|
80
|
-
cursor_thread.remove_label :inbox
|
81
|
-
hide_thread cursor_thread
|
82
|
-
regen_text
|
83
|
-
Index.save_thread thread
|
84
|
-
end
|
85
|
-
|
86
|
-
def multi_read_and_archive threads
|
87
|
-
old_labels = threads.map { |t| t.labels.dup }
|
88
|
-
|
89
|
-
threads.each do |t|
|
90
|
-
t.remove_label :unread
|
91
|
-
t.remove_label :inbox
|
92
|
-
hide_thread t
|
93
|
-
end
|
94
|
-
regen_text
|
95
|
-
|
96
|
-
UndoManager.register "reading and archiving #{threads.size.pluralize 'thread'}" do
|
97
|
-
threads.zip(old_labels).each do |t, l|
|
98
|
-
t.labels = l
|
99
|
-
add_or_unhide t.first
|
100
|
-
Index.save_thread t
|
101
|
-
end
|
102
|
-
regen_text
|
103
|
-
end
|
104
|
-
|
105
|
-
threads.each { |t| Index.save_thread t }
|
106
|
-
end
|
107
|
-
|
108
66
|
def handle_unarchived_update sender, m
|
109
67
|
add_or_unhide m
|
110
68
|
end
|
@@ -33,6 +33,7 @@ EOS
|
|
33
33
|
k.add_multi "Load all threads (! to confirm) :", '!' do |kk|
|
34
34
|
kk.add :load_all_threads, "Load all threads (may list a _lot_ of threads)", '!'
|
35
35
|
end
|
36
|
+
k.add :read_and_archive, "Archive thread (remove from inbox) and mark read", 'A'
|
36
37
|
k.add :cancel_search, "Cancel current search", :ctrl_g
|
37
38
|
k.add :reload, "Refresh view", '@'
|
38
39
|
k.add :toggle_archived, "Toggle archived status", 'a'
|
@@ -732,6 +733,47 @@ EOS
|
|
732
733
|
end
|
733
734
|
ignore_concurrent_calls :load_threads
|
734
735
|
|
736
|
+
def read_and_archive
|
737
|
+
return unless cursor_thread
|
738
|
+
thread = cursor_thread # to make sure lambda only knows about 'old' cursor_thread
|
739
|
+
|
740
|
+
was_unread = thread.labels.member? :unread
|
741
|
+
UndoManager.register "reading and archiving thread" do
|
742
|
+
thread.apply_label :inbox
|
743
|
+
thread.apply_label :unread if was_unread
|
744
|
+
add_or_unhide thread.first
|
745
|
+
Index.save_thread thread
|
746
|
+
end
|
747
|
+
|
748
|
+
cursor_thread.remove_label :unread
|
749
|
+
cursor_thread.remove_label :inbox
|
750
|
+
hide_thread cursor_thread
|
751
|
+
regen_text
|
752
|
+
Index.save_thread thread
|
753
|
+
end
|
754
|
+
|
755
|
+
def multi_read_and_archive threads
|
756
|
+
old_labels = threads.map { |t| t.labels.dup }
|
757
|
+
|
758
|
+
threads.each do |t|
|
759
|
+
t.remove_label :unread
|
760
|
+
t.remove_label :inbox
|
761
|
+
hide_thread t
|
762
|
+
end
|
763
|
+
regen_text
|
764
|
+
|
765
|
+
UndoManager.register "reading and archiving #{threads.size.pluralize 'thread'}" do
|
766
|
+
threads.zip(old_labels).each do |t, l|
|
767
|
+
t.labels = l
|
768
|
+
add_or_unhide t.first
|
769
|
+
Index.save_thread t
|
770
|
+
end
|
771
|
+
regen_text
|
772
|
+
end
|
773
|
+
|
774
|
+
threads.each { |t| Index.save_thread t }
|
775
|
+
end
|
776
|
+
|
735
777
|
def resize rows, cols
|
736
778
|
regen_text
|
737
779
|
super
|
@@ -692,6 +692,15 @@ EOS
|
|
692
692
|
end
|
693
693
|
end
|
694
694
|
|
695
|
+
|
696
|
+
def status
|
697
|
+
user_labels = @thread.labels.to_a.map do |l|
|
698
|
+
l.to_s if LabelManager.user_defined_labels.member?(l)
|
699
|
+
end.compact.join(",")
|
700
|
+
user_labels = (user_labels.empty? and "" or "<#{user_labels}>")
|
701
|
+
[user_labels, super].join(" -- ")
|
702
|
+
end
|
703
|
+
|
695
704
|
private
|
696
705
|
|
697
706
|
def initial_state_for m
|
data/lib/sup/person.rb
CHANGED
data/lib/sup/source.rb
CHANGED
data/lib/sup/util.rb
CHANGED
@@ -267,6 +267,14 @@ end
|
|
267
267
|
class String
|
268
268
|
def display_length
|
269
269
|
@display_length ||= Unicode.width(self.fix_encoding!, false)
|
270
|
+
|
271
|
+
# if Unicode.width fails and returns -1, fall back to
|
272
|
+
# regular String#length, see pull-request: #256.
|
273
|
+
if @display_length < 0
|
274
|
+
@display_length = self.length
|
275
|
+
end
|
276
|
+
|
277
|
+
@display_length
|
270
278
|
end
|
271
279
|
|
272
280
|
def slice_by_display_length len
|
data/lib/sup/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sup
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.16.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- William Morgan
|
@@ -11,253 +11,248 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain:
|
14
|
-
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
YXBuUHBzdEJxcWR2NjBSQjhITkd5ZEhRZUV6NnVzNXozbmorS2NoUHFKNjU3
|
37
|
-
RHo4b1gvTm02LzI0CjdRU1FwQ2g4eEJZZFNXRXBvSUUwelVTWTc3THRWVFJW
|
38
|
-
d0lyOXVEcFdUVHI5a0NWQklOQnNPUU5qV0tydUVXalYKK0pNdURzK2lXZWZw
|
39
|
-
RjRSM0J5U29PYzFRNFdvRVMzK29jMHFvMzdNc0FaeWZuUUlQVFpreUxaQ014
|
40
|
-
ZUw2TWhhNApoRmMyeUFOQmo4dm9hWTVDNzRDZzJWcUV4dGNuU2F4VXRXOXdD
|
41
|
-
NHc1aE9sZzBBVmZiMUpXemc9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0t
|
42
|
-
Cg==
|
43
|
-
date: 2014-02-06 00:00:00.000000000 Z
|
14
|
+
- |
|
15
|
+
-----BEGIN CERTIFICATE-----
|
16
|
+
MIIDVDCCAjygAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQDDAJlZzEV
|
17
|
+
MBMGCgmSJomT8ixkARkWBWdhdXRlMRUwEwYKCZImiZPyLGQBGRYFdmV0c2oxEzAR
|
18
|
+
BgoJkiaJk/IsZAEZFgNjb20wHhcNMTMwNTA4MTAzODQ3WhcNMTQwNTA4MTAzODQ3
|
19
|
+
WjBQMQswCQYDVQQDDAJlZzEVMBMGCgmSJomT8ixkARkWBWdhdXRlMRUwEwYKCZIm
|
20
|
+
iZPyLGQBGRYFdmV0c2oxEzARBgoJkiaJk/IsZAEZFgNjb20wggEiMA0GCSqGSIb3
|
21
|
+
DQEBAQUAA4IBDwAwggEKAoIBAQC7sNc5zY4MrYB7eywE/aK2IoDqpM9lq4ZFlHzt
|
22
|
+
Pmq1LG6ah2lu/HfjqxiPoqwY7QkdSOGDLSk7G8YBqDA/tODhkPPSTqxBDzYyCO46
|
23
|
+
haWTtoN5tJkxIDJKp1nVXHi0Mlb4GJVKd9P0q95BeBYBfs8vyPN+y4b4Gebgx9U3
|
24
|
+
KqMDbe5h9MAPZGmtiRFMb3ugmiujDm7v8fACa5EtSvK/lxMkRDglecT/knE99NYI
|
25
|
+
l35SO/Bune1bxYmkwW64mQ4wRlGVeAnX+19msALfS9rdJL26dfW2LgqWi5QoVTBH
|
26
|
+
KNKTl/i3fxK0mzgtnoRCWdMJQFNNonFTnPUUawi1c9Kh4AdPAgMBAAGjOTA3MAkG
|
27
|
+
A1UdEwQCMAAwHQYDVR0OBBYEFJNCOxL0SWcbW2M+DIEUzAMz1bZsMAsGA1UdDwQE
|
28
|
+
AwIEsDANBgkqhkiG9w0BAQUFAAOCAQEAr3QUayd0geBDExO+WwzaEPAuUZ3zWQYG
|
29
|
+
G9vrplCkmJtjS/X/wVAef7Jn/V5MNkXKXsiOgXJXki+n7HulNZUf1rzr7Un96gVJ
|
30
|
+
1hq/ZTuapnPpstBqqdv60RB8HNGydHQeEz6us5z3nj+KchPqJ657Dz8oX/Nm6/24
|
31
|
+
7QSQpCh8xBYdSWEpoIE0zUSY77LtVTRVwIr9uDpWTTr9kCVBINBsOQNjWKruEWjV
|
32
|
+
+JMuDs+iWefpF4R3BySoOc1Q4WoES3+oc0qo37MsAZyfnQIPTZkyLZCMxeL6Mha4
|
33
|
+
hFc2yANBj8voaY5C74Cg2VqExtcnSaxUtW9wC4w5hOlg0AVfb1JWzg==
|
34
|
+
-----END CERTIFICATE-----
|
35
|
+
date: 2014-03-21 00:00:00.000000000 Z
|
44
36
|
dependencies:
|
45
37
|
- !ruby/object:Gem::Dependency
|
46
38
|
name: xapian-ruby
|
47
39
|
requirement: !ruby/object:Gem::Requirement
|
48
40
|
requirements:
|
49
|
-
- - ~>
|
41
|
+
- - "~>"
|
50
42
|
- !ruby/object:Gem::Version
|
51
43
|
version: 1.2.15
|
52
44
|
type: :runtime
|
53
45
|
prerelease: false
|
54
46
|
version_requirements: !ruby/object:Gem::Requirement
|
55
47
|
requirements:
|
56
|
-
- - ~>
|
48
|
+
- - "~>"
|
57
49
|
- !ruby/object:Gem::Version
|
58
50
|
version: 1.2.15
|
59
51
|
- !ruby/object:Gem::Dependency
|
60
52
|
name: ncursesw
|
61
53
|
requirement: !ruby/object:Gem::Requirement
|
62
54
|
requirements:
|
63
|
-
- - ~>
|
55
|
+
- - "~>"
|
64
56
|
- !ruby/object:Gem::Version
|
65
57
|
version: 1.4.0
|
66
58
|
type: :runtime
|
67
59
|
prerelease: false
|
68
60
|
version_requirements: !ruby/object:Gem::Requirement
|
69
61
|
requirements:
|
70
|
-
- - ~>
|
62
|
+
- - "~>"
|
71
63
|
- !ruby/object:Gem::Version
|
72
64
|
version: 1.4.0
|
73
65
|
- !ruby/object:Gem::Dependency
|
74
66
|
name: rmail-sup
|
75
67
|
requirement: !ruby/object:Gem::Requirement
|
76
68
|
requirements:
|
77
|
-
- - ~>
|
69
|
+
- - "~>"
|
78
70
|
- !ruby/object:Gem::Version
|
79
71
|
version: 1.0.1
|
80
72
|
type: :runtime
|
81
73
|
prerelease: false
|
82
74
|
version_requirements: !ruby/object:Gem::Requirement
|
83
75
|
requirements:
|
84
|
-
- - ~>
|
76
|
+
- - "~>"
|
85
77
|
- !ruby/object:Gem::Version
|
86
78
|
version: 1.0.1
|
87
79
|
- !ruby/object:Gem::Dependency
|
88
80
|
name: highline
|
89
81
|
requirement: !ruby/object:Gem::Requirement
|
90
82
|
requirements:
|
91
|
-
- -
|
83
|
+
- - ">="
|
92
84
|
- !ruby/object:Gem::Version
|
93
85
|
version: '0'
|
94
86
|
type: :runtime
|
95
87
|
prerelease: false
|
96
88
|
version_requirements: !ruby/object:Gem::Requirement
|
97
89
|
requirements:
|
98
|
-
- -
|
90
|
+
- - ">="
|
99
91
|
- !ruby/object:Gem::Version
|
100
92
|
version: '0'
|
101
93
|
- !ruby/object:Gem::Dependency
|
102
94
|
name: trollop
|
103
95
|
requirement: !ruby/object:Gem::Requirement
|
104
96
|
requirements:
|
105
|
-
- -
|
97
|
+
- - ">="
|
106
98
|
- !ruby/object:Gem::Version
|
107
99
|
version: '1.12'
|
108
100
|
type: :runtime
|
109
101
|
prerelease: false
|
110
102
|
version_requirements: !ruby/object:Gem::Requirement
|
111
103
|
requirements:
|
112
|
-
- -
|
104
|
+
- - ">="
|
113
105
|
- !ruby/object:Gem::Version
|
114
106
|
version: '1.12'
|
115
107
|
- !ruby/object:Gem::Dependency
|
116
108
|
name: lockfile
|
117
109
|
requirement: !ruby/object:Gem::Requirement
|
118
110
|
requirements:
|
119
|
-
- -
|
111
|
+
- - ">="
|
120
112
|
- !ruby/object:Gem::Version
|
121
113
|
version: '0'
|
122
114
|
type: :runtime
|
123
115
|
prerelease: false
|
124
116
|
version_requirements: !ruby/object:Gem::Requirement
|
125
117
|
requirements:
|
126
|
-
- -
|
118
|
+
- - ">="
|
127
119
|
- !ruby/object:Gem::Version
|
128
120
|
version: '0'
|
129
121
|
- !ruby/object:Gem::Dependency
|
130
122
|
name: mime-types
|
131
123
|
requirement: !ruby/object:Gem::Requirement
|
132
124
|
requirements:
|
133
|
-
- - ~>
|
125
|
+
- - "~>"
|
134
126
|
- !ruby/object:Gem::Version
|
135
127
|
version: '1.0'
|
136
128
|
type: :runtime
|
137
129
|
prerelease: false
|
138
130
|
version_requirements: !ruby/object:Gem::Requirement
|
139
131
|
requirements:
|
140
|
-
- - ~>
|
132
|
+
- - "~>"
|
141
133
|
- !ruby/object:Gem::Version
|
142
134
|
version: '1.0'
|
143
135
|
- !ruby/object:Gem::Dependency
|
144
136
|
name: locale
|
145
137
|
requirement: !ruby/object:Gem::Requirement
|
146
138
|
requirements:
|
147
|
-
- - ~>
|
139
|
+
- - "~>"
|
148
140
|
- !ruby/object:Gem::Version
|
149
141
|
version: '2.0'
|
150
142
|
type: :runtime
|
151
143
|
prerelease: false
|
152
144
|
version_requirements: !ruby/object:Gem::Requirement
|
153
145
|
requirements:
|
154
|
-
- - ~>
|
146
|
+
- - "~>"
|
155
147
|
- !ruby/object:Gem::Version
|
156
148
|
version: '2.0'
|
157
149
|
- !ruby/object:Gem::Dependency
|
158
150
|
name: chronic
|
159
151
|
requirement: !ruby/object:Gem::Requirement
|
160
152
|
requirements:
|
161
|
-
- - ~>
|
153
|
+
- - "~>"
|
162
154
|
- !ruby/object:Gem::Version
|
163
155
|
version: 0.9.1
|
164
156
|
type: :runtime
|
165
157
|
prerelease: false
|
166
158
|
version_requirements: !ruby/object:Gem::Requirement
|
167
159
|
requirements:
|
168
|
-
- - ~>
|
160
|
+
- - "~>"
|
169
161
|
- !ruby/object:Gem::Version
|
170
162
|
version: 0.9.1
|
171
163
|
- !ruby/object:Gem::Dependency
|
172
164
|
name: unicode
|
173
165
|
requirement: !ruby/object:Gem::Requirement
|
174
166
|
requirements:
|
175
|
-
- - ~>
|
167
|
+
- - "~>"
|
176
168
|
- !ruby/object:Gem::Version
|
177
169
|
version: 0.4.4
|
178
170
|
type: :runtime
|
179
171
|
prerelease: false
|
180
172
|
version_requirements: !ruby/object:Gem::Requirement
|
181
173
|
requirements:
|
182
|
-
- - ~>
|
174
|
+
- - "~>"
|
183
175
|
- !ruby/object:Gem::Version
|
184
176
|
version: 0.4.4
|
185
177
|
- !ruby/object:Gem::Dependency
|
186
178
|
name: bundler
|
187
179
|
requirement: !ruby/object:Gem::Requirement
|
188
180
|
requirements:
|
189
|
-
- - ~>
|
181
|
+
- - "~>"
|
190
182
|
- !ruby/object:Gem::Version
|
191
183
|
version: '1.3'
|
192
184
|
type: :development
|
193
185
|
prerelease: false
|
194
186
|
version_requirements: !ruby/object:Gem::Requirement
|
195
187
|
requirements:
|
196
|
-
- - ~>
|
188
|
+
- - "~>"
|
197
189
|
- !ruby/object:Gem::Version
|
198
190
|
version: '1.3'
|
199
191
|
- !ruby/object:Gem::Dependency
|
200
192
|
name: rake
|
201
193
|
requirement: !ruby/object:Gem::Requirement
|
202
194
|
requirements:
|
203
|
-
- -
|
195
|
+
- - ">="
|
204
196
|
- !ruby/object:Gem::Version
|
205
197
|
version: '0'
|
206
198
|
type: :development
|
207
199
|
prerelease: false
|
208
200
|
version_requirements: !ruby/object:Gem::Requirement
|
209
201
|
requirements:
|
210
|
-
- -
|
202
|
+
- - ">="
|
211
203
|
- !ruby/object:Gem::Version
|
212
204
|
version: '0'
|
213
205
|
- !ruby/object:Gem::Dependency
|
214
206
|
name: minitest
|
215
207
|
requirement: !ruby/object:Gem::Requirement
|
216
208
|
requirements:
|
217
|
-
- - ~>
|
209
|
+
- - "~>"
|
218
210
|
- !ruby/object:Gem::Version
|
219
211
|
version: '4.7'
|
220
212
|
type: :development
|
221
213
|
prerelease: false
|
222
214
|
version_requirements: !ruby/object:Gem::Requirement
|
223
215
|
requirements:
|
224
|
-
- - ~>
|
216
|
+
- - "~>"
|
225
217
|
- !ruby/object:Gem::Version
|
226
218
|
version: '4.7'
|
227
219
|
- !ruby/object:Gem::Dependency
|
228
220
|
name: rr
|
229
221
|
requirement: !ruby/object:Gem::Requirement
|
230
222
|
requirements:
|
231
|
-
- - ~>
|
223
|
+
- - "~>"
|
232
224
|
- !ruby/object:Gem::Version
|
233
225
|
version: 1.0.5
|
234
226
|
type: :development
|
235
227
|
prerelease: false
|
236
228
|
version_requirements: !ruby/object:Gem::Requirement
|
237
229
|
requirements:
|
238
|
-
- - ~>
|
230
|
+
- - "~>"
|
239
231
|
- !ruby/object:Gem::Version
|
240
232
|
version: 1.0.5
|
241
233
|
- !ruby/object:Gem::Dependency
|
242
234
|
name: gpgme
|
243
235
|
requirement: !ruby/object:Gem::Requirement
|
244
236
|
requirements:
|
245
|
-
- -
|
237
|
+
- - ">="
|
246
238
|
- !ruby/object:Gem::Version
|
247
239
|
version: 2.0.2
|
248
240
|
type: :development
|
249
241
|
prerelease: false
|
250
242
|
version_requirements: !ruby/object:Gem::Requirement
|
251
243
|
requirements:
|
252
|
-
- -
|
244
|
+
- - ">="
|
253
245
|
- !ruby/object:Gem::Version
|
254
246
|
version: 2.0.2
|
255
|
-
description:
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
247
|
+
description: |2
|
248
|
+
Sup is a console-based email client for people with a lot of email.
|
249
|
+
|
250
|
+
* GMail-like thread-centered archiving, tagging and muting
|
251
|
+
* Handling mail from multiple mbox and Maildir sources
|
252
|
+
* Blazing fast full-text search with a rich query language
|
253
|
+
* Multiple accounts - pick the right one when sending mail
|
254
|
+
* Ruby-programmable hooks
|
255
|
+
* Automatically tracking recent contacts
|
261
256
|
email: sup-talk@rubyforge.org
|
262
257
|
executables:
|
263
258
|
- sup
|
@@ -268,7 +263,6 @@ executables:
|
|
268
263
|
- sup-recover-sources
|
269
264
|
- sup-sync
|
270
265
|
- sup-sync-back-maildir
|
271
|
-
- sup-sync-back-mbox
|
272
266
|
- sup-tweak-labels
|
273
267
|
- sup-psych-ify-config-files
|
274
268
|
extensions: []
|
@@ -288,7 +282,6 @@ files:
|
|
288
282
|
- bin/sup-recover-sources
|
289
283
|
- bin/sup-sync
|
290
284
|
- bin/sup-sync-back-maildir
|
291
|
-
- bin/sup-sync-back-mbox
|
292
285
|
- bin/sup-tweak-labels
|
293
286
|
- lib/sup.rb
|
294
287
|
- lib/sup/account.rb
|
@@ -359,26 +352,28 @@ homepage: http://supmua.org
|
|
359
352
|
licenses:
|
360
353
|
- GPL-2
|
361
354
|
metadata: {}
|
362
|
-
post_install_message:
|
363
|
-
|
364
|
-
|
365
|
-
|
355
|
+
post_install_message: |
|
356
|
+
SUP: If you are upgrading Sup from before version 0.14.0: Please
|
357
|
+
run `sup-psych-ify-config-files` to migrate from 0.13.
|
358
|
+
|
359
|
+
Check https://github.com/sup-heliotrope/sup/wiki/Migration-0.13-to-0.14
|
360
|
+
for more detailed and up-to-date instructions.
|
366
361
|
rdoc_options: []
|
367
362
|
require_paths:
|
368
363
|
- lib
|
369
364
|
required_ruby_version: !ruby/object:Gem::Requirement
|
370
365
|
requirements:
|
371
|
-
- -
|
366
|
+
- - ">="
|
372
367
|
- !ruby/object:Gem::Version
|
373
368
|
version: 1.9.2
|
374
369
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
375
370
|
requirements:
|
376
|
-
- -
|
371
|
+
- - ">="
|
377
372
|
- !ruby/object:Gem::Version
|
378
373
|
version: '0'
|
379
374
|
requirements: []
|
380
375
|
rubyforge_project:
|
381
|
-
rubygems_version: 2.2.
|
376
|
+
rubygems_version: 2.2.2
|
382
377
|
signing_key:
|
383
378
|
specification_version: 4
|
384
379
|
summary: A console-based email client with the best features of GMail, mutt and Emacs
|
metadata.gz.sig
CHANGED
Binary file
|
data/bin/sup-sync-back-mbox
DELETED
@@ -1,181 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
$:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
|
4
|
-
|
5
|
-
require 'rubygems'
|
6
|
-
require 'uri'
|
7
|
-
require 'tempfile'
|
8
|
-
require 'trollop'
|
9
|
-
require "sup"
|
10
|
-
|
11
|
-
fail "not working yet"
|
12
|
-
|
13
|
-
## save a message 'm' to an open file pointer 'fp'
|
14
|
-
def save m, fp
|
15
|
-
m.source.each_raw_message_line(m.source_info) { |l| fp.print l }
|
16
|
-
end
|
17
|
-
def die msg
|
18
|
-
$stderr.puts "Error: #{msg}"
|
19
|
-
exit(-1)
|
20
|
-
end
|
21
|
-
def has_any_from_source_with_label? index, source, label
|
22
|
-
query = { :source_id => source.id, :label => label, :limit => 1, :load_spam => true, :load_deleted => true, :load_killed => true }
|
23
|
-
index.num_results_for(query) != 0
|
24
|
-
end
|
25
|
-
|
26
|
-
opts = Trollop::options do
|
27
|
-
version "sup-sync-back-mbox (sup #{Redwood::VERSION})"
|
28
|
-
banner <<EOS
|
29
|
-
Drop or move messages from Sup sources that are marked as deleted or
|
30
|
-
spam in the Sup index.
|
31
|
-
|
32
|
-
Currently only works with mbox sources.
|
33
|
-
|
34
|
-
Usage:
|
35
|
-
sup-sync-back-mbox [options] <source>*
|
36
|
-
|
37
|
-
where <source>* is zero or more source URIs. If no sources are given,
|
38
|
-
sync back all usual sources.
|
39
|
-
|
40
|
-
You almost certainly want to run sup-sync --changed after this command.
|
41
|
-
Running this does not change the index.
|
42
|
-
|
43
|
-
Options include:
|
44
|
-
EOS
|
45
|
-
opt :drop_deleted, "Drop deleted messages.", :default => false, :short => "d"
|
46
|
-
opt :move_deleted, "Move deleted messages to a local mbox file.", :type => String, :short => :none
|
47
|
-
opt :drop_spam, "Drop spam messages.", :default => false, :short => "s"
|
48
|
-
opt :move_spam, "Move spam messages to a local mbox file.", :type => String, :short => :none
|
49
|
-
|
50
|
-
opt :with_dotlockfile, "Specific dotlockfile location (mbox files only).", :default => "/usr/bin/dotlockfile", :short => :none
|
51
|
-
opt :dont_use_dotlockfile, "Don't use dotlockfile to lock mbox files. Dangerous if other processes modify them concurrently.", :default => false, :short => :none
|
52
|
-
|
53
|
-
opt :verbose, "Print message ids as they're processed."
|
54
|
-
opt :dry_run, "Don't actually modify the index. Probably only useful with --verbose.", :short => "-n"
|
55
|
-
opt :version, "Show version information", :short => :none
|
56
|
-
|
57
|
-
conflicts :drop_deleted, :move_deleted
|
58
|
-
conflicts :drop_spam, :move_spam
|
59
|
-
end
|
60
|
-
|
61
|
-
unless opts[:drop_deleted] || opts[:move_deleted] || opts[:drop_spam] || opts[:move_spam]
|
62
|
-
puts <<EOS
|
63
|
-
Nothing to do. Please specify at least one of --drop-deleted, --move-deleted,
|
64
|
-
--drop-spam, or --move-spam.
|
65
|
-
EOS
|
66
|
-
|
67
|
-
exit
|
68
|
-
end
|
69
|
-
|
70
|
-
Redwood::start
|
71
|
-
index = Redwood::Index.init
|
72
|
-
index.lock_interactively or exit
|
73
|
-
|
74
|
-
deleted_fp, spam_fp = nil
|
75
|
-
unless opts[:dry_run]
|
76
|
-
deleted_fp = File.open(opts[:move_deleted], "a") if opts[:move_deleted]
|
77
|
-
spam_fp = File.open(opts[:move_spam], "a") if opts[:move_spam]
|
78
|
-
end
|
79
|
-
|
80
|
-
dotlockfile = opts[:with_dotlockfile] || "/usr/bin/dotlockfile"
|
81
|
-
|
82
|
-
begin
|
83
|
-
index.load
|
84
|
-
|
85
|
-
sources = ARGV.map do |uri|
|
86
|
-
s = Redwood::SourceManager.source_for(uri) or die "unknown source: #{uri}. Did you add it with sup-add first?"
|
87
|
-
s.is_a?(Redwood::MBox) or die "#{uri} is not an mbox source."
|
88
|
-
s
|
89
|
-
end
|
90
|
-
|
91
|
-
if sources.empty?
|
92
|
-
sources = Redwood::SourceManager.usual_sources.select { |s| s.is_a? Redwood::MBox }
|
93
|
-
end
|
94
|
-
|
95
|
-
unless sources.all? { |s| s.file_path.nil? } || File.executable?(dotlockfile) || opts[:dont_use_dotlockfile]
|
96
|
-
die <<EOS
|
97
|
-
can't execute dotlockfile binary: #{dotlockfile}. Specify --with-dotlockfile
|
98
|
-
if it's in a nonstandard location, or, if you want to live dangerously, try
|
99
|
-
--dont-use-dotlockfile
|
100
|
-
EOS
|
101
|
-
end
|
102
|
-
|
103
|
-
modified_sources = []
|
104
|
-
sources.each do |source|
|
105
|
-
$stderr.puts "Scanning #{source}..."
|
106
|
-
|
107
|
-
unless ((opts[:drop_deleted] || opts[:move_deleted]) && has_any_from_source_with_label?(index, source, :deleted)) || ((opts[:drop_spam] || opts[:move_spam]) && has_any_from_source_with_label?(index, source, :spam))
|
108
|
-
$stderr.puts "Nothing to do from this source; skipping"
|
109
|
-
next
|
110
|
-
end
|
111
|
-
|
112
|
-
source.reset!
|
113
|
-
num_dropped = num_moved = num_scanned = 0
|
114
|
-
|
115
|
-
out_fp = Tempfile.new "sup-sync-back-mbox-#{source.id}"
|
116
|
-
Redwood::PollManager.each_message_from source do |m|
|
117
|
-
num_scanned += 1
|
118
|
-
|
119
|
-
if(m_old = index.build_message(m.id))
|
120
|
-
labels = m_old.labels
|
121
|
-
|
122
|
-
if labels.member? :deleted
|
123
|
-
if opts[:drop_deleted]
|
124
|
-
puts "Dropping deleted message #{source}##{m.source_info}" if opts[:verbose]
|
125
|
-
num_dropped += 1
|
126
|
-
elsif opts[:move_deleted] && labels.member?(:deleted)
|
127
|
-
puts "Moving deleted message #{source}##{m.source_info}" if opts[:verbose]
|
128
|
-
save m, deleted_fp unless opts[:dry_run]
|
129
|
-
num_moved += 1
|
130
|
-
end
|
131
|
-
|
132
|
-
elsif labels.member? :spam
|
133
|
-
if opts[:drop_spam]
|
134
|
-
puts "Dropping spam message #{source}##{m.source_info}" if opts[:verbose]
|
135
|
-
num_dropped += 1
|
136
|
-
elsif opts[:move_spam] && labels.member?(:spam)
|
137
|
-
puts "Moving spam message #{source}##{m.source_info}" if opts[:verbose]
|
138
|
-
save m, spam_fp unless opts[:dry_run]
|
139
|
-
num_moved += 1
|
140
|
-
end
|
141
|
-
else
|
142
|
-
save m, out_fp unless opts[:dry_run]
|
143
|
-
end
|
144
|
-
else
|
145
|
-
save m, out_fp unless opts[:dry_run]
|
146
|
-
end
|
147
|
-
end
|
148
|
-
$stderr.puts "Scanned #{num_scanned}, dropped #{num_dropped}, moved #{num_moved} messages from #{source}."
|
149
|
-
modified_sources << source if num_dropped > 0 || num_moved > 0
|
150
|
-
out_fp.close unless opts[:dry_run]
|
151
|
-
|
152
|
-
unless opts[:dry_run] || (num_dropped == 0 && num_moved == 0)
|
153
|
-
deleted_fp.flush if deleted_fp
|
154
|
-
spam_fp.flush if spam_fp
|
155
|
-
unless opts[:dont_use_dotlockfile]
|
156
|
-
puts "Locking #{source.file_path}..."
|
157
|
-
system "#{opts[:dotlockfile]} -l #{source.file_path}"
|
158
|
-
puts "Writing #{source.file_path}..."
|
159
|
-
FileUtils.cp out_fp.path, source.file_path
|
160
|
-
puts "Unlocking #{source.file_path}..."
|
161
|
-
system "#{opts[:dotlockfile]} -u #{source.file_path}"
|
162
|
-
end
|
163
|
-
end
|
164
|
-
end
|
165
|
-
|
166
|
-
unless opts[:dry_run]
|
167
|
-
deleted_fp.close if deleted_fp
|
168
|
-
spam_fp.close if spam_fp
|
169
|
-
end
|
170
|
-
|
171
|
-
$stderr.puts "Done."
|
172
|
-
unless modified_sources.empty?
|
173
|
-
$stderr.puts "You should now run: sup-sync --changed #{modified_sources.join(' ')}"
|
174
|
-
end
|
175
|
-
rescue Exception => e
|
176
|
-
File.open("sup-exception-log.txt", "w") { |f| f.puts e.backtrace }
|
177
|
-
raise
|
178
|
-
ensure
|
179
|
-
Redwood::finish
|
180
|
-
index.unlock
|
181
|
-
end
|