[DRE-commits] [sup-mail] 03/26: Imported Upstream version 0.14.0
Per Andersson
avtobiff at moszumanska.debian.org
Wed Oct 1 19:06:06 UTC 2014
This is an automated email from the git hooks/post-receive script.
avtobiff pushed a commit to branch next-0.14.1.1
in repository sup-mail.
commit 6ce2f5d5e169ca384e7938195bfac1f7a614f276
Author: Per Andersson <avtobiff at gmail.com>
Date: Thu Aug 22 22:19:11 2013 +0200
Imported Upstream version 0.14.0
---
.ditz-plugins | 1 -
.gitignore | 7 -
CONTRIBUTORS | 50 ++--
Gemfile | 3 +
History.txt | 24 ++
README.md | 70 ++++++
README.txt | 128 ----------
Rakefile | 71 ++----
ReleaseNotes | 33 +++
bin/sup | 49 ++--
bin/sup-add | 4 +-
bin/sup-cmd | 138 -----------
bin/sup-config | 20 +-
bin/sup-dump | 2 +
bin/sup-import-dump | 4 +-
bin/sup-psych-ify-config-files | 16 ++
bin/sup-recover-sources | 2 +
bin/sup-server | 44 ----
bin/sup-sync | 4 +-
bin/sup-sync-back | 4 +-
bin/sup-tweak-labels | 4 +-
...e-0240b36671ecb019e57ef27e0901bff055385371.yaml | 22 --
...e-08d6bae05fa885bf6fcae39f864eb923c1e9a79e.yaml | 27 ---
...e-09479a2ada22c2a0d76427e12ef2514d4753d070.yaml | 18 --
...e-15738247f939d20f8f202f80ccb85d9ad92101e0.yaml | 18 --
...e-182841e15d6909892adf43678bae03597ce10519.yaml | 25 --
...e-1a1527438c2d198eae9a264ce9e6b847854d9837.yaml | 30 ---
...e-2312263b6a2b7de6ae1ec4ab315c7829763e61be.yaml | 22 --
...e-23658477a445c2e61405fecb4cb641a2298caba6.yaml | 27 ---
...e-2673f091c15dd90222a59621a1842d4ef0a743f7.yaml | 19 --
...e-2a0363cdf9d25edfa2a04b21299a538365e8b319.yaml | 30 ---
...e-2e74aa6843feee4daefe740b6e3f1fc54ff4bfcb.yaml | 22 --
...e-314f0cdac8d1998c46759a4ebef9077999bcef09.yaml | 18 --
...e-3408c200a5f47f92d12b5c063a00ce891c2ba4ce.yaml | 22 --
...e-3441fb8b7f955d625633d06fa0bf67a9afab046e.yaml | 18 --
...e-38d6f805b0c8bad013ec73f56e6245c890528591.yaml | 29 ---
...e-3b25f1d56b9be533edaf232b9e60dc24e00cba0b.yaml | 26 ---
...e-42ab0840f9a1924f1c0561e8ddcf7e6988543ba0.yaml | 26 ---
...e-46df983ccdb75408a37b3911472d4015664a3cf6.yaml | 20 --
...e-47aab6443b6c107c3067cdb614186099db570acf.yaml | 37 ---
...e-4af242013994ae557e431ba350a92c4f9e1739ef.yaml | 28 ---
...e-4daa2721dac8dfeb8730ee081f73b6c62702bd3e.yaml | 23 --
...e-4e501973cea5bd1f28739ae4cea98edce8249895.yaml | 32 ---
...e-5348fec2b1112250e241afc7467de29e5691d1be.yaml | 21 --
...e-57668c69d0190d6e849309834d4ad1d215efa779.yaml | 21 --
...e-5795c3c1b47e88f7261f57f31d33fe15ad08465d.yaml | 20 --
...e-5fab957dcd16f1da8962fe5b1f3a58d970315deb.yaml | 24 --
...e-60d86dd32054533a6206f698033ec668af6a7574.yaml | 29 ---
...e-61949ec83770b5d46f89eff21799968187012cce.yaml | 22 --
...e-65506670167642cc581956bc1b25c26b5bff215b.yaml | 30 ---
...e-658389418b5f0038cc3e6bc20fd3fd1566eb7111.yaml | 26 ---
...e-69f785cddcc6e09ef0a357151373b3aa923d5e3f.yaml | 22 --
...e-6c053cca2eb05af486a2d09c6772fd5bd0cca444.yaml | 20 --
...e-6e0d634de74b2eb8297174ecd408b3810ba9351b.yaml | 24 --
...e-6e7960514f66ee67da083bc7bb5632d5808fc607.yaml | 30 ---
...e-7456c2d8fbd5de4dac651f6f4e9756f577497e01.yaml | 26 ---
...e-76802330c4fdd091e8b1dd08dcc29ed432f003d4.yaml | 26 ---
...e-799771a6a435dcad66dc80e7e051d91d24d005b1.yaml | 31 ---
...e-7a68c1e7120a8540c7c51c6095f4815918d16641.yaml | 28 ---
...e-7c77e757321c2639daea013824ad1a14099815b1.yaml | 26 ---
...e-7d8474dfeeefaa50151c3ce48bee6b686d36a216.yaml | 29 ---
...e-829b449c51fca9a39047d00fabc552cc110c69b2.yaml | 24 --
...e-82c80f6dc2ce7b10b9e8f503d68253ced0ee8a1b.yaml | 24 --
...e-8a5cf9242ca60fa6c81091e425f734b4fb03e41a.yaml | 53 -----
...e-8aa7ea95f066fd0668452093b85903bd142905c9.yaml | 26 ---
...e-8c0e627c500f679badca28f60ba76998fd65d46a.yaml | 26 ---
...e-8e825caee33a6ac144580bf44d0d3060ad162394.yaml | 21 --
...e-91e1549102c0bfa2c201476d9618f7d234d1a626.yaml | 22 --
...e-9f7e28de46d74f7f1e445ae75ea4e230c7473374.yaml | 22 --
...e-a1a3427de5e8d4f74c0620f99e97ed92d21e924c.yaml | 30 ---
...e-a1e622dbae0e1841b4d9a376d419aed1d91460e0.yaml | 26 ---
...e-a533480a30a18c3e823dbe20b759e1dcb32ca2b9.yaml | 26 ---
...e-a68148169baa3838051f4bdb4c175e11cbf7f143.yaml | 22 --
...e-aae5ae6378afa9bd2a8e1b15d28ba7ccef867791.yaml | 27 ---
...e-ad82aa00f4064fc7e1332cee0dae2c2ae95bb217.yaml | 26 ---
...e-b1f1579fd8350d8add15c5cb588169acfdc5ea24.yaml | 29 ---
...e-b80aa39ef3b8d33bd57e4988c55d89c7c0df5c96.yaml | 24 --
...e-bc03bc702f41e6a9687b52d3e32db29132c0f65a.yaml | 25 --
...e-bdd4415a9d4c8fd3602500111bf9268aa7c7c6a4.yaml | 27 ---
...e-bff2527210b3aacae2f74029e5856fed82f1689c.yaml | 33 ---
...e-c48f7fc58bba0b38ff6ae14cca01b08a5a7a6c33.yaml | 21 --
...e-c52f9762bc24a8f45863eb2e7beefa4201db34e8.yaml | 22 --
...e-c660ddfa9d633501140dd199bdfd7cd9fed5df0b.yaml | 22 --
...e-cef3096582de268c050f78223eb6a22ac2599606.yaml | 31 ---
...e-cf09ec6ec7c35d7d8c002b0521f97b6e94dc9b3e.yaml | 26 ---
...e-cfbfc65dc90280fa5ecc63094af01d2a47ff0c6e.yaml | 22 --
...e-d131464e921aefc35571c119aac4d9f1decdebae.yaml | 30 ---
...e-d994a360c9cb2a6e12a734962a39ffbc6486a725.yaml | 34 ---
...e-d9e6be1b524c6c0a5c31c9c468bda170c2a8cb58.yaml | 33 ---
...e-e24df153080c6e7a16335018b04d70d9381258b8.yaml | 20 --
...e-e43b18777ea3aef3566bd80acd126e9ef8a5883a.yaml | 34 ---
...e-e7739718b4dbf49bbd3dd47133affbf7cb1e2361.yaml | 24 --
...e-e9c2f66a7ff4fb4525c2719e77ac8eedf3835dfd.yaml | 20 --
...e-f767a9d2071da7b0f66698ce74e642bf347be96b.yaml | 21 --
...e-fd7c7a7d7caf41ff20e7d10ca3f074fc02c14a5b.yaml | 30 ---
...e-fdfc906e8f4f6eb10f1ebdf39c416415d9ab6af9.yaml | 26 ---
bugs/project.yaml | 53 -----
contrib/colorpicker.rb | 6 +-
doc/FAQ.txt | 4 +-
doc/NewUserGuide.txt | 258 ---------------------
lib/sup.rb | 146 ++++++------
lib/sup/account.rb | 3 +-
lib/sup/buffer.rb | 36 ++-
lib/sup/client.rb | 92 --------
lib/sup/colormap.rb | 1 +
lib/sup/contact.rb | 9 +-
lib/sup/crypto.rb | 76 ++++--
lib/sup/draft.rb | 7 +-
lib/sup/hook.rb | 10 +
...rizontal-selector.rb => horizontal_selector.rb} | 11 +-
lib/sup/index.rb | 146 +++++++-----
.../{interactive-lock.rb => interactive_lock.rb} | 0
lib/sup/label.rb | 4 +-
lib/sup/logger.rb | 2 +-
lib/sup/logger/singleton.rb | 10 +
lib/sup/message.rb | 20 +-
lib/sup/{message-chunks.rb => message_chunks.rb} | 9 +-
.../{buffer-list-mode.rb => buffer_list_mode.rb} | 0
.../{completion-mode.rb => completion_mode.rb} | 6 +-
lib/sup/modes/{compose-mode.rb => compose_mode.rb} | 2 +
lib/sup/modes/{console-mode.rb => console_mode.rb} | 17 +-
.../{contact-list-mode.rb => contact_list_mode.rb} | 0
...ge-async-mode.rb => edit_message_async_mode.rb} | 0
.../{edit-message-mode.rb => edit_message_mode.rb} | 77 ++++--
.../{file-browser-mode.rb => file_browser_mode.rb} | 0
lib/sup/modes/{forward-mode.rb => forward_mode.rb} | 0
lib/sup/modes/{help-mode.rb => help_mode.rb} | 0
lib/sup/modes/{inbox-mode.rb => inbox_mode.rb} | 2 +-
.../{label-list-mode.rb => label_list_mode.rb} | 0
...esults-mode.rb => label_search_results_mode.rb} | 0
.../{line-cursor-mode.rb => line_cursor_mode.rb} | 4 +-
lib/sup/modes/{log-mode.rb => log_mode.rb} | 0
...sults-mode.rb => person_search_results_mode.rb} | 0
lib/sup/modes/{poll-mode.rb => poll_mode.rb} | 0
lib/sup/modes/{reply-mode.rb => reply_mode.rb} | 60 ++---
lib/sup/modes/{resume-mode.rb => resume_mode.rb} | 0
lib/sup/modes/{scroll-mode.rb => scroll_mode.rb} | 8 +-
.../{search-list-mode.rb => search_list_mode.rb} | 0
...arch-results-mode.rb => search_results_mode.rb} | 0
lib/sup/modes/{text-mode.rb => text_mode.rb} | 0
.../{thread-index-mode.rb => thread_index_mode.rb} | 20 +-
.../{thread-view-mode.rb => thread_view_mode.rb} | 6 +-
lib/sup/poll.rb | 137 ++++++-----
lib/sup/protocol.rb | 161 -------------
lib/sup/rfc2047.rb | 4 +-
lib/sup/sent.rb | 9 +-
lib/sup/server.rb | 116 ---------
lib/sup/service/label_service.rb | 45 ++++
lib/sup/source.rb | 38 ++-
lib/sup/textfield.rb | 10 +
lib/sup/util.rb | 127 ++++++----
lib/sup/util/path.rb | 9 +
lib/sup/util/query.rb | 14 ++
lib/sup/util/uri.rb | 15 ++
lib/sup/version.rb | 3 +
protocol.md | 168 --------------
release-script.txt | 17 --
sup-files.rb | 11 -
sup-version.rb | 15 --
sup.gemspec | 66 ++++++
test/dummy_source.rb | 2 +-
test/gnupg_test_home/gpg.conf | 1 +
test/gnupg_test_home/pubring.gpg | Bin 0 -> 1945 bytes
test/gnupg_test_home/receiver_pubring.gpg | Bin 0 -> 718 bytes
test/gnupg_test_home/receiver_secring.gpg | Bin 0 -> 1382 bytes
test/gnupg_test_home/receiver_trustdb.gpg | Bin 0 -> 1280 bytes
test/gnupg_test_home/secring.gpg | Bin 0 -> 2529 bytes
test/gnupg_test_home/sup-test-2 at foo.bar.asc | 20 ++
test/gnupg_test_home/trustdb.gpg | Bin 0 -> 1360 bytes
test/integration/test_label_service.rb | 18 ++
test/test_crypto.rb | 109 +++++++++
test/test_header_parsing.rb | 35 ++-
test/test_helper.rb | 7 +
test/test_message.rb | 36 ++-
test/test_server.rb | 106 ---------
test/test_yaml_migration.rb | 80 +++++++
test/test_yaml_regressions.rb | 17 ++
test/unit/service/test_label_service.rb | 19 ++
test/unit/test_horizontal_selector.rb | 40 ++++
test/unit/util/test_query.rb | 37 +++
test/unit/util/test_string.rb | 57 +++++
test/unit/util/test_uri.rb | 19 ++
www/index.html | 224 ------------------
www/main.css | 36 ---
www/ss1.png | Bin 93669 -> 0 bytes
www/ss2.png | Bin 38059 -> 0 bytes
www/ss3.png | Bin 43946 -> 0 bytes
www/ss4.png | Bin 43776 -> 0 bytes
www/ss5.png | Bin 63085 -> 0 bytes
www/ss6.png | Bin 30276 -> 0 bytes
190 files changed, 1486 insertions(+), 4048 deletions(-)
diff --git a/.ditz-plugins b/.ditz-plugins
deleted file mode 100644
index 2756e1e..0000000
--- a/.ditz-plugins
+++ /dev/null
@@ -1 +0,0 @@
-- git
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 0820160..0000000
--- a/.gitignore
+++ /dev/null
@@ -1,7 +0,0 @@
-# i use vi
-*.swp
-.ditz-config
-# i use emacs
-*~
-# i use rake package task
-pkg/
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index 04d346b..9b60058 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -1,54 +1,68 @@
-William Morgan <wmorgan-sup at the masanjin dot nets>
+William Morgan <william at the twitter dot coms>
Rich Lane <rlane at the club.cc.cmu dot edus>
+Gaute Hope <eg at the gaute.vetsj dot coms>
+Whyme Lyu <callme5long at the gmail dot coms>
+Hamish Downer <dmishd at the gmail dot coms>
+Sascha Silbe <sascha-pgp at the silbe dot orgs>
Ismo Puustinen <ismo at the iki dot fis>
Nicolas Pouillard <nicolas.pouillard at the gmail dot coms>
-Eric Sherman <hyperbolist at the gmail dot coms>
Michael Stapelberg <michael at the stapelberg dot des>
+Eric Sherman <hyperbolist at the gmail dot coms>
+Tero Tilus <tero at the tilus dot nets>
Ben Walton <bwalton at the artsci.utoronto dot cas>
Mike Stipicevic <stipim at the rpi dot edus>
+Clint Byrum <clint at the ubuntu dot coms>
Marcus Williams <marcus-sup at the bar-coded dot nets>
Lionel Ott <white.magic at the gmx dot des>
-Tero Tilus <tero at the tilus dot nets>
+Gaudenz Steinlin <gaudenz at the soziologie dot chs>
+Damien Leone <damien.leone at the fensalir dot frs>
Ingmar Vanhassel <ingmar at the exherbo dot orgs>
Mark Alexander <marka at the pobox dot coms>
-Gaute Hope <eg at the gaute.vetsj dot coms>
+Eric Weikl <eric.weikl at the gmx dot nets>
Christopher Warrington <chrisw at the rice dot edus>
W. Trevor King <wking at the drexel dot edus>
-Gaudenz Steinlin <gaudenz at the soziologie dot chs>
Richard Brown <rbrown at the exherbo dot orgs>
+Anthony Martinez <pi+sup at the pihost dot uss>
Marc Hartstein <marc.hartstein at the alum.vassar dot edus>
-Sascha Silbe <sascha-pgp at the silbe dot orgs>
Israel Herraiz <israel.herraiz at the gmail dot coms>
-Anthony Martinez <pi+sup at the pihost dot uss>
-Hamish Downer <dmishd at the gmail dot coms>
Bo Borgerson <gigabo at the gmail dot coms>
-William Erik Baxter <web at the superscript dot coms>
Michael Hamann <michael at the content-space dot des>
+Jonathan Lassoff <jof at the thejof dot coms>
+William Erik Baxter <web at the superscript dot coms>
Grant Hollingworth <grant at the antiflux dot orgs>
+Markus Klinik <markus.klinik at the gmx dot des>
+Ico Doornekamp <ico at the pruts dot nls>
Adeodato Simó <dato at the net.com.org dot ess>
Daniel Schoepe <daniel.schoepe at the googlemail dot coms>
Jason Petsod <jason at the petsod dot orgs>
+Edward Z. Yang <edwardzyang at the thewritingpot dot coms>
+Robin Burchell <viroteck at the viroteck dot nets>
Steve Goldman <sgoldman at the tower-research dot coms>
-Edward Z. Yang <ezyang at the MIT dot EDUs>
+Peter Harkins <ph at the malaprop dot orgs>
Decklin Foster <decklin at the red-bean dot coms>
Cameron Matheson <cam+sup at the cammunism dot orgs>
Carl Worth <cworth at the cworth dot orgs>
-Jeff Balogh <its.jeff.balogh at the gmail dot coms>
+Alex Vandiver <alex at the chmrr dot nets>
Andrew Pimlott <andrew at the pimlott dot nets>
-Alex Vandiver <alexmv at the mit dot edus>
-Peter Harkins <ph at the malaprop dot orgs>
+Jeff Balogh <its.jeff.balogh at the gmail dot coms>
+Matías Aguirre <matiasaguirre at the gmail dot coms>
Kornilios Kourtis <kkourt at the cslab.ece.ntua dot grs>
+Kevin Riggle <kevinr at the free-dissociation dot coms>
Giorgio Lando <patroclo7 at the gmail dot coms>
-Damien Leone <damien.leone at the fensalir dot frs>
Benoît PIERRE <benoit.pierre at the gmail dot coms>
+Matthieu Rakotojaona <matthieu.rakotojaona at the gmail dot coms>
Alvaro Herrera <alvherre at the alvh.no-ip dot orgs>
+Steven Lawrance <stl at the koffein dot nets>
Jonah <Jonah at the GoodCoffee dot cas>
-Adam Lloyd <adam at the alloy-d dot nets>
+ian <itaylor at the uark dot edus>
Todd Eisenberger <teisenbe at the andrew.cmu dot edus>
-ian <ian at the lorf dot orgs>
+Adam Lloyd <adam at the alloy-d dot nets>
+MichaelRevell <mikearevell at the gmail dot coms>
+Per Andersson <avtobiff at the gmail dot coms>
+Gregor Hoffleit <gregor at the sam.mediasupervision dot des>
Steven Walter <swalter at the monarch.(none)>
-ian <itaylor at the uark dot edus>
Jon M. Dugan <jdugan at the es dot nets>
-Gregor Hoffleit <gregor at the sam.mediasupervision dot des>
+Matthias Vallentin <vallentin at the icir dot orgs>
Stefan Lundström <lundst at the snabb.(none)>
+Horacio Sanson <horacio at the skillupjapan.co dot jps>
Kirill Smelkov <kirr at the landau.phys.spbu dot rus>
diff --git a/Gemfile b/Gemfile
new file mode 100644
index 0000000..e088013
--- /dev/null
+++ b/Gemfile
@@ -0,0 +1,3 @@
+source 'https://rubygems.org/'
+
+gemspec
diff --git a/History.txt b/History.txt
index 8bfd5eb..59b5a90 100644
--- a/History.txt
+++ b/History.txt
@@ -1,3 +1,27 @@
+== 0.14.0 / 2013-08-15
+
+* CJK compatability
+* Psych over Syck
+* Ruby 1.8 deprecated
+* Thread safety
+* No more Iconv, but using built in Ruby encodings. Better UTF-8
+ handling.
+* GPGME 2.0 support
+
+== 0.13.2 / 2013-06-26
+
+* FreeBSD 10 comptability
+* More threadsafe polling
+
+== 0.13.1 / 2013-06-21
+
+* Bugfixes
+
+== 0.13.0 / 2013-05-15
+
+* Bugfixes
+* Depend on ncursesw-sup
+
== 0.12.1 / 2011-01-23
* Depend on ncursesw rather than ncurses (Ruby 1.9 compatibility)
* Add sup-import-dump
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..5385a59
--- /dev/null
+++ b/README.md
@@ -0,0 +1,70 @@
+# Sup
+
+A console-based email client with the best features of GMail, mutt and
+Emacs.
+
+## Installation
+
+[See the wiki][Installation]
+
+## Features / Problems
+
+Features:
+
+* GMail-like thread-centered archiving, tagging and muting
+* [Handling mail from multiple mbox and Maildir sources][sources]
+* Blazing fast full-text search with a [rich query language][search]
+* Multiple accounts - pick the right one when sending mail
+* [Ruby-programmable hooks][hooks]
+* Automatically tracking recent contacts
+
+Current limitations which will be fixed:
+
+* [Doesn't run on Ruby 2.0][ruby20]
+
+* Sup doesn't play nicely with other mail clients. Changes in Sup won't be
+ synced back to mail source.
+
+* Unix-centrism in MIME attachment handling and in sendmail invocation.
+
+## Problems
+
+Please report bugs to the [Github issue tracker](https://github.com/sup-heliotrope/sup/issues).
+
+## Links
+
+* [Homepage](http://supmua.org/)
+* [Code repository](https://github.com/sup-heliotrope/sup)
+* [Wiki](https://github.com/sup-heliotrope/sup/wiki)
+* IRC: [#sup @ freenode.net](http://webchat.freenode.net/?channels=#sup)
+* Mailing list: [sup-talk] and [sup-devel]
+
+## License
+
+```
+Copyright (c) 2013 Sup developers.
+Copyright (c) 2006--2009 William Morgan.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.
+```
+
+[sources]: https://github.com/sup-heliotrope/sup/wiki/Adding-sources
+[hooks]: https://github.com/sup-heliotrope/sup/wiki/Hooks
+[search]: https://github.com/sup-heliotrope/sup/wiki/Searching-your-mail
+[Installation]: https://github.com/sup-heliotrope/sup/wiki#installation
+[ruby20]: https://github.com/sup-heliotrope/sup/wiki/Development#sup-014
+[sup-talk]: http://rubyforge.org/mailman/listinfo/sup-talk
+[sup-devel]: http://rubyforge.org/mailman/listinfo/sup-devel
diff --git a/README.txt b/README.txt
deleted file mode 100644
index c2f0768..0000000
--- a/README.txt
+++ /dev/null
@@ -1,128 +0,0 @@
-sup
- by William Morgan <wmorgan-sup at masanjin.net>
- http://sup.rubyforge.org
-
-== 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 and Maildirs.
-
-- 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 customize Sup to whatever particular and bizarre
- needs you may have.
-
-- 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.
-
-== FEATURES/PROBLEMS:
-
-Features:
-
-- Scalability to massive amounts of email. Immediate startup and
- operability, regardless of how much amount of email you have.
-
-- Immediate full-text search of your entire email archive, using the
- Xapian query language. Search over message bodies, labels, from: and
- to: fields, or any combination thereof.
-
-- Thread-centrism. Operations are performed at the thread, not the
- message level. Entire threads are manipulated and viewed (with
- redundancies removed) at a time.
-
-- Labels instead of folders. Drop that tired old metaphor and you'll see
- how much easier it is to organize email.
-
-- GMail-style thread management. Archive a thread, and it will disappear
- from your inbox until someone replies. Kill a thread, and it will
- never come back to your inbox (but will still show up in searches.)
- Mark a thread as spam and you'll never again see it unless explicitly
- searching for spam.
-
-- Console based interface. No mouse clicking required!
-
-- Programmability. It's in Ruby. The code is good. It has an extensive
- hook system that makes it easy to extend and customize.
-
-- Multiple buffer support. Why be limited to viewing one thing at a
- time?
-
-- Tons of other little features, like automatic context-sensitive help,
- multi-message operations, MIME attachment viewing, recent contact list
- generation, etc.
-
-Current limitations which will be fixed:
-
-- Sup doesn't play nicely with other mail clients. If you alter a mail
- source (read, move, delete, etc) with another client Sup will punish
- you with a lengthy reindexing process.
-
-- Unix-centrism in MIME attachment handling and in sendmail invocation.
-
-== SYNOPSYS:
-
- 0. sup-config
- 1. sup
-
- Note that Sup never changes the contents of any mailboxes; it only
- indexes in to them. So it shouldn't ever corrupt your mail. The flip
- side is that if you change a mailbox (e.g. delete messages, or, in the
- case of mbox files, read an unread message) then Sup will be unable to
- load messages from that source and will ask you to run sup-sync
- --changed.
-
-== REQUIREMENTS:
-
- - xapian-full >= 1.1.3.2
- - ncurses >= 0.9.1
- - rmail >= 0.17
- - highline
- - net-ssh
- - trollop >= 1.12
- - lockfile
- - mime-types
- - gettext
- - fastthread
-
-== INSTALL:
-
-* gem install sup
-
-== PROBLEMS:
-
-See FAQ.txt for some common problems and their solutions.
-
-== LICENSE:
-
-Copyright (c) 2006--2009 William Morgan.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA.
-
diff --git a/Rakefile b/Rakefile
index d88fd8d..b830e9f 100644
--- a/Rakefile
+++ b/Rakefile
@@ -1,64 +1,19 @@
-## is there really no way to make a rule for this?
-WWW_FILES = %w(www/index.html README.txt doc/Philosophy.txt doc/FAQ.txt doc/NewUserGuide.txt www/main.css)
-
-rule 'ss?.png' => 'ss?-small.png' do |t|
-end
-SCREENSHOTS = FileList["www/ss?.png"]
-SCREENSHOTS_SMALL = []
-SCREENSHOTS.each do |fn|
- fn =~ /ss(\d+)\.png/
- sfn = "www/ss#{$1}-small.png"
- file sfn => [fn] do |t|
- sh "cat #{fn} | pngtopnm | pnmscale -xysize 320 240 | pnmtopng > #{sfn}"
- end
- SCREENSHOTS_SMALL << sfn
-end
-
-task :upload_webpage => WWW_FILES do |t|
- sh "rsync -essh -cavz #{t.prerequisites * ' '} wmorgan at rubyforge.org:/var/www/gforge-projects/sup/"
-end
-
-task :upload_webpage_images => (SCREENSHOTS + SCREENSHOTS_SMALL) do |t|
- sh "rsync -essh -cavz #{t.prerequisites * ' '} wmorgan at rubyforge.org:/var/www/gforge-projects/sup/"
-end
-
-# vim: syntax=ruby
-# -*- ruby -*-
-task :upload_report do |t|
- sh "ditz html ditz"
- sh "rsync -essh -cavz ditz wmorgan at rubyforge.org:/var/www/gforge-projects/sup/"
-end
-
-$:.push "lib"
require 'rubygems'
-require "sup-files"
-require "sup-version"
-require 'rake/gempackagetask.rb'
-
-spec = Gem::Specification.new do |s|
- s.name = %q{sup}
- s.version = SUP_VERSION
- s.date = Time.now.to_s
- s.authors = ["William Morgan"]
- s.email = %q{wmorgan-sup at masanjin.net}
- s.summary = %q{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.}
- s.homepage = %q{http://sup.rubyforge.org/}
- s.description = %q{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. - Instant [...]
- s.files = SUP_FILES
- s.executables = SUP_EXECUTABLES
+require 'rake/testtask'
- s.add_dependency "xapian-full", ">= 1.2.1"
- s.add_dependency "ncursesw"
- s.add_dependency "rmail", ">= 0.17"
- s.add_dependency "highline"
- s.add_dependency "trollop", ">= 1.12"
- s.add_dependency "lockfile"
- s.add_dependency "mime-types", "~> 1"
- s.add_dependency "gettext"
+Rake::TestTask.new(:test) do |test|
+ test.libs << 'test'
+ test.test_files = FileList.new('test/**/test_*.rb')
+ test.verbose = true
end
+task :default => :test
+
+require 'rubygems/package_task'
+# For those who don't have `rubygems-bundler` installed
+load 'sup.gemspec' unless defined? Redwood::Gemspec
-Rake::GemPackageTask.new(spec) do |pkg|
- pkg.need_tar = true
+Gem::PackageTask.new(Redwood::Gemspec) do |pkg|
+ pkg.need_tar = true
end
-task :tarball => ["pkg/sup-#{SUP_VERSION}.tgz"]
+task :travis => [:test, :gem]
diff --git a/ReleaseNotes b/ReleaseNotes
index 69b9286..736dad2 100644
--- a/ReleaseNotes
+++ b/ReleaseNotes
@@ -1,3 +1,36 @@
+Release 0.14.0:
+
+CJK-compatability, Psych usage, thread safety, GPGME 2.0 support. Sup is now
+Ruby 1.9 based, and apart from RMail - ready for Ruby 2.0.0.
+
+Sup now uses Psych as a YAML parser (default by Ruby) and your previous
+configuration files (~/.sup/*.yaml) may need to be migrated or re-created for
+them to work with the new sup. A migration script is included for this.
+
+Check https://github.com/sup-heliotrope/sup/wiki/Migration-0.13-to-0.14 for
+the latest instructions.
+
+First back up your ~/.sup directory and index, after installing the new sup
+run:
+
+$ sup-psych-ify-config-files
+
+to migrate your files. You should now be all set for buisness.
+
+
+Release 0.13.2:
+
+FreeBSD compatability and more thread safe polling.
+
+Release 0.13.1:
+
+Another ruby 1.8 compatible release, various fixes.
+
+Release 0.13.0:
+
+Collection of bugfixes and stability fixes since 0.12.1. We now depend on our
+own ncursesw-sup fork.
+
Release 0.12.1:
This release changes the gem dependency on ncurses to ncursesw, which
diff --git a/bin/sup b/bin/sup
index ad7a0d1..ca1071a 100755
--- a/bin/sup
+++ b/bin/sup
@@ -1,14 +1,11 @@
#!/usr/bin/env ruby
+# encoding: utf-8
+
+$:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
require 'rubygems'
-no_ncursesw = false
-begin
- require 'ncursesw'
-rescue LoadError
- require 'ncurses'
- no_ncursesw = true
-end
+require 'ncursesw'
no_gpgme = false
begin
@@ -19,17 +16,13 @@ end
require 'fileutils'
require 'trollop'
-require "sup"; Redwood::check_library_version_against "git"
+require "sup"
if ENV['SUP_PROFILE']
require 'ruby-prof'
RubyProf.start
end
-if no_ncursesw
- info "No 'ncursesw' gem detected. Install it for wide character support."
-end
-
if no_gpgme
info "No 'gpgme' gem detected. Install it for email encryption, decryption and signatures."
end
@@ -112,14 +105,14 @@ end
## ncurses.so that's been compiled against libncursesw. (note the w.) why
## this works, i have no idea. much like pretty much every aspect of
## dealing with curses. cargo cult programming at its best.
-##
-## BSD users: if libc.so.6 is not found, try installing compat6x.
require 'dl/import'
+require 'rbconfig'
module LibC
extend DL.const_defined?(:Importer) ? DL::Importer : DL::Importable
- setlocale_lib = case Config::CONFIG['arch']
+ setlocale_lib = case RbConfig::CONFIG['arch']
when /darwin/; "libc.dylib"
when /cygwin/; "cygwin1.dll"
+ when /freebsd/; "libc.so.7"
else; "libc.so.6"
end
@@ -132,9 +125,6 @@ module LibC
rescue RuntimeError => e
warn "cannot dlload setlocale(); ncurses wide character support probably broken."
warn "dlload error was #{e.class}: #{e.message}"
- if Config::CONFIG['arch'] =~ /bsd/
- warn "BSD variant detected. You may have to install a compat6x package to acquire libc."
- end
end
end
@@ -167,7 +157,11 @@ begin
$die = false
trap("TERM") { |x| $die = true }
- trap("WINCH") { |x| BufferManager.sigwinch_happened! }
+ trap("WINCH") do |x|
+ ::Thread.new do
+ BufferManager.sigwinch_happened!
+ end
+ end
if(s = Redwood::SourceManager.source_for DraftManager.source_name)
DraftManager.source = s
@@ -298,7 +292,10 @@ begin
b, new = bm.spawn_unless_exists("Contact List") { ContactListMode.new }
b.mode.load_in_background if new
when :search
- query = BufferManager.ask :search, "Search all messages (enter for saved searches): "
+ completions = LabelManager.all_labels.map { |l| "label:#{LabelManager.string_for l}" }
+ completions = completions.each { |l| l.fix_encoding }
+ completions += Index::COMPL_PREFIXES
+ query = BufferManager.ask_many_with_completions :search, "Search all messages (enter for saved searches): ", completions
unless query.nil?
if query.empty?
bm.spawn_unless_exists("Saved searches") { SearchListMode.new }
@@ -310,7 +307,7 @@ begin
SearchResultsMode.spawn_from_query "is:unread"
when :list_labels
labels = LabelManager.all_labels.map { |l| LabelManager.string_for l }
- labels = labels.each { |l| l.force_encoding 'UTF-8' if l.methods.include?(:encoding) }
+ labels = labels.each { |l| l.fix_encoding }
user_label = bm.ask_with_completions :label, "Show threads with label (enter for listing): ", labels
unless user_label.nil?
@@ -415,14 +412,14 @@ unless Redwood::exceptions.empty?
end
$stderr.puts <<EOS
----------------------------------------------------------------
-I'm very sorry. It seems that an error occurred in Sup. Please
-accept my sincere apologies. Please submit the contents of
+We are very sorry. It seems that an error occurred in Sup. Please
+accept our sincere apologies. Please submit the contents of
#{BASE_DIR}/exception-log.txt and a brief report of the
-circumstances to http://masanjin.net/sup-bugs/ so that I might
-address this problem. Thank you!
+circumstances to https://github.com/sup-heliotrope/sup/issues so that
+we might address this problem. Thank you!
Sincerely,
-William
+The Sup Developers
----------------------------------------------------------------
EOS
Redwood::exceptions.each do |e, name|
diff --git a/bin/sup-add b/bin/sup-add
index c77720f..eae893f 100755
--- a/bin/sup-add
+++ b/bin/sup-add
@@ -1,10 +1,12 @@
#!/usr/bin/env ruby
+$:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
+
require 'uri'
require 'rubygems'
require 'highline/import'
require 'trollop'
-require "sup"; Redwood::check_library_version_against "git"
+require "sup"
$opts = Trollop::options do
version "sup-add (sup #{Redwood::VERSION})"
diff --git a/bin/sup-cmd b/bin/sup-cmd
deleted file mode 100755
index 8ec5c69..0000000
--- a/bin/sup-cmd
+++ /dev/null
@@ -1,138 +0,0 @@
-#!/usr/bin/env ruby
-require 'rubygems'
-require 'trollop'
-require 'sup'
-require 'sup/client'
-require 'pp'
-require 'yaml'
-include Redwood
-
-SUB_COMMANDS = %w(query count label add)
-global_opts = Trollop::options do
- #version = "sup-cmd (sup #{Redwood::VERSION})"
- banner <<EOS
-Connect to a running sup-server.
-
-Usage:
- sup-cmd [global options] command [options]
-
- Valid commands: #{SUB_COMMANDS * ', '}
-
- Global options:
-EOS
-
- opt :host, "server address", :type => :string, :default => 'localhost', :short => 'o'
- opt :port, "server port", :type => :int, :default => 4300
- opt :socket, "unix domain socket path", :type => :string, :default => nil
- opt :verbose
-
- conflicts :host, :socket
- conflicts :port, :socket
-
- stop_on SUB_COMMANDS
-end
-
-cmd = ARGV.shift
-cmd_opts = case cmd
-when "query"
- Trollop.options do
- opt :offset, "Offset", :default => 0, :type => :int
- opt :limit, "Limit", :type => :int
- opt :raw, "Retrieve raw message text", :default => false
- end
-when "count"
- Trollop.options do
- end
-when "label"
- Trollop.options do
- opt :add_labels, "Labels to add", :default => ""
- opt :remove_labels, "Labels to remove", :default => ""
- end
-when "add"
- Trollop.options do
- opt :labels, "Labels separated by commas", :default => ""
- opt :mbox, "Treat input files as mboxes", :default => false
- end
-else
- Trollop::die "unrecognized command #{cmd.inspect}"
-end
-
-class SupCmd < Redwood::Client
- def initialize cmd, args, opts
- @cmd = cmd
- @opts = opts
- @args = args
- super()
- end
-
- def get_query
- @args.first or fail "query argument required"
- end
-
- def connection_established
- case @cmd
- when "query"
- query get_query, @opts[:offset], @opts[:limit], @opts[:raw] do |result|
- if result
- puts YAML.dump(result['summary'])
- puts YAML.dump(result['raw']) if @opts[:raw]
- else
- close_connection
- end
- end
- when "count"
- count(get_query) do |x|
- puts x
- close_connection
- end
- when "label"
- label get_query, @opts[:remove_labels].split(','), @opts[:add_labels].split(',') do
- close_connection
- end
- when "add"
- ARGF.binmode
- labels = @opts[:labels].split(',')
- get_message = lambda do
- return ARGF.gets(nil) unless @opts[:mbox]
- str = ""
- l = ARGF.gets
- str << l until ARGF.closed? || ARGF.eof? || MBox::is_break_line?(l = ARGF.gets)
- str.empty? ? nil : str
- end
- i_s = i = 0
- t = Time.now
- while raw = get_message[]
- i += 1
- t_d = Time.now - t
- if t_d >= 5
- i_d = i - i_s
- puts "indexed #{i} messages (#{i_d/t_d} m/s)" if global_opts[:verbose]
- t = Time.now
- i_s = i
- end
- add raw, labels do
- close_connection
- end
- end
- else
- fail "#{@cmd} command unimplemented"
- close_connection
- end
- end
-
- def unbind
- EM.stop
- end
-end
-
-
-EM.run do
- if global_opts[:socket]
- EM.connect global_opts[:socket], SupCmd, cmd, ARGV, cmd_opts.merge(global_opts)
- else
- EM.connect global_opts[:host], global_opts[:port], SupCmd, cmd, ARGV, cmd_opts.merge(global_opts)
- end
-end
-
-exit 0
-
diff --git a/bin/sup-config b/bin/sup-config
index c4a64a3..2cd3765 100755
--- a/bin/sup-config
+++ b/bin/sup-config
@@ -1,8 +1,9 @@
#!/usr/bin/env ruby
+$:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
+
require 'rubygems'
require 'highline/import'
-require 'yaml'
require 'trollop'
require "sup"
@@ -20,12 +21,13 @@ EOS
end
def axe q, default=nil
- ans = if default && !default.empty?
- ask "#{q} (enter for \"#{default}\"): "
- else
- ask "#{q}: "
- end
- ans.empty? ? default : ans
+ question = if default && !default.empty?
+ "#{q} (enter for \"#{default}\"): "
+ else
+ "#{q}: "
+ end
+ ans = ask question
+ ans.empty? ? default : ans.to_s
end
def axe_yes q, default="n"
@@ -37,6 +39,8 @@ def build_cmd cmd
end
def add_source
+ require "sup/util/uri"
+
type = nil
say "Ok, adding a new source."
@@ -70,7 +74,7 @@ def add_source
end
uri = begin
- URI::Generic.build components
+ Redwood::Util::Uri.build components
rescue URI::Error => e
say "Whoopsie! I couldn't build a URI from that: #{e.message}"
if axe_yes("Try again?") then next else return end
diff --git a/bin/sup-dump b/bin/sup-dump
index 4908b18..271a982 100755
--- a/bin/sup-dump
+++ b/bin/sup-dump
@@ -1,5 +1,7 @@
#!/usr/bin/env ruby
+$:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
+
require 'rubygems'
require 'xapian'
require 'trollop'
diff --git a/bin/sup-import-dump b/bin/sup-import-dump
index 91a1721..bde1723 100755
--- a/bin/sup-import-dump
+++ b/bin/sup-import-dump
@@ -1,9 +1,11 @@
#!/usr/bin/env ruby
+$:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
+
require 'uri'
require 'rubygems'
require 'trollop'
-require "sup"; Redwood::check_library_version_against "git"
+require "sup"
PROGRESS_UPDATE_INTERVAL = 15 # seconds
diff --git a/bin/sup-psych-ify-config-files b/bin/sup-psych-ify-config-files
new file mode 100755
index 0000000..c023169
--- /dev/null
+++ b/bin/sup-psych-ify-config-files
@@ -0,0 +1,16 @@
+#!/usr/bin/env ruby
+
+$:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
+
+require "sup"
+require "fileutils"
+
+Redwood.start
+
+fn = Redwood::SOURCE_FN
+FileUtils.cp fn, "#{fn}.syck_bak"
+
+Redwood::SourceManager.load_sources fn
+Redwood::SourceManager.save_sources fn, true
+
+Redwood.finish
diff --git a/bin/sup-recover-sources b/bin/sup-recover-sources
index 1f69f62..2d62c32 100755
--- a/bin/sup-recover-sources
+++ b/bin/sup-recover-sources
@@ -1,5 +1,7 @@
#!/usr/bin/env ruby
+$:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
+
require 'optparse'
$opts = {
diff --git a/bin/sup-server b/bin/sup-server
deleted file mode 100755
index aeec37c..0000000
--- a/bin/sup-server
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/usr/bin/env ruby
-require 'rubygems'
-require 'trollop'
-require 'sup'
-require 'sup/server'
-require 'pp'
-require 'yaml'
-include Redwood
-
-global_opts = Trollop::options do
- #version = "sup-cmd (sup #{Redwood::VERSION})"
- banner <<EOS
-Interact with a Sup index.
-
-Usage:
- sup-server [options]
-EOS
-
- opt :host, "address to listen on", :type => :string, :default => 'localhost', :short => 'o'
- opt :port, "port to listen on", :type => :int, :default => 4300
- opt :verbose
-end
-
-Redwood.start
-Index.init
-Index.lock_interactively or exit
-begin
- if(s = Redwood::SourceManager.source_for SentManager.source_uri)
- SentManager.source = s
- else
- Redwood::SourceManager.add_source SentManager.default_source
- end
-
- Index.load
-
- EM.run do
- EM.start_server global_opts[:host], global_opts[:port],
- Redwood::Server, Index.instance
- EM.next_tick { puts "ready" }
- end
-
-ensure
- Index.unlock
-end
diff --git a/bin/sup-sync b/bin/sup-sync
index b4d5cba..ee6d932 100755
--- a/bin/sup-sync
+++ b/bin/sup-sync
@@ -1,9 +1,11 @@
#!/usr/bin/env ruby
+$:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
+
require 'uri'
require 'rubygems'
require 'trollop'
-require "sup"; Redwood::check_library_version_against "git"
+require "sup"
PROGRESS_UPDATE_INTERVAL = 15 # seconds
diff --git a/bin/sup-sync-back b/bin/sup-sync-back
index 5d84cba..de4e869 100755
--- a/bin/sup-sync-back
+++ b/bin/sup-sync-back
@@ -1,10 +1,12 @@
#!/usr/bin/env ruby
+$:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
+
require 'rubygems'
require 'uri'
require 'tempfile'
require 'trollop'
-require "sup"; Redwood::check_library_version_against "git"
+require "sup"
fail "not working yet"
diff --git a/bin/sup-tweak-labels b/bin/sup-tweak-labels
index 076c802..36947d5 100755
--- a/bin/sup-tweak-labels
+++ b/bin/sup-tweak-labels
@@ -1,8 +1,10 @@
#!/usr/bin/env ruby
+$:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
+
require 'rubygems'
require 'trollop'
-require "sup"; Redwood::check_library_version_against "git"
+require "sup"
class Float
def to_s; sprintf '%.2f', self; end
diff --git a/bugs/issue-0240b36671ecb019e57ef27e0901bff055385371.yaml b/bugs/issue-0240b36671ecb019e57ef27e0901bff055385371.yaml
deleted file mode 100644
index e5565ce..0000000
--- a/bugs/issue-0240b36671ecb019e57ef27e0901bff055385371.yaml
+++ /dev/null
@@ -1,22 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: messages with unparseable date headers are being discarded entirely
-desc: it's better to forge the date headers and keep the messages
-type: :bugfix
-component: sup
-release: "0.5"
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :closed
-disposition: fixed
-creation_time: 2008-03-07 03:57:25.399978 Z
-references: []
-
-id: 0240b36671ecb019e57ef27e0901bff055385371
-log_events:
-- - 2008-03-07 03:57:25.400014 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-03-07 03:57:29.249827 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - changed status from unstarted to fixed
- - ""
diff --git a/bugs/issue-08d6bae05fa885bf6fcae39f864eb923c1e9a79e.yaml b/bugs/issue-08d6bae05fa885bf6fcae39f864eb923c1e9a79e.yaml
deleted file mode 100644
index 3c4be72..0000000
--- a/bugs/issue-08d6bae05fa885bf6fcae39f864eb923c1e9a79e.yaml
+++ /dev/null
@@ -1,27 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: reply-from hook
-desc: "hook for setting the from: address of a reply programmatically"
-type: :feature
-component: hooks
-release: "0.6"
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :closed
-disposition: :fixed
-creation_time: 2008-06-19 17:58:26.142289 Z
-references: []
-
-id: 08d6bae05fa885bf6fcae39f864eb923c1e9a79e
-log_events:
-- - 2008-06-19 17:58:27.334371 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-06-19 17:58:40.526270 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - changed status from unstarted to in_progress
- - branch reply-from-hook, merged into next
-- - 2008-07-30 23:41:56.898257 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - closed with disposition fixed
- - merged into master
-git_branch: reply-from-hook
diff --git a/bugs/issue-09479a2ada22c2a0d76427e12ef2514d4753d070.yaml b/bugs/issue-09479a2ada22c2a0d76427e12ef2514d4753d070.yaml
deleted file mode 100644
index 94aa231..0000000
--- a/bugs/issue-09479a2ada22c2a0d76427e12ef2514d4753d070.yaml
+++ /dev/null
@@ -1,18 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: forwarded messages should be threaded under original
-desc: ""
-type: :feature
-component: threading
-release:
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :unstarted
-disposition:
-creation_time: 2008-06-07 23:45:11.606455 Z
-references: []
-
-id: 09479a2ada22c2a0d76427e12ef2514d4753d070
-log_events:
-- - 2008-06-07 23:45:12.746568 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
diff --git a/bugs/issue-15738247f939d20f8f202f80ccb85d9ad92101e0.yaml b/bugs/issue-15738247f939d20f8f202f80ccb85d9ad92101e0.yaml
deleted file mode 100644
index 3c780b9..0000000
--- a/bugs/issue-15738247f939d20f8f202f80ccb85d9ad92101e0.yaml
+++ /dev/null
@@ -1,18 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: command to reload hooks
-desc: useful for debugging hooks without having to restart sup each time
-type: :feature
-component: hooks
-release:
-reporter: William Morgan <wmorgan-ditz at masanjin.net>
-status: :unstarted
-disposition:
-creation_time: 2008-05-09 06:09:46.127686 Z
-references: []
-
-id: 15738247f939d20f8f202f80ccb85d9ad92101e0
-log_events:
-- - 2008-05-09 06:09:46.803222 Z
- - William Morgan <wmorgan-ditz at masanjin.net>
- - created
- - ""
diff --git a/bugs/issue-182841e15d6909892adf43678bae03597ce10519.yaml b/bugs/issue-182841e15d6909892adf43678bae03597ce10519.yaml
deleted file mode 100644
index b680b9d..0000000
--- a/bugs/issue-182841e15d6909892adf43678bae03597ce10519.yaml
+++ /dev/null
@@ -1,25 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: external mime viewing logic not quite right
-desc: |-
- weird things happen depending on the specifics on whether you have
- certain binaries in your path, or you implement the mime-view hook,
- you can get very weird behavior
-type: :bugfix
-component: hooks
-release: "0.5"
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :closed
-disposition: fixed
-creation_time: 2008-03-07 04:05:53.956188 Z
-references: []
-
-id: 182841e15d6909892adf43678bae03597ce10519
-log_events:
-- - 2008-03-07 04:05:53.956222 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-03-07 04:06:02.239869 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - changed status from unstarted to fixed
- - ""
diff --git a/bugs/issue-1a1527438c2d198eae9a264ce9e6b847854d9837.yaml b/bugs/issue-1a1527438c2d198eae9a264ce9e6b847854d9837.yaml
deleted file mode 100644
index 87d0472..0000000
--- a/bugs/issue-1a1527438c2d198eae9a264ce9e6b847854d9837.yaml
+++ /dev/null
@@ -1,30 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: attachment name searchability
-desc: ""
-type: :feature
-component: indexing
-release: "0.6"
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :closed
-disposition: :fixed
-creation_time: 2008-05-25 03:53:44.524558 Z
-references: []
-
-id: 1a1527438c2d198eae9a264ce9e6b847854d9837
-log_events:
-- - 2008-05-25 03:53:45.177580 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-05-25 03:54:05.978412 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - changed status from unstarted to in_progress
- - branch attachments, merged into next
-- - 2008-05-31 17:09:04.254381 Z
- - William Morgan <wmorgan-ditz at masanjin.net>
- - commented
- - see {issue 65506670167642cc581956bc1b25c26b5bff215b} and {issue 7a68c1e7120a8540c7c51c6095f4815918d16641}
-- - 2008-06-19 18:20:41.656527 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - closed issue with disposition fixed
- - merged into master
diff --git a/bugs/issue-2312263b6a2b7de6ae1ec4ab315c7829763e61be.yaml b/bugs/issue-2312263b6a2b7de6ae1ec4ab315c7829763e61be.yaml
deleted file mode 100644
index 38364d9..0000000
--- a/bugs/issue-2312263b6a2b7de6ae1ec4ab315c7829763e61be.yaml
+++ /dev/null
@@ -1,22 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: sup-sync-back "nothing to do" error message not informative
-desc: should tell the user that one of the four magic options are required
-type: :bugfix
-component: sup-sync-back
-release: "0.5"
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :closed
-disposition: fixed
-creation_time: 2008-03-07 03:37:41.693484 Z
-references: []
-
-id: 2312263b6a2b7de6ae1ec4ab315c7829763e61be
-log_events:
-- - 2008-03-07 03:37:41.693520 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-03-07 03:37:46.110644 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - changed status from unstarted to fixed
- - ""
diff --git a/bugs/issue-23658477a445c2e61405fecb4cb641a2298caba6.yaml b/bugs/issue-23658477a445c2e61405fecb4cb641a2298caba6.yaml
deleted file mode 100644
index 91e661a..0000000
--- a/bugs/issue-23658477a445c2e61405fecb4cb641a2298caba6.yaml
+++ /dev/null
@@ -1,27 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: wide character ncurses support
-desc: ""
-type: :feature
-component: curses
-release:
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :in_progress
-disposition:
-creation_time: 2008-04-22 22:43:23.153185 Z
-references: []
-
-id: 23658477a445c2e61405fecb4cb641a2298caba6
-log_events:
-- - 2008-04-22 22:43:24.808717 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-04-22 22:45:52.511820 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - changed status from unstarted to in_progress
- - |-
- Branch 'ncurses-widechar' has been merged into next.
-
- Branch "ncursesw" now has a copy of the ncurses 0.9.2 gem with wide character
- modifications, and a script "run-this-for-sup.sh" to build and install it
- (assuming you're running from git, of course.)
diff --git a/bugs/issue-2673f091c15dd90222a59621a1842d4ef0a743f7.yaml b/bugs/issue-2673f091c15dd90222a59621a1842d4ef0a743f7.yaml
deleted file mode 100644
index df14160..0000000
--- a/bugs/issue-2673f091c15dd90222a59621a1842d4ef0a743f7.yaml
+++ /dev/null
@@ -1,19 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: make sup-sync-back work on IMAP folders
-desc: ""
-type: :feature
-component: sup-sync-back
-release:
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :unstarted
-disposition:
-creation_time: 2008-10-14 01:14:08.690909 Z
-references: []
-
-id: 2673f091c15dd90222a59621a1842d4ef0a743f7
-log_events:
-- - 2008-10-14 01:14:09.898338 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-git_branch:
diff --git a/bugs/issue-2a0363cdf9d25edfa2a04b21299a538365e8b319.yaml b/bugs/issue-2a0363cdf9d25edfa2a04b21299a538365e8b319.yaml
deleted file mode 100644
index 8aab1df..0000000
--- a/bugs/issue-2a0363cdf9d25edfa2a04b21299a538365e8b319.yaml
+++ /dev/null
@@ -1,30 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: gpg mode hook
-desc: |-
- need a hook for controlling the default setting of the gpg mode (none,
- sign, sign & encrypt) in reply-mode, based on the gpg mode of the original
- message.
-type: :feature
-component: hooks
-release:
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :unstarted
-disposition:
-creation_time: 2008-03-07 02:42:29.391022 Z
-references: []
-
-id: 2a0363cdf9d25edfa2a04b21299a538365e8b319
-log_events:
-- - 2008-03-07 02:42:29.391058 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-04-20 21:18:14.263736 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - assigned to release 0.6 from 0.5
- - ""
-- - 2008-07-31 00:54:02.960978 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - unassigned from release 0.6
- - ""
-git_branch:
diff --git a/bugs/issue-2e74aa6843feee4daefe740b6e3f1fc54ff4bfcb.yaml b/bugs/issue-2e74aa6843feee4daefe740b6e3f1fc54ff4bfcb.yaml
deleted file mode 100644
index 87252e4..0000000
--- a/bugs/issue-2e74aa6843feee4daefe740b6e3f1fc54ff4bfcb.yaml
+++ /dev/null
@@ -1,22 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: oldest-first thread ordering
-desc: ""
-type: :feature
-component: indexing
-release:
-reporter: Matt Liggett <mml at pobox.com>
-status: :unstarted
-disposition:
-creation_time: 2008-03-14 18:33:01.603318 Z
-references:
-- http://rubyforge.org/pipermail/sup-talk/2008-March/001271.html
-id: 2e74aa6843feee4daefe740b6e3f1fc54ff4bfcb
-log_events:
-- - 2008-03-14 18:33:01.603569 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-03-14 18:33:31.116057 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - added reference 1
- - ""
diff --git a/bugs/issue-314f0cdac8d1998c46759a4ebef9077999bcef09.yaml b/bugs/issue-314f0cdac8d1998c46759a4ebef9077999bcef09.yaml
deleted file mode 100644
index 431a522..0000000
--- a/bugs/issue-314f0cdac8d1998c46759a4ebef9077999bcef09.yaml
+++ /dev/null
@@ -1,18 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: new user welcome screen the first time you start up
-desc: ""
-type: :feature
-component: curses
-release:
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :unstarted
-disposition:
-creation_time: 2008-03-07 02:44:24.399133 Z
-references: []
-
-id: 314f0cdac8d1998c46759a4ebef9077999bcef09
-log_events:
-- - 2008-03-07 02:44:24.399167 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
diff --git a/bugs/issue-3408c200a5f47f92d12b5c063a00ce891c2ba4ce.yaml b/bugs/issue-3408c200a5f47f92d12b5c063a00ce891c2ba4ce.yaml
deleted file mode 100644
index cde47bd..0000000
--- a/bugs/issue-3408c200a5f47f92d12b5c063a00ce891c2ba4ce.yaml
+++ /dev/null
@@ -1,22 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: "email header parsing: space doesn't need to follow colon"
-desc: ""
-type: :bugfix
-component: sup
-release: "0.5"
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :closed
-disposition: fixed
-creation_time: 2008-03-07 04:31:55.733379 Z
-references: []
-
-id: 3408c200a5f47f92d12b5c063a00ce891c2ba4ce
-log_events:
-- - 2008-03-07 04:31:55.733416 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-03-07 04:31:59.580856 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - changed status from unstarted to fixed
- - ""
diff --git a/bugs/issue-3441fb8b7f955d625633d06fa0bf67a9afab046e.yaml b/bugs/issue-3441fb8b7f955d625633d06fa0bf67a9afab046e.yaml
deleted file mode 100644
index bd3c0fe..0000000
--- a/bugs/issue-3441fb8b7f955d625633d06fa0bf67a9afab046e.yaml
+++ /dev/null
@@ -1,18 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: saving a message as a draft drops attachments
-desc: ""
-type: :bugfix
-component: sup
-release:
-reporter: William Morgan <wmorgan-ditz at masanjin.net>
-status: :unstarted
-disposition:
-creation_time: 2008-05-25 02:14:13.362087 Z
-references: []
-
-id: 3441fb8b7f955d625633d06fa0bf67a9afab046e
-log_events:
-- - 2008-05-25 02:14:14.224040 Z
- - William Morgan <wmorgan-ditz at masanjin.net>
- - created
- - ""
diff --git a/bugs/issue-38d6f805b0c8bad013ec73f56e6245c890528591.yaml b/bugs/issue-38d6f805b0c8bad013ec73f56e6245c890528591.yaml
deleted file mode 100644
index 635bd65..0000000
--- a/bugs/issue-38d6f805b0c8bad013ec73f56e6245c890528591.yaml
+++ /dev/null
@@ -1,29 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: "'m' in edit-message-mode should prompt for a to: with a default"
-desc: |-
- the current behavior is to just go ahead and compose the message, which
- is irritating if you're just trying to compose a message incidental to
- having highlighted someone's email address.
-type: :bugfix
-component: curses
-release: "0.6"
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :closed
-disposition: :fixed
-creation_time: 2008-03-07 02:37:38.905689 Z
-references: []
-
-id: 38d6f805b0c8bad013ec73f56e6245c890528591
-log_events:
-- - 2008-03-07 02:37:38.905723 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-04-20 21:44:06.473431 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - assigned to release 0.6 from 0.5
- - ""
-- - 2008-05-25 03:47:42.600153 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - closed issue with disposition fixed
- - fixed in master
diff --git a/bugs/issue-3b25f1d56b9be533edaf232b9e60dc24e00cba0b.yaml b/bugs/issue-3b25f1d56b9be533edaf232b9e60dc24e00cba0b.yaml
deleted file mode 100644
index 07ca173..0000000
--- a/bugs/issue-3b25f1d56b9be533edaf232b9e60dc24e00cba0b.yaml
+++ /dev/null
@@ -1,26 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: maildir speedups
-desc: caching mtimes, using dir mtimes as an upper bound on file mtimes
-type: :feature
-component: maildir
-release: "0.6"
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :closed
-disposition: :fixed
-creation_time: 2008-05-25 02:30:42.010965 Z
-references: []
-
-id: 3b25f1d56b9be533edaf232b9e60dc24e00cba0b
-log_events:
-- - 2008-05-25 02:30:42.815974 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-05-25 02:30:59.062438 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - changed status from unstarted to in_progress
- - branch maildir-speedups. merged into next.
-- - 2008-06-19 18:09:27.239553 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - closed issue with disposition fixed
- - merged into master
diff --git a/bugs/issue-42ab0840f9a1924f1c0561e8ddcf7e6988543ba0.yaml b/bugs/issue-42ab0840f9a1924f1c0561e8ddcf7e6988543ba0.yaml
deleted file mode 100644
index ba95c00..0000000
--- a/bugs/issue-42ab0840f9a1924f1c0561e8ddcf7e6988543ba0.yaml
+++ /dev/null
@@ -1,26 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: query normalization breaking disjunctive queries, date modifers, etc
-desc: ""
-type: :bugfix
-component: indexing
-release: "0.5"
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :closed
-disposition: :fixed
-creation_time: 2008-03-07 03:39:26.683059 Z
-references: []
-
-id: 42ab0840f9a1924f1c0561e8ddcf7e6988543ba0
-log_events:
-- - 2008-03-07 03:39:26.683093 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-03-07 03:50:16.796313 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - changed status from unstarted to in_progress
- - ""
-- - 2008-04-20 22:10:39.075075 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - closed issue with disposition fixed
- - ""
diff --git a/bugs/issue-46df983ccdb75408a37b3911472d4015664a3cf6.yaml b/bugs/issue-46df983ccdb75408a37b3911472d4015664a3cf6.yaml
deleted file mode 100644
index 5358756..0000000
--- a/bugs/issue-46df983ccdb75408a37b3911472d4015664a3cf6.yaml
+++ /dev/null
@@ -1,20 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: curses interface generally sluggish
-desc: |-
- moving cursors around, etc is sluggish. should be faster. will require
- profiling. might require dipping into the C level.
-type: :bugfix
-component: curses
-release:
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :unstarted
-disposition:
-creation_time: 2008-05-19 23:38:35.608104 Z
-references: []
-
-id: 46df983ccdb75408a37b3911472d4015664a3cf6
-log_events:
-- - 2008-05-19 23:38:36.229747 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
diff --git a/bugs/issue-47aab6443b6c107c3067cdb614186099db570acf.yaml b/bugs/issue-47aab6443b6c107c3067cdb614186099db570acf.yaml
deleted file mode 100644
index ced024b..0000000
--- a/bugs/issue-47aab6443b6c107c3067cdb614186099db570acf.yaml
+++ /dev/null
@@ -1,37 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: before-add-hook not applied to sent messages
-desc: |-
- they're not being polled in the regular way but in a vestigal irregular
- way
-type: :bugfix
-component: sup
-release: "0.5"
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :closed
-disposition: fixed
-creation_time: 2008-03-07 03:54:10.773413 Z
-references:
-- http://rubyforge.org/pipermail/sup-talk/2008-March/001259.html
-- http://rubyforge.org/pipermail/sup-talk/2008-February/001203.html
-id: 47aab6443b6c107c3067cdb614186099db570acf
-log_events:
-- - 2008-03-07 03:54:10.773449 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-03-07 03:54:15.699906 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - changed status from unstarted to in_progress
- - ""
-- - 2008-03-08 22:02:45.840451 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - changed status from in_progress to fixed
- - merged down to master.
-- - 2008-03-08 22:16:00.346710 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - added reference 1
- - ""
-- - 2008-03-08 22:22:02.528552 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - added reference 2
- - ""
diff --git a/bugs/issue-4af242013994ae557e431ba350a92c4f9e1739ef.yaml b/bugs/issue-4af242013994ae557e431ba350a92c4f9e1739ef.yaml
deleted file mode 100644
index db4b825..0000000
--- a/bugs/issue-4af242013994ae557e431ba350a92c4f9e1739ef.yaml
+++ /dev/null
@@ -1,28 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: sup-sync shouldn't save the index and sources if an error occurred
-desc: |-
- If the error was caused by a particular message, saving the source file
- will move the pointer past the message, so it will never get added.
-type: :bugfix
-component: sup-sync
-release: "0.5"
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :closed
-disposition: fixed
-creation_time: 2008-03-07 04:14:07.913103 Z
-references: []
-
-id: 4af242013994ae557e431ba350a92c4f9e1739ef
-log_events:
-- - 2008-03-07 04:14:07.913140 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-03-07 04:14:12.599051 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - changed status from unstarted to fixed
- - ""
-- - 2008-03-09 18:29:51.789364 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - changed description
- - ""
diff --git a/bugs/issue-4daa2721dac8dfeb8730ee081f73b6c62702bd3e.yaml b/bugs/issue-4daa2721dac8dfeb8730ee081f73b6c62702bd3e.yaml
deleted file mode 100644
index 2761c60..0000000
--- a/bugs/issue-4daa2721dac8dfeb8730ee081f73b6c62702bd3e.yaml
+++ /dev/null
@@ -1,23 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: last message of every source is returned twice during polling
-desc: http://rubyforge.org/pipermail/sup-talk/2008-April/001358.html
-type: :bugfix
-component: sup
-release:
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :unstarted
-disposition:
-creation_time: 2008-05-01 01:11:50.650800 Z
-references: []
-
-id: 4daa2721dac8dfeb8730ee081f73b6c62702bd3e
-log_events:
-- - 2008-05-01 01:11:51.434589 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-07-31 00:54:39.589377 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - unassigned from release 0.6
- - ""
-git_branch:
diff --git a/bugs/issue-4e501973cea5bd1f28739ae4cea98edce8249895.yaml b/bugs/issue-4e501973cea5bd1f28739ae4cea98edce8249895.yaml
deleted file mode 100644
index 1c3d0a4..0000000
--- a/bugs/issue-4e501973cea5bd1f28739ae4cea98edce8249895.yaml
+++ /dev/null
@@ -1,32 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: thread joining is not preserved when reindexing
-desc: |
- the current thread joining just adds references to the index entries. that's
- fine but if the messages are reindexed, the references obviously won't be
- there.
- i think we need to add some separate blob of information somewhere that
- maintains these references, which sup-sync is aware of.
-
- if we're going down the bdb route for state preservation, that might be an
- obvious place to put this too, because it's essentially a hashtable keyed on
- message ids.
-
-type: :bugfix
-component: indexing
-release:
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :unstarted
-disposition:
-creation_time: 2008-03-14 18:39:59.697902 Z
-references:
-- http://rubyforge.org/pipermail/sup-talk/2008-March/001270.html
-id: 4e501973cea5bd1f28739ae4cea98edce8249895
-log_events:
-- - 2008-03-14 18:39:59.698163 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-03-14 18:40:26.559418 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - added reference 1
- - ""
diff --git a/bugs/issue-5348fec2b1112250e241afc7467de29e5691d1be.yaml b/bugs/issue-5348fec2b1112250e241afc7467de29e5691d1be.yaml
deleted file mode 100644
index 64d84a2..0000000
--- a/bugs/issue-5348fec2b1112250e241afc7467de29e5691d1be.yaml
+++ /dev/null
@@ -1,21 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: imap header caching
-desc: |-
- imap headers aren't cached at all. that would speed up the initial
- connection, at least for servers that didn't set uid_validity to
- the current time (blearf).
-type: :feature
-component: imap
-release:
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :unstarted
-disposition:
-creation_time: 2008-03-07 04:26:31.474463 Z
-references: []
-
-id: 5348fec2b1112250e241afc7467de29e5691d1be
-log_events:
-- - 2008-03-07 04:26:31.474497 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
diff --git a/bugs/issue-57668c69d0190d6e849309834d4ad1d215efa779.yaml b/bugs/issue-57668c69d0190d6e849309834d4ad1d215efa779.yaml
deleted file mode 100644
index fcb39c1..0000000
--- a/bugs/issue-57668c69d0190d6e849309834d4ad1d215efa779.yaml
+++ /dev/null
@@ -1,21 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: make sup-sync-back work on Maildir folders
-desc: |-
- possibly we could abstract things entirely between mbox and maildir, but
- it might just be easiest to have a sup-sync-back-maildir or a big if
- statement.
-type: :feature
-component: sup-sync-back
-release:
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :unstarted
-disposition:
-creation_time: 2008-06-12 19:24:51.772444 Z
-references: []
-
-id: 57668c69d0190d6e849309834d4ad1d215efa779
-log_events:
-- - 2008-06-12 19:24:53.668373 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
diff --git a/bugs/issue-5795c3c1b47e88f7261f57f31d33fe15ad08465d.yaml b/bugs/issue-5795c3c1b47e88f7261f57f31d33fe15ad08465d.yaml
deleted file mode 100644
index 8f774aa..0000000
--- a/bugs/issue-5795c3c1b47e88f7261f57f31d33fe15ad08465d.yaml
+++ /dev/null
@@ -1,20 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: flat (gmail-style) version of thread-view-mode
-desc: |-
- make thread-view-mode show a flat, chronological list of messages
- instead of a tree, based on some configuration variable.
-type: :feature
-component: curses
-release:
-reporter: William Morgan <wmorgan-ditz at masanjin.net>
-status: :unstarted
-disposition:
-creation_time: 2008-05-25 02:38:06.098950 Z
-references: []
-
-id: 5795c3c1b47e88f7261f57f31d33fe15ad08465d
-log_events:
-- - 2008-05-25 02:38:06.823848 Z
- - William Morgan <wmorgan-ditz at masanjin.net>
- - created
- - ""
diff --git a/bugs/issue-5fab957dcd16f1da8962fe5b1f3a58d970315deb.yaml b/bugs/issue-5fab957dcd16f1da8962fe5b1f3a58d970315deb.yaml
deleted file mode 100644
index 7c3c725..0000000
--- a/bugs/issue-5fab957dcd16f1da8962fe5b1f3a58d970315deb.yaml
+++ /dev/null
@@ -1,24 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: extra-contact-addresses hook for lbdb (etc.) integration
-desc: |-
- add an extra-contact-addresses hook for inserting addresses into the
- tab-completion list for To:, Cc:, etc. entries.
-type: :feature
-component: hooks
-release: "0.5"
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :closed
-disposition: :fixed
-creation_time: 2008-04-20 20:43:06.972853 Z
-references: []
-
-id: 5fab957dcd16f1da8962fe5b1f3a58d970315deb
-log_events:
-- - 2008-04-20 20:43:08.667355 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-04-20 20:43:20.678566 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - closed issue with disposition fixed
- - ""
diff --git a/bugs/issue-60d86dd32054533a6206f698033ec668af6a7574.yaml b/bugs/issue-60d86dd32054533a6206f698033ec668af6a7574.yaml
deleted file mode 100644
index 2830fff..0000000
--- a/bugs/issue-60d86dd32054533a6206f698033ec668af6a7574.yaml
+++ /dev/null
@@ -1,29 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: killed threads showing up in inbox-mode
-desc: this goddamn problem is recurring
-type: :bugfix
-component: indexing
-release:
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :closed
-disposition: :fixed
-creation_time: 2008-04-25 19:28:51.369257 Z
-references: []
-
-id: 60d86dd32054533a6206f698033ec668af6a7574
-log_events:
-- - 2008-04-25 19:28:52.476687 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-07-31 00:54:38.916308 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - unassigned from release 0.6
- - ""
-- - 2008-11-21 14:23:17.566852 Z
- - Nicolas Pouillard <nicolas.pouillard at gmail.com>
- - closed with disposition fixed
- - |-
- Loading options was not given to load_thread_for_message in
- ThreadIndexMode.add_or_unhide.
-git_branch:
diff --git a/bugs/issue-61949ec83770b5d46f89eff21799968187012cce.yaml b/bugs/issue-61949ec83770b5d46f89eff21799968187012cce.yaml
deleted file mode 100644
index fb3df1a..0000000
--- a/bugs/issue-61949ec83770b5d46f89eff21799968187012cce.yaml
+++ /dev/null
@@ -1,22 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: \127 should be handled like backspace (it's the 70's all over again)
-desc: ""
-type: :bugfix
-component: curses
-release: "0.5"
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :closed
-disposition: fixed
-creation_time: 2008-03-07 04:29:46.043812 Z
-references: []
-
-id: 61949ec83770b5d46f89eff21799968187012cce
-log_events:
-- - 2008-03-07 04:29:46.043850 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-03-07 04:29:52.233706 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - changed status from unstarted to fixed
- - ""
diff --git a/bugs/issue-65506670167642cc581956bc1b25c26b5bff215b.yaml b/bugs/issue-65506670167642cc581956bc1b25c26b5bff215b.yaml
deleted file mode 100644
index e43d6af..0000000
--- a/bugs/issue-65506670167642cc581956bc1b25c26b5bff215b.yaml
+++ /dev/null
@@ -1,30 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: attachment markers in thread-index-mode
-desc: show a little @ if the message has an attachment
-type: :feature
-component: curses
-release: "0.6"
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :closed
-disposition: :fixed
-creation_time: 2008-05-25 03:53:10.005404 Z
-references: []
-
-id: 65506670167642cc581956bc1b25c26b5bff215b
-log_events:
-- - 2008-05-25 03:53:10.994290 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-05-25 03:53:26.388023 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - changed status from unstarted to in_progress
- - branch attachments, merged into next
-- - 2008-05-31 17:09:17.710631 Z
- - William Morgan <wmorgan-ditz at masanjin.net>
- - commented
- - see {issue 1a1527438c2d198eae9a264ce9e6b847854d9837} and {issue 7a68c1e7120a8540c7c51c6095f4815918d16641}
-- - 2008-06-19 18:20:33.912937 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - closed issue with disposition fixed
- - ""
diff --git a/bugs/issue-658389418b5f0038cc3e6bc20fd3fd1566eb7111.yaml b/bugs/issue-658389418b5f0038cc3e6bc20fd3fd1566eb7111.yaml
deleted file mode 100644
index 26ce1e8..0000000
--- a/bugs/issue-658389418b5f0038cc3e6bc20fd3fd1566eb7111.yaml
+++ /dev/null
@@ -1,26 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: add a startup hook
-desc: ""
-type: :feature
-component: hooks
-release: "0.5"
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :closed
-disposition: :fixed
-creation_time: 2008-03-07 04:03:52.999956 Z
-references: []
-
-id: 658389418b5f0038cc3e6bc20fd3fd1566eb7111
-log_events:
-- - 2008-03-07 04:03:52.999992 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-03-07 04:03:56.880347 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - changed status from unstarted to in_progress
- - ""
-- - 2008-04-20 20:45:20.047253 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - closed issue with disposition fixed
- - ""
diff --git a/bugs/issue-69f785cddcc6e09ef0a357151373b3aa923d5e3f.yaml b/bugs/issue-69f785cddcc6e09ef0a357151373b3aa923d5e3f.yaml
deleted file mode 100644
index 6a6f488..0000000
--- a/bugs/issue-69f785cddcc6e09ef0a357151373b3aa923d5e3f.yaml
+++ /dev/null
@@ -1,22 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: escape filenames in call to run-mailcap
-desc: otherwise, filenames with spaces don't work
-type: :bugfix
-component: sup
-release: "0.5"
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :closed
-disposition: fixed
-creation_time: 2008-03-07 04:10:43.771843 Z
-references: []
-
-id: 69f785cddcc6e09ef0a357151373b3aa923d5e3f
-log_events:
-- - 2008-03-07 04:10:43.771878 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-03-07 04:10:48.789189 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - changed status from unstarted to fixed
- - ""
diff --git a/bugs/issue-6c053cca2eb05af486a2d09c6772fd5bd0cca444.yaml b/bugs/issue-6c053cca2eb05af486a2d09c6772fd5bd0cca444.yaml
deleted file mode 100644
index bbdf1c6..0000000
--- a/bugs/issue-6c053cca2eb05af486a2d09c6772fd5bd0cca444.yaml
+++ /dev/null
@@ -1,20 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: cache threading
-desc: |-
- thread information should be cached so that it doesn't have to be
- recomputed each time.
-type: :feature
-component: threading
-release:
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :unstarted
-disposition:
-creation_time: 2008-05-19 23:39:19.716625 Z
-references: []
-
-id: 6c053cca2eb05af486a2d09c6772fd5bd0cca444
-log_events:
-- - 2008-05-19 23:39:20.190260 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
diff --git a/bugs/issue-6e0d634de74b2eb8297174ecd408b3810ba9351b.yaml b/bugs/issue-6e0d634de74b2eb8297174ecd408b3810ba9351b.yaml
deleted file mode 100644
index 564b3b1..0000000
--- a/bugs/issue-6e0d634de74b2eb8297174ecd408b3810ba9351b.yaml
+++ /dev/null
@@ -1,24 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: imap connection sharing
-desc: |
- current behavior is a separate connection for each folder, which is kinda
- silly.
- potentially want to still keep a separate connection for polling, but that
- might be micro-optimization, especially given that the whole ruby imap
- library seems quite slow.
-
-type: :feature
-component: imap
-release:
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :unstarted
-disposition:
-creation_time: 2008-03-07 04:25:12.351934 Z
-references: []
-
-id: 6e0d634de74b2eb8297174ecd408b3810ba9351b
-log_events:
-- - 2008-03-07 04:25:12.351966 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
diff --git a/bugs/issue-6e7960514f66ee67da083bc7bb5632d5808fc607.yaml b/bugs/issue-6e7960514f66ee67da083bc7bb5632d5808fc607.yaml
deleted file mode 100644
index 9656537..0000000
--- a/bugs/issue-6e7960514f66ee67da083bc7bb5632d5808fc607.yaml
+++ /dev/null
@@ -1,30 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: "'!!' will load all threads in current search"
-desc: |-
- can be dangerous, but sometimes you know there aren't a million and you
- just want them all loaded, e.g. to apply some mass tagging operation.
- with the cancel-search feature, can always be canceled if
- onerous.
-type: :feature
-component: sup
-release: "0.5"
-reporter: Marcus Williams <marcus-sup at bar-coded.net>
-status: :closed
-disposition: fixed
-creation_time: 2008-03-07 04:17:44.706909 Z
-references: []
-
-id: 6e7960514f66ee67da083bc7bb5632d5808fc607
-log_events:
-- - 2008-03-07 04:17:44.706948 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-03-07 04:17:48.834972 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - changed status from unstarted to fixed
- - ""
-- - 2008-03-11 06:52:15.604233 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - changed description
- - ""
diff --git a/bugs/issue-7456c2d8fbd5de4dac651f6f4e9756f577497e01.yaml b/bugs/issue-7456c2d8fbd5de4dac651f6f4e9756f577497e01.yaml
deleted file mode 100644
index 915eb68..0000000
--- a/bugs/issue-7456c2d8fbd5de4dac651f6f4e9756f577497e01.yaml
+++ /dev/null
@@ -1,26 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: edit-as-new doesn't preserve replyto and references headers
-desc: ""
-type: :bugfix
-component: sup
-release: "0.6"
-reporter: William Morgan <wmorgan-ditz at masanjin.net>
-status: :closed
-disposition: :fixed
-creation_time: 2008-05-31 17:07:05.126884 Z
-references: []
-
-id: 7456c2d8fbd5de4dac651f6f4e9756f577497e01
-log_events:
-- - 2008-05-31 17:07:07.008637 Z
- - William Morgan <wmorgan-ditz at masanjin.net>
- - created
- - ""
-- - 2008-05-31 17:07:22.611383 Z
- - William Morgan <wmorgan-ditz at masanjin.net>
- - changed status from unstarted to in_progress
- - in branch edit-as-new-fix, merged into next
-- - 2008-06-19 18:22:24.036557 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - closed issue with disposition fixed
- - merged into master
diff --git a/bugs/issue-76802330c4fdd091e8b1dd08dcc29ed432f003d4.yaml b/bugs/issue-76802330c4fdd091e8b1dd08dcc29ed432f003d4.yaml
deleted file mode 100644
index e219937..0000000
--- a/bugs/issue-76802330c4fdd091e8b1dd08dcc29ed432f003d4.yaml
+++ /dev/null
@@ -1,26 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: in-buffer search always shifts the screen, even when unnecessary
-desc: ""
-type: :bugfix
-component: curses
-release: "0.6"
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :closed
-disposition: :fixed
-creation_time: 2008-05-01 22:34:01.983057 Z
-references: []
-
-id: 76802330c4fdd091e8b1dd08dcc29ed432f003d4
-log_events:
-- - 2008-05-01 22:34:02.958758 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-05-01 22:34:24.254778 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - changed status from unstarted to in_progress
- - branch find-in-buffer-fix, merged into next
-- - 2008-05-25 04:19:45.168367 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - closed issue with disposition fixed
- - merged into master
diff --git a/bugs/issue-799771a6a435dcad66dc80e7e051d91d24d005b1.yaml b/bugs/issue-799771a6a435dcad66dc80e7e051d91d24d005b1.yaml
deleted file mode 100644
index f1f2397..0000000
--- a/bugs/issue-799771a6a435dcad66dc80e7e051d91d24d005b1.yaml
+++ /dev/null
@@ -1,31 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: IMAP server restart crashes sup
-desc: |-
- this very bizarre backtrace:
-
- --- SystemExit from thread: main
- closed stream
- /usr/lib/ruby/1.8/openssl/buffering.rb:237:in `select'
- ./lib/sup/buffer.rb:31:in `nonblocking_getch'
- bin/sup:227
-
- wtf?
-
- There's no reason that
- nonblocking_getch would be calling the openssl stuff, and openssl's
- buffering.rb doesn't mention select at all. Weird.
-type: :bugfix
-component: imap
-release:
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :unstarted
-disposition:
-creation_time: 2008-05-19 23:17:32.271870 Z
-references: []
-
-id: 799771a6a435dcad66dc80e7e051d91d24d005b1
-log_events:
-- - 2008-05-19 23:17:33.615525 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
diff --git a/bugs/issue-7a68c1e7120a8540c7c51c6095f4815918d16641.yaml b/bugs/issue-7a68c1e7120a8540c7c51c6095f4815918d16641.yaml
deleted file mode 100644
index 3892dc7..0000000
--- a/bugs/issue-7a68c1e7120a8540c7c51c6095f4815918d16641.yaml
+++ /dev/null
@@ -1,28 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: attachment markers in thread-view-mode
-desc: |-
- i'd like to see them in thread-view-mode as well
- (c.f. {issue 65506670167642cc581956bc1b25c26b5bff215b} and {issue 1a1527438c2d198eae9a264ce9e6b847854d9837})
-type: :feature
-component: curses
-release: "0.6"
-reporter: William Morgan <wmorgan-ditz at masanjin.net>
-status: :closed
-disposition: :fixed
-creation_time: 2008-05-31 17:08:28.081944 Z
-references: []
-
-id: 7a68c1e7120a8540c7c51c6095f4815918d16641
-log_events:
-- - 2008-05-31 17:08:28.710190 Z
- - William Morgan <wmorgan-ditz at masanjin.net>
- - created
- - ""
-- - 2008-05-31 17:08:50.679595 Z
- - William Morgan <wmorgan-ditz at masanjin.net>
- - changed status from unstarted to in_progress
- - on branch attachments as well, remerged into next
-- - 2008-06-19 18:20:56.657318 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - closed issue with disposition fixed
- - merged into master
diff --git a/bugs/issue-7c77e757321c2639daea013824ad1a14099815b1.yaml b/bugs/issue-7c77e757321c2639daea013824ad1a14099815b1.yaml
deleted file mode 100644
index ecc1ae8..0000000
--- a/bugs/issue-7c77e757321c2639daea013824ad1a14099815b1.yaml
+++ /dev/null
@@ -1,26 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: in-buffer searches should move buffer horizontally when necessary
-desc: ""
-type: :feature
-component: curses
-release: "0.5"
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :closed
-disposition: :fixed
-creation_time: 2008-03-07 03:56:17.653639 Z
-references: []
-
-id: 7c77e757321c2639daea013824ad1a14099815b1
-log_events:
-- - 2008-03-07 03:56:17.653674 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-03-07 03:56:21.870750 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - changed status from unstarted to in_progress
- - ""
-- - 2008-04-20 20:44:07.668281 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - closed issue with disposition fixed
- - ""
diff --git a/bugs/issue-7d8474dfeeefaa50151c3ce48bee6b686d36a216.yaml b/bugs/issue-7d8474dfeeefaa50151c3ce48bee6b686d36a216.yaml
deleted file mode 100644
index a2906d8..0000000
--- a/bugs/issue-7d8474dfeeefaa50151c3ce48bee6b686d36a216.yaml
+++ /dev/null
@@ -1,29 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: reply-to mode hook
-desc: |-
- need a hook for selecting the default setting of the reply-to
- horizontal selector
-type: :feature
-component: hooks
-release: "0.6"
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :closed
-disposition: :fixed
-creation_time: 2008-06-04 03:04:10.253690 Z
-references: []
-
-id: 7d8474dfeeefaa50151c3ce48bee6b686d36a216
-log_events:
-- - 2008-06-04 03:04:10.945071 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-06-04 03:04:21.284329 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - changed status from unstarted to in_progress
- - branch 'reply-to-hook', merged into next
-- - 2008-07-30 23:41:50.393799 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - closed with disposition fixed
- - merged into master
-git_branch: reply-to-hook
diff --git a/bugs/issue-829b449c51fca9a39047d00fabc552cc110c69b2.yaml b/bugs/issue-829b449c51fca9a39047d00fabc552cc110c69b2.yaml
deleted file mode 100644
index e17e213..0000000
--- a/bugs/issue-829b449c51fca9a39047d00fabc552cc110c69b2.yaml
+++ /dev/null
@@ -1,24 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: don't crash when people.txt is corrupted
-desc: |-
- This was a debug check, but if Sup crashes when writing out people.txt,
- this will prevent it from ever starting again!
-type: :bugfix
-component: sup
-release: "0.5"
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :closed
-disposition: fixed
-creation_time: 2008-03-07 04:07:56.208521 Z
-references: []
-
-id: 829b449c51fca9a39047d00fabc552cc110c69b2
-log_events:
-- - 2008-03-07 04:07:56.208558 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-03-07 04:21:04.553157 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - changed status from unstarted to fixed
- - ""
diff --git a/bugs/issue-82c80f6dc2ce7b10b9e8f503d68253ced0ee8a1b.yaml b/bugs/issue-82c80f6dc2ce7b10b9e8f503d68253ced0ee8a1b.yaml
deleted file mode 100644
index 86be9e0..0000000
--- a/bugs/issue-82c80f6dc2ce7b10b9e8f503d68253ced0ee8a1b.yaml
+++ /dev/null
@@ -1,24 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: gpg generates invalid signature when :edit_signature is on
-desc: |-
- when :edit_signature is on and there's a signature, gpg signatures are invalid,
- ccording to mutt and other clients. sup itself thinks they're fine.
-type: :bugfix
-component: crypto
-release: "0.6"
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :closed
-disposition: :fixed
-creation_time: 2008-05-19 21:19:23.267668 Z
-references: []
-
-id: 82c80f6dc2ce7b10b9e8f503d68253ced0ee8a1b
-log_events:
-- - 2008-05-19 21:19:24.611826 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-05-19 21:19:49.649415 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - closed issue with disposition fixed
- - turns out it was a newline issue. patch directly applied to master.
diff --git a/bugs/issue-8a5cf9242ca60fa6c81091e425f734b4fb03e41a.yaml b/bugs/issue-8a5cf9242ca60fa6c81091e425f734b4fb03e41a.yaml
deleted file mode 100644
index b91de0d..0000000
--- a/bugs/issue-8a5cf9242ca60fa6c81091e425f734b4fb03e41a.yaml
+++ /dev/null
@@ -1,53 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: index speedup
-desc: |
- I've just merged in a changeset that makes Sup store message body
- content in the Ferret index. (They've always been indexed, but now
- they're stored as well.) This means that changing the labels on a
- message can be a copy operation of the previous Ferret document, rather
- than requiring downloading and parsing the original message to create a
- new Ferret document.
- So, this should have two effects:
-
- 1. The Ferret index size will expand by about 50%. Sorry.
- 2. Tweaking message labels should be much, much faster, since the
- message no longer has to be downloaded from the source in order to
- change the labels. If you've ever tried to label a large IMAP thread,
- you no longer have to wait 5 minutes just to save. :)
-
- The index size increase is unfortunate, but it's something that has to
- happen anyways if we want search-results-mode to have matching text in
- the snippets, which is in the future TODO.
-
- The change was made in such a way that it's incrementally applied
- whenever a message is saved or changed in the Ferret index. So, if you
- want the above behavior on all messages immediately, you must do
- sup-sync --all on a source (which will require downloading each
- message). Otherwise, you will get the slow behavior (message body needs
- to be downloaded from the source) the first time you save a message
- after merging this change, and the fast behavior (no downloading
- required) on all subsequent times.
-
-type: :feature
-component: indexing
-release: "0.5"
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :closed
-disposition: :fixed
-creation_time: 2008-03-07 02:48:23.885656 Z
-references: []
-
-id: 8a5cf9242ca60fa6c81091e425f734b4fb03e41a
-log_events:
-- - 2008-03-07 02:48:23.885693 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-03-07 02:48:50.979828 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - changed status from unstarted to in_progress
- - ""
-- - 2008-04-20 22:10:33.970635 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - closed issue with disposition fixed
- - ""
diff --git a/bugs/issue-8aa7ea95f066fd0668452093b85903bd142905c9.yaml b/bugs/issue-8aa7ea95f066fd0668452093b85903bd142905c9.yaml
deleted file mode 100644
index 59c41c0..0000000
--- a/bugs/issue-8aa7ea95f066fd0668452093b85903bd142905c9.yaml
+++ /dev/null
@@ -1,26 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: "'q' asks and 'Q' quits without asking"
-desc: ""
-type: :feature
-component: curses
-release: "0.6"
-reporter: William Morgan <wmorgan-ditz at masanjin.net>
-status: :closed
-disposition: :fixed
-creation_time: 2008-05-20 03:25:17.109472 Z
-references: []
-
-id: 8aa7ea95f066fd0668452093b85903bd142905c9
-log_events:
-- - 2008-05-20 03:25:19.265580 Z
- - William Morgan <wmorgan-ditz at masanjin.net>
- - created
- - ""
-- - 2008-05-25 02:13:32.219668 Z
- - William Morgan <wmorgan-ditz at masanjin.net>
- - closed issue with disposition fixed
- - fixed in master
-- - 2008-05-25 02:13:40.344453 Z
- - William Morgan <wmorgan-ditz at masanjin.net>
- - assigned to release 0.6 from unassigned
- - ""
diff --git a/bugs/issue-8c0e627c500f679badca28f60ba76998fd65d46a.yaml b/bugs/issue-8c0e627c500f679badca28f60ba76998fd65d46a.yaml
deleted file mode 100644
index f31067e..0000000
--- a/bugs/issue-8c0e627c500f679badca28f60ba76998fd65d46a.yaml
+++ /dev/null
@@ -1,26 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: workaround for rubymail quoting bug in pgp MIME header
-desc: gpg MIME headers are being double-quoted due to a rubymail bug
-type: :bugfix
-component: sup
-release: "0.5"
-reporter: Jan Spakula <teatime at gmx.com>
-status: :closed
-disposition: fixed
-creation_time: 2008-03-07 03:35:36.731751 Z
-references:
-- http://rubyforge.org/pipermail/sup-talk/2008-February/001222.html
-id: 8c0e627c500f679badca28f60ba76998fd65d46a
-log_events:
-- - 2008-03-07 03:35:36.731787 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-03-07 03:36:24.938159 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - changed status from unstarted to fixed
- - ""
-- - 2008-03-08 22:22:59.515414 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - added reference 1
- - ""
diff --git a/bugs/issue-8e825caee33a6ac144580bf44d0d3060ad162394.yaml b/bugs/issue-8e825caee33a6ac144580bf44d0d3060ad162394.yaml
deleted file mode 100644
index 77a3ce8..0000000
--- a/bugs/issue-8e825caee33a6ac144580bf44d0d3060ad162394.yaml
+++ /dev/null
@@ -1,21 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: From lines detected over-aggressively
-desc: |-
- mbox lines starting with "From " should only be considered new-message
- delimiters if they have a valid email address, date, etc.
-type: :bugfix
-component: mbox
-release:
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :unstarted
-disposition:
-creation_time: 2008-11-10 03:56:07.002467 Z
-references: []
-
-id: 8e825caee33a6ac144580bf44d0d3060ad162394
-log_events:
-- - 2008-11-10 03:56:07.002940 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-git_branch:
diff --git a/bugs/issue-91e1549102c0bfa2c201476d9618f7d234d1a626.yaml b/bugs/issue-91e1549102c0bfa2c201476d9618f7d234d1a626.yaml
deleted file mode 100644
index ae6d02a..0000000
--- a/bugs/issue-91e1549102c0bfa2c201476d9618f7d234d1a626.yaml
+++ /dev/null
@@ -1,22 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: gpg should use exact match for email address
-desc: otherwise substring matches can select the wrong key
-type: :bugfix
-component: crypto
-release: "0.6"
-reporter: William Morgan <wmorgan-ditz at masanjin.net>
-status: :closed
-disposition: :fixed
-creation_time: 2008-05-25 02:15:58.006265 Z
-references: []
-
-id: 91e1549102c0bfa2c201476d9618f7d234d1a626
-log_events:
-- - 2008-05-25 02:15:59.100203 Z
- - William Morgan <wmorgan-ditz at masanjin.net>
- - created
- - ""
-- - 2008-05-25 02:16:07.730483 Z
- - William Morgan <wmorgan-ditz at masanjin.net>
- - closed issue with disposition fixed
- - fixed in master
diff --git a/bugs/issue-9f7e28de46d74f7f1e445ae75ea4e230c7473374.yaml b/bugs/issue-9f7e28de46d74f7f1e445ae75ea4e230c7473374.yaml
deleted file mode 100644
index e711eea..0000000
--- a/bugs/issue-9f7e28de46d74f7f1e445ae75ea4e230c7473374.yaml
+++ /dev/null
@@ -1,22 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: threads with unsent draft messages are now shown in red
-desc: ""
-type: :feature
-component: curses
-release: "0.5"
-reporter: Nicolas Pouillard <nicolas.pouillard at gmail.com>
-status: :closed
-disposition: fixed
-creation_time: 2008-03-07 04:30:53.909487 Z
-references: []
-
-id: 9f7e28de46d74f7f1e445ae75ea4e230c7473374
-log_events:
-- - 2008-03-07 04:30:53.909522 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-03-07 04:31:03.704713 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - changed status from unstarted to fixed
- - ""
diff --git a/bugs/issue-a1a3427de5e8d4f74c0620f99e97ed92d21e924c.yaml b/bugs/issue-a1a3427de5e8d4f74c0620f99e97ed92d21e924c.yaml
deleted file mode 100644
index 7c30f15..0000000
--- a/bugs/issue-a1a3427de5e8d4f74c0620f99e97ed92d21e924c.yaml
+++ /dev/null
@@ -1,30 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: sup-config name guessing logic can generate nil and crash
-desc: ""
-type: :bugfix
-component: sup
-release: "0.5"
-reporter: Jean-Hadrien CHABRAN <jh at chabran.fr>
-status: :closed
-disposition: fixed
-creation_time: 2008-03-09 17:45:46.095924 Z
-references:
-- http://rubyforge.org/pipermail/sup-talk/2008-March/001260.html
-id: a1a3427de5e8d4f74c0620f99e97ed92d21e924c
-log_events:
-- - 2008-03-09 17:45:46.095961 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-03-09 17:46:21.702965 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - added reference 1
- - ""
-- - 2008-03-09 17:46:45.446763 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - changed reporter
- - ""
-- - 2008-03-09 17:47:06.797832 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - changed status from unstarted to fixed
- - fixed in master
diff --git a/bugs/issue-a1e622dbae0e1841b4d9a376d419aed1d91460e0.yaml b/bugs/issue-a1e622dbae0e1841b4d9a376d419aed1d91460e0.yaml
deleted file mode 100644
index aa6e31f..0000000
--- a/bugs/issue-a1e622dbae0e1841b4d9a376d419aed1d91460e0.yaml
+++ /dev/null
@@ -1,26 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: non-ascii characters in message id need to be normalized
-desc: apparently this happens. in spam email, of course.
-type: :bugfix
-component: sup
-release: "0.6"
-reporter: William Morgan <wmorgan-ditz at masanjin.net>
-status: :closed
-disposition: :fixed
-creation_time: 2008-05-11 23:04:01.078305 Z
-references: []
-
-id: a1e622dbae0e1841b4d9a376d419aed1d91460e0
-log_events:
-- - 2008-05-11 23:04:01.677838 Z
- - William Morgan <wmorgan-ditz at masanjin.net>
- - created
- - ""
-- - 2008-05-11 23:21:40.281018 Z
- - William Morgan <wmorgan-ditz at masanjin.net>
- - changed status from unstarted to in_progress
- - branch non-ascii-message-id, merged into next
-- - 2008-06-19 18:09:04.143173 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - closed issue with disposition fixed
- - merged into master
diff --git a/bugs/issue-a533480a30a18c3e823dbe20b759e1dcb32ca2b9.yaml b/bugs/issue-a533480a30a18c3e823dbe20b759e1dcb32ca2b9.yaml
deleted file mode 100644
index 2021c6f..0000000
--- a/bugs/issue-a533480a30a18c3e823dbe20b759e1dcb32ca2b9.yaml
+++ /dev/null
@@ -1,26 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: forward/reply without saving in the editor drops all newlines
-desc: ""
-type: :bugfix
-component: sup
-release: "0.6"
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :closed
-disposition: :fixed
-creation_time: 2008-04-23 01:31:16.072859 Z
-references: []
-
-id: a533480a30a18c3e823dbe20b759e1dcb32ca2b9
-log_events:
-- - 2008-04-23 01:31:16.640737 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-04-23 01:39:10.304801 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - changed status from unstarted to in_progress
- - branch unedited-newlines, merged into next
-- - 2008-05-25 04:22:44.178693 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - closed issue with disposition fixed
- - merged into master
diff --git a/bugs/issue-a68148169baa3838051f4bdb4c175e11cbf7f143.yaml b/bugs/issue-a68148169baa3838051f4bdb4c175e11cbf7f143.yaml
deleted file mode 100644
index e4ce8bf..0000000
--- a/bugs/issue-a68148169baa3838051f4bdb4c175e11cbf7f143.yaml
+++ /dev/null
@@ -1,22 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: all ferret access needs to be wrapped in a mutex
-desc: |-
- concurrent access breaks things. at least, that's what I *think* is
- going on here.
-
- http://rubyforge.org/pipermail/sup-talk/2008-April/001333.html
-type: :bugfix
-component: indexing
-release:
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :unstarted
-disposition:
-creation_time: 2008-05-01 01:09:39.706808 Z
-references: []
-
-id: a68148169baa3838051f4bdb4c175e11cbf7f143
-log_events:
-- - 2008-05-01 01:09:40.747646 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
diff --git a/bugs/issue-aae5ae6378afa9bd2a8e1b15d28ba7ccef867791.yaml b/bugs/issue-aae5ae6378afa9bd2a8e1b15d28ba7ccef867791.yaml
deleted file mode 100644
index 83cc00a..0000000
--- a/bugs/issue-aae5ae6378afa9bd2a8e1b15d28ba7ccef867791.yaml
+++ /dev/null
@@ -1,27 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: remove email->name mapping
-desc: it doesn't work and wouldn't buy that much even if it did
-type: :bugfix
-component: sup
-release:
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :closed
-disposition: :fixed
-creation_time: 2008-05-19 23:42:25.910550 Z
-references: []
-
-id: aae5ae6378afa9bd2a8e1b15d28ba7ccef867791
-log_events:
-- - 2008-05-19 23:42:26.490587 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-07-31 00:54:39.921596 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - unassigned from release 0.6
- - ""
-- - 2008-11-22 16:31:27.450146 Z
- - Nicolas Pouillard <nicolas.pouillard at gmail.com>
- - closed with disposition fixed
- - This mapping and the PersonManager are now removed.
-git_branch:
diff --git a/bugs/issue-ad82aa00f4064fc7e1332cee0dae2c2ae95bb217.yaml b/bugs/issue-ad82aa00f4064fc7e1332cee0dae2c2ae95bb217.yaml
deleted file mode 100644
index 1802a8a..0000000
--- a/bugs/issue-ad82aa00f4064fc7e1332cee0dae2c2ae95bb217.yaml
+++ /dev/null
@@ -1,26 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: add more vi keys
-desc: ""
-type: :feature
-component: curses
-release: "0.6"
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :closed
-disposition: :fixed
-creation_time: 2008-04-26 22:23:43.675951 Z
-references: []
-
-id: ad82aa00f4064fc7e1332cee0dae2c2ae95bb217
-log_events:
-- - 2008-04-26 22:23:44.484689 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-04-26 22:24:00.893661 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - changed status from unstarted to in_progress
- - branch more-vi-keys. in next.
-- - 2008-05-25 04:12:57.577438 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - closed issue with disposition fixed
- - merged into master
diff --git a/bugs/issue-b1f1579fd8350d8add15c5cb588169acfdc5ea24.yaml b/bugs/issue-b1f1579fd8350d8add15c5cb588169acfdc5ea24.yaml
deleted file mode 100644
index 138772c..0000000
--- a/bugs/issue-b1f1579fd8350d8add15c5cb588169acfdc5ea24.yaml
+++ /dev/null
@@ -1,29 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: offer to delete lockfile after trying to kill owner process
-desc: |-
- often the lockfile points to a dead process, so repeatedly offering to kill
- it isn't all that useful.
-type: :feature
-component: sup
-release:
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :unstarted
-disposition:
-creation_time: 2008-04-14 01:25:59.111165 Z
-references: []
-
-id: b1f1579fd8350d8add15c5cb588169acfdc5ea24
-log_events:
-- - 2008-04-14 01:26:00.135062 Z
- - William Morgan <w at adap.tv>
- - created
- - ""
-- - 2008-05-19 23:40:28.102694 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - assigned to release 0.6 from unassigned
- - ""
-- - 2008-07-31 00:54:38.573917 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - unassigned from release 0.6
- - ""
-git_branch:
diff --git a/bugs/issue-b80aa39ef3b8d33bd57e4988c55d89c7c0df5c96.yaml b/bugs/issue-b80aa39ef3b8d33bd57e4988c55d89c7c0df5c96.yaml
deleted file mode 100644
index f293a90..0000000
--- a/bugs/issue-b80aa39ef3b8d33bd57e4988c55d89c7c0df5c96.yaml
+++ /dev/null
@@ -1,24 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: spurious messages appearing in inbox
-desc: |-
- this is because ThreadSet is claiming that non-relevant videos are actually
- relevant
-type: :bugfix
-component: indexing
-release: "0.5"
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :closed
-disposition: fixed
-creation_time: 2008-03-07 03:55:29.353904 Z
-references: []
-
-id: b80aa39ef3b8d33bd57e4988c55d89c7c0df5c96
-log_events:
-- - 2008-03-07 03:55:29.353940 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-03-07 03:55:34.495965 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - changed status from unstarted to fixed
- - ""
diff --git a/bugs/issue-bc03bc702f41e6a9687b52d3e32db29132c0f65a.yaml b/bugs/issue-bc03bc702f41e6a9687b52d3e32db29132c0f65a.yaml
deleted file mode 100644
index 2572ce4..0000000
--- a/bugs/issue-bc03bc702f41e6a9687b52d3e32db29132c0f65a.yaml
+++ /dev/null
@@ -1,25 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: add a mark-as-spam hook
-desc: |-
- a simple hook that triggers when a message is marked as spam, so that
- users can trigger additional stuff.
-type: :feature
-component: hooks
-release: "0.6"
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :closed
-disposition: :fixed
-creation_time: 2008-07-31 00:50:51.282526 Z
-references: []
-
-id: bc03bc702f41e6a9687b52d3e32db29132c0f65a
-log_events:
-- - 2008-07-31 00:50:52.114135 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-07-31 00:51:10.671706 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - closed with disposition fixed
- - branch mark-as-spam-hook, merged into master
-git_branch:
diff --git a/bugs/issue-bdd4415a9d4c8fd3602500111bf9268aa7c7c6a4.yaml b/bugs/issue-bdd4415a9d4c8fd3602500111bf9268aa7c7c6a4.yaml
deleted file mode 100644
index b8fc2ad..0000000
--- a/bugs/issue-bdd4415a9d4c8fd3602500111bf9268aa7c7c6a4.yaml
+++ /dev/null
@@ -1,27 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: configurable colors
-desc: All colors should be user-configurable.
-type: :feature
-component: curses
-release: "0.6"
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :closed
-disposition: :fixed
-creation_time: 2008-06-04 02:27:15.458560 Z
-references: []
-
-id: bdd4415a9d4c8fd3602500111bf9268aa7c7c6a4
-log_events:
-- - 2008-06-04 02:27:16.721829 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-06-04 02:27:27.256556 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - changed status from unstarted to in_progress
- - branch 'colors', merged into next.
-- - 2008-07-30 23:41:33.553377 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - closed with disposition fixed
- - merged into master
-git_branch: color
diff --git a/bugs/issue-bff2527210b3aacae2f74029e5856fed82f1689c.yaml b/bugs/issue-bff2527210b3aacae2f74029e5856fed82f1689c.yaml
deleted file mode 100644
index 802f1b0..0000000
--- a/bugs/issue-bff2527210b3aacae2f74029e5856fed82f1689c.yaml
+++ /dev/null
@@ -1,33 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: wide characters break screen clearing
-desc: |-
- if you look at a message with wide characters using the new wide-char-aware
- ncurses library, there will often be snippets of the previous screen
- immediately to the right of the end of the lines that have wide characters
- in them.
-
- some kind of line length issue maybe? (because everything is done in terms
- of bytes still. thanks ruby!)
-type: :bugfix
-component: curses
-release:
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :closed
-disposition: :wontfix
-creation_time: 2008-04-26 21:35:31.519359 Z
-references: []
-
-id: bff2527210b3aacae2f74029e5856fed82f1689c
-log_events:
-- - 2008-04-26 21:35:32.384516 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-04-26 21:44:04.152193 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - unassigned from release 0.6
- - depends on {issue 23658477a445c2e61405fecb4cb641a2298caba6} and that's not necessarily destined for 0.6 yet.
-- - 2008-04-28 02:36:51.698817 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - closed issue with disposition wontfix
- - dup of {issue c48f7fc58bba0b38ff6ae14cca01b08a5a7a6c33}. you'd think i'd'a remembered.
diff --git a/bugs/issue-c48f7fc58bba0b38ff6ae14cca01b08a5a7a6c33.yaml b/bugs/issue-c48f7fc58bba0b38ff6ae14cca01b08a5a7a6c33.yaml
deleted file mode 100644
index b15f04a..0000000
--- a/bugs/issue-c48f7fc58bba0b38ff6ae14cca01b08a5a7a6c33.yaml
+++ /dev/null
@@ -1,21 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: wide characters screw up line cursor display
-desc: |-
- in a message with wide characters, the screen isn't cleared properly, or
- something. probably due to the # of characters for something being calculated
- wrong (bytes instead of chars).
-type: :bugfix
-component: curses
-release:
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :unstarted
-disposition:
-creation_time: 2008-04-23 02:05:47.272610 Z
-references: []
-
-id: c48f7fc58bba0b38ff6ae14cca01b08a5a7a6c33
-log_events:
-- - 2008-04-23 02:05:49.360399 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
diff --git a/bugs/issue-c52f9762bc24a8f45863eb2e7beefa4201db34e8.yaml b/bugs/issue-c52f9762bc24a8f45863eb2e7beefa4201db34e8.yaml
deleted file mode 100644
index b5b573f..0000000
--- a/bugs/issue-c52f9762bc24a8f45863eb2e7beefa4201db34e8.yaml
+++ /dev/null
@@ -1,22 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: add a --compose option to spawn a compose-message buffer on startup
-desc: ""
-type: :feature
-component: sup
-release: "0.5"
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :closed
-disposition: fixed
-creation_time: 2008-03-07 04:28:32.198492 Z
-references: []
-
-id: c52f9762bc24a8f45863eb2e7beefa4201db34e8
-log_events:
-- - 2008-03-07 04:28:32.198527 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-03-07 04:28:37.471873 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - changed status from unstarted to fixed
- - ""
diff --git a/bugs/issue-c660ddfa9d633501140dd199bdfd7cd9fed5df0b.yaml b/bugs/issue-c660ddfa9d633501140dd199bdfd7cd9fed5df0b.yaml
deleted file mode 100644
index 56c68c5..0000000
--- a/bugs/issue-c660ddfa9d633501140dd199bdfd7cd9fed5df0b.yaml
+++ /dev/null
@@ -1,22 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: ctrl-g should interrupt thread search operation
-desc: ""
-type: :feature
-component: sup
-release: "0.5"
-reporter: Marcus Williams <marcus-sup at bar-coded.net>
-status: :closed
-disposition: fixed
-creation_time: 2008-03-07 04:15:47.155992 Z
-references: []
-
-id: c660ddfa9d633501140dd199bdfd7cd9fed5df0b
-log_events:
-- - 2008-03-07 04:15:47.156031 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-03-07 04:15:52.274258 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - changed status from unstarted to fixed
- - ""
diff --git a/bugs/issue-cef3096582de268c050f78223eb6a22ac2599606.yaml b/bugs/issue-cef3096582de268c050f78223eb6a22ac2599606.yaml
deleted file mode 100644
index 1881fc4..0000000
--- a/bugs/issue-cef3096582de268c050f78223eb6a22ac2599606.yaml
+++ /dev/null
@@ -1,31 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: ruby 1.8.7 breaks sup in weird ways
-desc: |-
- --- ArgumentError from thread: main
- wrong number of arguments (2 for 1)
- /home/benjamin/projects/sup/lib/sup/index.rb:422:in `respond_to?'
- /home/benjamin/projects/sup/lib/sup/index.rb:422:in `flatten'
- /home/benjamin/projects/sup/lib/sup/index.rb:422:in `load_sources'
- /home/benjamin/projects/sup/lib/sup/index.rb:108:in `load'
- /home/benjamin/projects/sup/lib/sup/util.rb:497:in `send'
- /home/benjamin/projects/sup/lib/sup/util.rb:497:in `method_missing'
- /home/benjamin/projects/sup/bin/sup:122
-type: :bugfix
-component: sup
-release: "0.6"
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :closed
-disposition: :fixed
-creation_time: 2008-06-04 17:39:39.013305 Z
-references: []
-
-id: cef3096582de268c050f78223eb6a22ac2599606
-log_events:
-- - 2008-06-04 17:39:39.670176 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-06-19 17:57:46.648682 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - closed issue with disposition fixed
- - fixed directly in master
diff --git a/bugs/issue-cf09ec6ec7c35d7d8c002b0521f97b6e94dc9b3e.yaml b/bugs/issue-cf09ec6ec7c35d7d8c002b0521f97b6e94dc9b3e.yaml
deleted file mode 100644
index bbba370..0000000
--- a/bugs/issue-cf09ec6ec7c35d7d8c002b0521f97b6e94dc9b3e.yaml
+++ /dev/null
@@ -1,26 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: invalid gecos can cause sup-config to crash
-desc: ""
-type: :bugfix
-component: sup
-release: "0.5"
-reporter: Jean-Hadrien CHABRAN <jh at chabran.fr>
-status: :closed
-disposition: fixed
-creation_time: 2008-03-14 18:54:32.560987 Z
-references:
-- http://rubyforge.org/pipermail/sup-talk/2008-March/001260.html
-id: cf09ec6ec7c35d7d8c002b0521f97b6e94dc9b3e
-log_events:
-- - 2008-03-14 18:54:32.561241 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-03-14 18:54:52.486259 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - added reference 1
- - ""
-- - 2008-03-14 18:55:10.323790 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - changed status from unstarted to fixed
- - ""
diff --git a/bugs/issue-cfbfc65dc90280fa5ecc63094af01d2a47ff0c6e.yaml b/bugs/issue-cfbfc65dc90280fa5ecc63094af01d2a47ff0c6e.yaml
deleted file mode 100644
index 5db69fa..0000000
--- a/bugs/issue-cfbfc65dc90280fa5ecc63094af01d2a47ff0c6e.yaml
+++ /dev/null
@@ -1,22 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: exception thrown when a forwarded attachment is not a known mime type
-desc: a minor typo
-type: :bugfix
-component: sup
-release: "0.6"
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :closed
-disposition: :fixed
-creation_time: 2008-04-23 01:23:06.368926 Z
-references: []
-
-id: cfbfc65dc90280fa5ecc63094af01d2a47ff0c6e
-log_events:
-- - 2008-04-23 01:23:07.968757 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-04-23 01:23:14.995087 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - closed issue with disposition fixed
- - fixed in master
diff --git a/bugs/issue-d131464e921aefc35571c119aac4d9f1decdebae.yaml b/bugs/issue-d131464e921aefc35571c119aac4d9f1decdebae.yaml
deleted file mode 100644
index d49dcaf..0000000
--- a/bugs/issue-d131464e921aefc35571c119aac4d9f1decdebae.yaml
+++ /dev/null
@@ -1,30 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: blank message-id headers are treated as valid and crash indexing
-desc: |-
- specifically, they trigger the "just added message to index" debug exception
- because the id consists of nothing but spaces.
-
- header parsing needs to be fixed to not grab headers that are empty.
-type: :bugfix
-component: mbox
-release: "0.6"
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :closed
-disposition: :fixed
-creation_time: 2008-04-26 21:07:33.463910 Z
-references: []
-
-id: d131464e921aefc35571c119aac4d9f1decdebae
-log_events:
-- - 2008-04-26 21:07:34.221325 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-04-26 21:41:55.731750 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - changed status from unstarted to in_progress
- - branch header-parsing-fix. merged into next.
-- - 2008-05-25 04:19:15.986573 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - closed issue with disposition fixed
- - merged into master
diff --git a/bugs/issue-d994a360c9cb2a6e12a734962a39ffbc6486a725.yaml b/bugs/issue-d994a360c9cb2a6e12a734962a39ffbc6486a725.yaml
deleted file mode 100644
index 1fbb23a..0000000
--- a/bugs/issue-d994a360c9cb2a6e12a734962a39ffbc6486a725.yaml
+++ /dev/null
@@ -1,34 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: flags need a separate backup outside of the ferret index
-desc: |
- Ferret still occasionally barfs and corrupts its own index. Currently all
- user state is stored in the index and only in the index, so that means
- you lose big-time if that happens. You can sup-dump your labels, but really,
- how often are you going to do that.
- Sup should maintain a separate backup of all labels in some fast on-disk
- hashtable (message ids to label sets). Bdb comes to mind.
-
-type: :feature
-component: sup
-release:
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :unstarted
-disposition:
-creation_time: 2008-03-07 04:22:50.236621 Z
-references: []
-
-id: d994a360c9cb2a6e12a734962a39ffbc6486a725
-log_events:
-- - 2008-03-07 04:22:50.236657 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-04-20 21:44:51.655741 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - assigned to release 0.6 from 0.5
- - ""
-- - 2008-07-31 00:54:37.881077 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - unassigned from release 0.6
- - ""
-git_branch:
diff --git a/bugs/issue-d9e6be1b524c6c0a5c31c9c468bda170c2a8cb58.yaml b/bugs/issue-d9e6be1b524c6c0a5c31c9c468bda170c2a8cb58.yaml
deleted file mode 100644
index 81bb3a8..0000000
--- a/bugs/issue-d9e6be1b524c6c0a5c31c9c468bda170c2a8cb58.yaml
+++ /dev/null
@@ -1,33 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: temp files disappear on sup crash
-desc: |-
- because we're using the Tempfile library, Sup crashes mean that tempfiles
- containing message bodies are lost. Sup needs to manage its own tempfiles.
-type: :bugfix
-component: sup
-release:
-reporter: "Marko Myllym\xC3\xA4ki <marko.myllymaki at iki.fi>"
-status: :unstarted
-disposition:
-creation_time: 2008-03-07 04:59:51.404664 Z
-references:
-- http://rubyforge.org/pipermail/sup-talk/2008-February/001174.html
-id: d9e6be1b524c6c0a5c31c9c468bda170c2a8cb58
-log_events:
-- - 2008-03-07 04:59:51.404701 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-03-11 06:20:47.540967 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - added reference 1
- - ""
-- - 2008-04-20 21:45:00.615452 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - assigned to release 0.6 from 0.5
- - ""
-- - 2008-07-31 00:54:38.222035 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - unassigned from release 0.6
- - ""
-git_branch:
diff --git a/bugs/issue-e24df153080c6e7a16335018b04d70d9381258b8.yaml b/bugs/issue-e24df153080c6e7a16335018b04d70d9381258b8.yaml
deleted file mode 100644
index 006e2b1..0000000
--- a/bugs/issue-e24df153080c6e7a16335018b04d70d9381258b8.yaml
+++ /dev/null
@@ -1,20 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: Pulling new threads should not shift the cursor.
-desc: |-
- In thread-view-index, the selected thread should not change due to additions
- of new threads.
-type: :bugfix
-component: curses
-release:
-reporter: Nicolas Pouillard <nicolas.pouillard at gmail.com>
-status: :unstarted
-disposition:
-creation_time: 2008-04-21 08:26:00.191881 Z
-references: []
-
-id: e24df153080c6e7a16335018b04d70d9381258b8
-log_events:
-- - 2008-04-21 08:26:03.807376 Z
- - Nicolas Pouillard <nicolas.pouillard at gmail.com>
- - created
- - ""
diff --git a/bugs/issue-e43b18777ea3aef3566bd80acd126e9ef8a5883a.yaml b/bugs/issue-e43b18777ea3aef3566bd80acd126e9ef8a5883a.yaml
deleted file mode 100644
index 0216c8b..0000000
--- a/bugs/issue-e43b18777ea3aef3566bd80acd126e9ef8a5883a.yaml
+++ /dev/null
@@ -1,34 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: long message ids (>255 characters) never get matched by ferret
-desc: |
- this is a ferret bug.
- Apparently, constructing a TermQuery object with a field value of more than
- 255 characters never successfully matches.
-
- This is not a good long-term solution. A good one would be to take the SHA1
- of every message id instead. That will require an index rebuild, so I will
- save that patch until later.
-
-type: :bugfix
-component: indexing
-release: "0.5"
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :closed
-disposition: :fixed
-creation_time: 2008-03-07 03:40:55.475449 Z
-references: []
-
-id: e43b18777ea3aef3566bd80acd126e9ef8a5883a
-log_events:
-- - 2008-03-07 03:40:55.475485 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-03-07 03:50:18.590242 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - changed status from unstarted to in_progress
- - ""
-- - 2008-04-20 22:10:44.010446 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - closed issue with disposition fixed
- - ""
diff --git a/bugs/issue-e7739718b4dbf49bbd3dd47133affbf7cb1e2361.yaml b/bugs/issue-e7739718b4dbf49bbd3dd47133affbf7cb1e2361.yaml
deleted file mode 100644
index 5e471f9..0000000
--- a/bugs/issue-e7739718b4dbf49bbd3dd47133affbf7cb1e2361.yaml
+++ /dev/null
@@ -1,24 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: "maildir speedup: don't scan directory except when polling"
-desc: |-
- lots of useless scanning. removing it should make things faster for large
- maildirs.
-type: :feature
-component: maildir
-release: "0.5"
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :closed
-disposition: fixed
-creation_time: 2008-03-07 04:20:32.735159 Z
-references: []
-
-id: e7739718b4dbf49bbd3dd47133affbf7cb1e2361
-log_events:
-- - 2008-03-07 04:20:32.735194 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-03-07 04:20:37.257919 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - changed status from unstarted to fixed
- - ""
diff --git a/bugs/issue-e9c2f66a7ff4fb4525c2719e77ac8eedf3835dfd.yaml b/bugs/issue-e9c2f66a7ff4fb4525c2719e77ac8eedf3835dfd.yaml
deleted file mode 100644
index f0ffc9d..0000000
--- a/bugs/issue-e9c2f66a7ff4fb4525c2719e77ac8eedf3835dfd.yaml
+++ /dev/null
@@ -1,20 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: force hook reload feature
-desc: |-
- would be nice for hook debugging. otherwise you have to restart sup
- each time.
-type: :feature
-component: hooks
-release:
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :unstarted
-disposition:
-creation_time: 2008-05-19 23:19:38.202269 Z
-references: []
-
-id: e9c2f66a7ff4fb4525c2719e77ac8eedf3835dfd
-log_events:
-- - 2008-05-19 23:19:38.757600 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
diff --git a/bugs/issue-f767a9d2071da7b0f66698ce74e642bf347be96b.yaml b/bugs/issue-f767a9d2071da7b0f66698ce74e642bf347be96b.yaml
deleted file mode 100644
index ce4ef23..0000000
--- a/bugs/issue-f767a9d2071da7b0f66698ce74e642bf347be96b.yaml
+++ /dev/null
@@ -1,21 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: mbox file handle closing
-desc: |-
- currently an open file handle is maintained for every single mbox folder.
- (well, every one that's accessed by polling or by opening a message therefrom.)
- that is plum crazy.
-type: :feature
-component: mbox
-release:
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :unstarted
-disposition:
-creation_time: 2008-03-07 04:27:35.146273 Z
-references: []
-
-id: f767a9d2071da7b0f66698ce74e642bf347be96b
-log_events:
-- - 2008-03-07 04:27:35.146307 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
diff --git a/bugs/issue-fd7c7a7d7caf41ff20e7d10ca3f074fc02c14a5b.yaml b/bugs/issue-fd7c7a7d7caf41ff20e7d10ca3f074fc02c14a5b.yaml
deleted file mode 100644
index f4d38d9..0000000
--- a/bugs/issue-fd7c7a7d7caf41ff20e7d10ca3f074fc02c14a5b.yaml
+++ /dev/null
@@ -1,30 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: thread joining doesn't always work
-desc: |
- sometimes it works, and sometimes it doesn't, and i haven't found the
- pattern yet.
-
- also, UpdateManager isn't being called properly (maybe even needs a
- custom event). e.g. if you join in search-results-mode, the results
- aren't joined in inbox-mode.
-
-type: :bugfix
-component: indexing
-release:
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :unstarted
-disposition:
-creation_time: 2008-04-29 00:09:38.366801 Z
-references: []
-
-id: fd7c7a7d7caf41ff20e7d10ca3f074fc02c14a5b
-log_events:
-- - 2008-04-29 00:09:38.998592 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-07-31 00:54:39.251862 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - unassigned from release 0.6
- - ""
-git_branch:
diff --git a/bugs/issue-fdfc906e8f4f6eb10f1ebdf39c416415d9ab6af9.yaml b/bugs/issue-fdfc906e8f4f6eb10f1ebdf39c416415d9ab6af9.yaml
deleted file mode 100644
index 99cbd3e..0000000
--- a/bugs/issue-fdfc906e8f4f6eb10f1ebdf39c416415d9ab6af9.yaml
+++ /dev/null
@@ -1,26 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/issue
-title: archive-and-mark-read command in inbox-mode
-desc: ""
-type: :feature
-component: curses
-release: "0.6"
-reporter: William Morgan <wmorgan-sup at masanjin.net>
-status: :closed
-disposition: :fixed
-creation_time: 2008-04-26 23:32:53.791207 Z
-references: []
-
-id: fdfc906e8f4f6eb10f1ebdf39c416415d9ab6af9
-log_events:
-- - 2008-04-26 23:32:57.083084 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
-- - 2008-04-26 23:33:12.980220 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - changed status from unstarted to in_progress
- - branch read-and-archive. in next.
-- - 2008-05-25 04:14:48.307896 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - closed issue with disposition fixed
- - merged into master
diff --git a/bugs/project.yaml b/bugs/project.yaml
deleted file mode 100644
index f6afd47..0000000
--- a/bugs/project.yaml
+++ /dev/null
@@ -1,53 +0,0 @@
---- !ditz.rubyforge.org,2008-03-06/project
-name: sup
-version: 0.0.1
-components:
-- !ditz.rubyforge.org,2008-03-06/component
- name: sup
-- !ditz.rubyforge.org,2008-03-06/component
- name: threading
-- !ditz.rubyforge.org,2008-03-06/component
- name: indexing
-- !ditz.rubyforge.org,2008-03-06/component
- name: curses
-- !ditz.rubyforge.org,2008-03-06/component
- name: hooks
-- !ditz.rubyforge.org,2008-03-06/component
- name: sup-sync
-- !ditz.rubyforge.org,2008-03-06/component
- name: sup-sync-back
-- !ditz.rubyforge.org,2008-03-06/component
- name: maildir
-- !ditz.rubyforge.org,2008-03-06/component
- name: imap
-- !ditz.rubyforge.org,2008-03-06/component
- name: mbox
-- !ditz.rubyforge.org,2008-03-06/component
- name: crypto
-releases:
-- !ditz.rubyforge.org,2008-03-06/release
- name: "0.5"
- status: :released
- release_time: 2008-04-22 15:55:47.323776 Z
- log_events:
- - - 2008-03-07 02:37:54.903172 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
- - - 2008-04-22 15:55:47.323829 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - released
- - ""
-- !ditz.rubyforge.org,2008-03-06/release
- name: "0.6"
- status: :released
- release_time: 2008-08-04 02:48:44.154676 Z
- log_events:
- - - 2008-04-20 21:17:04.443432 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - created
- - ""
- - - 2008-08-04 02:48:44.154704 Z
- - William Morgan <wmorgan-sup at masanjin.net>
- - released
- - ""
diff --git a/contrib/colorpicker.rb b/contrib/colorpicker.rb
index c981a23..947b3d5 100644
--- a/contrib/colorpicker.rb
+++ b/contrib/colorpicker.rb
@@ -1,10 +1,6 @@
require 'rubygems'
-begin
- require 'ncursesw'
-rescue LoadError
- require 'ncurses'
-end
+require 'ncursesw'
Ncurses.initscr
Ncurses.noecho
diff --git a/doc/FAQ.txt b/doc/FAQ.txt
index 9a24d7f..be19399 100644
--- a/doc/FAQ.txt
+++ b/doc/FAQ.txt
@@ -21,8 +21,8 @@ A: I hate ads, I hate using a mouse, and I hate non-programmability and
Q: Why the console?
A: Because a keystroke is worth a hundred mouse clicks, as any Unix
- user knows. Because you don't need web browser. Because you get
- instantaneous response and a simple interface.
+ user knows. Because you don't need a web browser. Because you get
+ an instantaneous response and a simple interface.
Q: How does Sup deal with spam?
A: You can manually mark messages as spam, which prevents them from
diff --git a/doc/NewUserGuide.txt b/doc/NewUserGuide.txt
deleted file mode 100644
index c071deb..0000000
--- a/doc/NewUserGuide.txt
+++ /dev/null
@@ -1,258 +0,0 @@
-Welcome to Sup! Here's how to get started.
-
-First, try running `sup`. Since this is your first time, you'll be
-confronted with a mostly blank screen, and a notice at the bottom that
-you have no new messages. That's because Sup doesn't hasn't loaded
-anything into its index yet, and has no idea where to look for them
-anyways.
-
-If you want to play around a little at this point, you can press 'b'
-to cycle between buffers, ';' to get a list of the open buffers, and
-'x' to kill a buffer. There's probably not too much interesting there,
-but there's a log buffer with some cryptic messages. You can also
-press '?' at any point to get a list of keyboard commands, but in the
-absence of any email, these will be mostly useless. When you get
-bored, press 'q' to quit.
-
-To use Sup for email, we need to load messages into the index. The
-index is where Sup stores all message state (e.g. read or unread, any
-message labels), and all information necessary for searching and for
-threading messages. Sup only knows about messages in its index.
-
-We can add messages to the index by telling Sup about the "source"
-where the messages reside. Sources are things like mbox folders, and
-maildir directories. Sup doesn't duplicate the actual message content
-in the index; it only stores whatever information is necessary for
-searching, threading and labelling. So when you search for messages or
-view your inbox, Sup talks only to the index (stored locally on
-disk). When you view a thread, Sup requests the full content of all
-the messages from the source.
-
-The easiest way to set up all your sources is to run `sup-config`.
-This will interactively walk you through some basic configuration,
-prompt you for all the sources you need, and optionally import
-messages from them. Sup-config uses two other tools, sup-add and
-sup-sync, to load messages into the index. In the future you may make
-use of these tools directly (see below).
-
-Once you've run sup-config, you're ready to run `sup`. You should see
-the most recent unarchived messages appear in your inbox.
-Congratulations, you've got Sup working!
-
-If you're coming from the world of traditional MUAs, there are a
-couple differences you should be aware of at this point. First, Sup
-has no folders. Instead, you organize and find messages by a
-combination of search and labels (known as "tags" everywhere else in
-the world). Search and labels are an integral part of Sup because in
-Sup, rather than viewing the contents of a folder, you view the
-results of a search. I mentioned above that your inbox is, by
-definition, the set of all messages that aren't archived. This means
-that your inbox is nothing more than the result of the search for all
-messages with the label "inbox". (It's actually slightly more
-complicated---we also omit messages marked as killed, deleted or
-spam.)
-
-You could replicate the folder paradigm easily under this scheme, by
-giving each message exactly one label and only viewing the results of
-simple searches for those labels. But you'd quickly find out that life
-can be easier than that if you just trust the search engine, and use
-labels judiciously for things that are too hard to find with search.
-The idea is that a labeling system that allows arbitrary, user-defined
-labels, supplemented by a quick and easy-to-access search mechanism
-provides all the functionality that folders does, plus much more, at a
-far lower cost to the user.
-
-Now let's take a look at your inbox. You'll see that Sup groups
-messages together into threads: each line in the inbox is a thread,
-and the number in parentheses is the number of messages in that
-thread. (If there's no number, there's just one message in the
-thread.) In Sup, most operations are on threads, not individual
-messages. The idea is that you rarely want to operate on a message
-independent of its context. You typically want to view, archive, kill,
-or label all the messages in a thread at one time.
-
-Use the up and down arrows to highlight a thread. ('j' and 'k' do the
-same thing, and 'J' and 'K' will scroll the whole window. Even the
-left and right arrow keys work.) By default, Sup only loads as many
-threads as it takes to fill the window; if you'd like to load more,
-press 'M'. You can hit tab to cycle between only threads with new
-messages.
-
-Highlight a thread and press enter to view it. You'll notice that all
-messages in the thread are displayed together, laid out graphically by
-their relationship to each other (replies are nested under parents).
-By default, only the new messages in a thread are expanded, and the
-others are hidden. You can toggle an individual message's state by
-highlighting a green line and pressing enter. You can use 'E' to
-expand or collapse all messages or 'N' to expand only the new
-messages. You'll also notice that Sup hides quoted text and
-signatures. If you highlight a particular hidden chunk, you can press
-enter to expand it, or you can press 'o' to toggle every hidden chunk
-in a particular message.
-
-Other useful keyboard commands when viewing a thread are: 'n' and 'p'
-to jump to the next and previous open messages, 'h' to toggle the
-detailed headers for the current message, and enter to expand or
-collapse the current message (when it's on a text region). Enter and
-'n' in combination are useful for scanning through a thread---press
-enter to close the current message and jump to the next open one, and
-'n' to keep it open and jump. If the buffer is misaligned with a
-message, you can press 'z' to highlight it.
-
-This is a lot to remember, but you can always hit '?' to see the full
-list of keyboard commands at any point. There's a lot of useful stuff
-in there---once you learn some, try out some of the others!
-
-Now press 'x' to kill the thread view buffer. You should see the inbox
-again. If you don't, you can cycle through the buffers by pressing
-'b', or you can press ';' to see a list of all buffers and simply
-select the inbox.
-
-There are many operations you can perform on threads beyond viewing
-them. To archive a thread, press 'a'. The thread will disappear from
-your inbox, but will still appear in search results. If someone
-replies an archived thread, it will reappear in your inbox. To kill a
-thread, press '&'. Killed threads will never come back to your inbox,
-even if people reply, but will still be searchable. (This is useful
-for those interminable threads that you really have no immediate
-interest in, but which seem to pop up on every mailing list.)
-
-If a thread is spam, press 'S'. It will disappear and won't come back.
-It won't even appear in search results, unless you explicitly search
-for spam.
-
-You can star a thread by pressing '*'. Starred threads are displayed
-with a little yellow asterisk next to them, but otherwise have no
-special semantics. But you can also search for them easily---we'll see
-how in a moment.
-
-To edit the labels for (all the messages in) a thread, press 'l'. Type
-in the labels as a sequence of space-separated words. To cancel the
-input, press Ctrl-G.
-
-Many of these operations can be applied to a group of threads. Press
-'t' to tag a thread. Tag a couple, then press '=' to apply the next
-command to the set of threads. '=t', of course, will untag all tagged
-messages.
-
-Ok, let's try using labels and search. Press 'L' to do a quick label
-search. You'll be prompted for a label; simply hit enter to bring up
-scrollable list of all the labels you've ever used, along with some
-special labels (Draft, Starred, Sent, Spam, etc.). Highlight a label
-and press enter to view all the messages with that label.
-
-What you just did was actually a specific search. For a general search,
-press '\' (backslash---forward slash is used for in-buffer search,
-following console conventions). Now type in your query (again, Ctrl-G to
-cancel at any point.) You can just type in arbitrary text, which will be
-matched on a per-word basis against the bodies of all email in the
-index, or you can make use of the full Xapian query syntax
-(http://xapian.org/docs/queryparser.html):
-
-- Phrasal queries using double-quotes, e.g.: "three contiguous words"
-- Queries against a particular field using <field name>:<query>,
- e.g.: label:ruby-talk, or from:matz at ruby-lang.org. (Fields include:
- body, from, to, and subject.)
-- Force non-occurrence by -, e.g. -body:"hot soup".
-- If you have the chronic gem installed, date queries like
- "before:today", "on:today", "after:yesterday", "after:(2 days ago)"
- (parentheses required for multi-word descriptions).
-
-You can combine those all together. For example:
-
- label:ruby-talk subject:\[ANN\] -rails on:today
-
-Play around with the search, and see the Xapian documentation for
-details on more sophisticated queries (date ranges, "within n words",
-etc.)
-
-At this point, you're well on your way to figuring out all the cool
-things Sup can do. By repeated application of the '?' key, see if you
-can figure out how to:
-
- - List some recent contacts
- - Easily search for all mail from a recent contact
- - Easily search for all mail from several recent contacts
- - Add someone to your address book
- - Postpone a message (i.e., save a draft)
- - Quickly re-edit a just-saved draft message
- - View the raw header of a message
- - Star an individual message, not just a thread
-
-There's one last thing to be aware of when using Sup: how it interacts
-with other email programs. As I described above, Sup stores data about
-messages in the index, but doesn't duplicate the message contents
-themselves. The messages remain on the source. If the index and the
-source every fall out of sync, e.g. due to another email client
-modifying the source, then Sup will be unable to operate on that
-source. For example, for mbox files, Sup stores a byte offset into the
-file for each message. If a message deleted from that file by another
-client, or even marked as read (yeah, mbox sucks), all succeeding
-offsets will be wrong.
-
-That's the bad news. The good news is that Sup is pretty good at being
-able to detect this type of situation, and fixing it is just a matter
-of running `sup-sync --changed` on the source. Sup will even tell you
-how to invoke sup-sync when it detects a problem. This is a
-complication you will almost certainly run in to if you use both Sup
-and another MUA on the same source, so it's good to be aware of it.
-
-Have fun, and email sup-talk at rubyforge.org if you have any problems!
-
-Appendix A: sup-add and sup-sync
----------------------------------
-
-Instead of using sup-config to add a new source, you can manually run
-`sup-add` with a URI pointing to it. The URI should be of the form:
-
-- mbox://path/to/a/filename, for an mbox file on disk.
-- maildir://path/to/a/filename, for a maildir directory on disk.
-
-Before you add the source, you need make three decisions. The first is
-whether you want Sup to regularly poll this source for new messages.
-By default it will, but if this is a source that will never have new
-messages, you can specify `--unusual`. Sup polls only "usual" sources
-when checking for new mail (unless you manually invoke sup-sync).
-
-The second is whether you want messages from the source to be
-automatically archived. An archived message will not show up in your
-inbox, but will be found when you search. (Your inbox in Sup is, by
-definition, the set of all all non-archived messages). Specify
-`--archive` to automatically archive all messages from the source. This
-is useful for sources that contain, for example, high-traffic mailing
-lists that you don't want polluting your inbox.
-
-The final decision is whether you want any labels automatically
-applied to messages from this source. You can use `--labels` to do this.
-
-Now that you've added the source, let's import all the current
-messages from it, by running sup-sync with the source URI. You can
-specify `--archive` to automatically archive all messages in this
-import; typically you'll want to specify this for every source you
-import except your actual inbox. You can also specify `--read` to mark
-all imported messages as read; the default is to preserve the
-read/unread status from the source.
-
-Sup-sync will now load all the messages from the source into the
-index. Depending on the size of the source, this may take a while.
-Don't panic! It's a one-time process.
-
-Appendix B: Automatically labeling incoming email
--------------------------------------------------
-
-One option is to filter incoming email into different sources with
-something like procmail, and have each of these sources auto-apply
-labels by using `sup-add --labels`.
-
-But the better option is to learn Ruby and write a before-add hook.
-This will allow you to apply labels based on whatever crazy logic you
-can come up with. See http://sup.rubyforge.org/wiki/wiki.pl?Hooks for
-examples.
-
-Appendix C: Reading blogs with Sup
-----------------------------------
-
-Really, blog posts should be read like emails are read---you should be
-able to mark them as unread, flag them, label them, etc. Use rss2email
-to transform RSS feeds into emails, direct them all into a source, and
-add that source to Sup. Voila!
diff --git a/lib/sup.rb b/lib/sup.rb
index 74d5cde..4fb4118 100644
--- a/lib/sup.rb
+++ b/lib/sup.rb
@@ -1,10 +1,12 @@
+# encoding: utf-8
+
require 'rubygems'
-require 'syck'
require 'yaml'
+YAML::ENGINE.yamler = 'psych'
require 'zlib'
require 'thread'
require 'fileutils'
-require 'gettext'
+require 'locale'
require 'curses'
require 'rmail'
begin
@@ -23,24 +25,27 @@ end
class Module
def yaml_properties *props
props = props.map { |p| p.to_s }
- vars = props.map { |p| "@#{p}" }
- klass = self
- path = klass.name.gsub(/::/, "/")
- klass.instance_eval do
- define_method(:to_yaml_properties) { vars }
- define_method(:to_yaml_type) { "!#{Redwood::YAML_DOMAIN},#{Redwood::YAML_DATE}/#{path}" }
+ path = name.gsub(/::/, "/")
+ yaml_tag "!#{Redwood::YAML_DOMAIN},#{Redwood::YAML_DATE}/#{path}"
+
+ define_method :init_with do |coder|
+ initialize(*coder.map.values_at(*props))
end
- YAML.add_domain_type("#{Redwood::YAML_DOMAIN},#{Redwood::YAML_DATE}", path) do |type, val|
- klass.new(*props.map { |p| val[p] })
+ define_method :encode_with do |coder|
+ coder.map = props.inject({}) do |hash, key|
+ hash[key] = instance_variable_get("@#{key}")
+ hash
+ end
end
+
+ # Legacy
+ Psych.load_tags["!#{Redwood::LEGACY_YAML_DOMAIN},#{Redwood::YAML_DATE}/#{path}"] = self
end
end
module Redwood
- VERSION = "git"
-
BASE_DIR = ENV["SUP_BASE"] || File.join(ENV["HOME"], ".sup")
CONFIG_FN = File.join(BASE_DIR, "config.yaml")
COLOR_FN = File.join(BASE_DIR, "colors.yaml")
@@ -55,7 +60,8 @@ module Redwood
SEARCH_FN = File.join(BASE_DIR, "searches.txt")
LOG_FN = File.join(BASE_DIR, "log")
- YAML_DOMAIN = "masanjin.net"
+ YAML_DOMAIN = "supmua.org"
+ LEGACY_YAML_DOMAIN = "masanjin.net"
YAML_DATE = "2006-10-01"
## record exceptions thrown in threads nicely
@@ -231,36 +237,6 @@ EOM
end
end
- ## to be called by entry points in bin/, to ensure that
- ## their versions match up against the library versions.
- ##
- ## this is a perennial source of bug reports from people
- ## who both use git and have a gem version installed.
- def check_library_version_against v
- unless Redwood::VERSION == v
- $stderr.puts <<EOS
-Error: version mismatch!
-The sup executable is at version #{v.inspect}.
-The sup libraries are at version #{Redwood::VERSION.inspect}.
-
-Your development environment may be picking up code from a
-rubygems installation of sup.
-
-If you're running from git with a commandline like
-
- ruby -Ilib #{$0}
-
-try this instead:
-
- RUBY_INVOCATION="ruby -Ilib" ruby -Ilib #{$0}
-
-You can also try `gem uninstall sup` and removing all Sup rubygems.
-
-EOS
-#' duh!
- abort
- end
- end
## set up default configuration file
def load_config filename
@@ -285,7 +261,8 @@ EOS
:poll_interval => 300,
:wrap_width => 0,
:slip_rows => 0,
- :col_jump => 2
+ :col_jump => 2,
+ :stem_language => "english"
}
if File.exists? filename
config = Redwood::load_yaml_obj filename
@@ -294,7 +271,7 @@ EOS
else
require 'etc'
require 'socket'
- name = Etc.getpwnam(ENV["USER"]).gecos.split(/,/).first rescue nil
+ name = Etc.getpwnam(ENV["USER"]).gecos.split(/,/).first.force_encoding($encoding).fix_encoding rescue nil
name ||= ENV["USER"]
email = ENV["USER"] + "@" +
begin
@@ -306,8 +283,8 @@ EOS
config = {
:accounts => {
:default => {
- :name => name,
- :email => email,
+ :name => name.fix_encoding,
+ :email => email.fix_encoding,
:alternates => [],
:sendmail => "/usr/sbin/sendmail -oem -ti",
:signature => File.join(ENV["HOME"], ".signature"),
@@ -326,22 +303,21 @@ EOS
end
module_function :save_yaml_obj, :load_yaml_obj, :start, :finish,
- :report_broken_sources, :check_library_version_against,
- :load_config, :managers
+ :report_broken_sources, :load_config, :managers
end
+require 'sup/version'
require "sup/util"
require "sup/hook"
require "sup/time"
## everything we need to get logging working
-require "sup/logger"
-Redwood::Logger.init.add_sink $stderr
-include Redwood::LogsStuff
+require "sup/logger/singleton"
## determine encoding and character set
$encoding = Locale.current.charset
$encoding = "UTF-8" if $encoding == "utf8"
+$encoding = "UTF-8" if $encoding == "UTF8"
if $encoding
debug "using character set encoding #{$encoding.inspect}"
else
@@ -349,14 +325,24 @@ else
$encoding = "UTF-8"
end
+# test encoding
+teststr = "test"
+teststr.encode('UTF-8')
+begin
+ teststr.encode($encoding)
+rescue Encoding::ConverterNotFoundError
+ warn "locale encoding is invalid, defaulting to utf-8"
+ $encoding = "UTF-8"
+end
+
require "sup/buffer"
require "sup/keymap"
require "sup/mode"
-require "sup/modes/scroll-mode"
-require "sup/modes/text-mode"
-require "sup/modes/log-mode"
+require "sup/modes/scroll_mode"
+require "sup/modes/text_mode"
+require "sup/modes/log_mode"
require "sup/update"
-require "sup/message-chunks"
+require "sup/message_chunks"
require "sup/message"
require "sup/source"
require "sup/mbox"
@@ -364,7 +350,7 @@ require "sup/maildir"
require "sup/person"
require "sup/account"
require "sup/thread"
-require "sup/interactive-lock"
+require "sup/interactive_lock"
require "sup/index"
require "sup/textfield"
require "sup/colormap"
@@ -375,31 +361,31 @@ require "sup/draft"
require "sup/poll"
require "sup/crypto"
require "sup/undo"
-require "sup/horizontal-selector"
-require "sup/modes/line-cursor-mode"
-require "sup/modes/help-mode"
-require "sup/modes/edit-message-mode"
-require "sup/modes/edit-message-async-mode"
-require "sup/modes/compose-mode"
-require "sup/modes/resume-mode"
-require "sup/modes/forward-mode"
-require "sup/modes/reply-mode"
-require "sup/modes/label-list-mode"
-require "sup/modes/contact-list-mode"
-require "sup/modes/thread-view-mode"
-require "sup/modes/thread-index-mode"
-require "sup/modes/label-search-results-mode"
-require "sup/modes/search-results-mode"
-require "sup/modes/person-search-results-mode"
-require "sup/modes/inbox-mode"
-require "sup/modes/buffer-list-mode"
-require "sup/modes/poll-mode"
-require "sup/modes/file-browser-mode"
-require "sup/modes/completion-mode"
-require "sup/modes/console-mode"
+require "sup/horizontal_selector"
+require "sup/modes/line_cursor_mode"
+require "sup/modes/help_mode"
+require "sup/modes/edit_message_mode"
+require "sup/modes/edit_message_async_mode"
+require "sup/modes/compose_mode"
+require "sup/modes/resume_mode"
+require "sup/modes/forward_mode"
+require "sup/modes/reply_mode"
+require "sup/modes/label_list_mode"
+require "sup/modes/contact_list_mode"
+require "sup/modes/thread_view_mode"
+require "sup/modes/thread_index_mode"
+require "sup/modes/label_search_results_mode"
+require "sup/modes/search_results_mode"
+require "sup/modes/person_search_results_mode"
+require "sup/modes/inbox_mode"
+require "sup/modes/buffer_list_mode"
+require "sup/modes/poll_mode"
+require "sup/modes/file_browser_mode"
+require "sup/modes/completion_mode"
+require "sup/modes/console_mode"
require "sup/sent"
require "sup/search"
-require "sup/modes/search-list-mode"
+require "sup/modes/search_list_mode"
require "sup/idle"
$:.each do |base|
diff --git a/lib/sup/account.rb b/lib/sup/account.rb
index 1cbf7d8..8303157 100644
--- a/lib/sup/account.rb
+++ b/lib/sup/account.rb
@@ -50,8 +50,9 @@ class AccountManager
[:name, :sendmail, :signature, :gpgkey].each { |k| hash[k] ||= @default_account.send(k) }
end
hash[:alternates] ||= []
+ fail "alternative emails are not an array: #{hash[:alternates]}" unless hash[:alternates].kind_of? Array
- [:name, :signature].each { |x| hash[x].force_encoding Encoding::UTF_8 if hash[x].respond_to? :encoding }
+ [:name, :signature].each { |x| hash[x] ? hash[x].fix_encoding : nil }
a = Account.new hash
@accounts[a] = true
diff --git a/lib/sup/buffer.rb b/lib/sup/buffer.rb
index 444589a..d6f618c 100644
--- a/lib/sup/buffer.rb
+++ b/lib/sup/buffer.rb
@@ -1,11 +1,9 @@
+# encoding: utf-8
+
require 'etc'
require 'thread'
-begin
- require 'ncursesw'
-rescue LoadError
- require 'ncurses'
-end
+require 'ncursesw'
if defined? Ncurses
module Ncurses
@@ -130,14 +128,11 @@ class Buffer
@w.attrset Colormap.color_for(opts[:color] || :none, opts[:highlight])
s ||= ""
maxl = @width - x # maximum display width width
- stringl = maxl # string "length"
# fill up the line with blanks to overwrite old screen contents
@w.mvaddstr y, x, " " * maxl unless opts[:no_fill]
- ## the next horribleness is thanks to ruby's lack of widechar support
- stringl += 1 while stringl < s.length && s[0 ... stringl].display_length < maxl
- @w.mvaddstr y, x, s[0 ... stringl]
+ @w.mvaddstr y, x, s.slice_by_display_length(maxl)
end
def clear
@@ -271,7 +266,7 @@ EOS
def handle_input c
if @focus_buf
- if @focus_buf.mode.in_search? && c != CONTINUE_IN_BUFFER_SEARCH_KEY[0]
+ if @focus_buf.mode.in_search? && c != CONTINUE_IN_BUFFER_SEARCH_KEY.ord
@focus_buf.mode.cancel_search!
@focus_buf.mark_dirty
end
@@ -454,7 +449,7 @@ EOS
def ask_with_completions domain, question, completions, default=nil
ask domain, question, default do |s|
- s.force_encoding 'UTF-8' if s.methods.include?(:encoding)
+ s.fix_encoding
completions.select { |x| x =~ /^#{Regexp::escape s}/iu }.map { |x| [x, x] }
end
end
@@ -471,9 +466,9 @@ EOS
raise "william screwed up completion: #{partial.inspect}"
end
- prefix.force_encoding 'UTF-8' if prefix.methods.include?(:encoding)
- target.force_encoding 'UTF-8' if target.methods.include?(:encoding)
- completions.select { |x| x =~ /^#{Regexp::escape target}/i }.map { |x| [prefix + x, x] }
+ prefix.fix_encoding
+ target.fix_encoding
+ completions.select { |x| x =~ /^#{Regexp::escape target}/iu }.map { |x| [prefix + x, x] }
end
end
@@ -481,12 +476,12 @@ EOS
ask domain, question, default do |partial|
prefix, target = partial.split_on_commas_with_remainder
target ||= prefix.pop || ""
- target.force_encoding 'UTF-8' if target.methods.include?(:encoding)
+ target.fix_encoding
prefix = prefix.join(", ") + (prefix.empty? ? "" : ", ")
- prefix.force_encoding 'UTF-8' if prefix.methods.include?(:encoding)
+ prefix.fix_encoding
- completions.select { |x| x =~ /^#{Regexp::escape target}/i }.sort_by { |c| [ContactManager.contact_for(c) ? 0 : 1, c] }.map { |x| [prefix + x, x] }
+ completions.select { |x| x =~ /^#{Regexp::escape target}/iu }.sort_by { |c| [ContactManager.contact_for(c) ? 0 : 1, c] }.map { |x| [prefix + x, x] }
end
end
@@ -499,7 +494,7 @@ EOS
if dir
[[s.sub(full, dir), "~#{name}"]]
else
- users.select { |u| u =~ /^#{Regexp::escape name}/ }.map do |u|
+ users.select { |u| u =~ /^#{Regexp::escape name}/u }.map do |u|
[s.sub("~#{name}", "~#{u}"), "~#{u}"]
end
end
@@ -558,6 +553,7 @@ EOS
completions = (recent + contacts).flatten.uniq
completions += HookManager.run("extra-contact-addresses") || []
+
answer = BufferManager.ask_many_emails_with_completions domain, question, completions, default
if answer
@@ -626,7 +622,7 @@ EOS
tf.deactivate
draw_screen :sync => false, :status => status, :title => title
end
- tf.value.tap { |x| x.force_encoding Encoding::UTF_8 if x && x.respond_to?(:encoding) }
+ tf.value.tap { |x| x }
end
def ask_getch question, accept=nil
@@ -713,7 +709,7 @@ EOS
end
Ncurses.mutex.lock unless opts[:sync] == false
- Ncurses.attrset Colormap.color_for(:none)
+ Ncurses.attrset Colormap.color_for(:text_color)
adj = @asking ? 2 : 1
m.each_with_index do |s, i|
Ncurses.mvaddstr Ncurses.rows - i - adj, 0, s + (" " * [Ncurses.cols - s.length, 0].max)
diff --git a/lib/sup/client.rb b/lib/sup/client.rb
deleted file mode 100644
index 23da5c6..0000000
--- a/lib/sup/client.rb
+++ /dev/null
@@ -1,92 +0,0 @@
-require 'sup/protocol'
-
-module Redwood
-
-class Client < EM::P::RedwoodClient
- def initialize *a
- @next_tag = 1
- @cbs = {}
- super *a
- end
-
- def mktag &b
- @next_tag.tap do |x|
- @cbs[x] = b
- @next_tag += 1
- end
- end
-
- def rmtag tag
- @cbs.delete tag
- end
-
- def query qstr, offset, limit, raw, &b
- tag = mktag do |type,tag,args|
- if type == 'message'
- b.call args
- else
- fail unless type == 'done'
- b.call nil
- rmtag tag
- end
- end
- send_message 'query', tag,
- 'query' => qstr,
- 'offset' => offset,
- 'limit' => limit,
- 'raw' => raw
- end
-
- def count qstr, &b
- tag = mktag do |type,tag,args|
- b.call args['count']
- rmtag tag
- end
- send_message 'count', tag,
- 'query' => qstr
- end
-
- def label qstr, add, remove, &b
- tag = mktag do |type,tag,args|
- b.call
- rmtag tag
- end
- send_message 'label', tag,
- 'query' => qstr,
- 'add' => add,
- 'remove' => remove
- end
-
- def add raw, labels, &b
- tag = mktag do |type,tag,args|
- b.call
- rmtag tag
- end
- send_message 'add', tag,
- 'raw' => raw,
- 'labels' => labels
- end
-
- def thread msg_id, raw, &b
- tag = mktag do |type,tag,args|
- if type == 'message'
- b.call args
- else
- fail unless type == 'done'
- b.call nil
- rmtag tag
- end
- end
-
- send_message 'thread', tag,
- 'message_id' => msg_id,
- 'raw' => raw
- end
-
- def receive_message type, tag, args
- cb = @cbs[tag] or fail "invalid tag #{tag.inspect}"
- cb[type, tag, args]
- end
-end
-
-end
diff --git a/lib/sup/colormap.rb b/lib/sup/colormap.rb
index 2957de7..c29aaad 100644
--- a/lib/sup/colormap.rb
+++ b/lib/sup/colormap.rb
@@ -26,6 +26,7 @@ class Colormap
@@instance = nil
DEFAULT_COLORS = {
+ :text => { :fg => "white", :bg => "black" },
:status => { :fg => "white", :bg => "blue", :attrs => ["bold"] },
:index_old => { :fg => "white", :bg => "default" },
:index_new => { :fg => "white", :bg => "default", :attrs => ["bold"] },
diff --git a/lib/sup/contact.rb b/lib/sup/contact.rb
index 382896d..82c059e 100644
--- a/lib/sup/contact.rb
+++ b/lib/sup/contact.rb
@@ -1,3 +1,5 @@
+# encoding: utf-8
+
module Redwood
class ContactManager
@@ -27,9 +29,10 @@ class ContactManager
def contacts_with_aliases; @a2p.values.uniq end
def update_alias person, aalias=nil
- if(old_aalias = @p2a[person]) # remove old alias
+ old_aalias = @p2a[person]
+ if(old_aalias != nil and old_aalias != "") # remove old alias
@a2p.delete old_aalias
- @e2p.delete old_aalias.email
+ @e2p.delete person.email
end
@p2a[person] = aalias
unless aalias.nil? || aalias.empty?
@@ -53,7 +56,7 @@ class ContactManager
def is_aliased_contact? person; !@p2a[person].nil? end
def save
- File.open(@fn, "w") do |f|
+ File.open(@fn, "w:UTF-8") do |f|
@p2a.sort_by { |(p, a)| [p.full_address, a] }.each do |(p, a)|
f.puts "#{a || ''}: #{p.full_address}"
end
diff --git a/lib/sup/crypto.rb b/lib/sup/crypto.rb
index bc96f88..8f042cd 100644
--- a/lib/sup/crypto.rb
+++ b/lib/sup/crypto.rb
@@ -39,6 +39,20 @@ from_key: the key that generated the signature (class is GPGME::Key)
Return value: an array of lines of output
EOS
+ HookManager.register "gpg-expand-keys", <<EOS
+Runs when the list of encryption recipients is created, allowing you to
+replace a recipient with one or more GPGME recipients. For example, you could
+replace the email address of a mailing list with the key IDs that belong to
+the recipients of that list. This is essentially what GPG groups do, which
+are not supported by GPGME.
+
+Variables:
+recipients: an array of recipients of the current email
+
+Return value: an array of recipients (email address or GPG key ID) to encrypt
+the email for
+EOS
+
def initialize
@mutex = Mutex.new
@@ -48,28 +62,39 @@ EOS
@gpgme_present =
begin
begin
- GPGME.check_version({:protocol => GPGME::PROTOCOL_OpenPGP})
+ begin
+ GPGME.check_version({:protocol => GPGME::PROTOCOL_OpenPGP})
+ rescue TypeError
+ GPGME.check_version(nil)
+ end
true
rescue GPGME::Error
false
+ rescue ArgumentError
+ # gpgme 2.0.0 raises this due to the hash->string conversion
+ false
end
rescue NameError
false
end
unless @gpgme_present
- @not_working_reason = ['gpgme gem not present',
+ @not_working_reason = ['gpgme gem not present',
'Install the gpgme gem in order to use signed and encrypted emails']
return
end
# if gpg2 is available, it will start gpg-agent if required
if (bin = `which gpg2`.chomp) =~ /\S/
- GPGME.set_engine_info GPGME::PROTOCOL_OpenPGP, bin, nil
+ if GPGME.respond_to?('set_engine_info')
+ GPGME.set_engine_info GPGME::PROTOCOL_OpenPGP, bin, nil
+ else
+ GPGME.gpgme_set_engine_info GPGME::PROTOCOL_OpenPGP, bin, nil
+ end
else
# check if the gpg-options hook uses the passphrase_callback
# if it doesn't then check if gpg agent is present
- gpg_opts = HookManager.run("gpg-options",
+ gpg_opts = HookManager.run("gpg-options",
{:operation => "sign", :options => {}}) || {}
if gpg_opts[:passphrase_callback].nil?
if ENV['GPG_AGENT_INFO'].nil?
@@ -94,22 +119,29 @@ EOS
end
def have_crypto?; @not_working_reason.nil? end
+ def not_working_reason; @not_working_reason end
def sign from, to, payload
return unknown_status(@not_working_reason) unless @not_working_reason.nil?
gpg_opts = {:protocol => GPGME::PROTOCOL_OpenPGP, :armor => true, :textmode => true}
gpg_opts.merge!(gen_sign_user_opts(from))
- gpg_opts = HookManager.run("gpg-options",
+ gpg_opts = HookManager.run("gpg-options",
{:operation => "sign", :options => gpg_opts}) || gpg_opts
begin
- sig = GPGME.detach_sign(format_payload(payload), gpg_opts)
+ if GPGME.respond_to?('detach_sign')
+ sig = GPGME.detach_sign(format_payload(payload), gpg_opts)
+ else
+ crypto = GPGME::Crypto.new
+ gpg_opts[:mode] = GPGME::SIG_MODE_DETACH
+ sig = crypto.sign(format_payload(payload), gpg_opts).read
+ end
rescue GPGME::Error => exc
raise Error, gpgme_exc_msg(exc.message)
end
- # if the key (or gpg-agent) is not available GPGME does not complain
+ # if the key (or gpg-agent) is not available GPGME does not complain
# but just returns a zero length string. Let's catch that
if sig.length == 0
raise Error, gpgme_exc_msg("GPG failed to generate signature: check that gpg-agent is running and your key is available.")
@@ -129,20 +161,26 @@ EOS
gpg_opts = {:protocol => GPGME::PROTOCOL_OpenPGP, :armor => true, :textmode => true}
if sign
- gpg_opts.merge!(gen_sign_user_opts(from))
+ gpg_opts.merge!(gen_sign_user_opts(from))
gpg_opts.merge!({:sign => true})
end
gpg_opts = HookManager.run("gpg-options",
{:operation => "encrypt", :options => gpg_opts}) || gpg_opts
recipients = to + [from]
-
+ recipients = HookManager.run("gpg-expand-keys", { :recipients => recipients }) || recipients
begin
- cipher = GPGME.encrypt(recipients, format_payload(payload), gpg_opts)
+ if GPGME.respond_to?('encrypt')
+ cipher = GPGME.encrypt(recipients, format_payload(payload), gpg_opts)
+ else
+ crypto = GPGME::Crypto.new
+ gpg_opts[:recipients] = recipients
+ cipher = crypto.encrypt(format_payload(payload), gpg_opts).read
+ end
rescue GPGME::Error => exc
raise Error, gpgme_exc_msg(exc.message)
end
- # if the key (or gpg-agent) is not available GPGME does not complain
+ # if the key (or gpg-agent) is not available GPGME does not complain
# but just returns a zero length string. Let's catch that
if cipher.length == 0
raise Error, gpgme_exc_msg("GPG failed to generate cipher text: check that gpg-agent is running and your key is available.")
@@ -246,7 +284,11 @@ EOS
{:operation => "decrypt", :options => gpg_opts}) || gpg_opts
ctx = GPGME::Ctx.new(gpg_opts)
cipher_data = GPGME::Data.from_str(format_payload(payload))
- plain_data = GPGME::Data.empty
+ if GPGME::Data.respond_to?('empty')
+ plain_data = GPGME::Data.empty
+ else
+ plain_data = GPGME::Data.empty!
+ end
begin
ctx.decrypt_verify(cipher_data, plain_data)
rescue GPGME::Error => exc
@@ -259,7 +301,7 @@ EOS
end
plain_data.seek(0, IO::SEEK_SET)
output = plain_data.read
- output.force_encoding Encoding::ASCII_8BIT if output.respond_to? :force_encoding
+ output.transcode(Encoding::ASCII_8BIT, output.encoding)
## TODO: test to see if it is still necessary to do a 2nd run if verify
## fails.
@@ -274,7 +316,7 @@ EOS
# Look for Charset, they are put before the base64 crypted part
charsets = payload.body.split("\n").grep(/^Charset:/)
if !charsets.empty? and charsets[0] =~ /^Charset: (.+)$/
- output = Iconv.easy_decode($encoding, $1, output)
+ output.transcode($encoding, $1)
end
msg.body = output
else
@@ -298,7 +340,7 @@ EOS
msg = RMail::Parser.read output
if msg.header.content_type =~ %r{^multipart/} && !msg.multipart?
output = "MIME-Version: 1.0\n" + output
- output.force_encoding Encoding::ASCII_8BIT if output.respond_to? :force_encoding
+ output.fix_encoding
msg = RMail::Parser.read output
end
end
@@ -314,7 +356,7 @@ private
def gpgme_exc_msg msg
err_msg = "Exception in GPGME call: #{msg}"
- info err_msg
+ #info err_msg
err_msg
end
@@ -346,7 +388,7 @@ private
else
first_sig = "Unknown error or empty signature"
end
- rescue EOFError
+ rescue EOFError
from_key = nil
first_sig = "No public key available for #{signature.fingerprint}"
end
diff --git a/lib/sup/draft.rb b/lib/sup/draft.rb
index 58c45db..27dd556 100644
--- a/lib/sup/draft.rb
+++ b/lib/sup/draft.rb
@@ -32,14 +32,17 @@ class DraftLoader < Source
attr_accessor :dir
yaml_properties
- def initialize
- dir = Redwood::DRAFT_DIR
+ def initialize dir=Redwood::DRAFT_DIR
Dir.mkdir dir unless File.exists? dir
super DraftManager.source_name, true, false
@dir = dir
@cur_offset = 0
end
+ def properly_initialized?
+ !!(@dir && @cur_offset)
+ end
+
def id; DraftManager.source_id; end
def to_s; DraftManager.source_name; end
def uri; DraftManager.source_name; end
diff --git a/lib/sup/hook.rb b/lib/sup/hook.rb
index 9be1295..31d7921 100644
--- a/lib/sup/hook.rb
+++ b/lib/sup/hook.rb
@@ -1,3 +1,5 @@
+require "sup/util"
+
module Redwood
class HookManager
@@ -17,6 +19,14 @@ class HookManager
end
end
+ def flash s
+ if BufferManager.instantiated?
+ BufferManager.flash s
+ else
+ log s
+ end
+ end
+
def log s
info "hook[#@__name]: #{s}"
end
diff --git a/lib/sup/horizontal-selector.rb b/lib/sup/horizontal_selector.rb
similarity index 83%
rename from lib/sup/horizontal-selector.rb
rename to lib/sup/horizontal_selector.rb
index e6ec6dc..4b14410 100644
--- a/lib/sup/horizontal-selector.rb
+++ b/lib/sup/horizontal_selector.rb
@@ -1,6 +1,8 @@
module Redwood
class HorizontalSelector
+ class UnknownValue < StandardError; end
+
attr_accessor :label, :changed_by_user
def initialize label, vals, labels, base_color=:horizontal_selector_unselected_color, selected_color=:horizontal_selector_selected_color
@@ -13,7 +15,14 @@ class HorizontalSelector
@changed_by_user = false
end
- def set_to val; @selection = @vals.index(val) end
+ def set_to val
+ raise UnknownValue, val.inspect unless can_set_to? val
+ @selection = @vals.index(val)
+ end
+
+ def can_set_to? val
+ @vals.include? val
+ end
def val; @vals[@selection] end
diff --git a/lib/sup/index.rb b/lib/sup/index.rb
index 95f104a..dbfb14a 100644
--- a/lib/sup/index.rb
+++ b/lib/sup/index.rb
@@ -1,20 +1,27 @@
ENV["XAPIAN_FLUSH_THRESHOLD"] = "1000"
+ENV["XAPIAN_CJK_NGRAM"] = "1"
require 'xapian'
require 'set'
require 'fileutils'
require 'monitor'
+require 'chronic'
-begin
- require 'chronic'
- $have_chronic = true
-rescue LoadError => e
- debug "No 'chronic' gem detected. Install it for date/time query restrictions."
- $have_chronic = false
-end
+require "sup/util/query"
+require "sup/interactive_lock"
+require "sup/hook"
+require "sup/logger/singleton"
+
+
+if ([Xapian.major_version, Xapian.minor_version, Xapian.revision] <=> [1,2,15]) < 0
+ fail <<-EOF
+\n
+Xapian version 1.2.15 or higher required.
+If you have xapian-full-alaveteli installed,
+Please remove it by running `gem uninstall xapian-full-alaveteli`
+since it's been replaced by the xapian-ruby gem.
-if ([Xapian.major_version, Xapian.minor_version, Xapian.revision] <=> [1,2,1]) < 0
- fail "Xapian version 1.2.1 or higher required"
+ EOF
end
module Redwood
@@ -25,7 +32,6 @@ module Redwood
class Index
include InteractiveLock
- STEM_LANGUAGE = "english"
INDEX_VERSION = '4'
## dates are converted to integers for xapian, and are used for document ids,
@@ -262,6 +268,11 @@ EOS
end
end
+ # Search messages. Returns an Enumerator.
+ def find_messages query_expr
+ enum_for :each_message, parse_query(query_expr)
+ end
+
# wrap all future changes inside a transaction so they're done atomically
def begin_transaction
synchronize { @xapian.begin_transaction }
@@ -310,6 +321,48 @@ EOS
class ParseError < StandardError; end
+ # Stemmed
+ NORMAL_PREFIX = {
+ 'subject' => {:prefix => 'S', :exclusive => false},
+ 'body' => {:prefix => 'B', :exclusive => false},
+ 'from_name' => {:prefix => 'FN', :exclusive => false},
+ 'to_name' => {:prefix => 'TN', :exclusive => false},
+ 'name' => {:prefix => %w(FN TN), :exclusive => false},
+ 'attachment' => {:prefix => 'A', :exclusive => false},
+ 'email_text' => {:prefix => 'E', :exclusive => false},
+ '' => {:prefix => %w(S B FN TN A E), :exclusive => false},
+ }
+
+ # Unstemmed
+ BOOLEAN_PREFIX = {
+ 'type' => {:prefix => 'K', :exclusive => true},
+ 'from_email' => {:prefix => 'FE', :exclusive => false},
+ 'to_email' => {:prefix => 'TE', :exclusive => false},
+ 'email' => {:prefix => %w(FE TE), :exclusive => false},
+ 'date' => {:prefix => 'D', :exclusive => true},
+ 'label' => {:prefix => 'L', :exclusive => false},
+ 'source_id' => {:prefix => 'I', :exclusive => true},
+ 'attachment_extension' => {:prefix => 'O', :exclusive => false},
+ 'msgid' => {:prefix => 'Q', :exclusive => true},
+ 'id' => {:prefix => 'Q', :exclusive => true},
+ 'thread' => {:prefix => 'H', :exclusive => false},
+ 'ref' => {:prefix => 'R', :exclusive => false},
+ 'location' => {:prefix => 'J', :exclusive => false},
+ }
+
+ PREFIX = NORMAL_PREFIX.merge BOOLEAN_PREFIX
+
+ COMPL_OPERATORS = %w[AND OR NOT]
+ COMPL_PREFIXES = (
+ %w[
+ from to
+ is has label
+ filename filetypem
+ before on in during after
+ limit
+ ] + NORMAL_PREFIX.keys + BOOLEAN_PREFIX.keys
+ ).map{|p|"#{p}:"} + COMPL_OPERATORS
+
## parse a query string from the user. returns a query object
## that can be passed to any index method with a 'query'
## argument.
@@ -389,27 +442,25 @@ EOS
end
end
- if $have_chronic
- lastdate = 2<<32 - 1
- firstdate = 0
- subs = subs.gsub(/\b(before|on|in|during|after):(\((.+?)\)\B|(\S+)\b)/) do
- field, datestr = $1, ($3 || $4)
- realdate = Chronic.parse datestr, :guess => false, :context => :past
- if realdate
- case field
- when "after"
- debug "chronic: translated #{field}:#{datestr} to #{realdate.end}"
- "date:#{realdate.end.to_i}..#{lastdate}"
- when "before"
- debug "chronic: translated #{field}:#{datestr} to #{realdate.begin}"
- "date:#{firstdate}..#{realdate.end.to_i}"
- else
- debug "chronic: translated #{field}:#{datestr} to #{realdate}"
- "date:#{realdate.begin.to_i}..#{realdate.end.to_i}"
- end
+ lastdate = 2<<32 - 1
+ firstdate = 0
+ subs = subs.gsub(/\b(before|on|in|during|after):(\((.+?)\)\B|(\S+)\b)/) do
+ field, datestr = $1, ($3 || $4)
+ realdate = Chronic.parse datestr, :guess => false, :context => :past
+ if realdate
+ case field
+ when "after"
+ debug "chronic: translated #{field}:#{datestr} to #{realdate.end}"
+ "date:#{realdate.end.to_i}..#{lastdate}"
+ when "before"
+ debug "chronic: translated #{field}:#{datestr} to #{realdate.begin}"
+ "date:#{firstdate}..#{realdate.end.to_i}"
else
- raise ParseError, "can't understand date #{datestr.inspect}"
+ debug "chronic: translated #{field}:#{datestr} to #{realdate}"
+ "date:#{realdate.begin.to_i}..#{realdate.end.to_i}"
end
+ else
+ raise ParseError, "can't understand date #{datestr.inspect}"
end
end
@@ -428,7 +479,7 @@ EOS
qp = Xapian::QueryParser.new
qp.database = @xapian
- qp.stemmer = Xapian::Stem.new(STEM_LANGUAGE)
+ qp.stemmer = Xapian::Stem.new($config[:stem_language])
qp.stemming_strategy = Xapian::QueryParser::STEM_SOME
qp.default_op = Xapian::Query::OP_AND
qp.add_valuerangeprocessor(Xapian::NumberValueRangeProcessor.new(DATE_VALUENO, 'date:', true))
@@ -441,7 +492,7 @@ EOS
raise ParseError, "xapian query parser error: #{e}"
end
- debug "parsed xapian query: #{xapian_query.description}"
+ debug "parsed xapian query: #{Util::Query.describe(xapian_query)}"
raise ParseError if xapian_query.nil? or xapian_query.empty?
query[:qobj] = xapian_query
@@ -482,37 +533,6 @@ EOS
private
- # Stemmed
- NORMAL_PREFIX = {
- 'subject' => {:prefix => 'S', :exclusive => false},
- 'body' => {:prefix => 'B', :exclusive => false},
- 'from_name' => {:prefix => 'FN', :exclusive => false},
- 'to_name' => {:prefix => 'TN', :exclusive => false},
- 'name' => {:prefix => %w(FN TN), :exclusive => false},
- 'attachment' => {:prefix => 'A', :exclusive => false},
- 'email_text' => {:prefix => 'E', :exclusive => false},
- '' => {:prefix => %w(S B FN TN A E), :exclusive => false},
- }
-
- # Unstemmed
- BOOLEAN_PREFIX = {
- 'type' => {:prefix => 'K', :exclusive => true},
- 'from_email' => {:prefix => 'FE', :exclusive => false},
- 'to_email' => {:prefix => 'TE', :exclusive => false},
- 'email' => {:prefix => %w(FE TE), :exclusive => false},
- 'date' => {:prefix => 'D', :exclusive => true},
- 'label' => {:prefix => 'L', :exclusive => false},
- 'source_id' => {:prefix => 'I', :exclusive => true},
- 'attachment_extension' => {:prefix => 'O', :exclusive => false},
- 'msgid' => {:prefix => 'Q', :exclusive => true},
- 'id' => {:prefix => 'Q', :exclusive => true},
- 'thread' => {:prefix => 'H', :exclusive => false},
- 'ref' => {:prefix => 'R', :exclusive => false},
- 'location' => {:prefix => 'J', :exclusive => false},
- }
-
- PREFIX = NORMAL_PREFIX.merge BOOLEAN_PREFIX
-
MSGID_VALUENO = 0
THREAD_VALUENO = 1
DATE_VALUENO = 2
@@ -804,7 +824,7 @@ class Xapian::Document
def index_text text, prefix, weight=1
term_generator = Xapian::TermGenerator.new
- term_generator.stemmer = Xapian::Stem.new(Redwood::Index::STEM_LANGUAGE)
+ term_generator.stemmer = Xapian::Stem.new($config[:stem_language])
term_generator.document = self
term_generator.index_text text, weight, prefix
end
diff --git a/lib/sup/interactive-lock.rb b/lib/sup/interactive_lock.rb
similarity index 100%
rename from lib/sup/interactive-lock.rb
rename to lib/sup/interactive_lock.rb
diff --git a/lib/sup/label.rb b/lib/sup/label.rb
index 1699896..24b7dc4 100644
--- a/lib/sup/label.rb
+++ b/lib/sup/label.rb
@@ -1,3 +1,5 @@
+# encoding: utf-8
+
module Redwood
class LabelManager
@@ -77,7 +79,7 @@ class LabelManager
def save
return unless @modified
- File.open(@fn, "w") { |f| f.puts @labels.keys.sort_by { |l| l.to_s } }
+ File.open(@fn, "w:UTF-8") { |f| f.puts @labels.keys.sort_by { |l| l.to_s } }
@new_labels = {}
end
end
diff --git a/lib/sup/logger.rb b/lib/sup/logger.rb
index 46e8a08..7dd296a 100644
--- a/lib/sup/logger.rb
+++ b/lib/sup/logger.rb
@@ -1,4 +1,4 @@
-require "sup"
+require "sup/util"
require 'stringio'
require 'thread'
diff --git a/lib/sup/logger/singleton.rb b/lib/sup/logger/singleton.rb
new file mode 100644
index 0000000..3321785
--- /dev/null
+++ b/lib/sup/logger/singleton.rb
@@ -0,0 +1,10 @@
+# TODO: this is ugly. It's better to have a application singleton passed
+# down to lower level components instead of including logging methods in
+# class `Object'
+#
+# For now this is what we have to do.
+require "sup/logger"
+Redwood::Logger.init.add_sink $stderr
+class Object
+ include Redwood::LogsStuff
+end
diff --git a/lib/sup/message.rb b/lib/sup/message.rb
index 66745ca..e4f16d4 100644
--- a/lib/sup/message.rb
+++ b/lib/sup/message.rb
@@ -69,7 +69,9 @@ class Message
return unless v
return v unless v.is_a? String
return unless v.size < MAX_HEADER_VALUE_SIZE # avoid regex blowup on spam
- Rfc2047.decode_to $encoding, Iconv.easy_decode($encoding, 'ASCII', v)
+ d = v.dup
+ d = d.transcode($encoding, 'ASCII')
+ Rfc2047.decode_to $encoding, d
end
def parse_header encoded_header
@@ -109,7 +111,9 @@ class Message
Time.now
end
- @subj = header["subject"] ? header["subject"].gsub(/\s+/, " ").gsub(/\s+$/, "") : DEFAULT_SUBJECT
+ subj = header["subject"]
+ subj = subj ? subj.fix_encoding : nil
+ @subj = subj ? subj.gsub(/\s+/, " ").gsub(/\s+$/, "") : DEFAULT_SUBJECT
@to = Person.from_address_list header["to"]
@cc = Person.from_address_list header["cc"]
@bcc = Person.from_address_list header["bcc"]
@@ -260,6 +264,8 @@ class Message
rescue SourceError, SocketError, RMail::EncodingUnsupportedError => e
warn "problem reading message #{id}"
[Chunk::Text.new(error_message.split("\n"))]
+
+ debug "could not load message: #{location.inspect}, exception: #{e.inspect}"
end
end
@@ -524,7 +530,7 @@ private
## if there's no charset, use the current encoding as the charset.
## this ensures that the body is normalized to avoid non-displayable
## characters
- body = Iconv.easy_decode($encoding, m.charset || $encoding, m.decode)
+ body = m.decode.transcode($encoding, m.charset)
else
body = ""
end
@@ -540,11 +546,13 @@ private
def inline_gpg_to_chunks body, encoding_to, encoding_from
lines = body.split("\n")
gpg = lines.between(GPG_SIGNED_START, GPG_SIGNED_END)
- if !gpg.empty?
+ # between does not check if GPG_END actually exists
+ # Reference: http://permalink.gmane.org/gmane.mail.sup.devel/641
+ if !gpg.empty? && !lines.index(GPG_END).nil?
msg = RMail::Message.new
msg.body = gpg.join("\n")
- body = Iconv.easy_decode(encoding_to, encoding_from, body)
+ body = body.transcode(encoding_to, encoding_from)
lines = body.split("\n")
sig = lines.between(GPG_SIGNED_START, GPG_SIG_START)
startidx = lines.index(GPG_SIGNED_START)
@@ -615,7 +623,7 @@ private
## like ":a:a:a:a:a" that occurred in certain emails.
if line =~ QUOTE_PATTERN || (line =~ /:$/ && line =~ /\w/ && nextline =~ QUOTE_PATTERN)
newstate = :quote
- elsif line =~ SIG_PATTERN && (lines.length - i) < MAX_SIG_DISTANCE
+ elsif line =~ SIG_PATTERN && (lines.length - i) < MAX_SIG_DISTANCE && !lines[(i+1)..-1].index { |l| l =~ /^-- $/ }
newstate = :sig
elsif line =~ BLOCK_QUOTE_PATTERN
newstate = :block_quote
diff --git a/lib/sup/message-chunks.rb b/lib/sup/message_chunks.rb
similarity index 98%
rename from lib/sup/message-chunks.rb
rename to lib/sup/message_chunks.rb
index 7a061d9..f3f807b 100644
--- a/lib/sup/message-chunks.rb
+++ b/lib/sup/message_chunks.rb
@@ -1,4 +1,5 @@
require 'tempfile'
+require 'rbconfig'
## Here we define all the "chunks" that a message is parsed
## into. Chunks are used by ThreadViewMode to render a message. Chunks
@@ -123,13 +124,13 @@ EOS
@lines = nil
if text
- text = text.transcode(encoded_content.charset || $encoding)
+ text = text.transcode(encoded_content.charset || $encoding, text.encoding)
@lines = text.gsub("\r\n", "\n").gsub(/\t/, " ").gsub(/\r/, "").split("\n")
@quotable = true
end
end
- def color; :none end
+ def color; :text_color end
def patina_color; :attachment_color end
def patina_text
if expandable?
@@ -146,7 +147,7 @@ EOS
def initial_state; :open end
def viewable?; @lines.nil? end
def view_default! path
- case Config::CONFIG['arch']
+ case RbConfig::CONFIG['arch']
when /darwin/
cmd = "open '#{path}'"
else
@@ -190,7 +191,7 @@ EOS
def quotable?; true end
def expandable?; false end
def viewable?; false end
- def color; :none end
+ def color; :text_color end
end
class Quote
diff --git a/lib/sup/modes/buffer-list-mode.rb b/lib/sup/modes/buffer_list_mode.rb
similarity index 100%
rename from lib/sup/modes/buffer-list-mode.rb
rename to lib/sup/modes/buffer_list_mode.rb
diff --git a/lib/sup/modes/completion-mode.rb b/lib/sup/modes/completion_mode.rb
similarity index 82%
rename from lib/sup/modes/completion-mode.rb
rename to lib/sup/modes/completion_mode.rb
index 3cb2fad..4bf06e8 100644
--- a/lib/sup/modes/completion-mode.rb
+++ b/lib/sup/modes/completion_mode.rb
@@ -38,11 +38,11 @@ private
suffix = s[(@prefix_len + 1) .. -1]
char = s[@prefix_len].chr
- @lines.last += [[:none, sprintf("%#{max_length - suffix.length - 1}s", prefix)],
+ @lines.last += [[:text_color, sprintf("%#{max_length - suffix.length - 1}s", prefix)],
[:completion_character_color, char],
- [:none, suffix + INTERSTITIAL]]
+ [:text_color, suffix + INTERSTITIAL]]
else
- @lines.last += [[:none, sprintf("%#{max_length}s#{INTERSTITIAL}", s)]]
+ @lines.last += [[:text_color, sprintf("%#{max_length}s#{INTERSTITIAL}", s)]]
end
else
@lines << "" if i % num_per == 0
diff --git a/lib/sup/modes/compose-mode.rb b/lib/sup/modes/compose_mode.rb
similarity index 98%
rename from lib/sup/modes/compose-mode.rb
rename to lib/sup/modes/compose_mode.rb
index cf7a9de..7d08ac2 100644
--- a/lib/sup/modes/compose-mode.rb
+++ b/lib/sup/modes/compose_mode.rb
@@ -1,3 +1,5 @@
+# encoding: utf-8
+
module Redwood
class ComposeMode < EditMessageMode
diff --git a/lib/sup/modes/console-mode.rb b/lib/sup/modes/console_mode.rb
similarity index 82%
rename from lib/sup/modes/console-mode.rb
rename to lib/sup/modes/console_mode.rb
index 6442b9d..6c602cd 100644
--- a/lib/sup/modes/console-mode.rb
+++ b/lib/sup/modes/console_mode.rb
@@ -1,10 +1,13 @@
require 'pp'
+require "sup/service/label_service"
+
module Redwood
class Console
def initialize mode
@mode = mode
+ @label_service = LabelService.new
end
def query(query)
@@ -12,19 +15,27 @@ class Console
end
def add_labels(query, *labels)
- query(query).each { |m| m.labels += labels; m.save Index }
+ count = @label_service.add_labels(query, *labels)
+ print_buffer_dirty_msg count
end
def remove_labels(query, *labels)
- query(query).each { |m| m.labels -= labels; m.save Index }
+ count = @label_service.remove_labels(query, *labels)
+ print_buffer_dirty_msg count
+ end
+
+ def print_buffer_dirty_msg msg_count
+ puts "Scanned #{msg_count} messages."
+ puts "You might want to refresh open buffers with `@` key."
end
+ private :print_buffer_dirty_msg
def xapian; Index.instance.instance_variable_get :@xapian; end
def loglevel; Redwood::Logger.level; end
def set_loglevel(level); Redwood::Logger.level = level; end
- def special_methods; methods - Object.methods end
+ def special_methods; public_methods - Object.methods end
def puts x; @mode << "#{x.to_s.rstrip}\n" end
def p x; puts x.inspect end
diff --git a/lib/sup/modes/contact-list-mode.rb b/lib/sup/modes/contact_list_mode.rb
similarity index 100%
rename from lib/sup/modes/contact-list-mode.rb
rename to lib/sup/modes/contact_list_mode.rb
diff --git a/lib/sup/modes/edit-message-async-mode.rb b/lib/sup/modes/edit_message_async_mode.rb
similarity index 100%
rename from lib/sup/modes/edit-message-async-mode.rb
rename to lib/sup/modes/edit_message_async_mode.rb
diff --git a/lib/sup/modes/edit-message-mode.rb b/lib/sup/modes/edit_message_mode.rb
similarity index 92%
rename from lib/sup/modes/edit-message-mode.rb
rename to lib/sup/modes/edit_message_mode.rb
index 5947ffd..e203ed0 100644
--- a/lib/sup/modes/edit-message-mode.rb
+++ b/lib/sup/modes/edit_message_mode.rb
@@ -93,7 +93,6 @@ EOS
@header_lines = []
@body = opts.delete(:body) || []
- @body += sig_lines if $config[:edit_signature] && !opts.delete(:have_signature)
if opts[:attachments]
@attachments = opts[:attachments].values
@@ -112,10 +111,14 @@ EOS
@message_id = "<#{Time.now.to_i}-sup-#{rand 10000}@#{hostname}>"
@edited = false
+ @sig_edited = false
@selectors = []
@selector_label_width = 0
@async_mode = nil
+ HookManager.run "before-edit", :header => @header, :body => @body
+
+ @account_selector = nil
# only show account selector if there is more than one email address
if $config[:account_selector] && AccountManager.user_emails.length > 1
## Duplicate e-mail strings to prevent a "can't modify frozen
@@ -128,13 +131,18 @@ EOS
HorizontalSelector.new "Account:", AccountManager.user_emails + [nil], user_emails_copy + ["Customized"]
if @header["From"] =~ /<?(\S+@(\S+?))>?$/
- @account_selector.set_to $1
- @account_user = ""
+ # TODO: this is ugly. might implement an AccountSelector and handle
+ # special cases more transparently.
+ account_from = @account_selector.can_set_to?($1) ? $1 : nil
+ @account_selector.set_to account_from
else
@account_selector.set_to nil
- @account_user = @header["From"]
end
+ # A single source of truth might better than duplicating this in both
+ # @account_user and @account_selector.
+ @account_user = @header["From"]
+
add_selector @account_selector
end
@@ -144,7 +152,6 @@ EOS
end
add_selector @crypto_selector if @crypto_selector
- HookManager.run "before-edit", :header => @header, :body => @body
if @crypto_selector
HookManager.run "crypto-mode", :header => @header, :body => @body, :crypto_selector => @crypto_selector
end
@@ -185,14 +192,41 @@ EOS
def edit_cc; edit_field "Cc" end
def edit_subject; edit_field "Subject" end
- def edit_message
- old_from = @header["From"] if @account_selector
-
- @file = Tempfile.new "sup.#{self.class.name.gsub(/.*::/, '').camel_to_hyphy}"
+ def save_message_to_file
+ sig = sig_lines.join("\n")
+ @file = Tempfile.new ["sup.#{self.class.name.gsub(/.*::/, '').camel_to_hyphy}", ".eml"]
@file.puts format_headers(@header - NON_EDITABLE_HEADERS).first
@file.puts
@file.puts @body.join("\n")
+ @file.puts sig if ($config[:edit_signature] and !@sig_edited)
@file.close
+ end
+
+ def set_sig_edit_flag
+ sig = sig_lines.join("\n")
+ if $config[:edit_signature]
+ pbody = @body.join("\n")
+ blen = pbody.length
+ slen = sig.length
+
+ if blen > slen and pbody[blen-slen..blen] == sig
+ @sig_edited = false
+ @body = pbody[0..blen-slen].split("\n")
+ else
+ @sig_edited = true
+ end
+ end
+ end
+
+ def edit_message
+ old_from = @header["From"] if @account_selector
+
+ begin
+ save_message_to_file
+ rescue SystemCallError => e
+ BufferManager.flash "Can't save message to file: #{e.message}"
+ return
+ end
editor = $config[:editor] || ENV['EDITOR'] || "/usr/bin/vi"
@@ -204,6 +238,7 @@ EOS
header, @body = parse_file @file.path
@header = header - NON_EDITABLE_HEADERS
+ set_sig_edit_flag
if @account_selector and @header["From"] != old_from
@account_user = @header["From"]
@@ -218,11 +253,12 @@ EOS
end
def edit_message_async
- @file = Tempfile.new ["sup.#{self.class.name.gsub(/.*::/, '').camel_to_hyphy}", ".eml"]
- @file.puts format_headers(@header - NON_EDITABLE_HEADERS).first
- @file.puts
- @file.puts @body.join("\n")
- @file.close
+ begin
+ save_message_to_file
+ rescue SystemCallError => e
+ BufferManager.flash "Can't save message to file: #{e.message}"
+ return
+ end
@mtime = File.mtime @file.path
@@ -245,6 +281,7 @@ EOS
header, @body = parse_file @file.path
@header = header - NON_EDITABLE_HEADERS
+ set_sig_edit_flag
handle_new_text @header, @body
update
@@ -362,7 +399,7 @@ protected
def regen_text
header, @header_lines = format_headers(@header - NON_EDITABLE_HEADERS) + [""]
@text = header + [""] + @body
- @text += sig_lines unless $config[:edit_signature]
+ @text += sig_lines unless @sig_edited
@attachment_lines_offset = 0
@@ -447,10 +484,10 @@ protected
m = build_message date
if HookManager.enabled? "sendmail"
- if not HookManager.run "sendmail", :message => m, :account => acct
- warn "Sendmail hook was not successful"
- return false
- end
+ if not HookManager.run "sendmail", :message => m, :account => acct
+ warn "Sendmail hook was not successful"
+ return false
+ end
else
IO.popen(acct.sendmail, "w") { |p| p.puts m }
raise SendmailCommandFailed, "Couldn't execute #{acct.sendmail}" unless $? == 0
@@ -477,7 +514,7 @@ protected
m = RMail::Message.new
m.header["Content-Type"] = "text/plain; charset=#{$encoding}"
m.body = @body.join("\n")
- m.body += sig_lines.join("\n") unless $config[:edit_signature]
+ m.body += "\n" + sig_lines.join("\n") unless @sig_edited
## body must end in a newline or GPG signatures will be WRONG!
m.body += "\n" unless m.body =~ /\n\Z/
diff --git a/lib/sup/modes/file-browser-mode.rb b/lib/sup/modes/file_browser_mode.rb
similarity index 100%
rename from lib/sup/modes/file-browser-mode.rb
rename to lib/sup/modes/file_browser_mode.rb
diff --git a/lib/sup/modes/forward-mode.rb b/lib/sup/modes/forward_mode.rb
similarity index 100%
rename from lib/sup/modes/forward-mode.rb
rename to lib/sup/modes/forward_mode.rb
diff --git a/lib/sup/modes/help-mode.rb b/lib/sup/modes/help_mode.rb
similarity index 100%
rename from lib/sup/modes/help-mode.rb
rename to lib/sup/modes/help_mode.rb
diff --git a/lib/sup/modes/inbox-mode.rb b/lib/sup/modes/inbox_mode.rb
similarity index 98%
rename from lib/sup/modes/inbox-mode.rb
rename to lib/sup/modes/inbox_mode.rb
index 9e37909..a021d4e 100644
--- a/lib/sup/modes/inbox-mode.rb
+++ b/lib/sup/modes/inbox_mode.rb
@@ -1,4 +1,4 @@
-require 'sup'
+require "sup/modes/thread_index_mode"
module Redwood
diff --git a/lib/sup/modes/label-list-mode.rb b/lib/sup/modes/label_list_mode.rb
similarity index 100%
rename from lib/sup/modes/label-list-mode.rb
rename to lib/sup/modes/label_list_mode.rb
diff --git a/lib/sup/modes/label-search-results-mode.rb b/lib/sup/modes/label_search_results_mode.rb
similarity index 100%
rename from lib/sup/modes/label-search-results-mode.rb
rename to lib/sup/modes/label_search_results_mode.rb
diff --git a/lib/sup/modes/line-cursor-mode.rb b/lib/sup/modes/line_cursor_mode.rb
similarity index 97%
rename from lib/sup/modes/line-cursor-mode.rb
rename to lib/sup/modes/line_cursor_mode.rb
index aad6fe1..d762c5b 100644
--- a/lib/sup/modes/line-cursor-mode.rb
+++ b/lib/sup/modes/line_cursor_mode.rb
@@ -47,9 +47,9 @@ protected
def draw_line ln, opts={}
if ln == @curpos
- super ln, :highlight => true, :debug => opts[:debug]
+ super ln, :highlight => true, :debug => opts[:debug], :color => :text_color
else
- super
+ super ln, :color => :text_color
end
end
diff --git a/lib/sup/modes/log-mode.rb b/lib/sup/modes/log_mode.rb
similarity index 100%
rename from lib/sup/modes/log-mode.rb
rename to lib/sup/modes/log_mode.rb
diff --git a/lib/sup/modes/person-search-results-mode.rb b/lib/sup/modes/person_search_results_mode.rb
similarity index 100%
rename from lib/sup/modes/person-search-results-mode.rb
rename to lib/sup/modes/person_search_results_mode.rb
diff --git a/lib/sup/modes/poll-mode.rb b/lib/sup/modes/poll_mode.rb
similarity index 100%
rename from lib/sup/modes/poll-mode.rb
rename to lib/sup/modes/poll_mode.rb
diff --git a/lib/sup/modes/reply-mode.rb b/lib/sup/modes/reply_mode.rb
similarity index 82%
rename from lib/sup/modes/reply-mode.rb
rename to lib/sup/modes/reply_mode.rb
index ccdf371..d7d914f 100644
--- a/lib/sup/modes/reply-mode.rb
+++ b/lib/sup/modes/reply_mode.rb
@@ -48,6 +48,7 @@ EOS
## the full headers (most importantly the list-post header, if
## any)
body = reply_body_lines message
+ @body_orig = body
## first, determine the address at which we received this email. this will
## become our From: address in the reply.
@@ -97,14 +98,21 @@ EOS
@headers = {}
@headers[:recipient] = {
"To" => cc.map { |p| p.full_address },
+ "Cc" => [],
} if useful_recipient
## typically we don't want to have a reply-to-sender option if the sender
## is a user account. however, if the cc is empty, it's a message to
## ourselves, so for the lack of any other options, we'll add it.
- @headers[:sender] = { "To" => [to.full_address], } if !AccountManager.is_account?(to) || !useful_recipient
+ @headers[:sender] = {
+ "To" => [to.full_address],
+ "Cc" => [],
+ } if !AccountManager.is_account?(to) || !useful_recipient
- @headers[:user] = {}
+ @headers[:user] = {
+ "To" => [],
+ "Cc" => [],
+ }
not_me_ccs = cc.select { |p| !AccountManager.is_account?(p) }
@headers[:all] = {
@@ -114,22 +122,11 @@ EOS
@headers[:list] = {
"To" => [@m.list_address.full_address],
+ "Cc" => [],
} if @m.is_list_message?
refs = gen_references
- @headers.each do |k, v|
- @headers[k] = {
- "From" => from.full_address,
- "To" => [],
- "Cc" => [],
- "Bcc" => [],
- "In-reply-to" => "<#{@m.id}>",
- "Subject" => Message.reify_subj(@m.subj),
- "References" => refs,
- }.merge v
- end
-
types = REPLY_TYPES.select { |t| @headers.member?(t) }
@type_selector = HorizontalSelector.new "Reply to:", types, types.map { |x| TYPE_DESCRIPTIONS[x] }
@@ -148,13 +145,17 @@ EOS
:recipient
end)
- @bodies = {}
- @headers.each do |k, v|
- @bodies[k] = body
- HookManager.run "before-edit", :header => v, :body => @bodies[k]
- end
+ headers_full = {
+ "From" => from.full_address,
+ "Bcc" => [],
+ "In-reply-to" => "<#{@m.id}>",
+ "Subject" => Message.reify_subj(@m.subj),
+ "References" => refs,
+ }.merge @headers[@type_selector.val]
+
+ HookManager.run "before-edit", :header => headers_full, :body => body
- super :header => @headers[@type_selector.val], :body => @bodies[@type_selector.val], :twiddles => false
+ super :header => headers_full, :body => body, :twiddles => false
add_selector @type_selector
end
@@ -163,8 +164,7 @@ protected
def move_cursor_right
super
if @headers[@type_selector.val] != self.header
- self.header = @headers[@type_selector.val]
- self.body = @bodies[@type_selector.val] unless @edited
+ self.header = self.header.merge @headers[@type_selector.val]
rerun_crypto_selector_hook
update
end
@@ -173,8 +173,7 @@ protected
def move_cursor_left
super
if @headers[@type_selector.val] != self.header
- self.header = @headers[@type_selector.val]
- self.body = @bodies[@type_selector.val] unless @edited
+ self.header = self.header.merge @headers[@type_selector.val]
rerun_crypto_selector_hook
update
end
@@ -192,14 +191,15 @@ protected
end
def handle_new_text new_header, new_body
- if new_body != @bodies[@type_selector.val]
- @bodies[@type_selector.val] = new_body
+ if new_body != @body_orig
+ @body_orig = new_body
@edited = true
end
old_header = @headers[@type_selector.val]
- if new_header.size != old_header.size || old_header.any? { |k, v| new_header[k] != v }
+ if old_header.any? { |k, v| new_header[k] != v }
@type_selector.set_to :user
- self.header = @headers[:user] = new_header
+ self.header["To"] = @headers[:user]["To"] = new_header["To"]
+ self.header["Cc"] = @headers[:user]["Cc"] = new_header["Cc"]
update
end
end
@@ -210,8 +210,10 @@ protected
def edit_field field
edited_field = super
- if edited_field && edited_field != "Subject"
+ if edited_field and (field == "To" or field == "Cc")
@type_selector.set_to :user
+ @headers[:user]["To"] = self.header["To"]
+ @headers[:user]["Cc"] = self.header["Cc"]
update
end
end
diff --git a/lib/sup/modes/resume-mode.rb b/lib/sup/modes/resume_mode.rb
similarity index 100%
rename from lib/sup/modes/resume-mode.rb
rename to lib/sup/modes/resume_mode.rb
diff --git a/lib/sup/modes/scroll-mode.rb b/lib/sup/modes/scroll_mode.rb
similarity index 96%
rename from lib/sup/modes/scroll-mode.rb
rename to lib/sup/modes/scroll_mode.rb
index aac1c19..9bee795 100644
--- a/lib/sup/modes/scroll-mode.rb
+++ b/lib/sup/modes/scroll_mode.rb
@@ -43,12 +43,12 @@ class ScrollMode < Mode
def draw
ensure_mode_validity
- (@topline ... @botline).each { |ln| draw_line ln }
+ (@topline ... @botline).each { |ln| draw_line ln, :color => :text_color }
((@botline - @topline) ... buffer.content_height).each do |ln|
if @twiddles
buffer.write ln, 0, "~", :color => :twiddle_color
else
- buffer.write ln, 0, ""
+ buffer.write ln, 0, "", :color => :text_color
end
end
@status = "lines #{@topline + 1}:#{@botline}/#{lines}"
@@ -208,7 +208,7 @@ protected
# return
end
- def matching_text_array s, regex, oldcolor=:none
+ def matching_text_array s, regex, oldcolor=:text_color
s.split(regex).map do |text|
next if text.empty?
if text =~ regex
@@ -244,7 +244,7 @@ protected
end
def draw_line_from_string ln, s, opts
- buffer.write ln - @topline, 0, s[@leftcol .. -1], :highlight => opts[:highlight]
+ buffer.write ln - @topline, 0, s[@leftcol .. -1], :highlight => opts[:highlight], :color => opts[:color]
end
end
diff --git a/lib/sup/modes/search-list-mode.rb b/lib/sup/modes/search_list_mode.rb
similarity index 100%
rename from lib/sup/modes/search-list-mode.rb
rename to lib/sup/modes/search_list_mode.rb
diff --git a/lib/sup/modes/search-results-mode.rb b/lib/sup/modes/search_results_mode.rb
similarity index 100%
rename from lib/sup/modes/search-results-mode.rb
rename to lib/sup/modes/search_results_mode.rb
diff --git a/lib/sup/modes/text-mode.rb b/lib/sup/modes/text_mode.rb
similarity index 100%
rename from lib/sup/modes/text-mode.rb
rename to lib/sup/modes/text_mode.rb
diff --git a/lib/sup/modes/thread-index-mode.rb b/lib/sup/modes/thread_index_mode.rb
similarity index 97%
rename from lib/sup/modes/thread-index-mode.rb
rename to lib/sup/modes/thread_index_mode.rb
index f04295b..256da05 100644
--- a/lib/sup/modes/thread-index-mode.rb
+++ b/lib/sup/modes/thread_index_mode.rb
@@ -110,7 +110,7 @@ EOS
num = t.size
message = "Loading #{num.pluralize 'message body'}..."
BufferManager.say(message) do |sid|
- t.each_with_index do |(m, *o), i|
+ t.each_with_index do |(m, *_), i|
next unless m
BufferManager.say "#{message} (#{i}/#{num})", sid if t.size > 1
m.load_from_source!
@@ -247,7 +247,7 @@ EOS
def edit_message
return unless(t = cursor_thread)
- message, *crap = t.find { |m, *o| m.has_label? :draft }
+ message, *_ = t.find { |m, *o| m.has_label? :draft }
if message
mode = ResumeMode.new message
BufferManager.spawn "Edit message", mode
@@ -258,7 +258,6 @@ EOS
## returns an undo lambda
def actually_toggle_starred t
- pos = curpos
if t.has_label? :starred # if ANY message has a star
t.remove_label :starred # remove from all
UpdateManager.relay self, :unstarred, t.first
@@ -857,14 +856,14 @@ protected
abbrev =
if cur_width + name.display_length > from_width
- name[0 ... (from_width - cur_width - 1)] + "."
+ name.slice_by_display_length(from_width - cur_width - 1) + "."
elsif cur_width + name.display_length == from_width
- name[0 ... (from_width - cur_width)]
+ name.slice_by_display_length(from_width - cur_width)
else
if last
- name[0 ... (from_width - cur_width)]
+ name.slice_by_display_length(from_width - cur_width)
else
- name[0 ... (from_width - cur_width - 1)] + ","
+ name.slice_by_display_length(from_width - cur_width - 1) + ","
end
end
@@ -877,8 +876,9 @@ protected
from << [(newness ? :index_new_color : (starred ? :index_starred_color : :index_old_color)), abbrev]
end
- dp = t.direct_participants.any? { |p| AccountManager.is_account? p }
- p = dp || t.participants.any? { |p| AccountManager.is_account? p }
+ is_me = AccountManager.method(:is_account?)
+ directly_participated = t.direct_participants.any?(&is_me)
+ participated = directly_participated || t.participants.any?(&is_me)
subj_color =
if t.has_label?(:draft)
@@ -908,7 +908,7 @@ protected
[
[:size_widget_color, size_widget_text],
[:to_me_color, t.labels.member?(:attachment) ? "@" : " "],
- [:to_me_color, dp ? ">" : (p ? '+' : " ")],
+ [:to_me_color, directly_participated ? ">" : (participated ? '+' : " ")],
] +
(t.labels - @hidden_labels).sort_by {|x| x.to_s}.map {
|label| [Colormap.sym_is_defined("label_#{label}_color".to_sym) || :label_color, "#{label} "]
diff --git a/lib/sup/modes/thread-view-mode.rb b/lib/sup/modes/thread_view_mode.rb
similarity index 99%
rename from lib/sup/modes/thread-view-mode.rb
rename to lib/sup/modes/thread_view_mode.rb
index 9fcc45d..1ca352b 100644
--- a/lib/sup/modes/thread-view-mode.rb
+++ b/lib/sup/modes/thread_view_mode.rb
@@ -846,7 +846,11 @@ private
else
width = buffer.content_width
end
- lines = lines.map { |l| l.chomp.wrap width }.flatten
+ # lines can apparently be both String and Array, convert to Array for map.
+ if lines.kind_of? String
+ lines = lines.lines.to_a
+ end
+ lines = lines.map { |l| l.chomp.wrap width if l }.flatten
end
return lines
end
diff --git a/lib/sup/poll.rb b/lib/sup/poll.rb
index 7e05292..9c7f628 100644
--- a/lib/sup/poll.rb
+++ b/lib/sup/poll.rb
@@ -22,6 +22,8 @@ Variables:
num: the total number of new messages added in this poll
num_inbox: the number of new messages added in this poll which
appear in the inbox (i.e. were not auto-archived).
+ num_total: the total number of messages
+ num_inbox_total: the total number of new messages in the inbox.
num_inbox_total_unread: the total number of unread messages in the inbox
from_and_subj: an array of (from email address, subject) pairs
from_and_subj_inbox: an array of (from email address, subject) pairs for
@@ -33,7 +35,7 @@ EOS
@mutex = Mutex.new
@thread = nil
@last_poll = nil
- @polling = false
+ @polling = Mutex.new
@poll_sources = nil
@mode = nil
@should_clear_running_totals = false
@@ -43,40 +45,59 @@ EOS
def poll_with_sources
@mode ||= PollMode.new
- HookManager.run "before-poll"
- BufferManager.flash "Polling for new messages..."
+ if HookManager.enabled? "before-poll"
+ HookManager.run("before-poll")
+ else
+ BufferManager.flash "Polling for new messages..."
+ end
+
num, numi, from_and_subj, from_and_subj_inbox, loaded_labels = @mode.poll
clear_running_totals if @should_clear_running_totals
@running_totals[:num] += num
@running_totals[:numi] += numi
@running_totals[:loaded_labels] += loaded_labels || []
- if @running_totals[:num] > 0
- BufferManager.flash "Loaded #{@running_totals[:num].pluralize 'new message'}, #{@running_totals[:numi]} to inbox. Labels: #{@running_totals[:loaded_labels].map{|l| l.to_s}.join(', ')}"
+
+
+ if HookManager.enabled? "after-poll"
+ hook_args = { :num => num, :num_inbox => numi,
+ :num_total => @running_totals[:num], :num_inbox_total => @running_totals[:numi],
+ :from_and_subj => from_and_subj, :from_and_subj_inbox => from_and_subj_inbox,
+ :num_inbox_total_unread => lambda { Index.num_results_for :labels => [:inbox, :unread] } }
+
+ HookManager.run("after-poll", hook_args)
else
- BufferManager.flash "No new messages."
+ if @running_totals[:num] > 0
+ BufferManager.flash "Loaded #{@running_totals[:num].pluralize 'new message'}, #{@running_totals[:numi]} to inbox. Labels: #{@running_totals[:loaded_labels].map{|l| l.to_s}.join(', ')}"
+ else
+ BufferManager.flash "No new messages."
+ end
end
- HookManager.run "after-poll", :num => num, :num_inbox => numi, :from_and_subj => from_and_subj, :from_and_subj_inbox => from_and_subj_inbox, :num_inbox_total_unread => lambda { Index.num_results_for :labels => [:inbox, :unread] }
-
end
def poll
- return if @polling
- @polling = true
- @poll_sources = SourceManager.usual_sources
- num, numi = poll_with_sources
- @polling = false
- [num, numi]
+ if @polling.try_lock
+ @poll_sources = SourceManager.usual_sources
+ num, numi = poll_with_sources
+ @polling.unlock
+ [num, numi]
+ else
+ debug "poll already in progress."
+ return
+ end
end
def poll_unusual
- return if @polling
- @polling = true
- @poll_sources = SourceManager.unusual_sources
- num, numi = poll_with_sources
- @polling = false
- [num, numi]
+ if @polling.try_lock
+ @poll_sources = SourceManager.unusual_sources
+ num, numi = poll_with_sources
+ @polling.unlock
+ [num, numi]
+ else
+ debug "poll_unusual already in progress."
+ return
+ end
end
def start
@@ -142,7 +163,6 @@ EOS
loaded_labels = loaded_labels - LabelManager::HIDDEN_RESERVED_LABELS - [:inbox, :killed]
yield "Done polling; loaded #{total_num} new messages total"
@last_poll = Time.now
- @polling = false
end
[total_num, total_numi, from_and_subj, from_and_subj_inbox, loaded_labels]
end
@@ -151,42 +171,51 @@ EOS
## labels and locations set correctly. The Messages are saved to or removed
## from the index after being yielded.
def poll_from source, opts={}
- begin
- source.poll do |sym, args|
- case sym
- when :add
- m = Message.build_from_source source, args[:info]
- old_m = Index.build_message m.id
- m.labels += args[:labels]
- m.labels.delete :inbox if source.archived?
- m.labels.delete :unread if source.read?
- m.labels.delete :unread if m.source_marked_read? # preserve read status if possible
- m.labels.each { |l| LabelManager << l }
- m.labels = old_m.labels + (m.labels - [:unread, :inbox]) if old_m
- m.locations = old_m.locations + m.locations if old_m
- HookManager.run "before-add-message", :message => m
- yield :add, m, old_m, args[:progress] if block_given?
- Index.sync_message m, true
-
- ## We need to add or unhide the message when it either did not exist
- ## before at all or when it was updated. We do *not* add/unhide when
- ## the same message was found at a different location
- if !old_m or not old_m.locations.member? m.location
- UpdateManager.relay self, :added, m
- end
- when :delete
- Index.each_message :location => [source.id, args[:info]] do |m|
- m.locations.delete Location.new(source, args[:info])
- yield :delete, m, [source,args[:info]], args[:progress] if block_given?
- Index.sync_message m, false
- #UpdateManager.relay self, :deleted, m
+ debug "trying to acquire poll lock for: #{source}.."
+ if source.poll_lock.try_lock
+ debug "lock acquired for: #{source}."
+ begin
+ source.poll do |sym, args|
+ case sym
+ when :add
+ m = Message.build_from_source source, args[:info]
+ old_m = Index.build_message m.id
+ m.labels += args[:labels]
+ m.labels.delete :inbox if source.archived?
+ m.labels.delete :unread if source.read?
+ m.labels.delete :unread if m.source_marked_read? # preserve read status if possible
+ m.labels.each { |l| LabelManager << l }
+ m.labels = old_m.labels + (m.labels - [:unread, :inbox]) if old_m
+ m.locations = old_m.locations + m.locations if old_m
+ HookManager.run "before-add-message", :message => m
+ yield :add, m, old_m, args[:progress] if block_given?
+ Index.sync_message m, true
+
+ ## We need to add or unhide the message when it either did not exist
+ ## before at all or when it was updated. We do *not* add/unhide when
+ ## the same message was found at a different location
+ if !old_m or not old_m.locations.member? m.location
+ UpdateManager.relay self, :added, m
+ end
+ when :delete
+ Index.each_message :location => [source.id, args[:info]] do |m|
+ m.locations.delete Location.new(source, args[:info])
+ yield :delete, m, [source,args[:info]], args[:progress] if block_given?
+ Index.sync_message m, false
+ #UpdateManager.relay self, :deleted, m
+ end
end
end
- end
- source.go_idle
- rescue SourceError => e
- warn "problem getting messages from #{source}: #{e.message}"
+ rescue SourceError => e
+ warn "problem getting messages from #{source}: #{e.message}"
+
+ ensure
+ source.go_idle
+ source.poll_lock.unlock
+ end
+ else
+ debug "source #{source} is already being polled."
end
end
diff --git a/lib/sup/protocol.rb b/lib/sup/protocol.rb
deleted file mode 100644
index 573138b..0000000
--- a/lib/sup/protocol.rb
+++ /dev/null
@@ -1,161 +0,0 @@
-require 'eventmachine'
-require 'socket'
-require 'stringio'
-require 'yajl'
-
-class EM::P::Redwood < EM::Connection
- VERSION = 1
- ENCODINGS = %w(marshal json)
-
- attr_reader :debug
-
- def initialize *args
- @state = :negotiating
- @version_buf = ""
- @debug = false
- super
- end
-
- def receive_data data
- if @state == :negotiating
- @version_buf << data
- if i = @version_buf.index("\n")
- l = @version_buf.slice!(0..i)
- receive_version *parse_version(l.strip)
- x = @version_buf
- @version_buf = nil
- @state = :established
- connection_established
- receive_data x
- end
- else
- @filter.decode(data).each do |msg|
- puts "#{self.class.name} received: #{msg.inspect}" if @debug
- validate_message *msg
- receive_message *msg
- end
- end
- end
-
- def connection_established
- end
-
- def send_version encodings, extensions
- fail if encodings.empty?
- send_data "Redwood #{VERSION} #{encodings * ','} #{extensions.empty? ? :none : (extensions * ',')}\n"
- end
-
- def send_message type, tag, params={}
- fail "attempted to send message during negotiation" unless @state == :established
- puts "#{self.class.name} sent: #{[type, tag, params].inspect}" if @debug
- validate_message type, tag, params
- send_data @filter.encode([type,tag,params])
- end
-
- def receive_version l
- fail "unimplemented"
- end
-
- def receive_message type, tag, params
- fail "unimplemented"
- end
-
-private
-
- def validate_message type, tag, params
- fail unless type.is_a? String or type.is_a? Symbol
- fail unless tag.is_a? String or tag.is_a? Integer
- fail unless params.is_a? Hash
- end
-
- def parse_version l
- l =~ /^Redwood\s+(\d+)\s+([\w,]+)\s+([\w,]+)$/ or fail "unexpected banner #{l.inspect}"
- version, encodings, extensions = $1.to_i, $2, $3
- encodings = encodings.split ','
- extensions = extensions.split ','
- extensions = [] if extensions == ['none']
- fail unless version == VERSION
- fail if encodings.empty?
- [encodings, extensions]
- end
-
- def create_filter encoding
- case encoding
- when 'json' then JSONFilter.new
- when 'marshal' then MarshalFilter.new
- else fail "unknown encoding #{encoding.inspect}"
- end
- end
-
- class JSONFilter
- def initialize
- @parser = Yajl::Parser.new :check_utf8 => false
- end
-
- def decode chunk
- parsed = []
- @parser.on_parse_complete = lambda { |o| parsed << o }
- @parser << chunk
- parsed
- end
-
- def encode *os
- os.inject('') { |s, o| s << Yajl::Encoder.encode(o) }
- end
- end
-
- class MarshalFilter
- def initialize
- @buf = ''
- @state = :prefix
- @size = 0
- end
-
- def decode chunk
- received = []
- @buf << chunk
-
- begin
- if @state == :prefix
- break unless @buf.size >= 4
- prefix = @buf.slice!(0...4)
- @size = prefix.unpack('N')[0]
- @state = :data
- end
-
- fail unless @state == :data
- break if @buf.size < @size
- received << Marshal.load(@buf.slice!(0... at size))
- @state = :prefix
- end until @buf.empty?
-
- received
- end
-
- def encode o
- data = Marshal.dump o
- [data.size].pack('N') + data
- end
- end
-end
-
-class EM::P::RedwoodServer < EM::P::Redwood
- def post_init
- send_version ENCODINGS, []
- end
-
- def receive_version encodings, extensions
- fail unless encodings.size == 1
- fail unless ENCODINGS.member? encodings.first
- @filter = create_filter encodings.first
- end
-end
-
-class EM::P::RedwoodClient < EM::P::Redwood
- def receive_version encodings, extensions
- encoding = (ENCODINGS & encodings).first
- fail unless encoding
- @filter = create_filter encoding
- send_version [encoding], []
- end
-end
diff --git a/lib/sup/rfc2047.rb b/lib/sup/rfc2047.rb
index 8b987db..1b00f23 100644
--- a/lib/sup/rfc2047.rb
+++ b/lib/sup/rfc2047.rb
@@ -16,8 +16,6 @@
#
# This file is distributed under the same terms as Ruby.
-require 'iconv'
-
module Rfc2047
WORD = %r{=\?([!\#$%&'*+-/0-9A-Z\\^\`a-z{|}~]+)\?([BbQq])\?([!->@-~]+)\?=} # :nodoc: 'stupid ruby-mode
WORDSEQ = %r{(#{WORD.source})\s+(?=#{WORD.source})}
@@ -52,7 +50,7 @@ module Rfc2047
# WORD.
end
- Iconv.easy_decode(target, charset, text)
+ text.transcode(target, charset)
end
end
end
diff --git a/lib/sup/sent.rb b/lib/sup/sent.rb
index 0ca1fb1..05d9a8a 100644
--- a/lib/sup/sent.rb
+++ b/lib/sup/sent.rb
@@ -25,8 +25,13 @@ class SentManager
end
def write_sent_message date, from_email, &block
- @source.store_message date, from_email, &block
- PollManager.poll_from @source
+ ::Thread.new do
+ debug "store the sent message (locking sent source..)"
+ @source.poll_lock.synchronize do
+ @source.store_message date, from_email, &block
+ end
+ PollManager.poll_from @source
+ end
end
end
diff --git a/lib/sup/server.rb b/lib/sup/server.rb
deleted file mode 100644
index f2dde6a..0000000
--- a/lib/sup/server.rb
+++ /dev/null
@@ -1,116 +0,0 @@
-require 'sup/protocol'
-
-module Redwood
-
-class Server < EM::P::RedwoodServer
- def initialize index
- super
- @index = index
- end
-
- def receive_message type, tag, params
- if respond_to? :"request_#{type}"
- send :"request_#{type}", tag, params
- else
- send_message 'error', tag, 'description' => "invalid request type #{type.inspect}"
- end
- end
-
- def request_query tag, a
- q = @index.parse_query a['query']
- query q, a['offset'], a['limit'], a['raw'] do |r|
- send_message 'message', tag, r
- end
- send_message 'done', tag
- end
-
- def request_count tag, a
- q = @index.parse_query a['query']
- c = count q
- send_message 'count', tag, 'count' => c
- end
-
- def request_label tag, a
- q = @index.parse_query a['query']
- label q, a['add'], a['remove']
- send_message 'done', tag
- end
-
- def request_add tag, a
- add a['raw'], a['labels']
- send_message 'done', tag
- end
-
- def request_thread tag, a
- thread a['message_id'], a['raw'] do |r|
- send_message 'message', tag, r
- end
- send_message 'done', tag
- end
-
-private
-
- def result_from_message m, raw
- mkperson = lambda { |p| { :email => p.email, :name => p.name } }
- {
- 'summary' => {
- 'message_id' => m.id,
- 'date' => m.date,
- 'from' => mkperson[m.from],
- 'to' => m.to.map(&mkperson),
- 'cc' => m.cc.map(&mkperson),
- 'bcc' => m.bcc.map(&mkperson),
- 'subject' => m.subj,
- 'refs' => m.refs,
- 'replytos' => m.replytos,
- 'labels' => m.labels.map(&:to_s),
- },
- 'raw' => raw ? m.raw_message : nil,
- }
- end
-
- def query query, offset, limit, raw
- c = 0
- @index.each_message query do |m|
- next if c < offset
- break if c >= offset + limit if limit
- yield result_from_message(m, raw)
- c += 1
- end
- nil
- end
-
- def count query
- @index.num_results_for query
- end
-
- def label query, remove_labels, add_labels
- @index.each_message query do |m|
- remove_labels.each { |l| m.remove_label l }
- add_labels.each { |l| m.add_label l }
- @index.update_message_state m
- end
- nil
- end
-
- def add raw, labels
- SentManager.source.store_message Time.now, "test at example.com" do |io|
- io.write raw
- end
- PollManager.poll_from SentManager.source do |sym,m,old_m,progress|
- next unless sym == :add
- m.labels = labels
- end
- nil
- end
-
- def thread msg_id, raw
- msg = @index.build_message msg_id
- @index.each_message_in_thread_for msg do |id, builder|
- m = builder.call
- yield result_from_message(m, raw)
- end
- end
-end
-
-end
diff --git a/lib/sup/service/label_service.rb b/lib/sup/service/label_service.rb
new file mode 100644
index 0000000..1882c67
--- /dev/null
+++ b/lib/sup/service/label_service.rb
@@ -0,0 +1,45 @@
+require "sup/index"
+
+module Redwood
+ # Provides label tweaking service to the user.
+ # Working as the backend of ConsoleMode.
+ #
+ # Should become the backend of bin/sup-tweak-labels in the future.
+ class LabelService
+ # @param index [Redwood::Index]
+ def initialize index=Index.instance
+ @index = index
+ end
+
+ def add_labels query, *labels
+ run_on_each_message(query) do |m|
+ labels.each {|l| m.add_label l }
+ end
+ end
+
+ def remove_labels query, *labels
+ run_on_each_message(query) do |m|
+ labels.each {|l| m.remove_label l }
+ end
+ end
+
+
+ private
+ def run_on_each_message query, &operation
+ count = 0
+
+ find_messages(query).each do |m|
+ operation.call(m)
+ @index.update_message_state m
+ count += 1
+ end
+
+ @index.save_index
+ count
+ end
+
+ def find_messages query
+ @index.find_messages(query)
+ end
+ end
+end
diff --git a/lib/sup/source.rb b/lib/sup/source.rb
index e0aa90e..c590477 100644
--- a/lib/sup/source.rb
+++ b/lib/sup/source.rb
@@ -22,30 +22,23 @@ class Source
## read, delete them, or anything else. (Well, it's nice to be able
## to delete them, but that is optional.)
##
- ## On the other hand, Sup assumes that you can assign each message a
- ## unique integer id, such that newer messages have higher ids than
- ## earlier ones, and that those ids stay constant across sessions
- ## (in the absence of some other client going in and fucking
- ## everything up). For example, for mboxes I use the file offset of
- ## the start of the message. If a source does NOT have that
- ## capability, e.g. IMAP, then you have to do a little more work to
- ## simulate it.
+ ## Messages are identified internally based on the message id, and stored
+ ## with an unique document id. Along with the message, source information
+ ## that can contain arbitrary fields (set up by the source) is stored. This
+ ## information will be passed back to the source when a message in the
+ ## index (Sup database) needs to be identified to its source, e.g. when
+ ## re-reading or modifying a unique message.
##
## To write a new source, subclass this class, and implement:
##
- ## - start_offset
- ## - end_offset (exclusive!) (or, #done?)
+ ## - initialize
## - load_header offset
## - load_message offset
## - raw_header offset
## - raw_message offset
- ## - check (optional)
+ ## - store_message (optional)
+ ## - poll (loads new messages)
## - go_idle (optional)
- ## - next (or each, if you prefer): should return a message and an
- ## array of labels.
- ##
- ## ... where "offset" really means unique id. (You can tell I
- ## started with mbox.)
##
## All exceptions relating to accessing the source must be caught
## and rethrown as FatalSourceErrors or OutOfSyncSourceErrors.
@@ -57,12 +50,11 @@ class Source
## Finally, be sure the source is thread-safe, since it WILL be
## pummelled from multiple threads at once.
##
- ## Examples for you to look at: mbox/loader.rb, imap.rb, and
- ## maildir.rb.
+ ## Examples for you to look at: mbox.rb and maildir.rb.
bool_accessor :usual, :archived
attr_reader :uri
- attr_accessor :id
+ attr_accessor :id, :poll_lock
def initialize uri, usual=true, archived=false, id=nil
raise ArgumentError, "id must be an integer: #{id.inspect}" unless id.is_a? Fixnum if id
@@ -71,6 +63,8 @@ class Source
@usual = usual
@archived = archived
@id = id
+
+ @poll_lock = Mutex.new
end
## overwrite me if you have a disk incarnation (currently used only for sup-sync-back)
@@ -160,7 +154,7 @@ module SerializeLabelsNicely
end
def after_unmarshal!
- @labels = Set.new(@labels.map { |s| s.to_sym })
+ @labels = Set.new(@labels.to_a.map { |s| s.to_sym })
end
end
@@ -209,9 +203,9 @@ class SourceManager
end
end
- def save_sources fn=Redwood::SOURCE_FN
+ def save_sources fn=Redwood::SOURCE_FN, force=false
@source_mutex.synchronize do
- if @sources_dirty
+ if @sources_dirty || force
Redwood::save_yaml_obj sources, fn, false, true
end
@sources_dirty = false
diff --git a/lib/sup/textfield.rb b/lib/sup/textfield.rb
index 343e450..c69d3e3 100644
--- a/lib/sup/textfield.rb
+++ b/lib/sup/textfield.rb
@@ -168,6 +168,16 @@ private
else # trailing spaces
v + (" " * (x - @question.length - v.length))
end
+
+ # ncurses returns a ASCII-8BIT (binary) string, which
+ # bytes presumably are of current charset encoding. we force_encoding
+ # so that the char representation / string is tagged will be the
+ # system locale and also hopefully the terminal/input encoding. an
+ # incorrectly configured terminal encoding (not matching the system
+ # encoding) will produce erronous results, but will also do that for
+ # a log of other programs since it is impossible to detect which is
+ # which and what encoding the inputted byte chars are supposed to have.
+ v.force_encoding($encoding).fix_encoding
end
def remove_extra_space
diff --git a/lib/sup/util.rb b/lib/sup/util.rb
index cd68fe0..5cff6fa 100644
--- a/lib/sup/util.rb
+++ b/lib/sup/util.rb
@@ -1,3 +1,5 @@
+# encoding: utf-8
+
require 'thread'
require 'lockfile'
require 'mime/types'
@@ -5,6 +7,7 @@ require 'pathname'
require 'set'
require 'enumerator'
require 'benchmark'
+require 'unicode'
## time for some monkeypatching!
class Symbol
@@ -30,7 +33,7 @@ class Lockfile
def dump_lock_id lock_id = @lock_id
"host: %s\npid: %s\nppid: %s\ntime: %s\nuser: %s\npname: %s\n" %
lock_id.values_at('host','pid','ppid','time','user', 'pname')
- end
+ end
def lockinfo_on_disk
h = load_lock_id IO.read(path)
@@ -113,6 +116,25 @@ module RMail
end
class Header
+
+ # Convert to ASCII before trying to match with regexp
+ class Field
+
+ EXTRACT_FIELD_NAME_RE = /\A([^\x00-\x1f\x7f-\xff :]+):\s*/no
+
+ class << self
+ def parse(field)
+ field = field.dup.to_s
+ field = field.fix_encoding.ascii
+ if field =~ EXTRACT_FIELD_NAME_RE
+ [ $1, $'.chomp ]
+ else
+ [ "", Field.value_strip(field) ]
+ end
+ end
+ end
+ end
+
## Be more cautious about invalid content-type headers
## the original RMail code calls
## value.strip.split(/\s*;\s*/)[0].downcase
@@ -233,14 +255,14 @@ class Object
end
class String
- ## nasty multibyte hack for ruby 1.8. if it's utf-8, split into chars using
- ## the utf8 regex and count those. otherwise, use the byte length.
def display_length
- if RUBY_VERSION < '1.9.1' && ($encoding == "UTF-8" || $encoding == "utf8")
- # scan hack is somewhat slow, worth trying to cache
- @display_length ||= scan(/./u).size
- else
- size
+ @display_length ||= Unicode.width(self, false)
+ end
+
+ def slice_by_display_length len
+ each_char.each_with_object "" do |c, buffer|
+ len -= c.display_length
+ buffer << c if len >= 0
end
end
@@ -327,20 +349,69 @@ class String
def wrap len
ret = []
s = self
- while s.length > len
- cut = s[0 ... len].rindex(/\s/)
+ while s.display_length > len
+ cut = s.slice_by_display_length(len).rindex(/\s/)
if cut
ret << s[0 ... cut]
s = s[(cut + 1) .. -1]
else
- ret << s[0 ... len]
- s = s[len .. -1]
+ ret << s.slice_by_display_length(len)
+ s = s[ret.last.length .. -1]
end
end
ret << s
end
+ # Fix the damn string! make sure it is valid utf-8, then convert to
+ # user encoding.
+ #
+ # Not Ruby 1.8 compatible
+ def fix_encoding
+ # first try to encode to utf-8 from whatever current encoding
+ encode!('UTF-8', :invalid => :replace, :undef => :replace)
+
+ # do this anyway in case string is set to be UTF-8, encoding to
+ # something else (UTF-16 which can fully represent UTF-8) and back
+ # ensures invalid chars are replaced.
+ encode!('UTF-16', 'UTF-8', :invalid => :replace, :undef => :replace)
+ encode!('UTF-8', 'UTF-16', :invalid => :replace, :undef => :replace)
+
+ fail "Could not create valid UTF-8 string out of: '#{self.to_s}'." unless valid_encoding?
+
+ # now convert to $encoding
+ encode!($encoding, :invalid => :replace, :undef => :replace)
+
+ fail "Could not create valid #{$encoding.inspect} string out of: '#{self.to_s}'." unless valid_encoding?
+
+ self
+ end
+
+ # transcode the string if original encoding is know
+ # fix if broken.
+ #
+ # Not Ruby 1.8 compatible
+ def transcode to_encoding, from_encoding
+ begin
+ encode!(to_encoding, from_encoding, :invalid => :replace, :undef => :replace)
+
+ unless valid_encoding?
+ # fix encoding (through UTF-8)
+ encode!('UTF-16', from_encoding, :invalid => :replace, :undef => :replace)
+ encode!(to_encoding, 'UTF-16', :invalid => :replace, :undef => :replace)
+ end
+
+ rescue Encoding::ConverterNotFoundError
+ debug "Encoding converter not found for #{from_encoding.inspect} or #{to_encoding.inspect}, fixing string: '#{self.to_s}', but expect weird characters."
+ fix_encoding
+ end
+
+ fail "Could not create valid #{to_encoding.inspect} string out of: '#{self.to_s}'." unless valid_encoding?
+
+ self
+ end
+
def normalize_whitespace
+ fix_encoding
gsub(/\t/, " ").gsub(/\r/, "")
end
@@ -382,12 +453,8 @@ class String
out << b.chr
end
end
- out.force_encoding Encoding::UTF_8 if out.respond_to? :force_encoding
- out
- end
-
- def transcode src_encoding=$encoding
- Iconv.easy_decode $encoding, src_encoding, self
+ out = out.fix_encoding # this should now be an utf-8 string of ascii
+ # compat chars.
end
unless method_defined? :ascii_only?
@@ -658,27 +725,3 @@ class FinishLine
end
end
-class Iconv
- def self.easy_decode target, orig_charset, text
- if text.respond_to? :force_encoding
- text = text.dup
- text.force_encoding Encoding::BINARY
- end
- charset = case orig_charset
- when /UTF[-_ ]?8/i then "utf-8"
- when /(iso[-_ ])?latin[-_ ]?1$/i then "ISO-8859-1"
- when /iso[-_ ]?8859[-_ ]?15/i then 'ISO-8859-15'
- when /unicode[-_ ]1[-_ ]1[-_ ]utf[-_]7/i then "utf-7"
- when /^euc$/i then 'EUC-JP' # XXX try them all?
- when /^(x-unknown|unknown[-_ ]?8bit|ascii[-_ ]?7[-_ ]?bit)$/i then 'ASCII'
- else orig_charset
- end
-
- begin
- returning(Iconv.iconv(target + "//IGNORE", charset, text + " ").join[0 .. -2]) { |str| str.check }
- rescue Errno::EINVAL, Iconv::InvalidEncoding, Iconv::InvalidCharacter, Iconv::IllegalSequence, String::CheckError
- debug "couldn't transcode text from #{orig_charset} (#{charset}) to #{target} (#{text[0 ... 20].inspect}...): got #{$!.class} (#{$!.message})"
- text.ascii
- end
- end
-end
diff --git a/lib/sup/util/path.rb b/lib/sup/util/path.rb
new file mode 100644
index 0000000..3e24ff7
--- /dev/null
+++ b/lib/sup/util/path.rb
@@ -0,0 +1,9 @@
+module Redwood
+ module Util
+ module Path
+ def self.expand(path)
+ ::File.expand_path(path)
+ end
+ end
+ end
+end
diff --git a/lib/sup/util/query.rb b/lib/sup/util/query.rb
new file mode 100644
index 0000000..534cfab
--- /dev/null
+++ b/lib/sup/util/query.rb
@@ -0,0 +1,14 @@
+module Redwood
+ module Util
+ module Query
+ class QueryDescriptionError < ArgumentError; end
+
+ def self.describe query
+ d = query.description.force_encoding("UTF-8")
+
+ raise QueryDescriptionError.new(d) unless d.valid_encoding?
+ return d
+ end
+ end
+ end
+end
diff --git a/lib/sup/util/uri.rb b/lib/sup/util/uri.rb
new file mode 100644
index 0000000..dfb27b3
--- /dev/null
+++ b/lib/sup/util/uri.rb
@@ -0,0 +1,15 @@
+require "uri"
+
+require "sup/util/path"
+
+module Redwood
+ module Util
+ module Uri
+ def self.build(components)
+ components = components.dup
+ components[:path] = Path.expand(components[:path])
+ ::URI::Generic.build(components)
+ end
+ end
+ end
+end
diff --git a/lib/sup/version.rb b/lib/sup/version.rb
new file mode 100644
index 0000000..4f58b72
--- /dev/null
+++ b/lib/sup/version.rb
@@ -0,0 +1,3 @@
+module Redwood
+ VERSION = "0.14.0"
+end
diff --git a/protocol.md b/protocol.md
deleted file mode 100644
index 1d070a5..0000000
--- a/protocol.md
+++ /dev/null
@@ -1,168 +0,0 @@
-Redwood Protocol
-================
-
-The server begins by sending a line of the form `Redwood <ver> <encodings>
-<extensions>`, where `ver` is the major protocol version (1), encodings is a
-comma-separated list of supported message encodings (e.g. `json,bert,marshal`),
-and `extensions` is a comma-separated list of protocol extensions. The server
-must advertise at least one encoding. A zero-length list of extensions is
-represented by `none`. The client replies in the same format, with the
-restrictions that the protocol version must match, `encodings` and `extensions`
-must be subsets of what the server advertised, and there must be exactly 1
-encoding specified.
-
-Requests and responses are represented as `[type, params]`, where `type`
-is a lowercase string corresponding to one of the message types specified
-below and `params` is a dictionary with string keys.
-
-Requests
---------
-
-There may be zero or more replies to a request. Multiple requests may be
-issued concurrently. There is an implicit, optional, opaque `tag` parameter to
-every request which will be returned in all replies to the request to
-aid clients in keeping multiple requests in flight. `tag` may be an
-arbitrary datastructure and for the purposes of Cancel defaults to nil.
-
-### Query
-Send a Message response for each hit on `query` starting at `offset`
-and sending a maximum of `limit` Messages responses. `raw` controls
-whether the raw message text is included in the response.
-
-#### Parameters
-* `query`: Query
-* `offset`: int
-* `limit`: int
-* `raw`: boolean
-
-#### Responses
-* multiple Message
-* one Done after all Messages
-
-
-### Count
-Send a count reply with the number of hits for `query`.
-
-#### Parameters
-* `query`: Query
-
-#### Responses
-* one Count
-
-
-### Label
-Modify the labels on all messages matching `query`. First removes the
-labels in `remove` then adds those in `add`.
-
-#### Parameters
-* `query`: Query
-* `add`: string list
-* `remove`: string list
-
-#### Responses
-* one Done
-
-
-### Add
-Add a message to the database. `raw` is the normal RFC 2822 message text.
-
-#### Parameters
-* `raw`: string
-* `labels`: string list
-
-#### Responses
-* one Done
-
-
-### Stream
-Sends a Message response whenever a new message that matches `query` is
-added with the Add request. This request will not terminate until a
-corresponding Cancel request is sent.
-
-#### Parameters
-* `query`: Query
-
-#### Responses
-multiple Message
-
-
-### Cancel
-Cancels all active requests with tag `target`. This is only required to
-be implemented for the Stream request.
-
-#### Parameters
-* `target`: string
-
-#### Responses
-one Done
-
-
-
-Responses
----------
-
-### Done
-Signifies that a request has completed successfully.
-
-
-### Message
-Represents a query result. If `raw` is present it is the raw message
-text that was previously a parameter to the Add request.
-
-#### Parameters
-* `summary`: Summary
-* `raw`: optional string
-
-
-### Count
-`count` is the number of messages matched.
-
-#### Parameters
-* `count`: int
-
-
-### Error
-
-#### Parameters
-* `type`: string
-* `message`: string
-
-
-
-Datatypes
----------
-
-### Query
-Recursive prefix-notation datastructure describing a boolean condition.
-Where `a` and `b` are Queries and `field` and `value` are strings, a
-Query can be any of the following:
-
-* `[:and, a, b, ...]`
-* `[:or, a, b, ...]`
-* `[:not, a, b]`
-* `[:term, field, value]`
-
-
-### Summary
-* `message_id`: string
-* `date`: time
-* `from`: Person
-* `to`, `cc`, `bcc`: Person list
-* `subject`: string
-* `refs`: string list
-* `replytos`: string list
-* `labels`: string list
-
-
-### Person
-* `name`: string
-* `email`: string
-
-
-TODO
-----
-
-* Protocol negotiation
- - Version
- - Compression (none, gzip, ...)
-* Specify string encodings
diff --git a/release-script.txt b/release-script.txt
deleted file mode 100644
index 4063139..0000000
--- a/release-script.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-Just a few simple steps to make a new release.
-
-vi History.txt
-vi ReleaseNotes
-vi www/index.html # and bump version number
-git rank-contributors -n -o > CONTRIBUTORS
-vi CONTRIBUTORS # and merge
-vi www/index.html # and include CONTRIBUTORS
-# ... git add, commit, etc
-git checkout -b release-<releasename>
-vi lib/sup.rb bin/* # and bump version numbers in all files
-# ... git add, commit, etc
-rake gem
-rake tarball
-gem push pkg/<gem name> # now using gemcutter
-git publish-branch
-rake upload_webpage
diff --git a/sup-files.rb b/sup-files.rb
deleted file mode 100644
index 2c7d874..0000000
--- a/sup-files.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-SUP_LIB_DIRS = %w(lib lib/sup lib/sup/modes)
-SUP_EXECUTABLES = %w(sup sup-add sup-cmd sup-config sup-dump sup-import-dump sup-recover-sources sup-server sup-sync sup-sync-back sup-tweak-labels)
-SUP_EXTRA_FILES = %w(CONTRIBUTORS README.txt LICENSE History.txt ReleaseNotes)
-SUP_FILES =
- SUP_EXTRA_FILES +
- SUP_EXECUTABLES.map { |f| "bin/#{f}" } +
- SUP_LIB_DIRS.map { |d| Dir["#{d}/*.rb"] }.flatten
-
-if $0 == __FILE__ # if executed from commandline
- puts SUP_FILES
-end
diff --git a/sup-version.rb b/sup-version.rb
deleted file mode 100644
index 1a10ed2..0000000
--- a/sup-version.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-## allow people who use development versions by running "rake gem"
-## and installing the resulting gem it to be able to do this. (gem
-## versions must be in dotted-digit notation only and can be passed
-## with the REL environment variable to "rake gem").
-SUP_VERSION = if ENV['REL']
- ENV['REL']
-else
- $:.unshift 'lib' # force loading from ./lib/ if it exists
- require 'sup'
- if Redwood::VERSION == "git"
- "999"
- else
- Redwood::VERSION
- end
-end
diff --git a/sup.gemspec b/sup.gemspec
new file mode 100644
index 0000000..130e1aa
--- /dev/null
+++ b/sup.gemspec
@@ -0,0 +1,66 @@
+lib = File.expand_path("../lib", __FILE__)
+$:.unshift(lib) unless $:.include?(lib)
+
+require 'sup/version'
+
+# Files
+SUP_EXECUTABLES = %w(sup sup-add sup-config sup-dump sup-import-dump
+ sup-recover-sources sup-sync sup-sync-back sup-tweak-labels
+ sup-psych-ify-config-files)
+SUP_EXTRA_FILES = %w(CONTRIBUTORS README.md LICENSE History.txt ReleaseNotes)
+SUP_FILES =
+ SUP_EXTRA_FILES +
+ SUP_EXECUTABLES.map { |f| "bin/#{f}" } +
+ Dir["lib/**/*.rb"]
+
+
+module Redwood
+ Gemspec = Gem::Specification.new do |s|
+ s.name = "sup"
+ s.version = ENV["REL"] || (::Redwood::VERSION == "git" ? "999" : ::Redwood::VERSION)
+ s.date = Time.now.strftime "%Y-%m-%d"
+ s.authors = ["William Morgan", "Gaute Hope", "Hamish Downer", "Matthieu Rakotojaona"]
+ s.email = "sup-talk at rubyforge.org"
+ s.summary = "A console-based email client with the best features of GMail, mutt and Emacs"
+ s.homepage = "http://supmua.org"
+ s.description = <<-DESC
+ Sup is a console-based email client for people with a lot of email.
+
+ * GMail-like thread-centered archiving, tagging and muting
+ * Handling mail from multiple mbox and Maildir sources
+ * Blazing fast full-text search with a rich query language
+ * Multiple accounts - pick the right one when sending mail
+ * Ruby-programmable hooks
+ * Automatically tracking recent contacts
+DESC
+ s.license = 'GPL-2'
+ # TODO: might want to add index migrating script here, too
+ s.post_install_message = <<-EOF
+SUP: Please run `sup-psych-ify-config-files` to migrate from 0.13 to 0.14.
+
+SUP: Check https://github.com/sup-heliotrope/sup/wiki/Migration-0.13-to-0.14
+ for more detailed up-to-date instructions.
+ EOF
+ s.files = SUP_FILES
+ s.executables = SUP_EXECUTABLES
+
+ s.required_ruby_version = '>= 1.9.2'
+
+ s.add_runtime_dependency "xapian-ruby", "~> 1.2.15"
+ s.add_runtime_dependency "ncursesw-sup", "~> 1.3.1"
+ s.add_runtime_dependency "rmail", ">= 0.17"
+ s.add_runtime_dependency "highline"
+ s.add_runtime_dependency "trollop", ">= 1.12"
+ s.add_runtime_dependency "lockfile"
+ s.add_runtime_dependency "mime-types", "~> 1.0"
+ s.add_runtime_dependency "locale", "~> 2.0"
+ s.add_runtime_dependency "chronic", "~> 0.9.1"
+ s.add_runtime_dependency "unicode", "~> 0.4.4"
+
+ s.add_development_dependency "bundler", "~> 1.3"
+ s.add_development_dependency "rake"
+ s.add_development_dependency "minitest", "~> 4.7"
+ s.add_development_dependency "rr", "~> 1.0.5"
+ s.add_development_dependency "gpgme", ">= 2.0.2"
+ end
+end
diff --git a/test/dummy_source.rb b/test/dummy_source.rb
index da26e44..abedf71 100644
--- a/test/dummy_source.rb
+++ b/test/dummy_source.rb
@@ -12,7 +12,7 @@ class DummySource < Source
attr_accessor :messages
def initialize uri, last_date=nil, usual=true, archived=false, id=nil, labels=[]
- super uri, last_date, usual, archived, id
+ super uri, usual, archived, id
@messages = nil
end
diff --git a/test/gnupg_test_home/gpg.conf b/test/gnupg_test_home/gpg.conf
new file mode 100644
index 0000000..b590914
--- /dev/null
+++ b/test/gnupg_test_home/gpg.conf
@@ -0,0 +1 @@
+default-key 789E7011
diff --git a/test/gnupg_test_home/pubring.gpg b/test/gnupg_test_home/pubring.gpg
new file mode 100644
index 0000000..3f604d7
Binary files /dev/null and b/test/gnupg_test_home/pubring.gpg differ
diff --git a/test/gnupg_test_home/receiver_pubring.gpg b/test/gnupg_test_home/receiver_pubring.gpg
new file mode 100644
index 0000000..84cbdc3
Binary files /dev/null and b/test/gnupg_test_home/receiver_pubring.gpg differ
diff --git a/test/gnupg_test_home/receiver_secring.gpg b/test/gnupg_test_home/receiver_secring.gpg
new file mode 100644
index 0000000..d92f0b8
Binary files /dev/null and b/test/gnupg_test_home/receiver_secring.gpg differ
diff --git a/test/gnupg_test_home/receiver_trustdb.gpg b/test/gnupg_test_home/receiver_trustdb.gpg
new file mode 100644
index 0000000..937117c
Binary files /dev/null and b/test/gnupg_test_home/receiver_trustdb.gpg differ
diff --git a/test/gnupg_test_home/secring.gpg b/test/gnupg_test_home/secring.gpg
new file mode 100644
index 0000000..513777c
Binary files /dev/null and b/test/gnupg_test_home/secring.gpg differ
diff --git a/test/gnupg_test_home/sup-test-2 at foo.bar.asc b/test/gnupg_test_home/sup-test-2 at foo.bar.asc
new file mode 100644
index 0000000..26e24d5
--- /dev/null
+++ b/test/gnupg_test_home/sup-test-2 at foo.bar.asc
@@ -0,0 +1,20 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v2.0.20 (GNU/Linux)
+
+mI0EUgi0fAEEAOLAcQW96NEUSB7YE/la8X56jGW5BMX3aAixOF8LvOwMBbUK1T+U
+0H2PGIrXVcYyHcPqWRpRahbsIAldBqzffPlzMa+aqJaB1xKkNruxSoIzwPdidZMe
+l0Dxz2FDsoXD0KPyWnAYhGmQyz2MFpZxu2tlYqvwWVW//XGnk/KHvIXbABEBAAG0
+PlN1cCBUZXN0IFJlY2VpdmVyIChUZXN0IHJlY2VpdmVyIGZvciBTdXApIDxzdXAt
+dGVzdC0yQGZvby5iYXI+iL8EEwECACkFAlIItHwCGwMFCQHhM4AHCwkIBwMCAQYV
+CAIJCgsEFgIDAQIeAQIXgAAKCRAsABl+cWpykMMVBADHkQPgTz0CqKKp3k+z3dbm
+ocmI4tYNn1dOkDQqyfoBTfs6L3g4j5OE2UrguntRYyg5oon+uO5d18CQ5dY0sCw/
+o5IwyzTrxI8IocbtZvBdSb+XjLndynGuIQoqaJq9i6n1V4klFHVOna8Q9JstLfRX
+H1d4xPhnvKcaDDx/NV3X/biNBFIItHwBBADBpb43MpkrUWlg7HWJ1ZfOlxnOxrJ3
+Gz9WFNV06UbcZEuFKA/vHRjM6gWzUn5903FLuCWu3eBrq5xQfWipbp187PmocpoG
+skJ6gosLs1fMYRBjv2VbG9xJVKdKJMjqZw5FUpXKAaHr8P9jN6g2STQrbeQ8CVUK
+h7zOWRXAXSKUgwARAQABiKUEGAECAA8FAlIItHwCGwwFCQHhM4AACgkQLAAZfnFq
+cpDV1QQAzcxFXznEX92DjWxWRC7gRHgIsQk9WJnDzjtnDjSWCp3H85qeTZGZrn9W
+NoneV/S5Y7K3Mkceh4rFaANQ3zx4b05y1LFt5N/lPwIe5VB0vcPumtZum2fSGfpK
+nTXvzelcWcm2aGyUSaWvOkntWKEEt1kB5Oq6EtZoRZLMzAxLd7s=
+=aKsV
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/test/gnupg_test_home/trustdb.gpg b/test/gnupg_test_home/trustdb.gpg
new file mode 100644
index 0000000..8666c17
Binary files /dev/null and b/test/gnupg_test_home/trustdb.gpg differ
diff --git a/test/integration/test_label_service.rb b/test/integration/test_label_service.rb
new file mode 100644
index 0000000..a05b42d
--- /dev/null
+++ b/test/integration/test_label_service.rb
@@ -0,0 +1,18 @@
+require "test_helper"
+
+require "sup/service/label_service"
+
+require "tmpdir"
+
+describe Redwood::LabelService do
+ let(:tmpdir) { Dir.mktmpdir }
+ after do
+ require "fileutils"
+ FileUtils.remove_entry_secure @tmpdir unless @tmpdir.nil?
+ end
+
+ describe "#add_labels" do
+ # Integration tests are hard to write at this moment :(
+ it "add labels to all messages matching the query"
+ end
+end
diff --git a/test/test_crypto.rb b/test/test_crypto.rb
new file mode 100644
index 0000000..ae5b6eb
--- /dev/null
+++ b/test/test_crypto.rb
@@ -0,0 +1,109 @@
+# tests for sup's crypto libs
+#
+# Copyright Clint Byrum <clint at ubuntu.com> 2011. All Rights Reserved.
+# Copyright Sup Developers 2013.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+
+require 'test_helper'
+require 'sup'
+require 'stringio'
+require 'tmpdir'
+
+module Redwood
+
+class TestCryptoManager < ::Minitest::Unit::TestCase
+
+ def setup
+ @from_email = 'sup-test-1 at foo.bar'
+ @to_email = 'sup-test-2 at foo.bar'
+ # Use test gnupg setup
+ @orig_gnupghome = ENV['GNUPGHOME']
+ ENV['GNUPGHOME'] = File.join(File.dirname(__FILE__), 'gnupg_test_home')
+
+ @path = Dir.mktmpdir
+ Redwood::HookManager.init File.join(@path, 'hooks')
+
+ am = {:default=> {:name => "test", :email=> 'sup-test-1 at foo.bar'}}
+ Redwood::AccountManager.init am
+
+ Redwood::CryptoManager.init
+
+ if not CryptoManager.have_crypto?
+ warn "No crypto set up, crypto will not be tested. Reason: #{CryptoManager.not_working_reason}"
+ end
+ end
+
+ def teardown
+ CryptoManager.deinstantiate!
+ AccountManager.deinstantiate!
+ HookManager.deinstantiate!
+ FileUtils.rm_r @path
+
+ ENV['GNUPGHOME'] = @orig_gnupghome
+ end
+
+ def test_sign
+ if CryptoManager.have_crypto? then
+ signed = CryptoManager.sign @from_email, at to_email,"ABCDEFG"
+ assert_instance_of RMail::Message, signed
+ assert_equal "ABCDEFG", signed.body[0]
+ assert signed.body[1].body.length > 0 , "signature length must be > 0"
+ assert (signed.body[1].body.include? "-----BEGIN PGP SIGNATURE-----") , "Expecting PGP armored data"
+ end
+ end
+
+ def test_encrypt
+ if CryptoManager.have_crypto? then
+ encrypted = CryptoManager.encrypt @from_email, [@to_email], "ABCDEFG"
+ assert_instance_of RMail::Message, encrypted
+ assert (encrypted.body[1].body.include? "-----BEGIN PGP MESSAGE-----") , "Expecting PGP armored data"
+ end
+ end
+
+ def test_sign_and_encrypt
+ if CryptoManager.have_crypto? then
+ encrypted = CryptoManager.sign_and_encrypt @from_email, [@to_email], "ABCDEFG"
+ assert_instance_of RMail::Message, encrypted
+ assert (encrypted.body[1].body.include? "-----BEGIN PGP MESSAGE-----") , "Expecting PGP armored data"
+ end
+ end
+
+ def test_decrypt
+ if CryptoManager.have_crypto? then
+ encrypted = CryptoManager.encrypt @from_email, [@to_email], "ABCDEFG"
+ assert_instance_of RMail::Message, encrypted
+ assert_instance_of String, (encrypted.body[1].body)
+ decrypted = CryptoManager.decrypt encrypted.body[1], true
+ assert_instance_of Array, decrypted
+ assert_instance_of Chunk::CryptoNotice, decrypted[0]
+ assert_instance_of Chunk::CryptoNotice, decrypted[1]
+ assert_instance_of RMail::Message, decrypted[2]
+ assert_equal "ABCDEFG" , decrypted[2].body
+ end
+ end
+
+ def test_verify
+ if CryptoManager.have_crypto?
+ signed = CryptoManager.sign @from_email, @to_email, "ABCDEFG"
+ assert_instance_of RMail::Message, signed
+ assert_instance_of String, (signed.body[1].body)
+ CryptoManager.verify signed.body[0], signed.body[1], true
+ end
+ end
+end
+
+end
diff --git a/test/test_header_parsing.rb b/test/test_header_parsing.rb
index 1929e07..a2aa2a2 100644
--- a/test/test_header_parsing.rb
+++ b/test/test_header_parsing.rb
@@ -1,16 +1,20 @@
#!/usr/bin/ruby
-require 'test/unit'
+require 'test_helper'
require 'sup'
require 'stringio'
include Redwood
-class TestMBoxParsing < Test::Unit::TestCase
+class TestMBoxParsing < Minitest::Unit::TestCase
+
def setup
+ @path = Dir.mktmpdir
+ @mbox = File.join(@path, 'test_mbox')
end
def teardown
+ FileUtils.rm_r @path
end
def test_normal_headers
@@ -106,7 +110,7 @@ EOS
end
def test_from_line_splitting
- l = MBox.new StringIO.new(<<EOS)
+ l = MBox.new mbox_for_string(<<EOS)
From sup-talk-bounces at rubyforge.org Mon Apr 27 12:56:18 2009
From: Bob <bob at bob.com>
To: a dear friend
@@ -125,14 +129,14 @@ From bob at bob.com
This is the end of the email.
EOS
- offset, labels = l.next
- assert_equal 0, offset
- offset, labels = l.next
+ offset = l.next_offset 0
+ assert_equal 61, offset
+ offset = l.next_offset 61
assert_nil offset
end
def test_more_from_line_splitting
- l = MBox.new StringIO.new(<<EOS)
+ l = MBox.new mbox_for_string(<<EOS)
From sup-talk-bounces at rubyforge.org Mon Apr 27 12:56:18 2009
From: Bob <bob at bob.com>
To: a dear friend
@@ -145,13 +149,20 @@ To: a dear friend
Hello again! Would you like to buy my products?
EOS
- offset, labels = l.next
- assert_not_nil offset
+ offset = l.next_offset 0
+ refute_nil offset
- offset, labels = l.next
- assert_not_nil offset
+ offset = l.next_offset offset
+ refute_nil offset
- offset, labels = l.next
+ offset = l.next_offset offset
assert_nil offset
end
+
+ def mbox_for_string content
+ File.open(@mbox, 'w') do |f|
+ f.write content
+ end
+ "mbox://#{@mbox}"
+ end
end
diff --git a/test/test_helper.rb b/test/test_helper.rb
new file mode 100644
index 0000000..adb09b7
--- /dev/null
+++ b/test/test_helper.rb
@@ -0,0 +1,7 @@
+require "rubygems" rescue nil
+require 'minitest/autorun'
+require "rr"
+
+class Minitest::Unit::TestCase
+ include ::RR::Adapters::MiniTest
+end
diff --git a/test/test_message.rb b/test/test_message.rb
index 94b962a..6283174 100644
--- a/test/test_message.rb
+++ b/test/test_message.rb
@@ -1,6 +1,6 @@
#!/usr/bin/ruby
-require 'test/unit'
+require 'test_helper'
require 'sup'
require 'stringio'
@@ -26,12 +26,16 @@ end
module Redwood
-class TestMessage < Test::Unit::TestCase
+class TestMessage < ::Minitest::Unit::TestCase
def setup
+ @path = Dir.mktmpdir
+ Redwood::HookManager.init File.join(@path, 'hooks')
end
def teardown
+ Redwood::HookManager.deinstantiate!
+ FileUtils.rm_r @path
end
def test_simple_message
@@ -72,7 +76,7 @@ EOS
source.messages = [ message ]
source_info = 0
- sup_message = Message.new( {:source => source, :source_info => source_info } )
+ sup_message = Message.build_from_source(source, source_info)
sup_message.load_from_source!
# see how well parsing the header went
@@ -222,7 +226,7 @@ EOS
source.messages = [ message ]
source_info = 0
- sup_message = Message.new( {:source => source, :source_info => source_info } )
+ sup_message = Message.build_from_source(source, source_info)
sup_message.load_from_source!
# read the message body chunks
@@ -272,7 +276,7 @@ EOS
source.messages = [ message ]
source_info = 0
- sup_message = Message.new( {:source => source, :source_info => source_info } )
+ sup_message = Message.build_from_source(source, source_info)
sup_message.load_from_source!
to = sup_message.to
@@ -285,7 +289,7 @@ EOS
from = sup_message.from
# very basic email address check
assert_match(/\w+@\w+\.\w{2,4}/, from.email)
- assert_not_nil(from.name)
+ refute_nil(from.name)
end
@@ -318,16 +322,12 @@ EOS
source.messages = [ message ]
source_info = 0
- sup_message = Message.new( {:source => source, :source_info => source_info } )
+ sup_message = Message.build_from_source(source, source_info)
sup_message.load_from_source!
# read the message body chunks: no errors should reach this level
- chunks = nil
-
- assert_nothing_raised() do
- chunks = sup_message.load_from_source!
- end
+ chunks = sup_message.load_from_source!
# the chunks list should be empty
@@ -417,15 +417,12 @@ EOS
source.messages = [ message ]
source_info = 0
- sup_message = Message.new( {:source => source, :source_info => source_info } )
+ sup_message = Message.build_from_source(source, source_info)
sup_message.load_from_source!
# read the message body chunks
- assert_nothing_raised() do
- chunks = sup_message.load_from_source!
- end
-
+ sup_message.load_from_source!
end
def test_blank_header_lines
@@ -508,7 +505,7 @@ EOS
source.messages = [ message ]
source_info = 0
- sup_message = Message.new( {:source => source, :source_info => source_info } )
+ sup_message = Message.build_from_source(source, source_info)
sup_message.load_from_source!
# See how well parsing the message ID went.
@@ -517,7 +514,7 @@ EOS
# Look at another header field whose first line was blank.
list_unsubscribe = sup_message.list_unsubscribe
- assert_equal("<http://mailman2.widget.com/mailman/listinfo/monitor-list>, " +
+ assert_equal("<http://mailman2.widget.com/mailman/listinfo/monitor-list>,\n \t" +
"<mailto:monitor-list-request at widget.com?subject=unsubscribe>",
list_unsubscribe)
@@ -533,4 +530,3 @@ end
end
# vim:noai:ts=2:sw=2:
-
diff --git a/test/test_server.rb b/test/test_server.rb
deleted file mode 100644
index a49d309..0000000
--- a/test/test_server.rb
+++ /dev/null
@@ -1,106 +0,0 @@
-#!/usr/bin/ruby
-# encoding: utf-8
-
-require 'test/unit'
-require 'iconv'
-require 'stringio'
-require 'tmpdir'
-require 'fileutils'
-require 'thread'
-require 'eventmachine'
-require 'sup'
-require 'sup/server'
-
-Thread.abort_on_exception = true
-
-module EM
- # Run the reactor in a new thread. This is useful for using EventMachine
- # alongside synchronous code. It is recommended to use EM.error_handler to
- # detect when an exception terminates the reactor thread.
- def self.spawn_reactor_thread
- fail "reactor already started" if EM.reactor_running?
- q = ::Queue.new
- Thread.new { EM.run { q << nil } }
- q.pop
- end
-
- # Stop the reactor and wait for it to finish. This is the counterpart to #spawn_reactor_thread.
- def self.kill_reactor_thread
- fail "reactor is not running" unless EM.reactor_running?
- fail "current thread is running the reactor" if EM.reactor_thread?
- EM.stop
- EM.reactor_thread.join
- end
-end
-
-class QueueingClient < EM::P::RedwoodClient
- def initialize
- super
- @q = Queue.new
- @readyq = Queue.new
- end
-
- def receive_message type, tag, params
- @q << [type, tag, params]
- end
-
- def connection_established
- @readyq << nil
- end
-
- def wait_until_ready
- @readyq.pop
- end
-
- def read
- @q.pop
- end
-
- alias write send_message
-end
-
-class TestServer < Test::Unit::TestCase
- def setup
- port = rand(1000) + 30000
- EM.spawn_reactor_thread
- @path = Dir.mktmpdir
- socket_path = File.join(@path, 'socket')
- Redwood::HookManager.init File.join(@path, 'hooks')
- Redwood::SourceManager.init
- Redwood::SourceManager.load_sources File.join(@path, 'sources.yaml')
- Redwood::Index.init @path
- Redwood::SearchManager.init File.join(@path, 'searches')
- Redwood::Index.load
- @server = EM.start_server socket_path,
- Redwood::Server, Redwood::Index.instance
- @client = EM.connect socket_path, QueueingClient
- @client.wait_until_ready
- end
-
- def teardown
- FileUtils.rm_r @path if passed?
- puts "not cleaning up #{@path}" unless passed?
- %w(Index SearchManager SourceManager HookManager).each do |x|
- Redwood.const_get(x.to_sym).deinstantiate!
- end
- EM.kill_reactor_thread
- end
-
- def test_invalid_request
- @client.write 'foo', '1'
- check @client.read, 'error', '1'
- end
-
- def test_query
- @client.write 'query', '1', 'query' => 'type:mail'
- check @client.read, 'done', '1'
- end
-
- def check resp, type, tag, args={}
- assert_equal type.to_s, resp[0]
- assert_equal tag.to_s, resp[1]
- args.each do |k,v|
- assert_equal v, resp[2][k.to_s]
- end
- end
-end
diff --git a/test/test_yaml_migration.rb b/test/test_yaml_migration.rb
new file mode 100644
index 0000000..7f2c048
--- /dev/null
+++ b/test/test_yaml_migration.rb
@@ -0,0 +1,80 @@
+require "test_helper"
+
+require "sup"
+require "psych"
+
+describe "Sup's YAML util" do
+ describe "Module#yaml_properties" do
+ def build_class_with_name name, &b
+ Class.new do
+ meta_cls = class << self; self; end
+ meta_cls.send(:define_method, :name) { name }
+ class_exec(&b) unless b.nil?
+ end
+ end
+
+ after do
+ Psych.load_tags = {}
+ Psych.dump_tags = {}
+ end
+
+ it "defines YAML tag for class" do
+ cls = build_class_with_name 'Cls' do
+ yaml_properties
+ end
+
+ expected_yaml_tag = "!supmua.org,2006-10-01/Cls"
+
+ Psych.load_tags[expected_yaml_tag].must_equal cls
+ Psych.dump_tags[cls].must_equal expected_yaml_tag
+
+ end
+
+ it "Loads legacy YAML format as well" do
+ cls = build_class_with_name 'Cls' do
+ yaml_properties :id
+ attr_accessor :id
+ def initialize id
+ @id = id
+ end
+ end
+
+ Psych.load_tags["!masanjin.net,2006-10-01/Cls"].must_equal cls
+
+ yaml = <<EOF
+--- !masanjin.net,2006-10-01/Cls
+id: ID
+EOF
+ loaded = YAML.load(yaml)
+
+ loaded.id.must_equal 'ID'
+ loaded.must_be_kind_of cls
+ end
+
+ it "Dumps & loads w/ state re-initialized" do
+ cls = build_class_with_name 'Cls' do
+ yaml_properties :id
+ attr_accessor :id
+ attr_reader :flag
+
+ def initialize id
+ @id = id
+ @flag = true
+ end
+ end
+
+ instance = cls.new 'ID'
+
+ dumped = YAML.dump(instance)
+ loaded = YAML.load(dumped)
+
+ dumped.must_equal <<-EOF
+--- !supmua.org,2006-10-01/Cls
+id: ID
+ EOF
+
+ loaded.id.must_equal 'ID'
+ assert loaded.flag
+ end
+ end
+end
diff --git a/test/test_yaml_regressions.rb b/test/test_yaml_regressions.rb
new file mode 100644
index 0000000..1ab978e
--- /dev/null
+++ b/test/test_yaml_regressions.rb
@@ -0,0 +1,17 @@
+require 'test_helper'
+
+# Requiring 'yaml' before 'sup' in 1.9.x would get Psych loaded first
+# and becoming the default yamler.
+require 'yaml'
+require 'sup'
+
+module Redwood
+ class TestYamlRegressions < ::Minitest::Unit::TestCase
+ def test_yamling_hash
+ hsh = {:foo => 42}
+ reloaded = YAML.load(hsh.to_yaml)
+
+ assert_equal reloaded, hsh
+ end
+ end
+end
diff --git a/test/unit/service/test_label_service.rb b/test/unit/service/test_label_service.rb
new file mode 100644
index 0000000..7c46e34
--- /dev/null
+++ b/test/unit/service/test_label_service.rb
@@ -0,0 +1,19 @@
+require "test_helper"
+
+require "sup/service/label_service"
+
+describe Redwood::LabelService do
+ describe "#add_labels" do
+ it "add labels to all messages matching the query" do
+ q = 'is:starred'
+ label = 'superstarred'
+ message = mock!.add_label(label).subject
+ index = mock!.find_messages(q){ [message] }.subject
+ mock(index).update_message_state(message)
+ mock(index).save_index
+
+ service = Redwood::LabelService.new(index)
+ service.add_labels q, label
+ end
+ end
+end
diff --git a/test/unit/test_horizontal_selector.rb b/test/unit/test_horizontal_selector.rb
new file mode 100644
index 0000000..6cc252c
--- /dev/null
+++ b/test/unit/test_horizontal_selector.rb
@@ -0,0 +1,40 @@
+require "test_helper"
+
+require "sup/horizontal_selector"
+
+describe Redwood::HorizontalSelector do
+ let(:values) { %w[foo at example.com bar at example.com] }
+ let(:strange_value) { "strange at example.com" }
+
+ before do
+ @selector = Redwood::HorizontalSelector.new(
+ 'Acc:', values, [])
+ end
+
+ it "init w/ the first value selected" do
+ first_value = values.first
+ @selector.val.must_equal first_value
+ end
+
+ it "stores value for selection" do
+ second_value = values[1]
+ @selector.set_to second_value
+ @selector.val.must_equal second_value
+ end
+
+ describe "for unknown value" do
+ it "cannot select unknown value" do
+ @selector.wont_be :can_set_to?, strange_value
+ end
+
+ it "refuses selecting unknown value" do
+ old_value = @selector.val
+
+ assert_raises Redwood::HorizontalSelector::UnknownValue do
+ @selector.set_to strange_value
+ end
+
+ @selector.val.must_equal old_value
+ end
+ end
+end
diff --git a/test/unit/util/test_query.rb b/test/unit/util/test_query.rb
new file mode 100644
index 0000000..7d20eab
--- /dev/null
+++ b/test/unit/util/test_query.rb
@@ -0,0 +1,37 @@
+# encoding: utf-8
+
+require "test_helper"
+
+require "sup/util/query"
+require "xapian"
+
+describe Redwood::Util::Query do
+ describe ".describe" do
+ it "returns a UTF-8 description of query" do
+ query = Xapian::Query.new "テスト"
+ life = "生活: "
+
+ assert_raises Encoding::CompatibilityError do
+ _ = life + query.description
+ end
+
+ desc = Redwood::Util::Query.describe(query)
+ _ = (life + desc) # No exception thrown
+ end
+
+ it "returns a valid UTF-8 description of bad input" do
+ msg = "asdfa \xc3\x28 åasdf"
+ query = Xapian::Query.new msg
+ life = 'hæi'
+
+ # this is now possibly UTF-8 string with possibly invalid chars
+ assert_raises Redwood::Util::Query::QueryDescriptionError do
+ desc = Redwood::Util::Query.describe (query)
+ end
+
+ assert_raises Encoding::CompatibilityError do
+ _ = life + query.description
+ end
+ end
+ end
+end
diff --git a/test/unit/util/test_string.rb b/test/unit/util/test_string.rb
new file mode 100644
index 0000000..0d10d08
--- /dev/null
+++ b/test/unit/util/test_string.rb
@@ -0,0 +1,57 @@
+# encoding: utf-8
+
+require "test_helper"
+
+require "sup/util"
+
+describe "Sup's String extension" do
+ describe "#display_length" do
+ let :data do
+ [
+ ['some words', 10,],
+ ['中文', 4,],
+ ['ä', 1,],
+ ]
+ end
+
+ it "calculates display length of a string" do
+ data.each do |(str, length)|
+ str.display_length.must_equal length
+ end
+ end
+ end
+
+ describe "#slice_by_display_length(len)" do
+ let :data do
+ [
+ ['some words', 6, 'some w'],
+ ['中文', 2, '中'],
+ ['älpha', 3, 'älp'],
+ ]
+ end
+
+ it "slices string by display length" do
+ data.each do |(str, length, sliced)|
+ str.slice_by_display_length(length).must_equal sliced
+ end
+ end
+ end
+
+ describe "#wrap" do
+ let :data do
+ [
+ ['some words', 6, ['some', 'words']],
+ ['some words', 80, ['some words']],
+ ['中文', 2, ['中', '文']],
+ ['中文', 5, ['中文']],
+ ['älpha', 3, ['älp', 'ha']],
+ ]
+ end
+
+ it "wraps string by display length" do
+ data.each do |(str, length, wrapped)|
+ str.wrap(length).must_equal wrapped
+ end
+ end
+ end
+end
diff --git a/test/unit/util/test_uri.rb b/test/unit/util/test_uri.rb
new file mode 100644
index 0000000..137d5af
--- /dev/null
+++ b/test/unit/util/test_uri.rb
@@ -0,0 +1,19 @@
+require "test_helper.rb"
+
+require "sup/util/uri"
+
+describe Redwood::Util::Uri do
+ describe ".build" do
+ it "builds uri from hash" do
+ components = {:path => "/var/mail/foo", :scheme => "mbox"}
+ uri = Redwood::Util::Uri.build(components)
+ uri.to_s.must_equal "mbox:/var/mail/foo"
+ end
+
+ it "expands ~ in path" do
+ components = {:path => "~/foo", :scheme => "maildir"}
+ uri = Redwood::Util::Uri.build(components)
+ uri.to_s.must_equal "maildir:#{ENV["HOME"]}/foo"
+ end
+ end
+end
diff --git a/www/index.html b/www/index.html
deleted file mode 100644
index 19ebb0a..0000000
--- a/www/index.html
+++ /dev/null
@@ -1,224 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
- <head>
- <title>Sup</title>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <link rel="stylesheet" href="main.css" type="text/css" />
- </head>
-
- <body>
- <h1>Sup</h1>
-
- <blockquote>
- “Finally a mail client that does what we want, how we want it.”
- </blockquote>
-
- <blockquote>
- “Every other client we've tried is intolerable.”
- </blockquote>
-
- <blockquote>
- “It's just what I wanted, but I hadn't realized what I wanted until I saw it.”
- </blockquote>
-
- <blockquote>
- “Sup is almost to the point where I could jump ship from mutt.”
- </blockquote>
-
- <blockquote>
- “I was previously intrigued by a gmail-styled
- mutt-killer written in Ruby, but having actually spent a few
- hours reading the docs, and trying out all the keys, and
- reading the docs again, and trying the keys out again, and then
- actually engaging in a bunch of practice usage runs, I now
- officially can't fucking wait for the future of this thing; it
- has my full attention.”
- </blockquote>
-
- <p>
- 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, custom code insertion via a hook system, and more.
- If you're the type of person who treats email as an extension of your
- long-term memory, Sup is for you.
- </p>
-
- <p>
- Sup makes it easy to:
- </p>
-
- <ul>
- <li>
- Handle massive amounts of email.
- </li>
-
- <li>
- Mix email from different sources: mbox files and maildirs.
- For remote sources (IMAP, IMAPS, ssh+file), use another
- tool (offlineimap, fetchmail, rsync) to grab local copies.
- </li>
-
- <li>
- Instantaneously search over your entire email collection.
- Search over body text, or use a query language to combine
- search predicates in any way.
- </li>
-
- <li>
- Handle multiple accounts. Replying to email sent to a
- particular account will use the correct SMTP server, signature,
- and from address.
- </li>
-
- <li>
- Add custom code to handle certain types of messages or to
- handle certain types of text within messages.
- </li>
-
- <li>
- Organize email with user-defined labels, automatically track
- recent contacts, and much more!
- </li>
- </ul>
-
- <p>
- The goal of Sup is to become the email client of choice for nerds
- everywhere.
- </p>
-
- <h2>Screenshots</h2>
-
- <ul id="screenshots">
- <li><a href="ss1.png"><img src="ss1-small.png" alt="Sup screenshot 1" /></a></li>
- <li><a href="ss2.png"><img src="ss2-small.png" alt="Sup screenshot 2" /></a></li>
- <li><a href="ss3.png"><img src="ss3-small.png" alt="Sup screenshot 3" /></a></li>
- <li><a href="ss4.png"><img src="ss4-small.png" alt="Sup screenshot 4" /></a></li>
- <li><a href="ss5.png"><img src="ss5-small.png" alt="Sup screenshot 5" /></a></li>
- <li><a href="ss6.png"><img src="ss6-small.png" alt="Sup screenshot 6" /></a></li>
- </ul>
-
- <h2>Documentation</h2>
-
- <p>
- Please read the <a href="README.txt">README</a>, the <a
- href="FAQ.txt">FAQ</a>, the <a href="NewUserGuide.txt">new user guide</a>
- and the <a href="Philosophy.txt">philosophical statement</a>.
- </p>
-
- <p> Please also read and contribute to the <a href="http://sup.rubyforge.org/wiki/wiki.pl">Sup wiki</a>. </p>
-
- <h2>Status</h2>
-
- <p>
- The current version of Sup is 0.12.1, released 2011-01-23. This is a
- beta release. It supports mbox and Maildir mailstores.
- </p>
-
- <p>To be notified by email of Sup releases, subscribe to the
- <a href="http://rubyforge.org/mailman/listinfo/sup-announce">sup-announce mailing list</a>. One email per release.
- </p>
-
- <!-- <p>Issue and release status is available on the <a href="ditz/">Sup ditz page</a>.</p> -->
- <p>Sup news can often be see on <a href="http://all-thing.net/label/sup/">William's blog</a>.</p>
-
- <h2>Bug reports</h2>
- <p>Find a problem with Sup? Or have a feature you'd like to see? <a href="http://masanjin.net/sup-bugs/issue?@template=item">Submit
- it</a> to the <a href="http://masanjin.net/sup-bugs/">official Sup issue
- tracker</a>.
-
- <h2>Getting it</h2>
-
- <p>
- You can download Sup releases from the <a
- href="http://rubyforge.org/projects/sup/">Sup RubyForge page</a>.
- If you have RubyGems installed, simply command your computer to "gem
- install sup".
- </p>
-
- <p>
- If you're interested in development, you can clone the git repository like so: <code>git clone git://gitorious.org/sup/mainline.git</code>. You can also browse the <a
- href="http://gitorious.org/projects/sup">Sup Gitorious
- repository</a>. You may consider subscribing to the sup-devel list (below).
- </p>
-
- <h2>Make some new friends</h2>
-
- <p> If you'd like to meet hot single Sup users in your area, try the <a
- href="http://rubyforge.org/mailman/listinfo/sup-talk">sup-talk mailing list</a> (<a href="http://rubyforge.org/pipermail/sup-talk/">archives</a>).
- </p>
-
- <p> If you'd like to meet some grumpy old programmers to talk about Sup internals with, try the <a
- href="http://rubyforge.org/mailman/listinfo/sup-devel">sup-devel mailing list</a> (<a href="http://rubyforge.org/pipermail/sup-devel/">archives</a>).
-
-
- <h2>Credit</h2>
-
- <p>
- Sup is brought to you by <a href="http://masanjin.net/">William Morgan</a> and the following honorable contributors:
- <ul>
- <li> William Morgan </li>
- <li> Rich Lane </li>
- <li> Ismo Puustinen </li>
- <li> Nicolas Pouillard </li>
- <li> Eric Sherman </li>
- <li> Michael Stapelberg </li>
- <li> Ben Walton </li>
- <li> Mike Stipicevic </li>
- <li> Marcus Williams </li>
- <li> Lionel Ott </li>
- <li> Tero Tilus </li>
- <li> Ingmar Vanhassel </li>
- <li> Mark Alexander </li>
- <li> Gaute Hope </li>
- <li> Christopher Warrington </li>
- <li> W. Trevor King </li>
- <li> Gaudenz Steinlin </li>
- <li> Richard Brown </li>
- <li> Marc Hartstein </li>
- <li> Sascha Silbe </li>
- <li> Israel Herraiz </li>
- <li> Anthony Martinez </li>
- <li> Hamish Downer </li>
- <li> Bo Borgerson </li>
- <li> William Erik Baxter </li>
- <li> Michael Hamann </li>
- <li> Grant Hollingworth </li>
- <li> Adeodato Simó </li>
- <li> Daniel Schoepe </li>
- <li> Jason Petsod </li>
- <li> Steve Goldman </li>
- <li> Edward Z. Yang </li>
- <li> Decklin Foster </li>
- <li> Cameron Matheson </li>
- <li> Carl Worth </li>
- <li> Jeff Balogh </li>
- <li> Andrew Pimlott </li>
- <li> Alex Vandiver </li>
- <li> Peter Harkins </li>
- <li> Kornilios Kourtis </li>
- <li> Giorgio Lando </li>
- <li> Damien Leone </li>
- <li> Benoît PIERRE </li>
- <li> Alvaro Herrera </li>
- <li> Jonah </li>
- <li> Adam Lloyd </li>
- <li> Todd Eisenberger </li>
- <li> ian </li>
- <li> Steven Walter </li>
- <li> ian </li>
- <li> Jon M. Dugan </li>
- <li> Gregor Hoffleit </li>
- <li> Stefan Lundström </li>
- <li> Kirill Smelkov </li>
- </ul>
- </p>
-
- <p>
- Sup is made possible by the <a href="http://xapian.org">Xapian</a> search engine,
- and by <a href="http://www.lickey.com/">Matt Armstrong</a> and his
- tragically abandoned <a href="http://www.rfc20.org/rubymail/">RubyMail</a>
- package.
- </p>
- </body>
-</html>
diff --git a/www/main.css b/www/main.css
deleted file mode 100644
index 63246fa..0000000
--- a/www/main.css
+++ /dev/null
@@ -1,36 +0,0 @@
-body
-{
- background: white;
- color: #404040;
- margin-bottom: 2em;
- margin-left: auto;
- margin-right: auto;
- width: 90%;
-}
-
-a, a:visited
-{
- border-bottom: 1px dotted #03c;
- background: inherit;
- color: #03c;
- text-decoration: none;
-}
-
-#screenshots
-{
- margin: 0;
- padding: 0;
-}
-#screenshots li
-{
- display: inline;
- list-style: none;
-}
-#screenshots a
-{
- border-bottom: none;
-}
-#screenshots img
-{
- border: 0;
-}
diff --git a/www/ss1.png b/www/ss1.png
deleted file mode 100644
index a5c43d4..0000000
Binary files a/www/ss1.png and /dev/null differ
diff --git a/www/ss2.png b/www/ss2.png
deleted file mode 100644
index f9b6df7..0000000
Binary files a/www/ss2.png and /dev/null differ
diff --git a/www/ss3.png b/www/ss3.png
deleted file mode 100644
index 4038cb5..0000000
Binary files a/www/ss3.png and /dev/null differ
diff --git a/www/ss4.png b/www/ss4.png
deleted file mode 100644
index eb79f3e..0000000
Binary files a/www/ss4.png and /dev/null differ
diff --git a/www/ss5.png b/www/ss5.png
deleted file mode 100644
index aa367ae..0000000
Binary files a/www/ss5.png and /dev/null differ
diff --git a/www/ss6.png b/www/ss6.png
deleted file mode 100644
index 68ff5bf..0000000
Binary files a/www/ss6.png and /dev/null differ
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ruby-extras/sup-mail.git
More information about the Pkg-ruby-extras-commits
mailing list