unofficial mirror of notmuch@notmuchmail.org
 help / color / mirror / code / Atom feed
* [PATCH 1/2] Add 'cat' subcommand
@ 2010-04-20  7:16 Michal Sojka
  2010-04-20  7:16 ` [PATCH 2/2] emacs: Access raw messages through cat subcommand Michal Sojka
  2010-04-20  7:21 ` [PATCH 1/2] Add 'cat' subcommand David Edmondson
  0 siblings, 2 replies; 16+ messages in thread
From: Michal Sojka @ 2010-04-20  7:16 UTC (permalink / raw)
  To: notmuch

This command dumps a raw message identified by a filename to the
standard output. It allows MUAs to access the messages for piping,
attachment manipulation, etc. in the same way as it is done in
notmuch-show-mode (through notmuch show subcommand). This will simplify
the MUAs when they need to operate with a remote database.

Signed-off-by: Michal Sojka <sojkam1@fel.cvut.cz>
---
 NEWS             |    3 +++
 notmuch-client.h |    3 +++
 notmuch-show.c   |   39 +++++++++++++++++++++++++++++++++++++++
 notmuch.c        |    4 ++++
 4 files changed, 49 insertions(+), 0 deletions(-)

diff --git a/NEWS b/NEWS
index eba0fd5..1a81e64 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,6 @@
+A new subcommand 'cat' was added, which simplifies use of Emacs
+interface with remote database (accessed over SSH).
+
 Notmuch 0.2 (2010-04-16)
 ========================
 This is the second release of the notmuch mail system, with actual
diff --git a/notmuch-client.h b/notmuch-client.h
index d36b9ec..0efc41c 100644
--- a/notmuch-client.h
+++ b/notmuch-client.h
@@ -111,6 +111,9 @@ int
 notmuch_search_tags_command (void *ctx, int argc, char *argv[]);
 
 int
+notmuch_cat_command (void *ctx, int argc, char *argv[]);
+
+int
 notmuch_part_command (void *ctx, int argc, char *argv[]);
 
 const char *
diff --git a/notmuch-show.c b/notmuch-show.c
index 76873a1..bade9bb 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -504,6 +504,45 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[]))
 }
 
 int
+notmuch_cat_command (void *ctx, unused (int argc), unused (char *argv[]))
+{
+    int i;
+    FILE *file;
+    const char *filename;
+    size_t size;
+    char buf[4096];
+
+    (void)ctx;
+
+    for (i = 0; i < argc && argv[i][0] == '-'; i++) {
+	fprintf (stderr, "Unrecognized option: %s\n", argv[i]);
+	return 1;
+    }
+
+    argc -= i;
+    argv += i;
+
+    if (argc == 0) {
+	fprintf (stderr, "Error: No filename given\n");
+	return 1;
+    }
+    filename = argv[0];
+
+    file = fopen (filename, "r");
+    if (file == NULL) {
+	fprintf (stderr, "Error: Cannot open %s: %s\n", filename, strerror (errno));
+	return 1;
+    }
+    while  (!feof (file)) {
+	size = fread(buf, 1, sizeof(buf), file);
+	fwrite (buf, size, 1, stdout);
+    }
+    fclose (file);
+
+    return 0;
+}
+
+int
 notmuch_part_command (void *ctx, unused (int argc), unused (char *argv[]))
 {
 	notmuch_config_t *config;
diff --git a/notmuch.c b/notmuch.c
index 0eea5e1..477d746 100644
--- a/notmuch.c
+++ b/notmuch.c
@@ -296,6 +296,10 @@ command_t commands[] = {
       "\tcontain tags only from messages that match the search-term(s).\n"
       "\n"
       "\tIn both cases the list will be alphabetically sorted." },
+    { "cat", notmuch_cat_command,
+      "<path>",
+      "Dump raw message identified by path to standard output.",
+      "" },
     { "part", notmuch_part_command,
       "--part=<num> <search-terms>",
       "Output a single MIME part of a message.",
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 2/2] emacs: Access raw messages through cat subcommand
  2010-04-20  7:16 [PATCH 1/2] Add 'cat' subcommand Michal Sojka
@ 2010-04-20  7:16 ` Michal Sojka
  2010-04-20  7:21 ` [PATCH 1/2] Add 'cat' subcommand David Edmondson
  1 sibling, 0 replies; 16+ messages in thread
From: Michal Sojka @ 2010-04-20  7:16 UTC (permalink / raw)
  To: notmuch

The following commands now access the messages via the cat subcommand:
view/save attachments, view raw message and pipe message to command.

With this patch, it is straightforward to use notmuch emacs interface
with a remote database accessed over SSH. To do this, it is sufficient
to redefine notmuch-command variable to contain the name of a script
containing:

    ssh user@host notmuch "$@"

If the ssh client has enabled connection sharing (ControlMaster option
in OpenSSH), the emacs interface is almost as responsive as with local
invocation.

Signed-off-by: Michal Sojka <sojkam1@fel.cvut.cz>
---
 emacs/notmuch-show.el |   11 ++++++++---
 1 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 81276d9..29a726e 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -328,7 +328,11 @@ buffer."
 (defun notmuch-show-view-raw-message ()
   "View the raw email of the current message."
   (interactive)
-  (view-file (notmuch-show-get-filename)))
+  (let ((filename (notmuch-show-get-filename)))
+    (let ((buf (get-buffer-create (concat "*notmuch-raw-" filename "*"))))
+      (switch-to-buffer buf)
+      (save-excursion
+	(call-process notmuch-command nil t nil "cat" filename)))))
 
 (defmacro with-current-notmuch-show-message (&rest body)
   "Evaluate body with current buffer set to the text of current message"
@@ -336,7 +340,7 @@ buffer."
      (let ((filename (notmuch-show-get-filename)))
        (let ((buf (generate-new-buffer (concat "*notmuch-msg-" filename "*"))))
          (with-current-buffer buf
-           (insert-file-contents filename nil nil nil t)
+	    (call-process notmuch-command nil t nil "cat" filename)
            ,@body)
 	 (kill-buffer buf)))))
 
@@ -390,7 +394,8 @@ current email message as stdin. Anything printed by the command
 to stdout or stderr will appear in the *Messages* buffer."
   (interactive "sPipe message to command: ")
   (apply 'start-process-shell-command "notmuch-pipe-command" "*notmuch-pipe*"
-	 (list command " < " (shell-quote-argument (notmuch-show-get-filename)))))
+	 (list notmuch-command "cat"
+	       (shell-quote-argument (notmuch-show-get-filename)) " | " command)))
 
 (defun notmuch-show-move-to-current-message-summary-line ()
   "Move to the beginning of the one-line summary of the current message.
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH 1/2] Add 'cat' subcommand
  2010-04-20  7:16 [PATCH 1/2] Add 'cat' subcommand Michal Sojka
  2010-04-20  7:16 ` [PATCH 2/2] emacs: Access raw messages through cat subcommand Michal Sojka
@ 2010-04-20  7:21 ` David Edmondson
  2010-04-20  8:09   ` Sebastian Spaeth
  1 sibling, 1 reply; 16+ messages in thread
From: David Edmondson @ 2010-04-20  7:21 UTC (permalink / raw)
  To: Michal Sojka, notmuch

On Tue, 20 Apr 2010 09:16:32 +0200, Michal Sojka <sojkam1@fel.cvut.cz> wrote:
> This command dumps a raw message identified by a filename to the
> standard output. It allows MUAs to access the messages for piping,
> attachment manipulation, etc. in the same way as it is done in
> notmuch-show-mode (through notmuch show subcommand). This will simplify
> the MUAs when they need to operate with a remote database.

I'm puzzled why you chose to pass a filename as the argument to 'cat'
rather than a message id (id:foo@bar.com)?

Removing knowledge of filenames (or that anything is stored as a file)
from the UI seems like a good idea.

dme.
-- 
David Edmondson, http://dme.org

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 1/2] Add 'cat' subcommand
  2010-04-20  7:21 ` [PATCH 1/2] Add 'cat' subcommand David Edmondson
@ 2010-04-20  8:09   ` Sebastian Spaeth
  2010-04-20 10:14     ` Michal Sojka
  0 siblings, 1 reply; 16+ messages in thread
From: Sebastian Spaeth @ 2010-04-20  8:09 UTC (permalink / raw)
  To: David Edmondson, Michal Sojka, notmuch

> I'm puzzled why you chose to pass a filename as the argument to 'cat'
> rather than a message id (id:foo@bar.com)?

I agree, especially as some people want to introduce abstract mailstores
which might not even have the concept of a file name :).

Passing a message-id seems more useful.

Sebastian

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 1/2] Add 'cat' subcommand
  2010-04-20  8:09   ` Sebastian Spaeth
@ 2010-04-20 10:14     ` Michal Sojka
  2010-04-20 10:53       ` David Edmondson
                         ` (2 more replies)
  0 siblings, 3 replies; 16+ messages in thread
From: Michal Sojka @ 2010-04-20 10:14 UTC (permalink / raw)
  To: Sebastian Spaeth; +Cc: notmuch

On 20.4.2010 09:21, David Edmondson wrote:
 > On Tue, 20 Apr 2010 09:16:32 +0200, Michal Sojka<sojkam1@fel.cvut.cz> 
  wrote:
 >> This command dumps a raw message identified by a filename to the
 >> standard output. It allows MUAs to access the messages for piping,
 >> attachment manipulation, etc. in the same way as it is done in
 >> notmuch-show-mode (through notmuch show subcommand). This will simplify
 >> the MUAs when they need to operate with a remote database.
 >
 > I'm puzzled why you chose to pass a filename as the argument to 'cat'
 > rather than a message id (id:foo@bar.com)?

The reason is that I want be able to distinguish between several 
messages with the same id. Consider a message sent to a list. One copy 
is stored in your sent folder and one in another folder. You may want to 
investigate the Received headers the latter message. You would not be 
happy if, after pressing 'V', notmuch shows you the message in sent 
folder without any headers.

The same holds for pipe command. I think that the message you pipe to 
some command should be exactly the same you see in your client.

On 20.4.2010 10:09, Sebastian Spaeth wrote:
> I agree, especially as some people want to introduce abstract mailstores
> which might not even have the concept of a file name :).

OK, maybe file name is not the proper name for it :-). In my abstract 
mail stores, I use the "file name" just as an unique identifier of the 
message.

Michal

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 1/2] Add 'cat' subcommand
  2010-04-20 10:14     ` Michal Sojka
@ 2010-04-20 10:53       ` David Edmondson
  2010-04-20 11:13         ` Michal Sojka
  2010-04-20 13:32       ` Jameson Rollins
  2010-04-22  0:44       ` Carl Worth
  2 siblings, 1 reply; 16+ messages in thread
From: David Edmondson @ 2010-04-20 10:53 UTC (permalink / raw)
  To: Michal Sojka, Sebastian Spaeth; +Cc: notmuch

On Tue, 20 Apr 2010 12:14:56 +0200, Michal Sojka <sojkam1@fel.cvut.cz> wrote:
>  > I'm puzzled why you chose to pass a filename as the argument to 'cat'
>  > rather than a message id (id:foo@bar.com)?
> 
> The reason is that I want be able to distinguish between several
> messages with the same id.

It strikes me that notmuch is not well suited to this in general. For
example, how would you find the filenames for the two messages with the
same message id?

dme.
-- 
David Edmondson, http://dme.org

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 1/2] Add 'cat' subcommand
  2010-04-20 10:53       ` David Edmondson
@ 2010-04-20 11:13         ` Michal Sojka
  2010-04-20 11:30           ` David Edmondson
  0 siblings, 1 reply; 16+ messages in thread
From: Michal Sojka @ 2010-04-20 11:13 UTC (permalink / raw)
  To: David Edmondson, Sebastian Spaeth; +Cc: notmuch

On Tue, 20 Apr 2010, David Edmondson wrote:
> On Tue, 20 Apr 2010 12:14:56 +0200, Michal Sojka <sojkam1@fel.cvut.cz> wrote:
> >  > I'm puzzled why you chose to pass a filename as the argument to 'cat'
> >  > rather than a message id (id:foo@bar.com)?
> > 
> > The reason is that I want be able to distinguish between several
> > messages with the same id.
> 
> It strikes me that notmuch is not well suited to this in general. For
> example, how would you find the filenames for the two messages with the
> same message id?

Currently, it is probably not possible but I can imagine that "notmuch
show" will output all file names associated with the message id and user
could select between them if he needs.

M.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 1/2] Add 'cat' subcommand
  2010-04-20 11:13         ` Michal Sojka
@ 2010-04-20 11:30           ` David Edmondson
  0 siblings, 0 replies; 16+ messages in thread
From: David Edmondson @ 2010-04-20 11:30 UTC (permalink / raw)
  To: Michal Sojka, Sebastian Spaeth; +Cc: notmuch

On Tue, 20 Apr 2010 13:13:36 +0200, Michal Sojka <sojkam1@fel.cvut.cz> wrote:
> On Tue, 20 Apr 2010, David Edmondson wrote:
> > On Tue, 20 Apr 2010 12:14:56 +0200, Michal Sojka <sojkam1@fel.cvut.cz> wrote:
> > >  > I'm puzzled why you chose to pass a filename as the argument to 'cat'
> > >  > rather than a message id (id:foo@bar.com)?
> > > 
> > > The reason is that I want be able to distinguish between several
> > > messages with the same id.
> > 
> > It strikes me that notmuch is not well suited to this in general. For
> > example, how would you find the filenames for the two messages with the
> > same message id?
> 
> Currently, it is probably not possible but I can imagine that "notmuch
> show" will output all file names associated with the message id and user
> could select between them if he needs.

If the filenames are really 'unique message identifiers' and may not
work when passed to open(2), then I don't have a problem.

dme.
-- 
David Edmondson, http://dme.org

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 1/2] Add 'cat' subcommand
  2010-04-20 10:14     ` Michal Sojka
  2010-04-20 10:53       ` David Edmondson
@ 2010-04-20 13:32       ` Jameson Rollins
  2010-04-22  0:44       ` Carl Worth
  2 siblings, 0 replies; 16+ messages in thread
From: Jameson Rollins @ 2010-04-20 13:32 UTC (permalink / raw)
  To: Michal Sojka, Sebastian Spaeth; +Cc: notmuch

[-- Attachment #1: Type: text/plain, Size: 1027 bytes --]

On Tue, 20 Apr 2010 12:14:56 +0200, Michal Sojka <sojkam1@fel.cvut.cz> wrote:
> The reason is that I want be able to distinguish between several 
> messages with the same id. Consider a message sent to a list. One copy 
> is stored in your sent folder and one in another folder. You may want to 
> investigate the Received headers the latter message. You would not be 
> happy if, after pressing 'V', notmuch shows you the message in sent 
> folder without any headers.

I think this is actually a problem with notmuch, and something that I
have complained about in the past.  It was previously dismissed, but I
still think that it's something we should address.  Notmuch should not
irrevocably hide messages, just because they cursorily look like a
another similar but distinct message.

What are ways that we can avoid this?  Could notmuch append a string to
the message id in the database for the different messages that share an
id?  Something like "id:foo@bar.com{0}", "id:foo@bar.com{1}", etc?

jamie.

[-- Attachment #2: Type: application/pgp-signature, Size: 835 bytes --]

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 1/2] Add 'cat' subcommand
  2010-04-20 10:14     ` Michal Sojka
  2010-04-20 10:53       ` David Edmondson
  2010-04-20 13:32       ` Jameson Rollins
@ 2010-04-22  0:44       ` Carl Worth
  2010-04-22  2:37         ` Dirk Hohndel
  2010-04-22  6:38         ` Michal Sojka
  2 siblings, 2 replies; 16+ messages in thread
From: Carl Worth @ 2010-04-22  0:44 UTC (permalink / raw)
  To: Michal Sojka, Sebastian Spaeth; +Cc: notmuch

[-- Attachment #1: Type: text/plain, Size: 1061 bytes --]

On Tue, 20 Apr 2010 12:14:56 +0200, Michal Sojka <sojkam1@fel.cvut.cz> wrote:
> On 20.4.2010 09:21, David Edmondson wrote:
>  > I'm puzzled why you chose to pass a filename as the argument to 'cat'
>  > rather than a message id (id:foo@bar.com)?
> 
> The reason is that I want be able to distinguish between several 
> messages with the same id.

All other commands currently accept the generic search terms to specify
messages, (even a command like "notmuch reply" for which it would have
been natural to accept only a single message).

So I'd prefer to have this command behave just like all others and use
the same naming.

The question of how to unambiguously refer to a single file is
orthogonal, (and similarly applies to all commands, such as "notmuch
tag" etc.). I would recommend supporting a search syntax something like:

	filename:/complete/path/to/file

for that use case. And this should work fine whether the filenames are
actual filenames or keys into some abstract file store of some sort.

What do you think?

-Carl

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 1/2] Add 'cat' subcommand
  2010-04-22  0:44       ` Carl Worth
@ 2010-04-22  2:37         ` Dirk Hohndel
  2010-04-22  3:13           ` Anthony Towns
  2010-04-22  6:38         ` Michal Sojka
  1 sibling, 1 reply; 16+ messages in thread
From: Dirk Hohndel @ 2010-04-22  2:37 UTC (permalink / raw)
  To: Carl Worth, Michal Sojka, Sebastian Spaeth; +Cc: notmuch

On Wed, 21 Apr 2010 17:44:03 -0700, Carl Worth <cworth@cworth.org> wrote:
> On Tue, 20 Apr 2010 12:14:56 +0200, Michal Sojka <sojkam1@fel.cvut.cz> wrote:
> > On 20.4.2010 09:21, David Edmondson wrote:
> >  > I'm puzzled why you chose to pass a filename as the argument to 'cat'
> >  > rather than a message id (id:foo@bar.com)?
> > 
> > The reason is that I want be able to distinguish between several 
> > messages with the same id.
> 
> All other commands currently accept the generic search terms to specify
> messages, (even a command like "notmuch reply" for which it would have
> been natural to accept only a single message).
> 
> So I'd prefer to have this command behave just like all others and use
> the same naming.
> 
> The question of how to unambiguously refer to a single file is
> orthogonal, (and similarly applies to all commands, such as "notmuch
> tag" etc.). I would recommend supporting a search syntax something like:
> 
> 	filename:/complete/path/to/file

should we extend this to something generic that allows remote
specifications? 

URI:file/path/to/local/file
URI:ssh/user@host/path/to/file
URI:git/user@host/path/to/file

or even (yikes)

URI:ftp/user@host/path/to/file
 
I'm using '/' to separate components, assuming that ':' should be used
only for keywords in the search syntax - if the parser is flexible
enough we could of course use the standard URI syntax instead
http://en.wikipedia.org/wiki/URI_scheme#Generic_syntax

foo://username:password@example.com:8042/over/there/index.dtb?type=animal;name=ferret#nose

That would allow to encode the query in a standard way in the remote
syntax... 

/D

-- 
Dirk Hohndel
Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 1/2] Add 'cat' subcommand
  2010-04-22  2:37         ` Dirk Hohndel
@ 2010-04-22  3:13           ` Anthony Towns
  2010-04-22  6:57             ` Michal Sojka
  0 siblings, 1 reply; 16+ messages in thread
From: Anthony Towns @ 2010-04-22  3:13 UTC (permalink / raw)
  To: Dirk Hohndel; +Cc: notmuch

On Thu, Apr 22, 2010 at 12:37, Dirk Hohndel <hohndel@infradead.org> wrote:
> On Wed, 21 Apr 2010 17:44:03 -0700, Carl Worth <cworth@cworth.org> wrote:
>> So I'd prefer to have this command behave just like all others and use
>> the same naming.
>>       filename:/complete/path/to/file

Would "notmuch cat" be any different to "notmuch show" in this case?
What happens if you say "notmuch cat something" and multiple messages
match (eg, an id: for a mail that you both sent (Mail/.sent/cur/12345)
and received (Mail/.Lists.notmuch/cur/12346))?

Maybe notmuch show should be able to deal with all these things, and
notmuch cat could be an alias for something like:

    notmuch show --format=mbox --show-duplicate-files $SPEC

?

> should we extend this to something generic that allows remote
> specifications?
> URI:file/path/to/local/file
> URI:ssh/user@host/path/to/file
> URI:git/user@host/path/to/file

You could already do that by using FUSE filesystems to mount your
remote mail dirs under those paths, without having to teach notmuch
about those protocols, as long as you still have the Xapian database
local.

If the Xapian database is remote, you need to invoke "ssh $USER@$HOST
notmuch" (or similar) instead of "notmuch", but the "cat" patch should
be enough to make that work right.

Otherwise, wouldn't you be better off just having this be something
for the database::path setting in .notmuch-config? So you say:

   [database]
   path=/home/aj/Mail

or

   [database]
   path=/home/aj/Mail/.git
   format=git

or

   [database]
   # multiple backends
   path=/home/aj/Mail
   path=git:///home/aj/OldMail.git

and have filename: just serve as a unique id that the database knows
how to convert to the contents of the file?

At most (afaics) maybe you'd want to say something like:

    [database]
    path=/home/aj/Mail
    path.old=git:///home/aj/OldMail.git

so that any filename starting with "old/" has the "old/" trimmed and
gets passed to the git backend, while the rest go to the default file
backend.

Cheers,
aj

-- 
Anthony Towns <aj@erisian.com.au>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 1/2] Add 'cat' subcommand
  2010-04-22  0:44       ` Carl Worth
  2010-04-22  2:37         ` Dirk Hohndel
@ 2010-04-22  6:38         ` Michal Sojka
  2010-04-23 19:07           ` Carl Worth
  1 sibling, 1 reply; 16+ messages in thread
From: Michal Sojka @ 2010-04-22  6:38 UTC (permalink / raw)
  To: Carl Worth; +Cc: notmuch

On Thu, 22 Apr 2010, Carl Worth wrote:
> On Tue, 20 Apr 2010 12:14:56 +0200, Michal Sojka <sojkam1@fel.cvut.cz> wrote:
> > On 20.4.2010 09:21, David Edmondson wrote:
> >  > I'm puzzled why you chose to pass a filename as the argument to 'cat'
> >  > rather than a message id (id:foo@bar.com)?
> > 
> > The reason is that I want be able to distinguish between several 
> > messages with the same id.
> 
> All other commands currently accept the generic search terms to specify
> messages, (even a command like "notmuch reply" for which it would have
> been natural to accept only a single message).
> 
> So I'd prefer to have this command behave just like all others and use
> the same naming.
> 
> The question of how to unambiguously refer to a single file is
> orthogonal, (and similarly applies to all commands, such as "notmuch
> tag" etc.). I would recommend supporting a search syntax something like:
> 
> 	filename:/complete/path/to/file
> 
> for that use case. And this should work fine whether the filenames are
> actual filenames or keys into some abstract file store of some sort.
> 
> What do you think?

It sounds reasonable. I looked at the code to see how this could be
implemented and I have a few questions:

If a filename:dir/file term is present in the query, it will be
necessary to first query the database for directory:dir to find the
<directory_ID> and then put in the query
file-direntry:<directory_ID>:file. This conversion is already
implemented in _notmuch_database_filename_to_direntry(). Right?

_notmuch_database_filename_to_direntry() requires writable database as
it creates the directory document if it doesn't exist. This is probably
not what we want for filename: queries - if the user types the filename
incorrectly, the nonexisting directory document could be added to the
database. So I think that _notmuch_database_find_directory_id() should
be modified to not modify the database. The directory documents should
be created somewhere else in notmuch new path. Do you agree?

-Michal

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 1/2] Add 'cat' subcommand
  2010-04-22  3:13           ` Anthony Towns
@ 2010-04-22  6:57             ` Michal Sojka
  0 siblings, 0 replies; 16+ messages in thread
From: Michal Sojka @ 2010-04-22  6:57 UTC (permalink / raw)
  To: Anthony Towns, Dirk Hohndel; +Cc: notmuch

On Thu, 22 Apr 2010, Anthony Towns wrote:
> On Thu, Apr 22, 2010 at 12:37, Dirk Hohndel <hohndel@infradead.org> wrote:
> > On Wed, 21 Apr 2010 17:44:03 -0700, Carl Worth <cworth@cworth.org> wrote:
> >> So I'd prefer to have this command behave just like all others and use
> >> the same naming.
> >>       filename:/complete/path/to/file
> 
> Would "notmuch cat" be any different to "notmuch show" in this case?
> What happens if you say "notmuch cat something" and multiple messages
> match (eg, an id: for a mail that you both sent (Mail/.sent/cur/12345)
> and received (Mail/.Lists.notmuch/cur/12346))?
> 
> Maybe notmuch show should be able to deal with all these things, and
> notmuch cat could be an alias for something like:
> 
>     notmuch show --format=mbox --show-duplicate-files $SPEC

I think this was discussed earlier with part subcommand and the result
was that "part" should become a part of show. The same probably applies
to the cat subcommand.

I don't think that --format=mbox is the right thing to do. A simple

    grep -R '^From[^:]' ~/mail

shows that I have many messages where "From" is present in the body at
the beginning of the line so it would have to be escaped and all the
tools dealing with this output need to de-escape it.

I think that --format=raw is better and this command should fail if the
query produces more than one message.

> Otherwise, wouldn't you be better off just having this be something
> for the database::path setting in .notmuch-config? So you say:
> 
>    [database]
>    path=/home/aj/Mail
> 
> or
> 
>    [database]
>    path=/home/aj/Mail/.git
>    format=git

This is something similar to what I have implemented in
id:1270737766-29237-1-git-send-email-sojkam1@fel.cvut.cz. Carl doesn't
want to merge it in its current form so I'm extracting some features
from it and sending them separately.

-Michal

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 1/2] Add 'cat' subcommand
  2010-04-22  6:38         ` Michal Sojka
@ 2010-04-23 19:07           ` Carl Worth
  0 siblings, 0 replies; 16+ messages in thread
From: Carl Worth @ 2010-04-23 19:07 UTC (permalink / raw)
  To: Michal Sojka; +Cc: notmuch

[-- Attachment #1: Type: text/plain, Size: 972 bytes --]

On Thu, 22 Apr 2010 08:38:54 +0200, Michal Sojka <sojkam1@fel.cvut.cz> wrote:
> If a filename:dir/file term is present in the query, it will be
> necessary to first query the database for directory:dir to find the
> <directory_ID> and then put in the query
> file-direntry:<directory_ID>:file. This conversion is already
> implemented in _notmuch_database_filename_to_direntry(). Right?

Yes.

> _notmuch_database_filename_to_direntry() requires writable database as
> it creates the directory document if it doesn't exist. This is probably
> not what we want for filename: queries - if the user types the filename
> incorrectly, the nonexisting directory document could be added to the
> database. So I think that _notmuch_database_find_directory_id() should
> be modified to not modify the database. The directory documents should
> be created somewhere else in notmuch new path. Do you agree?

Yes. Good job anticipating that failure mode before we ran into it.

-Carl

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 1/2] Add 'cat' subcommand
  2010-10-22  9:28 [PATCH 0/2] Notmuch cat v2 Michal Sojka
@ 2010-10-22  9:28 ` Michal Sojka
  0 siblings, 0 replies; 16+ messages in thread
From: Michal Sojka @ 2010-10-22  9:28 UTC (permalink / raw)
  To: notmuch

This command outputs a raw message matched by search term to the
standard output. It allows MUAs to access the messages for piping,
attachment manipulation, etc. by running notmuch cat rather then
directly access the file. This will simplify the MUAs when they need
to operate on a remote database.
---
 notmuch-client.h  |    3 ++
 notmuch-show.c    |   83 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 notmuch.1         |    4 ++
 notmuch.c         |    4 ++
 test/cat          |   38 ++++++++++++++++++++++++
 test/notmuch-test |    2 +-
 6 files changed, 133 insertions(+), 1 deletions(-)
 create mode 100755 test/cat

diff --git a/notmuch-client.h b/notmuch-client.h
index 20be43b..82526f8 100644
--- a/notmuch-client.h
+++ b/notmuch-client.h
@@ -111,6 +111,9 @@ int
 notmuch_search_tags_command (void *ctx, int argc, char *argv[]);
 
 int
+notmuch_cat_command (void *ctx, int argc, char *argv[]);
+
+int
 notmuch_part_command (void *ctx, int argc, char *argv[]);
 
 const char *
diff --git a/notmuch-show.c b/notmuch-show.c
index ea465de..285f38f 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -632,6 +632,89 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[]))
 }
 
 int
+notmuch_cat_command (void *ctx, unused (int argc), unused (char *argv[]))
+{
+    notmuch_config_t *config;
+    notmuch_database_t *notmuch;
+    notmuch_query_t *query;
+    notmuch_messages_t *messages;
+    notmuch_message_t *message;
+    char *query_string;
+    int i;
+    const char *filename;
+    FILE *file;
+    size_t size;
+    char buf[4096];
+
+    for (i = 0; i < argc && argv[i][0] == '-'; i++) {
+	fprintf (stderr, "Unrecognized option: %s\n", argv[i]);
+	return 1;
+    }
+
+    config = notmuch_config_open (ctx, NULL, NULL);
+    if (config == NULL)
+	return 1;
+
+    query_string = query_string_from_args (ctx, argc, argv);
+    if (query_string == NULL) {
+	fprintf (stderr, "Out of memory\n");
+	return 1;
+    }
+
+    if (*query_string == '\0') {
+	fprintf (stderr, "Error: notmuch cat requires at least one search term.\n");
+	return 1;
+    }
+
+    notmuch = notmuch_database_open (notmuch_config_get_database_path (config),
+				     NOTMUCH_DATABASE_MODE_READ_ONLY);
+    if (notmuch == NULL)
+	return 1;
+
+    query = notmuch_query_create (notmuch, query_string);
+    if (query == NULL) {
+	fprintf (stderr, "Error: Out of memory\n");
+	return 1;
+    }
+
+    if (notmuch_query_count_messages (query) != 1) {
+	fprintf (stderr, "Error: search term did not match precisely one message.\n");
+	return 1;
+    }
+    
+    messages = notmuch_query_search_messages (query);
+    message = notmuch_messages_get (messages);
+    
+    if (message == NULL) {
+	fprintf (stderr, "Error: Cannot find matching message.\n");
+	return 1;
+    }
+
+    filename = notmuch_message_get_filename (message);
+    if (filename == NULL) {
+	fprintf (stderr, "Error: Cannot message filename.\n");
+	return 1;
+    }
+
+    file = fopen (filename, "r");
+    if (file == NULL) {
+	fprintf (stderr, "Error: Cannot open file %s: %s\n", filename, strerror (errno));
+	return 1;
+    }
+    
+    while (!feof (file)) {
+	size = fread (buf, 1, sizeof (buf), file);
+	fwrite (buf, size, 1, stdout);
+    }
+
+    fclose (file);
+    notmuch_query_destroy (query);
+    notmuch_database_close (notmuch);
+
+    return 0;
+}
+
+int
 notmuch_part_command (void *ctx, unused (int argc), unused (char *argv[]))
 {
 	notmuch_config_t *config;
diff --git a/notmuch.1 b/notmuch.1
index 3ec9c55..2ec4048 100644
--- a/notmuch.1
+++ b/notmuch.1
@@ -255,6 +255,10 @@ See the
 section below for details of the supported syntax for <search-terms>.
 .RE
 .TP
+.BR cat  " <search-term>..."
+
+Output raw content of a single message matched by the search term.
+.TP
 .BR count " <search-term>..."
 
 Count messages matching the search terms.
diff --git a/notmuch.c b/notmuch.c
index f6b8c13..e36486c 100644
--- a/notmuch.c
+++ b/notmuch.c
@@ -310,6 +310,10 @@ command_t commands[] = {
       "\tcontain tags only from messages that match the search-term(s).\n"
       "\n"
       "\tIn both cases the list will be alphabetically sorted." },
+    { "cat", notmuch_cat_command,
+      "<search-terms>",
+      "Output raw content of a single message matched by the search term.",
+      "" },
     { "part", notmuch_part_command,
       "--part=<num> <search-terms>",
       "Output a single MIME part of a message.",
diff --git a/test/cat b/test/cat
new file mode 100755
index 0000000..c6cefea
--- /dev/null
+++ b/test/cat
@@ -0,0 +1,38 @@
+#!/bin/bash
+
+test_description='notmuch cat'
+. ./test-lib.sh
+
+test_begin_subtest "Generate some messages"
+generate_message
+generate_message
+output=$(NOTMUCH_NEW)
+test_expect_equal "$output" "Added 2 new messages to the database."
+
+test_begin_subtest "Without arguments"
+output=$(notmuch cat 2>&1)
+test_expect_equal "$output" "Error: notmuch cat requires at least one search term."
+
+test_begin_subtest "Attempt to cat multiple messages"
+output=$(notmuch cat "*" 2>&1)
+test_expect_equal "$output" "Error: search term did not match precisely one message."
+
+test_begin_subtest "Cat a message"
+output=$(notmuch cat id:msg-001@notmuch-test-suite)
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+To: Notmuch Test Suite <test_suite@notmuchmail.org>
+Message-Id: <msg-001@notmuch-test-suite>
+Subject: Test message #1
+Date: Tue, 05 Jan 2001 15:43:57 -0000
+
+This is just a test message (#1)"
+
+test_begin_subtest "Cat another message"
+output=$(notmuch cat id:msg-002@notmuch-test-suite)
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+To: Notmuch Test Suite <test_suite@notmuchmail.org>
+Message-Id: <msg-002@notmuch-test-suite>
+Subject: Test message #2
+Date: Tue, 05 Jan 2001 15:43:57 -0000
+
+This is just a test message (#2)"
diff --git a/test/notmuch-test b/test/notmuch-test
index 13c5d80..0c33a47 100755
--- a/test/notmuch-test
+++ b/test/notmuch-test
@@ -8,7 +8,7 @@
 
 cd $(dirname "$0")
 
-TESTS="basic new search json thread-naming reply dump-restore uuencode thread-order author-order from-guessing long-id encoding"
+TESTS="basic new search json thread-naming reply dump-restore uuencode thread-order author-order from-guessing long-id encoding cat"
 
 # Clean up any results from a previous run
 rm -r test-results >/dev/null 2>/dev/null
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2010-10-22  9:28 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-04-20  7:16 [PATCH 1/2] Add 'cat' subcommand Michal Sojka
2010-04-20  7:16 ` [PATCH 2/2] emacs: Access raw messages through cat subcommand Michal Sojka
2010-04-20  7:21 ` [PATCH 1/2] Add 'cat' subcommand David Edmondson
2010-04-20  8:09   ` Sebastian Spaeth
2010-04-20 10:14     ` Michal Sojka
2010-04-20 10:53       ` David Edmondson
2010-04-20 11:13         ` Michal Sojka
2010-04-20 11:30           ` David Edmondson
2010-04-20 13:32       ` Jameson Rollins
2010-04-22  0:44       ` Carl Worth
2010-04-22  2:37         ` Dirk Hohndel
2010-04-22  3:13           ` Anthony Towns
2010-04-22  6:57             ` Michal Sojka
2010-04-22  6:38         ` Michal Sojka
2010-04-23 19:07           ` Carl Worth
  -- strict thread matches above, loose matches on Subject: below --
2010-10-22  9:28 [PATCH 0/2] Notmuch cat v2 Michal Sojka
2010-10-22  9:28 ` [PATCH 1/2] Add 'cat' subcommand Michal Sojka

Code repositories for project(s) associated with this public inbox

	https://yhetil.org/notmuch.git/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).