[PATCH] Restore original keybinding ('r' = reply-to-all)

2012-06-28 Thread Thomas Jost
Le 28 juin 2012 ? 18:21 CEST, Jameson Graef Rollins a ?crit :
> On Thu, Jun 28 2012, Philip Hands  wrote:
>> Actually, instead of either of these options, how about some way of
>> letting r do the single reply, and then once inside the reply, having
>> some key binding to add the rest of the recipients in the group, or flip
>> between the two options so one can change one's mind after typing up the
>> reply?
>
> This is a good idea.  The other idea I had was to have 'r' query the
> user directly about whether or not they want to reply all before
> constructing the reply template.  Or right before you're about to send.

In my config, I use "r a" for "reply to all" and "r s" for "reply to
sender". Never got it wrong since I added this to my .emacs.
https://github.com/Schnouki/dotfiles/blob/master/emacs/init-50-mail.el#L111-114

Regards,
-- 
Thomas/Schnouki
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 489 bytes
Desc: not available
URL: 



Re: [PATCH] Restore original keybinding ('r' = reply-to-all)

2012-06-28 Thread Thomas Jost
Le 28 juin 2012 à 18:21 CEST, Jameson Graef Rollins a écrit :
 On Thu, Jun 28 2012, Philip Hands p...@hands.com wrote:
 Actually, instead of either of these options, how about some way of
 letting r do the single reply, and then once inside the reply, having
 some key binding to add the rest of the recipients in the group, or flip
 between the two options so one can change one's mind after typing up the
 reply?

 This is a good idea.  The other idea I had was to have 'r' query the
 user directly about whether or not they want to reply all before
 constructing the reply template.  Or right before you're about to send.

In my config, I use r a for reply to all and r s for reply to
sender. Never got it wrong since I added this to my .emacs.
https://github.com/Schnouki/dotfiles/blob/master/emacs/init-50-mail.el#L111-114

Regards,
-- 
Thomas/Schnouki


pgpo8HynnX3s2.pgp
Description: PGP signature
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH v6] emacs: Let the user choose where to compose new mails

2012-05-04 Thread Thomas Jost
Introduce a new defcustom notmuch-mua-compose-in that allows users to
specify where new mails are composed, either in the current window or
in a new window or frame.

Signed-off-by: Jameson Rollins 
---
Hi David et al.,

Here it is again, with a warning in the customize message that only
appears in Emacs 23. The indentation is a little bit of a mess but
that's needed for the docstring to look good :)

(If you want I can remove the test and also display the Emacs 23
warning in Emacs 24.)

Does it look good to you? I'm not comfortable with writing docs in
English, so feel free to rephrase it if needed.

I also moved notmuch-mua-compose-in to the 'notmuch-send group, just
as other notmuch-mua-* variables.

Regards,
Thomas

 emacs/notmuch-mua.el |   45 +++--
 1 file changed, 43 insertions(+), 2 deletions(-)

diff --git a/emacs/notmuch-mua.el b/emacs/notmuch-mua.el
index 87bd88d..641dae7 100644
--- a/emacs/notmuch-mua.el
+++ b/emacs/notmuch-mua.el
@@ -36,6 +36,26 @@
   :group 'notmuch-send
   :group 'notmuch-hooks)

+(defcustom notmuch-mua-compose-in 'current-window
+  (concat
+   "Where to create the mail buffer used to compose a new message.
+Possible values are `current-window' (default), `new-window' and
+`new-frame'. If set to `current-window', the mail buffer will be
+displayed in the current window, so the old buffer will be
+restored when the mail buffer is killed. If set to `new-window'
+or `new-frame', the mail buffer will be displayed in a new
+window/frame that will be destroyed when the buffer is killed.
+You may want to customize `message-kill-buffer-on-exit'
+accordingly."
+   (when (< emacs-major-version 24)
+   " Due to a known bug in Emacs 23, you should not set
+this to `new-window' if `message-kill-buffer-on-exit' is
+disabled: this would result in an incorrect behavior."))
+  :group 'notmuch-send
+  :type '(choice (const :tag "Compose in the current window" current-window)
+(const :tag "Compose mail in a new window"  new-window)
+(const :tag "Compose mail in a new frame"   new-frame)))
+
 (defcustom notmuch-mua-user-agent-function 'notmuch-mua-user-agent-full
   "Function used to generate a `User-Agent:' string. If this is
 `nil' then no `User-Agent:' will be generated."
@@ -55,6 +75,23 @@ list."

 ;;

+(defun notmuch-mua-get-switch-function ()
+  "Get a switch function according to `notmuch-mua-compose-in'."
+  (cond ((eq notmuch-mua-compose-in 'current-window)
+'switch-to-buffer)
+   ((eq notmuch-mua-compose-in 'new-window)
+'switch-to-buffer-other-window)
+   ((eq notmuch-mua-compose-in 'new-frame)
+'switch-to-buffer-other-frame)
+   (t (error "Invalid value for `notmuch-mua-compose-in'"
+
+(defun notmuch-mua-maybe-set-window-dedicated ()
+  "Set the selected window as dedicated according to
+`notmuch-mua-compose-in'."
+  (when (or (eq notmuch-mua-compose-in 'new-frame)
+   (eq notmuch-mua-compose-in 'new-window))
+(set-window-dedicated-p (selected-window) t)))
+
 (defun notmuch-mua-user-agent-full ()
   "Generate a `User-Agent:' string suitable for notmuch."
   (concat (notmuch-mua-user-agent-notmuch)
@@ -148,7 +185,8 @@ list."
 collect pair)))
  (notmuch-mua-mail (plist-get reply-headers :To)
(plist-get reply-headers :Subject)
-   (notmuch-headers-plist-to-alist reply-headers
+   (notmuch-headers-plist-to-alist reply-headers)
+   nil (notmuch-mua-get-switch-function

   ;; Insert the message body - but put it in front of the signature
   ;; if one is present
@@ -186,6 +224,7 @@ list."
   (set-buffer-modified-p nil))

 (defun notmuch-mua-forward-message ()
+  (funcall (notmuch-mua-get-switch-function) (current-buffer))
   (message-forward)

   (when notmuch-mua-user-agent-function
@@ -195,6 +234,7 @@ list."
   (message-sort-headers)
   (message-hide-headers)
   (set-buffer-modified-p nil)
+  (notmuch-mua-maybe-set-window-dedicated)

   (message-goto-to))

@@ -217,6 +257,7 @@ OTHER-ARGS are passed through to `message-mail'."
   (message-sort-headers)
   (message-hide-headers)
   (set-buffer-modified-p nil)
+  (notmuch-mua-maybe-set-window-dedicated)

   (message-goto-to))

@@ -273,7 +314,7 @@ the From: address first."
   (let ((other-headers
 (when (or prompt-for-sender notmuch-always-prompt-for-sender)
   (list (cons 'From (notmuch-mua-prompt-for-sender))
-(notmuch-mua-mail nil nil other-headers)))
+(notmuch-mua-mail nil nil other-headers nil 
(notmuch-mua-get-switch-function

 (defun notmuch-mua-new-forward-message ( prompt-for-sender)
   "Invoke the notmuch message forwarding window.
--
1.7.10.1


[PATCH v6] emacs: Let the user choose where to compose new mails

2012-05-04 Thread Thomas Jost
Introduce a new defcustom notmuch-mua-compose-in that allows users to
specify where new mails are composed, either in the current window or
in a new window or frame.

Signed-off-by: Jameson Rollins jroll...@finestructure.net
---
Hi David et al.,

Here it is again, with a warning in the customize message that only
appears in Emacs 23. The indentation is a little bit of a mess but
that's needed for the docstring to look good :)

(If you want I can remove the test and also display the Emacs 23
warning in Emacs 24.)

Does it look good to you? I'm not comfortable with writing docs in
English, so feel free to rephrase it if needed.

I also moved notmuch-mua-compose-in to the 'notmuch-send group, just
as other notmuch-mua-* variables.

Regards,
Thomas

 emacs/notmuch-mua.el |   45 +++--
 1 file changed, 43 insertions(+), 2 deletions(-)

diff --git a/emacs/notmuch-mua.el b/emacs/notmuch-mua.el
index 87bd88d..641dae7 100644
--- a/emacs/notmuch-mua.el
+++ b/emacs/notmuch-mua.el
@@ -36,6 +36,26 @@
   :group 'notmuch-send
   :group 'notmuch-hooks)

+(defcustom notmuch-mua-compose-in 'current-window
+  (concat
+   Where to create the mail buffer used to compose a new message.
+Possible values are `current-window' (default), `new-window' and
+`new-frame'. If set to `current-window', the mail buffer will be
+displayed in the current window, so the old buffer will be
+restored when the mail buffer is killed. If set to `new-window'
+or `new-frame', the mail buffer will be displayed in a new
+window/frame that will be destroyed when the buffer is killed.
+You may want to customize `message-kill-buffer-on-exit'
+accordingly.
+   (when ( emacs-major-version 24)
+Due to a known bug in Emacs 23, you should not set
+this to `new-window' if `message-kill-buffer-on-exit' is
+disabled: this would result in an incorrect behavior.))
+  :group 'notmuch-send
+  :type '(choice (const :tag Compose in the current window current-window)
+(const :tag Compose mail in a new window  new-window)
+(const :tag Compose mail in a new frame   new-frame)))
+
 (defcustom notmuch-mua-user-agent-function 'notmuch-mua-user-agent-full
   Function used to generate a `User-Agent:' string. If this is
 `nil' then no `User-Agent:' will be generated.
@@ -55,6 +75,23 @@ list.

 ;;

+(defun notmuch-mua-get-switch-function ()
+  Get a switch function according to `notmuch-mua-compose-in'.
+  (cond ((eq notmuch-mua-compose-in 'current-window)
+'switch-to-buffer)
+   ((eq notmuch-mua-compose-in 'new-window)
+'switch-to-buffer-other-window)
+   ((eq notmuch-mua-compose-in 'new-frame)
+'switch-to-buffer-other-frame)
+   (t (error Invalid value for `notmuch-mua-compose-in'
+
+(defun notmuch-mua-maybe-set-window-dedicated ()
+  Set the selected window as dedicated according to
+`notmuch-mua-compose-in'.
+  (when (or (eq notmuch-mua-compose-in 'new-frame)
+   (eq notmuch-mua-compose-in 'new-window))
+(set-window-dedicated-p (selected-window) t)))
+
 (defun notmuch-mua-user-agent-full ()
   Generate a `User-Agent:' string suitable for notmuch.
   (concat (notmuch-mua-user-agent-notmuch)
@@ -148,7 +185,8 @@ list.
 collect pair)))
  (notmuch-mua-mail (plist-get reply-headers :To)
(plist-get reply-headers :Subject)
-   (notmuch-headers-plist-to-alist reply-headers
+   (notmuch-headers-plist-to-alist reply-headers)
+   nil (notmuch-mua-get-switch-function

   ;; Insert the message body - but put it in front of the signature
   ;; if one is present
@@ -186,6 +224,7 @@ list.
   (set-buffer-modified-p nil))

 (defun notmuch-mua-forward-message ()
+  (funcall (notmuch-mua-get-switch-function) (current-buffer))
   (message-forward)

   (when notmuch-mua-user-agent-function
@@ -195,6 +234,7 @@ list.
   (message-sort-headers)
   (message-hide-headers)
   (set-buffer-modified-p nil)
+  (notmuch-mua-maybe-set-window-dedicated)

   (message-goto-to))

@@ -217,6 +257,7 @@ OTHER-ARGS are passed through to `message-mail'.
   (message-sort-headers)
   (message-hide-headers)
   (set-buffer-modified-p nil)
+  (notmuch-mua-maybe-set-window-dedicated)

   (message-goto-to))

@@ -273,7 +314,7 @@ the From: address first.
   (let ((other-headers
 (when (or prompt-for-sender notmuch-always-prompt-for-sender)
   (list (cons 'From (notmuch-mua-prompt-for-sender))
-(notmuch-mua-mail nil nil other-headers)))
+(notmuch-mua-mail nil nil other-headers nil 
(notmuch-mua-get-switch-function

 (defun notmuch-mua-new-forward-message (optional prompt-for-sender)
   Invoke the notmuch message forwarding window.
--
1.7.10.1
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH v3 1/4] emacs: Let the user choose where to compose new mails

2012-04-23 Thread Thomas Jost
Le 15 avril 2012 ? 16:52 CEST, David Bremner a ?crit :
> Jameson Graef Rollins  writes:
>
>> I think the issues that David was experiencing have to do with flakiness
>> in emacs's dedicated windows, not in this patch itself.
>
> Thomas,
>
> Did you have a change to investigate this as proposed in
> id:"87zke0aifa.fsf at thor.loria.fr"?

David,

Sorry for the delay. I did investigate a little bit, but I did not try
to write a patch to fix the wrong behaviour in Emacs 23.

AFAICT, Emacs 23 is just buggy in this case. By reading the code of
message-send-and-exit and message-bury [1], here is what happens when
you call message-send-buffer-and-exit with message-kill-buffer-on-exit
set to nil:
- message is sent
- buffer is buried with burry-buffer
- message-bury: if the window is dedicated and its frame not the only
  visible frame, then this frame is deleted

which explains what happens in Emacs 23 both in daemon and non-daemon
mode.

In Emacs 24 [2], here is what happens:
- message is sent
- message-bury: buffer is buried with bury-buffer

which is (obviously?) correct.

Really, this looks like a bug in Emacs 23 to me. Emacs 24 has been fixed
by Gnus commits [3] and [4] (maybe [3] is enough, I didn't try). Users
of Emacs 23 can probably just use an up-to-date version of Gnus to have
this issue fixed.

So I'm not sure it would make sense to try to come up with a workaround
in my patch, nor if it would be worth it. Maybe just adding a message
suggesting Emacs 23 users to enable message-kill-buffer-on-exit if they
use the Gnus version shipped with Emacs?

Other than that, Jameson's commit [5] is exactly the same as the one in
my tree with a better commit message, so I'm in favor of pulling it.

[1] 
http://bzr.savannah.gnu.org/lh/emacs/emacs-23/annotate/head:/lisp/gnus/message.el
[2] 
http://bzr.savannah.gnu.org/lh/emacs/emacs-24/annotate/head:/lisp/gnus/message.el
[3] 
http://git.gnus.org/cgit/gnus.git/commit/?id=30eb6d24d30bc028fce91a0c62044c5dc1fdd90e
[4] 
http://git.gnus.org/cgit/gnus.git/commit/?id=e3fc7cb33eb07dd3b48cfc72f0cada1f1edbcb85
[5] id:"1334436137-6099-1-git-send-email-jrollins at finestructure.net"

Regards,

--
Thomas/Schnouki
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 489 bytes
Desc: not available
URL: 



Re: [PATCH v3 1/4] emacs: Let the user choose where to compose new mails

2012-04-22 Thread Thomas Jost
Le 15 avril 2012 à 16:52 CEST, David Bremner a écrit :
 Jameson Graef Rollins jroll...@finestructure.net writes:

 I think the issues that David was experiencing have to do with flakiness
 in emacs's dedicated windows, not in this patch itself.

 Thomas,

 Did you have a change to investigate this as proposed in
 id:87zke0aifa@thor.loria.fr?

David,

Sorry for the delay. I did investigate a little bit, but I did not try
to write a patch to fix the wrong behaviour in Emacs 23.

AFAICT, Emacs 23 is just buggy in this case. By reading the code of
message-send-and-exit and message-bury [1], here is what happens when
you call message-send-buffer-and-exit with message-kill-buffer-on-exit
set to nil:
- message is sent
- buffer is buried with burry-buffer
- message-bury: if the window is dedicated and its frame not the only
  visible frame, then this frame is deleted

which explains what happens in Emacs 23 both in daemon and non-daemon
mode.

In Emacs 24 [2], here is what happens:
- message is sent
- message-bury: buffer is buried with bury-buffer

which is (obviously?) correct.

Really, this looks like a bug in Emacs 23 to me. Emacs 24 has been fixed
by Gnus commits [3] and [4] (maybe [3] is enough, I didn't try). Users
of Emacs 23 can probably just use an up-to-date version of Gnus to have
this issue fixed.

So I'm not sure it would make sense to try to come up with a workaround
in my patch, nor if it would be worth it. Maybe just adding a message
suggesting Emacs 23 users to enable message-kill-buffer-on-exit if they
use the Gnus version shipped with Emacs?

Other than that, Jameson's commit [5] is exactly the same as the one in
my tree with a better commit message, so I'm in favor of pulling it.

[1] 
http://bzr.savannah.gnu.org/lh/emacs/emacs-23/annotate/head:/lisp/gnus/message.el
[2] 
http://bzr.savannah.gnu.org/lh/emacs/emacs-24/annotate/head:/lisp/gnus/message.el
[3] 
http://git.gnus.org/cgit/gnus.git/commit/?id=30eb6d24d30bc028fce91a0c62044c5dc1fdd90e
[4] 
http://git.gnus.org/cgit/gnus.git/commit/?id=e3fc7cb33eb07dd3b48cfc72f0cada1f1edbcb85
[5] id:1334436137-6099-1-git-send-email-jroll...@finestructure.net

Regards,

--
Thomas/Schnouki


pgpU4xJp7PmDM.pgp
Description: PGP signature
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH] Update crypto test for gmime 2.6.5

2012-02-21 Thread Thomas Jost
gmime 2.6 had a bug [1] which made it impossible to tell why a signature
verification failed when the signer key was unavailable (empty sigstatus field
in the JSON output). Since 00b5623d the corresponding test is marked as broken
when using gmime 2.6 (2.4 is fine).

The bug has been fixed in gmime 2.6.5. Consequently, the crypto test needs to be
adjusted so that it is only marked broken for gmime 2.6.4 and below.

[1] https://bugzilla.gnome.org/show_bug.cgi?id=668085
---

Hello world,

Here's a little update about gmime 2.6. The latest version (2.6.5)
fixes the little regression introduced in 2.6.

In all honesty, I'm not sure adding such a workaround in the test
suite is worth the effort. If gmime 2.6.5 is quickly packaged by major
distros (it's already in Arch), we could as well make notmuch depend
on gmime = 2.6.5. (One line to change in configure). Or we could just
stop trying to mark the test as broken and let it fail for buggy
versions of gmime.

What do you think?

Best regards,
Thomas

 test/crypto |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/test/crypto b/test/crypto
index 1dbb60a..cbab216 100755
--- a/test/crypto
+++ b/test/crypto
@@ -104,8 +104,8 @@ test_expect_equal \
 $expected
 
 test_begin_subtest signature verification with signer key unavailable
-# this is broken with current versions of gmime-2.6
-(ldd $(which notmuch) | grep -Fq gmime-2.6)  test_subtest_known_broken
+# this is broken with gmime-2.6.x for x = 4
+ldd $(which notmuch) | grep -Fq gmime-2.6  pkg-config --max-version=2.6.4 
gmime-2.6  test_subtest_known_broken
 # move the gnupghome temporarily out of the way
 mv ${GNUPGHOME}{,.bak}
 output=$(notmuch show --format=json --verify subject:test signed message 001 
\
-- 
1.7.9.1

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH] build: Require gmime 2.6.5

2012-02-21 Thread Thomas Jost
gmime-2.6 had a bug [1] which made it impossible to tell why a signature
verification failed when the signer key was unavailable (empty sigstatus field
in the JSON output). Since 00b5623d the corresponding test is marked as broken
when using gmime-2.6 (2.4 is fine).

This bug has been fixed in gmime 2.6.5, which is now the minimal gmime-2.6
version required for building notmuch (gmime-2.4 is still available). As a
consequence the version check in test/crypto can be removed.

[1] https://bugzilla.gnome.org/show_bug.cgi?id=668085
---

Hi Tomi, hi again list,

I agree it's a better solution.

Here is another patch that makes gmime = 2.6.5 a requirement.
Building against gmime-2.4 is of course still possible.

Apparently gmime 2.6.5 is not available yet in Debian, nor in Fedora,
so I think we should wait a little bit before pushing this.

Best regards,
Thomas

 configure   |4 +++-
 test/crypto |2 --
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/configure b/configure
index 8b85b9d..279e650 100755
--- a/configure
+++ b/configure
@@ -273,9 +273,11 @@ if [ ${have_xapian} = 0 ]; then
 errors=$((errors + 1))
 fi
 
+# If using GMime 2.6, we need to have a version = 2.6.5 to avoid a
+# crypto bug.
 printf Checking for GMime development files... 
 have_gmime=0
-for gmimepc in gmime-2.6 gmime-2.4; do
+for gmimepc in 'gmime-2.6 = 2.6.5' gmime-2.4; do
 if pkg-config --exists $gmimepc; then
printf Yes ($gmimepc).\n
have_gmime=1
diff --git a/test/crypto b/test/crypto
index 1dbb60a..6723ef8 100755
--- a/test/crypto
+++ b/test/crypto
@@ -104,8 +104,6 @@ test_expect_equal \
 $expected
 
 test_begin_subtest signature verification with signer key unavailable
-# this is broken with current versions of gmime-2.6
-(ldd $(which notmuch) | grep -Fq gmime-2.6)  test_subtest_known_broken
 # move the gnupghome temporarily out of the way
 mv ${GNUPGHOME}{,.bak}
 output=$(notmuch show --format=json --verify subject:test signed message 001 
\
-- 
1.7.9.1

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Spellcheck second language

2012-02-16 Thread Thomas Jost
On Thu, 16 Feb 2012 11:45:10 -0500, Philippe LeCavalier  wrote:
> Hi.
> 
> I get this[1] when envoking keybindings to a second language
> flyspell. Any ideas? I've already tried alternate titles to reference
> the dictionary in question ie french, francais and fran?ais to no avail.
> 
> Also, how would I apply a variation to the dictionary ie. fr_ca?
> 
> ref.
> [1] ispell-change-dictionary: Undefined dictionary: fran?ais
> 
> rel sys details:
> emacs 23.3-9.fc16
> hunspell 1.3.2-1.fc16
> hunspell-en 0.20110318-1.fc16
> hunspell-fr 4.1-1.fc16
> 
> Please ask if you need more info.

Hi Philippe,

Do you have aspell? If you do, do you also have aspell-fr? I don't know
ispell.el very well, but apparently it will try to use aspell, then
ispell, then hunspell in that order. So if you have /usr/bin/aspell but
not the French aspell dictionary, that may explain your problem.

Now for fr_CA... I don't use it myself (only fr_FR) and apparently
there's no specific file for fr_CA (nor fr_BE btw) in aspell-fr. So I
guess you should try to stick with "francais".

If you *really* want to use fr_CA, you may have to switch to hunspell,
since hunspell-fr *has* a dictionary for fr_CA. The problem is then to
tell emacs about this dictionary. Here's something that almost works:

 (setq ispell-program-name "/usr/bin/hunspell"
   ispell-extra-args '("-i" "latin1"))
 (add-to-list 'ispell-local-dictionary-alist
  (cons "fr_CA" (cdr (assoc "francais" 
ispell-dictionary-base-alist

(it copies settings from the fr_FR dictionary but names it fr_CA).
Problems:
- you need to enter the encoding manually to avoid getting such errors:
 UTF-8 encoding error. Missing continuation byte in 0. [...]
  but of course this means that this won't work in UTF-8 buffers...
- using these settings, I get another error when changing the dictionary
  to american and running flyspell-buffer ("Can't check region"). I have
  to revert to aspell for it to work again.

So even if it's not a perfect solution, you should probably keep on
using "francais" with aspell.

Hope this helps.

Best regards

-- 
Thomas/Schnouki
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 489 bytes
Desc: not available
URL: 



Re: Spellcheck second language

2012-02-16 Thread Thomas Jost
On Thu, 16 Feb 2012 11:45:10 -0500, Philippe LeCavalier 
supp...@plecavalier.com wrote:
 Hi.
 
 I get this[1] when envoking keybindings to a second language
 flyspell. Any ideas? I've already tried alternate titles to reference
 the dictionary in question ie french, francais and français to no avail.
 
 Also, how would I apply a variation to the dictionary ie. fr_ca?
 
 ref.
 [1] ispell-change-dictionary: Undefined dictionary: français
 
 rel sys details:
 emacs 23.3-9.fc16
 hunspell 1.3.2-1.fc16
 hunspell-en 0.20110318-1.fc16
 hunspell-fr 4.1-1.fc16
 
 Please ask if you need more info.

Hi Philippe,

Do you have aspell? If you do, do you also have aspell-fr? I don't know
ispell.el very well, but apparently it will try to use aspell, then
ispell, then hunspell in that order. So if you have /usr/bin/aspell but
not the French aspell dictionary, that may explain your problem.

Now for fr_CA... I don't use it myself (only fr_FR) and apparently
there's no specific file for fr_CA (nor fr_BE btw) in aspell-fr. So I
guess you should try to stick with francais.

If you *really* want to use fr_CA, you may have to switch to hunspell,
since hunspell-fr *has* a dictionary for fr_CA. The problem is then to
tell emacs about this dictionary. Here's something that almost works:

 (setq ispell-program-name /usr/bin/hunspell
   ispell-extra-args '(-i latin1))
 (add-to-list 'ispell-local-dictionary-alist
  (cons fr_CA (cdr (assoc francais 
ispell-dictionary-base-alist

(it copies settings from the fr_FR dictionary but names it fr_CA).
Problems:
- you need to enter the encoding manually to avoid getting such errors:
 UTF-8 encoding error. Missing continuation byte in 0. [...]
  but of course this means that this won't work in UTF-8 buffers...
- using these settings, I get another error when changing the dictionary
  to american and running flyspell-buffer (Can't check region). I have
  to revert to aspell for it to work again.

So even if it's not a perfect solution, you should probably keep on
using francais with aspell.

Hope this helps.

Best regards

-- 
Thomas/Schnouki


pgpgYW2wQvhpF.pgp
Description: PGP signature
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH 1/2] emacs: Avoid `mail-header-parse-address' in `notmuch-show-clean-address'.

2012-01-25 Thread Thomas Jost
On Wed, 25 Jan 2012 11:45:03 +, David Edmondson  wrote:
> `mail-header-parse-address' expects un-decoded mailbox parts, which is
> not what we have at this point. Replace it with simple string
> deconstruction.
> 
> Mark the corresponding test as no longer broken.
> 
> Minor whitespace cleanup.
> ---
>  emacs/notmuch-show.el  |   50 ---
>  test/emacs-address-cleaning.sh |1 -
>  2 files changed, 36 insertions(+), 15 deletions(-)
> 
> diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
> index e6a5b31..1fd2524 100644
> --- a/emacs/notmuch-show.el
> +++ b/emacs/notmuch-show.el
> @@ -289,21 +289,43 @@ operation on the contents of the current buffer."
>"Try to clean a single email ADDRESS for display.  Return
>  unchanged ADDRESS if parsing fails."
>(condition-case nil
> -(let* ((parsed (mail-header-parse-address address))
> -(address (car parsed))
> -(name (cdr parsed)))
> -  ;; Remove double quotes. They might be required during transport,
> -  ;; but we don't need to see them.
> -  (when name
> -(setq name (replace-regexp-in-string "\"" "" name)))
> +(let (p-name p-address)
> +  ;; It would be convenient to use `mail-header-parse-address',
> +  ;; but that expects un-decoded mailbox parts, whereas our
> +  ;; mailbox parts are already decoded (and hence may contain
> +  ;; UTF-8). Given that notmuch should handle most of the awkward
> +  ;; cases, some simple string deconstruction should be sufficient
> +  ;; here.
> +  (cond
> +   ;; "User " style.
> +   ((string-match "\\(.*\\) <\\(.*\\)>" address)
> + (setq p-name (match-string 1 address)
> +   p-address (match-string 2 address)))
> +
> +   ;; "" style.
> +   ((string-match "<\\(.*\\)>" address)
> + (setq p-address (match-string 1 address)))
> +
> +   ;; Everything else.
> +   (t
> + (setq p-address address)))
> +
> +  ;; Remove outer double quotes. They might be required during
> +  ;; transport, but we don't need to see them.
> +  (when (and p-name
> +  (string-match "^\"\\(.*\\)\"$" p-name))
> + (setq p-name (match-string 1 p-name)))
> +
>;; If the address is 'foo at bar.com ' then show just
>;; 'foo at bar.com'.
> -  (when (string= name address)
> -(setq name nil))
> -
> -  (if (not name)
> -address
> -(concat name " <" address ">")))
> +  (when (string= p-name p-address)
> + (setq p-name nil))
> +
> +  ;; If no name results, return just the address.
> +  (if (not p-name)
> +   p-address
> + ;; Otherwise format the name and address together.
> + (concat p-name " <" p-address ">")))
>  (error address)))
>  
>  (defun notmuch-show-insert-headerline (headers date tags depth)
> @@ -1417,7 +1439,7 @@ than only the current message."
>(interactive "P\nsPipe message to command: ")
>(let (shell-command)
>  (if entire-thread
> - (setq shell-command 
> + (setq shell-command
> (concat notmuch-command " show --format=mbox "
> (shell-quote-argument
>  (mapconcat 'identity 
> (notmuch-show-get-message-ids-for-open-messages) " OR "))
> diff --git a/test/emacs-address-cleaning.sh b/test/emacs-address-cleaning.sh
> index 0d85bdc..51018fe 100755
> --- a/test/emacs-address-cleaning.sh
> +++ b/test/emacs-address-cleaning.sh
> @@ -12,7 +12,6 @@ test_emacs_expect_t \
>  '(load "emacs-address-cleaning.el") (notmuch-test-address-cleaning-2)'
>  
>  test_begin_subtest "notmuch-test-address-clean part 3"
> -test_subtest_known_broken
>  test_emacs_expect_t \
>  '(load "emacs-address-cleaning.el") (notmuch-test-address-cleaning-3)'
>  
> -- 
> 1.7.8.3

Hello David,

Works fine for me, but this also breaks en Emacs test:

 FAIL   notmuch-show for message with invalid From
--- emacs.10.expected   2012-01-25 12:50:00.310786410 +
+++ emacs.10.output 2012-01-25 12:50:00.310786410 +
@@ -1,4 +1,4 @@
-"Invalid " From"  (2001-01-05) (inbox)
+Invalid " From  (2001-01-05) (inbox)
 Subject: message-with-invalid-from
 To: Notmuch Test Suite 
 Date: Fri, 05 Jan 2001 15:43:57 +
nil

Thanks for this patch anyway :)

Regards,

-- 
Thomas/Schnouki
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 489 bytes
Desc: not available
URL: 



[PATCH] Fix NEWS about gmime 2.6

2012-01-22 Thread Thomas Jost
Previous version had a typo ("they may be" instead of "there may be")
and was lacking a proper description of the gmime bug.
---
Argh. Did not know how to tell it in proper English, ended with a huge
typo. Sorry about that, and thanks for noticing and fixing it :)

 NEWS |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/NEWS b/NEWS
index e78472c..2c2d9e9 100644
--- a/NEWS
+++ b/NEWS
@@ -42,8 +42,8 @@ Build fixes
 Compatibility with GMime 2.6

   It is now possible to build notmuch against both GMime 2.4 and 2.6.
-  However they may be some issues in PGP signature verification
-  because of a bug in current versions of GMime 2.6.
+  However, a bug in current GMime 2.6 causes notmuch not to report
+  signatures where the signer key is unavailable (GNOME bug 668085).

 Notmuch 0.11 (2012-01-13)
 =
-- 
1.7.8.4



[PATCH] show: don't use hex literals in JSON output

2012-01-22 Thread Thomas Jost
JSON does not support hex literals (0x..) so numbers must be formatted
as %d instead of %x.

Currently, the possible values for the gmime error code are 1 (expired
signature), 2 (no public key), 4 (expired key) and 8 (revoked key).
The other possible value is 16 (unsupported algorithm) but obviously
it is much more rare. If this happens, the current code will add
'"errors": 10'. This is valid JSON (it looks like a decimal number)
but it is incorrect (should be 16, not 10).

Since this is just an issue in the JSON encoder, no changes are needed
on the Emacs side (or in other UIs using the JSON output).
---

 notmuch-show.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/notmuch-show.c b/notmuch-show.c
index 43ee211..7b40568 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -728,7 +728,7 @@ format_part_sigstatus_json (const GMimeSignatureValidity* 
validity)
printf (", \"keyid\": %s", json_quote_str (ctx_quote, 
signer->keyid));
}
if (signer->errors != GMIME_SIGNER_ERROR_NONE) {
-   printf (", \"errors\": %x", signer->errors);
+   printf (", \"errors\": %d", signer->errors);
}

printf ("}");
-- 
1.7.8.4



[PATCH] show: don't use hex literals in JSON output

2012-01-21 Thread Thomas Jost
JSON does not support hex literals (0x..) so numbers must be formatted
as %d instead of %x.

Currently, the possible values for the gmime error code are 1 (expired
signature), 2 (no public key), 4 (expired key) and 8 (revoked key).
The other possible value is 16 (unsupported algorithm) but obviously
it is much more rare. If this happens, the current code will add
'errors: 10'. This is valid JSON (it looks like a decimal number)
but it is incorrect (should be 16, not 10).

Since this is just an issue in the JSON encoder, no changes are needed
on the Emacs side (or in other UIs using the JSON output).
---

 notmuch-show.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/notmuch-show.c b/notmuch-show.c
index 43ee211..7b40568 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -728,7 +728,7 @@ format_part_sigstatus_json (const GMimeSignatureValidity* 
validity)
printf (, \keyid\: %s, json_quote_str (ctx_quote, 
signer-keyid));
}
if (signer-errors != GMIME_SIGNER_ERROR_NONE) {
-   printf (, \errors\: %x, signer-errors);
+   printf (, \errors\: %d, signer-errors);
}
 
printf (});
-- 
1.7.8.4

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH] Fix NEWS about gmime 2.6

2012-01-21 Thread Thomas Jost
Previous version had a typo (they may be instead of there may be)
and was lacking a proper description of the gmime bug.
---
Argh. Did not know how to tell it in proper English, ended with a huge
typo. Sorry about that, and thanks for noticing and fixing it :)

 NEWS |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/NEWS b/NEWS
index e78472c..2c2d9e9 100644
--- a/NEWS
+++ b/NEWS
@@ -42,8 +42,8 @@ Build fixes
 Compatibility with GMime 2.6
 
   It is now possible to build notmuch against both GMime 2.4 and 2.6.
-  However they may be some issues in PGP signature verification
-  because of a bug in current versions of GMime 2.6.
+  However, a bug in current GMime 2.6 causes notmuch not to report
+  signatures where the signer key is unavailable (GNOME bug 668085).
 
 Notmuch 0.11 (2012-01-13)
 =
-- 
1.7.8.4

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH v4 1/3] show: don't use hex literals in JSON output

2012-01-20 Thread Thomas Jost
On Fri, 20 Jan 2012 07:55:03 -0400, David Bremner  wrote:
> On Fri, 20 Jan 2012 10:39:23 +0100, Thomas Jost  
> wrote:
> > JSON does not support hex literals (0x..) so numbers must be formatted as %d
> > instead of %x.
> > ---
> >  notmuch-show.c |2 +-
> >  1 files changed, 1 insertions(+), 1 deletions(-)
>  
> Probably I'm just being lazy here, but can you explain why this change
> does not require a corresponding change on the emacs side?

Because Emacs already does the right thing. JSON numbers are supposed to
be decimal only (see http://json.org/: digits are 0-9 only), but the
current code could result in displaying a hexadecimal number instead
("c" instead of "12"). This would then trigger an error in Emacs, or in
any other correct JSON parser.

However we are quite lucky: because of the possible values of the gmime
error codes, such an error cannot happen.

The most common gmime error codes are 1 (expired signature), 2 (no
public key), 4 (expired key) and 8 (revoked key). The other possible
value is 16 (unsupported algorithm) but obviously it is much more rare.
If this happens, the current code will add '"errors": 10' (hex for
16...). This is valid JSON (it looks like a decimal number) but it is
incorrect (should be 16, not 10).

With this patch, notmuch will correctly display '"errors": 16' if such a
case happens.

(By the way, this issue was spotted by Austin Clements in
id:"20120117034714.GG16740 at mit.edu", so he deserves the credits :))

Regards,

-- 
Thomas/Schnouki
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 489 bytes
Desc: not available
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20120120/80917bba/attachment.pgp>


[PATCH v4 3/3] Update NEWS and INSTALL about gmime 2.6

2012-01-20 Thread Thomas Jost
---
 INSTALL |   12 ++--
 NEWS|9 +
 2 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/INSTALL b/INSTALL
index e51b397..bc98f1d 100644
--- a/INSTALL
+++ b/INSTALL
@@ -20,8 +20,8 @@ configure stage.

 Dependencies
 
-Notmuch depends on three libraries: Xapian, GMime 2.4, and Talloc
-which are each described below:
+Notmuch depends on three libraries: Xapian, GMime 2.4 or 2.6, and
+Talloc which are each described below:

Xapian
--
@@ -39,14 +39,14 @@ which are each described below:
reading mail while notmuch would wait for Xapian when removing
the "inbox" and "unread" tags from messages in a thread.

-   GMime 2.4
-   -
-   GMime 2.4 provides decoding of MIME email messages for Notmuch.
+   GMime 2.4 or 2.6
+   
+   GMime provides decoding of MIME email messages for Notmuch.

Without GMime, Notmuch would not be able to extract and index
the actual text from email message encoded as BASE64, etc.

-   GMime 2.4 is available from http://spruce.sourceforge.net/gmime/
+   GMime is available from http://spruce.sourceforge.net/gmime/

Talloc
--
diff --git a/NEWS b/NEWS
index 6afa912..e78472c 100644
--- a/NEWS
+++ b/NEWS
@@ -36,6 +36,15 @@ New functions
   notmuch_query_add_tag_exclude supports the new tag exclusion
   feature.

+Build fixes
+---
+
+Compatibility with GMime 2.6
+
+  It is now possible to build notmuch against both GMime 2.4 and 2.6.
+  However they may be some issues in PGP signature verification
+  because of a bug in current versions of GMime 2.6.
+
 Notmuch 0.11 (2012-01-13)
 =

-- 
1.7.8.4



[PATCH v4 2/3] Add compatibility with gmime 2.6

2012-01-20 Thread Thomas Jost
There are lots of API changes in gmime 2.6 crypto handling. By adding
preprocessor directives, it is however possible to add gmime 2.6 compatibility
while preserving compatibility with gmime 2.4 too.

This is mostly based on id:"8762i8hrb9.fsf at bookbinder.fernseed.info".

This was tested against both gmime 2.6.4 and 2.4.31. With gmime 2.4.31, the
crypto tests all work fine (as expected). With gmime 2.6.4, one crypto test is
currently broken (signature verification with signer key unavailable), most
likely because of a bug in gmime which will hopefully be fixed in a future
version.
---
 mime-node.c  |   57 +++-
 notmuch-client.h |   30 -
 notmuch-reply.c  |7 
 notmuch-show.c   |   95 ++
 show-message.c   |4 ++
 test/crypto  |2 +
 6 files changed, 191 insertions(+), 4 deletions(-)

diff --git a/mime-node.c b/mime-node.c
index d26bb44..27077f7 100644
--- a/mime-node.c
+++ b/mime-node.c
@@ -33,7 +33,11 @@ typedef struct mime_node_context {
 GMimeMessage *mime_message;

 /* Context provided by the caller. */
+#ifdef GMIME_ATLEAST_26
+GMimeCryptoContext *cryptoctx;
+#else
 GMimeCipherContext *cryptoctx;
+#endif
 notmuch_bool_t decrypt;
 } mime_node_context_t;

@@ -57,8 +61,12 @@ _mime_node_context_free (mime_node_context_t *res)

 notmuch_status_t
 mime_node_open (const void *ctx, notmuch_message_t *message,
-   GMimeCipherContext *cryptoctx, notmuch_bool_t decrypt,
-   mime_node_t **root_out)
+#ifdef GMIME_ATLEAST_26
+   GMimeCryptoContext *cryptoctx,
+#else
+   GMimeCipherContext *cryptoctx,
+#endif
+   notmuch_bool_t decrypt, mime_node_t **root_out)
 {
 const char *filename = notmuch_message_get_filename (message);
 mime_node_context_t *mctx;
@@ -112,12 +120,21 @@ DONE:
 return status;
 }

+#ifdef GMIME_ATLEAST_26
+static int
+_signature_list_free (GMimeSignatureList **proxy)
+{
+g_object_unref (*proxy);
+return 0;
+}
+#else
 static int
 _signature_validity_free (GMimeSignatureValidity **proxy)
 {
 g_mime_signature_validity_free (*proxy);
 return 0;
 }
+#endif

 static mime_node_t *
 _mime_node_create (const mime_node_t *parent, GMimeObject *part)
@@ -165,11 +182,25 @@ _mime_node_create (const mime_node_t *parent, GMimeObject 
*part)
GMimeMultipartEncrypted *encrypteddata =
GMIME_MULTIPART_ENCRYPTED (part);
node->decrypt_attempted = TRUE;
+#ifdef GMIME_ATLEAST_26
+   GMimeDecryptResult *decrypt_result = NULL;
+   node->decrypted_child = g_mime_multipart_encrypted_decrypt
+   (encrypteddata, node->ctx->cryptoctx, _result, );
+#else
node->decrypted_child = g_mime_multipart_encrypted_decrypt
(encrypteddata, node->ctx->cryptoctx, );
+#endif
if (node->decrypted_child) {
node->decrypt_success = node->verify_attempted = TRUE;
+#ifdef GMIME_ATLEAST_26
+   /* This may be NULL if the part is not signed. */
+   node->sig_list = g_mime_decrypt_result_get_signatures 
(decrypt_result);
+   if (node->sig_list)
+   g_object_ref (node->sig_list);
+   g_object_unref (decrypt_result);
+#else
node->sig_validity = 
g_mime_multipart_encrypted_get_signature_validity (encrypteddata);
+#endif
} else {
fprintf (stderr, "Failed to decrypt part: %s\n",
 (err ? err->message : "no error explanation given"));
@@ -182,6 +213,15 @@ _mime_node_create (const mime_node_t *parent, GMimeObject 
*part)
 "(must be exactly 2)\n",
 node->nchildren);
} else {
+#ifdef GMIME_ATLEAST_26
+   node->sig_list = g_mime_multipart_signed_verify
+   (GMIME_MULTIPART_SIGNED (part), node->ctx->cryptoctx, );
+   node->verify_attempted = TRUE;
+
+   if (!node->sig_list)
+   fprintf (stderr, "Failed to verify signed part: %s\n",
+(err ? err->message : "no error explanation given"));
+#else
/* For some reason the GMimeSignatureValidity returned
 * here is not a const (inconsistent with that
 * returned by
@@ -200,12 +240,25 @@ _mime_node_create (const mime_node_t *parent, GMimeObject 
*part)
*proxy = sig_validity;
talloc_set_destructor (proxy, _signature_validity_free);
}
+#endif
}
 }

+#ifdef GMIME_ATLEAST_26
+/* sig_list may be created in both above cases, so we need to
+ * cleanly handle it here. */
+if (node->sig_list) {
+   GMimeSignatureList **proxy = talloc (node, GMimeSignatureList *);
+   *proxy = node->sig_list;
+   talloc_set_destructor (proxy, _signature_list_free);
+}
+#endif
+
+#ifndef GMIME_ATLEAST_26
 if (node->verify_attempted && 

[PATCH v4 1/3] show: don't use hex literals in JSON output

2012-01-20 Thread Thomas Jost
JSON does not support hex literals (0x..) so numbers must be formatted as %d
instead of %x.
---
 notmuch-show.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/notmuch-show.c b/notmuch-show.c
index d14dac9..91f566c 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -641,7 +641,7 @@ format_part_sigstatus_json (const GMimeSignatureValidity* 
validity)
printf (", \"keyid\": %s", json_quote_str (ctx_quote, 
signer->keyid));
}
if (signer->errors != GMIME_SIGNER_ERROR_NONE) {
-   printf (", \"errors\": %x", signer->errors);
+   printf (", \"errors\": %d", signer->errors);
}

printf ("}");
-- 
1.7.8.4



[PATCH v3 2/2] Add compatibility with gmime 2.6

2012-01-20 Thread Thomas Jost
On Thu, 19 Jan 2012 23:10:44 -0500, Austin Clements  wrote:
> Nearly there.  A few more small comments.

Thanks again :) Will post new version soon, including a new patch to
update NEWS and INSTALL.

> Quoth Thomas Jost on Jan 20 at  1:06 am:
> > There are lots of API changes in gmime 2.6 crypto handling. By adding
> > preprocessor directives, it is however possible to add gmime 2.6 
> > compatibility
> > while preserving compatibility with gmime 2.4 too.
> > 
> > This is mostly based on id:"8762i8hrb9.fsf at bookbinder.fernseed.info".
> > 
> > This was tested against both gmime 2.6.4 and 2.4.31. With gmime 2.4.31, the
> > crypto tests all work fine (as expected). With gmime 2.6.4, one crypto test 
> > is
> > currently broken (signature verification with signer key unavailable), most
> > likely because of a bug in gmime which will hopefully be fixed in a future
> > version.
> > ---
> >  mime-node.c  |   60 --
> >  notmuch-client.h |   30 -
> >  notmuch-reply.c  |7 
> >  notmuch-show.c   |   95 
> > ++
> >  show-message.c   |4 ++
> >  test/crypto  |2 +
> >  6 files changed, 192 insertions(+), 6 deletions(-)
> > 
> > diff --git a/mime-node.c b/mime-node.c
> > index d26bb44..ad19f5e 100644
> > --- a/mime-node.c
> > +++ b/mime-node.c
> > @@ -33,7 +33,11 @@ typedef struct mime_node_context {
> >  GMimeMessage *mime_message;
> >  
> >  /* Context provided by the caller. */
> > +#ifdef GMIME_ATLEAST_26
> > +GMimeCryptoContext *cryptoctx;
> > +#else
> >  GMimeCipherContext *cryptoctx;
> > +#endif
> >  notmuch_bool_t decrypt;
> >  } mime_node_context_t;
> >  
> > @@ -57,8 +61,12 @@ _mime_node_context_free (mime_node_context_t *res)
> >  
> >  notmuch_status_t
> >  mime_node_open (const void *ctx, notmuch_message_t *message,
> > -   GMimeCipherContext *cryptoctx, notmuch_bool_t decrypt,
> > -   mime_node_t **root_out)
> > +#ifdef GMIME_ATLEAST_26
> > +   GMimeCryptoContext *cryptoctx,
> > +#else
> > +   GMimeCipherContext *cryptoctx,
> > +#endif
> > +   notmuch_bool_t decrypt, mime_node_t **root_out)
> >  {
> >  const char *filename = notmuch_message_get_filename (message);
> >  mime_node_context_t *mctx;
> > @@ -112,12 +120,21 @@ DONE:
> >  return status;
> >  }
> >  
> > +#ifdef GMIME_ATLEAST_26
> > +static int
> > +_signature_list_free (GMimeSignatureList **proxy)
> > +{
> > +g_object_unref (*proxy);
> > +return 0;
> > +}
> > +#else
> >  static int
> >  _signature_validity_free (GMimeSignatureValidity **proxy)
> >  {
> >  g_mime_signature_validity_free (*proxy);
> >  return 0;
> >  }
> > +#endif
> >  
> >  static mime_node_t *
> >  _mime_node_create (const mime_node_t *parent, GMimeObject *part)
> > @@ -165,11 +182,24 @@ _mime_node_create (const mime_node_t *parent, 
> > GMimeObject *part)
> > GMimeMultipartEncrypted *encrypteddata =
> > GMIME_MULTIPART_ENCRYPTED (part);
> > node->decrypt_attempted = TRUE;
> > +#ifdef GMIME_ATLEAST_26
> > +   GMimeDecryptResult *decrypt_result = NULL;
> > +   node->decrypted_child = g_mime_multipart_encrypted_decrypt
> > +   (encrypteddata, node->ctx->cryptoctx, _result, );
> > +#else
> > node->decrypted_child = g_mime_multipart_encrypted_decrypt
> > (encrypteddata, node->ctx->cryptoctx, );
> > +#endif
> > if (node->decrypted_child) {
> > node->decrypt_success = node->verify_attempted = TRUE;
> > +#ifdef GMIME_ATLEAST_26
> > +   /* This may be NULL if the part is not signed. */
> > +   node->sig_list = g_mime_decrypt_result_get_signatures 
> > (decrypt_result);
> > +   g_object_ref (node->sig_list);
> 
> Apparently you can't g_object_ref NULL, so there should be a
> conditional around this.

Right, added. Thanks.

> (Does g_mime_decrypt_result_get_signatures *really* return NULL for an
> empty list? I feel like various tests should have failed in various
> versions of this patch if it did.)

Yes it does. I added some fprintf() in gmime (in gpg_decrypt() and
g_mime_decrypt_result_get_signatures()). Decryption tests (after "emacs
delivery of encrypted message with attachment") clearly show that
g_mime_decrypt_result_ge

[PATCH v3 2/2] Add compatibility with gmime 2.6

2012-01-20 Thread Thomas Jost
There are lots of API changes in gmime 2.6 crypto handling. By adding
preprocessor directives, it is however possible to add gmime 2.6 compatibility
while preserving compatibility with gmime 2.4 too.

This is mostly based on id:"8762i8hrb9.fsf at bookbinder.fernseed.info".

This was tested against both gmime 2.6.4 and 2.4.31. With gmime 2.4.31, the
crypto tests all work fine (as expected). With gmime 2.6.4, one crypto test is
currently broken (signature verification with signer key unavailable), most
likely because of a bug in gmime which will hopefully be fixed in a future
version.
---
 mime-node.c  |   60 --
 notmuch-client.h |   30 -
 notmuch-reply.c  |7 
 notmuch-show.c   |   95 ++
 show-message.c   |4 ++
 test/crypto  |2 +
 6 files changed, 192 insertions(+), 6 deletions(-)

diff --git a/mime-node.c b/mime-node.c
index d26bb44..ad19f5e 100644
--- a/mime-node.c
+++ b/mime-node.c
@@ -33,7 +33,11 @@ typedef struct mime_node_context {
 GMimeMessage *mime_message;

 /* Context provided by the caller. */
+#ifdef GMIME_ATLEAST_26
+GMimeCryptoContext *cryptoctx;
+#else
 GMimeCipherContext *cryptoctx;
+#endif
 notmuch_bool_t decrypt;
 } mime_node_context_t;

@@ -57,8 +61,12 @@ _mime_node_context_free (mime_node_context_t *res)

 notmuch_status_t
 mime_node_open (const void *ctx, notmuch_message_t *message,
-   GMimeCipherContext *cryptoctx, notmuch_bool_t decrypt,
-   mime_node_t **root_out)
+#ifdef GMIME_ATLEAST_26
+   GMimeCryptoContext *cryptoctx,
+#else
+   GMimeCipherContext *cryptoctx,
+#endif
+   notmuch_bool_t decrypt, mime_node_t **root_out)
 {
 const char *filename = notmuch_message_get_filename (message);
 mime_node_context_t *mctx;
@@ -112,12 +120,21 @@ DONE:
 return status;
 }

+#ifdef GMIME_ATLEAST_26
+static int
+_signature_list_free (GMimeSignatureList **proxy)
+{
+g_object_unref (*proxy);
+return 0;
+}
+#else
 static int
 _signature_validity_free (GMimeSignatureValidity **proxy)
 {
 g_mime_signature_validity_free (*proxy);
 return 0;
 }
+#endif

 static mime_node_t *
 _mime_node_create (const mime_node_t *parent, GMimeObject *part)
@@ -165,11 +182,24 @@ _mime_node_create (const mime_node_t *parent, GMimeObject 
*part)
GMimeMultipartEncrypted *encrypteddata =
GMIME_MULTIPART_ENCRYPTED (part);
node->decrypt_attempted = TRUE;
+#ifdef GMIME_ATLEAST_26
+   GMimeDecryptResult *decrypt_result = NULL;
+   node->decrypted_child = g_mime_multipart_encrypted_decrypt
+   (encrypteddata, node->ctx->cryptoctx, _result, );
+#else
node->decrypted_child = g_mime_multipart_encrypted_decrypt
(encrypteddata, node->ctx->cryptoctx, );
+#endif
if (node->decrypted_child) {
node->decrypt_success = node->verify_attempted = TRUE;
+#ifdef GMIME_ATLEAST_26
+   /* This may be NULL if the part is not signed. */
+   node->sig_list = g_mime_decrypt_result_get_signatures 
(decrypt_result);
+   g_object_ref (node->sig_list);
+   g_object_unref (decrypt_result);
+#else
node->sig_validity = 
g_mime_multipart_encrypted_get_signature_validity (encrypteddata);
+#endif
} else {
fprintf (stderr, "Failed to decrypt part: %s\n",
 (err ? err->message : "no error explanation given"));
@@ -182,6 +212,15 @@ _mime_node_create (const mime_node_t *parent, GMimeObject 
*part)
 "(must be exactly 2)\n",
 node->nchildren);
} else {
+#ifdef GMIME_ATLEAST_26
+   node->sig_list = g_mime_multipart_signed_verify
+   (GMIME_MULTIPART_SIGNED (part), node->ctx->cryptoctx, );
+   node->verify_attempted = TRUE;
+
+   if (!node->sig_list)
+   fprintf (stderr, "Failed to verify signed part: %s\n",
+(err ? err->message : "no error explanation given"));
+#else
/* For some reason the GMimeSignatureValidity returned
 * here is not a const (inconsistent with that
 * returned by
@@ -195,17 +234,30 @@ _mime_node_create (const mime_node_t *parent, GMimeObject 
*part)
node->verify_attempted = TRUE;
node->sig_validity = sig_validity;
if (sig_validity) {
-   GMimeSignatureValidity **proxy =
-   talloc (node, GMimeSignatureValidity *);
+   GMimeSignatureValidity **proxy = talloc (node, 
GMimeSignatureValidity *);
*proxy = sig_validity;
talloc_set_destructor (proxy, _signature_validity_free);
}
+#endif
}
 }

+#ifdef GMIME_ATLEAST_26
+/* sig_list may be created in both above cases, so we need to
+ * cleanly handle it 

[PATCH v3 1/2] show: don't use hex literals in JSON output

2012-01-20 Thread Thomas Jost
JSON does not support hex literals (0x..) so numbers must be formatted as %d
instead of %x.
---
 notmuch-show.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/notmuch-show.c b/notmuch-show.c
index d14dac9..91f566c 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -641,7 +641,7 @@ format_part_sigstatus_json (const GMimeSignatureValidity* 
validity)
printf (", \"keyid\": %s", json_quote_str (ctx_quote, 
signer->keyid));
}
if (signer->errors != GMIME_SIGNER_ERROR_NONE) {
-   printf (", \"errors\": %x", signer->errors);
+   printf (", \"errors\": %d", signer->errors);
}

printf ("}");
-- 
1.7.8.4



[PATCH v3 0/2] gmime 2.6 compatibilty, 3rd iteration

2012-01-20 Thread Thomas Jost
Hi list,

Here's another update of the patches to add gmime 2.6 compatibilty
while still preserving compatibility with gmime 2.4.

Any comments or review will be much appreciated.

The changes compared to the previous version ([1] and [2]) are pretty
minor:
- space and indentation fixes
- correctly dereference the instance of GMimeDecryptResult allocated
  by g_mime_decrypt_result_get_signatures()
- remove a useless local variable
- rename the preprocessor constant GMIME_26 to GMIME_ATLEAST_26
- mark one crypto test as broken when using gmime 2.6 (because of a
  bug in gmime [3])

The first patch is really not specific to gmime so it could probably
be pushed right away.

Thanks to Austin Clements, Tomi Ollila and Adrian Perez for their
reviews of the previous patches!

Best regards,
Thomas

[1] id:"1326797453-9405-1-git-send-email-schnouki at schnouki.net"
[2] id:"1326797453-9405-2-git-send-email-schnouki at schnouki.net"
[3] https://bugzilla.gnome.org/show_bug.cgi?id=668085

Thomas Jost (2):
  show: don't use hex literals in JSON output
  Add compatibility with gmime 2.6

 mime-node.c  |   60 +++--
 notmuch-client.h |   30 +++-
 notmuch-reply.c  |7 
 notmuch-show.c   |   97 +-
 show-message.c   |4 ++
 test/crypto  |2 +
 6 files changed, 193 insertions(+), 7 deletions(-)

-- 
1.7.8.4



[PATCH] Add pseudo-compatibility with gmime 2.6

2012-01-20 Thread Thomas Jost
On Tue, 17 Jan 2012 15:38:36 -0500, Austin Clements  wrote:
> Quoth Thomas Jost on Jan 17 at 11:48 am:
> > On Mon, 16 Jan 2012 22:47:14 -0500, Austin Clements  
> > wrote:
> > > Quoth Thomas Jost on Jan 17 at 12:56 am:
> > > > This is mostly based on id:"8762i8hrb9.fsf at bookbinder.fernseed.info".
> > > > 
> > > > This was tested against both gmime 2.6.4 and 2.4.31. With gmime 2.4.31, 
> > > > the
> > > > crypto tests all work fine (as expected). With gmime 2.6.4, one crypto 
> > > > test
> > > > fails (signature verification with signer key unavailable) but this 
> > > > will be hard
> > > > to fix since the new API does not report the reason why a signature 
> > > > verification
> > > > fails (other than the human-readable error message).
> > > 
> > > What is the result of this failing test?
> > 
> > The test looks like that:
> > 
> > FAIL   signature verification with signer key unavailable
> >--- crypto.4.expected   2012-01-16 23:05:06.765651183 +
> >+++ crypto.4.output 2012-01-16 23:05:06.765651183 +
> >@@ -12,9 +12,7 @@
> >  "Bcc": "",
> >  "Date": "01 Jan 2000 12:00:00 -"},
> >  "body": [{"id": 1,
> >- "sigstatus": [{"status": "error",
> >- "keyid": "6D92612D94E46381",
> >- "errors": 2}],
> >+ "sigstatus": [],
> >  "content-type": "multipart/signed",
> >  "content": [{"id": 2,
> >  "content-type": "text/plain",
> >Failed to verify signed part: gpg: keyblock resource 
> > `/home/schnouki/dev/notmuch/test/tmp.crypto/gnupg/pubring.gpg': file open 
> > error
> >gpg: armor header: Version: GnuPG v1.4.11 (GNU/Linux)
> >gpg: Signature made Mon Jan 16 23:05:06 2012 UTC using RSA key ID 
> > 94E46381
> >gpg: Can't check signature: public key not found
> > 
> > So basically if a signer public key is missing, we can't get the status
> > signature: empty "sigstatus" field in the JSON output, "Unknown
> > signature status" in Emacs.
> > 
> > IMHO this is a bug in gmime 2.6, and I think I know what causes it. I'll
> > file a bug in gmime and hopefully they'll find a cleaner way to fix it
> > than the one I came up with :)
> 
> Oh, okay.  That does seem like a bug in GMime.  Do you think it would
> be possible to mark this test as "broken" if notmuch is using GMime
> 2.6?  Off the top of my head, I can't think of an easy way to plumb
> that information through to the test suite.  I don't think we should
> push any patches that knowingly break a test, even if it's in just one
> configuration.

Here is how I did:

  (ldd notmuch | grep -q gmime-2.6) && test_subtest_known_broken

ldd notmuch will show "/path/to/libgmime-2.4.so.*" or
"libgmime-2.6.so.*" so we can easily check this in the test suite.
It's a little hacky but it seems to work. AFAIK ldd is a pretty standard
tool so it should be available (almost) everywhere. However if you have
a better idea I'll be glad to hear it.

> > > > +#ifdef GMIME_26
> > > > +if (node->verify_attempted && !node->sig_list)
> > > 
> > > Hmm.  This is correct for signed parts, but will incorrectly trigger
> > > for an encrypted part with no signatures.  For 2.6, I think this error
> > > checking may have to move into the branches of the if encrypted/signed
> > > since for encrypted parts you have to check if
> > > g_mime_multipart_encrypted_decrypt returned NULL.
> > 
> > That sound right. The weird part is that it did not cause anything to
> > fail in the test suite...
> 
> It would be worth adding a test with an encrypted but unsigned part.
> I don't know enough GPG myself to do that.

It looks like there's already one: "emacs delivery of encrypted message
with attachment" + following decryptions.

Regards,

-- 
Thomas/Schnouki
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 489 bytes
Desc: not available
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20120120/1544b0d5/attachment.pgp>


[PATCH v2 2/2] Add pseudo-compatibility with gmime 2.6

2012-01-20 Thread Thomas Jost
On Wed, 18 Jan 2012 12:35:34 -0500, Austin Clements  wrote:
> Quoth Tomi Ollila on Jan 18 at 10:15 am:
> > On Tue, 17 Jan 2012 17:25:46 -0500, Austin Clements  
> > wrote:
> > > Quoth Thomas Jost on Jan 17 at 11:50 am:
> > > >  
> > > > +#ifdef GMIME_26
> > > > +/* sig_list may be created in both above cases, so we need to
> > > > + * cleanly handle it here. */
> > > > +if (node->sig_list) {
> > > > +   GMimeSignatureList **proxy =
> > > > +   talloc (node, GMimeSignatureList *);
> > > 
> > > This doesn't need to be split into two lines.
> > > 
> > > > +   *proxy = node->sig_list;
> > > > +   talloc_set_destructor (proxy, _signature_list_free);
> > > > +}
> > > > +#else
> > > >  if (node->verify_attempted && !node->sig_validity)
> > > > fprintf (stderr, "Failed to verify signed part: %s\n",
> > > >  (err ? err->message : "no error explanation given"));
> > > > +#endif
> > > 
> > > I'd rather see the above as a separate #ifdef GMIME_26 and #ifndef
> > > GMIME_26, since they aren't logical alternates of each other.
> > 
> > That reminds me that it should then be like GMIME_ATLEAST_26, so
> > that this might be useful when GMIME > 2.6 is available...
> 
> Hopefully before GMIME 2.8 comes out, we'll be able to remove all of
> the GMIME 2.4 compatibility.  But GMIME_ATLEAST_26 would be fine, too.

Heh, maybe things will change again in 2.8 and "ATLEAST_26" will become
"ONLY_26"... But changed to GMIME_ATLEAST_26 anyway, thanks for the
suggestion :)

-- 
Thomas/Schnouki
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 489 bytes
Desc: not available
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20120120/00362800/attachment.pgp>


[PATCH v2 2/2] Add pseudo-compatibility with gmime 2.6

2012-01-20 Thread Thomas Jost
Thanks for this review Austin. New version coming soon.

On Tue, 17 Jan 2012 17:25:46 -0500, Austin Clements  wrote:
> Quoth Thomas Jost on Jan 17 at 11:50 am:
> > There are lots of API changes in gmime 2.6 crypto handling. By adding
> > preprocessor directives, it is however possible to add gmime 2.6 
> > compatibility
> > while preserving compatibility with gmime 2.4 too.
> > 
> > This is mostly based on id:"8762i8hrb9.fsf at bookbinder.fernseed.info".
> > 
> > This was tested against both gmime 2.6.4 and 2.4.31. With gmime 2.4.31, the
> > crypto tests all work fine (as expected). With gmime 2.6.4, one crypto test
> > fails (signature verification with signer key unavailable) but this will be 
> > hard
> > to fix since the new API does not report the reason why a signature 
> > verification
> > fails (other than the human-readable error message).
> > ---
> >  mime-node.c  |   56 ++--
> >  notmuch-client.h |   28 +++-
> >  notmuch-reply.c  |7 
> >  notmuch-show.c   |   95 
> > ++
> >  show-message.c   |4 ++
> >  5 files changed, 185 insertions(+), 5 deletions(-)
> > 
> > diff --git a/mime-node.c b/mime-node.c
> > index d26bb44..e575e1c 100644
> > --- a/mime-node.c
> > +++ b/mime-node.c
> > @@ -33,7 +33,11 @@ typedef struct mime_node_context {
> >  GMimeMessage *mime_message;
> >  
> >  /* Context provided by the caller. */
> > +#ifdef GMIME_26
> > +GMimeCryptoContext *cryptoctx;
> > +#else
> >  GMimeCipherContext *cryptoctx;
> > +#endif
> >  notmuch_bool_t decrypt;
> >  } mime_node_context_t;
> >  
> > @@ -57,8 +61,12 @@ _mime_node_context_free (mime_node_context_t *res)
> >  
> >  notmuch_status_t
> >  mime_node_open (const void *ctx, notmuch_message_t *message,
> > -   GMimeCipherContext *cryptoctx, notmuch_bool_t decrypt,
> > -   mime_node_t **root_out)
> > +#ifdef GMIME_26
> > +   GMimeCryptoContext *cryptoctx,
> > +#else
> > +   GMimeCipherContext *cryptoctx,
> > +#endif
> > +   notmuch_bool_t decrypt, mime_node_t **root_out)
> >  {
> >  const char *filename = notmuch_message_get_filename (message);
> >  mime_node_context_t *mctx;
> > @@ -112,12 +120,21 @@ DONE:
> >  return status;
> >  }
> >  
> > +#ifdef GMIME_26
> > +static int
> > +_signature_list_free (GMimeSignatureList **proxy)
> > +{
> > +g_object_unref (*proxy);
> > +return 0;
> > +}
> > +#else
> >  static int
> >  _signature_validity_free (GMimeSignatureValidity **proxy)
> >  {
> >  g_mime_signature_validity_free (*proxy);
> >  return 0;
> >  }
> > +#endif
> >  
> >  static mime_node_t *
> >  _mime_node_create (const mime_node_t *parent, GMimeObject *part)
> > @@ -165,11 +182,22 @@ _mime_node_create (const mime_node_t *parent, 
> > GMimeObject *part)
> > GMimeMultipartEncrypted *encrypteddata =
> > GMIME_MULTIPART_ENCRYPTED (part);
> > node->decrypt_attempted = TRUE;
> > +#ifdef GMIME_26
> > +   GMimeDecryptResult *decrypt_result = NULL;
> 
> Reading through the GMime code, it looks like we do have to unref
> decrypt_result.  I think this is easy, though.  Right after you call
> g_mime_decrypt_result_get_signatures below, do:
> 
>   g_object_ref (node->sig_list);
>   g_object_unref (decrypt_result);

Added, thanks!

> 
> > +   node->decrypted_child = g_mime_multipart_encrypted_decrypt
> > +   (encrypteddata, node->ctx->cryptoctx, _result, );
> > +#else
> > node->decrypted_child = g_mime_multipart_encrypted_decrypt
> > (encrypteddata, node->ctx->cryptoctx, );
> > +#endif
> > if (node->decrypted_child) {
> > -   node->decrypt_success = node->verify_attempted = TRUE;
> > +   node->decrypt_success = node->verify_attempted =TRUE;
> 
> Whitespace.  (There should be no diff on the above line)

Oops, my bad.

> 
> > +#ifdef GMIME_26
> > +   /* This may be NULL if the part is not signed. */
> > +   node->sig_list = g_mime_decrypt_result_get_signatures 
> > (decrypt_result);
> > +#else
> > node->sig_validity = 
> > g_mime_multipart_encrypted_get_signature_validity (encrypteddata);
> > +#endif
> > } else {
> > fprintf (stderr, "Fa

Re: [PATCH v3 2/2] Add compatibility with gmime 2.6

2012-01-20 Thread Thomas Jost
On Thu, 19 Jan 2012 23:10:44 -0500, Austin Clements amdra...@mit.edu wrote:
 Nearly there.  A few more small comments.

Thanks again :) Will post new version soon, including a new patch to
update NEWS and INSTALL.

 Quoth Thomas Jost on Jan 20 at  1:06 am:
  There are lots of API changes in gmime 2.6 crypto handling. By adding
  preprocessor directives, it is however possible to add gmime 2.6 
  compatibility
  while preserving compatibility with gmime 2.4 too.
  
  This is mostly based on id:8762i8hrb9@bookbinder.fernseed.info.
  
  This was tested against both gmime 2.6.4 and 2.4.31. With gmime 2.4.31, the
  crypto tests all work fine (as expected). With gmime 2.6.4, one crypto test 
  is
  currently broken (signature verification with signer key unavailable), most
  likely because of a bug in gmime which will hopefully be fixed in a future
  version.
  ---
   mime-node.c  |   60 --
   notmuch-client.h |   30 -
   notmuch-reply.c  |7 
   notmuch-show.c   |   95 
  ++
   show-message.c   |4 ++
   test/crypto  |2 +
   6 files changed, 192 insertions(+), 6 deletions(-)
  
  diff --git a/mime-node.c b/mime-node.c
  index d26bb44..ad19f5e 100644
  --- a/mime-node.c
  +++ b/mime-node.c
  @@ -33,7 +33,11 @@ typedef struct mime_node_context {
   GMimeMessage *mime_message;
   
   /* Context provided by the caller. */
  +#ifdef GMIME_ATLEAST_26
  +GMimeCryptoContext *cryptoctx;
  +#else
   GMimeCipherContext *cryptoctx;
  +#endif
   notmuch_bool_t decrypt;
   } mime_node_context_t;
   
  @@ -57,8 +61,12 @@ _mime_node_context_free (mime_node_context_t *res)
   
   notmuch_status_t
   mime_node_open (const void *ctx, notmuch_message_t *message,
  -   GMimeCipherContext *cryptoctx, notmuch_bool_t decrypt,
  -   mime_node_t **root_out)
  +#ifdef GMIME_ATLEAST_26
  +   GMimeCryptoContext *cryptoctx,
  +#else
  +   GMimeCipherContext *cryptoctx,
  +#endif
  +   notmuch_bool_t decrypt, mime_node_t **root_out)
   {
   const char *filename = notmuch_message_get_filename (message);
   mime_node_context_t *mctx;
  @@ -112,12 +120,21 @@ DONE:
   return status;
   }
   
  +#ifdef GMIME_ATLEAST_26
  +static int
  +_signature_list_free (GMimeSignatureList **proxy)
  +{
  +g_object_unref (*proxy);
  +return 0;
  +}
  +#else
   static int
   _signature_validity_free (GMimeSignatureValidity **proxy)
   {
   g_mime_signature_validity_free (*proxy);
   return 0;
   }
  +#endif
   
   static mime_node_t *
   _mime_node_create (const mime_node_t *parent, GMimeObject *part)
  @@ -165,11 +182,24 @@ _mime_node_create (const mime_node_t *parent, 
  GMimeObject *part)
  GMimeMultipartEncrypted *encrypteddata =
  GMIME_MULTIPART_ENCRYPTED (part);
  node-decrypt_attempted = TRUE;
  +#ifdef GMIME_ATLEAST_26
  +   GMimeDecryptResult *decrypt_result = NULL;
  +   node-decrypted_child = g_mime_multipart_encrypted_decrypt
  +   (encrypteddata, node-ctx-cryptoctx, decrypt_result, err);
  +#else
  node-decrypted_child = g_mime_multipart_encrypted_decrypt
  (encrypteddata, node-ctx-cryptoctx, err);
  +#endif
  if (node-decrypted_child) {
  node-decrypt_success = node-verify_attempted = TRUE;
  +#ifdef GMIME_ATLEAST_26
  +   /* This may be NULL if the part is not signed. */
  +   node-sig_list = g_mime_decrypt_result_get_signatures 
  (decrypt_result);
  +   g_object_ref (node-sig_list);
 
 Apparently you can't g_object_ref NULL, so there should be a
 conditional around this.

Right, added. Thanks.

 (Does g_mime_decrypt_result_get_signatures *really* return NULL for an
 empty list? I feel like various tests should have failed in various
 versions of this patch if it did.)

Yes it does. I added some fprintf() in gmime (in gpg_decrypt() and
g_mime_decrypt_result_get_signatures()). Decryption tests (after emacs
delivery of encrypted message with attachment) clearly show that
g_mime_decrypt_result_get_signatures returns NULL when there's no
signatures in an encrypted part.

I guess the reason why tests did not fail is that
format_part_sigstatus_json just displays an empty JSON array if sig_list
is NULL. And that's also what's expected when an encrypted part has no
signature.

I had a quick look at the GObject code; apparently if you pass NULL to
g_object_ref (or anything that is not a GObject) it will just return
NULL. So that's why this one did not fail either.

 
  +   g_object_unref (decrypt_result);
  +#else
  node-sig_validity = 
  g_mime_multipart_encrypted_get_signature_validity (encrypteddata);
  +#endif
  } else {
  fprintf (stderr, Failed to decrypt part: %s\n,
   (err ? err-message : no error explanation given));
  @@ -182,6 +212,15 @@ _mime_node_create (const

[PATCH v4 1/3] show: don't use hex literals in JSON output

2012-01-20 Thread Thomas Jost
JSON does not support hex literals (0x..) so numbers must be formatted as %d
instead of %x.
---
 notmuch-show.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/notmuch-show.c b/notmuch-show.c
index d14dac9..91f566c 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -641,7 +641,7 @@ format_part_sigstatus_json (const GMimeSignatureValidity* 
validity)
printf (, \keyid\: %s, json_quote_str (ctx_quote, 
signer-keyid));
}
if (signer-errors != GMIME_SIGNER_ERROR_NONE) {
-   printf (, \errors\: %x, signer-errors);
+   printf (, \errors\: %d, signer-errors);
}
 
printf (});
-- 
1.7.8.4

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH v4 2/3] Add compatibility with gmime 2.6

2012-01-20 Thread Thomas Jost
There are lots of API changes in gmime 2.6 crypto handling. By adding
preprocessor directives, it is however possible to add gmime 2.6 compatibility
while preserving compatibility with gmime 2.4 too.

This is mostly based on id:8762i8hrb9@bookbinder.fernseed.info.

This was tested against both gmime 2.6.4 and 2.4.31. With gmime 2.4.31, the
crypto tests all work fine (as expected). With gmime 2.6.4, one crypto test is
currently broken (signature verification with signer key unavailable), most
likely because of a bug in gmime which will hopefully be fixed in a future
version.
---
 mime-node.c  |   57 +++-
 notmuch-client.h |   30 -
 notmuch-reply.c  |7 
 notmuch-show.c   |   95 ++
 show-message.c   |4 ++
 test/crypto  |2 +
 6 files changed, 191 insertions(+), 4 deletions(-)

diff --git a/mime-node.c b/mime-node.c
index d26bb44..27077f7 100644
--- a/mime-node.c
+++ b/mime-node.c
@@ -33,7 +33,11 @@ typedef struct mime_node_context {
 GMimeMessage *mime_message;
 
 /* Context provided by the caller. */
+#ifdef GMIME_ATLEAST_26
+GMimeCryptoContext *cryptoctx;
+#else
 GMimeCipherContext *cryptoctx;
+#endif
 notmuch_bool_t decrypt;
 } mime_node_context_t;
 
@@ -57,8 +61,12 @@ _mime_node_context_free (mime_node_context_t *res)
 
 notmuch_status_t
 mime_node_open (const void *ctx, notmuch_message_t *message,
-   GMimeCipherContext *cryptoctx, notmuch_bool_t decrypt,
-   mime_node_t **root_out)
+#ifdef GMIME_ATLEAST_26
+   GMimeCryptoContext *cryptoctx,
+#else
+   GMimeCipherContext *cryptoctx,
+#endif
+   notmuch_bool_t decrypt, mime_node_t **root_out)
 {
 const char *filename = notmuch_message_get_filename (message);
 mime_node_context_t *mctx;
@@ -112,12 +120,21 @@ DONE:
 return status;
 }
 
+#ifdef GMIME_ATLEAST_26
+static int
+_signature_list_free (GMimeSignatureList **proxy)
+{
+g_object_unref (*proxy);
+return 0;
+}
+#else
 static int
 _signature_validity_free (GMimeSignatureValidity **proxy)
 {
 g_mime_signature_validity_free (*proxy);
 return 0;
 }
+#endif
 
 static mime_node_t *
 _mime_node_create (const mime_node_t *parent, GMimeObject *part)
@@ -165,11 +182,25 @@ _mime_node_create (const mime_node_t *parent, GMimeObject 
*part)
GMimeMultipartEncrypted *encrypteddata =
GMIME_MULTIPART_ENCRYPTED (part);
node-decrypt_attempted = TRUE;
+#ifdef GMIME_ATLEAST_26
+   GMimeDecryptResult *decrypt_result = NULL;
+   node-decrypted_child = g_mime_multipart_encrypted_decrypt
+   (encrypteddata, node-ctx-cryptoctx, decrypt_result, err);
+#else
node-decrypted_child = g_mime_multipart_encrypted_decrypt
(encrypteddata, node-ctx-cryptoctx, err);
+#endif
if (node-decrypted_child) {
node-decrypt_success = node-verify_attempted = TRUE;
+#ifdef GMIME_ATLEAST_26
+   /* This may be NULL if the part is not signed. */
+   node-sig_list = g_mime_decrypt_result_get_signatures 
(decrypt_result);
+   if (node-sig_list)
+   g_object_ref (node-sig_list);
+   g_object_unref (decrypt_result);
+#else
node-sig_validity = 
g_mime_multipart_encrypted_get_signature_validity (encrypteddata);
+#endif
} else {
fprintf (stderr, Failed to decrypt part: %s\n,
 (err ? err-message : no error explanation given));
@@ -182,6 +213,15 @@ _mime_node_create (const mime_node_t *parent, GMimeObject 
*part)
 (must be exactly 2)\n,
 node-nchildren);
} else {
+#ifdef GMIME_ATLEAST_26
+   node-sig_list = g_mime_multipart_signed_verify
+   (GMIME_MULTIPART_SIGNED (part), node-ctx-cryptoctx, err);
+   node-verify_attempted = TRUE;
+
+   if (!node-sig_list)
+   fprintf (stderr, Failed to verify signed part: %s\n,
+(err ? err-message : no error explanation given));
+#else
/* For some reason the GMimeSignatureValidity returned
 * here is not a const (inconsistent with that
 * returned by
@@ -200,12 +240,25 @@ _mime_node_create (const mime_node_t *parent, GMimeObject 
*part)
*proxy = sig_validity;
talloc_set_destructor (proxy, _signature_validity_free);
}
+#endif
}
 }
 
+#ifdef GMIME_ATLEAST_26
+/* sig_list may be created in both above cases, so we need to
+ * cleanly handle it here. */
+if (node-sig_list) {
+   GMimeSignatureList **proxy = talloc (node, GMimeSignatureList *);
+   *proxy = node-sig_list;
+   talloc_set_destructor (proxy, _signature_list_free);
+}
+#endif
+
+#ifndef GMIME_ATLEAST_26
 if (node-verify_attempted  !node-sig_validity)
 

[PATCH v4 3/3] Update NEWS and INSTALL about gmime 2.6

2012-01-20 Thread Thomas Jost
---
 INSTALL |   12 ++--
 NEWS|9 +
 2 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/INSTALL b/INSTALL
index e51b397..bc98f1d 100644
--- a/INSTALL
+++ b/INSTALL
@@ -20,8 +20,8 @@ configure stage.
 
 Dependencies
 
-Notmuch depends on three libraries: Xapian, GMime 2.4, and Talloc
-which are each described below:
+Notmuch depends on three libraries: Xapian, GMime 2.4 or 2.6, and
+Talloc which are each described below:
 
Xapian
--
@@ -39,14 +39,14 @@ which are each described below:
reading mail while notmuch would wait for Xapian when removing
the inbox and unread tags from messages in a thread.
 
-   GMime 2.4
-   -
-   GMime 2.4 provides decoding of MIME email messages for Notmuch.
+   GMime 2.4 or 2.6
+   
+   GMime provides decoding of MIME email messages for Notmuch.
 
Without GMime, Notmuch would not be able to extract and index
the actual text from email message encoded as BASE64, etc.
 
-   GMime 2.4 is available from http://spruce.sourceforge.net/gmime/
+   GMime is available from http://spruce.sourceforge.net/gmime/
 
Talloc
--
diff --git a/NEWS b/NEWS
index 6afa912..e78472c 100644
--- a/NEWS
+++ b/NEWS
@@ -36,6 +36,15 @@ New functions
   notmuch_query_add_tag_exclude supports the new tag exclusion
   feature.
 
+Build fixes
+---
+
+Compatibility with GMime 2.6
+
+  It is now possible to build notmuch against both GMime 2.4 and 2.6.
+  However they may be some issues in PGP signature verification
+  because of a bug in current versions of GMime 2.6.
+
 Notmuch 0.11 (2012-01-13)
 =
 
-- 
1.7.8.4

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH v4 1/3] show: don't use hex literals in JSON output

2012-01-20 Thread Thomas Jost
On Fri, 20 Jan 2012 07:55:03 -0400, David Bremner da...@tethera.net wrote:
 On Fri, 20 Jan 2012 10:39:23 +0100, Thomas Jost schno...@schnouki.net wrote:
  JSON does not support hex literals (0x..) so numbers must be formatted as %d
  instead of %x.
  ---
   notmuch-show.c |2 +-
   1 files changed, 1 insertions(+), 1 deletions(-)
  
 Probably I'm just being lazy here, but can you explain why this change
 does not require a corresponding change on the emacs side?

Because Emacs already does the right thing. JSON numbers are supposed to
be decimal only (see http://json.org/: digits are 0-9 only), but the
current code could result in displaying a hexadecimal number instead
(c instead of 12). This would then trigger an error in Emacs, or in
any other correct JSON parser.

However we are quite lucky: because of the possible values of the gmime
error codes, such an error cannot happen.

The most common gmime error codes are 1 (expired signature), 2 (no
public key), 4 (expired key) and 8 (revoked key). The other possible
value is 16 (unsupported algorithm) but obviously it is much more rare.
If this happens, the current code will add 'errors: 10' (hex for
16...). This is valid JSON (it looks like a decimal number) but it is
incorrect (should be 16, not 10).

With this patch, notmuch will correctly display 'errors: 16' if such a
case happens.

(By the way, this issue was spotted by Austin Clements in
id:20120117034714.gg16...@mit.edu, so he deserves the credits :))

Regards,

-- 
Thomas/Schnouki


pgpaN5CBNzUcv.pgp
Description: PGP signature
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH v2 2/2] Add pseudo-compatibility with gmime 2.6

2012-01-19 Thread Thomas Jost
Thanks for this review Austin. New version coming soon.

On Tue, 17 Jan 2012 17:25:46 -0500, Austin Clements amdra...@mit.edu wrote:
 Quoth Thomas Jost on Jan 17 at 11:50 am:
  There are lots of API changes in gmime 2.6 crypto handling. By adding
  preprocessor directives, it is however possible to add gmime 2.6 
  compatibility
  while preserving compatibility with gmime 2.4 too.
  
  This is mostly based on id:8762i8hrb9@bookbinder.fernseed.info.
  
  This was tested against both gmime 2.6.4 and 2.4.31. With gmime 2.4.31, the
  crypto tests all work fine (as expected). With gmime 2.6.4, one crypto test
  fails (signature verification with signer key unavailable) but this will be 
  hard
  to fix since the new API does not report the reason why a signature 
  verification
  fails (other than the human-readable error message).
  ---
   mime-node.c  |   56 ++--
   notmuch-client.h |   28 +++-
   notmuch-reply.c  |7 
   notmuch-show.c   |   95 
  ++
   show-message.c   |4 ++
   5 files changed, 185 insertions(+), 5 deletions(-)
  
  diff --git a/mime-node.c b/mime-node.c
  index d26bb44..e575e1c 100644
  --- a/mime-node.c
  +++ b/mime-node.c
  @@ -33,7 +33,11 @@ typedef struct mime_node_context {
   GMimeMessage *mime_message;
   
   /* Context provided by the caller. */
  +#ifdef GMIME_26
  +GMimeCryptoContext *cryptoctx;
  +#else
   GMimeCipherContext *cryptoctx;
  +#endif
   notmuch_bool_t decrypt;
   } mime_node_context_t;
   
  @@ -57,8 +61,12 @@ _mime_node_context_free (mime_node_context_t *res)
   
   notmuch_status_t
   mime_node_open (const void *ctx, notmuch_message_t *message,
  -   GMimeCipherContext *cryptoctx, notmuch_bool_t decrypt,
  -   mime_node_t **root_out)
  +#ifdef GMIME_26
  +   GMimeCryptoContext *cryptoctx,
  +#else
  +   GMimeCipherContext *cryptoctx,
  +#endif
  +   notmuch_bool_t decrypt, mime_node_t **root_out)
   {
   const char *filename = notmuch_message_get_filename (message);
   mime_node_context_t *mctx;
  @@ -112,12 +120,21 @@ DONE:
   return status;
   }
   
  +#ifdef GMIME_26
  +static int
  +_signature_list_free (GMimeSignatureList **proxy)
  +{
  +g_object_unref (*proxy);
  +return 0;
  +}
  +#else
   static int
   _signature_validity_free (GMimeSignatureValidity **proxy)
   {
   g_mime_signature_validity_free (*proxy);
   return 0;
   }
  +#endif
   
   static mime_node_t *
   _mime_node_create (const mime_node_t *parent, GMimeObject *part)
  @@ -165,11 +182,22 @@ _mime_node_create (const mime_node_t *parent, 
  GMimeObject *part)
  GMimeMultipartEncrypted *encrypteddata =
  GMIME_MULTIPART_ENCRYPTED (part);
  node-decrypt_attempted = TRUE;
  +#ifdef GMIME_26
  +   GMimeDecryptResult *decrypt_result = NULL;
 
 Reading through the GMime code, it looks like we do have to unref
 decrypt_result.  I think this is easy, though.  Right after you call
 g_mime_decrypt_result_get_signatures below, do:
 
   g_object_ref (node-sig_list);
   g_object_unref (decrypt_result);

Added, thanks!

 
  +   node-decrypted_child = g_mime_multipart_encrypted_decrypt
  +   (encrypteddata, node-ctx-cryptoctx, decrypt_result, err);
  +#else
  node-decrypted_child = g_mime_multipart_encrypted_decrypt
  (encrypteddata, node-ctx-cryptoctx, err);
  +#endif
  if (node-decrypted_child) {
  -   node-decrypt_success = node-verify_attempted = TRUE;
  +   node-decrypt_success = node-verify_attempted =TRUE;
 
 Whitespace.  (There should be no diff on the above line)

Oops, my bad.

 
  +#ifdef GMIME_26
  +   /* This may be NULL if the part is not signed. */
  +   node-sig_list = g_mime_decrypt_result_get_signatures 
  (decrypt_result);
  +#else
  node-sig_validity = 
  g_mime_multipart_encrypted_get_signature_validity (encrypteddata);
  +#endif
  } else {
  fprintf (stderr, Failed to decrypt part: %s\n,
   (err ? err-message : no error explanation given));
  @@ -182,6 +210,16 @@ _mime_node_create (const mime_node_t *parent, 
  GMimeObject *part)
   (must be exactly 2)\n,
   node-nchildren);
  } else {
  +#ifdef GMIME_26
  +   GMimeSignatureList *sig_list = g_mime_multipart_signed_verify
  +   (GMIME_MULTIPART_SIGNED (part), node-ctx-cryptoctx, err);
  +   node-verify_attempted = TRUE;
  +   node-sig_list = sig_list;
 
 Just a nit.  This could be
   node-sig_list = g_mime_multipart_signed_verify ( ... )
 To me, the local variable just makes this code more verbose without
 adding anything.  Up to you.

Yep, the local variable is useless. Removed it.

 
  +
  +   if (!sig_list)
  +   fprintf (stderr, Failed to verify signed part: %s\n,
  +(err ? err-message : no error

Re: [PATCH v2 2/2] Add pseudo-compatibility with gmime 2.6

2012-01-19 Thread Thomas Jost
On Wed, 18 Jan 2012 20:00:12 +0200, Tomi Ollila tomi.oll...@iki.fi wrote:
 On Wed, 18 Jan 2012 12:19:45 -0500, Tom Prince tom.pri...@ualberta.net 
 wrote:
  
  How did you test against multiple versions? Using different machines? If
  there was a way for configure (or something to pick the version, I would
  setup the buildbot to test against both, so we don't regress either.
 
 I currently compile notmuch on Fedora 15 so that I have 
 
 LIBRARY_PATH=/my/own/path/to/x86_64-linux/lib
 and
 CPATH=/my/own/path/to/x86_64-linux/include
 
 and gmime 2.4 development files are located in these
 directories. I'll be hiding gmime 2.4 stuff from these
 soon in order to build against 2.6 stuff.
 
 Tomi

For testing gmime 2.4 and 2.6, I just uninstalled 2.6 and reinstalled
2.4 (kept the binary package on purpose -- not a problem since notmuch
is the only package using gmime on my system).

When hacking the gmime git in order to fix
https://bugzilla.gnome.org/show_bug.cgi?id=668085, I set some
environment variables before calling ./configure and building notmuch:

  LDFLAGS=-Wl,-rpath,/home/schnouki/dev/gmime/gmime/.libs ./configure 
--prefix=/usr --sysconfdir=/etc
  make
  ldd ./notmuch

Regards,

-- 
Thomas/Schnouki


pgpybiDupPPyc.pgp
Description: PGP signature
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH] Add pseudo-compatibility with gmime 2.6

2012-01-19 Thread Thomas Jost
On Tue, 17 Jan 2012 15:38:36 -0500, Austin Clements amdra...@mit.edu wrote:
 Quoth Thomas Jost on Jan 17 at 11:48 am:
  On Mon, 16 Jan 2012 22:47:14 -0500, Austin Clements amdra...@mit.edu 
  wrote:
   Quoth Thomas Jost on Jan 17 at 12:56 am:
This is mostly based on id:8762i8hrb9@bookbinder.fernseed.info.

This was tested against both gmime 2.6.4 and 2.4.31. With gmime 2.4.31, 
the
crypto tests all work fine (as expected). With gmime 2.6.4, one crypto 
test
fails (signature verification with signer key unavailable) but this 
will be hard
to fix since the new API does not report the reason why a signature 
verification
fails (other than the human-readable error message).
   
   What is the result of this failing test?
  
  The test looks like that:
  
  FAIL   signature verification with signer key unavailable
 --- crypto.4.expected   2012-01-16 23:05:06.765651183 +
 +++ crypto.4.output 2012-01-16 23:05:06.765651183 +
 @@ -12,9 +12,7 @@
   Bcc: ,
   Date: 01 Jan 2000 12:00:00 -},
   body: [{id: 1,
 - sigstatus: [{status: error,
 - keyid: 6D92612D94E46381,
 - errors: 2}],
 + sigstatus: [],
   content-type: multipart/signed,
   content: [{id: 2,
   content-type: text/plain,
 Failed to verify signed part: gpg: keyblock resource 
  `/home/schnouki/dev/notmuch/test/tmp.crypto/gnupg/pubring.gpg': file open 
  error
 gpg: armor header: Version: GnuPG v1.4.11 (GNU/Linux)
 gpg: Signature made Mon Jan 16 23:05:06 2012 UTC using RSA key ID 
  94E46381
 gpg: Can't check signature: public key not found
  
  So basically if a signer public key is missing, we can't get the status
  signature: empty sigstatus field in the JSON output, Unknown
  signature status in Emacs.
  
  IMHO this is a bug in gmime 2.6, and I think I know what causes it. I'll
  file a bug in gmime and hopefully they'll find a cleaner way to fix it
  than the one I came up with :)
 
 Oh, okay.  That does seem like a bug in GMime.  Do you think it would
 be possible to mark this test as broken if notmuch is using GMime
 2.6?  Off the top of my head, I can't think of an easy way to plumb
 that information through to the test suite.  I don't think we should
 push any patches that knowingly break a test, even if it's in just one
 configuration.

Here is how I did:

  (ldd notmuch | grep -q gmime-2.6)  test_subtest_known_broken

ldd notmuch will show /path/to/libgmime-2.4.so.* or
libgmime-2.6.so.* so we can easily check this in the test suite.
It's a little hacky but it seems to work. AFAIK ldd is a pretty standard
tool so it should be available (almost) everywhere. However if you have
a better idea I'll be glad to hear it.

+#ifdef GMIME_26
+if (node-verify_attempted  !node-sig_list)
   
   Hmm.  This is correct for signed parts, but will incorrectly trigger
   for an encrypted part with no signatures.  For 2.6, I think this error
   checking may have to move into the branches of the if encrypted/signed
   since for encrypted parts you have to check if
   g_mime_multipart_encrypted_decrypt returned NULL.
  
  That sound right. The weird part is that it did not cause anything to
  fail in the test suite...
 
 It would be worth adding a test with an encrypted but unsigned part.
 I don't know enough GPG myself to do that.

It looks like there's already one: emacs delivery of encrypted message
with attachment + following decryptions.

Regards,

-- 
Thomas/Schnouki


pgpSQQuGYQQ6s.pgp
Description: PGP signature
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH v3 0/2] gmime 2.6 compatibilty, 3rd iteration

2012-01-19 Thread Thomas Jost
Hi list,

Here's another update of the patches to add gmime 2.6 compatibilty
while still preserving compatibility with gmime 2.4.

Any comments or review will be much appreciated.

The changes compared to the previous version ([1] and [2]) are pretty
minor:
- space and indentation fixes
- correctly dereference the instance of GMimeDecryptResult allocated
  by g_mime_decrypt_result_get_signatures()
- remove a useless local variable
- rename the preprocessor constant GMIME_26 to GMIME_ATLEAST_26
- mark one crypto test as broken when using gmime 2.6 (because of a
  bug in gmime [3])

The first patch is really not specific to gmime so it could probably
be pushed right away.

Thanks to Austin Clements, Tomi Ollila and Adrian Perez for their
reviews of the previous patches!

Best regards,
Thomas

[1] id:1326797453-9405-1-git-send-email-schno...@schnouki.net
[2] id:1326797453-9405-2-git-send-email-schno...@schnouki.net
[3] https://bugzilla.gnome.org/show_bug.cgi?id=668085

Thomas Jost (2):
  show: don't use hex literals in JSON output
  Add compatibility with gmime 2.6

 mime-node.c  |   60 +++--
 notmuch-client.h |   30 +++-
 notmuch-reply.c  |7 
 notmuch-show.c   |   97 +-
 show-message.c   |4 ++
 test/crypto  |2 +
 6 files changed, 193 insertions(+), 7 deletions(-)

-- 
1.7.8.4

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH v3 1/2] show: don't use hex literals in JSON output

2012-01-19 Thread Thomas Jost
JSON does not support hex literals (0x..) so numbers must be formatted as %d
instead of %x.
---
 notmuch-show.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/notmuch-show.c b/notmuch-show.c
index d14dac9..91f566c 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -641,7 +641,7 @@ format_part_sigstatus_json (const GMimeSignatureValidity* 
validity)
printf (, \keyid\: %s, json_quote_str (ctx_quote, 
signer-keyid));
}
if (signer-errors != GMIME_SIGNER_ERROR_NONE) {
-   printf (, \errors\: %x, signer-errors);
+   printf (, \errors\: %d, signer-errors);
}
 
printf (});
-- 
1.7.8.4

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH v3 2/2] Add compatibility with gmime 2.6

2012-01-19 Thread Thomas Jost
There are lots of API changes in gmime 2.6 crypto handling. By adding
preprocessor directives, it is however possible to add gmime 2.6 compatibility
while preserving compatibility with gmime 2.4 too.

This is mostly based on id:8762i8hrb9@bookbinder.fernseed.info.

This was tested against both gmime 2.6.4 and 2.4.31. With gmime 2.4.31, the
crypto tests all work fine (as expected). With gmime 2.6.4, one crypto test is
currently broken (signature verification with signer key unavailable), most
likely because of a bug in gmime which will hopefully be fixed in a future
version.
---
 mime-node.c  |   60 --
 notmuch-client.h |   30 -
 notmuch-reply.c  |7 
 notmuch-show.c   |   95 ++
 show-message.c   |4 ++
 test/crypto  |2 +
 6 files changed, 192 insertions(+), 6 deletions(-)

diff --git a/mime-node.c b/mime-node.c
index d26bb44..ad19f5e 100644
--- a/mime-node.c
+++ b/mime-node.c
@@ -33,7 +33,11 @@ typedef struct mime_node_context {
 GMimeMessage *mime_message;
 
 /* Context provided by the caller. */
+#ifdef GMIME_ATLEAST_26
+GMimeCryptoContext *cryptoctx;
+#else
 GMimeCipherContext *cryptoctx;
+#endif
 notmuch_bool_t decrypt;
 } mime_node_context_t;
 
@@ -57,8 +61,12 @@ _mime_node_context_free (mime_node_context_t *res)
 
 notmuch_status_t
 mime_node_open (const void *ctx, notmuch_message_t *message,
-   GMimeCipherContext *cryptoctx, notmuch_bool_t decrypt,
-   mime_node_t **root_out)
+#ifdef GMIME_ATLEAST_26
+   GMimeCryptoContext *cryptoctx,
+#else
+   GMimeCipherContext *cryptoctx,
+#endif
+   notmuch_bool_t decrypt, mime_node_t **root_out)
 {
 const char *filename = notmuch_message_get_filename (message);
 mime_node_context_t *mctx;
@@ -112,12 +120,21 @@ DONE:
 return status;
 }
 
+#ifdef GMIME_ATLEAST_26
+static int
+_signature_list_free (GMimeSignatureList **proxy)
+{
+g_object_unref (*proxy);
+return 0;
+}
+#else
 static int
 _signature_validity_free (GMimeSignatureValidity **proxy)
 {
 g_mime_signature_validity_free (*proxy);
 return 0;
 }
+#endif
 
 static mime_node_t *
 _mime_node_create (const mime_node_t *parent, GMimeObject *part)
@@ -165,11 +182,24 @@ _mime_node_create (const mime_node_t *parent, GMimeObject 
*part)
GMimeMultipartEncrypted *encrypteddata =
GMIME_MULTIPART_ENCRYPTED (part);
node-decrypt_attempted = TRUE;
+#ifdef GMIME_ATLEAST_26
+   GMimeDecryptResult *decrypt_result = NULL;
+   node-decrypted_child = g_mime_multipart_encrypted_decrypt
+   (encrypteddata, node-ctx-cryptoctx, decrypt_result, err);
+#else
node-decrypted_child = g_mime_multipart_encrypted_decrypt
(encrypteddata, node-ctx-cryptoctx, err);
+#endif
if (node-decrypted_child) {
node-decrypt_success = node-verify_attempted = TRUE;
+#ifdef GMIME_ATLEAST_26
+   /* This may be NULL if the part is not signed. */
+   node-sig_list = g_mime_decrypt_result_get_signatures 
(decrypt_result);
+   g_object_ref (node-sig_list);
+   g_object_unref (decrypt_result);
+#else
node-sig_validity = 
g_mime_multipart_encrypted_get_signature_validity (encrypteddata);
+#endif
} else {
fprintf (stderr, Failed to decrypt part: %s\n,
 (err ? err-message : no error explanation given));
@@ -182,6 +212,15 @@ _mime_node_create (const mime_node_t *parent, GMimeObject 
*part)
 (must be exactly 2)\n,
 node-nchildren);
} else {
+#ifdef GMIME_ATLEAST_26
+   node-sig_list = g_mime_multipart_signed_verify
+   (GMIME_MULTIPART_SIGNED (part), node-ctx-cryptoctx, err);
+   node-verify_attempted = TRUE;
+
+   if (!node-sig_list)
+   fprintf (stderr, Failed to verify signed part: %s\n,
+(err ? err-message : no error explanation given));
+#else
/* For some reason the GMimeSignatureValidity returned
 * here is not a const (inconsistent with that
 * returned by
@@ -195,17 +234,30 @@ _mime_node_create (const mime_node_t *parent, GMimeObject 
*part)
node-verify_attempted = TRUE;
node-sig_validity = sig_validity;
if (sig_validity) {
-   GMimeSignatureValidity **proxy =
-   talloc (node, GMimeSignatureValidity *);
+   GMimeSignatureValidity **proxy = talloc (node, 
GMimeSignatureValidity *);
*proxy = sig_validity;
talloc_set_destructor (proxy, _signature_validity_free);
}
+#endif
}
 }
 
+#ifdef GMIME_ATLEAST_26
+/* sig_list may be created in both above cases, so we need to
+ * cleanly handle it here. */
+if 

[PATCH v2 2/2] Add pseudo-compatibility with gmime 2.6

2012-01-17 Thread Thomas Jost
On Tue, 17 Jan 2012 14:48:34 +0200, Tomi Ollila  wrote:
> On Tue, 17 Jan 2012 11:50:53 +0100, Thomas Jost  
> wrote:
> > There are lots of API changes in gmime 2.6 crypto handling. By adding
> > preprocessor directives, it is however possible to add gmime 2.6 
> > compatibility
> > while preserving compatibility with gmime 2.4 too.
> > 
> > This is mostly based on id:"8762i8hrb9.fsf at bookbinder.fernseed.info".
> > 
> > This was tested against both gmime 2.6.4 and 2.4.31. With gmime 2.4.31, the
> > crypto tests all work fine (as expected). With gmime 2.6.4, one crypto test
> > fails (signature verification with signer key unavailable) but this will be 
> > hard
> > to fix since the new API does not report the reason why a signature 
> > verification
> > fails (other than the human-readable error message).
> > ---
> 
> LGTM. Some whitespace things but most of those were there already;
> I'd have one uncrustify round to be applied to the source and after
> that be more strict about those...

Thanks! I'll fix the whitespace issues in these patches when the source
in Git is uncrustified then.

> actually gmime 2.4 has GMIME_CHECK_VERSION defined as
> g_mime_check_version (major, minor, micro) so the comment about it
> is not entirely accurate (it is unusable in our context, though)

Oops, yes. What I really meant is that GMIME_MAJOR_VERSION is not
available as a preprocessor constant in 2.4, and GMIME_CHECK_VERSION is
unusable in our context since it just calls a runtime function.

By the way, how do you guys feel about setting GMIME_26 in
notmuch-client.h? Is that good enough, or should it be done in configure
so that gcc is called with "-DGMIME_26"?

I filed a bug about gmime 2.6 incorrect handling of signatures with
missing public keys: https://bugzilla.gnome.org/show_bug.cgi?id=668085.
A patch is attached there, feel free to test and comment.

(Arch Linux users: I made a little PKGBUILD that includes this patch if
you want to build your own gmime 2.6.4:
http://fichiers.schnouki.net/tmp/gmime-2.6.4-1.src.tar.gz)

Best regards,

-- 
Thomas/Schnouki
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 489 bytes
Desc: not available
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20120117/e5f7d377/attachment-0001.pgp>


[PATCH v2 2/2] Add pseudo-compatibility with gmime 2.6

2012-01-17 Thread Thomas Jost
There are lots of API changes in gmime 2.6 crypto handling. By adding
preprocessor directives, it is however possible to add gmime 2.6 compatibility
while preserving compatibility with gmime 2.4 too.

This is mostly based on id:"8762i8hrb9.fsf at bookbinder.fernseed.info".

This was tested against both gmime 2.6.4 and 2.4.31. With gmime 2.4.31, the
crypto tests all work fine (as expected). With gmime 2.6.4, one crypto test
fails (signature verification with signer key unavailable) but this will be hard
to fix since the new API does not report the reason why a signature verification
fails (other than the human-readable error message).
---
 mime-node.c  |   56 ++--
 notmuch-client.h |   28 +++-
 notmuch-reply.c  |7 
 notmuch-show.c   |   95 ++
 show-message.c   |4 ++
 5 files changed, 185 insertions(+), 5 deletions(-)

diff --git a/mime-node.c b/mime-node.c
index d26bb44..e575e1c 100644
--- a/mime-node.c
+++ b/mime-node.c
@@ -33,7 +33,11 @@ typedef struct mime_node_context {
 GMimeMessage *mime_message;

 /* Context provided by the caller. */
+#ifdef GMIME_26
+GMimeCryptoContext *cryptoctx;
+#else
 GMimeCipherContext *cryptoctx;
+#endif
 notmuch_bool_t decrypt;
 } mime_node_context_t;

@@ -57,8 +61,12 @@ _mime_node_context_free (mime_node_context_t *res)

 notmuch_status_t
 mime_node_open (const void *ctx, notmuch_message_t *message,
-   GMimeCipherContext *cryptoctx, notmuch_bool_t decrypt,
-   mime_node_t **root_out)
+#ifdef GMIME_26
+   GMimeCryptoContext *cryptoctx,
+#else
+   GMimeCipherContext *cryptoctx,
+#endif
+   notmuch_bool_t decrypt, mime_node_t **root_out)
 {
 const char *filename = notmuch_message_get_filename (message);
 mime_node_context_t *mctx;
@@ -112,12 +120,21 @@ DONE:
 return status;
 }

+#ifdef GMIME_26
+static int
+_signature_list_free (GMimeSignatureList **proxy)
+{
+g_object_unref (*proxy);
+return 0;
+}
+#else
 static int
 _signature_validity_free (GMimeSignatureValidity **proxy)
 {
 g_mime_signature_validity_free (*proxy);
 return 0;
 }
+#endif

 static mime_node_t *
 _mime_node_create (const mime_node_t *parent, GMimeObject *part)
@@ -165,11 +182,22 @@ _mime_node_create (const mime_node_t *parent, GMimeObject 
*part)
GMimeMultipartEncrypted *encrypteddata =
GMIME_MULTIPART_ENCRYPTED (part);
node->decrypt_attempted = TRUE;
+#ifdef GMIME_26
+   GMimeDecryptResult *decrypt_result = NULL;
+   node->decrypted_child = g_mime_multipart_encrypted_decrypt
+   (encrypteddata, node->ctx->cryptoctx, _result, );
+#else
node->decrypted_child = g_mime_multipart_encrypted_decrypt
(encrypteddata, node->ctx->cryptoctx, );
+#endif
if (node->decrypted_child) {
-   node->decrypt_success = node->verify_attempted = TRUE;
+   node->decrypt_success = node->verify_attempted =TRUE;
+#ifdef GMIME_26
+   /* This may be NULL if the part is not signed. */
+   node->sig_list = g_mime_decrypt_result_get_signatures 
(decrypt_result);
+#else
node->sig_validity = 
g_mime_multipart_encrypted_get_signature_validity (encrypteddata);
+#endif
} else {
fprintf (stderr, "Failed to decrypt part: %s\n",
 (err ? err->message : "no error explanation given"));
@@ -182,6 +210,16 @@ _mime_node_create (const mime_node_t *parent, GMimeObject 
*part)
 "(must be exactly 2)\n",
 node->nchildren);
} else {
+#ifdef GMIME_26
+   GMimeSignatureList *sig_list = g_mime_multipart_signed_verify
+   (GMIME_MULTIPART_SIGNED (part), node->ctx->cryptoctx, );
+   node->verify_attempted = TRUE;
+   node->sig_list = sig_list;
+
+   if (!sig_list)
+   fprintf (stderr, "Failed to verify signed part: %s\n",
+(err ? err->message : "no error explanation given"));
+#else
/* For some reason the GMimeSignatureValidity returned
 * here is not a const (inconsistent with that
 * returned by
@@ -200,12 +238,24 @@ _mime_node_create (const mime_node_t *parent, GMimeObject 
*part)
*proxy = sig_validity;
talloc_set_destructor (proxy, _signature_validity_free);
}
+#endif
}
 }

+#ifdef GMIME_26
+/* sig_list may be created in both above cases, so we need to
+ * cleanly handle it here. */
+if (node->sig_list) {
+   GMimeSignatureList **proxy =
+   talloc (node, GMimeSignatureList *);
+   *proxy = node->sig_list;
+   talloc_set_destructor (proxy, _signature_list_free);
+}
+#else
 if (node->verify_attempted && !node->sig_validity)
fprintf (stderr, "Failed to verify signed 

[PATCH v2 1/2] show: don't use hex literals in JSON output

2012-01-17 Thread Thomas Jost
JSON does not support hex literals (0x..) so numbers must be formatted as %d
instead of %x.
---
 notmuch-show.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/notmuch-show.c b/notmuch-show.c
index d14dac9..91f566c 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -641,7 +641,7 @@ format_part_sigstatus_json (const GMimeSignatureValidity* 
validity)
printf (", \"keyid\": %s", json_quote_str (ctx_quote, 
signer->keyid));
}
if (signer->errors != GMIME_SIGNER_ERROR_NONE) {
-   printf (", \"errors\": %x", signer->errors);
+   printf (", \"errors\": %d", signer->errors);
}

printf ("}");
-- 
1.7.8.3



[PATCH] Add pseudo-compatibility with gmime 2.6

2012-01-17 Thread Thomas Jost
On Mon, 16 Jan 2012 22:47:14 -0500, Austin Clements  wrote:
> Quoth Thomas Jost on Jan 17 at 12:56 am:
> > There are lots of API changes in gmime 2.6 crypto handling. By adding
> > preprocessor directives, it is however possible to add gmime 2.6 
> > compatibility
> > while preserving compatibility with gmime 2.4 too.
> 
> Awesome.  Comments inline below.

Thanks for reviewing this so quickly. Replies inline, and new patches
incoming soon.


> > This is mostly based on id:"8762i8hrb9.fsf at bookbinder.fernseed.info".
> > 
> > This was tested against both gmime 2.6.4 and 2.4.31. With gmime 2.4.31, the
> > crypto tests all work fine (as expected). With gmime 2.6.4, one crypto test
> > fails (signature verification with signer key unavailable) but this will be 
> > hard
> > to fix since the new API does not report the reason why a signature 
> > verification
> > fails (other than the human-readable error message).
> 
> What is the result of this failing test?

The test looks like that:

FAIL   signature verification with signer key unavailable
   --- crypto.4.expected   2012-01-16 23:05:06.765651183 +
   +++ crypto.4.output 2012-01-16 23:05:06.765651183 +
   @@ -12,9 +12,7 @@
 "Bcc": "",
 "Date": "01 Jan 2000 12:00:00 -"},
 "body": [{"id": 1,
   - "sigstatus": [{"status": "error",
   - "keyid": "6D92612D94E46381",
   - "errors": 2}],
   + "sigstatus": [],
 "content-type": "multipart/signed",
 "content": [{"id": 2,
 "content-type": "text/plain",
   Failed to verify signed part: gpg: keyblock resource 
`/home/schnouki/dev/notmuch/test/tmp.crypto/gnupg/pubring.gpg': file open error
   gpg: armor header: Version: GnuPG v1.4.11 (GNU/Linux)
   gpg: Signature made Mon Jan 16 23:05:06 2012 UTC using RSA key ID 
94E46381
   gpg: Can't check signature: public key not found

So basically if a signer public key is missing, we can't get the status
signature: empty "sigstatus" field in the JSON output, "Unknown
signature status" in Emacs.

IMHO this is a bug in gmime 2.6, and I think I know what causes it. I'll
file a bug in gmime and hopefully they'll find a cleaner way to fix it
than the one I came up with :)

> 
> > ---
> >  mime-node.c  |   50 ++-
> >  notmuch-client.h |   27 ++-
> >  notmuch-reply.c  |7 
> >  notmuch-show.c   |   97 
> > ++
> >  show-message.c   |4 ++
> >  5 files changed, 181 insertions(+), 4 deletions(-)
> > 
> > diff --git a/mime-node.c b/mime-node.c
> > index d26bb44..ae2473d 100644
> > --- a/mime-node.c
> > +++ b/mime-node.c
> > @@ -33,7 +33,11 @@ typedef struct mime_node_context {
> >  GMimeMessage *mime_message;
> >  
> >  /* Context provided by the caller. */
> > +#ifdef GMIME_26
> > +GMimeCryptoContext *cryptoctx;
> > +#else
> >  GMimeCipherContext *cryptoctx;
> > +#endif
> >  notmuch_bool_t decrypt;
> >  } mime_node_context_t;
> >  
> > @@ -57,8 +61,12 @@ _mime_node_context_free (mime_node_context_t *res)
> >  
> >  notmuch_status_t
> >  mime_node_open (const void *ctx, notmuch_message_t *message,
> > -   GMimeCipherContext *cryptoctx, notmuch_bool_t decrypt,
> > -   mime_node_t **root_out)
> > +#ifdef GMIME_26
> > +   GMimeCryptoContext *cryptoctx,
> > +#else
> > +   GMimeCipherContext *cryptoctx,
> > +#endif
> > +   notmuch_bool_t decrypt, mime_node_t **root_out)
> >  {
> >  const char *filename = notmuch_message_get_filename (message);
> >  mime_node_context_t *mctx;
> > @@ -112,12 +120,21 @@ DONE:
> >  return status;
> >  }
> >  
> > +#ifdef GMIME_26
> > +static int
> > +_signature_list_free (GMimeSignatureList **proxy)
> > +{
> > +g_object_unref (*proxy);
> > +return 0;
> > +}
> > +#else
> >  static int
> >  _signature_validity_free (GMimeSignatureValidity **proxy)
> >  {
> >  g_mime_signature_validity_free (*proxy);
> >  return 0;
> >  }
> > +#endif
> >  
> >  static mime_node_t *
> >  _mime_node_create (const mime_node_t *parent, GMimeObject *part)
> > @@ -165,11 +182,23 @@ _mime_node_create (const mime_node_t *parent, 
> > GMimeObject *part)

[PATCH] Add pseudo-compatibility with gmime 2.6

2012-01-17 Thread Thomas Jost
There are lots of API changes in gmime 2.6 crypto handling. By adding
preprocessor directives, it is however possible to add gmime 2.6 compatibility
while preserving compatibility with gmime 2.4 too.

This is mostly based on id:"8762i8hrb9.fsf at bookbinder.fernseed.info".

This was tested against both gmime 2.6.4 and 2.4.31. With gmime 2.4.31, the
crypto tests all work fine (as expected). With gmime 2.6.4, one crypto test
fails (signature verification with signer key unavailable) but this will be hard
to fix since the new API does not report the reason why a signature verification
fails (other than the human-readable error message).
---
 mime-node.c  |   50 ++-
 notmuch-client.h |   27 ++-
 notmuch-reply.c  |7 
 notmuch-show.c   |   97 ++
 show-message.c   |4 ++
 5 files changed, 181 insertions(+), 4 deletions(-)

diff --git a/mime-node.c b/mime-node.c
index d26bb44..ae2473d 100644
--- a/mime-node.c
+++ b/mime-node.c
@@ -33,7 +33,11 @@ typedef struct mime_node_context {
 GMimeMessage *mime_message;

 /* Context provided by the caller. */
+#ifdef GMIME_26
+GMimeCryptoContext *cryptoctx;
+#else
 GMimeCipherContext *cryptoctx;
+#endif
 notmuch_bool_t decrypt;
 } mime_node_context_t;

@@ -57,8 +61,12 @@ _mime_node_context_free (mime_node_context_t *res)

 notmuch_status_t
 mime_node_open (const void *ctx, notmuch_message_t *message,
-   GMimeCipherContext *cryptoctx, notmuch_bool_t decrypt,
-   mime_node_t **root_out)
+#ifdef GMIME_26
+   GMimeCryptoContext *cryptoctx,
+#else
+   GMimeCipherContext *cryptoctx,
+#endif
+   notmuch_bool_t decrypt, mime_node_t **root_out)
 {
 const char *filename = notmuch_message_get_filename (message);
 mime_node_context_t *mctx;
@@ -112,12 +120,21 @@ DONE:
 return status;
 }

+#ifdef GMIME_26
+static int
+_signature_list_free (GMimeSignatureList **proxy)
+{
+g_object_unref (*proxy);
+return 0;
+}
+#else
 static int
 _signature_validity_free (GMimeSignatureValidity **proxy)
 {
 g_mime_signature_validity_free (*proxy);
 return 0;
 }
+#endif

 static mime_node_t *
 _mime_node_create (const mime_node_t *parent, GMimeObject *part)
@@ -165,11 +182,23 @@ _mime_node_create (const mime_node_t *parent, GMimeObject 
*part)
GMimeMultipartEncrypted *encrypteddata =
GMIME_MULTIPART_ENCRYPTED (part);
node->decrypt_attempted = TRUE;
+#ifdef GMIME_26
+   GMimeDecryptResult *decrypt_result = g_mime_decrypt_result_new ();
+   node->decrypted_child = g_mime_multipart_encrypted_decrypt
+   (encrypteddata, node->ctx->cryptoctx, _result, );
+   if (node->decrypted_child) {
+   node->decrypt_success = node->verify_attempted = TRUE;
+   node->sig_list = g_mime_decrypt_result_get_signatures 
(decrypt_result);
+   if (!node->sig_list)
+   fprintf (stderr, "Failed to get signatures: %s\n",
+(err ? err->message : "no error explanation 
given"));
+#else
node->decrypted_child = g_mime_multipart_encrypted_decrypt
(encrypteddata, node->ctx->cryptoctx, );
if (node->decrypted_child) {
node->decrypt_success = node->verify_attempted = TRUE;
node->sig_validity = 
g_mime_multipart_encrypted_get_signature_validity (encrypteddata);
+#endif
} else {
fprintf (stderr, "Failed to decrypt part: %s\n",
 (err ? err->message : "no error explanation given"));
@@ -182,6 +211,18 @@ _mime_node_create (const mime_node_t *parent, GMimeObject 
*part)
 "(must be exactly 2)\n",
 node->nchildren);
} else {
+#ifdef GMIME_26
+   GMimeSignatureList *sig_list = g_mime_multipart_signed_verify
+   (GMIME_MULTIPART_SIGNED (part), node->ctx->cryptoctx, );
+   node->verify_attempted = TRUE;
+   node->sig_list = sig_list;
+   if (sig_list) {
+   GMimeSignatureList **proxy =
+   talloc (node, GMimeSignatureList *);
+   *proxy = sig_list;
+   talloc_set_destructor (proxy, _signature_list_free);
+   }
+#else
/* For some reason the GMimeSignatureValidity returned
 * here is not a const (inconsistent with that
 * returned by
@@ -200,10 +241,15 @@ _mime_node_create (const mime_node_t *parent, GMimeObject 
*part)
*proxy = sig_validity;
talloc_set_destructor (proxy, _signature_validity_free);
}
+#endif
}
 }

+#ifdef GMIME_26
+if (node->verify_attempted && !node->sig_list)
+#else
 if (node->verify_attempted && !node->sig_validity)
+#endif
fprintf (stderr, "Failed to verify signed part: %s\n",
 (err 

Re: [PATCH] Add pseudo-compatibility with gmime 2.6

2012-01-17 Thread Thomas Jost
On Mon, 16 Jan 2012 22:47:14 -0500, Austin Clements amdra...@mit.edu wrote:
 Quoth Thomas Jost on Jan 17 at 12:56 am:
  There are lots of API changes in gmime 2.6 crypto handling. By adding
  preprocessor directives, it is however possible to add gmime 2.6 
  compatibility
  while preserving compatibility with gmime 2.4 too.
 
 Awesome.  Comments inline below.

Thanks for reviewing this so quickly. Replies inline, and new patches
incoming soon.


  This is mostly based on id:8762i8hrb9@bookbinder.fernseed.info.
  
  This was tested against both gmime 2.6.4 and 2.4.31. With gmime 2.4.31, the
  crypto tests all work fine (as expected). With gmime 2.6.4, one crypto test
  fails (signature verification with signer key unavailable) but this will be 
  hard
  to fix since the new API does not report the reason why a signature 
  verification
  fails (other than the human-readable error message).
 
 What is the result of this failing test?

The test looks like that:

FAIL   signature verification with signer key unavailable
   --- crypto.4.expected   2012-01-16 23:05:06.765651183 +
   +++ crypto.4.output 2012-01-16 23:05:06.765651183 +
   @@ -12,9 +12,7 @@
 Bcc: ,
 Date: 01 Jan 2000 12:00:00 -},
 body: [{id: 1,
   - sigstatus: [{status: error,
   - keyid: 6D92612D94E46381,
   - errors: 2}],
   + sigstatus: [],
 content-type: multipart/signed,
 content: [{id: 2,
 content-type: text/plain,
   Failed to verify signed part: gpg: keyblock resource 
`/home/schnouki/dev/notmuch/test/tmp.crypto/gnupg/pubring.gpg': file open error
   gpg: armor header: Version: GnuPG v1.4.11 (GNU/Linux)
   gpg: Signature made Mon Jan 16 23:05:06 2012 UTC using RSA key ID 
94E46381
   gpg: Can't check signature: public key not found

So basically if a signer public key is missing, we can't get the status
signature: empty sigstatus field in the JSON output, Unknown
signature status in Emacs.

IMHO this is a bug in gmime 2.6, and I think I know what causes it. I'll
file a bug in gmime and hopefully they'll find a cleaner way to fix it
than the one I came up with :)

 
  ---
   mime-node.c  |   50 ++-
   notmuch-client.h |   27 ++-
   notmuch-reply.c  |7 
   notmuch-show.c   |   97 
  ++
   show-message.c   |4 ++
   5 files changed, 181 insertions(+), 4 deletions(-)
  
  diff --git a/mime-node.c b/mime-node.c
  index d26bb44..ae2473d 100644
  --- a/mime-node.c
  +++ b/mime-node.c
  @@ -33,7 +33,11 @@ typedef struct mime_node_context {
   GMimeMessage *mime_message;
   
   /* Context provided by the caller. */
  +#ifdef GMIME_26
  +GMimeCryptoContext *cryptoctx;
  +#else
   GMimeCipherContext *cryptoctx;
  +#endif
   notmuch_bool_t decrypt;
   } mime_node_context_t;
   
  @@ -57,8 +61,12 @@ _mime_node_context_free (mime_node_context_t *res)
   
   notmuch_status_t
   mime_node_open (const void *ctx, notmuch_message_t *message,
  -   GMimeCipherContext *cryptoctx, notmuch_bool_t decrypt,
  -   mime_node_t **root_out)
  +#ifdef GMIME_26
  +   GMimeCryptoContext *cryptoctx,
  +#else
  +   GMimeCipherContext *cryptoctx,
  +#endif
  +   notmuch_bool_t decrypt, mime_node_t **root_out)
   {
   const char *filename = notmuch_message_get_filename (message);
   mime_node_context_t *mctx;
  @@ -112,12 +120,21 @@ DONE:
   return status;
   }
   
  +#ifdef GMIME_26
  +static int
  +_signature_list_free (GMimeSignatureList **proxy)
  +{
  +g_object_unref (*proxy);
  +return 0;
  +}
  +#else
   static int
   _signature_validity_free (GMimeSignatureValidity **proxy)
   {
   g_mime_signature_validity_free (*proxy);
   return 0;
   }
  +#endif
   
   static mime_node_t *
   _mime_node_create (const mime_node_t *parent, GMimeObject *part)
  @@ -165,11 +182,23 @@ _mime_node_create (const mime_node_t *parent, 
  GMimeObject *part)
  GMimeMultipartEncrypted *encrypteddata =
  GMIME_MULTIPART_ENCRYPTED (part);
  node-decrypt_attempted = TRUE;
  +#ifdef GMIME_26
  +   GMimeDecryptResult *decrypt_result = g_mime_decrypt_result_new ();
 
 I think g_mime_multipart_encrypted_decrypt allocates the
 GMimeDecryptResult for you, so this will just leak memory.

You're right, fixed. Will it be freed along with node-decrypted_child,
or do we need to handle this ourself?

 
  +   node-decrypted_child = g_mime_multipart_encrypted_decrypt
  +   (encrypteddata, node-ctx-cryptoctx, decrypt_result, err);
  +   if (node-decrypted_child) {
  +   node-decrypt_success = node-verify_attempted = TRUE;
  +   node-sig_list = g_mime_decrypt_result_get_signatures 
  (decrypt_result);
  +   if (!node-sig_list)
  +   fprintf (stderr, Failed to get

[PATCH v2 2/2] Add pseudo-compatibility with gmime 2.6

2012-01-17 Thread Thomas Jost
There are lots of API changes in gmime 2.6 crypto handling. By adding
preprocessor directives, it is however possible to add gmime 2.6 compatibility
while preserving compatibility with gmime 2.4 too.

This is mostly based on id:8762i8hrb9@bookbinder.fernseed.info.

This was tested against both gmime 2.6.4 and 2.4.31. With gmime 2.4.31, the
crypto tests all work fine (as expected). With gmime 2.6.4, one crypto test
fails (signature verification with signer key unavailable) but this will be hard
to fix since the new API does not report the reason why a signature verification
fails (other than the human-readable error message).
---
 mime-node.c  |   56 ++--
 notmuch-client.h |   28 +++-
 notmuch-reply.c  |7 
 notmuch-show.c   |   95 ++
 show-message.c   |4 ++
 5 files changed, 185 insertions(+), 5 deletions(-)

diff --git a/mime-node.c b/mime-node.c
index d26bb44..e575e1c 100644
--- a/mime-node.c
+++ b/mime-node.c
@@ -33,7 +33,11 @@ typedef struct mime_node_context {
 GMimeMessage *mime_message;
 
 /* Context provided by the caller. */
+#ifdef GMIME_26
+GMimeCryptoContext *cryptoctx;
+#else
 GMimeCipherContext *cryptoctx;
+#endif
 notmuch_bool_t decrypt;
 } mime_node_context_t;
 
@@ -57,8 +61,12 @@ _mime_node_context_free (mime_node_context_t *res)
 
 notmuch_status_t
 mime_node_open (const void *ctx, notmuch_message_t *message,
-   GMimeCipherContext *cryptoctx, notmuch_bool_t decrypt,
-   mime_node_t **root_out)
+#ifdef GMIME_26
+   GMimeCryptoContext *cryptoctx,
+#else
+   GMimeCipherContext *cryptoctx,
+#endif
+   notmuch_bool_t decrypt, mime_node_t **root_out)
 {
 const char *filename = notmuch_message_get_filename (message);
 mime_node_context_t *mctx;
@@ -112,12 +120,21 @@ DONE:
 return status;
 }
 
+#ifdef GMIME_26
+static int
+_signature_list_free (GMimeSignatureList **proxy)
+{
+g_object_unref (*proxy);
+return 0;
+}
+#else
 static int
 _signature_validity_free (GMimeSignatureValidity **proxy)
 {
 g_mime_signature_validity_free (*proxy);
 return 0;
 }
+#endif
 
 static mime_node_t *
 _mime_node_create (const mime_node_t *parent, GMimeObject *part)
@@ -165,11 +182,22 @@ _mime_node_create (const mime_node_t *parent, GMimeObject 
*part)
GMimeMultipartEncrypted *encrypteddata =
GMIME_MULTIPART_ENCRYPTED (part);
node-decrypt_attempted = TRUE;
+#ifdef GMIME_26
+   GMimeDecryptResult *decrypt_result = NULL;
+   node-decrypted_child = g_mime_multipart_encrypted_decrypt
+   (encrypteddata, node-ctx-cryptoctx, decrypt_result, err);
+#else
node-decrypted_child = g_mime_multipart_encrypted_decrypt
(encrypteddata, node-ctx-cryptoctx, err);
+#endif
if (node-decrypted_child) {
-   node-decrypt_success = node-verify_attempted = TRUE;
+   node-decrypt_success = node-verify_attempted =TRUE;
+#ifdef GMIME_26
+   /* This may be NULL if the part is not signed. */
+   node-sig_list = g_mime_decrypt_result_get_signatures 
(decrypt_result);
+#else
node-sig_validity = 
g_mime_multipart_encrypted_get_signature_validity (encrypteddata);
+#endif
} else {
fprintf (stderr, Failed to decrypt part: %s\n,
 (err ? err-message : no error explanation given));
@@ -182,6 +210,16 @@ _mime_node_create (const mime_node_t *parent, GMimeObject 
*part)
 (must be exactly 2)\n,
 node-nchildren);
} else {
+#ifdef GMIME_26
+   GMimeSignatureList *sig_list = g_mime_multipart_signed_verify
+   (GMIME_MULTIPART_SIGNED (part), node-ctx-cryptoctx, err);
+   node-verify_attempted = TRUE;
+   node-sig_list = sig_list;
+
+   if (!sig_list)
+   fprintf (stderr, Failed to verify signed part: %s\n,
+(err ? err-message : no error explanation given));
+#else
/* For some reason the GMimeSignatureValidity returned
 * here is not a const (inconsistent with that
 * returned by
@@ -200,12 +238,24 @@ _mime_node_create (const mime_node_t *parent, GMimeObject 
*part)
*proxy = sig_validity;
talloc_set_destructor (proxy, _signature_validity_free);
}
+#endif
}
 }
 
+#ifdef GMIME_26
+/* sig_list may be created in both above cases, so we need to
+ * cleanly handle it here. */
+if (node-sig_list) {
+   GMimeSignatureList **proxy =
+   talloc (node, GMimeSignatureList *);
+   *proxy = node-sig_list;
+   talloc_set_destructor (proxy, _signature_list_free);
+}
+#else
 if (node-verify_attempted  !node-sig_validity)
fprintf (stderr, Failed to verify signed part: %s\n,
   

[PATCH v2 1/2] show: don't use hex literals in JSON output

2012-01-17 Thread Thomas Jost
JSON does not support hex literals (0x..) so numbers must be formatted as %d
instead of %x.
---
 notmuch-show.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/notmuch-show.c b/notmuch-show.c
index d14dac9..91f566c 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -641,7 +641,7 @@ format_part_sigstatus_json (const GMimeSignatureValidity* 
validity)
printf (, \keyid\: %s, json_quote_str (ctx_quote, 
signer-keyid));
}
if (signer-errors != GMIME_SIGNER_ERROR_NONE) {
-   printf (, \errors\: %x, signer-errors);
+   printf (, \errors\: %d, signer-errors);
}
 
printf (});
-- 
1.7.8.3

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH v2 2/2] Add pseudo-compatibility with gmime 2.6

2012-01-17 Thread Thomas Jost
On Tue, 17 Jan 2012 14:48:34 +0200, Tomi Ollila tomi.oll...@iki.fi wrote:
 On Tue, 17 Jan 2012 11:50:53 +0100, Thomas Jost schno...@schnouki.net wrote:
  There are lots of API changes in gmime 2.6 crypto handling. By adding
  preprocessor directives, it is however possible to add gmime 2.6 
  compatibility
  while preserving compatibility with gmime 2.4 too.
  
  This is mostly based on id:8762i8hrb9@bookbinder.fernseed.info.
  
  This was tested against both gmime 2.6.4 and 2.4.31. With gmime 2.4.31, the
  crypto tests all work fine (as expected). With gmime 2.6.4, one crypto test
  fails (signature verification with signer key unavailable) but this will be 
  hard
  to fix since the new API does not report the reason why a signature 
  verification
  fails (other than the human-readable error message).
  ---
 
 LGTM. Some whitespace things but most of those were there already;
 I'd have one uncrustify round to be applied to the source and after
 that be more strict about those...

Thanks! I'll fix the whitespace issues in these patches when the source
in Git is uncrustified then.

 actually gmime 2.4 has GMIME_CHECK_VERSION defined as
 g_mime_check_version (major, minor, micro) so the comment about it
 is not entirely accurate (it is unusable in our context, though)

Oops, yes. What I really meant is that GMIME_MAJOR_VERSION is not
available as a preprocessor constant in 2.4, and GMIME_CHECK_VERSION is
unusable in our context since it just calls a runtime function.

By the way, how do you guys feel about setting GMIME_26 in
notmuch-client.h? Is that good enough, or should it be done in configure
so that gcc is called with -DGMIME_26?

I filed a bug about gmime 2.6 incorrect handling of signatures with
missing public keys: https://bugzilla.gnome.org/show_bug.cgi?id=668085.
A patch is attached there, feel free to test and comment.

(Arch Linux users: I made a little PKGBUILD that includes this patch if
you want to build your own gmime 2.6.4:
http://fichiers.schnouki.net/tmp/gmime-2.6.4-1.src.tar.gz)

Best regards,

-- 
Thomas/Schnouki


pgp3y7I0N927m.pgp
Description: PGP signature
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH] Add pseudo-compatibility with gmime 2.6

2012-01-16 Thread Thomas Jost
There are lots of API changes in gmime 2.6 crypto handling. By adding
preprocessor directives, it is however possible to add gmime 2.6 compatibility
while preserving compatibility with gmime 2.4 too.

This is mostly based on id:8762i8hrb9@bookbinder.fernseed.info.

This was tested against both gmime 2.6.4 and 2.4.31. With gmime 2.4.31, the
crypto tests all work fine (as expected). With gmime 2.6.4, one crypto test
fails (signature verification with signer key unavailable) but this will be hard
to fix since the new API does not report the reason why a signature verification
fails (other than the human-readable error message).
---
 mime-node.c  |   50 ++-
 notmuch-client.h |   27 ++-
 notmuch-reply.c  |7 
 notmuch-show.c   |   97 ++
 show-message.c   |4 ++
 5 files changed, 181 insertions(+), 4 deletions(-)

diff --git a/mime-node.c b/mime-node.c
index d26bb44..ae2473d 100644
--- a/mime-node.c
+++ b/mime-node.c
@@ -33,7 +33,11 @@ typedef struct mime_node_context {
 GMimeMessage *mime_message;
 
 /* Context provided by the caller. */
+#ifdef GMIME_26
+GMimeCryptoContext *cryptoctx;
+#else
 GMimeCipherContext *cryptoctx;
+#endif
 notmuch_bool_t decrypt;
 } mime_node_context_t;
 
@@ -57,8 +61,12 @@ _mime_node_context_free (mime_node_context_t *res)
 
 notmuch_status_t
 mime_node_open (const void *ctx, notmuch_message_t *message,
-   GMimeCipherContext *cryptoctx, notmuch_bool_t decrypt,
-   mime_node_t **root_out)
+#ifdef GMIME_26
+   GMimeCryptoContext *cryptoctx,
+#else
+   GMimeCipherContext *cryptoctx,
+#endif
+   notmuch_bool_t decrypt, mime_node_t **root_out)
 {
 const char *filename = notmuch_message_get_filename (message);
 mime_node_context_t *mctx;
@@ -112,12 +120,21 @@ DONE:
 return status;
 }
 
+#ifdef GMIME_26
+static int
+_signature_list_free (GMimeSignatureList **proxy)
+{
+g_object_unref (*proxy);
+return 0;
+}
+#else
 static int
 _signature_validity_free (GMimeSignatureValidity **proxy)
 {
 g_mime_signature_validity_free (*proxy);
 return 0;
 }
+#endif
 
 static mime_node_t *
 _mime_node_create (const mime_node_t *parent, GMimeObject *part)
@@ -165,11 +182,23 @@ _mime_node_create (const mime_node_t *parent, GMimeObject 
*part)
GMimeMultipartEncrypted *encrypteddata =
GMIME_MULTIPART_ENCRYPTED (part);
node-decrypt_attempted = TRUE;
+#ifdef GMIME_26
+   GMimeDecryptResult *decrypt_result = g_mime_decrypt_result_new ();
+   node-decrypted_child = g_mime_multipart_encrypted_decrypt
+   (encrypteddata, node-ctx-cryptoctx, decrypt_result, err);
+   if (node-decrypted_child) {
+   node-decrypt_success = node-verify_attempted = TRUE;
+   node-sig_list = g_mime_decrypt_result_get_signatures 
(decrypt_result);
+   if (!node-sig_list)
+   fprintf (stderr, Failed to get signatures: %s\n,
+(err ? err-message : no error explanation 
given));
+#else
node-decrypted_child = g_mime_multipart_encrypted_decrypt
(encrypteddata, node-ctx-cryptoctx, err);
if (node-decrypted_child) {
node-decrypt_success = node-verify_attempted = TRUE;
node-sig_validity = 
g_mime_multipart_encrypted_get_signature_validity (encrypteddata);
+#endif
} else {
fprintf (stderr, Failed to decrypt part: %s\n,
 (err ? err-message : no error explanation given));
@@ -182,6 +211,18 @@ _mime_node_create (const mime_node_t *parent, GMimeObject 
*part)
 (must be exactly 2)\n,
 node-nchildren);
} else {
+#ifdef GMIME_26
+   GMimeSignatureList *sig_list = g_mime_multipart_signed_verify
+   (GMIME_MULTIPART_SIGNED (part), node-ctx-cryptoctx, err);
+   node-verify_attempted = TRUE;
+   node-sig_list = sig_list;
+   if (sig_list) {
+   GMimeSignatureList **proxy =
+   talloc (node, GMimeSignatureList *);
+   *proxy = sig_list;
+   talloc_set_destructor (proxy, _signature_list_free);
+   }
+#else
/* For some reason the GMimeSignatureValidity returned
 * here is not a const (inconsistent with that
 * returned by
@@ -200,10 +241,15 @@ _mime_node_create (const mime_node_t *parent, GMimeObject 
*part)
*proxy = sig_validity;
talloc_set_destructor (proxy, _signature_validity_free);
}
+#endif
}
 }
 
+#ifdef GMIME_26
+if (node-verify_attempted  !node-sig_list)
+#else
 if (node-verify_attempted  !node-sig_validity)
+#endif
fprintf (stderr, Failed to verify signed part: %s\n,
 (err ? err-message : no error 

Info about notmuch database

2012-01-08 Thread Thomas Jost
On Sun, 08 Jan 2012 13:59:30 +0100, Sebastian Spaeth  
wrote:
> On Thu, 05 Jan 2012 16:04:22 +0100, Thomas Jost  
> wrote:
> > There's a description of the DB "schema" in lib/database.cc in the
> > notmuch source code. But you may also consider just using libnotmuch
> > instead, if that's enough for what you want to do.
> > 
> > Also: why Xapian? I'm already using something similar I wrote with
> > Python, storing everything in a dictionary, using Pickle to save that to
> > disk: 162 lines of code and 45 kb of data are enough to store my
> > addressbook and have completion in Emacs...
> 
> Ohh, that sounds nice. Is that public somewhere?
> 
> Sebastian

https://github.com/Schnouki/dotfiles/blob/master/notmuch/addrbook.py

Maybe I should add more comments in it :)

Regards,

-- 
Thomas/Schnouki
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 489 bytes
Desc: not available
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20120108/4a45b952/attachment.pgp>


Re: Info about notmuch database

2012-01-08 Thread Thomas Jost
On Sun, 08 Jan 2012 13:59:30 +0100, Sebastian Spaeth sebast...@sspaeth.de 
wrote:
 On Thu, 05 Jan 2012 16:04:22 +0100, Thomas Jost schno...@schnouki.net wrote:
  There's a description of the DB schema in lib/database.cc in the
  notmuch source code. But you may also consider just using libnotmuch
  instead, if that's enough for what you want to do.
  
  Also: why Xapian? I'm already using something similar I wrote with
  Python, storing everything in a dictionary, using Pickle to save that to
  disk: 162 lines of code and 45 kb of data are enough to store my
  addressbook and have completion in Emacs...
 
 Ohh, that sounds nice. Is that public somewhere?
 
 Sebastian

https://github.com/Schnouki/dotfiles/blob/master/notmuch/addrbook.py

Maybe I should add more comments in it :)

Regards,

-- 
Thomas/Schnouki


pgpjufUuWWH1R.pgp
Description: PGP signature
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH v3 1/4] emacs: Let the user choose where to compose new mails

2012-01-06 Thread Thomas Jost
On Sun, 25 Dec 2011 23:54:41 -0500, Aaron Ecay  wrote:
> On Thu, 15 Dec 2011 19:50:36 -0400, David Bremner  
> wrote:
> > I think the problem is related to emacsclient.
> > 
> > With 'm' I have the following behaviour:
> > 
> > emacs -q --daemon
> > M-x notmuch (to load variable definitions)
> > M-x customize-variable notmuch-mua-compose-in
> > (select compose in new window, save for current session)
> > M-x notmuch
> > m   ;; new window is opened as it should be
> > C-c C-c ;; frame is closed.
> 
> I just tried, and I cannot reproduce this behavior.  IIUC, here is what
> happened to you: you set nm-mua-compose-in to 'new-window.  You began a
> new message, this opened a new window as expected.  Your emacs frame now
> has two windows in it.  You sent this message, which deleted the window
> showing it.  Your emacs frame was deleted as well, which made the other
> window, showing notmuch-hello (or some other notmuch buffer, from which
> you began writing the email message) disappear as well, unexpectedly.
> Is this a correct description of what happened?
> 
> Here?s the recipe I used for replicating:
> 
> emacs -q --daemon
> emacsclient -c
> C-x b *scratch*
> (add-to-list 'load-path "/path/to/notmuch/emacs/") C-j
> (load-library "notmuch") C-j
> C-x C-f /path/to/notmuch/emacs/notmuch-mua.el
> M-x eval-buffer (in order to pick up changes not in byte-compiled file)
> M-x customize-variable notmuch-mua-compose-in (set to 'new-window, save for 
> session)
> M-x notmuch
> m (new window is created in current frame, below the window showing 
> notmuch-hello)
> (type mail)
> C-c C-c (enter smtp settings, since emacs doesn?t know them)
> (new window disappears, the window with notmuch-hello fills whole frame)

I've used something like this (+setting message-send-mail-function,
sendmail-program, sendmail extra arguments, message-signature and
notmuch-fcc-dirs) and done the following tests:
- Emacs 23.3 vs Emacs 24.0.92 (23.3 from Arch [extra] repo, 24.0.92
  compiled from AUR emacs-pretest package)
- with and without --daemon
- setting message-kill-buffer-on-exit to nil and t

In every case, the new mail composition window opened correctly next to
the notmuch-hello window. Here is what I got after successfully sending
a test mail in every situation:

- when message-kill-buffer-on-exit is "t":
  * E23: mail buffer killed, window closed, frame still there (OK)
  * E23 daemon: same thing (OK)
  * E24: same thing (OK)
  * E24 daemon: same thing (OK)

- when message-kill-buffer-on-exit is "nil":
  * E23: mail buffer buried, window still there, frame still there
  * E23 daemon: frame was killed after sending. When restarting
emacsclient: buffer buried but still there
  * E24: mail buffer buried, window closed, frame still there (OK)
  * E24 daemon: same thing (OK)

So basically everything works as expected when mkboe is "t", and there
are issues with Emacs 23 when mkboe is "nil".

I'm very sorry for these issues, I should have done more testing with
mkboe set to "nil", and I don't think I tested Emacs 23 at all with the
latest versions of this patch. I'll try to fix that and post a new patch
in a few days.

Best regards,

-- 
Thomas/Schnouki
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 489 bytes
Desc: not available
URL: 



Info about notmuch database

2012-01-05 Thread Thomas Jost
On Thu, 5 Jan 2012 16:38:07 +0100, boyska  wrote:
> > There's a description of the DB "schema" in lib/database.cc in the
> > notmuch source code. But you may also consider just using libnotmuch
> > instead, if that's enough for what you want to do.
> 
> thanks, found it, much clearer now.
> But I really can't understand why not just putting these things on a
> separate file :) atomic consistency issues?

I doubt it's for consistency (see commit 824dad76), more likely it's
because people should use libnotmuch rather than directly hacking into
the DB ;)


> > Also: why Xapian? I'm already using something similar I wrote with
> > Python, storing everything in a dictionary, using Pickle to save that to
> > disk: 162 lines of code and 45 kb of data are enough to store my
> > addressbook and have completion in Emacs...
> 
> dictionary approach is fine to manage a "manual" addressbook, where you
> store addresses. But what I want is an _automatic_ addressbook, like the
> lbdb one, which just indexes all seen emails.

That's what my little script does too: index emails and how many times
they appear in the DB so that completion shows more frequently used ones
first. The indexing is done after running "notmuch new", when running my
auto-tagging script. I'm too lazy to maintain a "manual" addressbook
correctly :)

> The grep approach is better from this point of view, but still not
> advanced enough for me.
> For example, I'd like to store "cooccorrences": if some email is used in
> the same mail of some other, then it must contain a relationship; for
> example, your email should be correlated to the notmuch mailinglist,
> because you wrote to it. (they should be 0-weighted xapian term).  Also,
> I want to give more importance to email addresses which are frequently
> seen, and much less to not-so-frequently seen. Xapian makes these really
> easy, so the question is "why not using it?" ;)

Nice ideas, and Xapian is probably a good choice for doing that kind of
stuff :)

Do you plan to use this addressbook with notmuch-address.el, or will it
be a standalone program?

Regards,

-- 
Thomas/Schnouki
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 489 bytes
Desc: not available
URL: 



Info about notmuch database

2012-01-05 Thread Thomas Jost
On Wed, 04 Jan 2012 15:49:19 +, boyska  wrote:
> Hello!
> I like notmuch a lot, so I'm writing a (conceptually) similar software
> about addressbook: it will scan all your emails, storing email 
> addresses
> in a xapian database (you can think of it as little brother database[1] 
> on
> steroids)
> The part that I'd like to re-implement is "notmuch new": it seems that
> in the xapian db there is not only informations about each mail, but
> also the mtime of each directory. My impression is this being 
> "chaotic",
> but probably I am just missing the point.
> 
> So, here's the question: how is the db "structured"? is there any
> documentation to look at?
> 
> [1] http://www.spinnaker.de/lbdb/
> 
> -- 
> boyska
> GPG: 0x520CE393

There's a description of the DB "schema" in lib/database.cc in the
notmuch source code. But you may also consider just using libnotmuch
instead, if that's enough for what you want to do.

Also: why Xapian? I'm already using something similar I wrote with
Python, storing everything in a dictionary, using Pickle to save that to
disk: 162 lines of code and 45 kb of data are enough to store my
addressbook and have completion in Emacs...

Regards,

-- 
Thomas/Schnouki
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 489 bytes
Desc: not available
URL: 



Re: Info about notmuch database

2012-01-05 Thread Thomas Jost
On Wed, 04 Jan 2012 15:49:19 +, boyska piutto...@logorroici.org wrote:
 Hello!
 I like notmuch a lot, so I'm writing a (conceptually) similar software
 about addressbook: it will scan all your emails, storing email 
 addresses
 in a xapian database (you can think of it as little brother database[1] 
 on
 steroids)
 The part that I'd like to re-implement is notmuch new: it seems that
 in the xapian db there is not only informations about each mail, but
 also the mtime of each directory. My impression is this being 
 chaotic,
 but probably I am just missing the point.
 
 So, here's the question: how is the db structured? is there any
 documentation to look at?
 
 [1] http://www.spinnaker.de/lbdb/
 
 -- 
 boyska
 GPG: 0x520CE393

There's a description of the DB schema in lib/database.cc in the
notmuch source code. But you may also consider just using libnotmuch
instead, if that's enough for what you want to do.

Also: why Xapian? I'm already using something similar I wrote with
Python, storing everything in a dictionary, using Pickle to save that to
disk: 162 lines of code and 45 kb of data are enough to store my
addressbook and have completion in Emacs...

Regards,

-- 
Thomas/Schnouki


pgpLQ0UslCmY9.pgp
Description: PGP signature
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: Info about notmuch database

2012-01-05 Thread Thomas Jost
On Thu, 5 Jan 2012 16:38:07 +0100, boyska piutto...@logorroici.org wrote:
  There's a description of the DB schema in lib/database.cc in the
  notmuch source code. But you may also consider just using libnotmuch
  instead, if that's enough for what you want to do.
 
 thanks, found it, much clearer now.
 But I really can't understand why not just putting these things on a
 separate file :) atomic consistency issues?

I doubt it's for consistency (see commit 824dad76), more likely it's
because people should use libnotmuch rather than directly hacking into
the DB ;)


  Also: why Xapian? I'm already using something similar I wrote with
  Python, storing everything in a dictionary, using Pickle to save that to
  disk: 162 lines of code and 45 kb of data are enough to store my
  addressbook and have completion in Emacs...
 
 dictionary approach is fine to manage a manual addressbook, where you
 store addresses. But what I want is an _automatic_ addressbook, like the
 lbdb one, which just indexes all seen emails.

That's what my little script does too: index emails and how many times
they appear in the DB so that completion shows more frequently used ones
first. The indexing is done after running notmuch new, when running my
auto-tagging script. I'm too lazy to maintain a manual addressbook
correctly :)

 The grep approach is better from this point of view, but still not
 advanced enough for me.
 For example, I'd like to store cooccorrences: if some email is used in
 the same mail of some other, then it must contain a relationship; for
 example, your email should be correlated to the notmuch mailinglist,
 because you wrote to it. (they should be 0-weighted xapian term).  Also,
 I want to give more importance to email addresses which are frequently
 seen, and much less to not-so-frequently seen. Xapian makes these really
 easy, so the question is why not using it? ;)

Nice ideas, and Xapian is probably a good choice for doing that kind of
stuff :)

Do you plan to use this addressbook with notmuch-address.el, or will it
be a standalone program?

Regards,

-- 
Thomas/Schnouki


pgpMf0rrQZ1l2.pgp
Description: PGP signature
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH] Update NEWS for Emacs changes

2012-01-04 Thread Thomas Jost
---
Hello world,

Here's my part. (Also describes Ivy Foster's patch for notmuch-hello-mode-hook.)

Regards,
Thomas

 NEWS |   19 +++
 1 files changed, 19 insertions(+), 0 deletions(-)

diff --git a/NEWS b/NEWS
index 6650126..8a3ff5a 100644
--- a/NEWS
+++ b/NEWS
@@ -34,6 +34,25 @@ Improvements in saved search management
   not inserted in front. It's also possible to define a sort function
   for displaying saved searches; alphabetical sort is provided.

+Hooks for notmuch-hello
+
+  Two new hooks have been added: "notmuch-hello-mode-hook" (called after
+  entering notmuch-hello-mode) and "notmuch-hello-refresh-hook" (called
+  after updating a notmuch-hello buffer).
+
+New face for crypto parts headers
+
+  Crypto parts used to be displayed with a hardcoded color. A new face
+  has been introduced to fix this: notmuch-crypto-part-header. It
+  defaults to the same value as before, but can be customized to match
+  other color themes.
+
+Use space as default thousands separator
+
+  Big numbers in notmuch-hello are now displayed using a space as
+  thousands separator (e.g. "123 456" instead of "123,456"). This can be
+  changed by customizing "notmuch-hello-thousands-separator".
+
 Performance
 ---

-- 
1.7.8.1



[PATCH] Update NEWS for Emacs changes

2012-01-04 Thread Thomas Jost
---
Hello world,

Here's my part. (Also describes Ivy Foster's patch for notmuch-hello-mode-hook.)

Regards,
Thomas

 NEWS |   19 +++
 1 files changed, 19 insertions(+), 0 deletions(-)

diff --git a/NEWS b/NEWS
index 6650126..8a3ff5a 100644
--- a/NEWS
+++ b/NEWS
@@ -34,6 +34,25 @@ Improvements in saved search management
   not inserted in front. It's also possible to define a sort function
   for displaying saved searches; alphabetical sort is provided.
 
+Hooks for notmuch-hello
+
+  Two new hooks have been added: notmuch-hello-mode-hook (called after
+  entering notmuch-hello-mode) and notmuch-hello-refresh-hook (called
+  after updating a notmuch-hello buffer).
+
+New face for crypto parts headers
+
+  Crypto parts used to be displayed with a hardcoded color. A new face
+  has been introduced to fix this: notmuch-crypto-part-header. It
+  defaults to the same value as before, but can be customized to match
+  other color themes.
+
+Use space as default thousands separator
+
+  Big numbers in notmuch-hello are now displayed using a space as
+  thousands separator (e.g. 123 456 instead of 123,456). This can be
+  changed by customizing notmuch-hello-thousands-separator.
+
 Performance
 ---
 
-- 
1.7.8.1

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH 2/2] test: add test for `notmuch-hello-refresh-hook'

2011-12-21 Thread Thomas Jost
On Thu, 22 Dec 2011 01:54:21 +0400, Dmitry Kurochkin  wrote:
> On Wed, 21 Dec 2011 22:49:13 +0100, Thomas Jost  
> wrote:
> > On Wed, 21 Dec 2011 22:18:26 +0400, Dmitry Kurochkin  > gmail.com> wrote:
> > > Test that `notmuch-hello-refresh-hook' is called once when
> > > `notmuch-hello' is called and twice when calling
> > > `notmuch-hello-update' after that.
> > > 
> > > The tests are very similar to tests for `notmuch-hello-mode-hook'.
> > 
> > Quite nice, better than what I sent earlier [1] :)
> > 
> > However I'm not sure that notmuch-hello.el is the right place for this
> > kind of stuff; notmuch-lib.el may be better (so that it can also be used
> > in other hooks.
> > 
> 
> These patches do not touch notmuch-hello.el.  The functions are added to
> test/test-lib.el.

Wow. So apparently 22:49 is too late for me to read correctly.

Full ACK for me then!

Regards,
Thomas

> 
> Regards,
>   Dmitry
> 
> > Regards,
> > Thomas
> > 
> > [1] id:"1324473189-8622-1-git-send-email-schnouki at schnouki.net"
> > 
> > 
> > > ---
> > >  test/emacs   |   19 +++
> > >  test/test-lib.el |1 +
> > >  2 files changed, 20 insertions(+), 0 deletions(-)
> > > 
> > > diff --git a/test/emacs b/test/emacs
> > > index dffad0f..ca82445 100755
> > > --- a/test/emacs
> > > +++ b/test/emacs
> > > @@ -495,4 +495,23 @@ counter=$(test_emacs \
> > >  )
> > >  test_expect_equal "$counter" 1
> > >  
> > > +test_begin_subtest "notmuch-hello-refresh hook is called"
> > > +counter=$(test_emacs \
> > > +'(let ((notmuch-hello-refresh-hook-counter 0))
> > > +   (kill-buffer "*notmuch-hello*")
> > > +   (notmuch-hello)
> > > +   notmuch-hello-refresh-hook-counter)'
> > > +)
> > > +test_expect_equal "$counter" 1
> > > +
> > > +test_begin_subtest "notmuch-hello-refresh hook is called on updates"
> > > +counter=$(test_emacs \
> > > +'(let ((notmuch-hello-refresh-hook-counter 0))
> > > +   (kill-buffer "*notmuch-hello*")
> > > +   (notmuch-hello)
> > > +   (notmuch-hello-update)
> > > +   notmuch-hello-refresh-hook-counter)'
> > > +)
> > > +test_expect_equal "$counter" 2
> > > +
> > >  test_done
> > > diff --git a/test/test-lib.el b/test/test-lib.el
> > > index 83b8a65..3b817c3 100644
> > > --- a/test/test-lib.el
> > > +++ b/test/test-lib.el
> > > @@ -75,3 +75,4 @@ nothing."
> > >(add-hook hook (apply-partially 'hook-counter hook)))
> > >  
> > >  (add-hook-counter 'notmuch-hello-mode-hook)
> > > +(add-hook-counter 'notmuch-hello-refresh-hook)
> > > -- 
> > > 1.7.7.3
> > > 
> > > ___
> > > notmuch mailing list
> > > notmuch at notmuchmail.org
> > > http://notmuchmail.org/mailman/listinfo/notmuch
> > 
> > -- 
> > Thomas/Schnouki

-- 
Thomas/Schnouki
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 489 bytes
Desc: not available
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20111221/6882c762/attachment.pgp>


[PATCH] notmuch: Quiet buildbot warnings.

2011-12-21 Thread Thomas Jost
On Tue, 20 Dec 2011 15:20:04 +, David Edmondson  wrote:
> Cast away the result of various *write functions. Provide a default
> value for some variables to avoid "use before set" warnings.
> ---
> 
> The buildbot complains about these, though my own system (Debian
> testing on amd64) does not.

What's the version of glibc on the buildbot?
http://sourceware.org/bugzilla/show_bug.cgi?id=11959

Regards,

-- 
Thomas/Schnouki
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 489 bytes
Desc: not available
URL: 



[PATCH 2/2] test: add test for `notmuch-hello-refresh-hook'

2011-12-21 Thread Thomas Jost
On Wed, 21 Dec 2011 22:18:26 +0400, Dmitry Kurochkin  wrote:
> Test that `notmuch-hello-refresh-hook' is called once when
> `notmuch-hello' is called and twice when calling
> `notmuch-hello-update' after that.
> 
> The tests are very similar to tests for `notmuch-hello-mode-hook'.

Quite nice, better than what I sent earlier [1] :)

However I'm not sure that notmuch-hello.el is the right place for this
kind of stuff; notmuch-lib.el may be better (so that it can also be used
in other hooks.

Regards,
Thomas

[1] id:"1324473189-8622-1-git-send-email-schnouki at schnouki.net"


> ---
>  test/emacs   |   19 +++
>  test/test-lib.el |1 +
>  2 files changed, 20 insertions(+), 0 deletions(-)
> 
> diff --git a/test/emacs b/test/emacs
> index dffad0f..ca82445 100755
> --- a/test/emacs
> +++ b/test/emacs
> @@ -495,4 +495,23 @@ counter=$(test_emacs \
>  )
>  test_expect_equal "$counter" 1
>  
> +test_begin_subtest "notmuch-hello-refresh hook is called"
> +counter=$(test_emacs \
> +'(let ((notmuch-hello-refresh-hook-counter 0))
> +   (kill-buffer "*notmuch-hello*")
> +   (notmuch-hello)
> +   notmuch-hello-refresh-hook-counter)'
> +)
> +test_expect_equal "$counter" 1
> +
> +test_begin_subtest "notmuch-hello-refresh hook is called on updates"
> +counter=$(test_emacs \
> +'(let ((notmuch-hello-refresh-hook-counter 0))
> +   (kill-buffer "*notmuch-hello*")
> +   (notmuch-hello)
> +   (notmuch-hello-update)
> +   notmuch-hello-refresh-hook-counter)'
> +)
> +test_expect_equal "$counter" 2
> +
>  test_done
> diff --git a/test/test-lib.el b/test/test-lib.el
> index 83b8a65..3b817c3 100644
> --- a/test/test-lib.el
> +++ b/test/test-lib.el
> @@ -75,3 +75,4 @@ nothing."
>(add-hook hook (apply-partially 'hook-counter hook)))
>  
>  (add-hook-counter 'notmuch-hello-mode-hook)
> +(add-hook-counter 'notmuch-hello-refresh-hook)
> -- 
> 1.7.7.3
> 
> ___
> notmuch mailing list
> notmuch at notmuchmail.org
> http://notmuchmail.org/mailman/listinfo/notmuch

-- 
Thomas/Schnouki
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 489 bytes
Desc: not available
URL: 



[PATCH 2/2] emacs: Change the default thousands separator to a space

2011-12-21 Thread Thomas Jost
This had been discussed and decided on IRC.

Rationale:
  Therefore the space is recommended in the SI/ISO 31-0 standard, and the
  International Bureau of Weights and Measures states that "for numbers with
  many digits the digits may be divided into groups of three by a thin space, in
  order to facilitate reading. Neither dots nor commas are inserted in the
  spaces between groups of three".

(http://en.wikipedia.org/wiki/Decimal_separator#Digit_grouping)
---
 emacs/notmuch-hello.el |6 --
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el
index ef585ea..878d92a 100644
--- a/emacs/notmuch-hello.el
+++ b/emacs/notmuch-hello.el
@@ -131,10 +131,12 @@ So:
  (integer :tag "Number of characters")
  (float :tag "Fraction of window")))

-(defcustom notmuch-hello-thousands-separator ","
+(defcustom notmuch-hello-thousands-separator " "
   "The string used as a thousands separator.

-Typically \",\" in the US and UK and \".\" in Europe."
+Typically \",\" in the US and UK and \".\" or \" \" in Europe.
+The latter is recommended in the SI/ISO 31-0 standard and by the
+International Bureau of Weights and Measures."
   :group 'notmuch
   :type 'string)

-- 
1.7.8



[PATCH 1/2] emacs: rename notmuch-decimal-separator to notmuch-hello-thousands-separator

2011-12-21 Thread Thomas Jost
In 123,456.78, "." is the decimal separator, but "," is the thousands separator.
---
 emacs/notmuch-hello.el |6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el
index f892ff7..ef585ea 100644
--- a/emacs/notmuch-hello.el
+++ b/emacs/notmuch-hello.el
@@ -131,8 +131,8 @@ So:
  (integer :tag "Number of characters")
  (float :tag "Fraction of window")))

-(defcustom notmuch-decimal-separator ","
-  "The string used as a decimal separator.
+(defcustom notmuch-hello-thousands-separator ","
+  "The string used as a thousands separator.

 Typically \",\" in the US and UK and \".\" in Europe."
   :group 'notmuch
@@ -169,7 +169,7 @@ Typically \",\" in the US and UK and \".\" in Europe."
 (apply #'concat
  (number-to-string (car result))
  (mapcar (lambda (elem)
- (format "%s%03d" notmuch-decimal-separator elem))
+ (format "%s%03d" notmuch-hello-thousands-separator elem))
 (cdr result)

 (defun notmuch-hello-trim (search)
-- 
1.7.8



[PATCH] test: add tests for `notmuch-hello-refresh-hook'

2011-12-21 Thread Thomas Jost
Test that it's called once when `notmuch-hello' is called, and twice when
calling `notmuch-hello-update' after that.
---
Here it is. No broken subtest first since the first patch was already pushed
though.

Regards,
Thomas

 test/emacs |   23 +++
 1 files changed, 23 insertions(+), 0 deletions(-)

diff --git a/test/emacs b/test/emacs
index dffad0f..94b9171 100755
--- a/test/emacs
+++ b/test/emacs
@@ -495,4 +495,27 @@ counter=$(test_emacs \
 )
 test_expect_equal "$counter" 1

+test_begin_subtest "notmuch-hello-refresh-hook is called"
+counter=$(test_emacs \
+"(let ((refresh-hook-counter 0)
+   (notmuch-hello-refresh-hook nil))
+   (kill-buffer \"*notmuch-hello*\")
+   (add-hook 'notmuch-hello-refresh-hook (lambda () (incf 
refresh-hook-counter)))
+   (notmuch-hello)
+   refresh-hook-counter)"
+)
+test_expect_equal "$counter" 1
+
+test_begin_subtest "notmuch-hello-refresh-hook is called on updates"
+counter=$(test_emacs \
+"(let ((refresh-hook-counter 0)
+   (notmuch-hello-refresh-hook nil))
+   (kill-buffer \"*notmuch-hello*\")
+   (add-hook 'notmuch-hello-refresh-hook (lambda () (incf 
refresh-hook-counter)))
+   (notmuch-hello)
+   (notmuch-hello-update)
+   refresh-hook-counter)"
+)
+test_expect_equal "$counter" 2
+
 test_done
-- 
1.7.8



[PATCH] emacs: add notmuch-hello-refresh-hook

2011-12-21 Thread Thomas Jost
This hook is called every time a notmuch-hello buffer is updated.
---
Oops, the previous patch had a typo which prevented it to work (":group notmuch"
instead of ":group 'notmuch"). Sorry about that.

 emacs/notmuch-hello.el |9 -
 1 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el
index 115f80a..a2b1c4c 100644
--- a/emacs/notmuch-hello.el
+++ b/emacs/notmuch-hello.el
@@ -143,6 +143,11 @@ Typically \",\" in the US and UK and \".\" or \" \" in 
Europe."
   :group 'notmuch
   :type 'hook)

+(defcustom notmuch-hello-refresh-hook nil
+  "Functions called after updating a `notmuch-hello' buffer."
+  :type 'hook
+  :group 'notmuch)
+
 (defvar notmuch-hello-url "http://notmuchmail.org;
   "The `notmuch' web site.")

@@ -590,7 +595,9 @@ Complete list of currently available key bindings:
  (widget-forward 1)))

   (unless (widget-at)
-   (notmuch-hello-goto-search)
+   (notmuch-hello-goto-search
+
+  (run-hooks 'notmuch-hello-refresh-hook))

 (defun notmuch-folder ()
   "Deprecated function for invoking notmuch---calling `notmuch' is preferred 
now."
-- 
1.7.8



[PATCH 2/5] lib: Add a MTIME value to every mail document

2011-12-21 Thread Thomas Jost
On Wed, 14 Dec 2011 19:45:07 -0500, Austin Clements  wrote:
> A few minor comments below.
> 
> At a higher level, I'm curious what the tag synchronization protocol
> you're building on top of this is.  I can't think of one that doesn't
> have race conditions, but maybe I'm not thinking about it right.

The approach I've used is quite different from what you described in
id:"20111219194821.GA10376 at mit.edu". I don't directly sync host A to
host B but I use a server in the middle. (A is my laptop --> not always
on, B is my work PC --> turned off when I'm out of office, so a direct
sync would be harder to do).

My nm-sync script is written in Python 2 (2.7, may work with 2.6) and is
present on both my PCs and on my server. It can operate in two modes :
client (when run from one of my PCs) or server (called *from the client*
through ssh, running on my server).

When running in server mode, the script manipulates a small DB stored as
a Python dictionary (and stored on disk with the pickle module). It does
not even need notmuch to be installed on the server. Here is what this
DB looks like:
  {
"lastseen": {
  "pc_A": 1324428029,
  "pc_B": 1323952028
},
"messages": {
  "msgid_001": (mtime, tag1, tag2, ..., tagN),
  "msgid_002": (mtime, tag1, tag2, ..., tagM),
  ...
}
  }

So when running the client, here is what happens:
1. client starts a subprocess: "ssh myserver ~/nm-sync server"
2. client and server check that their sha1sum match (to avoid version
   mismatch)
3. client identifies itself with its hostname ("pc_A" in the example
   above), server replies with its "lastseen" value and updates its in
   the DB
4. server sends to client messages with mtime > lastseen (msgid + mtime
   + tags), client updates the notmuch DB with these values
5. client queries the notmuch DB for messages with mtime > lastseen and
   sends them (msgid + mtime + tags) to the server, which stores them in
   the DB
6. cleanup: server removes messages with mtime < min(lastseen) from its
   DB

So basically this approach assumes that all clocks are synchronized
(everyone uses ntp, right?...) and does not even try to detect
conflicts: if a message has been modified both locally and remotely,
then the local version will be overwritten by the remote one, period. It
should also work with more than 2 hosts (but not tested yet). No sync
data is kept in the notmuch DB.

Right now all of this fits in about 250 lines of Python (could be made
shorter) and works quite well for me. I'll put it online after doing
some cleanup.


> Quoth Thomas Jost on Dec 13 at  6:11 pm:
> > This is a time_t value, similar to the message date (TIMESTAMP). It is 
> > first set
> > when the message is added to the database, and is then updated every time a 
> > tag
> > is added or removed. It can thus be used for doing incremental dumps of the
> > database or for synchronizing it between several computers.
> > 
> > This value can be read freely (with notmuch_message_get_mtime()) but for 
> > now it
> > can't be set to an arbitrary value: it can only be set to "now" when 
> > updated.
> > There's no specific reason for this except that I don't really see a real 
> > use
> > case for setting it to an arbitrary value.
> > ---
> >  lib/database.cc   |7 ++-
> >  lib/message.cc|   32 
> >  lib/notmuch-private.h |6 +-
> >  lib/notmuch.h |4 
> >  4 files changed, 47 insertions(+), 2 deletions(-)
> > 
> > diff --git a/lib/database.cc b/lib/database.cc
> > index 2025189..6dc6f73 100644
> > --- a/lib/database.cc
> > +++ b/lib/database.cc
> > @@ -81,7 +81,7 @@ typedef struct {
> >   * STRING is the name of a file within that
> >   * directory for this mail message.
> >   *
> > - *A mail document also has four values:
> > + *A mail document also has five values:
> >   *
> >   * TIMESTAMP:  The time_t value corresponding to the message's
> >   * Date header.
> > @@ -92,6 +92,9 @@ typedef struct {
> >   *
> >   * SUBJECT:The value of the "Subject" header
> >   *
> > + * MTIME:  The time_t value corresponding to the last time
> > + * a tag was added or removed on the message.
> > + *
> >   * In addition, terms from the content of the message are added with
> >   * "from", "to", "attachment", and "subject" prefixes for use by the
> >   * user in searching. Similarly, terms from the path of the mail
> > @@ -1735,6 +1738

[PATCH 2/5] lib: Add a MTIME value to every mail document

2011-12-21 Thread Thomas Jost
On Wed, 14 Dec 2011 14:54:10 -0700, Mark Anderson  
wrote:
> On Tue, 13 Dec 2011 11:11:42 -0600, Thomas Jost  
> wrote:
> > This is a time_t value, similar to the message date (TIMESTAMP). It is 
> > first set
> > when the message is added to the database, and is then updated every time a 
> > tag
> > is added or removed. It can thus be used for doing incremental dumps of the
> > database or for synchronizing it between several computers.
> > 
> > This value can be read freely (with notmuch_message_get_mtime()) but for 
> > now it
> > can't be set to an arbitrary value: it can only be set to "now" when 
> > updated.
> > There's no specific reason for this except that I don't really see a real 
> > use
> > case for setting it to an arbitrary value.
> 
> I think it would be easier to write some testcases if the last modified
> time could be touched directly.  Perhaps they aren't in the set of "must
> have", but it's what comes to mind.

Well since I posted this, I found other good reasons to have a set_mtime
function. I'll post an updated series lated which will include it -- and
possibly some tests too :)

Thanks,

-- 
Thomas/Schnouki
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 489 bytes
Desc: not available
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20111221/bcb3fe45/attachment.pgp>


[PATCH v3 3/4] emacs: rename notmuch-decimal-separator to notmuch-thousands-separator

2011-12-21 Thread Thomas Jost
On Fri, 16 Dec 2011 16:34:03 +0400, Dmitry Kurochkin  wrote:
> On Fri, 16 Dec 2011 08:29:00 -0400, David Bremner  
> wrote:
> > On Fri, 16 Dec 2011 04:59:22 +0400, Dmitry Kurochkin  > gmail.com> wrote:
> > > 
> > > What do perople think about making the thousands separator a space by
> > > default?
> > > 
> > 
> > Is that really good for a majority of users? I had never heard of it
> > until now. I know this is hardly scientific, but still...
> > 
> 
> Well, to me "1 000 000 000" looks better than "1,000,000,000".  But I do
> not know about the others.  That is why I was asking :)

That's a complex topic unfortunately. I prefer "1 000 000" too, but many
would prefer "1,000,000", others would prefer "1'000'000", and in India
many would even prefer "1,00,"
(https://en.wikipedia.org/wiki/Thousands_separator#Examples_of_use).

The cleanest solution would be to use something that cares about the
LC_NUMERIC environment variable. sprintf() can do such things, but I'm
not aware of any possibility to do that in elisp.

-- 
Thomas/Schnouki
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 489 bytes
Desc: not available
URL: 



[PATCH] emacs: add notmuch-hello-refresh-hook

2011-12-21 Thread Thomas Jost
This hook is called every time a notmuch-hello buffer is updated.
---
Hi Dmitry,

I like the idea of having a -mode-hook and a -refresh-hook :) Thanks for your
suggestions!

Regards,
Thomas

 emacs/notmuch-hello.el |9 -
 1 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el
index 115f80a..9fa3137 100644
--- a/emacs/notmuch-hello.el
+++ b/emacs/notmuch-hello.el
@@ -143,6 +143,11 @@ Typically \",\" in the US and UK and \".\" or \" \" in 
Europe."
   :group 'notmuch
   :type 'hook)

+(defcustom notmuch-hello-refresh-hook nil
+  "Functions called after updating a `notmuch-hello' buffer."
+  :type 'hook
+  :group notmuch)
+
 (defvar notmuch-hello-url "http://notmuchmail.org;
   "The `notmuch' web site.")

@@ -590,7 +595,9 @@ Complete list of currently available key bindings:
  (widget-forward 1)))

   (unless (widget-at)
-   (notmuch-hello-goto-search)
+   (notmuch-hello-goto-search
+
+  (run-hooks 'notmuch-hello-refresh-hook))

 (defun notmuch-folder ()
   "Deprecated function for invoking notmuch---calling `notmuch' is preferred 
now."
-- 
1.7.8



[PATCH 1/2] emacs: rename notmuch-decimal-separator to notmuch-hello-thousands-separator

2011-12-21 Thread Thomas Jost
In 123,456.78, . is the decimal separator, but , is the thousands separator.
---
 emacs/notmuch-hello.el |6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el
index f892ff7..ef585ea 100644
--- a/emacs/notmuch-hello.el
+++ b/emacs/notmuch-hello.el
@@ -131,8 +131,8 @@ So:
  (integer :tag Number of characters)
  (float :tag Fraction of window)))
 
-(defcustom notmuch-decimal-separator ,
-  The string used as a decimal separator.
+(defcustom notmuch-hello-thousands-separator ,
+  The string used as a thousands separator.
 
 Typically \,\ in the US and UK and \.\ in Europe.
   :group 'notmuch
@@ -169,7 +169,7 @@ Typically \,\ in the US and UK and \.\ in Europe.
 (apply #'concat
  (number-to-string (car result))
  (mapcar (lambda (elem)
- (format %s%03d notmuch-decimal-separator elem))
+ (format %s%03d notmuch-hello-thousands-separator elem))
 (cdr result)
 
 (defun notmuch-hello-trim (search)
-- 
1.7.8

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH 2/2] emacs: Change the default thousands separator to a space

2011-12-21 Thread Thomas Jost
This had been discussed and decided on IRC.

Rationale:
  Therefore the space is recommended in the SI/ISO 31-0 standard, and the
  International Bureau of Weights and Measures states that for numbers with
  many digits the digits may be divided into groups of three by a thin space, in
  order to facilitate reading. Neither dots nor commas are inserted in the
  spaces between groups of three.

(http://en.wikipedia.org/wiki/Decimal_separator#Digit_grouping)
---
 emacs/notmuch-hello.el |6 --
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el
index ef585ea..878d92a 100644
--- a/emacs/notmuch-hello.el
+++ b/emacs/notmuch-hello.el
@@ -131,10 +131,12 @@ So:
  (integer :tag Number of characters)
  (float :tag Fraction of window)))
 
-(defcustom notmuch-hello-thousands-separator ,
+(defcustom notmuch-hello-thousands-separator  
   The string used as a thousands separator.
 
-Typically \,\ in the US and UK and \.\ in Europe.
+Typically \,\ in the US and UK and \.\ or \ \ in Europe.
+The latter is recommended in the SI/ISO 31-0 standard and by the
+International Bureau of Weights and Measures.
   :group 'notmuch
   :type 'string)
 
-- 
1.7.8

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH 2/2] test: add test for `notmuch-hello-refresh-hook'

2011-12-21 Thread Thomas Jost
On Wed, 21 Dec 2011 22:18:26 +0400, Dmitry Kurochkin 
dmitry.kuroch...@gmail.com wrote:
 Test that `notmuch-hello-refresh-hook' is called once when
 `notmuch-hello' is called and twice when calling
 `notmuch-hello-update' after that.
 
 The tests are very similar to tests for `notmuch-hello-mode-hook'.

Quite nice, better than what I sent earlier [1] :)

However I'm not sure that notmuch-hello.el is the right place for this
kind of stuff; notmuch-lib.el may be better (so that it can also be used
in other hooks.

Regards,
Thomas

[1] id:1324473189-8622-1-git-send-email-schno...@schnouki.net


 ---
  test/emacs   |   19 +++
  test/test-lib.el |1 +
  2 files changed, 20 insertions(+), 0 deletions(-)
 
 diff --git a/test/emacs b/test/emacs
 index dffad0f..ca82445 100755
 --- a/test/emacs
 +++ b/test/emacs
 @@ -495,4 +495,23 @@ counter=$(test_emacs \
  )
  test_expect_equal $counter 1
  
 +test_begin_subtest notmuch-hello-refresh hook is called
 +counter=$(test_emacs \
 +'(let ((notmuch-hello-refresh-hook-counter 0))
 +   (kill-buffer *notmuch-hello*)
 +   (notmuch-hello)
 +   notmuch-hello-refresh-hook-counter)'
 +)
 +test_expect_equal $counter 1
 +
 +test_begin_subtest notmuch-hello-refresh hook is called on updates
 +counter=$(test_emacs \
 +'(let ((notmuch-hello-refresh-hook-counter 0))
 +   (kill-buffer *notmuch-hello*)
 +   (notmuch-hello)
 +   (notmuch-hello-update)
 +   notmuch-hello-refresh-hook-counter)'
 +)
 +test_expect_equal $counter 2
 +
  test_done
 diff --git a/test/test-lib.el b/test/test-lib.el
 index 83b8a65..3b817c3 100644
 --- a/test/test-lib.el
 +++ b/test/test-lib.el
 @@ -75,3 +75,4 @@ nothing.
(add-hook hook (apply-partially 'hook-counter hook)))
  
  (add-hook-counter 'notmuch-hello-mode-hook)
 +(add-hook-counter 'notmuch-hello-refresh-hook)
 -- 
 1.7.7.3
 
 ___
 notmuch mailing list
 notmuch@notmuchmail.org
 http://notmuchmail.org/mailman/listinfo/notmuch

-- 
Thomas/Schnouki


pgpnUu0VlrAkF.pgp
Description: PGP signature
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH] notmuch: Quiet buildbot warnings.

2011-12-21 Thread Thomas Jost
On Tue, 20 Dec 2011 15:20:04 +, David Edmondson d...@dme.org wrote:
 Cast away the result of various *write functions. Provide a default
 value for some variables to avoid use before set warnings.
 ---
 
 The buildbot complains about these, though my own system (Debian
 testing on amd64) does not.

What's the version of glibc on the buildbot?
http://sourceware.org/bugzilla/show_bug.cgi?id=11959

Regards,

-- 
Thomas/Schnouki


pgppdpfefCyLO.pgp
Description: PGP signature
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH 2/2] test: add test for `notmuch-hello-refresh-hook'

2011-12-21 Thread Thomas Jost
On Thu, 22 Dec 2011 01:54:21 +0400, Dmitry Kurochkin 
dmitry.kuroch...@gmail.com wrote:
 On Wed, 21 Dec 2011 22:49:13 +0100, Thomas Jost schno...@schnouki.net wrote:
  On Wed, 21 Dec 2011 22:18:26 +0400, Dmitry Kurochkin 
  dmitry.kuroch...@gmail.com wrote:
   Test that `notmuch-hello-refresh-hook' is called once when
   `notmuch-hello' is called and twice when calling
   `notmuch-hello-update' after that.
   
   The tests are very similar to tests for `notmuch-hello-mode-hook'.
  
  Quite nice, better than what I sent earlier [1] :)
  
  However I'm not sure that notmuch-hello.el is the right place for this
  kind of stuff; notmuch-lib.el may be better (so that it can also be used
  in other hooks.
  
 
 These patches do not touch notmuch-hello.el.  The functions are added to
 test/test-lib.el.

Wow. So apparently 22:49 is too late for me to read correctly.

Full ACK for me then!

Regards,
Thomas

 
 Regards,
   Dmitry
 
  Regards,
  Thomas
  
  [1] id:1324473189-8622-1-git-send-email-schno...@schnouki.net
  
  
   ---
test/emacs   |   19 +++
test/test-lib.el |1 +
2 files changed, 20 insertions(+), 0 deletions(-)
   
   diff --git a/test/emacs b/test/emacs
   index dffad0f..ca82445 100755
   --- a/test/emacs
   +++ b/test/emacs
   @@ -495,4 +495,23 @@ counter=$(test_emacs \
)
test_expect_equal $counter 1

   +test_begin_subtest notmuch-hello-refresh hook is called
   +counter=$(test_emacs \
   +'(let ((notmuch-hello-refresh-hook-counter 0))
   +   (kill-buffer *notmuch-hello*)
   +   (notmuch-hello)
   +   notmuch-hello-refresh-hook-counter)'
   +)
   +test_expect_equal $counter 1
   +
   +test_begin_subtest notmuch-hello-refresh hook is called on updates
   +counter=$(test_emacs \
   +'(let ((notmuch-hello-refresh-hook-counter 0))
   +   (kill-buffer *notmuch-hello*)
   +   (notmuch-hello)
   +   (notmuch-hello-update)
   +   notmuch-hello-refresh-hook-counter)'
   +)
   +test_expect_equal $counter 2
   +
test_done
   diff --git a/test/test-lib.el b/test/test-lib.el
   index 83b8a65..3b817c3 100644
   --- a/test/test-lib.el
   +++ b/test/test-lib.el
   @@ -75,3 +75,4 @@ nothing.
  (add-hook hook (apply-partially 'hook-counter hook)))

(add-hook-counter 'notmuch-hello-mode-hook)
   +(add-hook-counter 'notmuch-hello-refresh-hook)
   -- 
   1.7.7.3
   
   ___
   notmuch mailing list
   notmuch@notmuchmail.org
   http://notmuchmail.org/mailman/listinfo/notmuch
  
  -- 
  Thomas/Schnouki

-- 
Thomas/Schnouki


pgptCfXMX4tC0.pgp
Description: PGP signature
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH] emacs: add notmuch-hello-refresh-hook

2011-12-20 Thread Thomas Jost
This hook is called every time a notmuch-hello buffer is updated.
---
Hi Dmitry,

I like the idea of having a -mode-hook and a -refresh-hook :) Thanks for your
suggestions!

Regards,
Thomas

 emacs/notmuch-hello.el |9 -
 1 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el
index 115f80a..9fa3137 100644
--- a/emacs/notmuch-hello.el
+++ b/emacs/notmuch-hello.el
@@ -143,6 +143,11 @@ Typically \,\ in the US and UK and \.\ or \ \ in 
Europe.
   :group 'notmuch
   :type 'hook)
 
+(defcustom notmuch-hello-refresh-hook nil
+  Functions called after updating a `notmuch-hello' buffer.
+  :type 'hook
+  :group notmuch)
+
 (defvar notmuch-hello-url http://notmuchmail.org;
   The `notmuch' web site.)
 
@@ -590,7 +595,9 @@ Complete list of currently available key bindings:
  (widget-forward 1)))
 
   (unless (widget-at)
-   (notmuch-hello-goto-search)
+   (notmuch-hello-goto-search
+
+  (run-hooks 'notmuch-hello-refresh-hook))
 
 (defun notmuch-folder ()
   Deprecated function for invoking notmuch---calling `notmuch' is preferred 
now.
-- 
1.7.8

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH v3 3/4] emacs: rename notmuch-decimal-separator to notmuch-thousands-separator

2011-12-20 Thread Thomas Jost
On Fri, 16 Dec 2011 16:34:03 +0400, Dmitry Kurochkin 
dmitry.kuroch...@gmail.com wrote:
 On Fri, 16 Dec 2011 08:29:00 -0400, David Bremner da...@tethera.net wrote:
  On Fri, 16 Dec 2011 04:59:22 +0400, Dmitry Kurochkin 
  dmitry.kuroch...@gmail.com wrote:
   
   What do perople think about making the thousands separator a space by
   default?
   
  
  Is that really good for a majority of users? I had never heard of it
  until now. I know this is hardly scientific, but still...
  
 
 Well, to me 1 000 000 000 looks better than 1,000,000,000.  But I do
 not know about the others.  That is why I was asking :)

That's a complex topic unfortunately. I prefer 1 000 000 too, but many
would prefer 1,000,000, others would prefer 1'000'000, and in India
many would even prefer 1,00,
(https://en.wikipedia.org/wiki/Thousands_separator#Examples_of_use).

The cleanest solution would be to use something that cares about the
LC_NUMERIC environment variable. sprintf() can do such things, but I'm
not aware of any possibility to do that in elisp.

-- 
Thomas/Schnouki


pgpyIvPp7KX9G.pgp
Description: PGP signature
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH 2/5] lib: Add a MTIME value to every mail document

2011-12-20 Thread Thomas Jost
On Wed, 14 Dec 2011 14:54:10 -0700, Mark Anderson markr.ander...@amd.com 
wrote:
 On Tue, 13 Dec 2011 11:11:42 -0600, Thomas Jost schno...@schnouki.net wrote:
  This is a time_t value, similar to the message date (TIMESTAMP). It is 
  first set
  when the message is added to the database, and is then updated every time a 
  tag
  is added or removed. It can thus be used for doing incremental dumps of the
  database or for synchronizing it between several computers.
  
  This value can be read freely (with notmuch_message_get_mtime()) but for 
  now it
  can't be set to an arbitrary value: it can only be set to now when 
  updated.
  There's no specific reason for this except that I don't really see a real 
  use
  case for setting it to an arbitrary value.
 
 I think it would be easier to write some testcases if the last modified
 time could be touched directly.  Perhaps they aren't in the set of must
 have, but it's what comes to mind.

Well since I posted this, I found other good reasons to have a set_mtime
function. I'll post an updated series lated which will include it -- and
possibly some tests too :)

Thanks,

-- 
Thomas/Schnouki


pgpibTonQiSUF.pgp
Description: PGP signature
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH 2/5] lib: Add a MTIME value to every mail document

2011-12-20 Thread Thomas Jost
On Wed, 14 Dec 2011 19:45:07 -0500, Austin Clements amdra...@mit.edu wrote:
 A few minor comments below.
 
 At a higher level, I'm curious what the tag synchronization protocol
 you're building on top of this is.  I can't think of one that doesn't
 have race conditions, but maybe I'm not thinking about it right.

The approach I've used is quite different from what you described in
id:20111219194821.ga10...@mit.edu. I don't directly sync host A to
host B but I use a server in the middle. (A is my laptop -- not always
on, B is my work PC -- turned off when I'm out of office, so a direct
sync would be harder to do).

My nm-sync script is written in Python 2 (2.7, may work with 2.6) and is
present on both my PCs and on my server. It can operate in two modes :
client (when run from one of my PCs) or server (called *from the client*
through ssh, running on my server).

When running in server mode, the script manipulates a small DB stored as
a Python dictionary (and stored on disk with the pickle module). It does
not even need notmuch to be installed on the server. Here is what this
DB looks like:
  {
lastseen: {
  pc_A: 1324428029,
  pc_B: 1323952028
},
messages: {
  msgid_001: (mtime, tag1, tag2, ..., tagN),
  msgid_002: (mtime, tag1, tag2, ..., tagM),
  ...
}
  }

So when running the client, here is what happens:
1. client starts a subprocess: ssh myserver ~/nm-sync server
2. client and server check that their sha1sum match (to avoid version
   mismatch)
3. client identifies itself with its hostname (pc_A in the example
   above), server replies with its lastseen value and updates its in
   the DB
4. server sends to client messages with mtime  lastseen (msgid + mtime
   + tags), client updates the notmuch DB with these values
5. client queries the notmuch DB for messages with mtime  lastseen and
   sends them (msgid + mtime + tags) to the server, which stores them in
   the DB
6. cleanup: server removes messages with mtime  min(lastseen) from its
   DB

So basically this approach assumes that all clocks are synchronized
(everyone uses ntp, right?...) and does not even try to detect
conflicts: if a message has been modified both locally and remotely,
then the local version will be overwritten by the remote one, period. It
should also work with more than 2 hosts (but not tested yet). No sync
data is kept in the notmuch DB.

Right now all of this fits in about 250 lines of Python (could be made
shorter) and works quite well for me. I'll put it online after doing
some cleanup.


 Quoth Thomas Jost on Dec 13 at  6:11 pm:
  This is a time_t value, similar to the message date (TIMESTAMP). It is 
  first set
  when the message is added to the database, and is then updated every time a 
  tag
  is added or removed. It can thus be used for doing incremental dumps of the
  database or for synchronizing it between several computers.
  
  This value can be read freely (with notmuch_message_get_mtime()) but for 
  now it
  can't be set to an arbitrary value: it can only be set to now when 
  updated.
  There's no specific reason for this except that I don't really see a real 
  use
  case for setting it to an arbitrary value.
  ---
   lib/database.cc   |7 ++-
   lib/message.cc|   32 
   lib/notmuch-private.h |6 +-
   lib/notmuch.h |4 
   4 files changed, 47 insertions(+), 2 deletions(-)
  
  diff --git a/lib/database.cc b/lib/database.cc
  index 2025189..6dc6f73 100644
  --- a/lib/database.cc
  +++ b/lib/database.cc
  @@ -81,7 +81,7 @@ typedef struct {
* STRING is the name of a file within that
* directory for this mail message.
*
  - *A mail document also has four values:
  + *A mail document also has five values:
*
* TIMESTAMP:  The time_t value corresponding to the message's
* Date header.
  @@ -92,6 +92,9 @@ typedef struct {
*
* SUBJECT:The value of the Subject header
*
  + * MTIME:  The time_t value corresponding to the last time
  + * a tag was added or removed on the message.
  + *
* In addition, terms from the content of the message are added with
* from, to, attachment, and subject prefixes for use by the
* user in searching. Similarly, terms from the path of the mail
  @@ -1735,6 +1738,8 @@ notmuch_database_add_message (notmuch_database_t 
  *notmuch,
  date = notmuch_message_file_get_header (message_file, date);
  _notmuch_message_set_header_values (message, date, from, subject);
   
  +_notmuch_message_update_mtime (message);
 
 Indentation.

Fixed, thanks.

 
  +
  _notmuch_message_index_file (message, filename);
  } else {
  ret = NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID;
  diff --git a/lib/message.cc b/lib/message.cc
  index 0075425..0c98589 100644
  --- a/lib/message.cc
  +++ b/lib/message.cc
  @@ -830,6 +830,34

[PATCH] emacs: add notmuch-hello-refresh-hook

2011-12-20 Thread Thomas Jost
This hook is called every time a notmuch-hello buffer is updated.
---
Oops, the previous patch had a typo which prevented it to work (:group notmuch
instead of :group 'notmuch). Sorry about that.

 emacs/notmuch-hello.el |9 -
 1 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el
index 115f80a..a2b1c4c 100644
--- a/emacs/notmuch-hello.el
+++ b/emacs/notmuch-hello.el
@@ -143,6 +143,11 @@ Typically \,\ in the US and UK and \.\ or \ \ in 
Europe.
   :group 'notmuch
   :type 'hook)
 
+(defcustom notmuch-hello-refresh-hook nil
+  Functions called after updating a `notmuch-hello' buffer.
+  :type 'hook
+  :group 'notmuch)
+
 (defvar notmuch-hello-url http://notmuchmail.org;
   The `notmuch' web site.)
 
@@ -590,7 +595,9 @@ Complete list of currently available key bindings:
  (widget-forward 1)))
 
   (unless (widget-at)
-   (notmuch-hello-goto-search)
+   (notmuch-hello-goto-search
+
+  (run-hooks 'notmuch-hello-refresh-hook))
 
 (defun notmuch-folder ()
   Deprecated function for invoking notmuch---calling `notmuch' is preferred 
now.
-- 
1.7.8

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH] Fix build with binutils-2.22

2011-12-15 Thread Thomas Jost
binutils-2.22 changes the behaviour of ld by defaulting to
--no-copy-dt-needed-entries, which means that required objects/libs are not
indirectly linked through intermediate objects/libs anymore. As a consequence,
when using binutils-2.22, building symbol-test fails with the following error:

/usr/bin/ld: test/symbol-test.o: undefined reference to symbol
'std::basic_stringchar, std::char_traitschar, std::allocatorchar
::~basic_string()@@GLIBCXX_3.4'

/usr/bin/ld: note: 'std::basic_stringchar, std::char_traitschar,
std::allocatorchar ::~basic_string()@@GLIBCXX_3.4' is defined in DSO
/usr/lib/libstdc++.so.6 so try adding it to the linker command line

/usr/lib/libstdc++.so.6: could not read symbols: Invalid operation

An easy fix is to link using CXX instead of CC.
---
Hi there,

This build issue happens on Arch Linux. For more details, the relevant binutils
changelog is here: http://ur1.ca/6px8j, and more explanations are available on
the Fedora wiki: https://fedoraproject.org/wiki/UnderstandingDSOLinkChange
(People who read the arch-general ML may want to read the thread starting at
id:1323458274-sup-9064@eris.)

Best regards,
Thomas

 test/Makefile.local |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/test/Makefile.local b/test/Makefile.local
index 6cb6c82..fa2df73 100644
--- a/test/Makefile.local
+++ b/test/Makefile.local
@@ -17,7 +17,7 @@ $(dir)/smtp-dummy: $(smtp_dummy_modules)
$(call quiet,CC) $^ -o $@
 
 $(dir)/symbol-test: $(dir)/symbol-test.o
-   $(call quiet,CC) $^ -o $@ -Llib -lnotmuch -lxapian
+   $(call quiet,CXX) $^ -o $@ -Llib -lnotmuch -lxapian
 
 .PHONY: test check
 
-- 
1.7.8

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH v3 4/4] emacs: add notmuch-hello-hook

2011-12-13 Thread Thomas Jost
This hook is called every time the notmuch-hello buffer is updated.
---
 emacs/notmuch-hello.el |9 -
 1 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el
index 0fe9c1d..112b40b 100644
--- a/emacs/notmuch-hello.el
+++ b/emacs/notmuch-hello.el
@@ -131,6 +131,11 @@ So:
  (integer :tag "Number of characters")
  (float :tag "Fraction of window")))

+(defcustom notmuch-hello-hook nil
+  "Functions called after populating a `notmuch-hello' buffer."
+  :type 'hook
+  :group 'notmuch)
+
 (defcustom notmuch-thousands-separator ","
   "The string used as a thousands separator.

@@ -579,7 +584,9 @@ Complete list of currently available key bindings:
  (widget-forward 1)))

   (unless (widget-at)
-   (notmuch-hello-goto-search)
+   (notmuch-hello-goto-search))
+
+  (run-hooks 'notmuch-hello-hook

 (defun notmuch-folder ()
   "Deprecated function for invoking notmuch---calling `notmuch' is preferred 
now."
-- 
1.7.8



[PATCH v3 3/4] emacs: rename notmuch-decimal-separator to notmuch-thousands-separator

2011-12-13 Thread Thomas Jost
In 123,456.78, "." is the decimal separator, but "," is the thousands separator.

This commit also mentions the space being used as thousands separator in several
European countries.
---
 emacs/notmuch-hello.el |8 
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el
index 0582cae..0fe9c1d 100644
--- a/emacs/notmuch-hello.el
+++ b/emacs/notmuch-hello.el
@@ -131,10 +131,10 @@ So:
  (integer :tag "Number of characters")
  (float :tag "Fraction of window")))

-(defcustom notmuch-decimal-separator ","
-  "The string used as a decimal separator.
+(defcustom notmuch-thousands-separator ","
+  "The string used as a thousands separator.

-Typically \",\" in the US and UK and \".\" in Europe."
+Typically \",\" in the US and UK and \".\" or \" \" in Europe."
   :group 'notmuch
   :type 'string)

@@ -159,7 +159,7 @@ Typically \",\" in the US and UK and \".\" in Europe."
 (apply #'concat
  (number-to-string (car result))
  (mapcar (lambda (elem)
- (format "%s%03d" notmuch-decimal-separator elem))
+ (format "%s%03d" notmuch-thousands-separator elem))
 (cdr result)

 (defun notmuch-hello-trim (search)
-- 
1.7.8



[PATCH v3 2/4] emacs: Add a face for crypto parts headers

2011-12-13 Thread Thomas Jost
Commit cb841878 introduced new parts handlers for crypto parts, but also
hardcoded values for their headers face. This replaces these hardcoded values
with a customizable face.
---
 emacs/notmuch-crypto.el |5 +
 emacs/notmuch-show.el   |4 ++--
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/emacs/notmuch-crypto.el b/emacs/notmuch-crypto.el
index 44fccae..67c26af 100644
--- a/emacs/notmuch-crypto.el
+++ b/emacs/notmuch-crypto.el
@@ -37,6 +37,11 @@ mode."
   :group 'notmuch
   :type 'boolean)

+(defface notmuch-crypto-part-header
+  '((t (:foreground "blue")))
+  "Face used for crypto parts headers."
+  :group 'notmuch)
+
 (defface notmuch-crypto-signature-good
   '((t (:background "green" :foreground "black")))
   "Face used for good signatures."
diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 33ee3d8..ec9c52c 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -457,7 +457,7 @@ current buffer, if possible."

 (defun notmuch-show-insert-part-multipart/signed (msg part content-type nth 
depth declared-type)
   (let ((button (notmuch-show-insert-part-header nth declared-type 
content-type nil)))
-(button-put button 'face '(:foreground "blue"))
+(button-put button 'face 'notmuch-crypto-part-header)
 ;; add signature status button if sigstatus provided
 (if (plist-member part :sigstatus)
(let* ((from (notmuch-show-get-header :From msg))
@@ -479,7 +479,7 @@ current buffer, if possible."

 (defun notmuch-show-insert-part-multipart/encrypted (msg part content-type nth 
depth declared-type)
   (let ((button (notmuch-show-insert-part-header nth declared-type 
content-type nil)))
-(button-put button 'face '(:foreground "blue"))
+(button-put button 'face 'notmuch-crypto-part-header)
 ;; add encryption status button if encstatus specified
 (if (plist-member part :encstatus)
(let ((encstatus (car (plist-get part :encstatus
-- 
1.7.8



[PATCH v3 1/4] emacs: Let the user choose where to compose new mails

2011-12-13 Thread Thomas Jost
Reusing the current window to compose a new mail may be troublesome for the
user. This patch introduces a new customizable variable, notmuch-mua-compose-in,
which lets the user choose where to create the mail buffer: in the current
window (current and default behaviour), in a new window, or in a new frame.
---
 emacs/notmuch-mua.el |   40 ++--
 1 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/emacs/notmuch-mua.el b/emacs/notmuch-mua.el
index 8824b08..90834d6 100644
--- a/emacs/notmuch-mua.el
+++ b/emacs/notmuch-mua.el
@@ -31,6 +31,21 @@
   :group 'notmuch
   :type 'hook)

+(defcustom notmuch-mua-compose-in 'current-window
+  "Where to create the mail buffer used to compose a new message.
+  Possible values are `current-window' (default), `new-window'
+  and `new-frame'. If set to `current-window', the mail buffer
+  will be displayed in the current window, so the old buffer will
+  be restored when the mail buffer is killed. If set to
+  `new-window' or `new-frame', the mail buffer will be displayed
+  in a new window/frame that will be destroyed when the buffer is
+  killed. You may want to customize `message-kill-buffer-on-exit'
+  accordingly."
+  :group 'notmuch
+  :type '(choice (const :tag "Compose in the current window" current-window)
+(const :tag "Compose mail in a new window"  new-window)
+(const :tag "Compose mail in a new frame"   new-frame)))
+
 (defcustom notmuch-mua-user-agent-function 'notmuch-mua-user-agent-full
   "Function used to generate a `User-Agent:' string. If this is
 `nil' then no `User-Agent:' will be generated."
@@ -48,6 +63,23 @@ list."

 ;;

+(defun notmuch-mua-get-switch-function ()
+  "Get a switch function according to `notmuch-mua-compose-in'."
+  (cond ((eq notmuch-mua-compose-in 'current-window)
+'switch-to-buffer)
+   ((eq notmuch-mua-compose-in 'new-window)
+'switch-to-buffer-other-window)
+   ((eq notmuch-mua-compose-in 'new-frame)
+'switch-to-buffer-other-frame)
+   (t (error "Invalid value for `notmuch-mua-compose-in'"
+
+(defun notmuch-mua-maybe-set-window-dedicated ()
+  "Set the selected window as dedicated according to
+`notmuch-mua-compose-in'."
+  (when (or (eq notmuch-mua-compose-in 'new-frame)
+   (eq notmuch-mua-compose-in 'new-window))
+(set-window-dedicated-p (selected-window) t)))
+
 (defun notmuch-mua-user-agent-full ()
   "Generate a `User-Agent:' string suitable for notmuch."
   (concat (notmuch-mua-user-agent-notmuch)
@@ -99,7 +131,8 @@ list."
((same-window-regexps '("\\*mail .*")))
   (notmuch-mua-mail (mail-header 'to headers)
(mail-header 'subject headers)
-   (message-headers-to-generate headers t '(to subject
+   (message-headers-to-generate headers t '(to subject))
+   nil (notmuch-mua-get-switch-function)))
 ;; insert the message body - but put it in front of the signature
 ;; if one is present
 (goto-char (point-max))
@@ -112,6 +145,7 @@ list."
   (message-goto-body))

 (defun notmuch-mua-forward-message ()
+  (funcall (notmuch-mua-get-switch-function) (current-buffer))
   (message-forward)

   (when notmuch-mua-user-agent-function
@@ -121,6 +155,7 @@ list."
   (message-sort-headers)
   (message-hide-headers)
   (set-buffer-modified-p nil)
+  (notmuch-mua-maybe-set-window-dedicated)

   (message-goto-to))

@@ -143,6 +178,7 @@ list."
   (message-sort-headers)
   (message-hide-headers)
   (set-buffer-modified-p nil)
+  (notmuch-mua-maybe-set-window-dedicated)

   (message-goto-to))

@@ -199,7 +235,7 @@ the From: address first."
   (let ((other-headers
 (when (or prompt-for-sender notmuch-always-prompt-for-sender)
   (list (cons 'from (notmuch-mua-prompt-for-sender))
-(notmuch-mua-mail nil nil other-headers)))
+(notmuch-mua-mail nil nil other-headers nil 
(notmuch-mua-get-switch-function

 (defun notmuch-mua-new-forward-message ( prompt-for-sender)
   "Invoke the notmuch message forwarding window.
-- 
1.7.8



[PATCH v3 0/4] Several minor Emacs enhancements

2011-12-13 Thread Thomas Jost
Hi David et al.,

Here is a rebased version of this patch series, with more descriptive
commit messages.

Please tell me if there are still ways to enhance them. English is not
my native language and it's sometimes hard to figure out what's relevant
and how to word it :)

Best regards,
Thomas

Thomas Jost (4):
  emacs: Let the user choose where to compose new mails
  emacs: Add a face for crypto parts headers
  emacs: rename notmuch-decimal-separator to
notmuch-thousands-separator
  emacs: add notmuch-hello-hook

 emacs/notmuch-crypto.el |5 +
 emacs/notmuch-hello.el  |   17 -
 emacs/notmuch-mua.el|   40 ++--
 emacs/notmuch-show.el   |4 ++--
 4 files changed, 57 insertions(+), 9 deletions(-)

-- 
1.7.8



[PATCH 1/5] Fix comments about what is stored in the database

2011-12-13 Thread Thomas Jost
Commit 567bcbc2 introduced two new values for each message (content of the
From and Subject headers), but the comments about the database schema had
not been updated accordingly.
---
 lib/database.cc |6 +-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/lib/database.cc b/lib/database.cc
index 98f101e..2025189 100644
--- a/lib/database.cc
+++ b/lib/database.cc
@@ -81,13 +81,17 @@ typedef struct {
  * STRING is the name of a file within that
  * directory for this mail message.
  *
- *A mail document also has two values:
+ *A mail document also has four values:
  *
  * TIMESTAMP:  The time_t value corresponding to the message's
  * Date header.
  *
  * MESSAGE_ID: The unique ID of the mail mess (see id above)
  *
+ * FROM:   The value of the From header
+ *
+ * SUBJECT:The value of the Subject header
+ *
  * In addition, terms from the content of the message are added with
  * from, to, attachment, and subject prefixes for use by the
  * user in searching. Similarly, terms from the path of the mail
-- 
1.7.8

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH 0/5] Store message modification times in the DB

2011-12-13 Thread Thomas Jost
Hello world,

This is a patch series I've been working on for some time in order to be
able to sync my tags on several computers. I'm posting it now, but
please consider it as a RFC rather than something that is ready to be
pushed.

The basic idea is to the last time each message was modified, i.e. the
message was added to the DB, a tag was added or a tag was removed.

This mtime is accessible through a library function and in the JSON
output of notmuch show. It is also searchable with the mtime: prefix
and with timestamp ranges, like for searching messages by date:

notmuch search mtime:$(date +%s 2011-12-01)..$(date +%s)

This can then be used in scripts or helper programs to do incremental
dumps or tags synchronization. (I already have a script to do
incremental backups, but it needs some cleaning, and I'm still working
on something for sync'ing tags, but it's starting to work really well;
I'll post them later).

This can be seen as an alternative to David Bremner's jlog branch, but
with several differences:

+ no external dependency
+ everything is stored in the notmuch DB: atomicity for free!
- when a message is removed we lose everything about it, which makes the
  sync process more complicated
- for a human, it's harder to manipulate timestamps than log messages
- this can store much less data than a proper log system

On IRC amdragon suggested using a simple sequence number instead of a
timestamp. This would indeed eliminate the need for proper time
synchronization between computers one would want to keep in sync, and it
would reduce the risk of time-going-backward problems, but IMHO it would
cause more problems: no global clock -- no simple way to tell if DB #A
is more recent than DB #B.

So, here are the patches:
- first a little fix to the comments describing the DB schema (not
  specific to this patch series at all, I just noticed it when rebasing
  this series)
- the second commit adds the MTIME value to the database schema, and
  creates the functions used to update and access this value.
- the third commit makes the MTIME value searchable with a range syntax.
- the fourth commit adds the MTIME to the JSON output of notmuch show.
- the fifth and last commit adds Message.get_mtime() to the Python
  bindings.

Please tell me what you think of this.

Best regards,
Thomas

Thomas Jost (5):
  Fix comments about what is stored in the database
  lib: Add a MTIME value to every mail document
  lib: Make MTIME values searchable
  show: include mtime in JSON output
  python: add get_mtime() to the Message class

 bindings/python/notmuch/message.py |   20 
 lib/database-private.h |1 +
 lib/database.cc|   14 +-
 lib/message.cc |   32 
 lib/notmuch-private.h  |6 +-
 lib/notmuch.h  |4 
 notmuch-show.c |7 ---
 notmuch.1  |   14 --
 notmuch.c  |   13 ++---
 9 files changed, 101 insertions(+), 10 deletions(-)

-- 
1.7.8

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH 2/5] lib: Add a MTIME value to every mail document

2011-12-13 Thread Thomas Jost
This is a time_t value, similar to the message date (TIMESTAMP). It is first set
when the message is added to the database, and is then updated every time a tag
is added or removed. It can thus be used for doing incremental dumps of the
database or for synchronizing it between several computers.

This value can be read freely (with notmuch_message_get_mtime()) but for now it
can't be set to an arbitrary value: it can only be set to now when updated.
There's no specific reason for this except that I don't really see a real use
case for setting it to an arbitrary value.
---
 lib/database.cc   |7 ++-
 lib/message.cc|   32 
 lib/notmuch-private.h |6 +-
 lib/notmuch.h |4 
 4 files changed, 47 insertions(+), 2 deletions(-)

diff --git a/lib/database.cc b/lib/database.cc
index 2025189..6dc6f73 100644
--- a/lib/database.cc
+++ b/lib/database.cc
@@ -81,7 +81,7 @@ typedef struct {
  * STRING is the name of a file within that
  * directory for this mail message.
  *
- *A mail document also has four values:
+ *A mail document also has five values:
  *
  * TIMESTAMP:  The time_t value corresponding to the message's
  * Date header.
@@ -92,6 +92,9 @@ typedef struct {
  *
  * SUBJECT:The value of the Subject header
  *
+ * MTIME:  The time_t value corresponding to the last time
+ * a tag was added or removed on the message.
+ *
  * In addition, terms from the content of the message are added with
  * from, to, attachment, and subject prefixes for use by the
  * user in searching. Similarly, terms from the path of the mail
@@ -1735,6 +1738,8 @@ notmuch_database_add_message (notmuch_database_t *notmuch,
date = notmuch_message_file_get_header (message_file, date);
_notmuch_message_set_header_values (message, date, from, subject);
 
+_notmuch_message_update_mtime (message);
+
_notmuch_message_index_file (message, filename);
} else {
ret = NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID;
diff --git a/lib/message.cc b/lib/message.cc
index 0075425..0c98589 100644
--- a/lib/message.cc
+++ b/lib/message.cc
@@ -830,6 +830,34 @@ _notmuch_message_set_header_values (notmuch_message_t 
*message,
 message-doc.add_value (NOTMUCH_VALUE_SUBJECT, subject);
 }
 
+/* Get the message mtime, i.e. when it was added or the last time a tag was
+ * added/removed. */
+time_t
+notmuch_message_get_mtime (notmuch_message_t *message)
+{
+std::string value;
+
+try {
+   value = message-doc.get_value (NOTMUCH_VALUE_MTIME);
+} catch (Xapian::Error error) {
+   INTERNAL_ERROR (Failed to read mtime value from document.);
+   return 0;
+}
+
+return Xapian::sortable_unserialise (value);
+}
+
+/* Set the message mtime to now. */
+void
+_notmuch_message_update_mtime (notmuch_message_t *message)
+{
+time_t time_value;
+
+time_value = time (NULL);
+message-doc.add_value (NOTMUCH_VALUE_MTIME,
+Xapian::sortable_serialise (time_value));
+}
+
 /* Synchronize changes made to message-doc out into the database. */
 void
 _notmuch_message_sync (notmuch_message_t *message)
@@ -994,6 +1022,8 @@ notmuch_message_add_tag (notmuch_message_t *message, const 
char *tag)
private_status);
 }
 
+_notmuch_message_update_mtime (message);
+
 if (! message-frozen)
_notmuch_message_sync (message);
 
@@ -1022,6 +1052,8 @@ notmuch_message_remove_tag (notmuch_message_t *message, 
const char *tag)
private_status);
 }
 
+_notmuch_message_update_mtime (message);
+
 if (! message-frozen)
_notmuch_message_sync (message);
 
diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h
index 60a932f..9859872 100644
--- a/lib/notmuch-private.h
+++ b/lib/notmuch-private.h
@@ -95,7 +95,8 @@ typedef enum {
 NOTMUCH_VALUE_TIMESTAMP = 0,
 NOTMUCH_VALUE_MESSAGE_ID,
 NOTMUCH_VALUE_FROM,
-NOTMUCH_VALUE_SUBJECT
+NOTMUCH_VALUE_SUBJECT,
+NOTMUCH_VALUE_MTIME
 } notmuch_value_t;
 
 /* Xapian (with flint backend) complains if we provide a term longer
@@ -276,6 +277,9 @@ _notmuch_message_set_header_values (notmuch_message_t 
*message,
const char *from,
const char *subject);
 void
+_notmuch_message_update_mtime (notmuch_message_t *message);
+
+void
 _notmuch_message_sync (notmuch_message_t *message);
 
 notmuch_status_t
diff --git a/lib/notmuch.h b/lib/notmuch.h
index 9f23a10..643ebce 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -910,6 +910,10 @@ notmuch_message_set_flag (notmuch_message_t *message,
 time_t
 notmuch_message_get_date  (notmuch_message_t *message);
 
+/* Get the mtime of 'message' as a time_t value. */
+time_t
+notmuch_message_get_mtime (notmuch_message_t *message);
+
 /* Get the value of the 

[PATCH 3/5] lib: Make MTIME values searchable

2011-12-13 Thread Thomas Jost
Tag modification times are now searchable as ranges (just like regular message
dates) with the mtime: prefix.
---
 lib/database-private.h |1 +
 lib/database.cc|3 +++
 notmuch.1  |   14 --
 notmuch.c  |   13 ++---
 4 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/lib/database-private.h b/lib/database-private.h
index 88532d5..e71c8e4 100644
--- a/lib/database-private.h
+++ b/lib/database-private.h
@@ -52,6 +52,7 @@ struct _notmuch_database {
 Xapian::QueryParser *query_parser;
 Xapian::TermGenerator *term_gen;
 Xapian::ValueRangeProcessor *value_range_processor;
+Xapian::ValueRangeProcessor *mtime_value_range_processor;
 };
 
 /* Return the list of terms from the given iterator matching a prefix.
diff --git a/lib/database.cc b/lib/database.cc
index 6dc6f73..cc970c1 100644
--- a/lib/database.cc
+++ b/lib/database.cc
@@ -677,12 +677,14 @@ notmuch_database_open (const char *path,
notmuch-term_gen = new Xapian::TermGenerator;
notmuch-term_gen-set_stemmer (Xapian::Stem (english));
notmuch-value_range_processor = new Xapian::NumberValueRangeProcessor 
(NOTMUCH_VALUE_TIMESTAMP);
+   notmuch-mtime_value_range_processor = new 
Xapian::NumberValueRangeProcessor (NOTMUCH_VALUE_MTIME, mtime:);
 
notmuch-query_parser-set_default_op (Xapian::Query::OP_AND);
notmuch-query_parser-set_database (*notmuch-xapian_db);
notmuch-query_parser-set_stemmer (Xapian::Stem (english));
notmuch-query_parser-set_stemming_strategy 
(Xapian::QueryParser::STEM_SOME);
notmuch-query_parser-add_valuerangeprocessor 
(notmuch-value_range_processor);
+   notmuch-query_parser-add_valuerangeprocessor 
(notmuch-mtime_value_range_processor);
 
for (i = 0; i  ARRAY_SIZE (BOOLEAN_PREFIX_EXTERNAL); i++) {
prefix_t *prefix = BOOLEAN_PREFIX_EXTERNAL[i];
@@ -726,6 +728,7 @@ notmuch_database_close (notmuch_database_t *notmuch)
 delete notmuch-query_parser;
 delete notmuch-xapian_db;
 delete notmuch-value_range_processor;
+delete notmuch-mtime_value_range_processor;
 talloc_free (notmuch);
 }
 
diff --git a/notmuch.1 b/notmuch.1
index 3dbd67e..2235096 100644
--- a/notmuch.1
+++ b/notmuch.1
@@ -644,6 +644,8 @@ terms to match against specific portions of an email, (where
 
folder:directory-path
 
+   mtime:timestamp-range
+
 The
 .B from:
 prefix is used to match the name or address of the sender of an email
@@ -707,8 +709,8 @@ operators, but will have to be protected from 
interpretation by the
 shell, (such as by putting quotation marks around any parenthesized
 expression).
 
-Finally, results can be restricted to only messages within a
-particular time range, (based on the Date: header) with a syntax of:
+Results can be restricted to only messages within a particular time range,
+(based on the Date: header) with a syntax of:
 
initial-timestamp..final-timestamp
 
@@ -721,6 +723,14 @@ specify a date range to return messages from 2009\-10\-01 
until the
 current time:
 
$(date +%s \-d 2009\-10\-01)..$(date +%s)
+
+Finally, the
+.B mtime:
+prefix can be used to search for messages which were modified (e.g. tags were
+added or removed) within a particular time range, with the same syntax as
+before:
+
+   mtime:initial-timestamp..final-timestamp
 .SH HOOKS
 Hooks are scripts (or arbitrary executables or symlinks to such) that notmuch
 invokes before and after certain actions. These scripts reside in
diff --git a/notmuch.c b/notmuch.c
index c0ce026..443cf59 100644
--- a/notmuch.c
+++ b/notmuch.c
@@ -71,6 +71,7 @@ static const char search_terms_help[] =
 \t\tid:message-id\n
 \t\tthread:thread-id\n
 \t\tfolder:directory-path\n
+\t\tmtime:timestamp-range\n
 \n
 \tThe from: prefix is used to match the name or address of\n
 \tthe sender of an email message.\n
@@ -112,8 +113,8 @@ static const char search_terms_help[] =
 \tinterpretation by the shell, (such as by putting quotation\n
 \tmarks around any parenthesized expression).\n
 \n
-\tFinally, results can be restricted to only messages within a\n
-\tparticular time range, (based on the Date: header) with:\n
+\tResults can be restricted to only messages within a particular\n
+\ttime range, (based on the Date: header) with:\n
 \n
 \t\tintial-timestamp..final-timestamp\n
 \n
@@ -125,7 +126,13 @@ static const char search_terms_help[] =
 \tfollowing syntax would specify a date range to return messages\n
 \tfrom 2009-10-01 until the current time:\n
 \n
-\t\t$(date +%%s -d 2009-10-01)..$(date +%%s)\n\n;
+\t\t$(date +%%s -d 2009-10-01)..$(date +%%s)\n\n
+\n
+\tFinally, the mtime: prefix can be used to search for messages\n
+\twhich were modified (e.g. tags were added or removed) within a\n
+\tparticular time range, with the same syntax as before:\n
+\n
+

[PATCH 4/5] show: include mtime in JSON output

2011-12-13 Thread Thomas Jost
This could be used by a UI implementation somehow.
---
 notmuch-show.c |7 ---
 1 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/notmuch-show.c b/notmuch-show.c
index 873a7c4..7279601 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -202,17 +202,18 @@ format_message_json (const void *ctx, notmuch_message_t 
*message, unused (int in
 notmuch_tags_t *tags;
 int first = 1;
 void *ctx_quote = talloc_new (ctx);
-time_t date;
+time_t date, mtime;
 const char *relative_date;
 
 date = notmuch_message_get_date (message);
 relative_date = notmuch_time_relative_date (ctx, date);
+mtime = notmuch_message_get_mtime (message);
 
-printf (\id\: %s, \match\: %s, \filename\: %s, \timestamp\: %ld, 
\date_relative\: \%s\, \tags\: [,
+printf (\id\: %s, \match\: %s, \filename\: %s, \timestamp\: %ld, 
\date_relative\: \%s\, \mtime\: %ld, \tags\: [,
json_quote_str (ctx_quote, notmuch_message_get_message_id 
(message)),
notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH) ? 
true : false,
json_quote_str (ctx_quote, notmuch_message_get_filename (message)),
-   date, relative_date);
+   date, relative_date, mtime);
 
 for (tags = notmuch_message_get_tags (message);
 notmuch_tags_valid (tags);
-- 
1.7.8

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH 5/5] python: add get_mtime() to the Message class

2011-12-13 Thread Thomas Jost
---
 bindings/python/notmuch/message.py |   20 
 1 files changed, 20 insertions(+), 0 deletions(-)

diff --git a/bindings/python/notmuch/message.py 
b/bindings/python/notmuch/message.py
index ce8e718..56f56c2 100644
--- a/bindings/python/notmuch/message.py
+++ b/bindings/python/notmuch/message.py
@@ -293,6 +293,10 @@ class Message(object):
 _get_date.argtypes = [NotmuchMessageP]
 _get_date.restype = c_long
 
+_get_mtime = nmlib.notmuch_message_get_mtime
+_get_mtime.argtypes = [NotmuchMessageP]
+_get_mtime.restype = c_long
+
 _get_header = nmlib.notmuch_message_get_header
 _get_header.argtypes = [NotmuchMessageP, c_char_p]
 _get_header.restype = c_char_p
@@ -401,6 +405,22 @@ class Message(object):
 raise NotmuchError(STATUS.NOT_INITIALIZED)
 return Message._get_date(self._msg)
 
+def get_mtime(self):
+Returns time_t of the message mtime
+
+The mtime is the timestamp of the last time the message was modified,
+e.g. the time it was added to the database or the last time a tag was
+added or removed.
+
+:returns: A time_t timestamp.
+:rtype: c_unit64
+:exception: :exc:`NotmuchError` STATUS.NOT_INITIALIZED if the message
+is not initialized.
+
+if self._msg is None:
+raise NotmuchError(STATUS.NOT_INITIALIZED)
+return Message._get_mtime(self._msg)
+
 def get_header(self, header):
 Get the value of the specified header.
 
-- 
1.7.8

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH v3 0/4] Several minor Emacs enhancements

2011-12-13 Thread Thomas Jost
Hi David et al.,

Here is a rebased version of this patch series, with more descriptive
commit messages.

Please tell me if there are still ways to enhance them. English is not
my native language and it's sometimes hard to figure out what's relevant
and how to word it :)

Best regards,
Thomas

Thomas Jost (4):
  emacs: Let the user choose where to compose new mails
  emacs: Add a face for crypto parts headers
  emacs: rename notmuch-decimal-separator to
notmuch-thousands-separator
  emacs: add notmuch-hello-hook

 emacs/notmuch-crypto.el |5 +
 emacs/notmuch-hello.el  |   17 -
 emacs/notmuch-mua.el|   40 ++--
 emacs/notmuch-show.el   |4 ++--
 4 files changed, 57 insertions(+), 9 deletions(-)

-- 
1.7.8

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH v3 1/4] emacs: Let the user choose where to compose new mails

2011-12-13 Thread Thomas Jost
Reusing the current window to compose a new mail may be troublesome for the
user. This patch introduces a new customizable variable, notmuch-mua-compose-in,
which lets the user choose where to create the mail buffer: in the current
window (current and default behaviour), in a new window, or in a new frame.
---
 emacs/notmuch-mua.el |   40 ++--
 1 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/emacs/notmuch-mua.el b/emacs/notmuch-mua.el
index 8824b08..90834d6 100644
--- a/emacs/notmuch-mua.el
+++ b/emacs/notmuch-mua.el
@@ -31,6 +31,21 @@
   :group 'notmuch
   :type 'hook)
 
+(defcustom notmuch-mua-compose-in 'current-window
+  Where to create the mail buffer used to compose a new message.
+  Possible values are `current-window' (default), `new-window'
+  and `new-frame'. If set to `current-window', the mail buffer
+  will be displayed in the current window, so the old buffer will
+  be restored when the mail buffer is killed. If set to
+  `new-window' or `new-frame', the mail buffer will be displayed
+  in a new window/frame that will be destroyed when the buffer is
+  killed. You may want to customize `message-kill-buffer-on-exit'
+  accordingly.
+  :group 'notmuch
+  :type '(choice (const :tag Compose in the current window current-window)
+(const :tag Compose mail in a new window  new-window)
+(const :tag Compose mail in a new frame   new-frame)))
+
 (defcustom notmuch-mua-user-agent-function 'notmuch-mua-user-agent-full
   Function used to generate a `User-Agent:' string. If this is
 `nil' then no `User-Agent:' will be generated.
@@ -48,6 +63,23 @@ list.
 
 ;;
 
+(defun notmuch-mua-get-switch-function ()
+  Get a switch function according to `notmuch-mua-compose-in'.
+  (cond ((eq notmuch-mua-compose-in 'current-window)
+'switch-to-buffer)
+   ((eq notmuch-mua-compose-in 'new-window)
+'switch-to-buffer-other-window)
+   ((eq notmuch-mua-compose-in 'new-frame)
+'switch-to-buffer-other-frame)
+   (t (error Invalid value for `notmuch-mua-compose-in'
+
+(defun notmuch-mua-maybe-set-window-dedicated ()
+  Set the selected window as dedicated according to
+`notmuch-mua-compose-in'.
+  (when (or (eq notmuch-mua-compose-in 'new-frame)
+   (eq notmuch-mua-compose-in 'new-window))
+(set-window-dedicated-p (selected-window) t)))
+
 (defun notmuch-mua-user-agent-full ()
   Generate a `User-Agent:' string suitable for notmuch.
   (concat (notmuch-mua-user-agent-notmuch)
@@ -99,7 +131,8 @@ list.
((same-window-regexps '(\\*mail .*)))
   (notmuch-mua-mail (mail-header 'to headers)
(mail-header 'subject headers)
-   (message-headers-to-generate headers t '(to subject
+   (message-headers-to-generate headers t '(to subject))
+   nil (notmuch-mua-get-switch-function)))
 ;; insert the message body - but put it in front of the signature
 ;; if one is present
 (goto-char (point-max))
@@ -112,6 +145,7 @@ list.
   (message-goto-body))
 
 (defun notmuch-mua-forward-message ()
+  (funcall (notmuch-mua-get-switch-function) (current-buffer))
   (message-forward)
 
   (when notmuch-mua-user-agent-function
@@ -121,6 +155,7 @@ list.
   (message-sort-headers)
   (message-hide-headers)
   (set-buffer-modified-p nil)
+  (notmuch-mua-maybe-set-window-dedicated)
 
   (message-goto-to))
 
@@ -143,6 +178,7 @@ list.
   (message-sort-headers)
   (message-hide-headers)
   (set-buffer-modified-p nil)
+  (notmuch-mua-maybe-set-window-dedicated)
 
   (message-goto-to))
 
@@ -199,7 +235,7 @@ the From: address first.
   (let ((other-headers
 (when (or prompt-for-sender notmuch-always-prompt-for-sender)
   (list (cons 'from (notmuch-mua-prompt-for-sender))
-(notmuch-mua-mail nil nil other-headers)))
+(notmuch-mua-mail nil nil other-headers nil 
(notmuch-mua-get-switch-function
 
 (defun notmuch-mua-new-forward-message (optional prompt-for-sender)
   Invoke the notmuch message forwarding window.
-- 
1.7.8

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH v3 3/4] emacs: rename notmuch-decimal-separator to notmuch-thousands-separator

2011-12-13 Thread Thomas Jost
In 123,456.78, . is the decimal separator, but , is the thousands separator.

This commit also mentions the space being used as thousands separator in several
European countries.
---
 emacs/notmuch-hello.el |8 
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el
index 0582cae..0fe9c1d 100644
--- a/emacs/notmuch-hello.el
+++ b/emacs/notmuch-hello.el
@@ -131,10 +131,10 @@ So:
  (integer :tag Number of characters)
  (float :tag Fraction of window)))
 
-(defcustom notmuch-decimal-separator ,
-  The string used as a decimal separator.
+(defcustom notmuch-thousands-separator ,
+  The string used as a thousands separator.
 
-Typically \,\ in the US and UK and \.\ in Europe.
+Typically \,\ in the US and UK and \.\ or \ \ in Europe.
   :group 'notmuch
   :type 'string)
 
@@ -159,7 +159,7 @@ Typically \,\ in the US and UK and \.\ in Europe.
 (apply #'concat
  (number-to-string (car result))
  (mapcar (lambda (elem)
- (format %s%03d notmuch-decimal-separator elem))
+ (format %s%03d notmuch-thousands-separator elem))
 (cdr result)
 
 (defun notmuch-hello-trim (search)
-- 
1.7.8

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH v3 2/4] emacs: Add a face for crypto parts headers

2011-12-13 Thread Thomas Jost
Commit cb841878 introduced new parts handlers for crypto parts, but also
hardcoded values for their headers face. This replaces these hardcoded values
with a customizable face.
---
 emacs/notmuch-crypto.el |5 +
 emacs/notmuch-show.el   |4 ++--
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/emacs/notmuch-crypto.el b/emacs/notmuch-crypto.el
index 44fccae..67c26af 100644
--- a/emacs/notmuch-crypto.el
+++ b/emacs/notmuch-crypto.el
@@ -37,6 +37,11 @@ mode.
   :group 'notmuch
   :type 'boolean)
 
+(defface notmuch-crypto-part-header
+  '((t (:foreground blue)))
+  Face used for crypto parts headers.
+  :group 'notmuch)
+
 (defface notmuch-crypto-signature-good
   '((t (:background green :foreground black)))
   Face used for good signatures.
diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 33ee3d8..ec9c52c 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -457,7 +457,7 @@ current buffer, if possible.
 
 (defun notmuch-show-insert-part-multipart/signed (msg part content-type nth 
depth declared-type)
   (let ((button (notmuch-show-insert-part-header nth declared-type 
content-type nil)))
-(button-put button 'face '(:foreground blue))
+(button-put button 'face 'notmuch-crypto-part-header)
 ;; add signature status button if sigstatus provided
 (if (plist-member part :sigstatus)
(let* ((from (notmuch-show-get-header :From msg))
@@ -479,7 +479,7 @@ current buffer, if possible.
 
 (defun notmuch-show-insert-part-multipart/encrypted (msg part content-type nth 
depth declared-type)
   (let ((button (notmuch-show-insert-part-header nth declared-type 
content-type nil)))
-(button-put button 'face '(:foreground blue))
+(button-put button 'face 'notmuch-crypto-part-header)
 ;; add encryption status button if encstatus specified
 (if (plist-member part :encstatus)
(let ((encstatus (car (plist-get part :encstatus
-- 
1.7.8

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH 2/2] test: use python2 instead of python if available

2011-12-07 Thread Thomas Jost
Some distros (Arch Linux) ship Python as python2 and Python 3 as python.
Checking for python2 is necessary for the Python tests to work on these
platforms.
---
 test/test-lib.sh |9 -
 1 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/test/test-lib.sh b/test/test-lib.sh
index 519bd84..155ad3c 100644
--- a/test/test-lib.sh
+++ b/test/test-lib.sh
@@ -923,8 +923,14 @@ test_python() {
export LD_LIBRARY_PATH=$TEST_DIRECTORY/../lib
export PYTHONPATH=$TEST_DIRECTORY/../bindings/python

+   # Some distros (e.g. Arch Linux) ship Python 2.* as /usr/bin/python2,
+   # most others as /usr/bin/python. So first try python2, and fallback to
+   # python if python2 doesn't exist.
+   cmd=python2
+   [[ "$test_missing_external_prereq_python2_" = t ]] && cmd=python
+
(echo "import sys; _orig_stdout=sys.stdout; sys.stdout=open('OUTPUT', 
'w')"; cat) \
-   | python -
+   | $cmd -
 }

 test_reset_state_ () {
@@ -1157,3 +1163,4 @@ test_declare_external_prereq emacsclient
 test_declare_external_prereq gdb
 test_declare_external_prereq gpg
 test_declare_external_prereq python
+test_declare_external_prereq python2
-- 
1.7.8



[PATCH 1/2] test: add a function to run Python tests

2011-12-07 Thread Thomas Jost
The new test_python() function makes writing Python tests a little easier:
- it sets the environment variables as needed
- it redirects stdout to the OUTPUT file (like test_emacs()).

This commit also declares python as an external prereq.

The stdout redirection is required to avoid trouble when running commands like
"python 'script' | sort > OUTPUT": in such a case, any error due to a missing
external prereq would be "swallowed" by sort, resulting to a failed test instead
of a skipped one.
---
 test/python  |6 ++
 test/test-lib.sh |9 +
 2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/test/python b/test/python
index f737749..c3aa726 100755
--- a/test/python
+++ b/test/python
@@ -5,9 +5,7 @@ test_description="python bindings"
 add_email_corpus

 test_begin_subtest "compare thread ids"
-LD_LIBRARY_PATH=$TEST_DIRECTORY/../lib \
-PYTHONPATH=$TEST_DIRECTORY/../bindings/python \
-python < OUTPUT
+test_python < EXPECTED
-test_expect_equal_file OUTPUT EXPECTED
+test_expect_equal_file <(sort OUTPUT) EXPECTED
 test_done
diff --git a/test/test-lib.sh b/test/test-lib.sh
index a975957..519bd84 100644
--- a/test/test-lib.sh
+++ b/test/test-lib.sh
@@ -919,6 +919,14 @@ test_emacs () {
emacsclient --socket-name="$EMACS_SERVER" --eval "(progn $@)"
 }

+test_python() {
+   export LD_LIBRARY_PATH=$TEST_DIRECTORY/../lib
+   export PYTHONPATH=$TEST_DIRECTORY/../bindings/python
+
+   (echo "import sys; _orig_stdout=sys.stdout; sys.stdout=open('OUTPUT', 
'w')"; cat) \
+   | python -
+}
+
 test_reset_state_ () {
test -z "$test_init_done_" && test_init_

@@ -1148,3 +1156,4 @@ test_declare_external_prereq emacs
 test_declare_external_prereq emacsclient
 test_declare_external_prereq gdb
 test_declare_external_prereq gpg
+test_declare_external_prereq python
-- 
1.7.8



[PATCH 2/2] test: use python2 instead of python if available

2011-12-07 Thread Thomas Jost
Some distros (Arch Linux) ship Python as python2 and Python 3 as python.
Checking for python2 is necessary for the Python tests to work on these
platforms.
---
 test/test-lib.sh |9 -
 1 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/test/test-lib.sh b/test/test-lib.sh
index 519bd84..155ad3c 100644
--- a/test/test-lib.sh
+++ b/test/test-lib.sh
@@ -923,8 +923,14 @@ test_python() {
export LD_LIBRARY_PATH=$TEST_DIRECTORY/../lib
export PYTHONPATH=$TEST_DIRECTORY/../bindings/python
 
+   # Some distros (e.g. Arch Linux) ship Python 2.* as /usr/bin/python2,
+   # most others as /usr/bin/python. So first try python2, and fallback to
+   # python if python2 doesn't exist.
+   cmd=python2
+   [[ $test_missing_external_prereq_python2_ = t ]]  cmd=python
+
(echo import sys; _orig_stdout=sys.stdout; sys.stdout=open('OUTPUT', 
'w'); cat) \
-   | python -
+   | $cmd -
 }
 
 test_reset_state_ () {
@@ -1157,3 +1163,4 @@ test_declare_external_prereq emacsclient
 test_declare_external_prereq gdb
 test_declare_external_prereq gpg
 test_declare_external_prereq python
+test_declare_external_prereq python2
-- 
1.7.8

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH] python: use wrapped notmuch_*_t types instead of raw pointers

2011-12-06 Thread Thomas Jost
Now that types are checked correctly, we also need to make sure that all the
arguments actually are instances of these types. Otherwise the function calls
will fail and raise an exception similar to this one:
   ctypes.ArgumentError: argument 3: : expected
   LP_LP_NotmuchMessageS instance instead of pointer to c_void_p
---
 bindings/python/notmuch/database.py |6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/bindings/python/notmuch/database.py 
b/bindings/python/notmuch/database.py
index 25b4b1b..c24555e 100644
--- a/bindings/python/notmuch/database.py
+++ b/bindings/python/notmuch/database.py
@@ -378,7 +378,7 @@ class Database(object):
   be added.
 """
 self._assert_db_is_initialized()
-msg_p = c_void_p()
+msg_p = NotmuchMessageP()
 status = self._add_message(self._db, _str(filename), byref(msg_p))

 if not status in [STATUS.SUCCESS, STATUS.DUPLICATE_MESSAGE_ID]:
@@ -446,7 +446,7 @@ class Database(object):
 the database was not intitialized.
 """
 self._assert_db_is_initialized()
-msg_p = c_void_p()
+msg_p = NotmuchMessageP()
 status = Database._find_message(self._db, _str(msgid), byref(msg_p))
 if status != STATUS.SUCCESS:
 raise NotmuchError(status)
@@ -479,7 +479,7 @@ class Database(object):

 *Added in notmuch 0.9*"""
 self._assert_db_is_initialized()
-msg_p = c_void_p()
+msg_p = NotmuchMessageP()
 status = Database._find_message_by_filename(self._db, _str(filename),
 byref(msg_p))
 if status != STATUS.SUCCESS:
-- 
1.7.7.4



[PATCH] python: use wrapped notmuch_*_t types instead of raw pointers

2011-12-06 Thread Thomas Jost
Now that types are checked correctly, we also need to make sure that all the
arguments actually are instances of these types. Otherwise the function calls
will fail and raise an exception similar to this one:
   ctypes.ArgumentError: argument 3: type 'exceptions.TypeError': expected
   LP_LP_NotmuchMessageS instance instead of pointer to c_void_p
---
 bindings/python/notmuch/database.py |6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/bindings/python/notmuch/database.py 
b/bindings/python/notmuch/database.py
index 25b4b1b..c24555e 100644
--- a/bindings/python/notmuch/database.py
+++ b/bindings/python/notmuch/database.py
@@ -378,7 +378,7 @@ class Database(object):
   be added.
 
 self._assert_db_is_initialized()
-msg_p = c_void_p()
+msg_p = NotmuchMessageP()
 status = self._add_message(self._db, _str(filename), byref(msg_p))
 
 if not status in [STATUS.SUCCESS, STATUS.DUPLICATE_MESSAGE_ID]:
@@ -446,7 +446,7 @@ class Database(object):
 the database was not intitialized.
 
 self._assert_db_is_initialized()
-msg_p = c_void_p()
+msg_p = NotmuchMessageP()
 status = Database._find_message(self._db, _str(msgid), byref(msg_p))
 if status != STATUS.SUCCESS:
 raise NotmuchError(status)
@@ -479,7 +479,7 @@ class Database(object):
 
 *Added in notmuch 0.9*
 self._assert_db_is_initialized()
-msg_p = c_void_p()
+msg_p = NotmuchMessageP()
 status = Database._find_message_by_filename(self._db, _str(filename),
 byref(msg_p))
 if status != STATUS.SUCCESS:
-- 
1.7.7.4

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH 0/6] Rebase of Pieter's "set test prereqs"

2011-11-17 Thread Thomas Jost
On Wed, 16 Nov 2011 21:50:17 +0100, Pieter Praet  wrote:
> On Wed, 16 Nov 2011 15:33:49 +0100, Thomas Jost  
> wrote:
> > Hello list,
> > 
> > This is another rebased version of Pieter's series to add GPG and Emacs as 
> > test
> > prereqs, plus some additions on my own. (Rebased and posted as requested by
> > Pieter [1].)
> > 
> 
> Thanks Thomas!
> 
> Although... you may have misread (or maybe I mistyped :), but what I
> actually intended [1] was for you to rebase *only* your fixes on top of
> my rebased series (e.g. see "tjost-fixes.patch" in att), so you could
> receive proper credit for cleaning up my mess.

Oh, ok, I must have misread that :) 

Right now your patches don't apply cleanly on master (conflict in patch
3 due to commit 5964a7), and I think that Dmitry's patches [1] may be a
better way to handle prereqs. So I probably won't send those patches
until we decide which approach is the way to go.

[1] id:"1321494986-18998-1-git-send-email-dmitry.kurochkin at gmail.com"

> Also, while my apprehension [2,3] re the inclusion of the SCREEN/DTACH
> prereq in patches #4,5,6 didn't have much merit (it's an all-or-nothing
> affair anyways), the issue [3] in patch #5 @ "Reply within emacs" still
> stands: `sed' will run unconditionally, and treat "EMACS" as an input
> file.  (see "sed-prereq-fix.patch" in att).

Nice catch with this sed issue. Looks like I need to be more careful
when replacing "OUTPUT" with "EMACS OUTPUT"...

Thanks,

-- 
Thomas/Schnouki
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 489 bytes
Desc: not available
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/2017/91b8f782/attachment.pgp>


[PATCH 0/9] test: (hopefully) better test prerequisites

2011-11-17 Thread Thomas Jost
On Thu, 17 Nov 2011 05:56:17 +0400, Dmitry Kurochkin  wrote:
> Hi all.
> 
> The following patch series is an attempt to introduce proper
> dependencies for external binaries in a less intrusive way than
> [1].  The primary aim was to avoid changing every subtest that
> uses external binaries.
> 
> There are still failing tests if a dependency is
> missing (e.g. "Verify that sent messages are
> saved/searchable (via FCC)" fails if there is no emacs).  It
> happens because such tests depend on others which are skipped.
> This issues are not addressed by this patch series.
> 
> If others do like the approach and it is pushed, I will work on
> updating tests that use the old style prerequisites (atomicity).
> 
> A careful review is needed!
> 
> Regards,
>   Dmitry
> 
> [1] id:"1321454035-22023-1-git-send-email-schnouki at schnouki.net"

Hi Dmitry,

This series looks quite good to me. It's a good approach, cleaner than
explicitely adding the prereqs to each test as in my previous patches
(and Pieter's).

Now, a few questions:

- same as Jamie: emacs_deliver_message hangs if dtach is not installed.
  In my patches I had to do this: "test_have_prereq EMACS &&
  emacs_deliver_message ...". Any idea how to handle this?

- what about indirect, "hidden" dependencies? The crypto test need to
  have a signed message delivered by emacs, so actually *all* the crypto
  tests depend on emacs. Right now, when dtach is not installed, the
  first test ("emacs delivery of signed message") is skipped and all the
  others fail. Would it be possible to handle this case without having
  to add explicit prereqs?

- right now functions like test_expect_success can be used as
  "test_expect_success COMMAND" or "test_expect_success PREREQ COMMAND".
  If we use your approach (and I hope we will!), do we need to keep that
  second syntax available in test-lib.sh too, or should we do some
  cleanup to get rid of it?

Thanks,

-- 
Thomas/Schnouki
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 489 bytes
Desc: not available
URL: 



  1   2   3   >