[PATCH 1/2] Add 'cat' subcommand
authorMichal Sojka <sojkam1@fel.cvut.cz>
Fri, 22 Oct 2010 09:28:03 +0000 (11:28 +0200)
committerW. Trevor King <wking@tremily.us>
Fri, 7 Nov 2014 17:37:18 +0000 (09:37 -0800)
ab/b486f5b9047419f1c665de4d62c98f9627b536 [new file with mode: 0644]

diff --git a/ab/b486f5b9047419f1c665de4d62c98f9627b536 b/ab/b486f5b9047419f1c665de4d62c98f9627b536
new file mode 100644 (file)
index 0000000..2de5a2e
--- /dev/null
@@ -0,0 +1,272 @@
+Return-Path: <sojkam1@fel.cvut.cz>\r
+X-Original-To: notmuch@notmuchmail.org\r
+Delivered-To: notmuch@notmuchmail.org\r
+Received: from localhost (localhost [127.0.0.1])\r
+       by olra.theworths.org (Postfix) with ESMTP id 842BB40D148\r
+       for <notmuch@notmuchmail.org>; Fri, 22 Oct 2010 02:28:47 -0700 (PDT)\r
+X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
+X-Spam-Flag: NO\r
+X-Spam-Score: -1.9\r
+X-Spam-Level: \r
+X-Spam-Status: No, score=-1.9 tagged_above=-999 required=5\r
+       tests=[BAYES_00=-1.9] autolearn=ham\r
+Received: from olra.theworths.org ([127.0.0.1])\r
+       by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
+       with ESMTP id PFCxltAzwREE for <notmuch@notmuchmail.org>;\r
+       Fri, 22 Oct 2010 02:28:32 -0700 (PDT)\r
+Received: from max.feld.cvut.cz (max.feld.cvut.cz [147.32.192.36])\r
+       by olra.theworths.org (Postfix) with ESMTP id 13AB140D14D\r
+       for <notmuch@notmuchmail.org>; Fri, 22 Oct 2010 02:28:18 -0700 (PDT)\r
+Received: from localhost (unknown [192.168.200.4])\r
+       by max.feld.cvut.cz (Postfix) with ESMTP id 1A57919F33B5;\r
+       Fri, 22 Oct 2010 11:28:17 +0200 (CEST)\r
+X-Virus-Scanned: IMAP AMAVIS\r
+Received: from max.feld.cvut.cz ([192.168.200.1])\r
+       by localhost (styx.feld.cvut.cz [192.168.200.4]) (amavisd-new,\r
+       port 10044)\r
+       with ESMTP id vHNwQ2xABZ-G; Fri, 22 Oct 2010 11:28:15 +0200 (CEST)\r
+Received: from imap.feld.cvut.cz (imap.feld.cvut.cz [147.32.192.34])\r
+       by max.feld.cvut.cz (Postfix) with ESMTP id EFADD19F3365;\r
+       Fri, 22 Oct 2010 11:28:14 +0200 (CEST)\r
+Received: from steelpick.2x.cz (note-sojka.felk.cvut.cz [147.32.86.30])\r
+       (Authenticated sender: sojkam1)\r
+       by imap.feld.cvut.cz (Postfix) with ESMTPSA id 041F4FA006;\r
+       Fri, 22 Oct 2010 11:28:14 +0200 (CEST)\r
+Received: from wsh by steelpick.2x.cz with local (Exim 4.72)\r
+       (envelope-from <sojkam1@fel.cvut.cz>)\r
+       id 1P9Dv4-0006oz-0v; Fri, 22 Oct 2010 11:28:14 +0200\r
+From: Michal Sojka <sojkam1@fel.cvut.cz>\r
+To: notmuch@notmuchmail.org\r
+Subject: [PATCH 1/2] Add 'cat' subcommand\r
+Date: Fri, 22 Oct 2010 11:28:03 +0200\r
+Message-Id: <1287739684-26188-2-git-send-email-sojkam1@fel.cvut.cz>\r
+X-Mailer: git-send-email 1.7.2.3\r
+In-Reply-To: <1287739684-26188-1-git-send-email-sojkam1@fel.cvut.cz>\r
+References: <1287739684-26188-1-git-send-email-sojkam1@fel.cvut.cz>\r
+X-BeenThere: notmuch@notmuchmail.org\r
+X-Mailman-Version: 2.1.13\r
+Precedence: list\r
+List-Id: "Use and development of the notmuch mail system."\r
+       <notmuch.notmuchmail.org>\r
+List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
+       <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
+List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
+List-Post: <mailto:notmuch@notmuchmail.org>\r
+List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
+List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
+       <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
+X-List-Received-Date: Fri, 22 Oct 2010 09:28:47 -0000\r
+\r
+This command outputs a raw message matched by search term to the\r
+standard output. It allows MUAs to access the messages for piping,\r
+attachment manipulation, etc. by running notmuch cat rather then\r
+directly access the file. This will simplify the MUAs when they need\r
+to operate on a remote database.\r
+---\r
+ notmuch-client.h  |    3 ++\r
+ notmuch-show.c    |   83 +++++++++++++++++++++++++++++++++++++++++++++++++++++\r
+ notmuch.1         |    4 ++\r
+ notmuch.c         |    4 ++\r
+ test/cat          |   38 ++++++++++++++++++++++++\r
+ test/notmuch-test |    2 +-\r
+ 6 files changed, 133 insertions(+), 1 deletions(-)\r
+ create mode 100755 test/cat\r
+\r
+diff --git a/notmuch-client.h b/notmuch-client.h\r
+index 20be43b..82526f8 100644\r
+--- a/notmuch-client.h\r
++++ b/notmuch-client.h\r
+@@ -111,6 +111,9 @@ int\r
+ notmuch_search_tags_command (void *ctx, int argc, char *argv[]);\r
\r
+ int\r
++notmuch_cat_command (void *ctx, int argc, char *argv[]);\r
++\r
++int\r
+ notmuch_part_command (void *ctx, int argc, char *argv[]);\r
\r
+ const char *\r
+diff --git a/notmuch-show.c b/notmuch-show.c\r
+index ea465de..285f38f 100644\r
+--- a/notmuch-show.c\r
++++ b/notmuch-show.c\r
+@@ -632,6 +632,89 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[]))\r
+ }\r
\r
+ int\r
++notmuch_cat_command (void *ctx, unused (int argc), unused (char *argv[]))\r
++{\r
++    notmuch_config_t *config;\r
++    notmuch_database_t *notmuch;\r
++    notmuch_query_t *query;\r
++    notmuch_messages_t *messages;\r
++    notmuch_message_t *message;\r
++    char *query_string;\r
++    int i;\r
++    const char *filename;\r
++    FILE *file;\r
++    size_t size;\r
++    char buf[4096];\r
++\r
++    for (i = 0; i < argc && argv[i][0] == '-'; i++) {\r
++      fprintf (stderr, "Unrecognized option: %s\n", argv[i]);\r
++      return 1;\r
++    }\r
++\r
++    config = notmuch_config_open (ctx, NULL, NULL);\r
++    if (config == NULL)\r
++      return 1;\r
++\r
++    query_string = query_string_from_args (ctx, argc, argv);\r
++    if (query_string == NULL) {\r
++      fprintf (stderr, "Out of memory\n");\r
++      return 1;\r
++    }\r
++\r
++    if (*query_string == '\0') {\r
++      fprintf (stderr, "Error: notmuch cat requires at least one search term.\n");\r
++      return 1;\r
++    }\r
++\r
++    notmuch = notmuch_database_open (notmuch_config_get_database_path (config),\r
++                                   NOTMUCH_DATABASE_MODE_READ_ONLY);\r
++    if (notmuch == NULL)\r
++      return 1;\r
++\r
++    query = notmuch_query_create (notmuch, query_string);\r
++    if (query == NULL) {\r
++      fprintf (stderr, "Error: Out of memory\n");\r
++      return 1;\r
++    }\r
++\r
++    if (notmuch_query_count_messages (query) != 1) {\r
++      fprintf (stderr, "Error: search term did not match precisely one message.\n");\r
++      return 1;\r
++    }\r
++    \r
++    messages = notmuch_query_search_messages (query);\r
++    message = notmuch_messages_get (messages);\r
++    \r
++    if (message == NULL) {\r
++      fprintf (stderr, "Error: Cannot find matching message.\n");\r
++      return 1;\r
++    }\r
++\r
++    filename = notmuch_message_get_filename (message);\r
++    if (filename == NULL) {\r
++      fprintf (stderr, "Error: Cannot message filename.\n");\r
++      return 1;\r
++    }\r
++\r
++    file = fopen (filename, "r");\r
++    if (file == NULL) {\r
++      fprintf (stderr, "Error: Cannot open file %s: %s\n", filename, strerror (errno));\r
++      return 1;\r
++    }\r
++    \r
++    while (!feof (file)) {\r
++      size = fread (buf, 1, sizeof (buf), file);\r
++      fwrite (buf, size, 1, stdout);\r
++    }\r
++\r
++    fclose (file);\r
++    notmuch_query_destroy (query);\r
++    notmuch_database_close (notmuch);\r
++\r
++    return 0;\r
++}\r
++\r
++int\r
+ notmuch_part_command (void *ctx, unused (int argc), unused (char *argv[]))\r
+ {\r
+       notmuch_config_t *config;\r
+diff --git a/notmuch.1 b/notmuch.1\r
+index 3ec9c55..2ec4048 100644\r
+--- a/notmuch.1\r
++++ b/notmuch.1\r
+@@ -255,6 +255,10 @@ See the\r
+ section below for details of the supported syntax for <search-terms>.\r
+ .RE\r
+ .TP\r
++.BR cat  " <search-term>..."\r
++\r
++Output raw content of a single message matched by the search term.\r
++.TP\r
+ .BR count " <search-term>..."\r
\r
+ Count messages matching the search terms.\r
+diff --git a/notmuch.c b/notmuch.c\r
+index f6b8c13..e36486c 100644\r
+--- a/notmuch.c\r
++++ b/notmuch.c\r
+@@ -310,6 +310,10 @@ command_t commands[] = {\r
+       "\tcontain tags only from messages that match the search-term(s).\n"\r
+       "\n"\r
+       "\tIn both cases the list will be alphabetically sorted." },\r
++    { "cat", notmuch_cat_command,\r
++      "<search-terms>",\r
++      "Output raw content of a single message matched by the search term.",\r
++      "" },\r
+     { "part", notmuch_part_command,\r
+       "--part=<num> <search-terms>",\r
+       "Output a single MIME part of a message.",\r
+diff --git a/test/cat b/test/cat\r
+new file mode 100755\r
+index 0000000..c6cefea\r
+--- /dev/null\r
++++ b/test/cat\r
+@@ -0,0 +1,38 @@\r
++#!/bin/bash\r
++\r
++test_description='notmuch cat'\r
++. ./test-lib.sh\r
++\r
++test_begin_subtest "Generate some messages"\r
++generate_message\r
++generate_message\r
++output=$(NOTMUCH_NEW)\r
++test_expect_equal "$output" "Added 2 new messages to the database."\r
++\r
++test_begin_subtest "Without arguments"\r
++output=$(notmuch cat 2>&1)\r
++test_expect_equal "$output" "Error: notmuch cat requires at least one search term."\r
++\r
++test_begin_subtest "Attempt to cat multiple messages"\r
++output=$(notmuch cat "*" 2>&1)\r
++test_expect_equal "$output" "Error: search term did not match precisely one message."\r
++\r
++test_begin_subtest "Cat a message"\r
++output=$(notmuch cat id:msg-001@notmuch-test-suite)\r
++test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>\r
++To: Notmuch Test Suite <test_suite@notmuchmail.org>\r
++Message-Id: <msg-001@notmuch-test-suite>\r
++Subject: Test message #1\r
++Date: Tue, 05 Jan 2001 15:43:57 -0000\r
++\r
++This is just a test message (#1)"\r
++\r
++test_begin_subtest "Cat another message"\r
++output=$(notmuch cat id:msg-002@notmuch-test-suite)\r
++test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>\r
++To: Notmuch Test Suite <test_suite@notmuchmail.org>\r
++Message-Id: <msg-002@notmuch-test-suite>\r
++Subject: Test message #2\r
++Date: Tue, 05 Jan 2001 15:43:57 -0000\r
++\r
++This is just a test message (#2)"\r
+diff --git a/test/notmuch-test b/test/notmuch-test\r
+index 13c5d80..0c33a47 100755\r
+--- a/test/notmuch-test\r
++++ b/test/notmuch-test\r
+@@ -8,7 +8,7 @@\r
\r
+ cd $(dirname "$0")\r
\r
+-TESTS="basic new search json thread-naming reply dump-restore uuencode thread-order author-order from-guessing long-id encoding"\r
++TESTS="basic new search json thread-naming reply dump-restore uuencode thread-order author-order from-guessing long-id encoding cat"\r
\r
+ # Clean up any results from a previous run\r
+ rm -r test-results >/dev/null 2>/dev/null\r
+-- \r
+1.7.2.3\r
+\r