[notmuch] keeping a copy of sent mail locally

2009-12-19 Thread Keith Packard
On Sun, 20 Dec 2009 15:29:15 +1100, Alex Ghitza  wrote:

> Good.  So we can put this in notmuch.el and Keith will get everybody's
> sent mail. :)

That seems sub-optimal, at least for me...

> It looks like we need a way to get the primary email address from the
> config file.

We actually want to let the user *select* an email address from the
config file, and then automagically set the bcc: flag as
appropriate. Without that, I'd end up bcc'ing all of my mail through my
home address, which would end up sending work email unencrypted to my
house. Sub-optimal

> (setq user-full-name "Alex Ghitza")
> (setq user-mail-address "aghitza at gmail.com")

You can set everything in the message-mail argument list:

(message-mail nil nil '(("bcc" "keith.packard at intel.com") ("from" "Keith 
Packard ")))

Alternatively, we can hack up message mode so that when the From address
is set (using completion from the notmuch config), the Bcc line is copied.

-- 
keith.packard at intel.com
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20091219/4241bcf9/attachment.pgp>


[notmuch] keeping a copy of sent mail locally

2009-12-19 Thread Keith Packard
On Sat, 19 Dec 2009 18:37:12 -0800, Carl Worth  wrote:

> So we need to figure out how to configure (or hook) that
> to insert the Bcc, and then we can fix notmuch.el to do this without any
> user configuration.

Just call:

(message-mail nil nil '(("bcc" "keithp at keithp.com")))

instead of (message-mail)

-- 
keith.packard at intel.com
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20091219/bbb80ae2/attachment.pgp>


[notmuch] keeping a copy of sent mail locally

2009-12-19 Thread Carl Worth
On Sun, 20 Dec 2009 11:24:52 +1100, Alex Ghitza  wrote:
> However, if I'm using notmuch in emacs and press 'm' to compose a new
> message, then the Bcc header is not added automatically and I guess it's
> not surprising that the rest doesn't work as expected.

Yeah, sorry about that. That's a known bug.

> So where is the difference between 'm' and 'r' coming from?

The difference is that 'r' actually runs the "notmuch reply" command and
that command explicitly puts your own address into the Bcc. So this is
happening outside of any emacs code.

When you hit 'm', though, there's not any notmuch code involved,
(neither C code, nor emacs lisp), as it's currently just running
`message-mail'. So we need to figure out how to configure (or hook) that
to insert the Bcc, and then we can fix notmuch.el to do this without any
user configuration.

> I have (setq mail-self-blind t)  in my .emacs, and I thought that should take
> care of things, but it obviously doesn't.

Ah, interesting.

I'm guessing that that variable would apply to the "mail" mode stuff in
emacs, but perhaps not the "message" mode stuff we're using.

Yes, emacs mail support is a huge pile of very similar, but incompatible
systems.

Hopefully someone can fix this soon, since I really don't like the fact
that I'm currently not getting copies of several messages that I'm
composing and sending.

-Carl
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20091219/682e4f96/attachment.pgp>


[notmuch] keeping a copy of sent mail locally

2009-12-19 Thread Alex Ghitza

Hello,

Many thanks to Marten and Carl for the advice on using scripts for
assigning tags automatically.  It works like a charm.

The next hurdle seems to be dealing with sent mail.  I would like each
message that I send to be saved in my local mail folder and treated the
same as all my other messages -- so it will get indexed and put in the
right thread, etc.  (For example, right now the thread that started with
my question about automatic tags only has the two replies in it, and its
subject is "Re: [notmuch] automatically...")  Bcc-ing myself on every
sent message is suboptimal for a number of reasons: (1) gmail throws
away the bcc-ed copy since it has the same message id as the one sitting
in the gmail sent mail, and so the bcc-ed copy never makes it back to my
local mail;  (2) even if this was working, it would be an unnecessary
waste of bandwidth. 

After looking around for a little bit, the only other option I could see
was to use the FCC mail header.  Unfortunately this wants a filename to
save to (rather than just a directory); so I have to manually add the
FCC: header, put in a filename that doesn't yet exist, type 'y' to
confirm that I want the file to be created.  It would be great if I
could just set the directory where sent mail should go to as a global
option, and then everything would happen automatically without any more
effort from me.

I realise that this is more of an emacs question than a notmuch
question, but I'm hoping that somebody on this list has an elegant
solution to this.


Best,
Alex


-- 
Alex Ghitza -- Lecturer in Mathematics -- The University of Melbourne
-- Australia -- http://www.ms.unimelb.edu.au/~aghitza/


[notmuch] [PATCH] Add ENVIRONMENT VARIABLES section to the man page

2009-12-19 Thread James Westby
Briefly describe the NOTMUCH_CONFIG variable there.
---

  It turns out that it is documented in notmuch help setup, but I
  missed it.

  I'm not sure how to phrase it to fit at the end of notmuch help,
  suggestions welcome. For now I added a traditional ENVIRONMENT
  VARIABLES section to the man page.

  Thanks,

  James

 notmuch.1 |4 
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/notmuch.1 b/notmuch.1
index 369ecba..f304404 100644
--- a/notmuch.1
+++ b/notmuch.1
@@ -432,6 +432,10 @@ specify a date range to return messages from 2009-10-01 
until the
 current time:

$(date +%s -d 2009-10-01)..$(date +%s)
+.SH ENVIRONMENT VARIABLES
+.IP NOTMUCH_CONFIG
+Specifies the location of the configuration file to override the default of
+.IR ~/.notmuch-config .
 .SH SEE ALSO
 The emacs-based interface to notmuch (available as
 .B notmuch.el
-- 
1.6.3.3



[notmuch] [PATCH 3/3] notmuch-show.c: prototype tabular output format, with output control

2009-12-19 Thread da...@tethera.net
From: David Bremner 

Currently this only outputs the information from the "message header";
i.e. the part before the rfc2822 header or body.

Adding this required adding an extra parameter, currently unused, to
format_message_text and format_message_json. Also the struct
definition is changed to match the new function prototypes.

An int (enum) is used as a mask, each bit corresponds to some part to
be shown or not shown.  This enum will need to be extended as more
things are controllable via --show.
---
 notmuch-show.c |   89 ---
 1 files changed, 77 insertions(+), 12 deletions(-)

diff --git a/notmuch-show.c b/notmuch-show.c
index 51aa87d..99a4d3c 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -20,10 +20,18 @@

 #include "notmuch-client.h"

+/* These should be powers of 2 */
+typedef enum {SHOW_MESSAGE_ID = 1, 
+ SHOW_MATCH = 2, 
+ SHOW_FILENAME = 4
+} show_mask_t;
+
+static const show_mask_t SHOW_ALL = ~0;
+
 typedef struct show_format {
 const char *message_set_start;
 const char *message_start;
-void (*message) (const void *ctx,
+void (*message) (const void *ctx, show_mask_t show_mask,
 notmuch_message_t *message,
 int indent);
 const char *header_start;
@@ -40,7 +48,7 @@ typedef struct show_format {
 } show_format_t;

 static void
-format_message_text (unused (const void *ctx),
+format_message_text (unused (const void *ctx), show_mask_t show_mask,
 notmuch_message_t *message,
 int indent);
 static void
@@ -59,7 +67,21 @@ static const show_format_t format_text = {
 };

 static void
-format_message_json (const void *ctx,
+format_message_tabular (unused (const void *ctx), show_mask_t show_mask,
+notmuch_message_t *message,
+int indent);
+
+static const show_format_t format_tabular = {
+"", 
+"", format_message_tabular, 
+"", NULL, "", 
+"", NULL, "",
+"\n", "", 
+""
+};
+
+static void
+format_message_json (const void *ctx, show_mask_t show_mask,
 notmuch_message_t *message,
 unused (int indent));
 static void
@@ -124,7 +146,30 @@ _get_one_line_summary (const void *ctx, notmuch_message_t 
*message)
 }

 static void
-format_message_text (unused (const void *ctx), notmuch_message_t *message, int 
indent)
+format_message_tabular (unused (const void *ctx), show_mask_t show_mask,
+   notmuch_message_t *message, 
+   unused(int indent))
+{
+int count=0;
+
+if (show_mask & SHOW_MESSAGE_ID) {
+   fputs ( notmuch_message_get_message_id (message), stdout);
+   count++;
+}
+
+if (show_mask & SHOW_MATCH) 
+   printf ("%s%d", count++ ? "\t" : "", 
+   notmuch_message_get_flag (message, 
+ NOTMUCH_MESSAGE_FLAG_MATCH));
+
+if (show_mask & SHOW_FILENAME) 
+   printf("%s%s", count++ ? "\t" : "", 
+  notmuch_message_get_filename (message));
+}
+
+static void
+format_message_text (unused (const void *ctx), unused(show_mask_t show_mask),
+notmuch_message_t *message, int indent)
 {
 printf ("id:%s depth:%d match:%d filename:%s\n",
notmuch_message_get_message_id (message),
@@ -134,7 +179,8 @@ format_message_text (unused (const void *ctx), 
notmuch_message_t *message, int i
 }

 static void
-format_message_json (const void *ctx, notmuch_message_t *message, unused (int 
indent))
+format_message_json (const void *ctx, unused(show_mask_t show_mask),
+notmuch_message_t *message, unused (int indent))
 {
 void *ctx_quote = talloc_new (ctx);

@@ -323,11 +369,12 @@ format_part_json (GMimeObject *part, int *part_count)
 }

 static void
-show_message (void *ctx, const show_format_t *format, notmuch_message_t 
*message, int indent)
+show_message (void *ctx, const show_format_t *format, show_mask_t show_mask,
+ notmuch_message_t *message, int indent)
 {
 fputs (format->message_start, stdout);
 if (format->message)
-   format->message(ctx, message, indent);
+   format->message(ctx, show_mask, message, indent);

 fputs (format->header_start, stdout);
 if (format->header) 
@@ -344,8 +391,8 @@ show_message (void *ctx, const show_format_t *format, 
notmuch_message_t *message


 static void
-show_messages (void *ctx, const show_format_t *format, notmuch_messages_t 
*messages, int indent,
-  notmuch_bool_t entire_thread)
+show_messages (void *ctx, const show_format_t *format,  show_mask_t show_mask, 
+  notmuch_messages_t *messages, int indent, notmuch_bool_t 
entire_thread)
 {
 notmuch_message_t *message;
 notmuch_bool_t match;
@@ -371,13 +418,14 @@ show_messages (void *ctx, const show_format_t *format, 
notmuch_messages_t *messa
next_indent = indent;

if 

[notmuch] [PATCH 2/3] notmuch-show.c: make calls to format functions conditional

2009-12-19 Thread da...@tethera.net
From: David Bremner 

This makes it easier to define minimal formats without defining several
dummy functions that do nothing.
---
 notmuch-show.c |   13 +
 1 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/notmuch-show.c b/notmuch-show.c
index b6e3f44..51aa87d 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -326,14 +326,17 @@ static void
 show_message (void *ctx, const show_format_t *format, notmuch_message_t 
*message, int indent)
 {
 fputs (format->message_start, stdout);
-format->message(ctx, message, indent);
+if (format->message)
+   format->message(ctx, message, indent);

 fputs (format->header_start, stdout);
-format->header(ctx, message);
+if (format->header) 
+   format->header(ctx, message);
 fputs (format->header_end, stdout);

 fputs (format->body_start, stdout);
-show_message_body (notmuch_message_get_filename (message), format->part);
+if (format->part) 
+   show_message_body (notmuch_message_get_filename (message), 
format->part);
 fputs (format->body_end, stdout);

 fputs (format->message_end, stdout);
@@ -408,7 +411,9 @@ notmuch_show_command (void *ctx, unused (int argc), unused 
(char *argv[]))
}
if (STRNCMP_LITERAL (argv[i], "--format=") == 0) {
opt = argv[i] + sizeof ("--format=") - 1;
-   if (strcmp (opt, "text") == 0) {
+   if (strcmp (opt, "tabular") == 0) {
+   format = _tabular;
+   } else if (strcmp (opt, "text") == 0) {
format = _text;
} else if (strcmp (opt, "json") == 0) {
format = _json;
-- 
1.6.5.3



[notmuch] [PATCH 1/3] rename option to select output format to --format from --output.

2009-12-19 Thread da...@tethera.net
From: David Bremner 

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

diff --git a/notmuch-search.c b/notmuch-search.c
index e243747..482c6e8 100644
--- a/notmuch-search.c
+++ b/notmuch-search.c
@@ -221,14 +221,14 @@ notmuch_search_command (void *ctx, int argc, char *argv[])
fprintf (stderr, "Invalid value for --sort: %s\n", opt);
return 1;
}
-   } else if (STRNCMP_LITERAL (argv[i], "--output=") == 0) {
-   opt = argv[i] + sizeof ("--output=") - 1;
+   } else if (STRNCMP_LITERAL (argv[i], "--format=") == 0) {
+   opt = argv[i] + sizeof ("--format=") - 1;
if (strcmp (opt, "text") == 0) {
format = _text;
} else if (strcmp (opt, "json") == 0) {
format = _json;
} else {
-   fprintf (stderr, "Invalid value for --output: %s\n", opt);
+   fprintf (stderr, "Invalid value for --format: %s\n", opt);
return 1;
}
} else {
diff --git a/notmuch-show.c b/notmuch-show.c
index b5b3eba..b6e3f44 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -406,15 +406,15 @@ notmuch_show_command (void *ctx, unused (int argc), 
unused (char *argv[]))
i++;
break;
}
-   if (STRNCMP_LITERAL (argv[i], "--output=") == 0) {
-   opt = argv[i] + sizeof ("--output=") - 1;
+   if (STRNCMP_LITERAL (argv[i], "--format=") == 0) {
+   opt = argv[i] + sizeof ("--format=") - 1;
if (strcmp (opt, "text") == 0) {
format = _text;
} else if (strcmp (opt, "json") == 0) {
format = _json;
entire_thread = 1;
} else {
-   fprintf (stderr, "Invalid value for --output: %s\n", opt);
+   fprintf (stderr, "Invalid value for --format: %s\n", opt);
return 1;
}
} else if (STRNCMP_LITERAL (argv[i], "--entire-thread") == 0) {
-- 
1.6.5.3



[notmuch] Prototype of --show option to control what is shown.

2009-12-19 Thread da...@tethera.net
Here is a set of 3 patches to implement (some) output control.  

[PATCH 1/3] rename option to select output format to --format from --output.
[PATCH 2/3] notmuch-show.c: make calls to format functions conditional

The first two are essentially suggestions for Scott.  In particular the first 
is not needed at all for this little experiment.

[PATCH 3/3] notmuch-show.c: prototype tabular output format, with output control

The third implements a new "tabular" output format, and shows how it
might be conditionally controlled.  At the moment the only
possibilities to output are message-id, match flag, and filename.
This is mainly a matter of laziness.  I didn't want to go too crazy
before Scott's reached some final(ish) version.




[notmuch] [PATCH] Store the size of the file for each message

2009-12-19 Thread Carl Worth
On Sat, 19 Dec 2009 09:02:11 +0100, Marten Veldthuis  
wrote:
> > Anyone have a solution here?
> 
> Something like "git help add" just opens the manpage for git-add. Can't
> we do the same here?

The granularity is different, though. I like that "notmuch help show"
shows just the documentation for "notmuch show". And I also like that
"man notmuch" shows all the documentation, (without having to have N
different man pages for each of the sub-commands).

Meanwhile, the git approach does mean that one doesn't get any "builtin"
help unless the external man-based stuff is working and installed. I'm
not sure that I want to depend on that.

-Carl
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20091219/e2e7ac71/attachment-0001.pgp>


[notmuch] [PATCH] Store the size of the file for each message

2009-12-19 Thread Marten Veldthuis
On Fri, 18 Dec 2009 21:24:10 -0800, Carl Worth  wrote:
> Currently we're replicating all of our documentation both in the man
> page and in the output from "notmuch help". It's annoying to have to
> add everything in two places, but I don't have a good idea for making
> that sharable yet.
> 
> Anyone have a solution here?

Something like "git help add" just opens the manpage for git-add. Can't
we do the same here?

-- 
- Marten


[notmuch] [PATCH] Fix-up some outdated comments.

2009-12-19 Thread James Westby
---
 lib/message.cc |6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/lib/message.cc b/lib/message.cc
index cc32741..7129d59 100644
--- a/lib/message.cc
+++ b/lib/message.cc
@@ -391,7 +391,7 @@ notmuch_message_get_replies (notmuch_message_t *message)
  * multiple filenames for email messages with identical message IDs.
  *
  * This change will not be reflected in the database until the next
- * call to _notmuch_message_set_sync. */
+ * call to _notmuch_message_sync. */
 void
 _notmuch_message_set_filename (notmuch_message_t *message,
   const char *filename)
@@ -622,7 +622,7 @@ _notmuch_message_close (notmuch_message_t *message)
  * names to prefix values.
  *
  * This change will not be reflected in the database until the next
- * call to _notmuch_message_set_sync. */
+ * call to _notmuch_message_sync. */
 notmuch_private_status_t
 _notmuch_message_add_term (notmuch_message_t *message,
   const char *prefix_name,
@@ -679,7 +679,7 @@ _notmuch_message_gen_terms (notmuch_message_t *message,
  * names to prefix values.
  *
  * This change will not be reflected in the database until the next
- * call to _notmuch_message_set_sync. */
+ * call to _notmuch_message_sync. */
 notmuch_private_status_t
 _notmuch_message_remove_term (notmuch_message_t *message,
  const char *prefix_name,
-- 
1.6.3.3



[notmuch] keeping a copy of sent mail locally

2009-12-19 Thread Jed Brown
On Sat, 19 Dec 2009 15:41:14 +1100, Alex Ghitza  wrote:
> Bcc-ing myself on every sent message is suboptimal for a number of
> reasons: (1) gmail throws away the bcc-ed copy since it has the same
> message id as the one sitting in the gmail sent mail, and so the
> bcc-ed copy never makes it back to my local mail;

I agree it is suboptimal, but are you sure this is true?  I send
messages via gmail and those having Bcc to me are marked as new and
downloaded by the next pass of getmail (via POP).

Jed


[notmuch] [PATCH] Store the size of the file for each message

2009-12-19 Thread James Westby
On Fri, 18 Dec 2009 16:57:16 -0800, Carl Worth  wrote:
> You can, actually. Just set the NOTMUCH_CONFIG environment variable to
> your alternate configuration file. (And yes, we're missing any mention
> of this in our documentation.)

Sweet. Where would be the best place to document it? Just in the
man page?

Thanks,

James


[notmuch] [PATCH] Reindex larger files that duplicate ids we have

2009-12-19 Thread James Westby
When we see a message where we already have the file
id stored, check if the size is larger. If it is then
re-index and set the file size and name to be the
new message.
---

  Here's the (quite simple) patch to implement indexing the
  largest copy of each mail that we have.

  Does the re-indexing replace the old terms? In the case
  where you had a collision with different text this could
  make a search return mails that don't contain that text.
  I don't think it's a big issue though, even if that is the
  case.

  Thanks,

  James

 lib/database.cc   |4 +++-
 lib/index.cc  |   27 +++
 lib/message.cc|   31 ++-
 lib/notmuch-private.h |   13 +
 lib/notmuch.h |5 +++--
 5 files changed, 72 insertions(+), 8 deletions(-)

diff --git a/lib/database.cc b/lib/database.cc
index d834d94..64f29b9 100644
--- a/lib/database.cc
+++ b/lib/database.cc
@@ -1000,7 +1000,9 @@ notmuch_database_add_message (notmuch_database_t *notmuch,
if (ret)
goto DONE;
} else {
-   ret = NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID;
+   ret = _notmuch_message_possibly_reindex (message, filename, size);
+   if (!ret)
+   ret = NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID;
goto DONE;
}

diff --git a/lib/index.cc b/lib/index.cc
index 125fa6c..14c3268 100644
--- a/lib/index.cc
+++ b/lib/index.cc
@@ -312,3 +312,30 @@ _notmuch_message_index_file (notmuch_message_t *message,

 return ret;
 }
+
+notmuch_status_t
+_notmuch_message_possibly_reindex (notmuch_message_t *message,
+const char *filename,
+const off_t size)
+{
+off_t realsize = size;
+off_t stored_size;
+notmuch_status_t ret = NOTMUCH_STATUS_SUCCESS;
+
+ret = _notmuch_message_size_on_disk (message, filename, );
+if (ret)
+goto DONE;
+stored_size = _notmuch_message_get_filesize (message);
+if (realsize > stored_size) {
+   ret = _notmuch_message_index_file (message, filename);
+   if (ret)
+   goto DONE;
+   ret = _notmuch_message_set_filesize (message, filename, realsize);
+   _notmuch_message_set_filename (message, filename);
+   _notmuch_message_sync (message);
+}
+
+  DONE:
+return ret;
+
+}
diff --git a/lib/message.cc b/lib/message.cc
index 2bfc5ed..cc32741 100644
--- a/lib/message.cc
+++ b/lib/message.cc
@@ -427,23 +427,38 @@ _notmuch_message_set_filename (notmuch_message_t *message,
 }

 notmuch_status_t
-_notmuch_message_set_filesize (notmuch_message_t *message,
+_notmuch_message_size_on_disk (notmuch_message_t *message,
   const char *filename,
-  const off_t size)
+  off_t *size)
 {
 struct stat st;
-off_t realsize = size;
 notmuch_status_t ret = NOTMUCH_STATUS_SUCCESS;

-if (realsize < 0) {
+if (*size < 0) {
if (stat (filename, )) {
ret = NOTMUCH_STATUS_FILE_ERROR;
goto DONE;
} else {
-   realsize = st.st_size;
+   *size = st.st_size;
}
 }

+  DONE:
+return ret;
+}
+
+notmuch_status_t
+_notmuch_message_set_filesize (notmuch_message_t *message,
+  const char *filename,
+  const off_t size)
+{
+off_t realsize = size;
+notmuch_status_t ret = NOTMUCH_STATUS_SUCCESS;
+
+ret = _notmuch_message_size_on_disk (message, filename, );
+if (ret)
+goto DONE;
+
 message->doc.add_value (NOTMUCH_VALUE_FILESIZE,
 Xapian::sortable_serialise (realsize));

@@ -451,6 +466,12 @@ _notmuch_message_set_filesize (notmuch_message_t *message,
 return ret;
 }

+off_t
+_notmuch_message_get_filesize (notmuch_message_t *message)
+{
+return Xapian::sortable_unserialise (message->doc.get_value 
(NOTMUCH_VALUE_FILESIZE));
+}
+
 const char *
 notmuch_message_get_filename (notmuch_message_t *message)
 {
diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h
index 1ba3055..cf65fd9 100644
--- a/lib/notmuch-private.h
+++ b/lib/notmuch-private.h
@@ -199,6 +199,14 @@ _notmuch_message_set_filesize (notmuch_message_t *message,
   const char *filename,
   const off_t size);

+off_t
+_notmuch_message_get_filesize (notmuch_message_t *message);
+
+notmuch_status_t
+_notmuch_message_size_on_disk (notmuch_message_t *message,
+  const char *filename,
+  off_t *size);
+
 void
 _notmuch_message_ensure_thread_id (notmuch_message_t *message);

@@ -218,6 +226,11 @@ notmuch_status_t
 _notmuch_message_index_file (notmuch_message_t *message,
 const char *filename);

+notmuch_status_t
+_notmuch_message_possibly_reindex (notmuch_message_t *message,
+const char *filename,
+ 

[notmuch] [PATCH v2] Store the size of the file for each message

2009-12-19 Thread James Westby
When indexing a message store the filesize along with it so that
when we store all the filenames for a message-id we can know if
any of them have different content cheaply.

The value stored is defined to be the largest filesize of any
of the files for that message.

This changes the API for efficiency reasons. The size is often
known to the caller, and so we save a second stat by asking them
to provide it. If they don't know it they can pass -1 and the
stat will be done for them.

We store the filesize such that we can query a range. Thus it
would be possible to query "filesize:0..100" if you somehow
knew the raw message was less that 100 bytes.
---

  With new, improved, working, filesize:.. search.

 lib/database.cc   |7 +++
 lib/message.cc|   25 +
 lib/notmuch-private.h |8 +++-
 lib/notmuch.h |5 +
 notmuch-new.c |2 +-
 5 files changed, 45 insertions(+), 2 deletions(-)

diff --git a/lib/database.cc b/lib/database.cc
index b6c4d07..d834d94 100644
--- a/lib/database.cc
+++ b/lib/database.cc
@@ -463,6 +463,8 @@ notmuch_database_open (const char *path,
 struct stat st;
 int err;
 unsigned int i;
+Xapian::NumberValueRangeProcessor *filesize_proc = new 
Xapian::NumberValueRangeProcessor (NOTMUCH_VALUE_FILESIZE,
+"filesize:", true);

 if (asprintf (_path, "%s/%s", path, ".notmuch") == -1) {
notmuch_path = NULL;
@@ -508,6 +510,7 @@ notmuch_database_open (const char *path,
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 (filesize_proc);

for (i = 0; i < ARRAY_SIZE (BOOLEAN_PREFIX_EXTERNAL); i++) {
prefix_t *prefix = _PREFIX_EXTERNAL[i];
@@ -889,6 +892,7 @@ _notmuch_database_link_message (notmuch_database_t *notmuch,
 notmuch_status_t
 notmuch_database_add_message (notmuch_database_t *notmuch,
  const char *filename,
+ const off_t size,
  notmuch_message_t **message_ret)
 {
 notmuch_message_file_t *message_file;
@@ -992,6 +996,9 @@ notmuch_database_add_message (notmuch_database_t *notmuch,
if (private_status == NOTMUCH_PRIVATE_STATUS_NO_DOCUMENT_FOUND) {
_notmuch_message_set_filename (message, filename);
_notmuch_message_add_term (message, "type", "mail");
+   ret = _notmuch_message_set_filesize (message, filename, size);
+   if (ret)
+   goto DONE;
} else {
ret = NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID;
goto DONE;
diff --git a/lib/message.cc b/lib/message.cc
index 49519f1..2bfc5ed 100644
--- a/lib/message.cc
+++ b/lib/message.cc
@@ -426,6 +426,31 @@ _notmuch_message_set_filename (notmuch_message_t *message,
 message->doc.set_data (s);
 }

+notmuch_status_t
+_notmuch_message_set_filesize (notmuch_message_t *message,
+  const char *filename,
+  const off_t size)
+{
+struct stat st;
+off_t realsize = size;
+notmuch_status_t ret = NOTMUCH_STATUS_SUCCESS;
+
+if (realsize < 0) {
+   if (stat (filename, )) {
+   ret = NOTMUCH_STATUS_FILE_ERROR;
+   goto DONE;
+   } else {
+   realsize = st.st_size;
+   }
+}
+
+message->doc.add_value (NOTMUCH_VALUE_FILESIZE,
+Xapian::sortable_serialise (realsize));
+
+  DONE:
+return ret;
+}
+
 const char *
 notmuch_message_get_filename (notmuch_message_t *message)
 {
diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h
index 116f63d..1ba3055 100644
--- a/lib/notmuch-private.h
+++ b/lib/notmuch-private.h
@@ -100,7 +100,8 @@ _internal_error (const char *format, ...) PRINTF_ATTRIBUTE 
(1, 2);

 typedef enum {
 NOTMUCH_VALUE_TIMESTAMP = 0,
-NOTMUCH_VALUE_MESSAGE_ID
+NOTMUCH_VALUE_MESSAGE_ID,
+NOTMUCH_VALUE_FILESIZE
 } notmuch_value_t;

 /* Xapian (with flint backend) complains if we provide a term longer
@@ -193,6 +194,11 @@ void
 _notmuch_message_set_filename (notmuch_message_t *message,
   const char *filename);

+notmuch_status_t
+_notmuch_message_set_filesize (notmuch_message_t *message,
+  const char *filename,
+  const off_t size);
+
 void
 _notmuch_message_ensure_thread_id (notmuch_message_t *message);

diff --git a/lib/notmuch.h b/lib/notmuch.h
index 60834fb..5d0d224 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -32,6 +32,7 @@
 NOTMUCH_BEGIN_DECLS

 #include 
+#include 

 #ifndef FALSE
 #define FALSE 0
@@ -241,6 +242,9 @@ notmuch_database_get_timestamp (notmuch_database_t 
*database,
  * notmuch database will reference the filename, and will not copy the
 

[notmuch] [PATCH] Store the size of the file for each message

2009-12-19 Thread James Westby
On Fri, 18 Dec 2009 14:29:21 -0800, Carl Worth  wrote:
> On Fri, 18 Dec 2009 21:21:03 +, James Westby  jameswestby.net> wrote:
> Yes, a value makes sense here and should make the value easy to
> retrieve.

Excellent.

> I usually use a little tool I wrote called xapian-dump. It currently
> exists only in the git history of notmuch. Look at commit:
> 
>   22691064666c03c5e76bc787395bfe586929f4cc
> 
> or so.

Thanks, I found delve, which at least showed that something was
being stored. It's in the xapian-tools package, and

   delve -V2 

prints out the filesize value for each document.

It would be great if we could specify an alternative configuration
file for testing so that I can set up a small maildir and test
against that.

> If the file size is just an integer, then you shouldn't need a custom
> ValueRangeProcessor. One of the existing processors in Xapian should
> work fine.

Correct, I hadn't read the documentation closely enough. After fixing
that and doing some testing I have this working now. Patch incoming.

Thanks,

James


Re: [notmuch] [PATCH] Store the size of the file for each message

2009-12-19 Thread Marten Veldthuis
On Fri, 18 Dec 2009 21:24:10 -0800, Carl Worth cwo...@cworth.org wrote:
 Currently we're replicating all of our documentation both in the man
 page and in the output from notmuch help. It's annoying to have to
 add everything in two places, but I don't have a good idea for making
 that sharable yet.
 
 Anyone have a solution here?

Something like git help add just opens the manpage for git-add. Can't
we do the same here?

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


Re: [notmuch] keeping a copy of sent mail locally

2009-12-19 Thread Jed Brown
On Sat, 19 Dec 2009 15:41:14 +1100, Alex Ghitza aghi...@gmail.com wrote:
 Bcc-ing myself on every sent message is suboptimal for a number of
 reasons: (1) gmail throws away the bcc-ed copy since it has the same
 message id as the one sitting in the gmail sent mail, and so the
 bcc-ed copy never makes it back to my local mail;

I agree it is suboptimal, but are you sure this is true?  I send
messages via gmail and those having Bcc to me are marked as new and
downloaded by the next pass of getmail (via POP).

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


[notmuch] Prototype of --show option to control what is shown.

2009-12-19 Thread david
Here is a set of 3 patches to implement (some) output control.  

[PATCH 1/3] rename option to select output format to --format from --output.
[PATCH 2/3] notmuch-show.c: make calls to format functions conditional

The first two are essentially suggestions for Scott.  In particular the first 
is not needed at all for this little experiment.

[PATCH 3/3] notmuch-show.c: prototype tabular output format, with output control

The third implements a new tabular output format, and shows how it
might be conditionally controlled.  At the moment the only
possibilities to output are message-id, match flag, and filename.
This is mainly a matter of laziness.  I didn't want to go too crazy
before Scott's reached some final(ish) version.


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


[notmuch] [PATCH 2/3] notmuch-show.c: make calls to format functions conditional

2009-12-19 Thread david
From: David Bremner brem...@unb.ca

This makes it easier to define minimal formats without defining several
dummy functions that do nothing.
---
 notmuch-show.c |   13 +
 1 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/notmuch-show.c b/notmuch-show.c
index b6e3f44..51aa87d 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -326,14 +326,17 @@ static void
 show_message (void *ctx, const show_format_t *format, notmuch_message_t 
*message, int indent)
 {
 fputs (format-message_start, stdout);
-format-message(ctx, message, indent);
+if (format-message)
+   format-message(ctx, message, indent);
 
 fputs (format-header_start, stdout);
-format-header(ctx, message);
+if (format-header) 
+   format-header(ctx, message);
 fputs (format-header_end, stdout);
 
 fputs (format-body_start, stdout);
-show_message_body (notmuch_message_get_filename (message), format-part);
+if (format-part) 
+   show_message_body (notmuch_message_get_filename (message), 
format-part);
 fputs (format-body_end, stdout);
 
 fputs (format-message_end, stdout);
@@ -408,7 +411,9 @@ notmuch_show_command (void *ctx, unused (int argc), unused 
(char *argv[]))
}
if (STRNCMP_LITERAL (argv[i], --format=) == 0) {
opt = argv[i] + sizeof (--format=) - 1;
-   if (strcmp (opt, text) == 0) {
+   if (strcmp (opt, tabular) == 0) {
+   format = format_tabular;
+   } else if (strcmp (opt, text) == 0) {
format = format_text;
} else if (strcmp (opt, json) == 0) {
format = format_json;
-- 
1.6.5.3

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


[notmuch] [PATCH 3/3] notmuch-show.c: prototype tabular output format, with output control

2009-12-19 Thread david
From: David Bremner brem...@unb.ca

Currently this only outputs the information from the message header;
i.e. the part before the rfc2822 header or body.

Adding this required adding an extra parameter, currently unused, to
format_message_text and format_message_json. Also the struct
definition is changed to match the new function prototypes.

An int (enum) is used as a mask, each bit corresponds to some part to
be shown or not shown.  This enum will need to be extended as more
things are controllable via --show.
---
 notmuch-show.c |   89 ---
 1 files changed, 77 insertions(+), 12 deletions(-)

diff --git a/notmuch-show.c b/notmuch-show.c
index 51aa87d..99a4d3c 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -20,10 +20,18 @@
 
 #include notmuch-client.h
 
+/* These should be powers of 2 */
+typedef enum {SHOW_MESSAGE_ID = 1, 
+ SHOW_MATCH = 2, 
+ SHOW_FILENAME = 4
+} show_mask_t;
+
+static const show_mask_t SHOW_ALL = ~0;
+
 typedef struct show_format {
 const char *message_set_start;
 const char *message_start;
-void (*message) (const void *ctx,
+void (*message) (const void *ctx, show_mask_t show_mask,
 notmuch_message_t *message,
 int indent);
 const char *header_start;
@@ -40,7 +48,7 @@ typedef struct show_format {
 } show_format_t;
 
 static void
-format_message_text (unused (const void *ctx),
+format_message_text (unused (const void *ctx), show_mask_t show_mask,
 notmuch_message_t *message,
 int indent);
 static void
@@ -59,7 +67,21 @@ static const show_format_t format_text = {
 };
 
 static void
-format_message_json (const void *ctx,
+format_message_tabular (unused (const void *ctx), show_mask_t show_mask,
+notmuch_message_t *message,
+int indent);
+
+static const show_format_t format_tabular = {
+, 
+, format_message_tabular, 
+, NULL, , 
+, NULL, ,
+\n, , 
+
+};
+
+static void
+format_message_json (const void *ctx, show_mask_t show_mask,
 notmuch_message_t *message,
 unused (int indent));
 static void
@@ -124,7 +146,30 @@ _get_one_line_summary (const void *ctx, notmuch_message_t 
*message)
 }
 
 static void
-format_message_text (unused (const void *ctx), notmuch_message_t *message, int 
indent)
+format_message_tabular (unused (const void *ctx), show_mask_t show_mask,
+   notmuch_message_t *message, 
+   unused(int indent))
+{
+int count=0;
+
+if (show_mask  SHOW_MESSAGE_ID) {
+   fputs ( notmuch_message_get_message_id (message), stdout);
+   count++;
+}
+
+if (show_mask  SHOW_MATCH) 
+   printf (%s%d, count++ ? \t : , 
+   notmuch_message_get_flag (message, 
+ NOTMUCH_MESSAGE_FLAG_MATCH));
+
+if (show_mask  SHOW_FILENAME) 
+   printf(%s%s, count++ ? \t : , 
+  notmuch_message_get_filename (message));
+}
+
+static void
+format_message_text (unused (const void *ctx), unused(show_mask_t show_mask),
+notmuch_message_t *message, int indent)
 {
 printf (id:%s depth:%d match:%d filename:%s\n,
notmuch_message_get_message_id (message),
@@ -134,7 +179,8 @@ format_message_text (unused (const void *ctx), 
notmuch_message_t *message, int i
 }
 
 static void
-format_message_json (const void *ctx, notmuch_message_t *message, unused (int 
indent))
+format_message_json (const void *ctx, unused(show_mask_t show_mask),
+notmuch_message_t *message, unused (int indent))
 {
 void *ctx_quote = talloc_new (ctx);
 
@@ -323,11 +369,12 @@ format_part_json (GMimeObject *part, int *part_count)
 }
 
 static void
-show_message (void *ctx, const show_format_t *format, notmuch_message_t 
*message, int indent)
+show_message (void *ctx, const show_format_t *format, show_mask_t show_mask,
+ notmuch_message_t *message, int indent)
 {
 fputs (format-message_start, stdout);
 if (format-message)
-   format-message(ctx, message, indent);
+   format-message(ctx, show_mask, message, indent);
 
 fputs (format-header_start, stdout);
 if (format-header) 
@@ -344,8 +391,8 @@ show_message (void *ctx, const show_format_t *format, 
notmuch_message_t *message
 
 
 static void
-show_messages (void *ctx, const show_format_t *format, notmuch_messages_t 
*messages, int indent,
-  notmuch_bool_t entire_thread)
+show_messages (void *ctx, const show_format_t *format,  show_mask_t show_mask, 
+  notmuch_messages_t *messages, int indent, notmuch_bool_t 
entire_thread)
 {
 notmuch_message_t *message;
 notmuch_bool_t match;
@@ -371,13 +418,14 @@ show_messages (void *ctx, const show_format_t *format, 
notmuch_messages_t *messa
next_indent = indent;
 
if (match || entire_thread) {
- 

Re: [notmuch] [PATCH] Store the size of the file for each message

2009-12-19 Thread Carl Worth
On Sat, 19 Dec 2009 09:02:11 +0100, Marten Veldthuis mar...@veldthuis.com 
wrote:
  Anyone have a solution here?
 
 Something like git help add just opens the manpage for git-add. Can't
 we do the same here?

The granularity is different, though. I like that notmuch help show
shows just the documentation for notmuch show. And I also like that
man notmuch shows all the documentation, (without having to have N
different man pages for each of the sub-commands).

Meanwhile, the git approach does mean that one doesn't get any builtin
help unless the external man-based stuff is working and installed. I'm
not sure that I want to depend on that.

-Carl


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


Re: [notmuch] keeping a copy of sent mail locally

2009-12-19 Thread Alex Ghitza
On Sat, 19 Dec 2009 02:55:16 -0800, Jed Brown j...@59a2.org wrote:
 On Sat, 19 Dec 2009 15:41:14 +1100, Alex Ghitza aghi...@gmail.com wrote:
  Bcc-ing myself on every sent message is suboptimal for a number of
  reasons: (1) gmail throws away the bcc-ed copy since it has the same
  message id as the one sitting in the gmail sent mail, and so the
  bcc-ed copy never makes it back to my local mail;
 
 I agree it is suboptimal, but are you sure this is true?  I send
 messages via gmail and those having Bcc to me are marked as new and
 downloaded by the next pass of getmail (via POP).
 

Aha!  Your reply prodded me to investigate this further.  The problem
seems to be in the way I'm working with the emacs Message mode.
Namely, Bcc works fine when I *reply* to a message from notmuch in
emacs: while composing the reply I see the automatically added Bcc
header, and after sending through gmail and getting the new mail via POP
I get the message back. 

However, if I'm using notmuch in emacs and press 'm' to compose a new
message, then the Bcc header is not added automatically and I guess it's
not surprising that the rest doesn't work as expected.

So where is the difference between 'm' and 'r' coming from?  I have
(setq mail-self-blind t)  in my .emacs, and I thought that should take
care of things, but it obviously doesn't.


Best,
Alex

-- 
Alex Ghitza -- Lecturer in Mathematics -- The University of Melbourne
-- Australia -- http://www.ms.unimelb.edu.au/~aghitza/
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [notmuch] keeping a copy of sent mail locally

2009-12-19 Thread Carl Worth
On Sun, 20 Dec 2009 11:24:52 +1100, Alex Ghitza aghi...@gmail.com wrote:
 However, if I'm using notmuch in emacs and press 'm' to compose a new
 message, then the Bcc header is not added automatically and I guess it's
 not surprising that the rest doesn't work as expected.

Yeah, sorry about that. That's a known bug.

 So where is the difference between 'm' and 'r' coming from?

The difference is that 'r' actually runs the notmuch reply command and
that command explicitly puts your own address into the Bcc. So this is
happening outside of any emacs code.

When you hit 'm', though, there's not any notmuch code involved,
(neither C code, nor emacs lisp), as it's currently just running
`message-mail'. So we need to figure out how to configure (or hook) that
to insert the Bcc, and then we can fix notmuch.el to do this without any
user configuration.

 I have (setq mail-self-blind t)  in my .emacs, and I thought that should take
 care of things, but it obviously doesn't.

Ah, interesting.

I'm guessing that that variable would apply to the mail mode stuff in
emacs, but perhaps not the message mode stuff we're using.

Yes, emacs mail support is a huge pile of very similar, but incompatible
systems.

Hopefully someone can fix this soon, since I really don't like the fact
that I'm currently not getting copies of several messages that I'm
composing and sending.

-Carl


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


Re: [notmuch] keeping a copy of sent mail locally

2009-12-19 Thread Alex Ghitza
On Sat, 19 Dec 2009 18:50:17 -0800, Keith Packard kei...@keithp.com wrote:
 On Sat, 19 Dec 2009 18:37:12 -0800, Carl Worth cwo...@cworth.org wrote:
 
  So we need to figure out how to configure (or hook) that
  to insert the Bcc, and then we can fix notmuch.el to do this without any
  user configuration.
 
 Just call:
 
 (message-mail nil nil '((bcc kei...@keithp.com)))
 
 instead of (message-mail)
 

Good.  So we can put this in notmuch.el and Keith will get everybody's
sent mail. :)

It looks like we need a way to get the primary email address from the
config file.  Actually, while we're at it, we can consider making this
more flexible and adding a new option to the config file (e.g. bcc=...)
which would take a semicolon-separated list of email addresses (in case
someone wants to always bcc an address other than the primary one).

Is there a nice clean way of getting the config variables in notmuch.el?
Or should this go into a new file notmuch-compose.c?  Note that the
latter would imply having a new command like notmuch compose.

Ah, I just realised there's another issue related to the fact that 'm'
immediately defers to Message mode while 'r' does some preprocessing:
after pressing 'r', various headers are set in the appropriate manner
(From:, for instance, using the user name and email address from the
config file).  If you press 'm', you would get something like

From: ghi...@artin.i-did-not-set--mail-host-address--so-tickle-me

due to the fact that Message mode doesn't know the name or the email
address.  This can be fixed by adding to .emacs something like

(setq user-full-name Alex Ghitza)
(setq user-mail-address aghi...@gmail.com)

It's not a big deal, but now the same thing must be set in two different
places (.notmuch-config and .emacs), and can lead to confusion if, say,
the user changes their primary email address in one place but forgets it
needs to also be changed in the other.  So I guess I would prefer it if
notmuch would do a very minimal amount of preprocessing before heading
into Message mode when composing mail.  In fact, we could make sure that
there is consistent behaviour between 'm' and 'r' by making notmuch
compose return a few preset headers (From:, Bcc:, whatever else is
deemed appropriate), and making notmuch reply call notmuch compose
first and then add the reply-specific content.

Sorry about writing a lot of prose and no code!  I'd like to get a sense
for people's reactions before trying to write a patch for this.


Best,
Alex


-- 
Alex Ghitza -- Lecturer in Mathematics -- The University of Melbourne
-- Australia -- http://www.ms.unimelb.edu.au/~aghitza/
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [notmuch] keeping a copy of sent mail locally

2009-12-19 Thread Keith Packard
On Sun, 20 Dec 2009 15:29:15 +1100, Alex Ghitza aghi...@gmail.com wrote:

 Good.  So we can put this in notmuch.el and Keith will get everybody's
 sent mail. :)

That seems sub-optimal, at least for me...

 It looks like we need a way to get the primary email address from the
 config file.

We actually want to let the user *select* an email address from the
config file, and then automagically set the bcc: flag as
appropriate. Without that, I'd end up bcc'ing all of my mail through my
home address, which would end up sending work email unencrypted to my
house. Sub-optimal

 (setq user-full-name Alex Ghitza)
 (setq user-mail-address aghi...@gmail.com)

You can set everything in the message-mail argument list:

(message-mail nil nil '((bcc keith.pack...@intel.com) (from Keith 
Packard keith.pack...@intel.com)))

Alternatively, we can hack up message mode so that when the From address
is set (using completion from the notmuch config), the Bcc line is copied.

-- 
keith.pack...@intel.com


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