sup 0.17.0 → 0.18.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +17 -0
- data/.travis.yml +12 -0
- data/Gemfile +3 -0
- data/HACKING +42 -0
- data/History.txt +8 -0
- data/Rakefile +12 -0
- data/ReleaseNotes +4 -0
- data/bin/sup-sync +1 -1
- data/bin/sup-tweak-labels +6 -1
- data/contrib/colorpicker.rb +100 -0
- data/contrib/completion/_sup.zsh +114 -0
- data/devel/console.sh +3 -0
- data/devel/count-loc.sh +3 -0
- data/devel/load-index.rb +9 -0
- data/devel/profile.rb +12 -0
- data/devel/start-console.rb +5 -0
- data/doc/FAQ.txt +119 -0
- data/doc/Hooks.txt +79 -0
- data/doc/Philosophy.txt +69 -0
- data/lib/sup/colormap.rb +6 -0
- data/lib/sup/modes/thread_index_mode.rb +12 -1
- data/lib/sup/modes/thread_view_mode.rb +20 -0
- data/lib/sup/version.rb +1 -1
- data/sup.gemspec +55 -0
- data/test/dummy_source.rb +61 -0
- data/test/gnupg_test_home/gpg.conf +1 -0
- data/test/gnupg_test_home/pubring.gpg +0 -0
- data/test/gnupg_test_home/receiver_pubring.gpg +0 -0
- data/test/gnupg_test_home/receiver_secring.gpg +0 -0
- data/test/gnupg_test_home/receiver_trustdb.gpg +0 -0
- data/test/gnupg_test_home/secring.gpg +0 -0
- data/test/gnupg_test_home/sup-test-2@foo.bar.asc +20 -0
- data/test/gnupg_test_home/trustdb.gpg +0 -0
- data/test/integration/test_label_service.rb +18 -0
- data/test/messages/bad-content-transfer-encoding-1.eml +8 -0
- data/test/messages/binary-content-transfer-encoding-2.eml +21 -0
- data/test/messages/missing-line.eml +9 -0
- data/test/test_crypto.rb +109 -0
- data/test/test_header_parsing.rb +168 -0
- data/test/test_helper.rb +7 -0
- data/test/test_message.rb +532 -0
- data/test/test_messages_dir.rb +147 -0
- data/test/test_yaml_migration.rb +85 -0
- data/test/test_yaml_regressions.rb +17 -0
- data/test/unit/service/test_label_service.rb +19 -0
- data/test/unit/test_horizontal_selector.rb +40 -0
- data/test/unit/util/test_query.rb +46 -0
- data/test/unit/util/test_string.rb +57 -0
- data/test/unit/util/test_uri.rb +19 -0
- metadata +81 -36
- checksums.yaml.gz.sig +0 -1
- data.tar.gz.sig +0 -0
- metadata.gz.sig +0 -0
data/doc/Hooks.txt
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
Sup's Hook System
|
2
|
+
-----------------
|
3
|
+
|
4
|
+
Sup can be easily customized via its hook system, which allows custom
|
5
|
+
user code to be injected into Sup's execution path by "hooking" the
|
6
|
+
code onto pre-defined events. When those events occur, the code is
|
7
|
+
executed.
|
8
|
+
|
9
|
+
To see which hooks are available, simply run sup -l. Each hook sits in
|
10
|
+
a file in ~/.sup/hooks/. Hooks are written in Ruby, and require no
|
11
|
+
class or method definitions, just the executable code itself.
|
12
|
+
|
13
|
+
Information passes from Sup to the hook code via Ruby variables
|
14
|
+
(actually method calls), and from the hook code back to Sup via a
|
15
|
+
return value. The values of variables persists across calls to the
|
16
|
+
same hook, but is NOT available to other hooks. To make the value of a
|
17
|
+
variable available to other hooks, use the get and set methods. Each
|
18
|
+
hook description lists the variables and return value expected, if
|
19
|
+
any.
|
20
|
+
|
21
|
+
The following special functions are available to hooks:
|
22
|
+
* say msg
|
23
|
+
Displays the string msg to the user at the bottom of the screen.
|
24
|
+
* log msg
|
25
|
+
Adds the string msg to the log, which the user can access via the
|
26
|
+
buffer list.
|
27
|
+
* ask_yes_or_no question
|
28
|
+
Prompts the user with the string question for a yes or no
|
29
|
+
response. Returns true if the user answered yes, false otherwise.
|
30
|
+
* get key
|
31
|
+
Gets the cross-hook value associated with key (which is typically a
|
32
|
+
string). If there is no value for a given key, nil is returned.
|
33
|
+
* set key value
|
34
|
+
Sets the cross-hook value associated with key to value. key is
|
35
|
+
typically a string, while value can be whatever type it needs to be,
|
36
|
+
including nil.
|
37
|
+
|
38
|
+
Some example hooks:
|
39
|
+
|
40
|
+
before-poll:
|
41
|
+
## runs fetchmail before polling
|
42
|
+
if (@last_fetchmail_time || Time.now) < Time.now - 60
|
43
|
+
say "Running fetchmail..."
|
44
|
+
system "fetchmail >& /dev/null"
|
45
|
+
say "Done running fetchmail."
|
46
|
+
end
|
47
|
+
@last_fetchmail_time = Time.now
|
48
|
+
|
49
|
+
|
50
|
+
mime-decode:
|
51
|
+
## Please read:
|
52
|
+
https://github.com/sup-heliotrope/sup/wiki/Viewing-Attachments for
|
53
|
+
some security concerns on opening attachments.
|
54
|
+
|
55
|
+
## turn text/html attachments into plain text, unless they are part
|
56
|
+
## of a multipart/alternative pair
|
57
|
+
require 'shellwords'
|
58
|
+
unless sibling_types.member? "text/plain"
|
59
|
+
case content_type
|
60
|
+
when "text/html"
|
61
|
+
`/usr/bin/w3m -dump -T #{content_type} #{Shellwords.escape filename}`
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
startup:
|
66
|
+
## runs a background task
|
67
|
+
@bgtask_pid = fork
|
68
|
+
if @bgtask_pid
|
69
|
+
set 'bgtask_pid' @bgtask_pid
|
70
|
+
Process.detach(@bgtask_pid) # so we don't have to wait on it when we go to kill it
|
71
|
+
else
|
72
|
+
exec "background-task args 2&>1 >> /tmp/logfile"
|
73
|
+
end
|
74
|
+
|
75
|
+
after-poll:
|
76
|
+
## kills the background task after the first poll
|
77
|
+
@bgtask_pid = get 'bgtask_pid'
|
78
|
+
Process.kill("TERM", @bgtask_pid) unless @bgtask_pid == nil
|
79
|
+
set 'bgtask_pid' nil
|
data/doc/Philosophy.txt
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
Should an email client have a philosophy? For many people, email is
|
2
|
+
one of our primary means of communication, and email archives are an
|
3
|
+
integral part of our long-term memory. Something so important ought to
|
4
|
+
warrant a little thought.
|
5
|
+
|
6
|
+
Here's Sup's philosophy.
|
7
|
+
|
8
|
+
Using "traditional" email clients today is increasingly problematic.
|
9
|
+
Anyone who's on a high-traffic mailing list knows this. My ruby-talk
|
10
|
+
folder is 430 megs and Mutt sits there for 60 seconds while it opens
|
11
|
+
it. Keeping up with the all the new traffic is impossible, even with
|
12
|
+
Mutt's excellent threading features, simply because there's so much of
|
13
|
+
it. A single thread can span several pages in the folder index view
|
14
|
+
alone! And Mutt is probably the fastest, most mailing-list aware email
|
15
|
+
client out there. God help me if I try and use Thunderbird.
|
16
|
+
|
17
|
+
The problem with traditional clients like Mutt is that they deal with
|
18
|
+
individual pieces of email. This places a high mental cost on the user
|
19
|
+
for each incoming email, by forcing them to ask: Should I keep this
|
20
|
+
email, or delete it? If I keep it, where should I file it? I've spent
|
21
|
+
the last 10 years of my life laboriously hand-filing every email
|
22
|
+
message I received and feeling a mild sense of panic every time an
|
23
|
+
email was both "from Mom" and "about school". The massive amounts of
|
24
|
+
email that many people receive, and the cheap cost of storage, have
|
25
|
+
made these questions both more costly and less useful to answer.
|
26
|
+
|
27
|
+
Contrast that with using Gmail. As a long-time Mutt user, I was blown
|
28
|
+
away when I first saw someone use Gmail. They treated their email
|
29
|
+
differently from how I ever had. They never filed email and they never
|
30
|
+
deleted it. They relied on an immediate, global, full-text search, and
|
31
|
+
thread-level tagging, to do everything I'd ever done with Mutt, but
|
32
|
+
with a trivial cost to the user at message receipt time.
|
33
|
+
|
34
|
+
From Gmail I learned that making certain operations quantitatively
|
35
|
+
easier (namely, search) resulted in a qualitative improvement in
|
36
|
+
usage. I also learned how thread-centrism was advantageous over
|
37
|
+
message-centrism when message volume was high: most of the time, a
|
38
|
+
message and its context deserve the same treatment. I think it's to
|
39
|
+
the Gmail designers' credit that they started with a somewhat ad-hoc
|
40
|
+
idea (hey, we're really good at search engines, so maybe we can build
|
41
|
+
an email client on top of one) and managed to build something that was
|
42
|
+
actually better than everything else out there. At least, that's how I
|
43
|
+
imagine in happened. Maybe they knew what they were doing from the
|
44
|
+
start.
|
45
|
+
|
46
|
+
Unfortunately, there's a lot to Gmail I can't tolerate (top posting,
|
47
|
+
HTML mail, one-level threads, and ads come to mind, never mind the
|
48
|
+
fact that it's not FOSS). Thus Sup was born.
|
49
|
+
|
50
|
+
Sup is based on the following principles, which I stole directly from
|
51
|
+
Gmail:
|
52
|
+
|
53
|
+
- An immediately accessible and fast search capability over the entire
|
54
|
+
email archive eliminates most of the need for folders, and most of
|
55
|
+
the necessity of deleting email.
|
56
|
+
|
57
|
+
- Labels eliminate what little need for folders search doesn't cover.
|
58
|
+
|
59
|
+
- A thread-centric approach to the UI is much more in line with how
|
60
|
+
people operate than dealing with individual messages is. In the vast
|
61
|
+
majority of cases, a message and its context should be subject to
|
62
|
+
the same treatment.
|
63
|
+
|
64
|
+
Sup is also based on many ideas from mutt and Emacs and vi, having to
|
65
|
+
do with the fantastic productivity of a console- and keyboard-based
|
66
|
+
application, the usefulness of multiple buffers, the necessity of
|
67
|
+
handling multiple email accounts, etc. But those are just details!
|
68
|
+
|
69
|
+
Try it and let me know what you think.
|
data/lib/sup/colormap.rb
CHANGED
@@ -50,6 +50,7 @@ class Colormap
|
|
50
50
|
:quote => { :fg => "yellow", :bg => "default" },
|
51
51
|
:sig => { :fg => "yellow", :bg => "default" },
|
52
52
|
:to_me => { :fg => "green", :bg => "default" },
|
53
|
+
:with_attachment => { :fg => "green", :bg => "default" },
|
53
54
|
:starred => { :fg => "yellow", :bg => "default", :attrs => ["bold"] },
|
54
55
|
:starred_patina => { :fg => "yellow", :bg => "green", :attrs => ["bold"] },
|
55
56
|
:alternate_starred_patina => { :fg => "yellow", :bg => "blue", :attrs => ["bold"] },
|
@@ -190,6 +191,11 @@ class Colormap
|
|
190
191
|
Redwood::load_yaml_obj Redwood::COLOR_FN
|
191
192
|
end
|
192
193
|
|
194
|
+
## Set attachment sybmol to sane default for existing colorschemes
|
195
|
+
if user_colors and user_colors.has_key? :to_me
|
196
|
+
user_colors[:with_attachment] = user_colors[:to_me] unless user_colors.has_key? :with_attachment
|
197
|
+
end
|
198
|
+
|
193
199
|
Colormap::DEFAULT_COLORS.merge(user_colors||{}).each_pair do |k, v|
|
194
200
|
fg = begin
|
195
201
|
Ncurses.const_get "COLOR_#{v[:fg].to_s.upcase}"
|
@@ -236,6 +236,13 @@ EOS
|
|
236
236
|
update
|
237
237
|
end
|
238
238
|
|
239
|
+
def handle_killed_update sender, m
|
240
|
+
t = @ts_mutex.synchronize { @ts.thread_for m }
|
241
|
+
return unless t
|
242
|
+
hide_thread t
|
243
|
+
update
|
244
|
+
end
|
245
|
+
|
239
246
|
def handle_spammed_update sender, m
|
240
247
|
t = @ts_mutex.synchronize { @ts.thread_for m }
|
241
248
|
return unless t
|
@@ -247,6 +254,10 @@ EOS
|
|
247
254
|
add_or_unhide m
|
248
255
|
end
|
249
256
|
|
257
|
+
def handle_unkilled_update sender, m
|
258
|
+
add_or_unhide m
|
259
|
+
end
|
260
|
+
|
250
261
|
def undo
|
251
262
|
UndoManager.undo
|
252
263
|
end
|
@@ -979,7 +990,7 @@ protected
|
|
979
990
|
from +
|
980
991
|
[
|
981
992
|
[:size_widget_color, size_widget_text],
|
982
|
-
[:
|
993
|
+
[:with_attachment_color , t.labels.member?(:attachment) ? "@" : " "],
|
983
994
|
[:to_me_color, directly_participated ? ">" : (participated ? '+' : " ")],
|
984
995
|
] +
|
985
996
|
(t.labels - @hidden_labels).sort_by {|x| x.to_s}.map {
|
@@ -78,11 +78,13 @@ EOS
|
|
78
78
|
|
79
79
|
k.add :archive_and_next, "Archive this thread, kill buffer, and view next", 'a'
|
80
80
|
k.add :delete_and_next, "Delete this thread, kill buffer, and view next", 'd'
|
81
|
+
k.add :kill_and_next, "Kill this thread, kill buffer, and view next", '&'
|
81
82
|
k.add :toggle_wrap, "Toggle wrapping of text", 'w'
|
82
83
|
|
83
84
|
k.add_multi "(a)rchive/(d)elete/mark as (s)pam/mark as u(N)read:", '.' do |kk|
|
84
85
|
kk.add :archive_and_kill, "Archive this thread and kill buffer", 'a'
|
85
86
|
kk.add :delete_and_kill, "Delete this thread and kill buffer", 'd'
|
87
|
+
kk.add :kill_and_kill, "Kill this thread and kill buffer", '&'
|
86
88
|
kk.add :spam_and_kill, "Mark this thread as spam and kill buffer", 's'
|
87
89
|
kk.add :unread_and_kill, "Mark this thread as unread and kill buffer", 'N'
|
88
90
|
kk.add :do_nothing_and_kill, "Just kill this buffer", '.'
|
@@ -91,6 +93,7 @@ EOS
|
|
91
93
|
k.add_multi "(a)rchive/(d)elete/mark as (s)pam/mark as u(N)read/do (n)othing:", ',' do |kk|
|
92
94
|
kk.add :archive_and_next, "Archive this thread, kill buffer, and view next", 'a'
|
93
95
|
kk.add :delete_and_next, "Delete this thread, kill buffer, and view next", 'd'
|
96
|
+
kk.add :kill_and_next, "Kill this thread, kill buffer, and view next", '&'
|
94
97
|
kk.add :spam_and_next, "Mark this thread as spam, kill buffer, and view next", 's'
|
95
98
|
kk.add :unread_and_next, "Mark this thread as unread, kill buffer, and view next", 'N'
|
96
99
|
kk.add :do_nothing_and_next, "Kill buffer, and view next", 'n', ','
|
@@ -99,6 +102,7 @@ EOS
|
|
99
102
|
k.add_multi "(a)rchive/(d)elete/mark as (s)pam/mark as u(N)read/do (n)othing:", ']' do |kk|
|
100
103
|
kk.add :archive_and_prev, "Archive this thread, kill buffer, and view previous", 'a'
|
101
104
|
kk.add :delete_and_prev, "Delete this thread, kill buffer, and view previous", 'd'
|
105
|
+
kk.add :kill_and_prev, "Kill this thread, kill buffer, and view previous", '&'
|
102
106
|
kk.add :spam_and_prev, "Mark this thread as spam, kill buffer, and view previous", 's'
|
103
107
|
kk.add :unread_and_prev, "Mark this thread as unread, kill buffer, and view previous", 'N'
|
104
108
|
kk.add :do_nothing_and_prev, "Kill buffer, and view previous", 'n', ']'
|
@@ -581,18 +585,21 @@ EOS
|
|
581
585
|
def archive_and_kill; archive_and_then :kill end
|
582
586
|
def spam_and_kill; spam_and_then :kill end
|
583
587
|
def delete_and_kill; delete_and_then :kill end
|
588
|
+
def kill_and_kill; kill_and_then :kill end
|
584
589
|
def unread_and_kill; unread_and_then :kill end
|
585
590
|
def do_nothing_and_kill; do_nothing_and_then :kill end
|
586
591
|
|
587
592
|
def archive_and_next; archive_and_then :next end
|
588
593
|
def spam_and_next; spam_and_then :next end
|
589
594
|
def delete_and_next; delete_and_then :next end
|
595
|
+
def kill_and_next; kill_and_then :next end
|
590
596
|
def unread_and_next; unread_and_then :next end
|
591
597
|
def do_nothing_and_next; do_nothing_and_then :next end
|
592
598
|
|
593
599
|
def archive_and_prev; archive_and_then :prev end
|
594
600
|
def spam_and_prev; spam_and_then :prev end
|
595
601
|
def delete_and_prev; delete_and_then :prev end
|
602
|
+
def kill_and_prev; kill_and_then :prev end
|
596
603
|
def unread_and_prev; unread_and_then :prev end
|
597
604
|
def do_nothing_and_prev; do_nothing_and_then :prev end
|
598
605
|
|
@@ -635,6 +642,19 @@ EOS
|
|
635
642
|
end
|
636
643
|
end
|
637
644
|
|
645
|
+
def kill_and_then op
|
646
|
+
dispatch op do
|
647
|
+
@thread.apply_label :killed
|
648
|
+
UpdateManager.relay self, :killed, @thread.first
|
649
|
+
Index.save_thread @thread
|
650
|
+
UndoManager.register "killed 1 thread" do
|
651
|
+
@thread.remove_label :killed
|
652
|
+
Index.save_thread @thread
|
653
|
+
UpdateManager.relay self, :unkilled, @thread.first
|
654
|
+
end
|
655
|
+
end
|
656
|
+
end
|
657
|
+
|
638
658
|
def unread_and_then op
|
639
659
|
dispatch op do
|
640
660
|
@thread.apply_label :unread
|
data/lib/sup/version.rb
CHANGED
data/sup.gemspec
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
$:.push File.expand_path("../lib", __FILE__)
|
2
|
+
|
3
|
+
require 'sup/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "sup"
|
7
|
+
s.version = ENV["REL"] || (::Redwood::VERSION == "git" ? "999" : ::Redwood::VERSION)
|
8
|
+
s.date = Time.now.strftime "%Y-%m-%d"
|
9
|
+
s.authors = ["William Morgan", "Gaute Hope", "Hamish Downer", "Matthieu Rakotojaona"]
|
10
|
+
s.email = "sup-talk@rubyforge.org"
|
11
|
+
s.summary = "A console-based email client with the best features of GMail, mutt and Emacs"
|
12
|
+
s.homepage = "http://supmua.org"
|
13
|
+
s.license = 'GPL-2'
|
14
|
+
s.description = <<-DESC
|
15
|
+
Sup is a console-based email client for people with a lot of email.
|
16
|
+
|
17
|
+
* GMail-like thread-centered archiving, tagging and muting
|
18
|
+
* Handling mail from multiple mbox and Maildir sources
|
19
|
+
* Blazing fast full-text search with a rich query language
|
20
|
+
* Multiple accounts - pick the right one when sending mail
|
21
|
+
* Ruby-programmable hooks
|
22
|
+
* Automatically tracking recent contacts
|
23
|
+
DESC
|
24
|
+
s.post_install_message = <<-EOF
|
25
|
+
SUP: If you are upgrading Sup from before version 0.14.0: Please
|
26
|
+
run `sup-psych-ify-config-files` to migrate from 0.13.
|
27
|
+
|
28
|
+
Check https://github.com/sup-heliotrope/sup/wiki/Migration-0.13-to-0.14
|
29
|
+
for more detailed and up-to-date instructions.
|
30
|
+
EOF
|
31
|
+
|
32
|
+
s.files = `git ls-files -z`.split("\x0")
|
33
|
+
s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
34
|
+
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
35
|
+
s.require_paths = ["lib"]
|
36
|
+
|
37
|
+
s.required_ruby_version = '>= 1.9.3'
|
38
|
+
|
39
|
+
s.add_runtime_dependency "xapian-ruby", "~> 1.2.15"
|
40
|
+
s.add_runtime_dependency "ncursesw", "~> 1.4.0"
|
41
|
+
s.add_runtime_dependency "rmail-sup", "~> 1.0.1"
|
42
|
+
s.add_runtime_dependency "highline"
|
43
|
+
s.add_runtime_dependency "trollop", ">= 1.12"
|
44
|
+
s.add_runtime_dependency "lockfile"
|
45
|
+
s.add_runtime_dependency "mime-types", "~> 1.0"
|
46
|
+
s.add_runtime_dependency "locale", "~> 2.0"
|
47
|
+
s.add_runtime_dependency "chronic", "~> 0.9.1"
|
48
|
+
s.add_runtime_dependency "unicode", "~> 0.4.4"
|
49
|
+
|
50
|
+
s.add_development_dependency "bundler", "~> 1.3"
|
51
|
+
s.add_development_dependency "rake"
|
52
|
+
s.add_development_dependency "minitest", "~> 4.7"
|
53
|
+
s.add_development_dependency "rr", "~> 1.0.5"
|
54
|
+
s.add_development_dependency "gpgme", ">= 2.0.2"
|
55
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
require 'sup'
|
4
|
+
require 'stringio'
|
5
|
+
require 'rmail'
|
6
|
+
require 'uri'
|
7
|
+
|
8
|
+
module Redwood
|
9
|
+
|
10
|
+
class DummySource < Source
|
11
|
+
|
12
|
+
attr_accessor :messages
|
13
|
+
|
14
|
+
def initialize uri, last_date=nil, usual=true, archived=false, id=nil, labels=[]
|
15
|
+
super uri, usual, archived, id
|
16
|
+
@messages = nil
|
17
|
+
end
|
18
|
+
|
19
|
+
def start_offset
|
20
|
+
0
|
21
|
+
end
|
22
|
+
|
23
|
+
def end_offset
|
24
|
+
# should contain the number of test messages -1
|
25
|
+
return @messages ? @messages.length - 1 : 0
|
26
|
+
end
|
27
|
+
|
28
|
+
def load_header offset
|
29
|
+
Source.parse_raw_email_header StringIO.new(raw_header(offset))
|
30
|
+
end
|
31
|
+
|
32
|
+
def load_message offset
|
33
|
+
RMail::Parser.read raw_message(offset)
|
34
|
+
end
|
35
|
+
|
36
|
+
def raw_header offset
|
37
|
+
ret = ""
|
38
|
+
f = StringIO.new(@messages[offset])
|
39
|
+
until f.eof? || (l = f.gets) =~ /^$/
|
40
|
+
ret += l
|
41
|
+
end
|
42
|
+
ret
|
43
|
+
end
|
44
|
+
|
45
|
+
def raw_message offset
|
46
|
+
@messages[offset]
|
47
|
+
end
|
48
|
+
|
49
|
+
def each_raw_message_line offset
|
50
|
+
ret = ""
|
51
|
+
f = StringIO.new(@messages[offset])
|
52
|
+
until f.eof?
|
53
|
+
yield f.gets
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
# vim:noai:ts=2:sw=2:
|
61
|
+
|
@@ -0,0 +1 @@
|
|
1
|
+
default-key 789E7011
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,20 @@
|
|
1
|
+
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
2
|
+
Version: GnuPG v2.0.20 (GNU/Linux)
|
3
|
+
|
4
|
+
mI0EUgi0fAEEAOLAcQW96NEUSB7YE/la8X56jGW5BMX3aAixOF8LvOwMBbUK1T+U
|
5
|
+
0H2PGIrXVcYyHcPqWRpRahbsIAldBqzffPlzMa+aqJaB1xKkNruxSoIzwPdidZMe
|
6
|
+
l0Dxz2FDsoXD0KPyWnAYhGmQyz2MFpZxu2tlYqvwWVW//XGnk/KHvIXbABEBAAG0
|
7
|
+
PlN1cCBUZXN0IFJlY2VpdmVyIChUZXN0IHJlY2VpdmVyIGZvciBTdXApIDxzdXAt
|
8
|
+
dGVzdC0yQGZvby5iYXI+iL8EEwECACkFAlIItHwCGwMFCQHhM4AHCwkIBwMCAQYV
|
9
|
+
CAIJCgsEFgIDAQIeAQIXgAAKCRAsABl+cWpykMMVBADHkQPgTz0CqKKp3k+z3dbm
|
10
|
+
ocmI4tYNn1dOkDQqyfoBTfs6L3g4j5OE2UrguntRYyg5oon+uO5d18CQ5dY0sCw/
|
11
|
+
o5IwyzTrxI8IocbtZvBdSb+XjLndynGuIQoqaJq9i6n1V4klFHVOna8Q9JstLfRX
|
12
|
+
H1d4xPhnvKcaDDx/NV3X/biNBFIItHwBBADBpb43MpkrUWlg7HWJ1ZfOlxnOxrJ3
|
13
|
+
Gz9WFNV06UbcZEuFKA/vHRjM6gWzUn5903FLuCWu3eBrq5xQfWipbp187PmocpoG
|
14
|
+
skJ6gosLs1fMYRBjv2VbG9xJVKdKJMjqZw5FUpXKAaHr8P9jN6g2STQrbeQ8CVUK
|
15
|
+
h7zOWRXAXSKUgwARAQABiKUEGAECAA8FAlIItHwCGwwFCQHhM4AACgkQLAAZfnFq
|
16
|
+
cpDV1QQAzcxFXznEX92DjWxWRC7gRHgIsQk9WJnDzjtnDjSWCp3H85qeTZGZrn9W
|
17
|
+
NoneV/S5Y7K3Mkceh4rFaANQ3zx4b05y1LFt5N/lPwIe5VB0vcPumtZum2fSGfpK
|
18
|
+
nTXvzelcWcm2aGyUSaWvOkntWKEEt1kB5Oq6EtZoRZLMzAxLd7s=
|
19
|
+
=aKsV
|
20
|
+
-----END PGP PUBLIC KEY BLOCK-----
|
Binary file
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
require "sup/service/label_service"
|
4
|
+
|
5
|
+
require "tmpdir"
|
6
|
+
|
7
|
+
describe Redwood::LabelService do
|
8
|
+
let(:tmpdir) { Dir.mktmpdir }
|
9
|
+
after do
|
10
|
+
require "fileutils"
|
11
|
+
FileUtils.remove_entry_secure @tmpdir unless @tmpdir.nil?
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "#add_labels" do
|
15
|
+
# Integration tests are hard to write at this moment :(
|
16
|
+
it "add labels to all messages matching the query"
|
17
|
+
end
|
18
|
+
end
|